feat(gate): add a script kind that runs a policy's own program - #154
Merged
Merged
Conversation
Merged
8 tasks
The declarative gate kinds answer questions a closed table can hold. A check that models flow through a method body cannot be written that way, and until now the only door for a script was the shell guard, which judges a command and never sees the file being written. `kind: script` names a Python file under the policy's implementations/. The runner hands it the same material every declarative kind reads -- the staged blobs at commit, the write at tool use and at the turn's end -- as JSON on stdin, and carries back its verdict: exit 0 allows, exit 1 blocks with the script's own words as the reason. Any other exit, a missing script, or a script that gives no verdict within 30 seconds refuses rather than allowing what it never judged. `chock compile` rewrites the bare name to the policy-relative path the git hook runs from. `chock check` refuses a name that is not a bare .py file and a declared script that is not shipped. The kind joins WRITE_PATH_KINDS, so it rides the existing pre-tool-use and stop fragments; a new emitter-stability fixture pins those bytes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
jothimani-rajendran
force-pushed
the
claude/script-gate-kind
branch
from
September 22, 2026 02:35
616cea4 to
c9052a5
Compare
jothimani-rajendran
marked this pull request as ready for review
September 22, 2026 11:56
jothimani-rajendran
added a commit
that referenced
this pull request
Sep 22, 2026
Merging main brought #154 (kind: script) into the 0.9.3 section; the heading is the release title, so it now names both features. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
Merged
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.
What
Adds
kind: scriptto the gate DSL. The declarative kinds (content_regex,forbidden_ref,dependency_allowlist,test_integrity) answer questions a closed table can hold; a check that models flow through a method body (the motivating case is the Java security policy being moved into the catalog) cannot be written that way, and the only door for a script until now was the shell guard, which judges a command and never sees the file being written.A script gate names a Python file under the policy's
implementations/. The runner hands it the same material every declarative kind reads -- staged blobs at commit, the write at tool use and at the turn's end -- as JSON on stdin ({"event", "repo_root", "writes": {path: text}}) and carries back its verdict: exit 0 allows, exit 1 blocks with the script's own stderr/stdout as the reason. Any other exit code, a missing script, or no verdict within 30 seconds refuses rather than allowing what it never judged.chock compilerewrites the bare name to the policy-relative path the git hook runs from (build.py).chock checkrefuses a name that is not a bare.pyfile (schema pattern) and a declared script that is not shipped (checks_gate_shape.py).WRITE_PATH_KINDS, so it rides the existing pre-tool-use and stop fragments unchanged; a new emitter-stability fixture (stability-script) pins those bytes..chock/bin/gate.pyre-vendored fromrunner.py; docs inspec/gate-dsl.md,docs/concepts.md,CHANGELOG.md.Definition of done
chock check→ 0 errors, 0 warnings; 5 infos, all pre-existing onmain(unchanged by this PR)chock check --only matrixpasses (32 invariants); no behavior change to existing kinds, matrix unchangedchock sync --repo . --checkcleanchock check --only verifycleanpytest -qgreen: 1414 passed, 6 skipped (baseline 1394 + 20 new intests/test_gate_script_kind.py, covering compiled path, commit/tool-use/stop verdicts, crash/missing/timeout refusals, emitter wiring, and validation)pytest acceptance/ -c acceptance/pytest.ini --rootdir=acceptancegreen: 21 passedscript, so nothing to migrate; the only touched manifest is the new stability fixtureruff check .andruff format --check .cleanClaims
INSTALLED_SURFACESis unchanged: the new kind emits through the same write and stop fragments the existing write-path kind uses, as thestability-scriptgoldens show, anddocs/enforcement-surfaces.mdneeded no change.🤖 Generated with Claude Code
https://claude.ai/code/session_01CzNYfzP8ymU3r4JB9Sz8Ha
Generated by Claude Code