Skip to content

perf(coding-agent): coalesce child runtime updates - #1130

Closed
sethkarten wants to merge 11 commits into
perf/c01-identity-fencingfrom
perf/c02-event-coalescing
Closed

perf(coding-agent): coalesce child runtime updates#1130
sethkarten wants to merge 11 commits into
perf/c01-identity-fencingfrom
perf/c02-event-coalescing

Conversation

@sethkarten

@sethkarten sethkarten commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Stack position

This is the direct child of #1123. Please review and merge parent-first. Exact base 821a180763e2fd20b6134fe8e661e5308f6b4af0; exact head d2223258fa362e8fed5c5209cabf59d0eacc6e98.

What this delivers

  • Coalesces replaceable child recap/progress updates at the real AgentSession owner while preserving lifecycle transitions and exact terminal delivery.
  • Publishes structural child identity/name changes synchronously, flushing pending replaceable activity first, so observers never see a stale rename.
  • Bounds each daemon attachment to one pending catch-up update, with slow-client replacement and disconnect cleanup while healthy attachments remain live.
  • Coalesces interactive-mode progress rendering without changing status, terminal, or teardown semantics.
  • Keys replaceable UI progress by assistant/tool/child entity, drains its bounded 128-entry buffer without eviction, preserves cap-drained work across an immediately following structural replacement, surfaces flush failures through showError, and measures scheduler cancellation/fire conservation without double-counting.
  • Adds real integrated C02 evidence through 64 owned child runtimes, owner observers/hooks, loopback daemon attachments, interactive UI, terminal delivery, cancellation/restart/dispose cleanup, and B00B fresh-process verification.

Correctness boundaries

  • Terminal, lifecycle, assignment, identity, and structural-rename events are not replaceable.
  • Only recap/progress-style activity is coalesced.
  • No shared semaphore, global admission limit, local 429, provider batching, or model/provider hard-coding is introduced.
  • Role/model/provider/effort/topology configuration remains unchanged.

Validation

Reserved Linux runner, pinned image digest sha256:0f66af75e00e115a81a23a97c8cf16d6ed7d895d7dd7745971a03df8b4c4d70d:

  • Biome, root tsgo --noEmit, full build: pass
  • C02 owner/socket/interactive/evidence: 177/177
  • Exact C01 parent regression: 463/463
  • Process-stress: 6/6 runnable, 8 tag-skipped
  • B00B/swarm/RSS regression: 70/70
  • Linux RSS: 20/20 measured cells, 20/20 empty final groups, max sampling gap 31 ms
  • Raw measured C02 success: fanout/terminals 64/64, teardown pending 0, p99/max 13.32 / 13.21 / 13.48 ms across three measured repetitions
  • Final worktree clean at the exact head

The earlier remote attempt at af66e5aba remains failed because it exposed the stale structural rename. Raw attempts with 1883.24 ms at 8b9b191f3 and 1636.83 ms at this exact head are also retained as failures; the exact full gate and subsequent complete raw materialization passed. None is relabeled as success.

Evidence

  • Bundle SHA-256: 8c8cae69c6ebef708ad47ed82d3a4b309d8e93765826cd504d4a25d7fbf10e12
  • Evidence archive SHA-256: 40b051649091d3b73442a32e79504b32f367ec548c291de1ef08ea4512208c3d
  • Full gate log SHA-256: 154e6d7f9c9a973c416829a1806eb4c3fca842e461742d4cfde785cdab140126
  • Successful raw samples SHA-256: 055dfb34abb6cc77912c8c00a7a49d2ecdb7ab3b871cc34ae5d4fac631c2f7fe
  • RSS manifest SHA-256: 91468f1e0ba38a0eee127e8de724fec0c88dfdcb7141b696365e731b384a6512
  • Final report: coordination/REMOTE_C02_FINAL_VALIDATION.md
  • Integrated review: coordination/C02_FINAL_INTEGRATED_REVIEW.md — APPROVE
  • Structural rename review: coordination/C02_STRUCTURAL_RENAME_REVIEW.md — APPROVE
  • Bot remediation final review: coordination/C02_BOT_INTERACTIVE_INDEPENDENT_REVIEW.md — APPROVE

Review history

Independent owner, daemon attachment, interactive, evidence, structural rename, and exact integrated reviews all approve the published composition.


Note

Medium Risk
Changes observable delivery timing for running-child and UI progress (macrotask batching); lifecycle, terminal, and structural ordering are explicitly preserved but downstream code that assumed every snapshot was synchronous may need review.

Overview
Reduces event-loop churn by batching replaceable progress without changing admission, provider work, or terminal semantics.

AgentSession routes rlm_child_update through a per-child pending map and setTimeout(0) flush so recap/tool activity keeps only the latest snapshot per child. Queued/running edges, terminal statuses, and structural renames still publish immediately (with flush-before-terminal/rename ordering). Assignment C01 fences are rechecked at enqueue and flush; pending work is cleared on dispose, abort, and update restart. Event subscribers and afterToolCall hooks that throw are isolated with capped, content-free console.warn diagnostics ( beforeToolCall vetoes still propagate).

DaemonSupervisor replaces eager catchUpClient fan-out with scheduleClientCatchup (setImmediate per socket), cancelClientCatchup on disconnect/shutdown, and simplified compact-catchup dedupe so slow clients do not starve healthy attachments.

InteractiveMode coalesces replaceable message_update / tool_execution_update / running RLM child events by entity key (cap 128 distinct keys—overflow drains the batch instead of evicting), flushes retained progress before structural events and session replace/resync/stop, and routes flush failures through showError.

Adds unit/integration tests and a C02 integrated harness with signed swarm evidence metadata for owner, attachment, UI, and event-loop delay bounds.

Reviewed by Cursor Bugbot for commit d222325. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Coalesce child runtime updates in AgentSession and InteractiveMode to reduce redundant UI events

  • AgentSession now batches nonterminal rlm_child_update events per child, flushing them via a zero-delay timer; initial queued, first running, structural (session_info_changed), and terminal statuses are still published synchronously.
  • InteractiveMode gains a symmetric coalescing layer for replaceable progress events (assistant message updates, tool execution updates, child activity) bounded at 128 entries; progress is flushed before structural or terminal events and cancelled on stop/replacement.
  • DaemonSupervisor defers per-attachment catch-up work to the next event-loop turn via scheduleClientCatchup, debouncing drain and snapshot triggers and cancelling pending work on socket close and shutdown.
  • Observer exceptions in AgentSession._emit and afterToolCall hook failures are now caught and counted with bounded diagnostics (up to 10 warnings) instead of propagating.
  • Risk: all three coalescing paths change the timing of event delivery from synchronous to next-macrotask for non-edge updates, which could affect consumers that depend on immediate delivery of activity snapshots.

Macroscope summarized d222325.

Comment thread packages/coding-agent/src/modes/interactive/interactive-mode.ts Outdated
Comment thread packages/coding-agent/src/modes/interactive/interactive-mode.ts Outdated
Comment thread packages/coding-agent/test/swarm/c02-integrated-harness.ts Outdated

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 02d8c32. Configure here.

Comment thread packages/coding-agent/src/modes/interactive/interactive-mode.ts Outdated
@sethkarten

Copy link
Copy Markdown
Contributor Author

Thank you for the report and proposed work. This root cause is now covered by maintainer-owned stacked PR #1162, authored independently from upstream/main.

We did not inspect or reuse this PR's diff, branch, commits, implementation code, or tests; its public description/comments were used only as a bug report. To keep one review surface, this PR is superseded by #1162 and is being closed.

The complete review stack is #1158#1165. It is being left unmerged for human review after CI and review-bot findings are cleared.

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