Repository navigation
fix(actor): an agent cannot switch chock off (CH-1) - #307
Conversation
The commands that change .chock/config.yaml, chock.lock or the compiled tree (sync, recompile, install-hooks, enable, disable, add, remove, init, compile) refuse under an agent marker with the rule `chock resume` applies; a person runs them from their own shell. The refusal is logged as policy_id chock-cli. `sync --check`, `check` and `status` stay open. One actor rule serves every check: CHOCK_AGENT_COMMIT=0 unsets that one variable and clears no vendor marker (CLAUDECODE=1, AI_AGENT, a configured agent_commit_env name), since an agent can set it too. The ask refusal tells a person the CHOCK_ALLOW line and tells an agent to ask the person, naming no override. For the agent asking chock_guidance, a policies.disabled entry counts only once committed at HEAD, the way the committed rollout caps the working tree's. docs/assurance-case.md restates "tamper-evident" to what the mechanism gives and lists the bytecode and runtime-pin limits; the spec and the surfaces doc state the new rule. Tests that asserted the old escape hatch now assert the opposite: the hatch was the review's B2 (an agent sets it too). Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
|
CI status on 69a4b85: This is this PR's failure and it is expected: What unblocks it, from a person's own shell on Nothing else in the PR waits on this. Reported to the orchestrator in the org-plan handoff. Generated by Claude Code |
…get (CH-1) Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
…erson to run chock sync (CH-1) `chock sync` now refuses an agent's shell, so a sentence inviting the agent to run it was false. The Claude Code runtime golden carries the new text; the vendored .chock/bin/claude_code.py follows at the person-run regen. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
|
Update to the regen step after b80f7fd (the SessionStart advice now tells an agent to ask a person to run
Generated by Claude Code |
Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
What
CH-1 from org-plan
plan/prerelease-fixes.md(chock review B1, B2, M2): the agent cannot switch chock off.sync,recompile,install-hooks,enable,disable,add,remove,initandcompile(every command that changes.chock/config.yaml,chock.lockor the compiled tree) refuse under an agent marker with the rulechock resumealready applies: "a person runschock <command>from their own shell". Data-driven:person_only: trueindata/commands.json, enforced once incli._dispatch, logged aspolicy_id: chock-cli. A--checkrun writes nothing and stays open, as docheckandstatus. The review's chain (wrapper script edits the config,chock syncapplies it) is now refused atsync.agent_signal()isstop_agent_signal()'s rule (the latter is gone, its two callers useagent_signal):CHOCK_AGENT_COMMIT=0unsets that one variable and clears no vendor marker.CHOCK_ALLOW=x CHOCK_AGENT_COMMIT=0 CLAUDECODE=1 git commiton an ask gate exits 1;CHOCK_ROLLOUT=observe CHOCK_AGENT_COMMIT=0withCLAUDECODE=1still blocks; a person's shell (no marker) keeps both.CHOCK_ALLOW=<id>line; an agent is told to ask the person and is given no recipe.policy_status(..., committed=)disables a policy for an agent only when the working tree and HEAD list it (the stricter-of-both reading of "read from the HEAD-committed file", the waycommitted_rolloutcaps rollout). Applied inchock_guidance(advise._enabled), the one runtime reader ofpolicies.disabledat an agent event;sync/recompile/autocompile, the other readers, are now person-only.docs/enforcement-surfaces.md,spec/gate-dsl.md,docs/agentic-risk-coverage.mdanddocs/decision-log.mdstated the old hatch rule and now state the new one.chock sync, since that command refuses an agent's shell;tests/test_sessionstart_arm.pypins it and the Claude Code runtime golden is regenerated.Tests changed because the fix is right (the plan's rule):
test_an_explicit_off_wins_over_every_marker,test_the_escape_hatch_lets_a_person_commit_in_an_agents_terminal,test_a_person_in_an_agent_terminal_answers_with_the_escape_hatch,test_the_escape_hatch_answers_from_an_agent_terminaland theCHOCK_AGENT_COMMIT=0 + CLAUDECODE=1 -> personrow oftest_a_git_hook_line_names_the_actor_by_the_actor_ruleasserted the escape hatch the review's B2 names. Each now asserts the opposite, with a bare-shell case beside it.test_a_disabled_policy_gives_no_guidancewrote an uncommitted disable; it is now a committed one, plus a test that the uncommitted one changes nothing. New:tests/test_person_only_commands.py(46 cases).Needs a person:
.chock/bin.gate.pyis assembled fromgate/runner/*.pyandclaude_code.pycarries the SessionStart text, so this PR makes both stale, andchock sync --repo .(the regen) is exactly what this PR refuses to an agent. CI's "Compiled artifacts match their manifests",chock check --only validate(compiled_drift),chock check --only verify,tests/test_compiled_freshness.pyandtests/test_runner_selfcontained.py::test_vendored_gate_py_matches_sourceare red until someone runs, from their own shell on this branch:The diff should be exactly
.chock/bin/gate.pyand.chock/bin/claude_code.py.Definition of done
chock check→ red onvalidate(compiled_drift) andverify(differs: bin/gate.py,bin/claude_code.py) until the regen above; evals, matrix, mechanisms, index and conflicts pass locallychock check --only matrixpasses; no matrix row changedchock sync --repo . --checkclean: pending the regen abovechock check --only verifyclean: pending the regen abovechock check --only indexpasses)pytest -qlocally: 4729 passed, 98 skipped, 2 failed (test_runner_selfcontained::test_vendored_gate_py_matches_source, the regen above;test_repo_standards::test_no_file_exceeds_line_budget, fixed in the second commit) withtest_compiled_freshness::test_this_repo_has_compiled_what_it_declaresdeselected (the regen above) andtest_wheel_install.pydeselected; new checks have attack (agent marker) + ordinary-data (person's shell) testspytest acceptance/ -c acceptance/pytest.ini --rootdir=acceptance: 21 passedchangelog.d/agent-cannot-switch-chock-off.mdaddedruff check .andruff format --check .cleanClaims
docs/enforcement-surfaces.mdstates the new actor rule.🤖 Generated with Claude Code