Address a fresh-eye review of the disposal/injection fixes:
- disposal now snapshots, clears, and marks disposed BEFORE emitting
agent/inbox/discard (mirroring cancel's snapshot→clear→emit), so a
re-entrant send/cancel from a discard listener throws 'disposed' or
finds an empty inbox instead of leaking or double-discarding an id.
The discard is unconditional (even on unpublished setup-rollback) to
match send's unconditional enqueue, keeping every id balanced.
- restore the turnRecorded guard on the idle-injection flush: a
turn/start rejected pre-commit (append reentrancy / internal-dispatch
veto) records nothing and owes no flush; the previous unconditional
flush emitted a phantom-turn agent/error. The isTurnOpen/turnRecorded
branches are reachable (reentrant inject from a session/event
listener) and now covered by a regression test rather than v8-ignored.
- rewrite the agent/inbox/discard event JSDoc to enumerate all three
emitters (cancel, terminal turn-stop, disposal) — every enqueued id
gets exactly one terminal dequeue-or-discard.
Per-file coverage stays 100%.
Address a second fresh-eye review of the review fixes:
- MAJOR: late steering that lands after runTurn returns terminally
stopped (e.g. during the post-turn flush) was drained by runLoop and
dropped without a discard, leaving a dangling outstanding id the
negative-only invariant can't catch. Emit agent/inbox/discard for it,
symmetric with the in-turn terminal-stop drop.
- remove the dead cancel() idle-settle branch: whenIdle's fast path
already resolves for a lone quiet item, so no waiter is ever left for
it to settle. Document why.
- gen-cordis-api classShape now drops private/protected/#private members
and strips getter/setter bodies, so Session no longer leaks private
fields and getter bodies into the model catalog.
- document that AgentMessage intentionally omits meta (durable-only).
Adds a regression test for the late-steering discard.
Resolve six review findings on the unified-send change:
- quiet (wakeup:false) queued items no longer un-park the driver; the
inbox distinguishes hasWakingQueued (drives the loop, idle/quiescence)
from hasQueued (anything to dequeue), so a lone quiet item parks at idle
and rides the next waking send. whenIdle/cancel settle off the waking
signal, so cancelling a parked quiet item no longer hangs whenIdle.
- SendOptions.meta on queued/steering sends now reaches the durable
user/message and steering/message (was dropped except on injection).
- a terminal agent/turn-stop that drops pending steering emits
agent/inbox/discard so the enqueue-dequeue-or-discard ledger balances.
- the loop-authored continuation reason is snapshotted and frozen like a
public send.
- gen-cordis-api collects exported classes (body-stripped) so the now-
abstract-class Agent and its transitive shapes reappear in the API
catalog.
Adds regression tests for each and re-records the affected snapshot.
Add a branded AgentMessageId assigned to each accepted send message and
returned from send/followup/steer/inject (was void). Rename the inbox
event payload InboxItemInfo to AgentMessage, carrying that id so a caller
can correlate a queued item with its enqueue/dequeue/discard events.
Replace send/steer/inject with one Agent.send primitive over the
(target × wakeup) matrix; followup/steer/inject become fixed-preset
alias methods on the now-abstract Agent class. Coalesce context/message
into user/message (injected context is a non-user source). Replace
agent/queued with agent/inbox/enqueue/dequeue/discard, add cancel
keepInbox, and add a FIFO-conservation invariant.