block / block/buzz

Remote host-agent Activity is typing-only: observer frames fail NIP-44 after trim

Open
#7,086 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

# Remote host-agent Activity goes blank (typing only)

**Summary:** A host-route `buzz-acp` agent with `BUZZ_ACP_RELAY_OBSERVER=true` is mid-turn and Buzz Desktop only shows a typing indicator. The VM logs NIP-44 encrypt failures after the observer trimmer, 4MiB queue drops, and relay `quota exceeded`. A same-relay Grok host agent on the owner Mac renders Activity fine.

## Environment

- Buzz Desktop 0.5.19 (macOS), owner signed in
- Remote host: Linux VM, `buzz-acp` from `Buzz_0.5.20_amd64.deb` generation / Aug 25 Linux binary (same observer code: `fit_observer_event_to_budget` present)
- Agent: Grok ACP (`grok agent --always-approve stdio`), `BUZZ_ACP_AGENTS=2`, `BUZZ_ACP_RELAY_OBSERVER=true`, `BUZZ_ACP_AGENT_OWNER` set, NIP-OA owner is the signed-in Desktop identity
- Channel: private stream, large multi-agent turn (tool reads/writes)

## Expected

Desktop Activity panel for the remote agent shows tool calls / reads / writes — the same transcript used for locally managed agents — as documented for `BUZZ_ACP_RELAY_OBSERVER=true` (kind 24200 frames to the owner).

## Actual

Desktop shows **typing only**. VM `buzz-acp` logs (same window):

```
failed to encrypt relay observer event: NIP-44 error: message too long
observer publish queue over byte budget; dropped oldest events dropped=1 total_dropped=7 pending_bytes=4131977
relay NOTICE: rate-limited: quota exceeded; retry in 21s
```

The encrypt error is **`NIP-44 error: message too long`**, not `PlaintextTooLarge`. So `fit_observer_event_to_budget` (PR #1072) accepted the JSON (≤ 65,535 per `OBSERVER_MAX_PLAINTEXT_LEN`), then `nip44::encrypt` still refused it. Those frames are dropped; typing events still ship.

A second host agent on the owner Mac against the same relay has **zero** of these warnings and Activity works.

## Why this looks like a bug

`publish_relay_observer_event` trims then calls `encrypt_observer_payload`, whose contract after #1072 is that encrypt should succeed. Remaining frames that fit the JSON cap still fail NIP-44 (padding / off-by-one vs 65,535 is the likely mismatch). Queue overflow and the shared 120 msg/min quota then drop the rest of a high-volume Grok turn. Desktop has no error — only a hanging typing indicator.

## Ask

1. Leave headroom so a trimmed 65,535-byte observer JSON always encrypts under NIP-44 v2 (including padding).
2. Never drop a frame the trimmer already accepted; log sizes if encrypt still fails.
3. Surface observer loss in Desktop instead of typing-only.

## Related

- https://github.com/block/buzz/pull/1072
- https://github.com/block/buzz/pull/4917

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.