Fix per-surface test command priority

Per-surface test commands in `createAnaJson` use direct runner invocation (`pnpm vitest run`) instead of the developer's actual test script (`pnpm run test`). This skips setup steps like `prisma:generate`, `dotenv`, `cross-env`, and build prerequisites. R3 pre-launch testing found 12 of 29 surfaces (41%) across 17 real repos produce mismatched commands; 8 would cause test failures on the first pipeline run. The fix: invert the priority so script passthrough comes first, with direct invocation as fallback for surfaces that lack a test script.

verdict PASSscore 10 / 10findings 6 (1 risk · 1 debt · 4 obs)duration 38mrejection cycles 0shipped May 21, 2026surface cli

Pipeline timeline

Intent to proven code in 38m across Think, Plan, Build, and Verify.

Think
7m
Plan
3m
Build
6m
Verify
4m

Assertion ledger

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

IDSaysMatcher
A001Surfaces with a test script use the developer's script instead of a direct runner commandverifiedok
A002Complex test scripts with setup steps are preserved, not overriddenverifiedok
A003Surfaces without a test script fall back to direct framework invocationverifiedok
A004Surfaces with neither test script nor detected framework get no test commandverifiedok
A005Bun workspaces use the correct bun run prefix for script passthroughverifiedok
A006An empty test script is treated as present and uses script passthroughverifiedok
A007Root-level test commands are not affected by this changeverifiedok
A008Build commands still use script passthrough as beforeverifiedok

Findings 6 total

obspackages/cli/src/commands/init/state.tsmonitor
scripts['test'] !== undefined treats explicit null value as 'present' — a package.json with test: null would get script passthrough producing a broken pnpm run test
obspackages/cli/tests/commands/init/makeTestCommand.test.tsclosed
File not in contract file_changes was modified — makeTestCommand.test.ts assertions updated to match new behavior
riskpackages/cli/src/commands/init/state.tsclosed
surface.path injected into shell command without sanitization — paths with spaces or special chars produce broken subshell
debtpackages/cli/tests/commands/init/monorepoCommandScoping.test.tsclosed
A006 empty-string assertion uses toContain('run test') — weaker than other assertions that use toBe for exact match
obspackages/cli/tests/commands/init/monorepoCommandScoping.test.tsmonitor
Repeated tmpDir/cwdDir setup+teardown boilerplate in all 4 new tests — follows existing pattern but adds to known tech debt
+1more findings

Integrity seal

scopesha256:598fb8b9d551f...
contractsha256:de80e2fcca47e...
plansha256:015b79fab2abc...
specsha256:8f16d434919f2...
build-reportsha256:2a965d663ea8a...
build-datasha256:87c1adaf9a56f...
verify-reportsha256:1f952e7744374...
verify-datasha256:ee7e927c99347...
audit cmd$ ana proof audit fix-surface-test-priority   → all hashes match