v0.49.4

thevoiceguy/siphon-aiv0.49.4Aug 19, 2026by github-actions[bot]

Upgrading?

AI Summary

Fixes the SIP ladder's `direction` field for wildcard-bound nodes, which was showing 'unknown' for nearly every message.

Key Highlights

  • Fixed `direction` field showing 'unknown' for wildcard IPs (0.0.0.0).
  • SIPp CI job improved to handle slow apt mirrors.

Full Release Notes

### Fixed

- **The SIP ladder's `direction` field was `"unknown"` for every message on a wildcard-bound node — i.e. on nearly every real deployment** (shipped in 0.49.3; found by running the 0.49.3 release artifact against a production-shaped node rather than in a test). siphon-rs stamps a HEP packet's local end with the **socket's** address, so on the usual `listen = "0.0.0.0:5060"` our own end is literally `0.0.0.0`. The derivation matched only `[node].public_address` and a non-wildcard bind IP, so neither end matched and the field fell through to `"unknown"` — sightglass drew `·` for every message and the ladder's arrows never rendered. Confirmed from a production node's own Homer capture: inbound `srcIp <peer> / dstIp 0.0.0.0`, outbound the reverse.
  - The **loopback** case failed the opposite way: both ends are `127.0.0.1`, both match, the `src` arm wins, and every message read `"out"` — including inbound INVITEs. That is how it surfaced, driving a real call through the shipped binary in a lab second instance.
  - **Fix:** an unspecified IP (`0.0.0.0` / `::`) counts as one of ours, which is exactly what siphon-rs means by it; and when *both* ends look local, the SIP bind port breaks the tie. Port is consulted **only after** IP has failed, never before — a port-first test mislabels inbound traffic, because SIP peers overwhelmingly send *from* 5060 too, and that earlier regression test still passes unchanged.
  - No API, config or schema change: `direction` already documented `in`/`out`/`unknown`, and `src`/`dst` were correct throughout, so this is a label fix rather than data recovery. Nodes on 0.49.3 lose nothing by upgrading; their captured messages were always accurate.

### Changed

- **The SIPp CI job no longer loses its whole budget to a slow apt mirror.** The install step cancelled the entire 15-minute job four times in a row on 2026-08-19 without running a single scenario: the runner's `azure.archive.ubuntu.com` mirror returned `Ign:` for every index and the `archive.ubuntu.com` fallback hung inside `apt-get update`. The step now tries the install against the indices the runner image already ships with — skipping the refresh entirely in the common case — and only falls back to `apt-get update` when a package is genuinely unresolvable, with retries, per-request timeouts, and its **own 6-minute budget** so a mirror outage is reported as itself instead of silently consuming the scenarios' time.

---

**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.4` (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