# CI was not the bottleneck

- **Article:** Learnings / ci-was-not-the-bottleneck
- **Runtime:** **~160 s (2:40)**, word-budget derived — see the derivation below. The staged
  90–120 s target was never budget-derived (334 words cannot fit 120 s at any natural
  pace). Ruling 2026-10-25: the 2:40 budget is accepted; no trim.
- **Companion deck:** explainer.html — one scene section per row below, recorded against
  the measured narration take.

A person records the explainer and uploads the finished video; the article's
`video` metadata field is then set to that link, or to `none` if the video is
waived. This article ships with its explainer video linked in the metadata and
embedded on the page; the script and the companion deck ship in the bundle beside it.
Every `~sec` is an **estimate** derived from the word budget, not a measurement
— the render pipeline measures the real narration take per scene and the deck
scales to it; the sanity gate fails any scene over `max(est × 1.8, est + 8 s)`.

**No `subtitle` column**: the narration is reused as the caption track (the
sanctioned default), carrying the full speech verbatim as burned-in captions.
The `on-screen text` column is what the viewer READS while the voice speaks —
2–5 words, never a transcript. Final caption segmentation and speech alignment
remain a production check.

## Scenes

| # | id | ~sec (est) | words | narration | on-screen text |
|---|----|------|-------|-----------|----------------|
| 1 | title | 10 | 22 | We were weeks from pricing a CI migration when the measurement came back. The pipeline was fine. Everything after it was not. | CI was not the bottleneck |
| 2 | felt-slow | 24 | 52 | The pipelines felt slow, the way pipelines always feel slow when delivery is behind. The question on the table was which provider to move to. Before anyone priced runners, we asked a different question. Where do the hours sit, between a change entering the queue and that change reaching an accepted result? | Where do the hours sit? |
| 3 | dwell-map | 18 | 40 | The instrument is a dwell map. Take the delivery path apart into hand-offs — intake to dispatch, dispatch to worker, opened to review, merge to verified. A timestamp on both ends of each. A median per edge, over a trailing month. | one median per hand-off |
| 4 | fast-parts | 17 | 36 | Three stages turned out to be fast. A pull request meets its first reviewer in about twelve minutes. A full CI run finishes in five minutes and change. The human merge gate takes twelve minutes more. | review 12 min · CI 5m 37s · merge 12 min |
| 5 | six-days | 19 | 37 | And then the merged change waits. Six days at the median — a hundred and forty-four hours — for independent verification to close. The ninetieth percentile is eleven days. The pipeline was never the constraint. The acceptance path was. | merge → verified: 6 days median |
| 6 | plumbing | 26 | 52 | Why does verification take six days? A forensic pass over sixty-eight verification transcripts found eighty-six percent of the desk's own tool calls going to plumbing — tokens, worktrees, claims, lint — and most of its check tables failing as written on the wrong operating system. The models were not the problem. The plumbing was. | 86% of the work was plumbing |
| 7 | threshold | 26 | 54 | So: no migration. Instead, a threshold declared before any benchmark runs — what would have to be true for a switch to be worth it. A candidate that loses coverage, or changes what a failure means, is rejected whatever its stopwatch says. A faster job with a slower acceptance path does not satisfy the goal. | declare the threshold before the demo |
| 8 | close | 20 | 41 | Draw your own map before the vendor demos start. Four or five hand-offs, timestamps you already have, a median per edge. If the hours sit inside the pipeline, buy the runner. If they sit after merge — you know what to fix. | Measure the dwell before you buy the runner. |

## Timing derivation (estimates; no take exists yet)

Register relay: scenes 1–4 and 8 conversational **150 wpm** (2.5 w/s); scenes 5–7
(number-dense) technical **140 wpm** (2.333 w/s). Speech: 8.8 + 20.8 + 16.0 +
14.4 + 15.9 + 22.3 + 23.1 + 16.4 = **137.7 s**. Holds budgeted separately from the
voice-delivery starting values (lead-in ~0.4 s; thought boundary ~0.35–0.4 s;
dense end ~1.45 s; closing hold 2.7 s): lead-ins 8×0.4, thought boundaries
(~2 per scene) ≈ 6, ends 6×1.15 + 2×1.45, closing 2.7 ≈ **22 s**. Total
**~160 s**; 10 % slow-take ceiling ≈ **~174 s**. The measured take overwrites
every number; the deck's fallback durations carry these estimates.

## Description

We were weeks from pricing a CI migration when we measured where work actually
dwells: the pipeline finishes in five minutes, review starts in twelve, and the
merged change waits six days for independent verification. The dwell map — one
median per hand-off — and the decision shape that follows: declare the switching
threshold before the vendor demos start. Full write-up:
https://assay.guide/blog/learnings/ci-was-not-the-bottleneck/

## Notes for the recording

- Read the narration as written; it inherits the article's honest-claims
  wording. Do not upgrade any framing: "six days" is a median over a stated
  cohort, "eighty-six percent" is one forensic pass over 68 transcripts, and
  neither becomes a general law in delivery.
- Every number the voice speaks is written out as words on purpose. Digits and
  symbols live on screen or in the burned captions — never let an edit move a
  numeral into the narration column.
- **Voice default**: **Aiden, warm and
  conversational** — one colleague explaining something useful to another,
  unhurried natural pace, clear gentle pause between thoughts, varied natural
  emphasis, no announcer cadence; this script's register adapts the emphasis —
  flat on the numbers, a little weight on the verdicts. The legacy
  `--steered-us-voice aiden` flag does NOT select the warmer treatment; use the
  authorized CustomVoice path or an explicit profile's instruct params, and
  verify the effective settings. Audition the actual take — an instruction is
  not evidence of how the speech sounds. Audition "CI" specifically — it should
  read as two letters; if the engine blends it, respell it "C.I." in the
  narration column only.
- Captions: burned-in, full speech, sentence-case, regenerated from one cue
  source against the measured audio clock; on-screen text is the only
  non-caption text.
- Scene 5 is the deck's one bold moment: three short bars land, hold, then the
  long bar sweeps and the verdict arrives. Every other scene stays quiet.
- End screen: the official mark centered between the two YouTube
  recommended-video regions, held eight seconds including the outro bed —
  production timing, not narration. The close scene's build carries a fixed
  eight-second hold for it; do not let the take's scaling absorb it.
- No internal names, paths, or tracker identifiers belong on the spoken track
  or any slide; this file and the deck are served publicly, byte for byte.
