feat: add model validate command with validate-all support#5
Merged
Conversation
Add `model validate` command to validate model inputs and resources against their Zod schemas. The command supports both single-model and batch validation: - `model validate <model_id_or_name>` - validates a single model by ID or name - `model validate` (no args) - validates all models in the repository Features: - ValidationService with parallel validation of input/resource schemas - Interactive output with checkmarks/X marks and colored results - JSON output mode for CI/automation use cases - Exit code 1 when any validation fails - Multi-model summary showing pass/fail counts Repository changes: - Add findAllGlobal() method to YamlInputRepository for batch operations - Add ValidationResult value object and DefaultModelValidationService Co-Authored-By: Claude Opus 4.5 <[email protected]>
fc4f934 to
a576c07
Compare
7 tasks
ianarsenault
pushed a commit
to ianarsenault/swamp
that referenced
this pull request
Apr 21, 2026
…-club#141) (systeminit#1205) ## Summary - Fixes [swamp-club#141](https://swamp.club/lab/issues/141): extension authors whose `_test.ts` imports the model source hit `TS7006` (implicit `any` on execute parameters) under strict mode. - Ships a type-only `ModelDefinition<TGlobalArgs>` in `@systeminit/swamp-testing` that authors opt into via `satisfies ModelDefinition<typeof Schema>` (or the `defineModel` function-form alternative). The literal stays identical — only a trailing satisfies and a type-only import are added. - `context.globalArgs` narrows to the schema-inferred shape (verified by probing an undeclared field → TS2339). This is a real type-safety upgrade, not a TS7006 silencer. - Default authoring experience is **unchanged** — unannotated execute params remain the Quick Start. Existing extensions do not need to migrate. The `: any` workaround keeps working for anyone already using it. ## What's included - `packages/testing/model_definition_types.ts` — new type-only file with `ModelDefinition`, `MethodDefinition`, `CheckDefinition`, `ResourceOutputSpec`, `FileOutputSpec`, `VersionUpgrade`, `CheckResult`, and the `defineModel` helper. - `packages/testing/types.ts` — `MethodContext<TGlobalArgs = Record<string, unknown>>` (additive, backward compatible). - `packages/testing/mod.ts` — new "Model authoring" export block. - `packages/testing/model_definition_types_test.ts` — type-level regression test asserting both `satisfies` and `defineModel` paths narrow `globalArgs` under strict+noImplicitAny. - `src/domain/models/testing_package_compat_test.ts` — extended to guard drift between testing and canonical `ModelDefinition` / `MethodDefinition`. - `.claude/skills/swamp-extension-model/references/typing.md` — new reference with before/after, "when not to use," and cross-links to the compat test and issue systeminit#141. - `.claude/skills/swamp-extension-model/SKILL.md` — Key Rule systeminit#5 points at typing.md. - `.claude/skills/swamp-extension-model/references/testing.md` — cross-link banner at the top. - `packages/testing/README.md` — new "Model authoring escape hatch" subsection. - `packages/testing/deno.json` — bumped 0.2.0 → 0.3.0. ## Author-facing usage ```typescript import { z } from "npm:zod@4"; import type { ModelDefinition } from "jsr:@systeminit/swamp-testing"; const GlobalArgsSchema = z.object({ region: z.string() }); export const model = { type: "@myorg/my-model", version: "2026.04.21.1", globalArguments: GlobalArgsSchema, methods: { run: { description: "Run the model", arguments: z.object({ bucket: z.string() }), execute: async (_args, context) => { // context.globalArgs narrows to { region: string } return { dataHandles: [] }; }, }, }, } satisfies ModelDefinition<typeof GlobalArgsSchema>; ``` ## Why not a per-method args-narrowing helper The plan's initial `defineModel` sketch intended per-method `args` inference via mapped-intersection generics. Both the F-bounded recursive constraint and the `Omit`-based override pattern failed contextual typing during inference — per-method args narrowing for inline literals requires a builder-style API (as used by tRPC / zod's own `.input()` chain), which is out of scope here. Authors narrow `args` per method with `MySchema.parse(args)` at runtime (the canonical Zod way). `typing.md` documents this. ## Test plan - [x] `deno check main.ts packages/testing/mod.ts` passes - [x] `deno run test` — all 4505 existing tests pass; new 4 type-level + smoke tests pass - [x] `deno lint` clean - [x] `deno fmt` applied - [x] `deno run review-skills` — all skills pass the 90% threshold - [x] Scratch-repo verification: reproduces TS7006 on the pre-fix shape; compiles cleanly with `satisfies ModelDefinition<typeof Schema>` and `defineModel({ ... })`; narrowing probe confirms `context.globalArgs.region` is typed and `context.globalArgs.undeclaredField` errors as expected. - [x] Drift-guard verification: injecting `description: number` into testing-side `MethodDefinition` immediately failed `testing_package_compat_test.ts` as designed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
model validatecommand to validate model inputs and resources against their Zod schemasmodel validate <model_id_or_name>model validate(no args) validates all models in repositoryfindAllGlobal()method toYamlInputRepositoryfor centralized batch operationsValidationServicewith parallel validation executionTest plan
deno task testpasses (192 tests)deno check main.tspassesdeno lintpassesdeno fmtpassesmodel validate --repo-dir /tmp/test🤖 Generated with Claude Code