Repository navigation
feat(hook): the adjudicator's first slice — envelope, parser, gh policy (CLOUD-202) - #113
Merged
Merged
Conversation
CLOUD-202 Port the five shell guards into `batten hook` — the neutral envelope, in Rust, from the battle-tested spec
The agent-neutral hook layer is the stated scarce property, and it already runs in production — as five Claude-Code-specific bash programs ( Scope, in order:
Ready
|
Refs: CLOUD-202
The agent-neutral hook layer existed as five single-harness bash programs
with one ~60-line command parser copy-pasted three times; that
duplication has produced two landed bug fixes and two open defects. This
lands the Rust core the port converges on:
hook.rs the normalized envelope (event/tool/command); the
wrapper-lookthrough parser — quoted spans neutralised,
segments split, env prefixes and wrapper programs (env,
timeout, sudo, mise exec --) looked through so policy judges
the EFFECTIVE program, the exact shape CLOUD-181 hardened;
and the gh lifecycle table ported verbatim from
gh-guard-check, reasons and all.
cli.rs `batten hook --harness <claude-code|exit-code>`. The
claude-code adapter answers in the host's JSON decision
object (exit 0, the channel the production guards already
use); the exit-code adapter is the neutral §7 inversion —
exit 2 denies, reason on stderr.
effect.rs `hook` is unclassified: its own run only reads, but its
decision mediates writes, so it must not leak into the
derived read-only allowlist.
Fail-open throughout: unreadable stdin, undecodable payload, empty
command, and the BATTEN_GH_GUARD_BYPASS hatch all allow. Unit tests pin
the parser's sharpest bats cases (wrapper look-through, quoted-span
non-match, interposed flag values, lookalike verbs); behavioural tests
pin both adapters' channels over the compiled binary.
The shell guards stay wired in settings.json until the remaining
policies (receipts, issue-key, run-shape, protected paths) are ported;
flipping the settings entry is CLOUD-202's item 5, not this commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VS5eTnMTruCWytpAk2gW7k
wenzowski
force-pushed
the
claude/committed-vs-docs-alignment-z1pb7a
branch
from
August 7, 2026 20:49
fe45691 to
4b2da11
Compare
wenzowski
marked this pull request as ready for review
August 7, 2026 20:50
Contributor
Author
|
/fast-forward |
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
First slice of CLOUD-202 (v0.1 spine item 1):
batten hookexists and adjudicates.hook.rs— the normalized envelope (event/tool/command); the wrapper-lookthrough command parser (quoted spans neutralised, segments split on shell separators, env prefixes andenv/timeout/sudo/mise exec --looked through so policy judges the effective program — the CLOUD-181-hardened shape, ported once instead of copy-pasted three times); and theghlifecycle deny table ported verbatim fromgh-guard-check, redirects and bypass hatch included.batten hook --harness <claude-code|exit-code>— the claude-code adapter answers in the host's JSONpermissionDecisionobject with exit 0 (the channel the production shell guards already use); the exit-code adapter is the neutral §7 inversion: exit 2 denies, reason on stderr.effect.rs—hookdeclaredunclassified(its decision mediates writes), so it cannot leak into the derived read-only allowlist; the completeness test enforces the pairing.BATTEN_GH_GUARD_BYPASS— all allow.Not in this slice (CLOUD-202 items 3–5): the receipt/issue-key/run-shape/protected-path policies and the
.claude/settings.jsonflip. The shell guards stay wired until those port.Why
The agent-neutral hook layer is the stated scarce property and until now existed only as five single-harness bash programs; the shared tokenizer's triplication has produced two landed bug-fix commits plus CLOUD-181/185. Refs CLOUD-202.
Verification
mise run ci, including thebatten-checkconsumer-ci: check in the main-branch protection ruleset #1 step);mise run verifybefore readying🤖 Generated with Claude Code
https://claude.ai/code/session_01VS5eTnMTruCWytpAk2gW7k