> For the complete documentation index, see [llms.txt](https://jordan-7.gitbook.io/jordan-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jordan-7.gitbook.io/jordan-docs/internal/run-b-verification.md).

# Run B — real verification: how it works, what is proven, what remains

**Date:** 2026-07-28 · **Branch:** `feat/run-b-verification`

## The loop, end to end

1. **A clip plays** during an air session. The server opens a playback window and issues rotating codes bound to that playback (`bounty-watermark.js`). The overlay renders each code as **5×7 dot-matrix glyphs inside a white registration ring** (`public/code-matrix.cjs` — one font table shared by writer and reader, drift impossible). Concurrent **viewer count** is captured into the evidence chain at the same instant (Twitch Helix / Kick channels; unbackfillable).
2. **Verification samples timestamps** at code-validity midpoints (`bounty-verifier.js`), pulls frames from the **VOD** at those offsets (`frame-sources.js`: Helix archive discovery → extractor seam → ffmpeg grab; live HLS spot-check shares the path minus discovery), and decodes them with the **deterministic matrix reader** (`bounty-ocr.js`): locate the ring geometrically at any scale, sample the dot grid, match glyphs, measure `pixelHeight` — the anti-shrink number the verifier's floor enforces.
3. **Verified playbacks** flow to the release math (stubbed settlement), **ambiguous** results and **source-unavailable** states open review-queue items, and everything a payout is computed from lives in the append-only evidence chain.

## Detection rates (synthetic corpus, real overlay pixels, H.264-mangled)

| condition       | frames |                                                    found | rate | med. confidence | med. pixel height |
| --------------- | -----: | -------------------------------------------------------: | ---: | --------------: | ----------------: |
| present-1080p   |     12 |                                                       12 | 100% |           0.843 |            27.4px |
| present-720p    |     12 |                                                       12 | 100% |           0.843 |            18.7px |
| present-480p    |     12 |                                                       11 |  92% |           0.413 |            12.3px |
| high-motion     |     12 |                                                       12 | 100% |           0.843 |            27.4px |
| too-small (40%) |     12 | 0 clean finds — every read measured under the 12px floor |      |                 |                   |
| occluded (60%)  |     12 |                                                        0 |   0% |               — |                 — |
| absent          |     12 |                                    **0 false positives** |   0% |               — |                 — |

**Minimum verifiable stream quality: 720p.** At 480p the glyphs land at 12.3px — right at the verifier's 12px legibility floor — and detection drops to 92% with marginal confidence. 480p-only streamers can be verified but should expect occasional AMBIGUOUS results routed to review; below 480p the mechanic cannot verify and says so rather than failing silently. Corpus is regenerated by `node _corpus-run-b.mjs` (never checked in); rates by `node _gate-run-b-ocr.mjs`.

## Proven tonight (no live broadcast needed)

* The **entire distance over HTTP** (`_gate-run-b-pipeline.mjs`, 12/0): real issued code → real overlay pixels → 720p/3Mbps re-encode → real decoder → `PASS` at confidence 0.83 → release computed from it (stub).
* **Replay defense**: frames carrying a different session's code verify zero and pay nothing.
* **Failure honesty**: deleted/sub-only/unprocessed VOD, offline channel, or a missing extractor produce typed `SOURCE_UNAVAILABLE`, land in the review queue, and pay nothing while unresolved — never a FAIL.
* **Stingers undisturbed** after the badge change (real-page suites all green).

## Pending exactly one real broadcast

Live HLS grab and VOD discovery against a real channel, end to end. The one-command harness:

```bash
node _rehearsal-run-b.mjs --handle <twitch-login>
```

With `TWITCH_STREAM_KEY` set it broadcasts unattended (overlay screencast over a test pattern via RTMP, \~12 min — set a test title on the channel first); already live with the overlay in OBS, pass `--skip-push`. It opens a real air session, drives three real playbacks, live-spot-checks mid-broadcast, polls for the VOD, runs the primary verification, and prints verdicts + release rows + where the viewer samples landed.

## Timestamp tolerance

±1.5s, derived: sampling happens at code-validity midpoints and the shortest window (code clamped to a 3s clip end) leaves ≥1.5s of on-screen code either side; ffmpeg's pre-input seek is accurate well inside that.

## Kick

Identity claim (OAuth 2.1 + PKCE, slug-based), app-token live status and viewer capture all real. **VOD discovery does not exist in Kick's official public API** — VOD pages extract fine by direct URL, but timestamp→VOD lookup needs the unofficial Cloudflare-guarded v2 web API. Kick verification is live-first; operator-supplied VOD URLs work. Platform finding, filed.

## Where I would attack it (design pushback)

1. **Play the clips to nobody.** The verifier proves clips AIRED, not that anyone watched. Stream at 4 a.m. to zero viewers, play everything, collect. Viewer samples are already in evidence — the payout formula should weight by them (that was the point of capturing them), but nothing enforces it yet. **This is the weakest joint.**
2. **Point the overlay at a private "broadcast".** Push the overlay to the claimed channel, but make the actual content a static image with clips "playing" server-side while the stream shows nothing else. Codes air, verification passes. Defense: moderation + streamer approval don't help (it's the streamer doing it); viewer-weighting again is the answer — a nothing-stream has no audience.
3. **480p on purpose.** Stream at the marginal quality so most samples read AMBIGUOUS and land with a human who might wave them through. The review queue's SLA pressure is the exposure; reviewers need the detection-rate table (this doc) as context.
4. Re-streaming someone else's broadcast with the overlay composited on top — codes air over stolen content. Moderation of the CLIPS doesn't see the surrounding stream. Platform ToS enforcement is the realistic backstop; we cannot verify surrounding-content ownership from frames alone.

The defense holds where money is computed from evidence (codes, sizes, replay, source honesty). It does not yet hold where the mechanic meets economics: **verified airtime with zero audience still pays**. Viewer-weighted release is designed for, captured for, and should be the next money change.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://jordan-7.gitbook.io/jordan-docs/internal/run-b-verification.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
