fix(agent-loop): order admission publication and gate idle on committed turns

Three ordering fixes on the admission and settlement boundaries.

kick() installs the abort owner, marks the interval busy (running is
emitted before any listener can observe the claim), and installs the
pending done BEFORE publishing agent/inbox/dequeue: a dequeue listener
that cancels or disposes now finds live cancellation and quiescence
ownership instead of the previous activity's settled state, and claimed
prompt admission — including asynchronous prompt-submit hooks — sits
inside the running interval where cancel routing can reach it. The
admission-rejected path yields one microtask before continueOrIdle so
the idle transition cannot fire inside send()'s synchronous extent.

agent/idle now names only committed turns: a run that aborts or fails
before its turn/start commits exits without the notification, since
there is no durable turn/end for settlement consumers to act against.
The event's JSDoc states the narrowed contract.
This commit is contained in:
_Kerman
2026-07-26 18:30:26 +08:00
parent 5e8225505c
commit 2bc994900b
2 changed files with 31 additions and 5 deletions
+4 -2
View File
@@ -379,8 +379,10 @@ declare module 'cordis' {
/**
* One drain chain reached its terminal turn: that turn's `turn/end` is
* already committed. Automatically recovered failed turns do not emit this
* notification. `reason` says why; model-request recovery is exhausted when
* an error reaches it.
* notification, and neither does a run that aborts or fails before its
* `turn/start` commits — there is no durable turn to settle against.
* `reason` says why; model-request recovery is exhausted when an error
* reaches it.
* @param agent - the agent whose turn closed.
* @param turn - the terminal turn number.
* @param reason - why the terminal turn ended, with live error facts when it failed.