UNI Universal Natural Intelligence

Wiki · Evidence & Verdicts

Receipt — `music-nowplaying-advances`: **PASS**

Evidence & Verdicts · docs/receipts/music_nowplaying_advances_2026-07-18.md @ 44baf03d5041 (gen2-runtime) — opens the published snapshot ac338733bbba

How to read this page

Three ways to read this page. Precise is the document itself, exactly as it is written in the repository. Plain and Clear were written for this website to help you meet that document — they are about it. They are not it, and they are not evidence.

Eighty-seven dated pages: receipts, pre-registrations, handoffs, validation records and review verdicts. A receipt is written at the moment a piece of work was checked. It names what was claimed, the commit and the seed, what was actually run, and the outcome in one of a small set of controlled words. Then it names what the work did not achieve. That last part is what makes it a receipt rather than an announcement. A pre-registration is the same discipline run in advance: the conditions that would count as a pass and the conditions that would falsify the claim are written down before the run, so neither can be adjusted once the numbers arrive.

That is why so many small dated stubs are an audit trail rather than noise. No one of them is meant to be a good read. The value is in the sequence and in the dates, because you can watch a prediction be registered, then the run happen, then the verdict land — sometimes against the prediction. Pages here record a falsified result, a rejected fix, a retracted overclaim, and a green receipt that turned out not to be reproducible from the commit that carried it. A record that carried only successes would be worth a good deal less than this one.

A gentle way in is to read a pre-registration first, so the shape becomes familiar, then a result page, then one of the corrections. This section sits off the main navigation on purpose: it is the record you check the rest of the site against, not the place to begin.

What it is not: documentation, and not a summary. Nothing here has been tidied in hindsight. Every entry reads as of its date, a later entry may overturn an earlier one, and the presence of a page is not a claim that its result stood.

Your browser cannot switch reading levels, so the document itself is shown.

Precise — the source document

This is the document. Rendered from the repository at the commit above, with nothing rewritten for the web. A gate re-renders it on every deploy and fails the build if a single byte differs.

Seat: science agent (chip-side services) · Date: 2026-07-18 (UTC timestamps 2026-07-19) Gate: music-nowplaying-advances · Verdict: PASS · Evidence class: B (observed-with-artifact) Root cause receipt: docs/receipts/music_nowplaying_stuck_root_cause_2026-07-18.md Fix: deploy/uni-os/cpradio/patch_session_liveness.py · Runbook: docs/runbooks/RADIO_AND_TELEMETRY_DEPLOY_2026-07-18.md Stage A

1. What was deployed

Applied the session-liveness patch to cpradio's /data/server.py (volume musicradio, rootful podman, mounted RW:false into the container so the write happened from a separate container with the volume mounted read-write), then restarted cpradio.

  • Backup preserved: /data/server.py.bak-pre-liveness-20260718 (20,766 B original vs 25,835 B patched).
  • Patch is idempotent, anchor-exact (all 11 anchors verified present exactly once beforehand), and ast-gated before writing. A post-write ast.parse also returned POST_SYNTAX_OK.
  • Two operator approvals were required, not one — the patch call and the restart call are separate mutating MCP invocations.

2. PASS evidence — both clauses satisfied together

Gate wording: two probes ≥ 60 s apart during a live radio stream MUST show either seq incrementing OR title/artist changing to a NEW pair; AND positionSec MUST NOT exceed durationSec + 5 across any successful probe.

Observed on session=obs-studio-thinker with OBS genuinely attached (not a synthetic probe):

seq=1  "Dracos & Cartiers"   43s / 153.2s
seq=1  "Dracos & Cartiers"   59s / 153.2s
seq=1  "Dracos & Cartiers"   76s / 153.2s
seq=1  "Dracos & Cartiers"   91s / 153.2s
seq=1  "Dracos & Cartiers"  101s / 153.2s
seq=1  "Dracos & Cartiers"  111s / 153.2s
seq=1  "Dracos & Cartiers"  124s / 153.2s
seq=1  "Dracos & Cartiers"  142s / 153.2s
seq=2  "Fake Cartiers"        4s / 139.3s   <<< ROLLOVER
seq=2  "Fake Cartiers"       15s / 139.3s
  • Clause 1 — BOTH forms satisfied: seq incremented 1 → 2 AND the title changed ("Dracos & Cartiers""Fake Cartiers"). Earlier in the same session it also stepped 0 → 1 ("Dead Faces""Dracos & Cartiers"), so this is sustained catalog advance, not a one-off boundary artifact.
  • Clause 2: positionSec never exceeded durationSec at any sample — 142 < 153.2, then a clean reset to 4 against the new track's 139.3. Compare the pre-fix phantom session: positionSec 10942.7 against durationSec 94.9 — a 115× overshoot.

FALSIFIES condition (seq fixed AND title unchanged AND positionSec > durationSec + 30 on two consecutive probes ≥ 60 s apart) was not observed.

3. Leak-regression clause — the actual root cause, cured

The gate's second clause exists because the defect was never a stuck advance loop; it was a leaked session record. Measured directly:

Probe Before fix After fix
/api/telemetry activeListeners 1 0
ss -tn state established 'sport = :8687' 0 0
Agreement NO — a ghost YES

And the leak scenario was reproduced deliberately on the patched service: a real listener was attached (activeListeners 0 → 1, position advancing at exactly 1.0× real-time, 6.0 s → 76.1 s over 70 s wall clock, ratio 0.80× of the 94.9 s track), then the connection was abruptly killed. Within 45 s activeListeners fell 1 → 0 and /api/nowplaying returned status=no-session with no positionSec field at all. Pre-fix, that same action stranded a ghost permanently with an unbounded playhead.

This also confirms the patch is live in the running process, not merely on disk: the socket timeout, the finally: cleanup and the reaper thread are the only things that can produce that 1 → 0 transition. (Grep-in-container was unavailable as unicpradio is rootful — so the behavioural proof is the stronger and the used one.)

Restart side-benefit, not the fix: the 10 stranded MAX_LISTENERS slots cleared (totalConnections 10 → 0). The slow-burn 503 stream full trajectory is removed structurally by deriving activeListeners from len(SESSIONS).

4. OPERATIONAL FINDING — a cpradio restart strands OBS on a half-open socket

This will recur on every future cpradio restart. Budget for it.

After the restart, obs64 still held an ESTABLISHED connection to :8687 created 4.5 hours earlier, from before the restart. OBS reported OBS_MEDIA_STATE_PLAYING with an advancing cursor while /api/nowplaying returned no-session for 3+ minutes. From OBS's side it looks perfectly healthy and is completely dead.

  • TriggerMediaInputAction RESTART did NOT clear it — returned success, changed nothing.
  • What worked: clear the source's input to "", wait 3 s, then restore the URL. That forces ffmpeg_source to drop the socket and open a fresh one. activeListeners went 0 → 1 immediately.

Cross-reference only — this is a studio-seat recovery step, owned by the studio agent and performed by them here. Recorded in this receipt and in the runbook so the next chip-side restart is not diagnosed as a server regression.

Explicitly not a regression in this patch: the transient activeListeners=0 was proven at the time to be OBS-side, by a manual probe (probe-test-sid) that registered instantly with status=OK and a real position while OBS still showed nothing. The service was fine throughout.

5. Air

Air never dropped during the deploy: uni READY, readers=2, 12.9 GB egress, fan-out armed with aliveCount=2 throughout. cpradio is not in the video or egress path — only the music bed was silent for the restart window. uni-colony, uni-producer, the fan-out and THINKER were untouched.

6. Honest scope of this verdict

PASS means: the reporter advances with the catalog for a live session, never reports an unbounded playhead, and no longer strands sessions that have no peer. It says nothing about audio quality, nothing about the studio-side rendering path, and nothing about awareness or life — it is a straightforward service-correctness gate on a metadata endpoint.

Not deployed by this receipt: /api/reset and /api/skip ship present but disabledRADIO_ADMIN_TOKEN is unset, so both return 503 not configured. Do not describe them as secured unless that token is actually set.

sha256 86768208d284aba7 — of the original file, so what was ingested stays checkable.

Plain — written for this website, not the source document

Written for this website — not the document. This is a plain-language retelling, written to help you meet the document. It is not the source, and it is not evidence. It has not yet been checked by a person. (or choose Precise in the reading-level control above)

A pass verdict for a fix that an earlier record had written but not deployed. The patch was applied, the service restarted, and two conditions were checked together against a genuinely attached listener rather than a synthetic probe: the track advanced, and the reported position never ran past the length of the track. The leak that caused the original fault was then recreated deliberately, and it healed itself within a minute. One operational finding is recorded for next time, because restarting this service leaves the consumer holding a dead connection that looks perfectly healthy from its own side and does not recover by itself.

Plain · written 2026-08-01 by claude-opus-5 · not yet checked by a person · about the document whose sha256 is 86768208d284aba7

Clear — written for this website, not the source document

Written for this website — not the document. This is a clearer retelling, written to help you meet the document. It is not the source, and it is not evidence. It has not yet been checked by a person. (or choose Precise in the reading-level control above)

A pass verdict, with its evidence class stated and the file recording its root cause named. The fix described in that earlier receipt was written and not deployed; here it is deployed and measured.

The deployment is described precisely, including the awkward part. The source is mounted read-only inside its own container, so the write came from a separate container with the volume mounted writable. A backup is preserved, sizes before and after are given, the patch is idempotent and matched against exact anchors, and the file is parsed before and after writing. Two separate human approvals were needed rather than one, because the patch and the restart are separate mutating calls.

The pass evidence quotes the gate's own wording and then the samples, taken with a listener genuinely attached rather than against a synthetic probe. Both forms of the first condition are satisfied, since the sequence number advances and the title changes. The page notes an earlier advance in the same session, so this is a sustained progression through the catalog rather than a one-off at a boundary. The second condition holds at every sample, and it is set against the pre-fix reading, where the position had run past the track length many times over.

The most convincing section reproduces the original fault on purpose. A real listener is attached, the position advances in step with the clock, and the connection is then killed abruptly. Within a minute the count falls to zero, and the endpoint reports no session at all rather than a stranded record with an unbounded position. That behaviour is also used as evidence the patch is live in the running process rather than only on disk, since only the new parts can produce it. Searching inside the container was unavailable, and the page says the behavioural evidence is both the stronger and the used one.

Then an operational finding written for the future rather than for this run. Restarting the service leaves the consumer holding a connection opened hours earlier, which looks entirely healthy from its own side and is completely dead. The obvious remedy did nothing; what worked was clearing the source's input and then restoring it. It is cross-referenced as somebody else's recovery step and recorded so that the next restart is not misdiagnosed as a server regression. A transient zero reading is explained as being on the consumer's side, and was shown to be so at the time by a separate probe.

The closing scope is deliberately narrow. The pass means the reporter advances, never reports an unbounded position, and no longer strands sessions with no peer. It says nothing about audio quality, nothing about the rendering path, and nothing about awareness or life. Two administrative verbs ship present but disabled, with an instruction not to describe them as secured unless the token is actually set.

Clear · written 2026-08-01 by claude-opus-5 · not yet checked by a person · about the document whose sha256 is 86768208d284aba7