You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Added
Thinking effort, per run. The launcher shows the levels each agent and model takes, with the default your CLI's own config uses marked, and stage_start takes effort. Codex (low to ultra, from its own model list; Codex reports the effort it applied and the run shows it), Muse (minimal to max, from its per-model variants) and Grok (--effort, accepted by the CLI; Grok's service was failing every run on the day this was checked, so its effect was not observed) apply it. Observed live: Codex reported the applied effort, and Muse used 30 thinking tokens at minimal against 1.2k at max on the same question. Until now ModStage never sent one, so every Codex run used whatever model_reasoning_effort your config says (medium here) however hard the task. An effort an agent cannot take is refused with what it does offer, never silently ignored: Antigravity carries its effort in the model name (High, Medium, Low) and OpenCode's ACP mode advertises no effort setting (checked live), so neither offers chips.
Thinking tokens are shown on the run card and in stage_status / stage_wait, so the effect of an effort is visible: the same question cost Muse 30 thinking tokens at minimal and 1.2k at max.
stage_agents lists each agent's levels and default.
Fixed
One message could still approve two actions when a reply was lost. If the bridge applied a stage_decide but its reply never arrived, the user's message was released and could then approve a second, different action. A request whose outcome is unknown (connection lost, or a 5xx) now keeps the message spent and tells Claude plainly that it could not confirm the result; the user answers again in a new message. Only a definite refusal from the bridge (a 4xx) or a failure before anything was sent gives the message back. Reported in review on the awesome-claude-code-mods listing; regression tests reproduce it on 0.0.13 and fail there.
Only a message that IS a decision counts as one.stage_decide used to read a decision out of any message that contained the right words, so "allow it just this once, not for the rest of this run" passed allow_session, "never allow that" passed allow, and "should I allow it? what does it do?" passed allow. A decision is now a message that consists of a decision ("allow it", "yes allow the pip install", "no, don't run that", "allow it for the rest of this run", "deny the curl"); questions, negations, conditions, a second instruction and extra words decide nothing. Allowing needs an explicit verb (allow, approve, accept): a bare "yes", "ok", "sure" or "go ahead" can answer any question Claude asked, and an agent can steer Claude into asking one, so it no longer approves anything. Denying stays easy ("no", "deny it").
A message answers only the approval it was sent for. It is bound, when the user sends it, to the one approval waiting, or, when it names an action ("allow the pip install"), to the one it names, and to nothing otherwise. So "allow the pip install" can no longer approve a different run's rm (even when the rm is the only one waiting), and a message the bridge refused (the panel answered first, the approval timed out) can no longer be reused on another approval. With several approvals waiting, "allow it" names none and Claude is told to ask which. A slow bridge never holds your prompt (the lookup gives up after 1.5 s and binds to nothing), and a newer message is never overwritten by an older one. A message that names an action must name that approval and nothing else ("allow codex nah", "allow pip install later", "allow it once for the run" answer nothing). Found by an independent adversarial review of the whole approval path (three rounds, the last with 30,888 generated phrases, none of which reaches the bridge carrying a decision the text does not state), after two upstream review rounds on the same gate.
Muse's edits showed no diff. Muse's edit tool takes find and replace, which the diff builder did not know. Found by running the real CLI.
Codex could not reach the coordination board. Its sandboxed shell cannot reach the local bridge, so when it chose modstage-cli instead of the board tools, the claim failed. Codex is now told to use the board tools only (the shell fallback stays for agents whose shell can reach the bridge).