Skip to content

fix(continuation): #987-completion β€” reset chain-budget for ordinary subagent-returns (#989-P2-1)#992

Merged
scribe-dandelion-cult merged 1 commit into
frond-scribe/20260609/assembly-token-wiringfrom
codeagent/989-p2-reset-gate
Jun 11, 2026
Merged

fix(continuation): #987-completion β€” reset chain-budget for ordinary subagent-returns (#989-P2-1)#992
scribe-dandelion-cult merged 1 commit into
frond-scribe/20260609/assembly-token-wiringfrom
codeagent/989-p2-reset-gate

Conversation

@scribe-dandelion-cult

Copy link
Copy Markdown

Completes the #987 doom-lock cure (#989, merged). Closes the residual Codex P2 on #989: figs's n/200 "195-forever" can still bite via the ordinary-subagent-return path.

The hole

#989's reset gate is gated on !isContinuationWake, preserving the chain-budget on continuation-wakes. But subagent-announce.ts set continuationTrigger: "delegate-return" for every subagent completion β€” including ordinary inter-session subagent calls that are NOT in-chain continuation hops. So the gate treated an ordinary subagent-return as an in-chain wake β†’ skipped the reset β†’ a long-lived session's stale continuationChainCount persisted β†’ a continuation elected from that fresh completion was rejected against the old cap. The #987 fix was incomplete for the non-continuation external turn that arrives as an ordinary subagent-return.

The fix (distinguish the two return-kinds at the trigger)

Mint a new subagent-return trigger for ordinary inter-session subagent completions, distinct from delegate-return (kept for in-chain [continuation:chain-hop:N] returns):

run-provenance keeps subagent-return heartbeat-equivalent + continuation-chain fire-reason β€” only the reset-gate classification changes. Protocol enum (gateway-protocol) + RFC doc (continue-work-signal-v2.md) updated.

Diff

11 files, +286/-83: subagent-announce.ts (+test), get-reply-run.ts (+media-only test), get-reply-options.types.ts, agent-runner.ts (+work-span test), run-provenance.ts (+test), gateway-protocol/schema/agent.ts (enum), continue-work-signal-v2.md (RFC).

Gate status

  • All 5 changed/added test files GREEN (subagent-drain, work-span incl new fix(continuation): reset chain budget on fresh non-wake turn-entry (#987)Β #989-P2, run-provenance, get-reply-run media-only, gateway-protocol schema).
  • Full-suite (88 shards via test-projects.mjs): 83 pass / 5 fail β€” all in the known pre-existing baseline-env set (model-selection / memory / secrets / telegram / deadcode-pnpm), none in changed files.
  • tsgo:core rc=0, oxlint clean.

Review

πŸͺ¨ Rune + 🌊 Ronan β€” the doom-lock-completeness eyes: verify the trigger-split correctly distinguishes ordinary-subagent-returns (reset) from actual continuation-chain delegate-returns (preserve+cap), and the runaway-leash stays intact. Off assembly tip 3084bf16fc; merges clean with PR #991 (#988-sweep β€” no file overlap).

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

…989-P2-1)

#989 reset the chain budget at turn-entry gated on `!isContinuationWake`, so a
genuine external turn resets while a continuation-wake preserves the count. But
subagent-announce minted `continuationTrigger: "delegate-return"` for EVERY
inter-session subagent completion, not just actual `[continuation:chain-hop:N]`
continuation-chain hops. So the reset gate treated every ordinary subagent
return as an in-chain wake and skipped the reset β€” a long-lived session with a
stale at-cap `continuationChainCount` then rejected any continuation elected
from a normal subagent return (the #987 n/200 doom-lock, still open via the
ordinary-subagent-return path).

Distinguish the two at the source: an in-chain chain-hop return keeps
`delegate-return` (mid-chain wake, preserves the leash); an ordinary subagent
completion now carries the new `subagent-return` trigger, which get-reply-run
classifies as a non-wake (`isContinuationWake=false`) so the reset gate rewinds
the chain budget like any other external turn-entry. `subagent-return` stays
heartbeat-equivalent and `continuation-chain` fire-reason in run-provenance, so
only the reset-gate behavior changes. The runaway leash for genuine
continue_delegate chains is preserved.

Tests: get-reply-run maps subagent-return -> not a continuation wake;
subagent-announce mints subagent-return for ordinary completions and
delegate-return for chain hops; run-provenance preserves provenance; the #987
reset-gate tests stay green plus a new #989 at-cap doom-lock reset scenario.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 43ed057d29

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +1469 to +1471
? isContinuationChainDelegate
? "delegate-return"
: "subagent-return"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require trusted chain metadata before preserving budget

When an ordinary subagent task text happens to contain the internal marker [continuation:chain-hop:N] (for example, a user asks a subagent to inspect docs/logs containing that literal), this branch now tags its completion as delegate-return, so get-reply-run treats it as a continuation wake and skips the chain-budget reset. I checked the actual chain-hop spawn sites (agent-runner.ts, delegate-dispatch.ts, and the recursive spawn paths in this module) and they also set drainsContinuationDelegateQueue: true, so relying only on the untrusted task string leaves a residual #989 doom-lock path for ordinary completions; require trusted chain metadata as well before emitting delegate-return.

Useful? React with πŸ‘Β / πŸ‘Ž.

Comment on lines +1468 to +1472
const delegateReturnTrigger: ContinuationTrigger | undefined = continuationEnabled
? isContinuationChainDelegate
? "delegate-return"
: "subagent-return"
: undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Split silent return wakes before the direct path

This new subagent-return trigger is only passed to deliverSubagentAnnouncement, but the silent/targeted return branches above this block return before reaching it; for example an ordinary silentAnnounce + wakeOnReturn subagent still calls requestHeartbeatNow(... reason: "silent-wake-enrichment"), which heartbeat-runner.ts maps back to continuationTrigger: "delegate-return". Because silentAnnounce is a general spawn option for ambient enrichment and is not restricted to [continuation:chain-hop:N] tasks, those ordinary silent-wake completions still skip the reset gate and can reproduce the stale chain-budget doom-lock this change is meant to close.

Useful? React with πŸ‘Β / πŸ‘Ž.

Comment on lines +1469 to +1471
? isContinuationChainDelegate
? "delegate-return"
: "subagent-return"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update ordinary completion tests for the new trigger

This value changed the ordinary direct-announce path from delegate-return to subagent-return, but existing ordinary-completion coverage in src/agents/subagent-announce.format.e2e.test.ts still asserts continuationTrigger: "delegate-return" for non-chain-hop completions. In a checkout with dependencies this focused suite will fail even when the runtime behavior is correct, so the commit needs to update those expectations alongside the trigger split.

Useful? React with πŸ‘Β / πŸ‘Ž.

@scribe-dandelion-cult scribe-dandelion-cult merged commit a437ca7 into frond-scribe/20260609/assembly-token-wiring Jun 11, 2026
131 of 145 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant