# W09 isolated Asterisk/ARI runtime PoC (2026-09-18) ## Scope and boundary This is an owner-authorized, mock-only compatibility probe on the existing Debian 13 ECS test host. It does not use a SIP provider, a real phone number, SaaS, RabbitMQ, OSS, AI credentials, or the production Agent binary. It is not W09, W13, W14, or P1 acceptance. The probe was deliberately kept outside the project module at `/tmp/ari-poc`. It uses the already reviewed temporary module: - `github.com/CyCoreSystems/ari/v5` `v5.3.1` - module checksum: `h1:S+NHG1+uMwoAIl0hMBnRUGNZsQKQQQFq7XCRSE2c2mg=` - Asterisk runtime: `22.10.1` - source image reference: `andrius/asterisk@sha256:1fde2a38e17c42c4f8999bb80d2ac52a01543bc696a98e02faee1cf6f14d4d64` - transferred image ID on the host: `sha256:08c732ed191c02ad54c019c4e6b46b641bb3ebbe42fcd5b525eb41c6373f6128` The image was transferred as an archive because Docker Hub was unreachable from the host. The host-local tag is only a transport/runtime tag; it is not a new upstream digest claim. The container is on the isolated Docker network `agent-call-asterisk-poc`, with ARI published only on host loopback `127.0.0.1:18088`. ## Runtime procedure The temporary Go probe: 1. listened on host UDP `0.0.0.0:19000` as the external-media sink; 2. connected to ARI with the mock `sipmock` application and mock credentials; 3. originated an internal `Local/900001@ari-gate` channel, with no provider leg; 4. waited for `StasisStart`; 5. created a `mixing` bridge and added the internal channel; 6. created an `ExternalMedia` channel using RTP/UDP, PCMA (`alaw`), direction `both`, and external host `172.18.0.1:19000`; 7. waited for the ExternalMedia `StasisStart`, added it to the bridge, read `UNICASTRTP_LOCAL_ADDRESS` and `UNICASTRTP_LOCAL_PORT`, and then hung it up; 8. observed `StasisEnd` for the ExternalMedia channel. The build and execution used the host-installed Go toolchain with `GOTOOLCHAIN=local`; the resulting probe binary was copied to the ECS host and run as `rogee`. ## Observed output ```text local_channel=ari-poc-local stasis_start channel=ari-poc-local args=[] bridge=ari-poc-bridge data=&{Key:ari-poc-bridge ID:ari-poc-bridge Class:stasis Type:mixing ChannelIDs:[01m2syek1a93x6jkz567r1m3j8-ch ari-poc-local] Creator:Stasis Name:ari-poc-bridge Technology:simple_bridge} external_channel=01m2syek1a93x6jkz567r1m3j8-ch state=Up name=UnicastRTP/172.18.0.1:19000-0x7f51780063b0 local_rtp=172.18.0.2:10748 probe_packets=0 peer= read_error=read udp4 0.0.0.0:19000: i/o timeout stasis_end channel=01m2syek1a93x6jkz567r1m3j8-ch ``` The first run exposed a real ordering requirement: adding ExternalMedia to the bridge before its `StasisStart` was observable returned HTTP `422`. Waiting for that event made the bridge add succeed. This is useful compatibility evidence, not a production implementation. ## Controlled RTP forwarding follow-up A second temporary probe used two independent ExternalMedia channels in the same mixing bridge. Both were configured as RTP/UDP, PCMA (`alaw`), direction `both`. The host listened on `172.18.0.1:19000` and `172.18.0.1:19001`, sent 20 synthetic RTP packets to the first channel's Asterisk-local port, and captured the bridge output at the second host port. The successful run, after restarting only the isolated PoC container to clear connections left by a timed-out disposable probe, returned: ```text connected bridge_created first_created=01m2szdw9r2s4erk251qpm4pme-ch first_stasis first_added second_created=01m2szdwa1p6a16jtqsyphcefj-ch second_stasis second_added bridge=ari-poc-media first=172.18.0.2:10724 second=172.18.0.2:10256 forwarded_rtp_bytes=172 peer=172.18.0.2:10256 version=2 payload_type=8 sequence=63988 timestamp=800 ssrc=1b5ec593 stasis_end channel=01m2szdwa1p6a16jtqsyphcefj-ch stasis_end channel=01m2szdw9r2s4erk251qpm4pme-ch remote_rc=0 channels: [] bridges: [] ``` This proves a controlled host-to-Asterisk-to-host RTP path through an Asterisk mixing bridge and confirms RTP version 2, PCMA payload type 8, and lifecycle cleanup. Asterisk rewrote the forwarded sequence/timestamp/SSRC; payload identity and production jitter/clock behavior were not assessed. ## Recording close follow-up A third temporary probe created the same two-channel synthetic bridge, started an ARI bridge recording with format `wav`, injected 40 PCMA packets, stopped the recording explicitly, and read the stored-recording metadata. The isolated container first received the missing `/var/spool/asterisk/recording` directory with `asterisk:asterisk` ownership; this was a disposable mock-container setup change, not a production artifact. The run returned: ```text connected recording_started name=ari-poc-record-20260918 format=wav state=recording forwarded_rtp_bytes=172 peer=172.18.0.2:10250 payload_type=8 recording_stopped name=ari-poc-record-20260918 format=wav stasis_end channel=01m2szqryme5sm3w89866j2key-ch stasis_end channel=01m2szqryxqpz6xgakr28bgdj0-ch recording_name=ari-poc-record-20260918 ``` The closed file was inspected before cleanup: ```text size=13804 mode=644 owner=asterisk:asterisk path=/var/spool/asterisk/recording/ari-poc-record-20260918.wav sha256=c62bede7c200c99a9fb9d73eee11ebefe71397b71aeff4dbfe0a05dc7d112e82 header=RIFF/WAVE, PCM mono, 8000 Hz, 16-bit channels: [] bridges: [] recording_cleanup=ok ``` The synthetic recording file was then removed from the disposable container. This proves ARI recording start/stop, a closed WAV header, and cleanup in the isolated environment; it does not prove business recording retention or OSS upload semantics. ## Result **Passed in isolation:** Asterisk 22.10.1 accepted the selected ARI client at runtime; internal Stasis channels and mixing bridges were created; RTP/UDP PCMA ExternalMedia channels reached `Up`; Asterisk-local RTP addresses and ports were retrievable; bridge insertion required and honored `StasisStart`; a controlled RTP packet stream traversed the bridge; an ARI bridge recording started and stopped with a valid closed WAV file; the artifact was cleaned; and both channels produced clean `StasisEnd` lifecycle events. **Not proven:** this remains synthetic ExternalMedia-to-ExternalMedia traffic, not a SIP/RTP provider leg or an Agent media session. The separate isolated SIPp-to-PJSIP/ARI signaling result is recorded in `docs/evidence/20260918-w09-sip-ari.md`. Full same-channel bidirectional semantics, exact PCMA sample preservation, reconnect/fencing behavior, provider lines, static artifact loading, Agent integration, retention/OSS upload, and capacity were not tested. The result therefore only advances the compatibility PoC and does not unlock W09's full M/G gate or any P1/production claim. ## Follow-up gate Before selecting ARI in the production module, retain this runtime result and complete the separate library/license/security review, full media-session and reconnect/fencing tests, approved static Asterisk/Cell artifact loading, retention/OSS handoff, and the remaining SIP/provider validation. Real provider and telephone tests remain under W14 authorization and are not implied by this document.