v0.49.9

thevoiceguy/siphon-aiv0.49.9Aug 21, 2026by github-actions[bot]

Upgrading?

AI Summary

Fixes two outbound call path issues: swapping the `From` URI mid-dialog and a dialog memory leak where successful transactions were not removed from the manager.

Key Highlights

  • Fixed `From` URI swapping on outbound legs per RFC 3261 §12.2.1.1.
  • Fixed dialog leak in outbound teardown path.
  • Added User-Agent stamping to 15 upstream request builders that previously lacked it.

Full Release Notes

Two fixes to the **outbound** call path, both found while verifying the
0.49.8 deploy and both older than it. Neither affects a node that only
accepts inbound calls; both matter to one that originates.

**No config change, no protocol change** (still `1`), CDR still v8. Wants
a restart to take effect.

### Fixed

- **In-dialog requests on outbound legs stop swapping their `From` URI
  mid-dialog** (#549), via siphon-rs `v2026.08.20.1` → `v2026.08.21`
  (its #121, opened from here). A UAC dialog's local URI now comes from
  the dialog-forming request's `From` rather than the client's configured
  identity, per RFC 3261 §12.2.1.1. Every outbound leg sets a per-call
  `From` — a `[[gateway]]`'s `from`, or its `[[register]]` AOR, is the
  caller-ID — so our BYE went out as `sip:siphon@<public_address>` on a
  dialog the INVITE had opened as the AOR, same tag. FreeSWITCH tolerated
  it (it matches on Call-ID + tags); a URI-validating peer answers `481`
  and the leg then hangs to the far end's media timeout, and From-based
  CDR correlation splits one call across two identities. The same release
  stamps `User-Agent` on the 15 of 27 upstream request builders that never
  did — our ACK and BYE carried none, so 0.49.8's product token covered
  only part of a call's traffic. Tag bump only; no API change, no config
  change, sip-uac 0.7.0 → 0.7.1.

- **Outbound calls no longer leak a dialog apiece** (#548). Gateway UACs
  are built with the UAS's `DialogManager` (#324), so an originated
  call's confirmed dialog lands in the shared store — but only the
  inbound teardown retired one, so the store grew by one entry per
  originated call for the life of the process and
  `siphon_ai_dialogs_active` never came back down. Past `sip-dialog`'s
  `MAX_CONFIRMED_DIALOGS` (10,000) `insert` fails silently and in-dialog
  requests stop matching — for inbound calls too, since the store is
  shared. The outbound teardown now retires its dialog after the BYE
  exchange, on the same deferred grace window the inbound path uses
  (#458), whichever side hung up. Present since #458 first shipped in
  0.48.13; a node that only accepts inbound calls was never affected.

---

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