When a thread is a Crew Captain or a live seat, every question or approval its provider raises for me (tool-approval requests, and user-input questions such as Claude's AskUserQuestion or Codex's request_user_input) renders inline in that thread's composer. Captains and seats run while I'm somewhere else, so those prompts sit unseen and the Crew stalls. My rule: anything a Captain or seat needs from me goes to my Inbox, the same way Crew seat requests and agent asks already do. The one exception is the initial roster approval card, which stays inline above the Captain's composer (crews.md, gate placement).
This issue is the server half. The web Inbox and hiding the inline cards is #264.
Where it breaks:
- The Inbox (
apps/server/src/j5/a2a/HumanInboxService.ts) holds only ledger Exchanges, and Crew seat additions are merged in on the client (apps/web/src/j5/crew/crewProposals.logic.ts:25-28). Nothing reads projection.runtimeRequests for Crew threads, so provider approvals and questions never reach the Inbox.
- The only automatic Inbox producer for Crews is
crewFailureAlert.ts, and it handles run failures only.
What should change:
- A J5 read of pending provider requests (
runtime-request.updated, status pending, kinds approval and user_input, skipping auth_refresh and dynamic_tool_call as derivePendingThreadRequests does) on every thread that AgentCrewInstanceService.listInvolving resolves to a live Captain or seat. Each item carries the thread, its Crew and seat (or Captain), the request kind, and the payload needed to answer (approval options, or the questions with their choices).
- Serve it as its own Inbox source beside Crew requests, not as ledger Exchanges:
HumanInboxService.answer writes an A2A reply, not a provider response. Read the live state from the projection instead of copying it into a new table, unless a measured need appears.
- A J5 answer route under
/api/j5/... that authenticates with operate scope and dispatches runtime-request.respond (packages/contracts/src/orchestrationV2.ts:2461-2469), copying the server-side precedent in apps/server/src/mcp/toolkits/thread/handlers.ts:201-213. Answering a request that is already resolved, or that was answered inline on another device, is refused with a clear message and changes nothing.
- A request stops being listed once it is resolved or its Crew retires.
- No upstream files. Wire the read into the J5 runtime layer and the J5 contract in
packages/contracts/src/j5.ts.
Tests to ship:
- a pending approval on a seat thread is listed with its Crew and seat; a pending question on the Captain's thread is listed as the Captain
- a thread outside any Crew is never listed
- answering through the route resolves the provider request exactly once; a second answer, or an answer after an inline answer, is refused
- a retired Crew's requests leave the list
- drive the flow with receipts, never sleeps or polling
Done when every pending provider approval or question on a live Captain or seat thread can be read and answered through the J5 Inbox API, and only those.
Related criteria: crews.md AC9 ("a Crew's contact with the person goes through the inbox or its Captain").
When a thread is a Crew Captain or a live seat, every question or approval its provider raises for me (tool-approval requests, and user-input questions such as Claude's AskUserQuestion or Codex's request_user_input) renders inline in that thread's composer. Captains and seats run while I'm somewhere else, so those prompts sit unseen and the Crew stalls. My rule: anything a Captain or seat needs from me goes to my Inbox, the same way Crew seat requests and agent asks already do. The one exception is the initial roster approval card, which stays inline above the Captain's composer (crews.md, gate placement).
This issue is the server half. The web Inbox and hiding the inline cards is #264.
Where it breaks:
apps/server/src/j5/a2a/HumanInboxService.ts) holds only ledger Exchanges, and Crew seat additions are merged in on the client (apps/web/src/j5/crew/crewProposals.logic.ts:25-28). Nothing readsprojection.runtimeRequestsfor Crew threads, so provider approvals and questions never reach the Inbox.crewFailureAlert.ts, and it handles run failures only.What should change:
runtime-request.updated, statuspending, kinds approval anduser_input, skippingauth_refreshanddynamic_tool_callasderivePendingThreadRequestsdoes) on every thread thatAgentCrewInstanceService.listInvolvingresolves to a live Captain or seat. Each item carries the thread, its Crew and seat (or Captain), the request kind, and the payload needed to answer (approval options, or the questions with their choices).HumanInboxService.answerwrites an A2A reply, not a provider response. Read the live state from the projection instead of copying it into a new table, unless a measured need appears./api/j5/...that authenticates with operate scope and dispatchesruntime-request.respond(packages/contracts/src/orchestrationV2.ts:2461-2469), copying the server-side precedent inapps/server/src/mcp/toolkits/thread/handlers.ts:201-213. Answering a request that is already resolved, or that was answered inline on another device, is refused with a clear message and changes nothing.packages/contracts/src/j5.ts.Tests to ship:
Done when every pending provider approval or question on a live Captain or seat thread can be read and answered through the J5 Inbox API, and only those.
Related criteria: crews.md AC9 ("a Crew's contact with the person goes through the inbox or its Captain").