Skip to content

fix: chart auto-migrate image, AppImage dmabuf, silent reply notice#2500

Open
Chessing234 wants to merge 5 commits into
block:mainfrom
Chessing234:fix/chart-dmabuf-silent-reply
Open

fix: chart auto-migrate image, AppImage dmabuf, silent reply notice#2500
Chessing234 wants to merge 5 commits into
block:mainfrom
Chessing234:fix/chart-dmabuf-silent-reply

Conversation

@Chessing234

Copy link
Copy Markdown
Contributor

Summary

  • Chart 0.1.7 defaults appVersion to main so BUZZ_AUTO_MIGRATE works out of the box (#2473)
  • AppImage sets WEBKIT_DISABLE_DMABUF_RENDERER=1 to avoid Intel Mesa / XWayland cores (#2338)
  • buzz-acp posts a failure notice when a mention turn ends Ok with no agent channel publish (#2459)

Test plan

  • helm template / chart render: image is ghcr.io/block/buzz:main when tag is empty
  • Linux AppImage on Intel Mesa + XWayland launches without dmabuf core dump
  • Force buzz messages send to fail during a mention turn — channel gets a failure notice

Fixes #2473
Fixes #2338
Fixes #2459

Made with Cursor

Chessing234 and others added 3 commits July 23, 2026 14:21
Signed-off-by: Taksh <takshkothari09@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Taksh <takshkothari09@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Taksh <takshkothari09@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@brocoppler

Copy link
Copy Markdown

Scoped to the #2459 part of this PR, against head 9331d35. Filed that issue; reviewed this against the failure observed there.

The core wiring is sound: take_self_publishes runs before mark_complete wipes the in-flight entry, kind 9 is in the Mentions-rule REQ so the echo does reach the counting site in the default config, and every PromptOutcome::Ok construction in pool.rs now carries the batch without any path re-entering requeue (checked all of them). Full buzz-acp suite passes locally on this branch. Two paths produce false "couldn't publish" notices:

1. Counting is gated on ignore_self. note_self_publish only runs inside if config.ignore_self && … (lib.rs). Under --no-ignore-self the counter never increments, so every successful mention turn posts the failure notice into the channel. The observation belongs above the gate: count self-authored kind-9s unconditionally, then let ignore_self decide the drop.

2. The counter is consumed at turn end, but the echo arrives on an independent path. The reply's echo comes in over the ws subscription; turn completion comes over the pool result channel — nothing orders them. The CLI publishes via REST, so a ws drop at turn end doesn't stop the reply from landing in the channel, but the reconnect since-replay delivers the echo after handle_prompt_result has already consumed a zero counter and posted the notice. Net effect: real reply in the channel with a spurious "I couldn't publish" right behind it — clustering exactly when the relay is unstable, which is when users are most inclined to believe the notice. A grace window closes it: don't decide at turn completion; schedule the check a few seconds later and re-read a counter that survives mark_complete until the deferred check consumes it.

Smaller notes:

  • SubscribeMode::All batches carry prompt_tag: "all", so mentions get no protection in that mode. If deliberate (every event fires a turn there, so zero-publish isn't anomalous), worth a comment in batch_expects_channel_reply.
  • A mention answered with only a reaction (kind 7) or a pure side effect (no channel message) posts the notice. Probably acceptable; noting it since it's user-visible.

Regression coverage that would catch 1 and 2: an ingest-level test driving a mention turn to Ok with (a) echo delivered before completion → no notice, (b) echo delivered after completion → no notice (fails today), (c) --no-ignore-self + echo delivered → no notice (fails today). The silent_reply.rs unit tests exercise the pure function only, which is why neither path surfaced.

@Chessing234

Copy link
Copy Markdown
Contributor Author

Addressed both false-notice paths: self-publishes are counted above the ignore_self gate, and the notice waits a 3s grace so a late ws echo can clear it. Also noted why SubscribeMode::All is excluded.

Silent-reply detection now counts agent kind-9/45001 publishes even
under --no-ignore-self, and defers the notice by 3s so a ws echo that
arrives after turn completion can clear a false "couldn't publish".

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Taksh <takshkothari09@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@Chessing234
Chessing234 force-pushed the fix/chart-dmabuf-silent-reply branch from 5580edd to 6bece8a Compare July 24, 2026 08:04
@brocoppler

Copy link
Copy Markdown

Reviewed 6bece8a. Both false-notice paths from the earlier review are fixed correctly:

  • Counting hoisted above the ignore_self gate — the counter increments regardless of config, the gate still drops afterward. Right shape.
  • The deferred decision is the right architecture: watch armed at Ok completion so counts survive mark_complete, decision re-checked on the main loop after the grace. The None-on-consumed guard covers the stale-timer case.

Two things remain, one substantive:

The 3s constant loses to the reconnect case it exists for. relay.rs documents resubscribe bursts spreading ≈6s under REQ pacing for a many-channel harness, plus the clock-skew tolerance on since replay — so a ws drop at turn end delivers the echo after the grace expires, and the false notice fires in exactly the relay-instability window where users are most likely to trust it. Ordering-race coverage (normal operation) is real; the reconnect race outlives 3s. Suggest deriving the deadline from connection state — defer the decision until the resubscribe pass after any reconnect has completed, plus a small epsilon — or at minimum make the grace configurable so operators with many channels can widen it.

Nit: two Ok mention turns on one channel completing within the grace window — the first turn's timer consumes the watch the second turn armed (take_silent_reply_watch is keyed by channel only), shortening the second turn's grace and deciding it against the first batch. A generation/turn id on the watch closes it.

The ingest-level regression cases from the earlier review would still catch both of these mechanically: echo-before-completion → no notice; echo-after-completion-within-grace → no notice; --no-ignore-self + echo → no notice. adambe0's report on #2459 (exit-0 zero-byte binary — the write "succeeds" with no relay accept) both widens the failure class this notice covers and validates the zero-publish heuristic as the harness-side catch-all; their accept-envelope check is the complementary CLI/agent-side guard and worth a line in the PR description as out of scope here.

Default grace is 8s (override with BUZZ_SILENT_REPLY_GRACE_SECS) so
post-reconnect echoes can clear the notice, and watches are keyed by
generation so a stale timer cannot steal a later Ok turn's check.

Signed-off-by: Taksh <takshkothari09@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@Chessing234

Copy link
Copy Markdown
Contributor Author

Widened the default grace to 8s (BUZZ_SILENT_REPLY_GRACE_SECS to tune) and generation-keyed the silent-reply watch so a stale timer can't consume a later Ok on the same channel.

@brocoppler

Copy link
Copy Markdown

Verified 348a7e5. Both remaining findings are closed:

  • Grace window: 8s default clears the ≈6s resubscribe spread from the earlier measurement, and the env override is the right escape hatch for many-channel harnesses.
  • Stale-timer race: the generation gating is sound beyond the tested interleaving. A silent_reply_watches entry is only removed by a take with the matching generation, and each armed generation has exactly one timer — so a re-minted generation (arm → take → re-arm restarts at 1) can never coexist with a live stale timer holding the same number. silent_reply_watch_generation_ignores_stale_timer covers the supersede path; the restart path is unreachable by construction. All 8 silent-reply tests pass standalone at head.

Two observations, neither blocking:

  1. Counts accumulate across superseded turns ("generations only gate take"): a silent turn that supersedes a publishing turn within the grace inherits the earlier count, so no notice posts. That's a false negative, not a false notice — and it predates this commit. Given buzz-acp: turn completes ok but reply is silently lost when the agent's buzz CLI write fails #2459 is about spurious notices, deferring is reasonable; flagging it so it's a known trade.
  2. BUZZ_SILENT_REPLY_GRACE_SECS=0 (or any unparsable value) silently falls back to 8 — the > 0 filter means the grace can't be disabled via env. If intentional, a line in .env.example would save someone the debugging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants