UNI Universal Natural Intelligence

Wiki · Evidence & Verdicts

Receipt — the fan-out supervisor stops lying (and I retract an overclaim)

Evidence & Verdicts · docs/receipts/fanout_supervisor_honesty_2026-07-16.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.

Date: 2026-07-16 · Track: studio · Surface: THINKER · viewer/command_center.cjs Gates: fanout-liveness-not-from-killed, fanout-arm-refuses-without-ffmpeg, flap-does-not-accuse-the-key, broadcast-test-stage4-partial-fails — all registered PENDING before the code changed; verdicts below.

Origin: the 52-agent adversarial sweep of 2026-07-16 (defects D2–D7). Everything here was found by trying to falsify the studio, not by reading it approvingly.


0. THE RETRACTION — I told the operator something that was not true

During the PIN/fake-key walkthrough I said, of the health board:

"This is the money shot … the health board says FLAPPING — 13 respawn(s) in 46s (rejected key likely: attach → refused → die → respawn)"

That narration was wrong, and the row it quoted was wrong. At that moment air was OFF. With no publisher on rtmp://127.0.0.1:1935/uni, ffmpeg dies at the input in ~0.2 s — it never opens a connection to YouTube or Twitch, so the fake key was never presented to anything. The flap I showed was caused by the absent program, not by key rejection. Measured:

condition respawns / 46 s
idle ingest, no keys implicated ~11
my "rejected fake keys" demo 13

Statistically indistinguishable. The row asserted the cause unconditionally; I repeated the assertion.

Why this matters more than a wrong sentence: G-PA requires ARM before the operator types CONFIRM, so the prescribed order guarantees a window in which perfectly good keys are accused of being rejected. The row was set up to send a live operator away to re-type working keys, mid-show, chasing nothing.

What survives: the stage-4 catch during the broadcast test was genuine — stage 2 starts the stream, so a publisher existed and the keys really were reaching the platform. Only the health-board narration (air off) was false. The gate did not lie; my sentence about the gate did.


1. D5 — a flap may only name the key when the key was actually sent

healthChecks() now reads the fact that separates the two causes — pmap.uni.ready, the local ingest's own publishing state, already in hand — and refuses to diagnose beyond what it can distinguish.

Rehearsal, air OFF, two fake keys armed:

--- AIR OFF, 2 fake keys armed ---
[RED ] Fan-out: YouTube #1 (YouTube)
        FLAPPING — but there is NO PROGRAM on the local ingest (:1935/uni is not publishing),
        so the pushers die at the input before your key is ever sent. YOUR KEY IS NOT IMPLICATED.
        This is normal when fan-out is armed before the stream starts.
[RED ] Fan-out: Twitch (Twitch)
        FLAPPING — but there is NO PROGRAM on the local ingest ... YOUR KEY IS NOT IMPLICATED.

Still RED (it is genuinely not pushing) — but it no longer accuses. Only a flap while the ingest is publishing may say A key <platform> is REJECTING is the usual cause.

Verdict: PASS. Note the fence: this proves the row states the honest cause in the no-publisher case. It does not prove the platform-rejection branch against a real rejecting platform — that needs a real key and real air, and is NOT VERIFIED.

2. D3 — liveness was derived from .killed, which is only true when we do the killing

alive was !!(rec.proc && !rec.proc.killed). .killed is set only when our code calls .kill(). A pusher that dies on its own — bad key, network drop, no input: i.e. every real failure — leaves .killed === false forever. Differential against a real child that exited by itself:

process is DEAD (exited by itself, exitCode=3); we never called .kill()
  .killed flag ............ false   <- only ever true if WE killed it
  OLD predicate (!killed) . true    <-- LIES: reports a corpse as alive -> green 'pushing ... stable'
  NEW predicate (exitCode). false   <-- correct: dead is reported dead

Now: exitCode === null && signalCode === null && !spawnFailed. Verdict: PASS.

3. D4 — the spawn-error handler was () => {}, and it killed the supervisor

Node emits 'error', not 'exit', when the binary cannot be spawned at all. The respawn timer hung off the exit path only, so a missing/renamed ffmpeg meant the loop stopped forever — silently.

OLD  p.on('error', () => {})
   respawn attempts in 2s .. 0      <-- the supervisor is DEAD. It will never try again.
   spawnFailed recorded ... null    <-- health row reads green '0 respawn(s), stable'
NEW  p.on('error', record + respawn)
   respawn attempts in 2s .. 6
   spawnFailed recorded ... ENOENT  <-- health row goes RED and names the cause

A supervisor that can die without saying so is not a supervisor. Also added a pre-flight: ARM now proves ffmpeg runs before claiming to have armed anything.

ARM pre-flight (ffmpegRunnable) against a missing binary:
   -> {ok:false, err:'ENOENT'} -- ARM REFUSES, HTTP 409, nothing claims to be armed

Positive control (real ffmpeg, this box): POST /api/fanout {on:true}{"ok":true,"count":2} — the pre-flight passes on a healthy box and does not block arming. Verdict: PASS (both gates).

4. D6/D7 — stage 4 passed the most realistic failure there is

The bar was readers >= 1. With two endpoints armed and one key bad, the healthy pusher pins readers to ≥1 at both samples — stage 4 went green with a platform dark. New bar: every pusher we ARMED must hold a reader, floored at 1 so the restream.ps1 path (where fanoutProcs.length is 0) does not become a permanent PASS — a worse lie than the one being fixed.

case                                    | OLD    | NEW    | NEW correct?
2 armed, BOTH healthy                   | PASS   | PASS   | yes
2 armed, ONE key bad (the real risk)    | PASS   | FAIL   | yes
2 armed, both dead                      | FAIL   | FAIL   | yes
restream.ps1 path (armed=0), 2 readers  | PASS   | PASS   | yes
restream.ps1 path (armed=0), 0 readers  | FAIL   | FAIL   | yes
1 armed, healthy                        | PASS   | PASS   | yes

Verdict: PASS. D7 (the 0-reader message said "turn FAN-OUT ON" while fan-out was on — sending the operator to flip a switch already flipped) is fixed in the same message: when armedN > 0 it names the two real causes and points at the per-endpoint rows that distinguish them.

5. D8 — a run getting longer must not make an alarm quieter

The flap rate was respawns / secondsSinceStart — a lifetime average with a growing denominator. A key revoked at hour 3 would read "stable" for ~22 minutes of dead air while the rate diluted. Now a trailing 60 s ring of exit timestamps: >= 6 deaths in the last minute is flapping, regardless of run length.

6. D2 — an orphaned PIN reported itself as a working one

hasPin was file existence. The reset path this panel itself prescribes ("delete endpoints*.enc by hand") can leave a wrapper with no store: PIN accepted, passphrase unwrapped, opens nothing — and it failed at pin-arm, seconds before air. Cheaply detectable at status time, so now said at status time (pinOrphan + a panel line in red). Live: {"hasPin":false,"pinOrphan":false,...} — no false alarm on a clean box.

Structural note: with the D1 module-boundary lock, no route can write the store under a different passphrase, so the "PIN silently wraps a stale passphrase after a rotate" half of D2 is now closed by construction rather than by a check. The trade is that passphrase rotation is not possible through the UI — there is no rotate route today; if one is ever added it must re-wrap the PIN in the same transaction.


Housekeeping — I removed the trap I left

viewer/runtime/endpoints.enc still held my demo store from the walkthrough. Because save() now authenticates against the store on disk, the operator's first real save would have been refused with "wrong passphrase" against a passphrase only I knew (demo-passphrase-2026). Deleted, after confirming every key in it was one I fabricated:

CONFIRMING what I am about to delete — every key must be a FAKE I created:
  YouTube #1   key=FAKE-yt-demo-key-0000-nope
  Twitch       key=live_000000000_FAKEDEMOKEYnope
All fake. Store deleted. exists now: false

The box is clean: no store, no PIN. The operator's first save starts fresh.

What is still NOT VERIFIED

  • The platform-rejection branch of the flap row against a real rejecting key on real air.
  • That any of this reaches a human not looking at the screen — the studio still has no alarm that leaves the monitor. That is the sweep's standing THE ONE CHANGE and is not fixed here.

sha256 9ec83a5d8add3997 — 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 record that opens with a retraction: the author told the operator something untrue and says so first. A health row had blamed a rejected key for a flapping process. But with nothing being broadcast, the process was dying at its input before any key was ever sent, and the measured rates with and without fake keys were indistinguishable. Worse, the prescribed order guarantees a window in which good keys get accused. Then several real defects are fixed, each with a rehearsal showing what the old behaviour would have reported beside the new one. Every gate for the work was registered as pending before any code changed.

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

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 receipt, the file recording what was run, whose first section is a retraction, in the author's own voice, of something said to the operator during a walkthrough. The sentence is quoted and then taken apart.

The correction is measured rather than argued. With nothing being published locally, the pushers die at their input in a fraction of a second, so no key was ever presented to anything, and the respawn rate during the fake-key demonstration is indistinguishable from the idle rate. The row asserted a cause it could not distinguish, and the narration repeated the assertion.

Why this matters more than a wrong sentence is the sharpest paragraph on the page. The prescribed order arms the destinations before the operator types the confirmation, so the procedure itself leaves a window in which perfectly good keys are accused of being rejected. That would send a live operator away mid-show to re-type working keys and chase nothing. What survives the retraction is stated too, because a different catch during the broadcast test was genuine.

Then the defects. A flap may now name the key only when the key could actually have been sent, using a fact already in hand about whether anything is publishing locally. The rehearsal shows the row staying red, because it genuinely is not pushing, while no longer accusing. The limit is explicit: this shows the honest message in the no-publisher case, and does not test the other branch against a real rejecting platform, which stays not verified.

Liveness had been derived from a flag that is set only when the code itself does the killing, so a process that died on its own, which is every real failure, read as alive forever. A differential against a real child that exited by itself is quoted, showing the old predicate reporting a corpse as healthy.

The spawn-error handler was empty, and the respawn timer hung off a path a failed spawn never takes, so a missing binary stopped the supervisor silently while the row stayed green. The principle is stated plainly: a supervisor that can die without saying so is not a supervisor. A pre-flight now proves the binary runs before anything claims to have armed, and refuses when it cannot.

A stage of the broadcast test passed the most realistic failure there is, because one healthy destination held the measured count above the bar while another was dark. The new bar requires every armed destination to hold one, with a floor so a different path does not become a permanent pass, which the page calls a worse lie than the one being fixed. A table shows old and new behaviour case by case, and a misleading remedy message is corrected in the same breath.

Two smaller items follow. An alarm's rate was a lifetime average with a growing denominator, so a failure at hour three would read as stable through a long stretch of dead air; it becomes a trailing window instead. And an orphaned unlock wrapper reported itself as working, which would have failed seconds before air, so it is now detected at status time. A housekeeping section removes a demonstration store the author had left behind, which would have refused the operator's first real save, with every key in it checked as fake before deletion. The page closes on what remains unverified, including that none of this reaches a person who is not looking at the screen.

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