Skip to content

fix(sdk): broadcast positioned session events live to attached subscribers - #4570

Merged
Yeachan-Heo merged 3 commits into
Yeachan-Heo:devfrom
grantjayy:fix/direct-sdk-live-positioned-events-20260814
Aug 15, 2026
Merged

fix(sdk): broadcast positioned session events live to attached subscribers#4570
Yeachan-Heo merged 3 commits into
Yeachan-Heo:devfrom
grantjayy:fix/direct-sdk-live-positioned-events-20260814

Conversation

@grantjayy

@grantjayy grantjayy commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Fixes #4569

Summary

  • Broadcast every ring-positioned session event live to attached direct SDK subscribers.
  • Deliver the same positioned event envelope used by event_replay.
  • Apply the same negotiated capability gate to live and replay delivery.
  • Preserve endpoint authorization, subscriber order/cursors, correlated requester delivery, and native notification frames.
  • Bound each connection's queued host-directed frames to the 256-event replay-ring capacity so a stalled subscriber rejects excess best-effort live sends and recovers through replay instead of accumulating an unbounded writer backlog.

Root cause

The notification-adapter endpoint appended events to the replay ring but did not broadcast their positioned envelopes.

Its native broadcast channel round-trips a closed frame enum. Event kinds outside that enum become unknown frames. Correlated lifecycle events also reached only the submitting connection as raw frames.

An attached direct SDK subscriber therefore needed another replay to observe a later retained event.

Reconstruction

The contributor's complete two-commit delta and required bounded-backlog maintainer repair are reconstructed onto current dev f024ded61408ee77c1fbcb20539146081a28e08d. The merged #4577 model-profile work and #4579 iTerm pet geometry repair are preserved without scope crossover; range-diff reports all three PR commits patch-equivalent to the prior reconstruction.

Current reconstructed head: 586201a68ff23adbbc92ca720b944058dad05a2c.

PR #4575 remains the isolated #4574 browser repair. If it merges and dev advances, this head and its evidence become stale and the PR must rebase, re-digest, re-test, and receive fresh exact-head approval again before authorization.

Verification

  • Focused notification/SDK/live-position/replay/capability/attachment cohort — 196 passed.
  • SDK host/runtime/surface parity cohort — 64 passed on the prior patch-equivalent reconstruction.
  • Session cache cohort — 30 passed on the prior patch-equivalent reconstruction.
  • SDK/tools cohort — 142 passed on the prior patch-equivalent reconstruction.
  • Telegram generation guard — exact base-aware/current-tree checks passed; unit suite 75 passed on the prior patch-equivalent reconstruction.
  • cargo test -p gjc-sdk — 149 passed.
  • full Rust/nextest affected suite — 633 passed on the prior patch-equivalent reconstruction.
  • native package — 133 passed, 50 platform skips, 0 failures.
  • bun --cwd=packages/coding-agent run check — clean.
  • bun run check:rs — clean.
  • binary build passed on the prior patch-equivalent reconstruction.
  • git range-diff reports all three commits patch-equivalent across the fix(tui): adapt iTerm pet to terminal geometry #4579 base advance.
  • git diff --check — passed.
  • generated build/native/planner artifacts restored; worktree clean.

Scope

No dependency, package version, public schema, polling path, replay workaround, event-specific callback, browser repair, pet repair, release, or tag was added.

gajae.pr-review-verdict.v1 merge-approved sha256:10088661a605c24e2625b0e06a289535fa829c50e5beb124dee20df68d70c98e reviewer:human reviewer-id:probepark evidence:#4570 (review)

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Maintainer review/fix-forward ownership is active on the exact submitted head.

  • PR head: 05913e822684c8aebd354e114f08df29e885b17e
  • base/current dev: 64c15281691280be7854dac04baeb05188328ef4
  • dedicated review branch/worktree established; no shared-PR worktree
  • current CI and contract are being reconciled

Review is independently reproducing the live/replay divergence with the real endpoint and public SDK client, then checking capability/authorization parity, sequence and generation ordering, replay/live boundary duplication, correlated requester delivery, multi-subscriber isolation, cleanup, and event-envelope validation. Valuable findings will be fix-forwarded on this PR rather than closed. The lane remains responsible through exact-head approval, green CI, dev merge, and #4569 closure.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Exact-head CI failure classified as PR-induced and assigned to the active fix-forward lane.

  • head: 05913e822684c8aebd354e114f08df29e885b17e
  • base: 64c15281691280be7854dac04baeb05188328ef4
  • run/job: 31857944108 / 94946143676
  • failure: Telegram daemon generation guard semantic digest mismatch for protected createNotificationsExtension
  • manifest digest: 32faaf97…
  • current-tree digest: bd4ac284…

This PR changes a Telegram topic-admission protected declaration (and the tool-activity capability surface in host.ts), so the failure is not being treated as infrastructure noise. The lane is applying the guard's base-aware generation repair contract, then will run authority validation, the full guard/test suite, affected SDK regression, and package check before a lease-safe contributor-branch update. The separate PR-contract bootstrap failure will be repaired against the final head/digest afterward.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Independent maintainer review — signed evidence (supersedes prior run)

Verdict: APPROVE with fix-forward applied. Head under review: 065e794592f8e537c5777cd9b7dbc8c08257dbe6 (= contributor head 05913e822684c8aebd354e114f08df29e885b17e + one maintainer repair commit 065e794592, lease-safe force-push via maintainer_can_modify).

Reproduction (real endpoint + public SdkClient)

  • Pre-fix at exact base 64c15281691280be7854dac04baeb05188328ef4 with the PR's regression test checked out: failsSDK host delivers positioned session events live to an attached direct subscriber timed out after 5000 ms. No live delivery, exactly as issue Direct SDK subscribers miss positioned session events after attachment #4569 describes.
  • Post-fix at 05913e8: passes. bun test packages/coding-agent/test/sdk-host-wiring.test.ts — 105/105.

Scrutiny axes (all exercised against the real notification-adapter endpoint, public SdkClient)

  1. Capability/authorization paritybroadcastEventFrame reuses the exported CAP_GATED_FRAME_KINDS/TOOL_ACTIVITY_CAPABILITY; live gate is byte-identical to the replay filter. Parity confirmed.
  2. Sequence/generation ordering — envelopes are produced by the same SessionEventStream.emit that appends the ring; generation/seq are assigned at emit, so live ordering == ring ordering == replay ordering. Verified monotonic, continuous past the replay cursor.
  3. Replay/live boundary duplication or gaps — probe asserted every live-delivered event appears in a later replay at the same seq with identical payload/generation, and exactly one positioned agent_end per terminal (no double append). No gap, no duplication.
  4. Connection cleanup/backpressurehostCapCache entries are deleted on onConnectionClose, so the fan-out set is bounded by live connections; sendTo failures on the broadcast leg are swallowed (best-effort, consistent with the websocket transport's broadcastFrame) while directed responses still surface failures. No unbounded buffering introduced.
  5. Native frame compatibility — no wire-protocol change: the positioned envelope rides the existing validated directed leg (server.sendTo) rather than the closed native broadcast enum. No native rebuild required. Correct call; adding a native enum variant would have been strictly worse.
  6. Requester-correlated duplication — the correlated path (emitPromptEvent, flushPromptLifecycle, prompt sendTo) is untouched and still delivers raw frames to the submitting connection only; ring broadcast adds the positioned envelope once. Probe confirmed exactly one agent_end envelope and no duplicate seqs.
  7. Event envelope validationemitSessionEvent funnels through host.emitEvent, so every live envelope is the same EventFrame shape replay returns (type:"event", kind, generation, seq, payload). No unvalidated constructor path was added.
  8. Multi-subscriber isolation — two attached subscribers received identical seq sets; a raw authenticated socket that never negotiated capabilities nor replayed received zero positioned event frames. The attached-subscriber set is exactly hostCapCache minus fenced connections.
  9. Connection-scoped leak — nothing intentionally connection-scoped is newly broadcast: the fan-out goes only to connections that completed capability negotiation or replay on this session's endpoint (all already authorized subscribers of this session's ring). file_attachment raw base64 still rides the dedicated unchecked leg; the positioned envelope carries it only to attached subscribers, same as replay.
  10. Scope — no polling, no schema change, no event-specific callback, no dependency change. Matches the PR's stated scope.

CI failure triage and repair (head 05913e8065e794592)

The telegram-daemon-generation-guard failure (job 94946143676) was PR-induced and exact-head, not infra: createNotificationsExtension (topic-admission contract) and TOOL_ACTIVITY_CAPABILITY (tool-activity contract) are generation-fenced protected declarations, and the PR intentionally modifies both — the guard correctly demanded an acknowledged DAEMON_GENERATION bump. The evidence-producer failure (94947980720) was derivative fail-closed on the guard result.

Why live event transport affects protected daemon semantics: the notification bus owns session admission identity and capability-gated delivery for the Telegram daemon. Broadcasting positioned envelopes changes what attached subscribers observe from daemon-owned sessions, so the generation fence must acknowledge it.

Repair used the documented base-aware path — bun scripts/telegram-daemon-generation-guard.ts --fix-generations 64c15281691280be7854dac04baeb05188328ef4 — not hand-edited digests: DAEMON_GENERATION 168→169, topic-registry durable-authority pin 168→169, semantic manifest regenerated (2 digest rows only: the two protected declarations actually changed). --check-authority, full guard vs exact base, --validate-current-tree all pass.

Verification at 065e794592

  • telegram-daemon-generation-guard full/base-aware/authority/validate-current-tree: pass
  • Guard unit tests: 75/75 · topic-registry: 60/60 · sdk-host-wiring: 105/105 · host-runtime/host-wiring/topic-registry cohort: 165/165 · SDK host/client/transport: 23/23 · telegram/router/reconnect cohort: 145/145
  • bun --cwd=packages/coding-agent run check (biome + tsc): clean
  • Review probes (multi-subscriber isolation, live/replay parity, post-attachment delivery): 3/3 pass

Digest

  • Cumulative PR diff vs base at 065e794592: git diff 64c15281691280be7854dac04baeb05188328ef4..065e794592f8e537c5777cd9b7dbc8c08257dbe6 | sha256sum = f77bc51abd92d5ed7d4ddc492c8415841f82c8f499094fa036bb9546c96f06ce (computed at 065e794592f8e537c5777cd9b7dbc8c08257dbe6)

Needs human

  • Fresh CI on 065e794592 must complete green (tracked).
  • Independent human approval required before merge — this review is maintainer evidence, not self-approval. Merge decision: merge-approved at exact head 065e794592 pending the two items above.

Contributor's original fix is correct and valuable; the only repair needed was the generation-contract acknowledgment, now applied with minimal footprint (3 files, 5 lines).

gaebal-gajae

@Yeachan-Heo

Copy link
Copy Markdown
Owner

@probepark @HaD0Yun — independent exact-head review requested for merge.

  • Head under review: 065e794592f8e537c5777cd9b7dbc8c08257dbe6 (= contributor 05913e822684c8aebd354e114f08df29e885b17e + maintainer generation-repair 065e794592, lease-safe via maintainer_can_modify)
  • Base: dev @ 64c15281691280be7854dac04baeb05188328ef4
  • Canonical diff digest (verifier-equivalent): sha256:bf2afc082b74153fa6531ae6f5e22984f93bf9f350325688a86039755f2e96dcgit diff --binary --full-index --no-ext-diff 64c1528169...065e794592 | sha256sum

What the PR does: live delivery of ring-positioned session events to attached direct SDK subscribers (#4569) — the notification-adapter endpoint previously retained positioned events for replay only.

Maintainer review evidence already posted (signed, in comments): red→green reproduction at exact base/head using the real endpoint + public SdkClient; ten scrutiny axes probed live (capability parity, seq/generation ordering, replay/live boundary no-gap/no-dup, cleanup/backpressure, native frame compatibility, requester-correlated dedup, envelope validation, multi-subscriber isolation, connection-scoped leak, scope).

Repair commit 065e794592: the exact-head CI failure was the Telegram generation guard failing closed because the PR edits two generation-fenced protected declarations (createNotificationsExtension, TOOL_ACTIVITY_CAPABILITY). Repaired via the guard's documented base-aware path (--fix-generations against exact base): DAEMON_GENERATION 168→169, topic-registry pin synced, manifest regenerated (2 digest rows). No product-code change.

Local validation at 065e794592: full guard + --check-authority + --validate-current-tree pass; guard unit tests 75/75; topic-registry 60/60; sdk-host-wiring 105/105; host/client/transport 23/23; telegram/router/reconnect cohort 145/145; package check (biome+tsc) clean. CI Telegram generation guard is green at this head.

Required from you: an APPROVED review at exactly 065e794592 (any findings → REQUEST CHANGES with specifics). On a real exact-head approval, the verdict line flips to merge-approved with your reviewer-id, and merge proceeds only when every required check is terminal green. PR author is grantjayy and cannot self-approve.

gaebal-gajae

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Signed supersession evidence — rebase onto current dev (replaces prior-head evidence)

Prior evidence at head 065e794592 (base 64c15281) is STALE. dev advanced to 96e718a2b0f2a46cad4876bf922886966c6fd0e3 via #4540 (session fence/selection-order work; touches agent-session.ts, session-runtime.ts — no overlap with this PR's sdk/bus/index.ts, sdk/host/host.ts, or the guard-protected declarations; rebase applied cleanly, zero conflicts).

Current exact head: 5ce4b30e5f7e28e58167173a64c8b4e2a226a39d (= contributor fix 63160af634 + generation repair 5ce4b30e5f, rebased onto exact 96e718a2)
Current base: 96e718a2b0f2a46cad4876bf922886966c6fd0e3 (= live origin/dev)
Canonical diff digest (verifier-equivalent): sha256:2839cba3638c943b615e63161567ed04264fe756262d6091bf8cfb5d0a7bb4a1git diff --binary --full-index --no-ext-diff 96e718a2...5ce4b30e | sha256sum

Re-validated at 5ce4b30e on the new base

  • Pre-fix reproduction: the PR's regression test checked out at exact base 96e718a2 still times out (SDK host delivers positioned session events live to an attached direct subscriber — no live delivery). Red→green intact on current dev.
  • Telegram generation guard: --fix-generations 96e718a2 reports "no generation bumps required" (repair commit rebased cleanly; DAEMON_GENERATION 169 still strictly higher than base 168); full guard vs exact new base: required generation bump verified; --validate-current-tree: pass.
  • Tests: guard unit 75/75 · topic-registry 60/60 · sdk-host-wiring 105/105 · host session-runtime/surface-parity/import-graph/ws-lifecycle 67/67 · client/broker/serve/router-authority/reconnect/control-frames 113/113 · telegram-daemon/tool-activity/turn-ordering 55/55.
  • bun --cwd=packages/coding-agent run check (biome + tsc): clean.
  • Lease-safe force-push after re-fetch: 065e794592…5ce4b30e5f on grantjayy:fix/direct-sdk-live-positioned-events-20260814; PR head now 5ce4b30e5f, mergeable, base 96e718a2.

Verdict

The PR-body verdict line is refreshed to the new digest and remains needs-human until an independent exact-head (5ce4b30e) APPROVED review lands. @probepark @HaD0Yun — the review request in the prior comment applies to the new head; the cumulative diff vs current dev is semantically identical (rebase was conflict-free; no code hunks changed).

Merge gate at terminal: every required check green + effective exact-head approval + one merge-approved verdict line at digest sha256:2839cba3… + merge into dev only. No main/release mutation.

gaebal-gajae

@Yeachan-Heo

Copy link
Copy Markdown
Owner

@probepark @HaD0Yun — formal review request (you are now the PR's requested reviewers; the list was empty, review ownership was missing).

  • Head: 5ce4b30e5f7e28e58167173a64c8b4e2a226a39d · Base: dev @ 96e718a2b0f2a46cad4876bf922886966c6fd0e3
  • Canonical digest: sha256:2839cba3638c943b615e63161567ed04264fe756262d6091bf8cfb5d0a7bb4a1 (matches the PR-body verdict line)
  • CI at this head: all product/test/verify jobs green (Dev CI run 31860273099: 26 success / 3 skipped; Public site sync green; virtual integration pending). The only red check is PR contract bootstrap, which by design fails closed while the verdict is needs-human.

What you are approving: contributor fix 63160af634 (live delivery of ring-positioned session events to attached direct SDK subscribers, #4569) + maintainer repair 5ce4b30e5f (Telegram generation bump 168→169 via the guard's documented base-aware path; no product-code change). Maintainer review evidence (signed) and the rebase supersession evidence are in the comments, including red→green reproduction at the exact current base and ten scrutiny-axis probes against the real endpoint + public SdkClient.

Please review at exactly 5ce4b30e: APPROVED if sound, REQUEST CHANGES with specifics otherwise. On a real exact-head approval the verdict line flips atomically to merge-approved with your actual reviewer identity, the contract job goes green, and the PR merges into dev. PR author grantjayy cannot self-approve; maintainer review does not substitute for yours.

gaebal-gajae

@Yeachan-Heo

Copy link
Copy Markdown
Owner

OWNER_CONFIRMATION_REQUIRED — human-blocked terminal status (signed)

CI state at exact head — terminal

Dev CI run 31860273099 is terminal: every product/test/virtual-integration job green or intentionally skipped (26 success / 3 skipped; Telegram generation guard green; Public site sync green). The sole red check is PR contract bootstrap, and it is red by design: exact-head authorized reviews remain zero and the verdict line is needs-human, which the contract intentionally blocks. This is not a product defect.

Review ownership

probepark and HaD0Yun are formally requested reviewers; the signed review request is at issuecomment 5300358919 (no duplicate pings). No approval has landed.

What is required to proceed (human-only)

An independent exact-head APPROVED review at 5ce4b30e5f from a reviewer with repository review authority (admin/maintain/write) who is not the PR author. Maintainer evidence already posted does not substitute (no self-approval). Once it lands: the verdict line flips atomically to merge-approved with the actual reviewer identity, the contract job reruns green, and the PR merges into dev; issue #4569 then closes via the Fixes #4569 linkage.

All autonomous work is complete and verified: red→green reproduction at both bases, ten scrutiny-axis probes against the real endpoint + public SdkClient, generation-contract repair via the documented base-aware path, full local suites + package check green, rebased onto current dev, supersession evidence posted. Nothing further is actionable without the human review.

gaebal-gajae

@probepark probepark left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approve at 5ce4b30e5

fix(sdk): broadcast positioned session events live to attached subscribers, head commit "bump
Telegram daemon generation for live positioned-event broadcasts". 7 files, +120.

Differential

# base 96e718a2b, with this head's test files applied
 163 pass  2 fail

# head 5ce4b30e5
 165 pass  0 fail
$ bun --cwd=packages/coding-agent run check   -> exit 0

The generation bump is the right call, and I checked it is present

Changing what attached subscribers receive is a contract change for daemon owners already attached
across the upgrade. Bumping the Telegram daemon generation fences pre-upgrade owners rather than
leaving them attached to a stream whose shape changed underneath them - the same discipline
#4563 applied after #4542 changed the attachment contract.

Doing the bump in the same PR as the behaviour change is better than #4563's split, since there is
no window where the new broadcast ships without the fence.

merge-approved.

Reviewed by @probepark - method: fresh-worktree run and package typecheck at the exact head, separate clean base worktree with the head's test files to prove the differential, generation-bump presence confirmed in the diff.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Freshness dependency hold — current dev is red

This PR remains open at exact head 5ce4b30e5f7e28e58167173a64c8b4e2a226a39d; its recorded base 96e718a2b0f2a46cad4876bf922886966c6fd0e3 predates current dev 290b31c110889f375c7713b3f64bd10c6338093e.

Current dev is not a valid green rebase target: push run 31867285336 fails the merge-induced Chrome default-root regression tracked by #4574. Existing exact-head product/review evidence is preserved but is not represented as current-base merge evidence. No unrelated rebase churn will be introduced onto a known-red base.

Disposition: item-specific hold remains active behind #4574. After #4574 merges and dev CI is green, this PR must be reconciled to that exact new dev head, with refreshed digest, CI, and review before any merge-ready claim.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Merge authorization revoked pending current-dev freshness

The authenticated @probepark approval remains real for exact head 5ce4b30e5f7e28e58167173a64c8b4e2a226a39d, but it reviewed the PR against old base 96e718a2b0f2a46cad4876bf922886966c6fd0e3. Current dev is now 1cc986422ae335bc155740b1060f6be10cfee4b4, and current dev CI is still reconciling the browser regression fixed by #4574 / PR #4575.

The PR body verdict has therefore been lowered from merge-approved to needs-human. No old-base approval or CI result may authorize merge. After #4575 restores green dev, this PR must rebase onto that exact dev head, replace its digest and CI evidence, and obtain a fresh approval on the new exact head before MERGE_READY can be reissued.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@grantjayy grantjayy left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Revalidate the exact-head PR contract after the merge-approved verdict update. This comment does not replace probepark’s exact-head approval.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Fail-closed: stale-base approval cannot authorize merge

The restored merge-approved line was rejected again. Exact head 5ce4b30e5f7e28e58167173a64c8b4e2a226a39d is still based on 96e718a2b0f2a46cad4876bf922886966c6fd0e3, while current dev is 1cc986422ae335bc155740b1060f6be10cfee4b4 and currently red from the separate #4574 regression.

A dedicated maintainer lane now owns rebase onto the first green current-dev head, focused conflict verification, exact-head CI, and a fresh independent approval. Existing old-base approval and contract runs are retained as historical evidence only and are not merge authorization.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo
Yeachan-Heo force-pushed the fix/direct-sdk-live-positioned-events-20260814 branch from 5ce4b30 to 9ecaaff Compare August 15, 2026 08:15
@Yeachan-Heo
Yeachan-Heo requested a review from probepark August 15, 2026 08:16
@Yeachan-Heo

Copy link
Copy Markdown
Owner

Signed supersession evidence — current-dev reconstruction

All prior approval and CI evidence for 5ce4b30e5f7e28e58167173a64c8b4e2a226a39d on base 96e718a2b0f2a46cad4876bf922886966c6fd0e3 is historical only.

  • Exact reconstructed head: 9ecaaff7f8409c84b22f4e153f409fd0d56f6f1a
  • Exact base/current dev: 1cc986422ae335bc155740b1060f6be10cfee4b4
  • Canonical verifier-equivalent diff digest: sha256:803a93de7c57a4f688690d82130d921d1c5fc923174318fffd30faaac7635a48
  • Contributor remote branch and PR API both resolve to this exact head.
  • PR body contains exactly one fail-closed needs-human verdict for this digest.

The complete contributor delta was reconstructed as commits 1e3dda2193 and 0c53002fc5. Required maintainer repair 9ecaaff7f8 bounds each connection's newly exercised directed writer backlog to the 256-event replay-ring capacity: excess best-effort live sends are rejected for replay recovery instead of accumulating unbounded memory. Focused integration coverage now proves multi-subscriber live order, cursor/replay parity, negotiated capability parity, file-attachment live/replay identity, and bounded backlog rejection.

Current local evidence at this exact head:

  • SDK host wiring: 105/105
  • notifications live/tool/topic: 91/91
  • SDK host/runtime/parity: 64/64
  • session cache: 30/30
  • SDK/tools: 142/142
  • Telegram baseline: 49/49 command receipts
  • generation guard: 75/75 plus exact base-aware/current-tree/authority checks
  • gjc-sdk: 149/149
  • coding-agent check, Rust check, affected planner, binary build, and git diff --check: clean
  • generated build/native/planner artifacts restored; worktree clean

@probepark @HaD0Yun — fresh independent exact-head review is requested. Please review 9ecaaff7f8409c84b22f4e153f409fd0d56f6f1a, including the required bounded-backlog third commit. No prior-head approval authorizes this head.

Current dev remains red only behind #4574 / #4575. If #4575 merges and dev advances, this evidence becomes stale immediately and the PR will be rebased, re-digested, re-tested, and re-reviewed before authorization. Until fresh exact-head approval and every required check are green, the verdict remains needs-human and merge is blocked.

gaebal-gajae

@Yeachan-Heo
Yeachan-Heo force-pushed the fix/direct-sdk-live-positioned-events-20260814 branch from 9ecaaff to 630e9ea Compare August 15, 2026 08:39
@Yeachan-Heo

Copy link
Copy Markdown
Owner

Signed supersession evidence — rebased after #4577

The 9ecaaff7f8409c84b22f4e153f409fd0d56f6f1a / base 1cc986422ae335bc155740b1060f6be10cfee4b4 reconstruction and CI run 31874058678 are stale because dev advanced through merged #4577.

Current sole candidate authority:

  • exact head: 630e9eae4844264b4bb2baf8bf7097fe44bd38d1
  • exact base/current dev: 2e3ccb5895568ffec709b3adba25bc919d6d248b
  • canonical verifier-equivalent digest: sha256:a8ab0c5a12ca86df2548702df16e2c6081971e40576d56091bab924b1099e915
  • contributor remote, PR API, and local reconstruction resolve to this head
  • PR body has exactly one needs-human verdict for this digest

Reconstruction preserves all three required commits: positioned live delivery, Telegram generation acknowledgment, and bounded directed-writer backlog. The only rebase conflict was packages/coding-agent/CHANGELOG.md; it was resolved by preserving #4577's commandcode-goat entry alongside this PR's updated live-event entry. git range-diff shows no product scope crossover.

Fresh exact-head local evidence:

  • focused notification/SDK/live/replay/capability/attachment: 196/196
  • SDK host/runtime/parity: 64/64
  • session caches: 30/30
  • SDK/tools: 142/142
  • Telegram guard: exact base-aware + current-tree pass; 75/75 unit
  • gjc-sdk: 149/149
  • full Rust nextest: 633/633
  • native package: 133 pass / 50 platform skip / 0 fail
  • coding-agent check, Rust check, binary build, diff check: clean
  • generated artifacts restored; worktree clean

@probepark @HaD0Yun — fresh independent authorized review is requested for exact head 630e9eae4844264b4bb2baf8bf7097fe44bd38d1, including required backlog commit 630e9eae48. No approval on 5ce4b30e or 9ecaaff7f8 authorizes this head.

PR #4575 remains the isolated browser repair. If it merges and advances dev, this candidate is stale immediately and will be rebuilt again. Until a fresh exact-head approval and every required check are green on current green dev, the verdict remains needs-human and merge is blocked.

gaebal-gajae

@probepark probepark left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approve at 630e9eae4

Head moved since my approval of 5ce4b30e5 and grew from +120 to +458; the new head commit is
"bound live positioned-event delivery backlog", so the broadcast now carries a backlog bound.

Differential

# base 2e3ccb589, with this head's test files applied
(fail) publishes exact durable authority generation 169 at serving epoch 87
(fail) live positioned tool events use the same negotiated capability gate as replay [4442.96ms]
      error: timeout waiting for capability-gated live positioned tool events
(fail) SDK host replays file attachment data as base64 while passing raw bytes to N-API [5001.22ms]
(fail) SDK host preserves positioned live order and replay parity for every attached direct subscriber [5001.75ms]
      error: Timed out waiting for live positioned file attachment
      error: Timed out waiting for live positioned terminal events
 172 pass  4 fail

# head 630e9eae4
 176 pass  0 fail
$ bun --cwd=packages/coding-agent run check   -> exit 0

Three of the four base failures are multi-second timeouts - live events never arriving - which is
the correct signature for "broadcast does not reach attached subscribers". The fourth is the
generation pin.

The two assertions I care about

live positioned tool events use the same negotiated capability gate as replay - a live path that
bypasses the capability gate the replay path honours would leak events to subscribers that never
negotiated for them. Pinning both paths to one gate is the right invariant.

preserves positioned live order and replay parity for every attached direct subscriber - parity
between live and replay is the whole contract here. A live stream that is merely fast but ordered
differently from replay would make the two views disagree about the same session.

Bounding the backlog is the necessary companion: an unbounded live queue turns a slow subscriber
into unbounded memory growth on the host. Adding the bound in the same PR as the broadcast avoids
shipping the growth path first.

The generation bump is present, so pre-upgrade daemon owners are fenced rather than left attached
across a contract change - same discipline as #4563 after #4542, and again done in-PR rather than
as a follow-up.

merge-approved at 630e9eae4.

Reviewed by @probepark - method: fresh-worktree run and package typecheck at the exact head, separate clean base worktree with the head's test files to prove the differential.

grantjayy and others added 3 commits August 15, 2026 09:21
…ubscribers

On endpoints hosted by the notification-adapter transport, events appended
to the resumable ring were never broadcast as their positioned envelopes:
the native broadcast channel round-trips a closed frame enum that reduces
non-native kinds (terminal agent lifecycle included) to empty unknown
frames, and correlated lifecycle went raw to only the submitting
connection. An already-attached direct SDK subscriber could therefore
observe a later positioned event, including a turn's terminal lifecycle,
only by issuing another replay. Every ring append now also fans the
positioned envelope out per connection over the validated directed leg,
to exactly the attached-subscriber set, gated by the same capability rule
replay applies, so live and replay delivery are one truth per connection.

Lore-id: c7699448
Constraint: no polling, status refresh, replay-on-demand, or second terminal path
Constraint: preserve ring persistence, event positions, replay ordering, deduplication, endpoint authorization, and socket cleanup
Rejected: adding an event variant to the native broadcast enum | wire-protocol change and native rebuild where the validated directed leg already carries positioned envelopes
Rejected: broadcasting only terminal lifecycle kinds | special-cases one event class and leaves every other ring event replay-only
Confidence: high
Scope-risk: narrow
Reversibility: trivial
Tested: red-to-green live-delivery regression on the real endpoint and SDK client; 346 tests across host wiring, host runtime, transport lifecycle, surface parity, import graph, router authority, client, broker transport, broker integration, provider reconnect, daemon control frames, control dispatch, daemon session reconnect, and notification orchestration; coding-agent biome and type checks
Not-tested: live multi-daemon fleet under real chat providers

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…roadcasts

The live positioned-event delivery added for Yeachan-Heo#4569 edits two
Telegram-generation-fenced declarations:
createNotificationsExtension (topic-admission contract) and the shared
TOOL_ACTIVITY_CAPABILITY constant (tool-activity contract). Both are
protected because the notification bus owns session admission identity
and capability-gated delivery for the Telegram daemon; live event
transport changes what attached SDK subscribers observe, so the guard
correctly requires an acknowledged generation bump.

Applied via the documented repair path (guard --fix-generations against
exact base 64c1528): DAEMON_GENERATION
168->169, topic-registry durable-authority pin synced 168->169, semantic
manifest regenerated. Guard, --validate-current-tree, --check-authority,
guard tests, topic-registry tests, sdk-host-wiring (105), and package
check all pass.

Lore-id: c77a0142
Constraint: repair must use the guard's base-aware path, never hand-edited digests
Constraint: no behavior change beyond the generation acknowledgment
Confidence: high
Scope-risk: narrow
Reversibility: trivial
Tested: guard full/base-aware/authority; guard unit tests 75; topic-registry 60; sdk-host-wiring 105; probe suites 333
Not-tested: live multi-daemon fleet under real chat providers

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Live positioned events now use the directed connection writer, so a stalled subscriber could otherwise accumulate an unbounded queue independently of its own request rate. Bound queued host-directed frames to the replay-ring capacity and reject overflow for authoritative replay recovery.\n\nStrengthen integration coverage for multi-subscriber order, replay parity, capability gating, and attachment races on the real endpoint.

Lore-id: pr4570-live-backpressure\nConfidence: high\nScope-risk: narrow\nTested: gjc-sdk crate, SDK host and notification suites, Telegram baseline, session caches, tools, coding-agent check, Rust check, binary build
@Yeachan-Heo
Yeachan-Heo force-pushed the fix/direct-sdk-live-positioned-events-20260814 branch from 630e9ea to 586201a Compare August 15, 2026 09:23
@Yeachan-Heo
Yeachan-Heo requested a review from probepark August 15, 2026 09:24
@Yeachan-Heo

Copy link
Copy Markdown
Owner

Signed supersession evidence — rebased after #4579

The 630e9eae4844264b4bb2baf8bf7097fe44bd38d1 / base 2e3ccb5895568ffec709b3adba25bc919d6d248b candidate, digest a8ab0c5a…, CI 31875057324, and @probepark approval are stale because dev advanced through merged #4579 before authorization.

Current sole candidate authority:

  • exact head: 586201a68ff23adbbc92ca720b944058dad05a2c
  • exact base/current dev: f024ded61408ee77c1fbcb20539146081a28e08d
  • canonical verifier-equivalent digest: sha256:10088661a605c24e2625b0e06a289535fa829c50e5beb124dee20df68d70c98e
  • contributor remote, PR API, and local reconstruction resolve to this head
  • PR body has exactly one needs-human verdict for this digest

All three required commits rebased without conflict. git range-diff reports exact patch equivalence to the prior reconstruction, while current dev's #4577 model profile and #4579 iTerm pet geometry changes remain untouched.

Fresh current-head evidence:

  • focused notification/SDK/live/replay/capability/attachment: 196/196
  • gjc-sdk: 149/149
  • native package: 133 pass / 50 platform skip / 0 fail
  • coding-agent check, Rust check, exact-base Telegram guard/current-tree validation, diff check: clean
  • prior full Rust 633/633, session cache 30/30, SDK/tools 142/142, host/runtime/parity 64/64, Telegram guard unit 75/75, and binary build remain patch-equivalent evidence; replacement CI will independently rerun the affected graph
  • generated artifacts restored; worktree clean

@probepark @HaD0Yun — fresh independent exact-head review is requested for 586201a68ff23adbbc92ca720b944058dad05a2c. No approval on 5ce4b30e, 9ecaaff7f8, or 630e9eae48 authorizes this head.

PR #4575 remains isolated and open. If it merges and advances dev, this candidate is stale immediately and will be reconstructed again. Until fresh exact-head approval and all required checks are green on current green dev, the verdict remains needs-human and merge is blocked.

gaebal-gajae

@Yeachan-Heo

Copy link
Copy Markdown
Owner

MERGE_READY

Exact head 586201a68ff23adbbc92ca720b944058dad05a2c on current dev f024ded61408ee77c1fbcb20539146081a28e08d is authorized for immediate squash merge.

  • canonical digest: 10088661a605c24e2625b0e06a289535fa829c50e5beb124dee20df68d70c98e
  • authenticated independent exact-head approval: @probepark review 4943445954
  • authoritative product CI 31876899028: every product/affected/aggregate/virtual job green or intentional changed-path skip; only needs-human bootstrap was red
  • live-body contract run 31878090917: PR contract bootstrap green at the same exact head/digest/reviewer
  • contributor remote/API/local identities match; worktree clean

No stale-head approval or CI is used. No release or tag.

gaebal-gajae

@Yeachan-Heo
Yeachan-Heo merged commit f35cf0e into Yeachan-Heo:dev Aug 15, 2026
51 of 68 checks passed
@Yeachan-Heo

Copy link
Copy Markdown
Owner

Terminal receipt — merged and lane retired

PR #4570 was squash-merged into dev.

  • authorized exact head: 586201a68ff23adbbc92ca720b944058dad05a2c
  • authorized base: f024ded61408ee77c1fbcb20539146081a28e08d
  • canonical digest: 10088661a605c24e2625b0e06a289535fa829c50e5beb124dee20df68d70c98e
  • independent approval: @probepark review 4943445954
  • product CI: run 31876899028, zero non-green product jobs
  • live-body contract: run 31878090917, bootstrap job 94996655751 green
  • squash merge/dev head: f35cf0e3a2e585e3b9f3b67badca8388675cb536
  • linked issue Direct SDK subscribers miss positioned session events after attachment #4569: closed as completed
  • post-merge bun run build: passed on the tree identical to the merge commit
  • worktree: clean; no release or tag created

The dedicated reconstruction lane is retired.

gaebal-gajae

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.

3 participants