Repository navigation
feat(acp): ACP elicitation loop (ZOD078) - #101
Merged
Merged
Conversation
zooidbot
reviewed
Sep 30, 2026
zooidbot
left a comment
Collaborator
There was a problem hiding this comment.
Architect review against the ZOD078 PLAN. Verdict: matches the plan, no blockers. CI is green.
What I checked and found correct
- The SDK 1.5
client()app is used soctx.signalreaches the handler. The capability is advertised only whenonElicitationRequestis set, and only the Matrix transport sets it (decisions 1 and 5). AcpClient.onElicitation: when the upstream signal aborts, the handler throws, so the SDK answers-32800. A local abort (interrupt) answers{action:'cancel'}. Idle reaping is held viasetHumanRequestPending.ElicitationCorrelator: transitions out of pending are atomic and happen once. Terminal records are kept (bounded) so late answers get stale feedback.failemits nothing, so no orphanresolvedis published. It is the ZOD072PendingInputRegistrythroughopts.pendingInput ?? opts.elicitations, andstart-daemondoesn't pass a competingpendingInput. Good: there is no second pending-input concept.- Response path: responses bypass
enqueueTurn. The handler rejects agent/bot senders and checks room, thread andrequest_event_idbefore membership (getJoinedMembers). It validates only while the request is pending and usessettlefor first-wins. Forbidden responses are dropped with no feedback (decision 3). - Publication: it's chained on the send queue so prose lands above the card. The send queue waits on the card, not on the answer. Stable txnIds, 3 tries, and
resolvedwaits for the publish, so it can't race the card. - The typing refresh skips sessions with an open question, and typing comes back on the answer (decision 7).
/clearcancels only sessions with an open question (decision 4). Keep it that way. Widening ZOD039 to cancel every live turn on/clearis a separate decision and shouldn't ride on this PR.
Non-blocking, for the follow-on journal cycle (don't fix here)
- If
elicitation_resolvedfails all 3 tries, the agent carries on, but the card stays interactive and the web "awaiting your input" indicator stays up for good. Today that's only a log line. It's the same class as the restart orphan the follow-on journal cycle already owns, so I'll make sure that cycle covers "resolved not delivered" too. handleElicitationResponseis awaited inside AS transaction processing and can wait out the publish retries (up to ~1.5 s plus the send-queue tail) before it acks the txn. That's fine at current volumes. Just note it if txn latency ever shows up.
Merge order per the plan: this first, then zooid-ai/clients#46.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Agents can now ask humans a form question during an ACP turn and resume the same tool call after an eligible room member answers. Implements the live-loop cycle in ZOD078 PLAN.md.
Adds conditional ACP form capability on SDK 1.5, typed request cancellation, daemon schema validation, a pending-input correlator, and the four Matrix elicitation events. Responses bypass the turn FIFO, match the room/thread/published request, check current membership, and atomically accept the first valid response. Invalid answers receive field errors; interrupt, clear, task closure, and process exit cancel pending questions. Publication retries use stable transaction IDs, including answers arriving before a retried publication acknowledgement.
Accepted resolution events carry the confirmed values so other viewers and reloads can display the answer. Includes package changesets. The existing permission callback and session lifecycle facade remain covered by the previous tests.
Validation:
Paired web PR: zooid-ai/clients#46. Per the plan, review and merge the daemon first, then the web client. Live Claude smoke is reserved for Ori after merge. Restart journaling/reconciliation and the architect's retrospective are follow-on work, as specified by the cycle.