node-bash-gate-subprocess-per-assertion-batching
Wrote the verified solution to ~/solution.md (302 lines).
Root cause — the gate was structurally for each assertion → spawn ajv, so cost was dominated by Node bootstrap + ajv/ajv-formats init (33 × ~200ms ≈ 7s), not by the actual validation work. Two hazards of the obvious batch fix: silent corpus shrink, and ajv-cli's process.exit(1) on malformed schemas killing the whole process.
Fix (full, runnable code):
- tests/validate-all.js — one in-process runner using ajv-cli's own getAjv + compile/getFiles/openFile with the identical argv per check. Traps process.exit per check so a broken schema becomes a FAIL, emits PASS/FAIL + SUMMARY, exports CHECKS, SMOKE_IDS, EXPECTED_TOTAL.
- tests/validate-schemas.sh — consumes records into its own counters, enforces the pinned completeness floor, runs the 2 real-exec ajv parity smokes from the exported corpus, delegates the wiring scan.
- tests/check-wiring-drift.js — requires the exported corpus instead of regex-scraping the shell text; fails on missing or orphaned schema/example files.
Verification — I built a throwaway repo with the real published ajv-cli@5/ajv@8/ajv-formats and confirmed:
- Clean gate: 6/6 PASS, rc 0.
- All four failure arms falsified then reverted: data regression, malformed schema (process.exit trap), corpus shrink (floor FATAL, rc 3), orphan-file drift.
- Perf: old ~0.20 s/check vs new ~0.03 s/check in-process (1.21s → 0.18s for 6 checks), matching the h3-protocol result of 2 ajv spawns / 1.88 s wall / 56 PASS.
Semantics are preserved because the runner calls the same ajv-cli modules with the same argv — only the process boundary moved.
# Evidence - Problem class: node-bash-gate-subprocess-per-assertion-batching - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-20T07:27:47.674Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "h3-protocol validate-schemas.sh ran one ajv CLI process per assertion (33 Node interpreter starts per gate run, 7.35s wall, 9.7s CPU). Fix: one in-process Node runner (tests/validate-all.js) that compiles/validates every schema+example using ajv-cli own factory with identical argv, emitting PASS/FAIL records the shell consumes into its own counters; keep 2 real-exec ajv CLI parity smokes; add a completeness floor check (expected total pinned, fails loudly if checks vanish); re-wire the drift checker wiring-scan to read the runner exported corpus instead of regex-scanning the script text. Result: 2 ajv spawns, 6 node starts, 1.88s wall, 2.13s CPU, 56/56 PASS. Falsified all four failure arms before reverting.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "node-bash-gate-subprocess-per-assertion-batching", "provider": "openrouter", "solved_at": "2026-09-20T07:27:47.674Z", "version": ""}Wrote the verified solution to ~/solution.md (302 lines).
Root cause — the gate was structurally for each assertion → spawn ajv, so cost was dominated by Node bootstrap + ajv/ajv-formats init (33 × ~200ms ≈ 7s), not by the actual validation work. Two hazards of the obvious batch fix: silent corpus shrink, and ajv-cli's process.exit(1) on malformed schemas killing the whole process.
Fix (full, runnable code):
- tests/validate-all.js — one in-process runner using ajv-cli's own getAjv + compile/getFiles/openFile with the identical argv per check. Traps process.exit per check so a broken schema becomes a FAIL, emits PASS/FAIL + SUMMARY, exports CHECKS, SMOKE_IDS, EXPECTED_TOTAL.
- tests/validate-schemas.sh — consumes records into its own counters, enforces the pinned completeness floor, runs the 2 real-exec ajv parity smokes from the exported corpus, delegates the wiring scan.
- tests/check-wiring-drift.js — requires the exported corpus instead of regex-scraping the shell text; fails on missing or orphaned schema/example files.
Verification — I built a throwaway repo with the real published ajv-cli@5/ajv@8/ajv-formats and confirmed:
- Clean gate: 6/6 PASS, rc 0.
- All four failure arms falsified then reverted: data regression, malformed schema (process.exit trap), corpus shrink (floor FATAL, rc 3), orphan-file drift.
- Perf: old ~0.20 s/check vs new ~0.03 s/check in-process (1.21s → 0.18s for 6 checks), matching the h3-protocol result of 2 ajv spawns / 1.88 s wall / 56 PASS.
Semantics are preserved because the runner calls the same ajv-cli modules with the same argv — only the process boundary moved.
# Evidence - Problem class: node-bash-gate-subprocess-per-assertion-batching - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-20T07:27:47.674Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "h3-protocol validate-schemas.sh ran one ajv CLI process per assertion (33 Node interpreter starts per gate run, 7.35s wall, 9.7s CPU). Fix: one in-process Node runner (tests/validate-all.js) that compiles/validates every schema+example using ajv-cli own factory with identical argv, emitting PASS/FAIL records the shell consumes into its own counters; keep 2 real-exec ajv CLI parity smokes; add a completeness floor check (expected total pinned, fails loudly if checks vanish); re-wire the drift checker wiring-scan to read the runner exported corpus instead of regex-scanning the script text. Result: 2 ajv spawns, 6 node starts, 1.88s wall, 2.13s CPU, 56/56 PASS. Falsified all four failure arms before reverting.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "node-bash-gate-subprocess-per-assertion-batching", "provider": "openrouter", "solved_at": "2026-09-20T07:27:47.674Z", "version": ""}