The suite had not been run since 2026-08-23 and deps were not installed. Running it
against the freshly rolled m12-vsc-20260830 found four failures. Every one was the
harness doing its job; three were stale pins it explicitly told me to invert.
REAL FINDING, caught by the suite and nothing else: tidaldb-2 was NotReady mid-run.
It had exited(0) with {"reason":"reseed_self_restart","shard":1}, reinstalled a
snapshot and converged. Designed behavior - but the suite sampled readiness ONCE and
reported a self-healing cluster as broken. Readiness is now polled via
waitForPodsReady with a bounded budget and the whole timeline attached as evidence.
Deliberately not Playwright retries: retries:0 is correct here, because a live check
that only passes on attempt two has told you something true.
STALE PINS INVERTED (each verified live first, not taken on the message's word):
- 06-logs: ANSI escapes are gone (0 in a 5-line sample), BUG-006 resolved on this
image. Now pinned so a regression to coloured output fails.
- 09-operator-authority + CAP-015 capture: tidaldb_http_* exists (185 series
against a 552 baseline). Runbook 9.1 moved from inert to LIVE. CAP-015 keeps its
purpose - state the gaps - and now names the one that is still real: no JSON_LOGS.
- The transient /search 500 and public 502 were tidaldb-2's restart window, not
defects; both surfaces returned 200 on eight retries afterwards.
THRESHOLD CALIBRATED AGAINST A MEASUREMENT, TWICE. My first fix capped
consecutive ship failures at 500, guessing a restart burst was ~100. Measurement
killed it: a reseed restart is a ~2 minute absence, which at the shipper's 100ms
cadence is ~1200-2000 failures - observed exactly 1950, then "peer recovered", with
peer_acked_seqno back at the frontier. A COUNT cannot separate "a peer restarted"
from "shipping is stuck"; it only encodes how long the peer was away. The test now
compares the newest distress line against the newest recovery line and fails only
when distress is newer. Same correction applied to the alert in k3s-fleet.
STALE EVIDENCE WAS THE WORST GAP. demo/public/captures and capture-manifest.json
still described m12-admin-gate-20260823 - two image rolls stale - while
demo:preflight reported "audited perfect" about week-old frames, and the rendered
title card read "image m12-admin-gate-20260823 - 32 checks green". The capture suite
writes to test-results/demo-captures/ and the copy-and-merge step into the published
set simply did not exist; it was done by hand once. Added demo/promote.ts: copies
frames, verifies each PNG against its fragment hash, and stamps buildRevision and
verifiedImage from the live StatefulSet. Verdicts land `pending`, so preflight fails
until the frames are audited - that failure is the gate. scenes.ts now derives the
image tag and check count from the manifest, and preflight fails if a literal is
pasted back in (proven by pasting one back in).
All 10 captures were opened individually at full resolution; the audit note is stored
in the manifest beside each verdict rather than only in prose.
Green: 34 e2e + 5 hermetic semantics + 10 captures + preflight + 2107 lib.
Video: demo/out/deploy-verification.mp4, 90.05s 1920x1080 h264, title card now
reading "image m12-vsc-20260830 - 34 checks green".
CLAUDE.md gains a Deploy Verification section and AGENTS.md a short mandatory
pointer: every deploy is verified through this harness, and maintaining it is part
of the change, not follow-up. The suite pins current reality including defects, so a
correct improvement WILL turn it red - and that is the harness working.
15 KiB
Visual audit — tidalDB deploy verification walkthrough
Audited against audience-brief.md. Per-screen verdicts are judged at the
quality-bar judge's standard (Kyle Kingsbury); the walk-the-render ledger is
written in the actual decision-maker's voice (Jordan Washburn).
- Build revision: see
capture-manifest.json.buildRevision(do not retype it here) - Verified image: see
capture-manifest.json.verifiedImage— stamped from the live StatefulSet bydemo:promote. It readm12-admin-gate-20260823here for a week after two image rolls, which is why this file no longer carries its own copy. - Render:
demo/out/deploy-verification.mp4— 90.05 s, 1920×1080, 30 fps, h264, 2700 frames - Regression suite at time of capture: 34 passed (32 deployment + 2 cluster ranking tripwires)
Re-audited 2026-08-30 for
m12-vsc-20260830(8aa1fbb). All 10 captures re-shot and re-audited at full resolution; per-capture verdicts and the audit note now live incapture-manifest.json(auditedAt,auditNote) rather than only in this prose. Two panels changed meaning with the roll:CAP-015-inertnow reports HTTP metrics LIVE with unstructured logs as the remaining gap, and the title card derives its image tag and check count from the manifest instead of hardcoding them. The tables below are the 2026-08-23 audit, retained as the prior record.
- Hermetic ranking-semantics suite: 5 passed (
npm run test:e2e:semantics, no cluster required) - Demo capture suite: 10 passed (each asserts before it photographs)
1. Programmatic preflight
| Check | Result |
|---|---|
| Every manifest file exists and decodes | pass — 10/10 |
| Filesystem inventory equals ledger count | pass — 10 promoted, 10 rows, 0 unclassified |
| Dimensions match declared viewport or documented crop | pass — 9 × 1600×900, 1 × 1600×502 (documented crop) |
| Files non-empty, not near-uniform blanks | pass — 64 KB–187 KB |
| Capture IDs and filenames unique | pass |
| No unexpected duplicates across distinct proof states | pass |
| Source test green | pass — 10 demo capture tests green; each asserts before it photographs |
| Secrets / tokens / local paths absent | pass — redact() masks every known secret before render; spot-checked all 10. CAP-016 additionally carries no credential by construction: the page reaches the node only through the harness proxy, which injects auth server-side |
2. Per-image review
Every image was opened individually at full resolution. Verdicts after the fix
round; the pre-fix verdict is shown where it differed, because a slop finding
that was silently overwritten is not an audit.
| Capture | State | Rendering | Layout | Content | Privacy | Errors | Audience verdict | Bugs |
|---|---|---|---|---|---|---|---|---|
CAP-002-convergence |
correct | complete | ok (was: 230 px dead space) | real 13.3M positions, real pod names | clean | none | perfect (was slop weak-design) |
BUG-011 |
CAP-006-quorum-write |
correct | complete | ok | 401/401/200/201, real hostname | clean | none | perfect | — |
CAP-008-network-isolation |
correct | complete | ok (was: 350 px dead space) | Connection refused + 332 series |
clean | none | perfect (was slop weak-design) |
BUG-011 |
CAP-010-dashboard |
correct | complete | ok (was: illegible when scaled) | OK / none / 33.3 K, per-pod legends | clean | no "No data" in crop | perfect (was slop weak-design) |
BUG-010 |
CAP-012-tidalctl |
correct | complete | ok (was: dead space) | NO REPORT markers, exit 2 |
clean | none | perfect (was slop weak-design + colour) |
BUG-011, BUG-012 |
CAP-013-backup |
correct | complete | ok (was: dead space) | 3708/3708, 48 PVBs | clean | none | perfect (was slop weak-design) |
BUG-011 |
CAP-014-authority |
correct | complete | ok (was: dead space) | 403 then 200 | clean | none | perfect (was slop weak-design) |
BUG-011 |
CAP-014-drift |
correct | complete | ok | git text + live image + 403/200 | clean | none | perfect | BUG-013 |
CAP-015-inert |
correct | complete | ok (was: dead space) | 332 baseline / 0 http | clean | none | perfect (was slop weak-design) |
BUG-011 |
CAP-016-feed-reorder |
correct | complete | ok (was: footer clipped, hover artefact) | 5-item feed before/after, 5→1 with like_boost 2.000 |
clean — no bearer reaches the page by construction | none | perfect (was slop twice: cut-off honesty footer, then a stray :hover ring) |
BUG-016, BUG-017 |
Non-promoted images
None. Ten images were produced by the capture runs and ten were promoted; no failure or debug images were generated because every capture test passed on the run that produced the promoted set.
3. Remotion frame audit
Scene proof frames rendered and inspected at demo/out/stills/; transition
frames extracted from the encoded MP4 (not re-renders) at
demo/out/frames/.
| Frame | Check | Result |
|---|---|---|
| f120 opening | purpose, personas, scope readable | pass |
| f375 B2, f600 B3, f825 B4, f1020 B5 | proof legible, entrance settled | pass |
| f1230 B6 dashboard | legible at delivery resolution | pass after BUG-010 |
| f840 B3a feed reorder | before/after both legible, capture at scale 1.0, honesty footer visible | pass after BUG-016 |
| f1440 B7, f1635 B8 | proof legible | pass |
| f1890 B9 dream | image agrees with caption | pass after BUG-013 |
| f2145 B10 recap | copy matches what was shown | pass |
| All 11 scene boundaries | no black/white/empty frame | pass after BUG-014 — 0 empty frames |
| Mean luma across all 11 boundary triplets (f-1, f, f+1) | continuous, no isolated dip | pass — every triplet varies by ≤1 (e.g. 5/4/4 at f960); the BUG-014 signature was an isolated collapse to bare background |
| Contact sheet, 30 samples across 90 s | order matches storyboard, no repeats or stale content | pass |
Captures are presented at scale ≥ 1.0 — the 1600×900 panels render 1:1 (CAP-016 measured at 1597/1600 px in-frame) and the 1600×502 dashboard crop renders at 1.10 — so no evidence is downscaled.
4. Walk the render as Jordan Washburn
One row per distinct screen a viewer reads.
| Screen | t | Viewer thought (verbatim, in their voice) | Verdict |
|---|---|---|---|
| B1 opening | 0–9 s | "Right, it names the cluster and the image up front. And it says every number came from a real command — that's the claim I actually care about." | neutral-orientation |
| B2 convergence | 9–16 s | "Per-node, not the aggregate. Good — the aggregate is exactly what lied to me last week. lag=0 on all nine group-replicas and they agree on the leaders." | earns-interest |
| B3 boundary + write | 16–24 s | "401, 401, 200, then a 201 quorum ack. That single 201 is worth more than the rest of the page — it means DNS, TLS, the gateway, auth and Raft all worked in one request." | earns-interest |
| B3a feed reorder | 24–32 s | "So that’s what it is actually for. One like, same query, and it goes from fifth to first with the boost shown next to it. And it says local node and fixture catalog, so it isn’t pretending that’s production data." | earns-interest |
| B4 isolation | 32–39 s | "Connection refused from gitea, 332 series to the scraper. That's the pair I'd want — it proves the policy is real without blinding monitoring." | earns-interest |
| B5 authority | 39–45 s | "403 not 401. So a leaked app key can't remove a member. That's the exposure I was worried about and it's closed." | earns-interest |
| B6 dashboard | 45–53 s | "That's the board I'd actually open. Health OK, reseed none, 33.3K vectors, and the legends finally say which node is which." | earns-interest |
| B7 recovery | 53–59 s | "3708/3708 and 48 of 48 volumes, selected by the schedule label. Good — picking the newest backup would have grabbed a canary." | earns-interest |
| B8 blind spot | 59–66 s | "It says NO REPORT instead of inventing 13 million events of lag. And it admits the exit code makes the deploy gate unusable. I trust a tool that tells me that." | earns-interest |
| B9a inert | 66–73 s | "It shows me what it cannot check yet, with the scrape count proving the scrape actually ran. That is the opposite of a green wall." | earns-interest |
| B9 dream | 73–83 s | "Wait — the doc I wrote said that was pending an image roll, and the harness proved it was already live. It caught my own documentation being wrong before I did. I want this running after every deploy." | earns-interest |
| B10 recap | 83–90 s | "32 green, and it names what it does not verify. That's the version I'd hand to someone else." | neutral-orientation |
No fails rows. The dream beat's thought shows genuine surprise and desire, so
it earns its rung.
5. Full render watch
Watched via the 30-sample contact sheet plus every boundary and proof frame; the render is silent (Remotion emits a silent audio track), so the muted and un-muted passes are identical and captions carry the whole narrative.
| Check | Result |
|---|---|
| Opening purpose and personas readable | pass — 9 s hold |
| Each proof state legible long enough | pass — 6–10 s, dense screens get the longer holds |
| Two-state screen readable as one comparison | pass — B3a stacks before/after at native scale rather than downscaling both to sit side by side |
| Dense screens get more time | pass — dream 10 s, write 8 s, dashboard 8 s vs authority 6 s |
| Captions agree with the visible outcome | pass after BUG-013 |
| Transitions smooth, sections clear | pass after BUG-014 |
| Story explains value, not a screen list | pass — ladder order, not runbook order |
| No scene repeats, skips, contradicts, or overstates | pass |
| Audio artefacts | n/a — silent by design |
Bug log (audit-originated)
Product/test defects found during verification are in
capability-inventory.md; these are the ones this visual audit produced.
| Bug | Asset | Severity | Expected | Actual | Root cause | Fix | Verification | Status |
|---|---|---|---|---|---|---|---|---|
| BUG-010 | CAP-010-dashboard, scene B6 |
high | Dashboard legible at delivery resolution | A 1600×1800 board scaled into 16:9 became unreadable — panel titles and numbers illegible | Capture was the full board; a near-square tall image cannot fit a 16:9 frame without heavy downscaling | Clip to the evidence band (latency + cluster correctness) using real element bounds, so the crop cannot drift with layout. Anchored to the row header and the last stat panel after a first attempt sliced the heading and bled a sliver of the next row | Re-captured 1600×502; renders at scale 1.10; re-inspected the capture and frame f1230 | verified |
| BUG-011 | 6 terminal captures | medium | Frames read as composed | 230–350 px of dead space below the content on sparse panels | margin-top:auto on the footer pushed the void into one block instead of distributing it |
.blocks { flex: 1; justify-content: center } |
Re-captured and individually re-inspected all six | verified |
| BUG-012 | CAP-012-tidalctl |
medium | Colour does not imply a meaning the content lacks | "Exit code 2" rendered green, i.e. as a success, when it is the finding | Verdict line defaulted to the positive colour role | Marked the block negative: true (amber) and rewrote the text to name the consequence |
Re-captured and re-inspected | verified |
| BUG-013 | scene B9 (dream) | blocker | Scene title, claim, and image agree | The dream caption described the runbook's stale claim and the probe that disproved it, while the image showed the unrelated inert-features panel | Beat reused an existing capture instead of one built for the claim | New CAP-014-drift capture showing the committed doc text from git show, the actually-running image, and the live 403/200 probe side by side |
Re-captured, inspected, frame f1890 re-audited, walk-the-render row rewritten | verified |
| BUG-014 | every scene boundary | blocker | No empty frame between scenes | The video blinked to bare background for one frame at all 9 boundaries | Remotion Sequences do not overlap; each scene faded out over its last 8 frames while the next faded in from its own frame 0, so both sat at opacity 0 on the boundary | Removed the fade-out and started each Sequence OVERLAP=10 frames early running long, producing a true 333 ms cross-dissolve. End times unchanged, so every storyboard hold is preserved |
Re-rendered; boundary luma went from flat 13.00 (bare background) to 17.5–23.2 with smooth progression; boundary frames re-inspected | verified |
| BUG-016 | CAP-016-feed-reorder |
blocker | The frame states its environment | Two six-row lists plus labels totalled ~922 px in a 900 px frame, pushing the “local standalone node · 60-item fixture catalog” footer off the bottom and clipping the last row | Composition height was never checked against the frame; the footer is margin-top:auto so it was the first thing squeezed out |
Reduced each half from six rows to five. Explicitly NOT solved by scaling the lists down — that is the BUG-010 mistake, and an unlabelled fixture screenshot reads as production | Re-captured, re-inspected: footer present, both lists complete, lists still 1:1 | verified |
| BUG-017 | CAP-016-feed-reorder |
low | No control looks meaningful unless it is | A blue-ringed Like button appeared on row 5 — an unrelated row — in the after state |
The mouse physically stays where it clicked; after the re-render a DIFFERENT row’s button occupies that pixel and picks up :hover. First fix attempt blurred focus, which changed nothing because it was hover, not focus |
page.mouse.move(0, 0) before the screenshot, plus a blur for the focus case |
Re-captured and re-inspected: no ring on any row | verified |
| BUG-015 | proof scenes | low | No duplicated headings | Remotion drew a scene heading above a capture that already carried its own title, producing a card-in-card with two competing titles | Composition and capture both owned a heading | Removed the heading from the proof scene; Remotion now owns only the capability badge, rung, and audience caption. Reclaimed 66 px for the evidence | Re-rendered and re-inspected f600, f1890 | verified |
Approval
- Every promoted image, card, and clip has an individual review record with an
audience verdict of
perfect. Noacceptable-with-noteverdicts exist, so no screen was promoted on a soft pass. - All blocker/high defects (BUG-010, BUG-013, BUG-014, BUG-016) are fixed and verified.
- Root causes are evidence-backed; no unresolved evidence gaps.
- Every scene proof and transition sample approved.
- Walk-the-render ledger complete for every hold and card, no
failsrows, and the dream beat records genuine surprise. - Every
needrung in the brief is served by at least one approved beat (seestoryboard.mdladder coverage). - Audience brief re-confirmed at approval: viewing moment, decision-maker, and revisit trigger unchanged.