Skip to content

feat(cli): add verified long-running client primitives - #3964

Draft
dspury wants to merge 1 commit into
block:mainfrom
Lunar-Park:pr/cli-external-agent-foundation
Draft

feat(cli): add verified long-running client primitives#3964
dspury wants to merge 1 commit into
block:mainfrom
Lunar-Park:pr/cli-external-agent-foundation

Conversation

@dspury

@dspury dspury commented Jul 31, 2026

Copy link
Copy Markdown

Summary

Adds generic CLI primitives for long-running clients that need to consume and verify Buzz events without embedding process or deployment policy in Buzz.

Buzz-owned changes

  • buzz listen with explicit h / p scope filters
  • canonical event-id and signature verification before output
  • bounded catch-up with an explicit overflow error
  • reconnect, shutdown, and stable transport-error behavior
  • buzz users me for local public-identity inspection
  • buzz keys generate for safe local key generation
  • additive compact message fields
  • synthetic fixtures covering wire/schema, channel/thread, replay, lifecycle, and malformed-input behavior

Deliberately out of scope

  • process discovery or lifecycle management
  • routing or activation policy
  • directory/profile publication
  • host, storage, or deployment configuration

Those concerns belong to the caller or adapter and require no Buzz-specific extension point.

Validation

  • just ci
  • cargo test -p buzz-cli
  • cargo clippy -p buzz-cli --all-targets -- -D warnings
  • focused listen, fixture, CLI, and key-generation tests

Coordination

#2933 and #2942 cover related identity and listening surfaces. This draft keeps only the independently useful hardening pieces: verified filtering, bounded catch-up, safe key generation, lifecycle/error behavior, and generic contract fixtures. The commits can be split or folded into those PRs based on maintainer preference.

@murdawkmedia

Copy link
Copy Markdown

I exercised the CLI branch in a composed checkout (all Buzz CLI/unit and added external-agent tests passed), but found four production blockers for long-running Hermes/OpenClaw residents:

  1. Windows secret-file ACLs: keys generate --out applies/reasserts 0600 only under #[cfg(unix)]. On Windows the key inherits the parent DACL while the command/docs promise owner-only storage. Please install and verify a restrictive DACL or fail closed as unsupported; a transactional write would also avoid partial key files.

  2. Replaceable-profile lost updates: apply_profile_update performs fetch → merge → publish without optimistic concurrency or post-write head verification. Kind 10100 uses second-resolution timestamps and event-ID tie-breaking, while a dominated replaceable event can still produce an accepted/duplicate response and exit zero. Same-second or concurrent updates can therefore be lost while the adapter believes they succeeded. Please verify the submitted event became the current head and return conflict/retry otherwise.

  3. Lossy catch-up above 1,000 events: listen --since supplies no limit, pagination cursor, or overflow signal. The relay/DB ceiling defaults to the newest 1,000 rows and then emits EOSE, silently skipping older unseen events after a long outage. A resident bridge needs paginated catch-up or an explicit composite cursor/overflow recovery contract.

  4. Events cannot be independently verified: the WebSocket path deserializes relay events, then normalize_events removes sig before output. The adapter cannot verify the claimed ID/author afterward, yet owner/allowlist activation depends on those claims. Please verify ID/signature before emitting and preserve sig (or include an explicit trustworthy verification result), with tests for forged authors, invalid signatures, and filter mismatches.

The scoped #h/#p subscriptions, NIP-42/NIP-OA use, public-only users me, and documented at-least-once reconnect behavior are good foundations. These fixes would make the surface suitable for a durable independently hosted resident rather than only a happy-path adapter.

@dspury

dspury commented Aug 2, 2026

Copy link
Copy Markdown
Author

@murdawkmedia Thanks for the careful read. I agree these are the right durability concerns, especially event verification/signature preservation and bounded catch-up.

Before I start changing the branch, I want to confirm whether this CLI surface is still the path maintainers want under the broader remote/resident-agent direction in #4174. If yes, I think this PR can be tightened sooner rather than later around the items you called out.

@dspury
dspury force-pushed the pr/cli-external-agent-foundation branch from d4f101c to d3e92df Compare August 13, 2026 05:30
@dspury

dspury commented Aug 13, 2026

Copy link
Copy Markdown
Author

@murdawkmedia I refreshed this branch onto current upstream main and addressed all four durability blockers in d3e92df21:

  • Windows secret-file output now fails closed until a verified owner-only ACL path exists.
  • Kind:10100 writes now reject dominated/duplicate responses and verify the submitted event is the current coordinate head.
  • listen --since counts each scoped filter and fails with an explicit recovery error above the relay 1,000-event ceiling.
  • Listen now verifies filter membership, canonical IDs, and Schnorr signatures before emitting, preserves sig, and has negative coverage for forged/out-of-scope events.

cargo test -p buzz-cli and the full just ci repository gate pass on head d3e92df212f0572326ce35a50ab6471edcc0faaf. The PR body now documents the overlap with #2942 so maintainers can evaluate the generic primitives without ambiguity.

Add scoped signed-event streaming with bounded replay, local public-identity inspection, safe key generation, and implementation-independent wire fixtures. Keep process lifecycle, routing policy, directory publication, and deployment configuration outside Buzz.

Signed-off-by: dspury <demitriusspury@gmail.com>
@dspury
dspury force-pushed the pr/cli-external-agent-foundation branch from d3e92df to 0ba5a86 Compare August 13, 2026 07:08
@dspury
dspury marked this pull request as draft August 13, 2026 07:08
@dspury dspury changed the title feat(cli): add external-agent identity and listen primitives feat(cli): add verified long-running client primitives Aug 13, 2026
@dspury

dspury commented Aug 13, 2026

Copy link
Copy Markdown
Author

Final rewrite note: the current one-commit head 0ba5a8662 replaces the earlier branch history, so my prior update about the old profile-write implementation is historical and no longer describes this PR.

The current draft contains no kind:10100 writer or profile merge path. It keeps only the generic, independently useful pieces: verified scoped listening, bounded catch-up, safe local key generation, public identity inspection, lifecycle/error behavior, and implementation-independent fixtures. Directory publication, activation/routing policy, process supervision, and deployment configuration are all out of scope pending the upstream directory decision.

The rewritten head passed just ci; current DCO, Semgrep, and zizmor checks are green.

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.

2 participants