v0.49.3
thevoiceguy/siphon-aiv0.49.3Aug 19, 2026by github-actions[bot]
Upgrading?
AI Summary
Adds per-call SIP ladder inspection and advisory scanning to the CI pipeline.
Key Highlights
- New `/admin/v1/calls/{id}/sip` endpoint and sightglass `s` pane for inspecting SIP messages.
- Added `cargo audit` to CI pipeline for vulnerability scanning.
- SIP capture enabled by default with a bounded ring.
New Features
- Per-call SIP ladder endpoint
- cargo audit CI job
Full Release Notes
Two additions, both operator-facing: a per-call SIP ladder you can read
without leaving the terminal, and advisory scanning in CI so the next
RUSTSEC finding arrives as a failing check rather than a hand run. **No
protocol change** (WS stays `version: "1"`), **no CDR change** (still
v8), and no upstream dependency movement — siphon-rs and forge-media are
pinned exactly where 0.49.2 left them.
Upgrade note: `[observability].sip_ring_size` defaults to `50`, so SIP
capture is **on** after this upgrade. It holds recent messages
unredacted in memory and the endpoint serving them is `operator`-gated —
see *Admin auth & RBAC* in `docs/DEPLOY.md`, and set it to `0` to opt
out.
### Added
- **Per-call SIP ladder: `GET /admin/v1/calls/{id}/sip` and sightglass's `s` pane** (DESIGN_SIP_LADDER.md). Select a call on sightglass's calls tab, press `s`, and see its signaling — the SIP messages the daemon captured for it, oldest first, timestamped relative to the call's first message because the gaps are what a ladder is read for. `⏎` expands one message to full raw text, `y` copies it via OSC 52 (works over SSH; no clipboard dependency added).
- **`operator` role, deliberately unredacted.** The endpoint returns messages verbatim, `Authorization` and `Proxy-Authorization` headers included — a redacted ladder invites the wrong conclusion about what actually went over the wire, so the access boundary is the token role rather than the content. This is **the first `GET` on the admin API gated above `readonly`**, and `DEPLOY.md` now states plainly that on a default install an `operator` token can read recent credentials. `--read-only` mode does not block it: the ladder changes nothing on the node.
- **Capture is a new sink leg, not a new capture mechanism.** siphon-rs's `sip-hep` owns no transport — it emits into the `HepSink` handle siphon-ai constructs — so every SIP message already passed through the process with the raw bytes, the `Call-ID` as correlation id, `src`/`dst` and a timestamp. No siphon-rs change, no second parse of the wire, no new dependency.
- **Works with HEP shipping off.** `HepTelemetry::build` now takes an optional collector plus extra in-process sinks; with `[observability.hep]` absent it opens no socket and spawns no worker, and a single sink leg is used directly rather than wrapped, so a HEP-only node keeps its exact previous call path. Teeing off the UDP sink instead would have left the pane silently *empty* on a node that ships nothing to Homer — "no messages" rather than "not enabled", the worst failure mode for an observability feature.
- **Bounded three ways, because most SIP dialogs are not calls.** Per call: 64 messages (`[observability].sip_ring_max_messages`), oldest-within-the-call dropped and the response flagged `truncated`. Completed calls: 50 (`sip_ring_size`, defaulting to `cdr_ring_size` so the recent-calls pane and the ladder never disagree about what is inspectable). And a third bound the design note missed — REGISTER refreshes, OPTIONS and, on a public-IP node, scanner INVITEs rejected with 403 all carry a `Call-ID`, all reach the sink, and none ever becomes a call, so none would ever be evicted by a completed-call window; the reference node alone would feed it ~1,440 REGISTER cycles a day. Pending traces are capped at 256 and evicted least-recently-touched.
- **Enabled by default** (`sip_ring_size = 50`); `0` disables capture entirely and the endpoint answers `501`. Sightglass renders `501` (capture off), `403` (token too low) and `404` (unknown call, or a pre-0.49.3 daemon) as notes *inside the pane* — none of them marks the node down. The pane is polled only while open: it is the one payload sightglass fetches measured in kilobytes.
- New metrics `siphon_ai_sip_ring_messages_total{result}` and `siphon_ai_sip_ring_traces` (named *traces*, not *calls*, for the same reason the third bound exists). No protocol change, no CDR change, nothing written to disk. **Not a Homer replacement** — minutes of history, one node, no search; `docs/HEP.md` remains the answer for anything in depth.
- **`cargo audit` in CI** (`.github/workflows/audit.yml`) — this repo had no advisory scanning at all, which is why [RUSTSEC-2026-0258](https://rustsec.org/advisories/RUSTSEC-2026-0258) sat in the lockfile for two days and then surfaced from a hand run rather than a check (see 0.49.2). The sibling forge-media repo caught the same advisory the day it published, because it has this job.
- The trigger set is deliberately **not** test.yml's. A **daily schedule** is the case that actually matters — an advisory lands against code nobody touched, so no push and no PR will ever fire a check, only a clock. **`push` to main** keeps the default branch's status honest between nightly runs. **Pull requests are gated on dependency files only** (`Cargo.lock`, `Cargo.toml`, the workflow itself): gating every PR means a newly published advisory turns unrelated work red through no fault of its own, which is exactly what happened to [forge-media#107](https://github.com/thevoiceguy/forge-media/pull/107) — a redis bump left sitting on an h2 failure it had nothing to do with.
- Fails on **vulnerabilities only**. The informational "unmaintained"/"unsound" advisories (currently 6: audiopus_sys, paste, rustls-pemfile, anyhow, lru ×2) are reported without failing the run — a gate that is chronically red gates nothing.
- `cargo audit` reads `Cargo.lock` and never builds, so the job needs no system libraries and no workspace compile.
---
**Artifacts**
- Static musl binaries for `x86_64` and `aarch64` (`.tar.gz`).
- Debian packages (`.deb`) for `amd64` and `arm64` — `apt install ./siphon-ai_*_amd64.deb`.
- `SHA256SUMS` — verify with `sha256sum -c SHA256SUMS`.
- `*-sbom.cdx.json` — CycloneDX SBOM.
- `SHA256SUMS.cosign.bundle` — cosign keyless signature over the checksums.
- Container: `ghcr.io/thevoiceguy/siphon-ai:v0.49.3` (multi-arch, cosign-signed).
Verify the checksums signature:
```
cosign verify-blob --bundle SHA256SUMS.cosign.bundle \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp 'release.yml@' SHA256SUMS
```
Related Repositories
farion1231/cc-switch★ 147,624
A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io
rustdesk/rustdesk★ 126,606
An open-source remote desktop application designed for self-hosting, as an alternative to TeamViewer.
tauri-apps/tauri★ 112,115
Build smaller, faster, and more secure desktop and mobile applications with a web frontend.
ruvnet/RuView★ 99,148
π RuView turns commodity WiFi signals into real-time spatial intelligence, vital sign monitoring, and presence detection — all without a single pixel of video.
oven-sh/bun★ 96,344
Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one