Extract Artifact Validators

`artifact.ts` is 2093 lines — the third-largest source file. 610 of those lines are 8 format validators (`validatePlanFormat`, `validateScopeFormat`, `validateContractFormat`, etc.) that are pure functions: file path in, error string (or null) out. They have no dependency on any other artifact.ts function, no shared state, and a clean dependency set (fs, path, yaml, findProjectRoot). They're called from exactly two places: `saveArtifact` and `saveAllArtifacts`.

verdict PASSscore 15 / 15findings 3 (0 risk · 1 debt · 2 obs)duration 19h 48mrejection cycles 0shipped May 25, 2026surface cli

Pipeline timeline

Intent to proven code in 19h 48m across Think, Plan, Build, and Verify.

Think
32m
Plan
5m
Build
7m
Verify
4m

Assertion ledger

15 claims, each independently verified. Showing 8 — show all →

IDSaysMatcher
A001The new validator module exists and exports all 8 validator functionsverifiedok
A002The original module still exports the 3 public validators for backward compatibilityverifiedok
A003The original module still exports validateVerifyDataFormat for backward compatibilityverifiedok
A004The original module still exports validateBuildDataFormat for backward compatibilityverifiedok
A005Plan validation still rejects plans missing the Phases headingverifiedok
A006Scope validation still rejects scopes with fewer than 3 acceptance criteriaverifiedok
A007Contract validation still catches missing version fieldverifiedok
A008Spec validation still catches missing Build Brief sectionverifiedok

Findings 3 total

debtpackages/cli/src/commands/artifact-validators.tsclosed
Constants exported unnecessarily — VALID_MATCHERS, VALUE_REQUIRED_MATCHERS, VALID_FINDING_CATEGORIES, VALID_FINDING_SEVERITIES, VALID_FINDING_ACTIONS were module-private in artifact.ts but exported in artifact-validators.ts
obspackages/cli/src/commands/artifact-validators.tsclosed
Interfaces VerifyDataSchema and BuildDataSchema are not exported — correct, since they were module-private before. But they use index signatures ([key: string]: unknown) that suppress type errors on unknown fields. This is inherited behavior, not new.
obsclosed
A013 matcher 'greater' with value 1350 is loose — artifact.ts is 1501 lines, well above the threshold. The assertion tests that extraction happened but doesn't tightly bound the result. A range-based check (e.g., between 1400-1600) would catch accidental inclusion or double-extraction.

Integrity seal

scopesha256:38f48356b580d...
contractsha256:4a3cd6490d840...
plansha256:c9f41709864bd...
specsha256:4a4253a6f4d14...
build-reportsha256:7bda11ee89f68...
build-datasha256:eedbc774d5164...
verify-reportsha256:c20f3605fb58b...
verify-datasha256:d0ca4ee30a2fd...
audit cmd$ ana proof audit extract-artifact-validators   → all hashes match