Summary
The mode/permission model carries four overlapping knobs in EffectiveModePolicy (crates/tui/src/tui/app.rs:1110-1119): allow_shell, approval_mode, trust_mode, auto_approve. Three of them co-vary in every mode, which is the structural source of the "UI says one mode but a different flag decides" bugs (#3733 Auto, #3735 YOLO-publish).
Current state (3 surviving modes after Auto deferral)
| Mode |
allow_shell |
approval_mode |
trust_mode |
auto_approve |
| Plan |
false |
Suggest |
false |
false |
| Agent |
prefs |
prefs |
prefs |
false |
| YOLO |
true |
Bypass |
true |
true |
YOLO sets three flags that all mean "approve everything."
What each knob really does
approval_mode (approval.rs:41-51): Suggest/Auto/Bypass/Never — the one genuinely meaningful control.
trust_mode (bool): enables sandbox workspace writes, skips the untrusted-workspace safety hold, and contributes to auto-approval (auto_approve || trust_mode, runtime_threads.rs:3296).
auto_approve (bool): skip prompts; fully covered by approval_mode == Bypass.
Proposal — collapse 4 → 2
approval_mode stays the single approve/ask/bypass/never control. Derive auto-approval from approval_mode == Bypass and delete auto_approve (remove the separate flag at app.rs:1117-1118 and its mirrors; replace auto_approve || trust_mode with approval_mode == Bypass || trust_mode).
trust_mode keeps its one distinct job — workspace-write capability + untrusted-workspace handling — and stops doubling as an approval flag.
allow_shell can likely be derived too (Plan = no shell; Agent/YOLO = shell), but keep for now if prefs need per-user shell toggle in Agent.
Why
Removing auto_approve as an independent flag eliminates the layer split that lets safety_floor's HoldForReview get silently bypassed (#3735) and that makes mode label and behavior disagree (#3733). One control = one source of truth.
Verification
Refs #3733, #3735, #3568.
Summary
The mode/permission model carries four overlapping knobs in
EffectiveModePolicy(crates/tui/src/tui/app.rs:1110-1119):allow_shell,approval_mode,trust_mode,auto_approve. Three of them co-vary in every mode, which is the structural source of the "UI says one mode but a different flag decides" bugs (#3733 Auto, #3735 YOLO-publish).Current state (3 surviving modes after Auto deferral)
YOLO sets three flags that all mean "approve everything."
What each knob really does
approval_mode(approval.rs:41-51):Suggest/Auto/Bypass/Never— the one genuinely meaningful control.trust_mode(bool): enables sandbox workspace writes, skips the untrusted-workspace safety hold, and contributes to auto-approval (auto_approve || trust_mode,runtime_threads.rs:3296).auto_approve(bool): skip prompts; fully covered byapproval_mode == Bypass.Proposal — collapse 4 → 2
approval_modestays the single approve/ask/bypass/never control. Derive auto-approval fromapproval_mode == Bypassand deleteauto_approve(remove the separate flag atapp.rs:1117-1118and its mirrors; replaceauto_approve || trust_modewithapproval_mode == Bypass || trust_mode).trust_modekeeps its one distinct job — workspace-write capability + untrusted-workspace handling — and stops doubling as an approval flag.allow_shellcan likely be derived too (Plan = no shell; Agent/YOLO = shell), but keep for now if prefs need per-user shell toggle in Agent.Why
Removing
auto_approveas an independent flag eliminates the layer split that letssafety_floor'sHoldForReviewget silently bypassed (#3735) and that makes mode label and behavior disagree (#3733). One control = one source of truth.Verification
approval_mode.HoldForReviewstill prompts (ties to YOLO mode silently approves publish actions (cargo publish / git push --tags), defeating safety_floor durable-review #3735).Refs #3733, #3735, #3568.