Skip to content

feat(continuation): extract post-compaction delegate dispatch helper#360

Closed
cael-dandelion-cult wants to merge 1 commit intocael/325-canonical2from
cael/343-queue-drain-budget
Closed

feat(continuation): extract post-compaction delegate dispatch helper#360
cael-dandelion-cult wants to merge 1 commit intocael/325-canonical2from
cael/343-queue-drain-budget

Conversation

@cael-dandelion-cult
Copy link
Copy Markdown

Summary

Why

This is the prince-driven comparison lane for #343 queue-drain-budget work. It is intentionally narrower than the gpt2/codex sibling lane: this PR isolates the stage-1 extraction so the cohort can compare a minimal helper-first shape against the fuller queue-correctness/cap lane.

What changed

  • adds post-compaction-delegate-dispatch.ts
  • moves inline chain-budget + spawn logic out of agent-runner.ts
  • adds focused tests for helper outcomes, budget gates, and re-stage/error paths
  • includes NOTE.md with the stage-1/stage-2 rationale and follow-up sketch

Verification

  • pnpm test src/auto-reply/reply/post-compaction-delegate-dispatch.test.ts src/auto-reply/reply/agent-runner.misc.runreplyagent.test.ts src/auto-reply/reply/post-compaction-context.test.ts src/auto-reply/reply/session.test.ts src/auto-reply/continuation-delegate-store.test.ts
    • 169 passed

Comparison surface

Sibling lane with fuller queue-model repairs:

  • frond-scribe/20260424/candidate-gpt2-354-codex-fixes

This PR exists so the cohort can byte-compare the narrower extraction against the more complete repair lane and decide whether to converge, cherry-pick, or supersede.

…rtable helper

Stage 1 of #343 / #332 Item B path B (move chain-budget enforcement out of
agent-runner inline loop). Per-delegate chain-budget evaluation and the
spawnSubagentDirect call live in src/auto-reply/reply/post-compaction-delegate-dispatch.ts;
agent-runner's post-compaction release block becomes a thin aggregator
over the helper's discriminated outcomes. Same log strings, same system
events, same re-stage trigger.

Stage 2 (substrate-side payload kind + queue-drain delivery) is sketched
in NOTE.md; the helper is the structural prerequisite that makes that
follow-up tractable without a sprawling refactor.
@cael-dandelion-cult cael-dandelion-cult changed the base branch from main to cael/325-canonical2 April 27, 2026 00:19
@chatgpt-codex-connector
Copy link
Copy Markdown

💡 Codex Review

const bracketDelegateOffset = continuationSignal?.kind === "delegate" ? 1 : 0;
const compactionBudget = Math.max(0, maxCompactionDelegates - bracketDelegateOffset);
const releasedCompactionDelegates = allCompactionDelegates.slice(0, compactionBudget);

P2 Badge Base compaction budget on actual bracket dispatch result

compactionBudget is reduced whenever continuationSignal?.kind === "delegate", but this runs before bracket continuation dispatch is attempted. If that bracket delegate is later rejected (chain cap, cost cap, or spawn refusal), we still reserve its slot and permanently drop post-compaction delegates via slice(0, compactionBudget), even though no delegate was actually spawned. This causes silent delegate loss in turns where compaction and a rejected bracket delegate happen together.


const originalCompactionChainCount = activeSessionEntry?.continuationChainCount ?? 0;
let currentCompactionChainCount = originalCompactionChainCount;
const compactionChainStartedAt =

P2 Badge Include delayed reservation hops in compaction chain budget

Post-compaction dispatch initializes currentCompactionChainCount only from persisted session state and does not account for outstanding delayed continuation reservations. The bracket/tool paths guard against this with highestDelayedContinuationReservationHop(...); without the same guard here, post-compaction delegates can reuse already-reserved hops, allowing additional delegates to run beyond the intended chain cap when delayed timers fire later.

ℹ️ 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".

@cael-dandelion-cult
Copy link
Copy Markdown
Author

Closing as superseded by #354 (1870a84f32 on cael/325-canonical2)

Byte-walked this branch (cf6e62e223) against the landed 1870a84f32. Going Option B (close as superseded) — the merged path is a strict architectural superset of what this PR proposed.

Convergence (low signal)

Both lanes agreed on the direction: extract the post-compaction delegate path out of the inline agent-runner.ts flow and into post-compaction-delegate-dispatch.ts with focused tests.

Divergence (the real finding)

The abstraction picked differently, and the landed shape is the better one:

  • This PR (mine, 142 LOC helper)helper-around-inline-flow. Extracted exactly two surfaces:

    • evaluatePostCompactionChainBudget(...){ allow: true } | { allow: false; reason: "chain-length" | "cost-cap" }
    • dispatchPostCompactionDelegate(...) — single-delegate spawn
      Stage-1 only; preserved existing inline drain/persist/lifecycle semantics.
  • Landed [PARALLEL] feat(continuation): substrate-native chain-budget extraction (path-b) #354 (660 LOC helper)substrate-queue-native. Full extraction of the queue-model surface:

    • normalizePostCompactionDelegate
    • persistPendingPostCompactionDelegates / takePendingPostCompactionDelegates
    • buildPostCompactionLifecycleEvent
    • deliverQueuedPostCompactionDelegate / drainPostCompactionDelegateDeliveries
    • dispatchPostCompactionDelegates
      Plus substrate plumbing in session-delivery-queue (storage, recovery), server-restart-sentinel, and substrate-capability-registry.

The landed lane also lands all three Codex P1/P2 repairs at the substrate layer (drain-filter unfiltered retries, persist-rethrow on chain-state failure, releasedDelegatesqueuedDelegates rename).

Verdict

No useful bytes to lift. The two lanes diverged at the abstraction boundary, and the merged abstraction supersedes mine — there is no piece of the helper-around-inline shape that adds signal back on top of substrate-native.

Closing without merge. Comparison material lives in this PR's diff for the cohort byte-walk record.

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