Source factask_user_question declares no timeout budget. ASK_ABORTED does not prove an elapsed-time deadline.

One pending promise, four settlement edges.

Host authorityPending questionSessionId + rpcId
Human answerANSWERED
Close cardASK_CANCELLED
Execution signalASK_ABORTED
Provider disposalASK_ABORTED

Trace the owner, not the clock.

question/requested→card rendered→Stop / dispose / answer?→question/resolved→tool/result

Disconnect is not cancellation.

Browser generation Asocket closes

The Host pending map remains authoritative.

↻
Browser generation Bsame rpcId replays

The card can return without creating a new question.

Separate three operator policies.

CompatibilityNo deadline

Wait for answer or explicit cancellation.

AttentionReminder

Notify again without settling or changing rpcId.

SettlementDeadline

Return a distinct ASK_TIMEOUT—never approval.

Expiry must never selectthe first optionthe recommended optionapproval

Exactly one claimant wins.

answercancelaborttimeout→ remove pending synchronously →one settlement

Six release gates.

Unanswered waits have no implicit timerReconnect preserves rpcIdLate answers are fencedReminder never settlesTimeout is typed separatelyUncertain effects never auto-replay

Primary evidence.

Keep the full abort timeline.

The canonical guide adds current containment, typed settlement, restart semantics, notification authority, race fencing, failure routing, and twenty-two regression gates.

Read and star on GitHub