mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-12 19:13:28 -10:00
A goroutine dump of a run "stuck for 33 minutes" showed the agent parked forever in executeToolCall -> requestPermission, blocked on the TUI's decision channel. Root cause: a shell command whose sandbox decision was Allow but which requested additional sandbox permissions (sandbox_permissions: with_additional_permissions) made shouldRequestPermission block on OnPermissionRequest, yet buildPermissionEvent stamped the event Action=allow. The TUI's permissionRequestMsg handler only rendered/resolved Action=prompt requests and silently dropped everything else — so the decide callback was never called, the agent waited on a channel nothing would signal (no ctx cancellation on the active run), and the UI showed "Working" with no prompt and zero network activity. Intermittent and model-dependent: gpt-5.5's folder-creation command set the additional-permissions flag, glm's did not, which is exactly why one hung and the other ran clean. Two-part fix: - agent (buildPermissionEvent): an additional-permissions request is an ELEVATION the user must consent to, even over a sandbox Allow, so mark it Action=prompt (matching shouldRequestPermission's own condition). It now surfaces as a real prompt instead of a dropped auto-allow. - tui (permissionRequestMsg handler): enforce the contract that a blocked agent ALWAYS gets a decision. A non-prompt action resolves immediately and FAILS CLOSED (deny; cancel stays cancel) so the UI can never silently grant an unsurfaced permission; a superseded-run (runID mismatch) resolves as cancel so its parked goroutine unblocks without depending on ctx-cancel ordering. Matches the ACP handler's always-resolve, fail-closed contract. Red-green: reverting the tui branch reproduces the deadlock (decide never called); reverting the agent override reproduces Action=allow. End-to-end against a mock backend emitting the exact triggering tool call, the real TUI now renders the permission prompt and the run completes on approval, where before it parked forever.