Repository navigation
Studio chat approvals: follow-ups from #1975 review #2142
Copy link
Copy link
Closed as duplicate
Description
Follow-ups from the review of #1975 (Studio chat approvals, plan review, Escape). None block merge. Parent: #1848.
Worth fixing (non-blocking)
- Plan-verdict logic is duplicated and has diverged.
chat-workspace.tsx(planUnavailableReason,respondToPlan, separate in-flight/uncertain sets,viewedSessionIdguard) vsside-thread-panel.tsx(plan folded into the ordinary path, no uncertain state for plans). After an ambiguous failure, retry/Escape can be allowed on one surface and blocked on the other. Extract oneusePlanVerdictControlhook. -
chat-workspace.tsxis ~3400 lines. Move plan-continuation follow/reattach state intoplan-continuation.ts. - Pending-ask card ternary is copied at 3 sites (
chat-transcript.tsx,chat-workspace.tsx,side-thread-panel.tsx). Extract aPendingAskCard. -
resolvePlanAskmaps genericfailed_preconditionto 409 "stale" (apps/server/src/mecatl/chat.ts). Keep onlystale_run_control,ask_not_pending,not_awaiting_plan, or log the underlying code. - Docs: in
user-docs/building/deployment/studio.md, the newReview tool calls and plansheading sits above the unrelated "Review authorization" paragraph. - Test gaps: 500ms draft-clear boundary (499/500ms); held Escape (
repeat: true) cannot fire ask deny / plan iterate / panel / stop; verdict keys with a dialog or menu open (or state in docs that only Escape applies); a planted secret in ask args/diff.
Nitpicks
- Add
unmatchedApprovals()tochat-state.ts(themessage.tools?.some(approvalMatchesToolCall)check is repeated 7 times). - Use one key helper:
settledAskKeysusesrunId\0askId,approvalKeyuses a JSON tuple withsessionId. -
plan-continuation.ts: replace the hand-rolled AbortController/deadline/Promise.racewithAbortSignal.any([signal, AbortSignal.timeout(ms)]). -
chat-escape.ts: drop the redundantfocusinbranch inchanged(); hoistdisarm()and reuse it in the seconduseEffect. -
stalePlanAskreuses codestale_run_control, so clients cannot tell a stale plan ask from a stale permission ask. -
runtime.tscopyCapabilitieshardcodesstorageMigration: falseand derivesbashfromshell; add a comment or fix the schema. Checkdetail()'s newclient.server.compatibility()call does not add a round trip per request. -
ci.yml:STUDIO_REQUIRE_MECATED=1on the Playwright step is read only bymecated-mock.test.ts, not bychat-approval.spec.ts. Drop it or make the spec honour it. - Docs: the Escape paragraph duplicates the Keyboard shortcuts page; state once and link.
- Tests: malformed/missing args at card level, unmatched
callIdpermission ask, double-click sends one POST, confirmuseRealTimersinafterEachinchat-escape.test.tsx.
Fully or partially written by an AI agent.
Metadata
Metadata
Assignees
Labels
No labels
Activity
kantord commentedon Oct 14, 2026
Merged into #2303: all items were copied there (section B). Closing as a duplicate. Fully or partially written by an AI agent.