Huddle audio was embedded in the v0 desktop client, forcing other
clients to duplicate its protocol and codec behavior. This extracts
`buzz-audio-client` so v1 can depend on a pinned library revision
without building the v0 application.
The crate owns the bounded v2 audio handshake, roster parsing, wire
format, Opus sender, and per-peer NetEQ jitter buffer. The v0 human and
agent senders use it, and the desktop retains room admission,
identity/signing, TLS policy, device routing, mute, and teardown.
Receive decoding preserves v1's support for 120 ms Opus packets. No
relay protocol changes, speech models, or model downloads are included.
Docker builder stages include CMake because cargo-chef compiles the
workspace dependency graph.
Dependency security: Opus 0.4 replaces the unmaintained `audiopus_sys`
backend with `opusic-sys`. NetEQ is pinned exactly to 0.8.3 because its
published Rust sources never reference its declared ringbuf dependency.
RUSTSEC-2026-0293 is documented as unreachable for this audited source,
and a wrapper restriction rejects every other consumer of vulnerable
ringbuf versions. Independent review confirmed the scope;
re-audit/remove the exception when changing NetEQ. NetEQ 0.9.1 still
declares ringbuf 0.3, so a version bump alone does not remove it. Local
`cargo deny check` passes with this constrained exception.
Validation:
- All 21 shared-crate tests pass, including real loopback WebSocket
authentication/cancellation, real Opus-to-NetEQ playback, malformed
input, and 120 ms decoding. These tests are included in `just
test-unit`.
- Shared-crate, root workspace, and desktop Tauri Clippy pass; `just
desktop-tauri-check` passes.
- The desktop Tauri test workspace passes; native two-person
listening/device checks remain separate.
- All mandatory push checks pass at `d06bac5dc`, including the complete
Rust unit gate and desktop workspace checks. Existing agent timing and
relay log-capture tests failed under concurrent load, passed separately,
and passed in the full serial test run; no tests or hooks were skipped.
- One test-only fixture change allows cold Perl startup before the
escaped-process test's inner timeout (2 seconds instead of 300 ms). Its
independent 5-second watchdog, 300-second surviving pipe writer, and all
assertions remain intact. All eight process-helper tests pass;
independent review confirmed this still tests bounded drain completion.
- Dependency inspection confirms the library brings in no desktop
application, Tauri, identity store, relay server, or speech-model
crates.
- Independent source review found no correctness blockers.
Draft: a native two-person call, mute/leave/cancellation, and
microphone/speaker switching still need a runtime tryout and human
review. Full `just ci` was stopped during the unrelated mobile toolchain
download because of disk pressure; it is not a passing gate. Consumer
integration is tracked in block/buzz-app#489.
---------
Signed-off-by: kenny lopez <klopez4212@gmail.com>
## Why
Phase 1 of progressive delivery needs an explicit eligibility boundary
before deployment automation can safely consume relay artifacts. Today
the canonical Docker workflow can publish independently of the same-SHA
CI result, the relay does not expose its source/build identity, and the
Helm chart only renders mutable tags.
The existing `ghcr.io/block/buzz-staging-dev` workflow in #6709 remains
a manual pre-merge preview lane. It is deliberately not a canonical
promotion input.
## What changed
- Compile the full source SHA and GitHub Actions build identity into
canonical relay binaries and expose it at `/_status`.
- Gate creation of tagged multi-architecture manifests on the latest
exact-SHA `CI` push run succeeding on `main` or `release`.
- Preserve the signed SLSA provenance and add a signed, release-only
deployment-eligibility predicate with source, build run, qualifying CI
run, and exact compatible Buzz chart version.
- Keep failed or pending builds untagged and without an eligibility
predicate; preview-package artifacts are excluded by package and signer
contract.
- Add optional `image.digest` support to Buzz chart `0.1.8`, retaining
the existing tag fallback.
- Document verification and the intentional boundary between image/chart
compatibility and backwards-compatible database migrations.
## Risk and rollout
Canonical tag publication now waits for same-SHA CI and fails closed
when the newest matching run fails. Per-architecture blobs may remain
untagged after a failed qualification; they are not promotion inputs.
Debug manifests are also CI-gated but do not receive the release
eligibility predicate.
There are no migration or schema-orchestration changes. The companion
BuilderBot infrastructure PR will pin a separately verified canonical
main digest and expose a read-only running-deployment inspection
command. Signed eligibility is available only for artifacts published
after this workflow lands.
## Verification
- Blox: workflow contract fixtures, including stale-green rejection and
predicate structure
- Blox: `actionlint` for `ci.yml` and `docker.yml`
- Blox: 46 Helm unit tests, chart lint, and production/quickstart render
fixtures
- Blox: relay status unit test, workspace Rust formatting, and workspace
all-target clippy
- Live evidence: exact-SHA CI selector chose successful run
`32857345153` for source `9d1e4b257657f382d3111ce748f3da8d063b7671`
- Existing canonical digest provenance verified with `gh attestation
verify`
## References
- #6709 — developer-preview precursor; intentionally separate from
canonical eligibility
- `docs/deployment-identity.md`
*Generated with Codex*
---------
Signed-off-by: Luke Tornquist <tornquist@squareup.com>
## Why
Native profilers such as `ddprof` need symbols to resolve optimized Buzz
relay stacks, while ordinary deployments should keep the current compact
stripped image.
## What
- Build optimized relay binaries with line-table debug information and
derive the stripped release binaries from the same ELF files
- Publish matching multi-arch `debug-*` tags while preserving existing
stripped tags and runtime behavior
- Document the debug image as an optimized symbol-bearing release, not a
debug-mode build
## Risk Assessment
Medium — this changes the relay image release workflow and adds a second
image variant, but existing tags remain stripped and use the same
runtime base, user, entrypoint, and optimized machine code.
## References
- Follows Envoy's optimized unstripped `debug-*` image pattern:
https://github.com/envoyproxy/envoy/blob/main/distribution/binary/BUILD
- Built both Docker targets locally; verified matching GNU build IDs and
`.text` hashes, with DWARF and symbol sections present only in the debug
variant
- Pre-push checks passed: branch skew, org policy, desktop checks/tests,
Rust tests, mobile tests, Tauri tests, and workspace tests
Generated with Amp
Signed-off-by: David Grochowski <dgrochowski@squareup.com>
Co-authored-by: Amp <amp@ampcode.com>
## Problem
A fresh `deploy/compose` install never starts. The relay exits during
config
validation and crash-loops under `restart: unless-stopped`:
```
Error: Configuration error: invalid config: BUZZ_GIT_PACK_CACHE_PATH=/data/git/.pack-cache could not be created: Permission denied (os error 13)
```
## Cause
The image runs as `buzz:buzz`. Docker seeds a volume's ownership from
the image
**only when the mount point already exists there** — otherwise it
creates the
mount point as `root:root`. `compose.yml` mounts `buzz-git-data` at
`/data/git`,
which the image doesn't create, so the relay can't write the pack cache.
`USER buzz:buzz` and `BUZZ_GIT_REPO_PATH=/data/git` arrived in the same
commit
(426497a), so there was never a working state to regress from.
The other deployment paths are unaffected, which is probably why this
went
unnoticed: the code default (`./repos`, under the `buzz`-owned home)
works
unmounted, and the Helm chart gets volume ownership from `fsGroup:
65532`.
## Fix
Create `/data/git` as `buzz:buzz` in the image, the way the official
`postgres`
image prepares `$PGDATA`.
`compose.yml`, `run.sh` and the volume layout are untouched, so existing
deployments need no migration and the `run.sh backup-hint` output stays
accurate.
## Testing
`ghcr.io/block/buzz@sha256:ec96e029` on arm64 with this change applied
as a
derived layer, running **unmodified** `deploy/compose/compose.yml`
against clean
volumes:
| Image | `/data/git` owner | Result |
|---|---|---|
| upstream | `root:root` | `Permission denied` — crash loop |
| patched | `buzz:buzz` | relay healthy |
```
relay health: healthy
/data/git = buzz:buzz (contains .pack-cache)
/_readiness -> 200
WS upgrade -> 101
```
Relay log shows migrations applied, the A3 git object-store conformance
probe
passing, and `buzz-relay TCP listening`.
I have not run `just ci` / `just test` — this touches no Rust, JS, or
mobile
code. Happy to run them if you'd like.
## Alternatives
- A `git-init` one-shot in `compose.yml` that chowns the volume. Works,
but adds
a container to every `up` and doesn't help `docker run` or Kubernetes
without
an `fsGroup`.
- Moving `BUZZ_GIT_REPO_PATH` to the code default `/var/lib/buzz/repos`
and
pre-creating that instead. Arguably tidier, since `/data/git` then only
lives
in the compose bundle — but it moves the volume mount point, so existing
installs would have to relocate their git data. Happy to do it that way
if you
prefer; it seemed the wrong trade for a bug fix.
Signed-off-by: Onno Klein Hofmeijer <onnokh@hotmail.com>