From 5771dc63ccea70405f3258848e54891afd08049b Mon Sep 17 00:00:00 2001 From: vivekchand Date: Fri, 11 Sep 2026 06:39:55 +0200 Subject: [PATCH] [RELEASE] Fish Audio is the 24th chat channel (carries #5055) Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xb6A5G74JiMe3zHFs1JZEP --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 395e79af0d..1b451fda3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ ## Unreleased +### Added: Fish Audio voice/telephony is the 24th chat channel (2026-09-11) +- **Why:** people delegate to agents through chat, so a channel ClawMetry cannot see is a conversation that does not exist in the product — the shape of the original report, *"I message Diya on Telegram and ClawMetry shows nothing"* (#5045). +- **What:** `fish-audio` joins the channel catalogue, its transcripts ingest from `~/.openclaw/fish-audio/*.jsonl`, live events arrive over the gateway tap as `fishaudio`, and `/api/channel/*` serves the tab. The channel count is derived, not typed, so every surface quoting it moved to 24 together. +- **A chat channel is four independent lists, and one in three of them is broken.** `sync._CHANNEL_DIRS` (history ingests), `gateway_tap.CHANNEL_NAMES` (live events arrive), `entitlements.ALL_CHANNELS` + `CHANNEL_LABELS` (the UI and entitlement can see it), and `routes/channels.py` (the endpoint exists). Each omission is silent and looks like a different bug: miss the gateway list and live messages never arrive while historical transcripts ingest normally, which reads as an ingest fault rather than a missing subscription. +- **That rule is now a check, not a review item.** `tests/test_channel_four_lists.py` asserts every catalogued channel appears in both ingest lists, that neither carries an orphan the catalogue does not know, that each has a label, and that the three lists are the same size. Comparison is on a normalised form, because the disk name and the wire name legitimately differ (`fish-audio` on disk, `fishaudio` on the wire) and deriving one list from the other is exactly what the architecture forbids. +- **A comment that would have caused the next half-wired channel is corrected.** The note above `_CHANNEL_DIRS` said adding a directory needed "no further wiring required" — false in precisely the way above — and still claimed "21 adapter routes" when there are 24. It now names all four lists with the symptom for each. +- **Recorded in the product record.** Drift Bot's five findings were one omission: adding the 24th adapter exposed that the whole subsystem had no record. The Runtime and Session Observability blueprint now carries six contracts and an ADR for why these stay four explicit lists rather than one derived registry. +- **Verified:** the four-list guard proven red against a deliberately half-wired channel and green on the tree; `tests/test_entitlement_channel_catalog.py` (27 tests) and the count guard both pass, reading 24 across every surface. Carries #5055, closes #5045. + ### Added: the onboarding strip can tell whether anything is actually reaching us (2026-09-11) - **Why:** a new user wiring up their first runtime had no way to see whether it worked. `GET /api/onboarding/ingest-status` answers "is anything arriving yet?", polled every 2 seconds while the overlay is open (#5680). - **What:** `LocalStore.query_ingest_status()` does two light passes over `events` — one aggregate (total, 24-hour bucket, first/last timestamps) and one `GROUP BY agent_type` for the per-source breakdown — plus the route in `routes/onboarding.py` and its entry on the daemon query surface in `routes/local_query.py`. No scan of `data` blobs; zone maps on `created_at` keep both passes fast on a large store. Rows written by ClawMetry's own daemon are excluded, so the strip cannot read its own heartbeat as the user's agent.