Home: deliver local question answers to ACP (ask-6ef2624788)

TE
4d ago
+641-9

Home's local answerQuestion previously recorded an answer without delivering it to the agent. The cmux-tui daemon now validates the conversation answer, reserves its message, re-reads the pending ACP request, and forwards the existing native person-decision proof. It records answered only after ACP accepts delivery. A closed request, stale digest, missing proof, unavailable agent or refused delivery returns a final conversation_rejected result to Home instead of a silent store or an indeterminate retry.

Leo-ask: ask-6ef2624788

oh stuff yeah actually we should be able to surface permissions/multiple choice related things inside chief... idk if y'all have researched dot/grokbot but those are def thng to look into

NEXT Mac uses HomeService.homeSource = DaemonHomeSource through HomeSourceRouter for a local Chief. This PR implements that local daemon path in cmux-tui-core/src/server/conversation_question.rs; it does not change optchat-chief. Swift carries the optional AgentQuestionAnswer.decision envelope through its existing HomeOp.answerQuestion mapping. The daemon advertises conversation-question-delivery-v1; DaemonHomeSource refuses an answer through an older store-only daemon as question.delivery_unavailable.

The envelope holds the question as displayed, raw original request, sorted-key SHA-256 digest, ACP instance, option, nonce and person proof. Rust verifies the stored question and normalized raw request agree, then verifies the live request/digest/instance/nonce. It derives the actual harness answers from the validated selections; ACP verifies and spends the proof under its pending-request lock. Proofs never enter the stored answer or idempotency ledger. No conversation text is permission authority.

This preserves #22747 and #22941: no Chief approval gate, no agent-created person provenance and no unanswerable wait. #28846's digest-revalidation semantics are retained; Feed and #33385's owned files are untouched. Native question-capable gesture/proof issuance is a separate integration with #33385. This daemon piece fails closed without it (question.person_decision_required) and does not claim a completed phone/Messages flow. Generic ACP permission cards stay outside this question-only route. Wire/Cloud are unchanged; the Cloud server operation belongs in cmux-platform.

Validation: new Rust tests cover proof/answer forwarding, stale and changed questions, closed requests, unavailable agents, rollback on refusal, once-only delivery with ledger replay, visible final refusal codes, and unrelated writes during a reservation. Swift verifies envelope forwarding and legacy serialization. Current head: 132178e00441b988d4016ee8548aa1ae90f5ad44. Run 41618450179 passed the Rust tests (including all 8 link tests) at b95a62edb4ad96591f5cbf11cec42daed40d2919, then strict clippy found one redundant clone in a test fixture. This head removes that clone; corrected tests and strict clippy are running in https://github.com/manaflow-ai/cmux/actions/runs/41621343331. App compile passed and AgentQuestionDecisionTests passed (1 test) at b95a62edb4ad96591f5cbf11cec42daed40d2919; the production and Swift sources are unchanged at the current head. Static prepush checks and formatting pass.

Socket admission now uses the existing socket2 dependency to bound connection establishment and verify a peer, with a saturated accept-backlog regression. Delivery has three RPC calls with three-second reply waits and the existing link’s bounded writes; no store/SQLite lock is held over those calls. A per-message reservation refuses concurrent replacement and is released on success, error or unwind. The connection closes at completion; no timer or background poll is added. A lost delivery acknowledgement or persistence failure can leave the question pending locally after ACP consumed it; replay cannot answer another request because ACP spends the bound nonce and reports closed. No success is fabricated in that case.

Dependency: #33562 fixes ACP's existing dropped-receiver false success and adds the real dropped-asker regression test. This bridge maps its agent_gone refusal to Home's final rejection channel. End-to-end native issuance, visible rendering and device verification remain integration work; this PR adds no UI design or captures.

Prior art: #22747, #22941, #28846, #33385, #28273 and #23312 read; no overlapping open PR in the available file scan. design/multiplayer-chief.md governs the Home surface; no visual changes.

🤖 Generated with Codex

Agent session: agent session