feat(automode): count operator form answers as user decisions in Claude Code auto mode#46
Merged
Merged
Conversation
…de auto mode Caucus routes a resolved operator form back as a message stamped origin=operator (server-set, peers cannot forge it), but Claude Code auto mode only trusts the human in the session, so it does not count that answer as a user decision. Add a caucus.automode module that detects whether the allow rule is installed and installs it atomically into .claude/settings.local.json, then runs claude auto-mode critique as the gate. setup() surfaces an automode block, gated on CLAUDECODE so non-Claude hosts get no noise. Expose the caucus-setup-automode console script. The rule scope is deliberately narrow (single low/medium soft_deny action, never high-severity or hard_deny) because the classifier sees only text and cannot verify the origin flag.
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.
Summary
Caucus routes a resolved operator form back into the room as a message stamped
origin=operator(the hub sets that flag, peers cannot forge it). To the supervising human it is an explicit decision, but Claude Code auto mode only trusts the human typing in the session, so by default it does not count an operator answer as a user decision. This bridges that gap, cleanly and without depending on theautomode-configskill.What it adds:
caucus.automode: detects whether the operator-answerallowrule is installed (pure file read, no subprocess), and installs it atomically into.claude/settings.local.json(backup,0600,$defaultspreserved).setup()now returns anautomodeblock (operator_rule: present | missing | unknown) so the agent can propose installing the rule. The block is gated onCLAUDECODE, so non-Claude hosts (Codex, Gemini, ...) get no irrelevant noise.caucus-setup-automodeconsole script:--applyinstalls the rule and runsclaude auto-mode critique(a first-class Claude Code command) as the gate, keeping a human in the loop.The rule itself is deliberately narrow. The classifier only sees rendered message text and cannot verify the
originflag, so the rule authorizes a single low or medium severity soft_deny action, never high-severity actions, and never lifts a hard_deny boundary. This scope was hardened directly in response to theclaude auto-mode critiquegate flagging the unbounded first draft as a prompt-injection surface.Test plan
pytest: 487 passing, including 12 new cases (detection across local/user scopes, idempotent install,$defaultssplice, backup, malformed JSON, host gating, CLI).caucus-setup-automodeend to end (check, apply, re-check) with the realclaude auto-mode critiquegate, hubGET /protocol, bridge boot, and a real MCP stdio client callingsetup()(theautomodeblock appears underCLAUDECODE=1and is absent without it).