# Figure test matrix — release pass, 6 October 2026

Scope: the 20 figures (23 instances: 20 placements plus the three selector panes) of the merged figure branch
(`claude/holding-companies-figures`, merge commit `7f31bdb` plus the release-pass commits that follow it), the
six chapter views of Figure 3, the task-economics calculator, the 20 SVG downloads and the PDF. One assistant ran
the three passes the brief asks for (semantic fidelity, browser interaction, visual and editorial consistency).
They are three processes by one reviewer, not three independent reviews. Nothing from memory; no source was
re-opened; no fact after the 5 October 2026 cutoff.

## Method

| Pass | How | Where the record is |
|---|---|---|
| 1 Semantic fidelity | Every figure's drawn text, controls, captions, text equivalents and sources disclosure were extracted from the built page and read against `the editorial record (not published)`, the data files and the ledgers; the browser-only detail panels were read through the browser check | the findings table below; `data/corrections-ledger-v3.json` rows FG-01 to FG-27 |
| 2 Interaction and calculation | `scripts/browser-check.mjs` (headless Chromium 141 over CDP, real pointer and key events): 205 assertions, 0 failed, including the 15 new ones of this pass | `dist/qa/browser-check.txt`; the assertions are listed below |
| 3 Visual and editorial | Element screenshots of every instance at 320, 375, 390, 768, 1024, 1366 and 1920 CSS px, light and dark (`prefers-color-scheme` emulated); browser zoom emulated as viewport 1366 ÷ zoom with `deviceScaleFactor` = zoom (200% = 683 CSS px at DPR 2; 400% = 342 CSS px at DPR 4); reduced motion emulated at 1366; 37 named interaction states at 1366; an automated scan on every capture (text-on-text overlap in root SVG coordinates, labels outside the viewBox, page and panel sideways scroll, controls outside their figure, smallest rendered label); every PNG looked at by the reviewer at 1366 and a sample at the other widths; all 20 downloads opened standalone in Chromium; the PDF inspected with PyMuPDF (figure pages rendered to PNG and looked at; type sizes measured; content past the text block measured) | `the editorial record (not published)` (desktop and phone PNGs kept), the scan logs in the session’s temporary files (not kept), `dist/qa/pdf-contact-*.png` |

Zoom note: Chromium's DevTools protocol has no browser-zoom command; CSS-pixel reflow at 200% and 400% was
emulated by narrowing the viewport and raising the device scale factor, which is what browser zoom does to layout.
It is an emulation, stated as such.

## Rendered label minimum by viewport (every figure; the drawing scales with the column)

| Viewport (CSS px) | Drawing shown? | Drawing width | Smallest SVG label (16 units) | Essential labels (20 units) | HTML text in the compact layout, list and detail |
|---|---|---|---|---|---|
| 320 | no: compact layout | — | — | — | 14.1 px body; 10.9 px eyebrow labels (`h5` in the detail panels and card eyebrows) |
| 375 | no: compact layout | — | — | — | as 320 |
| 390 | no: compact layout | — | — | — | as 320 |
| 768 | yes | 730 px | 11.3 px | 14.1 px | 14.1 px / 10.9 px |
| 1024 | yes | 973 px | 15.2 px | 19.0 px | 14.1 px / 10.9 px |
| 1366 | yes | 1054 px | 16.5 px | 20.7 px | 14.1 px / 10.9 px |
| 1920 | yes | 1120 px (the shell's maximum) | 17.6 px | 22.0 px | 14.1 px / 10.9 px |
| 200% zoom at 1366 (683 CSS px, DPR 2) | no: compact layout | — | — | — | 14.1 CSS px = 28 device px |
| 400% zoom at 1366 (342 CSS px, DPR 4) | no: compact layout | — | — | — | 14.1 CSS px = 56 device px |
| Print (A4, 180 mm block) | yes | 180 mm | 8.2 pt (16 units) | 10.2 pt (20 units) | captions 9.4 pt; badges and source chips 7.4 pt (pre-existing caption type) |

The 20-unit essential target (≥ 20 px at 1366, ≥ 10 pt in print) is met at 1366 and above and in print. At 1024
the essential labels render at 19.0 px and at 768 at 14.1 px; both widths show the drawing because the compact
layout starts at 700 px, and the Enlarge viewer serves readers who need the full map larger. Below 700 px the
drawing is hidden and the compact HTML layouts carry the content. Recorded as measured, not as a pass against the
1366 target.

## Per figure

Columns: states exercised (pointer and keyboard in the browser check); viewports (all = 320, 375, 390, 768, 1024,
1366, 1920 light and dark, plus 200% and 400% zoom and reduced motion); overflow or clipping after the fixes;
keyboard path; text alternative; export parity (download versus the page); PDF page; result.

| Figure (section) | States exercised | Viewports | Overflow / clipping | Keyboard path | Text alternative | Export parity | PDF | Result |
|---|---|---|---|---|---|---|---|---|
| 1 Five control questions (s1) | default; cards 3 and 5 selected; viewer open with a selection kept; compact cards at 375 opened and closed | all | none (the status pill, drawn 17 units past the canvas before this pass, now measured) | 5 list buttons, Enter selects and clears; details summaries on phones | prose + 2 tables | download = default view, resolved | p 6, 10.2 / 8.2 pt | pass |
| 2 From a claim to evidence (s2, ref s17) | evidence view; protocol view; gate 3 and 4 by pointer and keyboard; AdCP row; section 17 deep link | all | none (pill measured) | view buttons, gate buttons, item buttons | prose + gates table + protocol table | download = evidence view (the protocol view has no static export; it is in the tables) | p 10 | pass |
| 3 Who owns what, since when (s3; views s6–s11) | all 7 group tabs; every one of the 30 events; the LiveRamp and Kantar events; a map row; 6 chapter views; deep link and hash link; viewer | all | none | tabs (Enter), event buttons, links | prose (943 words) + 7 group tables + deal table + gaps | download = all 7 views stacked (1000 × 6256) | p 12–15 (five print sheets), views p 26–40 | pass; the half-empty print sheets stay an open layout item |
| 4 Dated events (s4) | overview; lens; company, type and period filters; empty result; every marker and list item; viewer | all | none | selects, view buttons, list buttons | prose + 26-row table | download = overview | p 22 (caption on p 23) | pass |
| 5 How to read a deal (s5) | template; Digitas, Sapient, LiveRamp and all 12 cases; clear | all | none (the LiveRamp case line, 1088 units long before this pass, now wraps to two lines) | case buttons (Enter selects, Enter clears) | prose + 12 × 8 table | download = template | p 25 | pass |
| 6 Value created and value captured (s14) | nine mechanisms; a selected mechanism scene; search (1 of 9, 0 of 9); earner filter; clear | all | none (the route table in the half-width list panel no longer scrolls sideways; it stacks one card per row) | row buttons, search, select | prose + 3 tables | download = nine-mechanism overview | p 51 | pass |
| 7 The task profile (s16) | two tasks; one task; content tool against the optimiser | all | none (a three-line cell left its box before this pass; rows now grow with their longest cell) | two selects | prose + 6 × 3 table | download = default pair | p 61 | pass |
| 8 Seven fee routes (s18) | buying comparison; nine mechanisms view; outcome fees and principal spread selected | all | none | as figure 6 | prose + tables | download = buying comparison | p 69 | pass |
| 9 Spending to proof (s18) | defaults; commitments $30,000; read delayed; daily spend out of range; cap typed; reset | all | none | five inputs, select, reset | prose + day table | static = download = `figures/spending-to-proof.svg` at the labelled defaults | p 72 | pass |
| 10 Who keeps a task saving? (s18) and the calculator | the five reference cases by input events, by keyboard typing and (the four presets) by pointer; fee 60 with no saving (shortfall bracket); fee 130 (label clamped); every field changed then reset by pointer, twice, and by `form.reset()` | all | none (the long preset label forced a 349 px page at 320 px before this pass; it now wraps) | inputs, preset buttons, native reset | prose + 5-row table | download = the base and four presets at the labelled defaults | p 73 | pass |
| 11 How judgment creates value (s19) | stage 2 and 6 selected (proposed measures) | all | none | 6 buttons | prose + 6-row table | one drawing serves page, download and print | p 78 | pass |
| 12 The present-day loop and the three paths (s20) | baseline; A; B; C; every path × stage (28); layers off and on; steps 1–7 and reset; stage kept or explained on switch (4 cases) | all | none (stage owners no longer run into the "Brand decides" line; the canvas follows the footer) | radiogroup (arrows, Home, End), stage buttons, step buttons, layer buttons | prose + comparison table + stages, arrows and correspondence tables | download = baseline full loop | p 80 (table continues p 81, caption p 81) | pass |
| 13 A. Brand-controlled (s21; selector pane) | chapter strip; deep link to the comparison | all | none (the strip's footer was clipped at 368 units before this pass; the strip is 368–382 units as its footer needs) | link | prose + stage table | download = full loop A (distinct from the page's strip; the tools row says so) | p 84 | pass |
| 14 B. Agency-led (s22; selector pane) | as 13 | all | none | link | prose + stage table | download = full loop B | p 89 | pass |
| 15 Two linked loops (s22) | client loop; capability loop; how they connect with 6 steps and reset; complete overview; stage buttons; viewer | all | none (the "evidence" cross-link label sat on the legend and its line crossed the loop headings before this pass) | view buttons, stage buttons, step buttons | prose + stage table + arrow table | download = default (client loop) | p 96 | pass |
| 16 C. Platform-dominated (s23; selector pane) | as 13 | all | none | link | prose + stage table | download = full loop C | p 99 | pass |
| 17 Openness and client control (s24) | every cell by pointer and keyboard | all | none (pill measured) | 4 list buttons | prose + 4-row table + axes paragraph | download = default | p 104 | pass |
| 18 What leaves with the brand (s25) | current operator; successor operator (radiogroup, ArrowLeft); asset buttons; cell click; viewer | all | none | radiogroup, 4 asset buttons | prose + 4 × 9 table + legend | download = current view | p 111 | pass |
| 19 One retailer, three agents (s26) | 25% code; 12% code; 15% shift (nothing moved; allowance used); lapsed-buyer email; chosen discount 30%, 10%; C = $70; week 4 read failed; tranche 1 spent; econ reset; walkthrough reset; viewer | all | none | proposal buttons (Enter), selects, inputs | prose + 6 tables | static = download = `figures/retailer-agents.svg` (first proposal at the printed inputs) | p 116 (caption p 117) | pass |
| 20 The next 90 days (s28) | phases and gates by pointer and keyboard; checklist tick, clear, persistence after reload; storage blocked | all | none (the "Selected" word covered the "Phase" label before this pass; it sits in a band at the foot of the card; pill measured) | 8 list buttons; checkboxes | prose + 3 tables | download = default | p 122 | pass |
| Selector panes (13, 14, 16 in s20) | click and ArrowRight; the Compare link and download follow the choice | 1366, 375 | none | radiogroup | the manuscript's tables | — | printed once as a one-line note | pass |
| Chapter views of figure 3 (s6–s11) | Dentsu deep link by pointer; Havas hash link | 1366, 375 | none; no duplicate ids | link | each view is a semantic table | — | p 26–40 | pass |
| Enlarged viewer | Enter opens; Fit width, Fit all, 100%, +, −, Reset view checked against computed values; Escape closes; focus returns; article position restored; a filter chosen inside is kept; tab switch inside; no duplicate ids | 1440, 375 | none | full keyboard route | — | — | hidden | pass |

## Edge cases from the brief

| Case | Where | Result |
|---|---|---|
| No labour saving (100/60/20/0/5) | calculator | cost 85, profit 15, client saving 0; sentence says no labour saving assumed |
| Added cost absorbs the saving (100/60/20/25/15; preset) | calculator and figure 10 | cost 80, profit 20, client saving 0 |
| Chosen fee above base (fee 130) | calculator | fee label clamped inside the drawing; client fee saving −30 shown as the arithmetic result |
| Negative profit (fee 60, saving 0) | calculator | shortfall 25.0 drawn as a bracket from the fee line; no negative-width rect; never called a certain loss |
| Exhausted tranche (tranche 1 spent before the read) | figure 19 | a permitted action waits: "spending pauses until the read"; no executed state |
| Failed evidence gate (week 4 read failed) | figure 19 | tranche 2 held; the plan returns to the CMO; agents cannot unlock it |
| Existing use of the aggregate shift allowance | figure 19 | the whole 15% proposal is held (both branches of P2-0201 shown) |
| Empty timeline filter | figure 4 | "No events match these filters" over the frame and in the list; 0 of 26 |
| Read delayed | figure 9 | pause at day 7; all spend awaiting; not a loss |

## Findings and fixes of this pass

Pass 1 (semantic): (a) the Horizon Blu "Deployment" cell of the protocol grid said "One named deployment" and
dropped the stated scope — now "Named use: audience collab." (the full wording stays in the detail and the table);
(b) the Dentsu FY2025 impairment printed "31 Dec 2025" in the ownership figure although the record gives the fiscal
year — now "FY2025"; (c) the Horizon Global row on the Horizon tab said "no dated event drawn" while the Havas tab
dated the same joint venture — now "Announced 29 Sep 2025 (drawn on the Havas tab)"; (d) the task-profile units
line said "stages and phases, not timing" (copied from another figure) — now "six stated conditions per task, not
scores, ranks or timing"; (e) the 90-day plan printed "Weeks 13" for one week — now "Week 13". Everything else
read against the manuscript and the ledgers held: LiveRamp pending and never owned (figures 3, 4, 5); orchestration
and principal buying coexist, no replacement claimed (figure 8 and the B strip); attribution assigns credit and does
not prove growth (figure 12 and its panels); proposed safeguards labelled proposals (figures 1, 18, 20); scenarios
conditional, not forecasts (12–16); Horizon interpretive (15); no vendor count as openness (17); no score or rank in
the task profile (7); the 25% code fails the floor by the recomputed formula (19); tranches conditional (19).

Pass 2 (interaction): no failure in the existing 190 assertions; 15 assertions added (the layout scan on 21 visible
instances and 24 exercised states; the chapter strips' height; see `scripts/browser-check.mjs`). The timeline lens
defect the rights agent found earlier (an SVG `hidden` property) was confirmed fixed.

Pass 3 (visual): (1) chapter strips clipped their footer (coordinator finding) — fixed, the canvas follows the
footer and the browser redraw sets the viewBox; (2) baseline stage 3 owner ran into "Brand decides" (coordinator
finding) — fixed, with a renderer refusal for owners over three lines; (3) task-profile three-line cell left its
box; (4) ninety-days "Selected" covered "Phase 2"; (5) deal figure case line past the canvas for LiveRamp;
(6) Horizon "evidence" label on the legend and its line through the loop headings; (7) commercial explorer route
tables scrolling sideways in the half-width list panel; (8) the status pill of four figures drawn 17 units past the
canvas (clipped on screen, drawn past the text block in print); (9) page-level sideways scroll at 320 px (a
preset button) and at 641–940 px and 200% zoom (the top bar); (10) a figure caption split across PDF pages — now
kept whole; (11) the site's accessibility check (`scripts/check-a11y.mjs`, run as the deploy workflow does) reported a
heading jump h2 → h5 on the page: the shell printed the figure title as a paragraph and the compact cards opened with
h5 labels; the figure and chapter-view titles are now h3 and the eyebrow labels are label paragraphs, not headings;
0 heading jumps remain. All fixed and re-verified; the scan reports 0 findings on 357 captures.

## Not tested

| Item | Status |
|---|---|
| Screen reader (NVDA, JAWS, VoiceOver, TalkBack) | not run; the keyboard route, names, roles, `aria-pressed` / `aria-checked`, the live detail panels and the dialog pattern were checked by DOM assertion only |
| A physical phone or tablet | not used; phone and tablet widths were emulated in headless Chromium with mobile metrics |
| Real browser zoom | emulated (see the zoom note); not run in a windowed browser |
| Safari, Firefox, Edge | not run; Chromium 141 only |
| External SVG editors (Illustrator, Inkscape, Figma) | not opened; the downloads were opened standalone in Chromium only |
| Touch gestures (pinch, drag) in the viewer | not run; drag-pan and buttons were exercised with mouse events |
| Print from a browser's own dialog | not run; the PDF is Chromium's print of the page through `build/pdf.mjs` |
| Dark theme screenshots at every width | captured for every figure at every width; looked at by the reviewer for a sample (timeline, value capture, evidence explorer, horizon, learning exit, scenario A) rather than every PNG |
| Windows ClearType / font rendering differences | not tested |

## Editorial repair, later on 6 October 2026 (after the author's live validation)

Scope: the live figure validation of 6 October 2026 (editorial record) was received after the release pass above. This
addendum records what that validation covered and found, what the editorial repair applied, what it verified on the
repaired build, and what stays open. The repair touched Figures 1, 2 (its section 17 summary), 11, 12, 13, 14, 16,
17 (the section 24 table only), 20 and the four scenario downloads. Three passes by one assistant, not three
independent reviews. No source was re-opened; the local pinned AdCP clone was read, nothing fetched.

### What the live validation covered and found

Performed by the validation: live Chromium inspection at 1363 × 936 of the published page; inventory and visual
examination across all 20 figure records; focused interaction tests (scenario switching and step-through, timeline
filters and lens, viewer zoom and Escape, the four calculator presets and a five-input reset, the retailer proposals);
DOM checks for canvas containment and selected state; source and correction-panel consistency; the standalone
ownership and learning-exit SVGs; the 153-page PDF with spot checks on pages 12, 111 and 116. Not performed by it:
screen readers, physical phones, real browser zoom, other browsers, a complete dark-theme pass, every module, filter
and input combination, all SVG downloads, all PDF pages, repository or code inspection, deployment-log verification,
fresh verification of the paper's sources or the AdCP repository.

Verdict of the validation: materially improved, not ready for an unqualified sign-off. Ten findings (V01 to V10) and a
disposition for every figure. It confirmed that the public QA record overstated its coverage: it claimed zero text
collisions and no labels outside the canvas "in exercised states", and the validation found remaining containment
and post-transition defects in states the release pass had not exercised (V05) and controls detached inside the
viewer (V01, V02).

### What this repair applied (rows FG-28 to FG-36 of the corrections ledger)

| Finding | Figure | What changed | Verified by |
|---|---|---|---|
| V06 (FG-28) | 12, 13, 14, 16 and the four downloads | The "Brand decides: yes/no" Boolean is gone; every stage names who runs it, whose sign-off its output needs ("Approval: …" on the box, defined on the drawing) and what is delegated, beside the paper's own owner cell | 28 stage selections assert the three fields in the panel and the approval line on the node; 28 compact items and 42 chapter and selector stage lines assert Runs / Approval / Delegated scope; the page carries no Boolean; the four exports carry seven approval lines each |
| V08 (FG-29; closes FG-22) | 17 (the section 24 table) | Row labels now "Open: providers can be connected and replaced" / "Restricted: providers are hard to connect or replace" | read in the built page; the figure's own assertions unchanged |
| V08 (FG-30; closes FG-24) | 2 and section 17 | One AdCP version record: analysed 3.2.1 at commit 6adfebe2 (GA 30 September 2026); tags v3.2.1 and v3.2.2 as the register recorded them; the v3.2.2 patch tag of 4 October 2026 (inside the cutoff) with what its changelog entry changes; never substituted; the shallow-clone limit stated | the AdCP row's detail asserts the record; the section 17 summary asserts it |
| FG-23 (FG-31) | 11 | Two proposed diagnostic questions, not measures (disagreement on the record; null and failed tests and why); the dense list moved to the detail panel, the phone cards and the table; the drawing lighter | default view, pointer and keyboard selection, the download and the table asserted |
| FG-26 (FG-32) | 1 | Cards three and two; the roles note (a title grants no legal authority; no role is a separate hire) in the sixth place; the stop-right detail names the technical revocation authority and the contractual cancellation limits | layout (two rows, three columns, cards ≥ 300 units), the note, the card 3 detail and the five phone cards asserted |
| FG-27 (FG-33) | section 17 | A compact semantic protocol summary from the same data file (six items × six stages, the record column, the version record), linked to the explorer; no second SVG | six rows, eight columns, no SVG, the version record and the deep link asserted; one `.fig-view--protocol` on the page |
| Figure 20 (FG-34) | 20 | Phase cards 152 units wide; the days line left the card face | card width ≥ 150 asserted; "Days 1 to 30" absent from the drawing |
| V10 (FG-35) | the record | ER-F14 and ER-F15 verdicts "applied"; this statement; the test record published as `data/figure-test-record.md` | the download link exists in `dist/` (download assertion) |
| the validation itself (FG-36) | the record | What it covered, found, and which findings are applied or open | logged |

### Verification of the repaired build (bounded)

Build: the worktree branch `claude/hc-fix-4`, commit recorded in the editorial repair notes; `node build/build-data.mjs`
(31 sections, 210 claims, 51 sources, 104 checks, 228 corrections, 20 figures), `node build/render.mjs`,
`node build/render-plain.mjs` (Flesch 87.5), `node build/render-md.mjs`, `node build/pdf.mjs` (156 pages, Chrome 141),
`node scripts/check.mjs --final` (OK, the two pre-existing warnings), `node scripts/browser-check.mjs` (207 assertions,
0 failed), `python3 scripts/pdf-type.py` (OK: body 10.5 pt, no text page under 7 pt, no near-empty page), `node scripts/check-figure-data.mjs` (22 of 22 files).

Transitions exercised by the browser check on the repaired build, inline: every scenario × stage (28), the four
stage-kept-or-explained switches, the layer toggles, Previous / Next / Reset, the radiogroup by keyboard, the chapter
deep link and the selector links; the judgment figure by pointer (stage 4) and keyboard (stage 6); the control
questions by pointer (card 3) and keyboard (card 5), and inside the viewer (card 4, kept after Escape); the evidence
figure's two views, the AdCP row by pointer and the "Meaningful scale" gate by keyboard, the section 17 deep link by
hash; the 90-day phases and gates by pointer and keyboard. The layout scan (text-on-text overlap over 3 units, labels
outside the viewBox, controls outside their figure, sideways scroll, smallest label) ran on every visible figure
instance in its default view and on the 24 named states listed in `scripts/browser-check.mjs`; it reports
no label collision, no label outside the canvas, no clipped control, no sideways scroll and a smallest label of at least 16 CSS px on all 21 visible instances and all 24 states. That is the scan's result for those states only; the validation's V05 findings concern states and exports the
scan does not reach (the viewer after a view change, the standalone ownership and learning-exit SVGs under fallback
fonts, the retailer tranche label) and stay open.

Sample exports opened standalone in Chromium (file URL, no site CSS): `dist/figures/baseline.svg`, `scenario-a.svg`,
`scenario-b.svg`, `scenario-c.svg`, `control-questions.svg`, `value-judgment.svg`, `ninety-days.svg` (the figures this
repair touched). Not re-opened: the other 13 downloads.

Visual: element screenshots at 1366 × 900 and 375 × 812 CSS px, light and dark, of Figures 1 (default and card 3),
11 (default and stage 6), 12 (baseline stage 2; A, B and C with a stage), 13, 14, 16, 17, 20 (default and phase 2),
the evidence figure's protocol view with the AdCP row, and the section 17 summary; before-and-after pairs for
Figures 1, 11, 12, 14 and 20 are kept as 8-bit PNGs under `the editorial record (not published)`. Every PNG at 1366 and 375 was
looked at by the reviewer. The PDF pages of the touched figures were looked at (the pages that carry Figures 1, 2, 11, 12, 13, 14, 16, 17, 20 and the section 17 summary).

Remaining limits of this verification: one assistant; Chromium 141 headless only; no screen reader; no physical
phone or tablet; browser zoom not run (the earlier emulation was not repeated); Safari, Firefox and Edge not run;
the viewer's post-transition states (V01, V02) not re-tested beyond the existing assertions; dark theme looked at for
the touched figures only; the Markdown and plain editions read for the changed blocks only.

### Open after this repair

V01 (controls and rendering detached inside the viewer), V02 (viewer zoom after a group change), V03 (cap enforcement
in Figure 9), V04 (approval and authority states in Figure 19), V05 (export fidelity and text containment), V07
(entity taxonomy in Figure 3), V09 (the deal figure's badge), and the author decisions FG-18, FG-19, FG-20, FG-21 and
FG-25. These are assigned to other repairs and are not claimed here.

## Merged repair, later on 6 October 2026: status of every validation finding

This section supersedes the open lists in the editorial-repair section above, which were written before the other
three repair passes were merged. One assistant ran four repair passes (viewer, models, entities, editorial) in
separate branches and merged them; these are not independent reviews.

| Finding | Status on the merged build | Ledger |
|---|---|---|
| V01 viewer lifecycle (blank or stale views inside Enlarge) | Applied. The whole figure moves into the dialog and back, so module state, listeners and lists stay valid. | FG-36 |
| V02 zoom readout after a view change | Applied. The viewer re-reads the active viewBox and rendered box after every change; readout, width and height come from the same geometry. | FG-36 |
| V03 spend past the cap | Applied. Hard pre-spend cap on divisible daily spend; a slow stop is a labelled assumption (default none); excess and exposure beyond the cap are their own lines. | FG-47, FG-50 |
| V04 permission versus execution | Applied. Eligible, awaiting creative sign-off, executable within an available tranche, executed and logged are separate; an exhausted tranche holds. | FG-48 |
| V05 exports and containment | Applied. Per-group ownership files and a labelled reading sheet; exports wrapped for the fallback font; retailer labels contained; inline height restored on close. | FG-43, FG-44, FG-49 |
| V06 "Brand decides" Boolean | Applied. Execution owner, approval owner and delegated scope on every stage. | FG-28 |
| V07 ownership taxonomy | Applied. Entity type, relation, transaction status and dates separated; all 40 rows checked against their basis. | FG-37 to FG-42 |
| V08 section 24 labels; AdCP version | Applied. | FG-29, FG-30 |
| V09 deal badge | Applied. "Worked case: name · status"; a one-line case summary above the checklist. | FG-45 |
| V10 sign-off language | Applied. Bounded statement, ledger status consistency, this record. | FG-35, FG-36 |
| FG-18 to FG-27 author decisions | All applied as the validation recommended. | FG-18 to FG-27 |

**Tested on the merged build.** The browser check runs every control of every interactive figure in the page and
in the enlarged view: 272 transitions, 544 rows, all pass. Each row checks that the selected control, the visible
drawing, the list, the detail panel and the text equivalent agree, that the readout equals the drawing's rendered
scale, that essential labels render at 16 px or more at Fit width, and that closing keeps the selection and the
inline height. The author's headline cases were reproduced separately in Chromium on the merged build: Stagwell to
Horizon in the viewer (readout 93%, rendered 93%); the timeline lens and the learning-exit successor view inside the
viewer; $100,000 a day against the $90,000 cap (spend stops at $90,000; with a 2-day slow stop the $200,000
overshoot is its own line); the 12% code before sign-off (waits), after sign-off (runs) and with tranche 1 spent
(held). Screenshots: `the editorial record (not published)`.

**Found and fixed during that reproduction.** With a slow stop, the cap label sat on the overshoot bars and under
the stop marker; it now takes a clear span or a halo and is drawn last (FG-50, with a browser-check assertion). The
slow-stop help text read "Assumption: assumption"; corrected.

**Still open.** Fit all on the two tallest views (Horizon group map, timeline overview) renders 20-unit labels at
14.0 to 14.4 px; Fit width, the default, keeps them at 18.5 px or more. The Horizon single-loop views are scaled
copies of the overview. The ownership print takes five half-empty sheets. The all-groups ownership file is a reading
sheet for zoom and print; the per-group files are the reading copies. One author decision: whether execution pauses
when the week 4 read fails while tranche 1 still has money.

**Not tested.** A screen reader, a physical phone or tablet, real browser zoom at 200% and 400%, Safari, Firefox,
Edge. Headless Chromium 141 only.

## Author review fix, 7 October 2026: failed-gate policy and ownership readability

The author's live check of 7 October 2026 confirmed the 6 October repair on the live page (the zoom readout, the
previously blank views, the commercial explorer, the cap at $100,000 and $60,000 a day, commitments above the cap,
the 12% offer's sign-off and tranche states, the learning-exit export and the Horizon download). It left two items.
Both are applied here (corrections ledger FG-51 to FG-59). One assistant made and checked these changes.

**Correction.** The record above said Fit all on the two tallest views renders 20-unit labels at 14.0 to 14.4 px.
That held for the timeline overview and an earlier, shorter ownership layout. It did not hold for the 1,590-unit
Horizon ownership view of the 6 October build: 9.9 px measured here, 10.4 px in the author's test (FG-59).

**Failed-gate policy (FG-55 to FG-57).** The author decided that a failed gate pauses new execution even when money
remains. Section 26 carries the author's wording; a delayed or inconclusive read gets a continuation set in advance
(week 4: up to 7 days, from what is left of tranche 1, capped at $22,500; week 8: none). The retailer figure follows
one rule in every representation. Tested: the author's reproduction (week 4 failed, signed off, tranche 1 unspent:
paused, no executed path) by pointer and keyboard, inline and enlarged; delayed inside the window; continuation used
up; delayed with tranche 1 spent; week 4 passed then week 8 failed; week 8 delayed; the earlier V04 cases.

**Ownership readability (FG-51 to FG-54, FG-58).** Rows show name, type, relationship and status; dates, checks and
source passages are in the selected-row panel, the compact cards, the tables and the text equivalent. Capability
mapping is its own view. Viewer buttons read "Fit width (reading)" and "Fit all (overview)", with a note when a fit
mode is below reading size; medium windows open with the side panel hidden.

Measured rendered label size (font-size × screen scale of visible text; essential = 20 units, supporting = 16):

| Viewport | Side panel | Fit width, essential / supporting | Fit all, essential / supporting |
|---|---|---|---|
| 1366 × 900 | shown | 18.7 / 14.9 px, all 14 views (93%) | 18.7 px on every ownership view; lowest view (Horizon capability) 17.7 / 14.2 px (89%) |
| 1366 × 900 | hidden | 26.4 / 21.1 px (132%) | at least 17.8 px (89% or more) |
| 1920 × 1080 | shown | 29.8 / 23.8 px (149%) | at least 21.8 / 17.4 px (109% or more) |
| 1024 × 768 | hidden (the default at this width) | 19.5 / 15.6 px (98%) | 13.6 to 19.5 px; the overview note shows on the views below 16 px |
| 1024 × 768 | shown (reader's choice) | 11.8 / 9.5 px (59%), with the reading-size note | 11.8 / 9.5 px, with the note |
| 375 × 812 | n/a | compact cards: names 14.1 px, facts 12.5 px, no sideways scroll | n/a |

Drawing heights at 1,000 units wide: ownership 430 to 760 units (Horizon 734, was 1,590); capability 546 to 890.
The full table, 113 rows, is in the editorial record.

**Gates on the merged build.** Build data, render, plain, Markdown, PDF, final check, browser check (every control
of every interactive figure in the page and in the enlarged view, plus the new cases), PDF type, figure data, and
the site build with the deploy workflow's checks.

**Still open.** The Horizon single-loop views are scaled copies of the overview. The ownership print keeps its dense
full-fact sheets. Not tested: a screen reader, a physical phone or tablet, real browser zoom, Safari, Firefox, Edge.

## Figure reading width, 7 October 2026 (author's note on scale; FG-60)

The figures grew with the window, so on wide screens labels rendered at about 25 px and drawing titles near 38 px
beside 17 px body text. On screen the figure block now stops at a reading width: every drawing renders at most
880 px wide. Measured at 1366, 1440 and 1920 px, every figure's essential 20-unit labels render at 17.6 px, its 16-unit
notes at 14.1 px and its drawing titles at 21 to 23 px; the Horizon single-loop view (now enlarged 1.2x, was 1.8x)
renders its stage names at about 21 px. The enlarged viewer, phones and print are unchanged. The browser check's label
floors follow the brief's targets (essential 16 px, notes 14 px), and a new check holds every drawing at 880 px or
less with essential labels between 16 and 22 px at 1440 and 1920 px.

## Release checks and readability on the final build, 7 October 2026 (author's final review; FG-61, FG-62)

The final editorial cleanup moved the dated update notes after the method section, behind a collapsed "Update history"
block, and put a short current-status note (about 70 words) between the hero and the abstract. These checks ran on the
resulting build of 7 October 2026: check --final (passed); browser check, 305 assertions at 375, 1024, 1366, 1440 and
1920 px, 0 failed; PDF type and overflow check on all 170 pages (smallest character 7.4 pt, body 10.5 pt, no
near-empty page); figure data, 22 of 22 files. The PDF grew from 168 to 170 pages: print shows the history open, and section 26 gained the week 8 rule (FG-63).

**Readability, measured 7 October 2026** with scripts/readability-narrative.py (textstat 0.7.13, pyphen syllables):
narrative 69.4 against a target of 85, not met (front matter 64.0, part I 73.1, parts II and III 66.9); plain edition
87.3, above its gate of 85. Lowest sections: s27 The retained team 56.6, s31 Method 60.9, s30 Five questions 62.3,
s22 Agency-led orchestration 62.7, s25 A commercial design 63.6. The lowest paragraphs are the list blocks of
sections 19 and 20 (the six client duties and the nine cost lines, which the formula scores as one long sentence) and
the cost enumerations and loop descriptions in sections 22 and 23 (P2-0124, P2-0126, P2-0128, P2-0151). They were
left as written: shortening them would drop the terms the cost boundary and the loops need. Rerun the measure if the
text changes.
