Tom Boucher
6c725438cc
fix( #2018 ): use helpers.cleanup() not raw fs.rmSync in surface test; drop unused imports ( #2033 )
...
The #2018 regression test used raw fs.rmSync() in afterEach, tripping the
local/no-raw-rmsync-in-tests eslint rule (Windows-EBUSY retry budget). CI's
lint-tests job (no eslint cache) caught it on next; local --cache runs had
false-greened it. Switch to helpers.cleanup(). Also drop two unused
destructured imports (evaluateCommandExitZero, interpolate) in the
gate-predicate-evaluator test that emitted no-unused-vars warnings.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-05 18:01:28 -04:00
Tom Boucher
8de2ff9121
feat( #2008 ): generic command-exit-zero gate-predicate evaluator ( #2011 )
...
* feat(#2008 ): add generic command-exit-zero gate-predicate evaluator
Third-party capability gates declared via check.predicate were rendered for
display but never evaluated (only built-in check.query gates fired; the
security capability's gate worked solely via a hard-coded ship.md branch).
Add a generic, deps-injected gate-predicate evaluator (src/gate-predicate-evaluator.cts)
that dispatches by predicate.kind. Built-in kind: command-exit-zero — runs a
bounded sh -c command at the project root (via shell-command-projection.execTool),
inherits env, exit 0 => pass, non-zero => block, timeout => block, fail-closed.
Wire a 'check predicate' subcommand into check-command-router.cts and extend
the three generic workflow gate-dispatch sites (execute:wave:post, execute:post,
plan:post) to route check.predicate gates to the new evaluator. The two-step
gate contract (command-failure => onError; block => halt) is unchanged.
- src/gate-predicate-evaluator.cts: pure leaf, KIND_TABLE extensible
- src/check-command-router.cts: cmdCheckPredicate + buildPredicateDeps + parsePredicateFlags
- docs/adr/2008-*, docs/reference/gate-predicates.md, docs/how-to/command-exit-zero-gate.md
- tests: 38 unit + integration tests (exit mapping, timeout, interpolation,
property-based bijection, malformed-predicate fail-closed, real subprocess e2e)
Closes #2008
* docs(#2008 ): backfill changeset pr number 2011
2026-07-05 14:04:29 -04:00