docs(agent): plan the HITL approval fix (F-024) - #4845
Conversation
Root-cause and design workspace for the broken human-in-the-loop tool approval flow. The Claude permission gate fires but the playground shows no Approve/Deny prompt: the runner parks an 'ask' gate by replying reject to the harness, which makes Claude emit a failed tool call that the egress projects as tool-output-error, overwriting the approval-requested part. Adds docs/design/agent-workflows/projects/hitl-fix/ (README, context, research, plan, status) with the smallest-correct fix across the runner, egress, FE, and Pi permission model, plus an FE+SDK+live test plan. Design only; no code change. Claude-Session: https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🔸 Decision needed — HITL approval fix (F-024) The bug. Claude + an Ask rule + a tool: the gate fires but the playground shows no Approve/Deny prompt — the tool resolves to ERROR "User refused permission to run tool" and the run auto-denies. Pi can't do HITL at all (only Root cause (one line). The runner parks an Proposed fix. Runner: park WITHOUT sending Decision 1 — park mechanism.
Decision 2 — Pi HITL.
The one real fork: how Pi HITL should behave (Pi-1 now vs commit to building Pi-2). The Claude fix is unambiguous (Approach A). My recommendation: Approach A + Option Pi-1 now, with Pi-2 tracked as the real Pi HITL path. One empirical unknown (settled by the live test in the plan): whether ending the parked turn without Full design: |
What
Design-only workspace for fixing the broken human-in-the-loop (HITL) tool approval flow, QA finding F-024. No code change.
Adds
docs/design/agent-workflows/projects/hitl-fix/(README, context, research, plan, status).The bug (F-024)
Claude harness + an Ask permission rule + a gateway tool: the permission gate fires, but the playground shows no "Run this tool? Approve / Deny" prompt. The tool-call card resolves straight to ERROR: "User refused permission to run tool" and the run auto-denies. Park → approve → resume never triggers. Separately, Pi's "Permission policy" field offers only
auto/deny— noask— so HITL is not configurable for Pi at all.Root cause (across layers)
The renderer (
ToolPart.tsx), the AI-SDK egress (stream.pyemitstool-approval-request), and the cross-turn resume (HITLResponder+extractApprovalDecisions) are all correct. The break is one conflicting reply in the runner:askgate with a human surface,HITLResponder.onPermissionreturnsdenyto "park", andattachPermissionRespondermaps that tosession.respondPermission(id, "reject").rejectproduces a failed tool call ("User refused permission to run tool"), whichmaybeCloseTool(tracing/otel.ts) records as atool_result {isError:true}.tool-output-erroron the sametoolCallIdas theapproval-requestedpart, so the AI SDK merges and the error overwrites the approval prompt.Park (the surface signal) and
reject(the harness reply) contradict each other on the wire.Proposed fix (smallest-correct)
parkoutcome; on park, do not sendreject(end the turn with the tool pending), so theapproval-requestedpart is the last word. No wire change. (Fallback B: suppress the park-induced failedtool_resultin the otel layer.)askfor Pi in the form now (honest, tiny); track real Pi HITL via relay enforcement (open-issues S5.2) as a follow-up.Test plan covers runner unit + SDK egress/ingest contract + golden wire (unchanged) + live FE e2e (park → approve → resume) + a replay-test pin.
Decisions needed
See the pinned "Decision needed" comment.
https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc