Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ BUZZ_PUSH_GATEWAY_DELIVERY_URL=https://push.buzz.xyz/v1/deliveries/apns

# Deployment-global operator-listener routes. Each configured Nostr identity
# may register target pubkeys and receives mention notifications at its URL.
# URLs may use HTTP or HTTPS. Use HTTP only for operator-controlled internal
# connections: NIP-98 signs requests.
# Format: pubkey:deliveryUrl;pubkey:deliveryUrl
# BUZZ_OPERATOR_LISTENER_TIMEOUT_MS=5000
# BUZZ_OPERATOR_LISTENERS=<64-char hex pubkey>:https://listener.example/mentions
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/_ci-clients.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ jobs:
name: Mobile
runs-on: ubuntu-latest
timeout-minutes: 30
if: inputs.lane == 'required' && (github.event_name == 'push' || inputs.mobile)
# The Dreamforge fork does not build or ship the phone app (owners use Block's store build).
if: inputs.lane == 'required' && github.repository == 'block/buzz' && (github.event_name == 'push' || inputs.mobile)
permissions:
contents: read
steps:
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ jobs:
mobile-swift-domain:
name: Mobile Swift Domain
needs: [changes]
if: needs.changes.outputs.mobile == 'true'
# The Dreamforge fork does not build or ship the phone app (owners use Block's store build).
if: github.repository == 'block/buzz' && needs.changes.outputs.mobile == 'true'
uses: ./.github/workflows/_ci-clients.yml
with:
web: ${{ needs.changes.outputs.web == 'true' }}
Expand Down Expand Up @@ -416,7 +417,8 @@ jobs:

mobile:
name: Mobile
if: always() && (needs.changes.result != 'success' || ((github.event_name == 'push' || needs.changes.outputs.mobile == 'true')))
# The Dreamforge fork does not build or ship the phone app (owners use Block's store build).
if: always() && github.repository == 'block/buzz' && (needs.changes.result != 'success' || ((github.event_name == 'push' || needs.changes.outputs.mobile == 'true')))
needs: [changes, clients]
runs-on: ubuntu-latest
timeout-minutes: 5
Expand Down
14 changes: 9 additions & 5 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -448,10 +448,11 @@ test-unit:
# suites are otherwise absent from the infra-free unit lane.
cargo nextest run -p buzz-media --lib \
-E 'test(=bucket_index::tests::bucket_snapshot_json_round_trip_preserves_community_keys)'
# buzz-admin: storage-snapshot worker plus the community archive
# command parser, validation, and propagation-evidence tests.
# buzz-admin: storage-snapshot worker, the community archive command
# parser, validation, and propagation-evidence tests, and the partition
# audit outcome contract.
cargo nextest run -p buzz-admin \
-E 'test(storage_snapshot) + test(/^communities::tests::/) + test(/^tests::communities_/)'
-E 'test(storage_snapshot) + test(/^communities::tests::/) + test(/^tests::communities_/) + test(=tests::partition_audit_outcomes_keep_their_json_names_and_exit_codes)'
# Multi-tenant conformance gate (buzz-conformance): the independent
# replay checker + golden fixtures. No infra — pure in-process trace
# replay — so it belongs in the unit job. Run all targets (lib + the
Expand Down Expand Up @@ -530,7 +531,7 @@ test-unit:
# are infra-free; config parses env into a struct and never connects.
# `^config::` is anchored so it does not also select nip_fi_config.
cargo nextest run -p buzz-relay --lib --bin buzz-relay \
-E 'test(/^api::admin::/) + test(/^push_runtime::/) + test(/^handlers::channel_authz::/) + test(/^handlers::moderation_authz::/) + test(/^handlers::side_effects::tests::/) + test(/^storage_sweep::tests::/) + test(/^nip_fi_core::tests::/) + test(/^nip_fi_http::tests::/) + test(/^nip_fi_config::tests::/) + test(/^readiness::tests::/) + test(/^router::tests::/) + test(/^api::parse_query_tests::/) + test(/^api::git::transport::off_mode_precedence_tests::/) + test(/^audio::join::tests::/) + test(/^audio::handler::tests::/) + test(/^nip_fi_gate::tests::/) + test(/^nip_fi_session::tests::/) + test(/^nip_fi_shadow::tests::/) + test(/^nip_fi_shadow_session::tests::/) + test(/^startup_steps::tests::/) + test(/^telemetry::tests::/) + test(/^config::tests::/) + test(=state::tests::neither_a_confirmed_inactive_community_nor_a_failed_lookup_admits_the_socket) + test(=state::tests::periodic_revalidation_disconnects_inside_the_fenced_callback) + test(=state::tests::bare_community_disconnect_fails_closed_when_the_fence_is_unavailable) + test(=connection::tests::send_loop_sends_policy_close_when_community_is_archived) + test(=state::tests::community_disconnect_then_nip_fi_keeps_community_deleted_reason) + test(=state::tests::disconnect_community_wins_reason_losing_nip_fi_does_not_enqueue_frame) + test(=handlers::req::tests::timed_out_historical_read_deregisters_before_closed) + test(=handlers::req::tests::superseded_timeout_leaves_replacement_intact) + test(=handlers::req::tests::search_claim_retires_live_and_yields_to_replacement) + test(=handlers::req::tests::concurrent_claims_and_stale_teardowns_keep_the_last_owner) + test(=handlers::req::tests::timeout_closed_is_emitted_before_a_replacement_can_claim) + test(=handlers::req::tests::revoke_then_replacement_keeps_replacement_whole) + test(=handlers::req::tests::claims_after_connection_cleanup_are_refused) + test(=handlers::req::tests::dropped_terminal_frame_cancels_connection) + test(=handlers::req::tests::revoke_dropped_terminal_frame_cancels_connection) + test(=handlers::req::tests::count_fallback_covers_filters_that_can_match_private_deletions) + (kind(bin) & (test(/^tests::/) + test(/^composition_tests::/) + test(/^env_filter_tests::/)) - test(/^tests::postgres_tests::/))'
-E 'test(/^api::admin::/) + test(/^push_runtime::/) + test(/^operator_listener::tests::/) + test(/^handlers::channel_authz::/) + test(/^handlers::moderation_authz::/) + test(/^handlers::side_effects::tests::/) + test(/^storage_sweep::tests::/) + test(/^nip_fi_core::tests::/) + test(/^nip_fi_http::tests::/) + test(/^nip_fi_config::tests::/) + test(/^readiness::tests::/) + test(/^router::tests::/) + test(/^api::parse_query_tests::/) + test(/^api::git::transport::off_mode_precedence_tests::/) + test(/^audio::join::tests::/) + test(/^audio::handler::tests::/) + test(/^nip_fi_gate::tests::/) + test(/^nip_fi_session::tests::/) + test(/^nip_fi_shadow::tests::/) + test(/^nip_fi_shadow_session::tests::/) + test(/^startup_steps::tests::/) + test(/^telemetry::tests::/) + test(/^config::tests::/) + test(=state::tests::neither_a_confirmed_inactive_community_nor_a_failed_lookup_admits_the_socket) + test(=state::tests::periodic_revalidation_disconnects_inside_the_fenced_callback) + test(=state::tests::bare_community_disconnect_fails_closed_when_the_fence_is_unavailable) + test(=connection::tests::send_loop_sends_policy_close_when_community_is_archived) + test(=state::tests::community_disconnect_then_nip_fi_keeps_community_deleted_reason) + test(=state::tests::disconnect_community_wins_reason_losing_nip_fi_does_not_enqueue_frame) + test(=handlers::req::tests::timed_out_historical_read_deregisters_before_closed) + test(=handlers::req::tests::superseded_timeout_leaves_replacement_intact) + test(=handlers::req::tests::search_claim_retires_live_and_yields_to_replacement) + test(=handlers::req::tests::concurrent_claims_and_stale_teardowns_keep_the_last_owner) + test(=handlers::req::tests::timeout_closed_is_emitted_before_a_replacement_can_claim) + test(=handlers::req::tests::revoke_then_replacement_keeps_replacement_whole) + test(=handlers::req::tests::claims_after_connection_cleanup_are_refused) + test(=handlers::req::tests::dropped_terminal_frame_cancels_connection) + test(=handlers::req::tests::revoke_dropped_terminal_frame_cancels_connection) + test(=handlers::req::tests::count_fallback_covers_filters_that_can_match_private_deletions) + (kind(bin) & (test(/^tests::/) + test(/^composition_tests::/) + test(/^env_filter_tests::/)) - test(/^tests::postgres_tests::/))'
# Note on audio::join::tests scope: the full suite is infra-free (no DB,
# no Redis). The infra-free audio/FI regression witnesses — bootstrap
# ordering barrier, CommitConfirmed arm, pending-close invisibility,
Expand All @@ -539,7 +540,9 @@ test-unit:
# DB-backed audio join tests use #[ignore] and run in the postgres lane.
# NIP-FI (S3/S4) relay witnesses: the wholly-new nip_fi_upgrade and
# api::nip_fi modules,
# the auth metrics contract module, plus the exact NIP-FI tests added,
# the auth metrics contract module, the DB-free partition alert series
# tests (their Postgres case is #[ignore]d and runs in the PostgreSQL
# lane), plus the exact NIP-FI tests added,
# or whose assertions changed, in mixed modules (audio::room,
# connection, handlers::*, state). nip_fi_config and router are
# selected whole by the command above. Mixed modules are listed by exact
Expand All @@ -550,6 +553,7 @@ test-unit:
cargo nextest run -p buzz-relay --lib -E '
test(/^nip_fi_upgrade::/)
+ test(/^metrics::contract_tests::/)
+ test(/^metrics::partition_alert_tests::/)
+ test(=audio::room::tests::roster_revisions_are_ordered_and_snapshot_is_authoritative)
+ test(=connection::tests::auth_lifecycle_reconciles_every_terminal_and_never_leaks_gauge)
+ test(=audio::room::tests::b1_pending_peer_removed_before_commit_emits_no_delta)
Expand Down
8 changes: 4 additions & 4 deletions crates/buzz-acp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ That's it. The harness spawns `goose acp`, connects to the relay, discovers chan
[codex-acp](https://github.com/agentclientprotocol/codex-acp) wraps OpenAI Codex in an ACP interface.

```bash
# Install the adapter (npm package — no Rust build required)
npm install -g @agentclientprotocol/codex-acp
# Install the adapter (npm package — no Rust build required; pinned to the tested version)
npm install -g @agentclientprotocol/codex-acp@1.13.1

# Run
export OPENAI_API_KEY="sk-..." # required — use an OpenAI API key, not a ChatGPT subscription
Expand All @@ -90,8 +90,8 @@ buzz-acp
[claude-agent-acp](https://github.com/agentclientprotocol/claude-agent-acp) wraps the Claude Agent SDK in an ACP interface.

```bash
# Install the current adapter package
npm install -g @agentclientprotocol/claude-agent-acp
# Install the adapter (pinned to the version Dreamforge is tested with)
npm install -g @agentclientprotocol/claude-agent-acp@0.70.0

# Run
export ANTHROPIC_API_KEY="sk-ant-..."
Expand Down
2 changes: 1 addition & 1 deletion crates/buzz-acp/src/base_prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Auth env vars: `BUZZ_RELAY_URL`, `BUZZ_PRIVATE_KEY`, `BUZZ_AUTH_TAG`. Exit codes
0 ok, 1 user error, 2 network, 3 auth, 4 other, 5 write conflict. Output is
structured JSON. `--format compact` is global — it goes before the subcommand.

Run `buzz --help` or `buzz <group> --help` for full usage. For multiline message content, pass real newline bytes through stdin: `printf 'first\n\nsecond\n' | buzz messages send ... --content -`. Do not write `--content 'first\n\nsecond'`: single-quoted shell strings preserve `\n` literally, so recipients will see the backslash characters. `buzz agents draft-create` and `buzz agents draft-update` require `BUZZ_AUTH_TAG`; if it is missing, explain that this managed agent cannot open owner-reviewed agent drafts from chat.
Run `buzz --help` or `buzz <group> --help` for full usage. For multiline or non-ASCII content (em dashes, curly quotes, emoji), write the text with your file-editing tool to a new UTF-8 file in the OS temp directory, named with the channel UUID plus a timestamp or random suffix, pass its absolute path, and delete the file after sending: `buzz messages send ... --content-file <temp-dir>/buzz-<channel-uuid>-<suffix>.md` (`buzz issues create` and `buzz canvas set` take `--content-file` too). Never reuse a fixed file name or write the file inside a git checkout: turns in other channels run in parallel from the same working directory and would send each other's text, and `git add -A` would commit it. On Windows always use `--content-file`: PowerShell re-encodes piped text, so every non-ASCII character arrives as `?`. Elsewhere you can also pass real newline bytes through stdin: `printf 'first\n\nsecond\n' | buzz messages send ... --content -`. Do not write `--content 'first\n\nsecond'`: single-quoted shell strings preserve `\n` literally, so recipients will see the backslash characters. `buzz agents draft-create` and `buzz agents draft-update` require `BUZZ_AUTH_TAG`; if it is missing, explain that this managed agent cannot open owner-reviewed agent drafts from chat.

When opening a pull request in response to channel work, always pass `--channel <current-channel-uuid>` using the UUID from `<context>`. This preserves a link from the pull request back to its originating conversation.

Expand Down
Loading
Loading