Skip to content

fix(acp): bound observer retention by bytes (#7987) - #9436

Merged
sanket1729 merged 1 commit into
mainfrom
sanketk/observer-byte-budget
Nov 13, 2026
Merged

sanket1729 merged 1 commit into
mainfrom
sanketk/observer-byte-budget

Conversation

@sanket1729

Copy link
Copy Markdown
Contributor

Replaces #9366 on a branch in this repository and resolves its conflicts with main.

Summary

The ACP observer kept up to 1,000 raw events in both replay and live buffers. Large valid messages could retain gigabytes before downstream trimming ran.

Fit telemetry before either buffer retains it. Cap replay at 4 MiB of serialized JSON and keep the existing live window. Its per-event limit bounds live JSON below 64 MiB.

Preserve the CPU and locking improvements from #9381: prepare large payloads and copy snapshots outside the replay lock. Finalize sequence and timestamp with publication. Account for that final metadata, including sequence digit-width changes, in the byte limit.

The tradeoffs are extra work per emit, shorter replay history for large events, and elided oversized telemetry. Agent protocol messages remain unchanged.

Related issue

Fixes #7987. Existing publisher byte limits act downstream of these buffers.

Testing

The opt-in probe exercises the real in-process emit, snapshot and stalled-subscriber paths:

CARGO_INCREMENTAL=0 CARGO_PROFILE_RELEASE_LTO=thin CARGO_PROFILE_RELEASE_CODEGEN_UNITS=4 \
  cargo test --release -p buzz-acp --lib observer::tests::retention_probe -- --exact --ignored --nocapture

Compared baseline a314975ce with candidate c2df3cb56 on macOS arm64, Rust 1.98.1. The baseline observer, fitter, workspace manifest and lockfile match the candidate's parent 8f3f4e266. Both arms use opt-level=3, thin LTO and four codegen units, with incremental compilation and compiler-cache wrappers off. This profile is fixed for the comparison; this PR does not change build settings.

Values are medians of three fresh-process runs per version and workload, in alternating order. Peak RSS comes from /usr/bin/time -l around each test executable; compilation is excluded. Each version was rebuilt separately and its executable and workload identity verified.

Workload Peak RSS before → after Emit time per event before → after
10,000 × 1 KiB 14.0 → 14.1 MiB 0.47 → 0.89 µs
1,000 × 60,000 bytes 199.4 → 80.8 MiB 8.54 → 22.53 µs
1,000 × 1 MiB 3,025.8 → 26.4 MiB 123.50 → 307.89 µs

For the 1 MiB workload, replay JSON fell from 1,000.2 MiB to 3.997 MiB. Live JSON fell from 1,000.2 MiB to 5.91 MiB. Replay retained 676 fitted events; the live subscriber received all 1,000.

Emit time includes payload construction. Peak RSS includes snapshot and receive copies made by the probe. JSON budgets are not exact heap limits. These local measurements show the memory/CPU tradeoff; concurrent producer throughput and native app latency were not benchmarked. See the probe instructions for workloads, controls and limits.

Human verification remains pending.

Generated with AI assistance

Fit telemetry before replay and broadcast retain it, and cap replay
at 4 MiB. Preserve sequence order across concurrent emitters and add
regressions plus a repeatable retention probe.

Co-authored-by: Codex <[email protected]>
Signed-off-by: Sanket Kanjalkar <[email protected]>
@sanket1729
sanket1729 marked this pull request as ready for review November 13, 2026 01:57
@sanket1729
sanket1729 requested a review from a team as a code owner November 13, 2026 01:57
@sanket1729
sanket1729 deployed to codex-review November 13, 2026 01:57 — with GitHub Actions Active
@github-actions github-actions Bot added the codex-security-review-current The posted Codex security review matches its recorded range. label Nov 13, 2026
@github-actions

Copy link
Copy Markdown

🔐 Codex Security Review

Note: This is an automated, security-focused review generated by Codex.
Use it as a supplement to human review; false positives are possible.

Scope

  • Exact PR diff: 0bbcf3e7c24c6bb46a4bd3f5fd7fb94aa391a3f3...c2df3cb567a3766aa796c50369903b09a8f04036
  • Model: gpt-6.1-sol

💡 Click "edited" above to see earlier reviews for this PR.


Review Summary

Overall Risk: NONE

No concrete security, correctness, or reliability findings identified in the authorized observer-retention changes.

Findings

No concrete security, correctness, or reliability findings were identified.

Notes

  • Review was limited to read-only inspection. Builds and tests were not run, as requested.

Generated by Codex Security Review |
Requested by: @sanket1729 |
Workflow run

@kazemek21 kazemek21 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Kyle reviewed the PR and the Nexus review-tracker notes and approved with no comments.

Posted by Codex (gpt-6.1-sol) on behalf of kylez

@sanket1729
sanket1729 merged commit bd031a0 into main Nov 13, 2026
97 checks passed
@sanket1729
sanket1729 deleted the sanketk/observer-byte-budget branch November 13, 2026 09:08
bostonaholic added a commit that referenced this pull request Nov 13, 2026
Co-authored-by: mboston.Engineer <932d3b6ebea6cc83e091551ae46d1c7e7f8f7d0fa8e9cef5e6facc8544af413b@buzz.block.builderlab.xyz>

* origin/main:
  fix(mobile): require Builderlab consent for existing identities (#8823)
  feat(mobile): use HTTP/2 on iOS through app-wide URLSessions (#8897)
  fix(relay): publish a git push only when refs changed; check the protocol by refinement (#9425)
  fix(mobile): show shared chats under Solo (#9348)
  chore(release): release Buzz Desktop version 0.5.29 (#9456)
  feat(mobile): render messages with gpt_markdown 1.3.4 plusparse (#8945)
  fix(acp): bound observer retention by bytes (#7987) (#9436)
  Tune release codegen for faster/smaller binaries (#9434)
  feat(desktop): add dismissible banner pointing to the new buzz app (#9379)
  fix(mobile): keep publishing presence while the app is open (#9441)
  feat(mobile): share into Buzz from the iOS share sheet (#9433)
  fix(mobile): qualify every namesake mention and keep authored mention casing (#9325)
  fix(mobile): match browser GIF timing in the iOS reaction sheet (#9437)
  fix(mobile): play short-delay animation frames at browser speed (#9432)
  buzz-search: read profile names without the profile_name_fields function (#9397)
  buzz-db: build the community deletion lock key in Rust (#9396)
  fix(cli): pair for the active community, skip stopped desktops, accept a bare relay host (#9417)
  test(mobile): run push tests without a gateway dart-define (#9423)
  fix(mobile): never pop Home when archiving from channel settings (#9387)
  perf(acp): reduce observer CPU and lock overhead (#9381)

Signed-off-by: Matthew Boston <[email protected]>
bostonaholic added a commit that referenced this pull request Nov 13, 2026
…count-backfill

Co-authored-by: mboston.Engineer <932d3b6ebea6cc83e091551ae46d1c7e7f8f7d0fa8e9cef5e6facc8544af413b@buzz.block.builderlab.xyz>

* bostonaholic--agent-reply-count:
  fix(mobile): require Builderlab consent for existing identities (#8823)
  feat(mobile): use HTTP/2 on iOS through app-wide URLSessions (#8897)
  fix(relay): publish a git push only when refs changed; check the protocol by refinement (#9425)
  fix(mobile): show shared chats under Solo (#9348)
  chore(release): release Buzz Desktop version 0.5.29 (#9456)
  feat(mobile): render messages with gpt_markdown 1.3.4 plusparse (#8945)
  fix(acp): bound observer retention by bytes (#7987) (#9436)
  Tune release codegen for faster/smaller binaries (#9434)
  feat(desktop): add dismissible banner pointing to the new buzz app (#9379)
  fix(mobile): keep publishing presence while the app is open (#9441)
  feat(mobile): share into Buzz from the iOS share sheet (#9433)
  fix(mobile): qualify every namesake mention and keep authored mention casing (#9325)
  fix(mobile): match browser GIF timing in the iOS reaction sheet (#9437)
  fix(mobile): play short-delay animation frames at browser speed (#9432)
  buzz-search: read profile names without the profile_name_fields function (#9397)
  buzz-db: build the community deletion lock key in Rust (#9396)
  fix(cli): pair for the active community, skip stopped desktops, accept a bare relay host (#9417)
  test(mobile): run push tests without a gateway dart-define (#9423)
  fix(mobile): never pop Home when archiving from channel settings (#9387)
  perf(acp): reduce observer CPU and lock overhead (#9381)

Signed-off-by: Matthew Boston <[email protected]>
sanket1729 added a commit that referenced this pull request Nov 14, 2026
Replaces #9413 with the packing optimization refreshed against main on a
branch in this repository.

## Summary

Busy agent activity streams repeatedly build and serialize a growing
JSON batch just to check whether the next event fits. Reuse cached event
sizes, measure the newest outer envelope, and build the batch payload
once per completed frame.

Preserve the wire format, greedy packing, per-channel order, channel
barriers, byte budget, and one-frame-per-second relay cadence.
Exact-limit coverage checks escaping, UTF-8, optional metadata, and
array separators. Move the queue tests into a separate module to satisfy
the file-size rule; their test names stay unchanged.

### Related issue

Related to #7987. This builds on the merged fitting/locking work in
#9381 and retention limits in #9436. Closest earlier batching work:
#4917. No duplicate packing fix found among open PRs.

### Testing

The ignored probe fills the production queue before timing, drains every
event, and checks complete FIFO delivery, frame byte limits, and empty
byte accounting.

```sh
CARGO_INCREMENTAL=0 CARGO_PROFILE_RELEASE_LTO=thin CARGO_PROFILE_RELEASE_CODEGEN_UNITS=4 \
  cargo test --release -p buzz-acp --lib observer::packing_tests::publish_queue_drain_probe -- \
  --exact --ignored --nocapture

BUZZ_OBSERVER_PROBE_EVENTS=100 cargo test --release -p buzz-acp --lib \
  observer::packing_tests::publish_queue_drain_probe -- --exact --ignored --nocapture
```

Five alternating fresh release processes per arm and workload compared
baseline `59ae028a3` with candidate `237b928b9` on macOS arm64, Rust
1.98.1. Both arms used `opt-level=3`, thin LTO and four codegen units,
with incremental compilation and compiler-cache wrappers off. Each
executable was rebuilt separately and its probe identity verified.
Medians:

| Events | Before | After | Frames in both arms |
| --- | ---: | ---: | ---: |
| 100 | 6.760 ms | 0.108 ms | 1 |
| 10,000 | 1,597.509 ms | 7.844 ms | 30 |

The one-event control measured 2.04 → 2.21 microseconds. The timed
region covers packing only; ingestion, validation, encryption, publish
pacing, relay delivery, and rendering are excluded. These local results
do not establish an overall app latency improvement. No timing threshold
was added to CI.

Native and deployed-relay latency, independent review, and human
verification remain pending. Keep this PR in draft.

Generated with AI assistance

Signed-off-by: Sanket Kanjalkar <[email protected]>
Co-authored-by: Codex <[email protected]>

This branch was successfully deployed

1 active deployment
codex-review — c2df3cb5 Deployed Nov 13, 2026 by sanket1729 via Run Codex Security Review #14795
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex-security-review-current The posted Codex security review matches its recorded range.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(acp): observer replay and broadcast retention lack a byte budget

2 participants