# The Delivery Record. Source: https://customlabs.io/delivery-record/ Updated: 2026-09-12 Delivery record # The Delivery Record. The Agentic Delivery Playbook says how we run a fleet of coding agents. This page is the receipts. Every page on customlabs.io was built that way: one task per branch, a fixed stage flow, nothing reaching main except through a merge request. 163 of those tasks merged in 63 days. 12 defects got past the agent that wrote them. Below is each one: what shipped, what caught it, and the check that now fails the build if it comes back. The playbook makes claims. This page shows the working. Counts as of 2026-09-05, at commit `99e817f`. 01: The numbers ## 6 numbers, each one caveated. Every tile carries a second line for what it doesn't tell you. Read them together, not alone. snapshot 163 ### Distinct tasks merged 173 merge commits from task branches, total. **Doesn't tell you:** Fewer than the merge-commit count above it, because some tasks merged into main more than once: 3 as a suffixed follow-up branch after review or verify rejected the first attempt, and 7 as a second merge from the same branch. snapshot 63 days ### Calendar window 2026-07-04 → 2026-09-04. **Doesn't tell you:** Says nothing about hours per day or how many agents ran concurrently — a busy day and a quiet one count the same. snapshot 3 ### Follow-up branches Opened after review or verify sent the first attempt back. **Doesn't tell you:** A lower bound, not a defect count — this only counts a rejection that needed a whole new branch. Rework inside the same branch, before it ever reached review, is invisible here. snapshot 35 ### "Fix …" commits on main Commit subjects on main starting with the word "Fix". **Doesn't tell you:** Counts only commits whose subject literally starts with the word "Fix" — a defect fixed under a different subject line, or folded into a larger commit, doesn't show up in this count. live 87 ### Published knowledge entries Computed live at build time, not from the snapshot below. **Doesn't tell you:** Counts insights, case studies, comparisons, patterns, failure modes, glossary terms, and tools — not every page on the site, and not this page either. curated 13 ### Build-time invariants added after a break Named in full below, section 03. **Doesn't tell you:** A curated count, not an exhaustive one — only checks with a traceable incident behind them are counted, not the rest of the test suite. 02: What the gates caught ## 12 defects, and what stopped each one. Every SHA below is evidence text, not a link. The repository is private. Review stage Human inspection after deploy Verify stage, after merge Browser check after merge Showing all 12 incidents Copy as Markdown 01 ### Nine product pages published a "what it's built with" stack that was inferred, not confirmed. `48ba32a` **Shipped** Nine product pages published a "what it's built with" stack list — TypeScript, Postgres, Terraform, and so on — for every product. Nothing else in the repo documented the real technology choices behind any of the nine; the lists were inferred, not confirmed. **Caught by** Review stage **Root cause** The claims were checkable, and once checked, they were wrong. **Guard added** `stack` became an optional field on the Product interface and was unset on all nine products; the page now renders a "What it's built with" section only when the field is actually populated, so confirming a real stack later brings the section back with no code change. [Practice: Machine review first](https://customlabs.io/agentic-delivery/#rt-machine-review-first) 02 ### 26 identical, blank Open Graph social cards shipped to production. `84e0bb8` **Shipped** 26 identical, blank Open Graph social cards. **Caught by** Human inspection after deploy **Root cause** renderSvgToPng() passed a fontBuffers option that @resvg/resvg-js@2.6.2 doesn't actually support — documented in the library's README, missing from its type definitions. Options cross the NAPI boundary as one JSON-stringified blob, so the single unknown key silently discarded the whole font object and resvg fell back to system fonts. Invisible on a dev machine with system fonts installed; every line of text dropped on the font-less CI build image. **Guard added** A byte-hash uniqueness check in verify-seo.mjs that fails the build if any two OG images render to identical bytes, plus wiring npm test into the CI build job — it had never actually run there. [Practice: Name the verification command](https://customlabs.io/agentic-delivery/#td-name-verification-command) 03 ### The light theme drew every focus ring in the lime accent — 1.08:1 on paper, so no visible indicator at all. `0750c52` **Shipped** A new light theme whose focus ring was the lime --accent token, the same value the dark theme uses. Every focusable element on every page was affected, in the theme that had just shipped. **Caught by** Verify stage, after merge **Root cause** Every focusable element on every page drew its focus indicator in the lime --accent token: 17:1 contrast on the dark theme, 1.08:1 on the new paper-colored light theme. Not a weak indicator — no indicator, on every focusable element, on every page, in light mode. **Guard added** A new --focus-ring token (unchanged lime on dark, a darker olive on light tuned to clear 3:1 against every surface); a non-text 3:1 contrast floor plus a grep rejecting var(--accent) inside any :focus rule in verify-theme.mjs — axe-core does not check focus-ring contrast at all. [Practice: Multi-pass, independent review](https://customlabs.io/agentic-delivery/#rt-multi-pass-independent) 04 ### Filter chips left five empty category headings behind, and two strings shipped literal markdown backticks. `5bb18fd` **Shipped** Category filter chips on the failure-modes field guide hid the matching cards but left their category headings behind — filtering to one category could leave five empty, ruled headings on the page. Two strings also shipped literal markdown backticks onto the page and into the emitted HowTo JSON-LD. **Caught by** Review stage **Root cause** The click handler toggled visibility on the cards only, never on the heading wrapper around them; the backticked strings were plain prose Astro renders as literal text, not markdown. **Guard added** The filter logic moved into one applyFilter() function that also hides an empty category heading and runs once on page load, so the default view matches a click on "All"; TopicMember became a discriminated union on kind to restore the compile-time guarantee that date fields are actually present. [Practice: Machine-checkable acceptance criterion](https://customlabs.io/agentic-delivery/#td-acceptance-criterion) 05 ### The header search trigger navigated to /search/ and opened the command palette on top of it. `13a7bdd` **Shipped** The header search trigger both navigated to /search/ and opened the command palette on top of the new page — two stacked search surfaces from one click. **Caught by** Browser check after merge **Root cause** Listener ordering, not the anchor. ClientRouter registers a document-level click listener at parse time and only bails if preventDefault() was already called; the palette's own delegated handler registered later, in bubble phase, so ClientRouter ran first and navigated before the palette could stop it. **Guard added** The delegated handler moved to { capture: true }, which always runs before a bubble-phase listener regardless of registration order; verify-seo.mjs now greps the source for that option, and the why is written into README.md. [Practice: Write it down](https://customlabs.io/agentic-delivery/#dm-write-it-down) 06 ### Nine product pages rendered nine content sections with no real heading — one h1, one h2, per page. `175100b` **Shipped** Nine product pages rendered their content sections as styled kicker spans — visually a heading, structurally nothing. Page outline was one h1 and a single h2 from the FAQ component, across nine content sections per page. **Caught by** Review stage **Root cause** The exact failure these pages existed to fix: no heading outline for a screen reader or crawler to navigate by. **Guard added** Every section now pairs its kicker with a real h2, the same way failure-modes/[slug].astro does; outline is now one h1 plus ten h2s per page. [Practice: Humans review decisions](https://customlabs.io/agentic-delivery/#rt-humans-review-decisions) 07 ### A mega-menu overflow fix silently killed the hover bridge an earlier fix had added. `991ba4f` **Shipped** A change that gave the library panel a scrolling body clipped a hover bridge positioned outside that scroll box. The bridge stayed in the CSS, but the pointer could no longer reach it. The panel then depended on a 300ms grace timer instead. **Caught by** Review stage **Root cause** The bridge lived on the panel itself, and the panel now clipped anything outside its own padding box. Its height and the real gap it had to cover had also drifted apart, from 4px to 16px. **Guard added** The bridge moved onto the non-scrolling trigger link, and its height and the panel offset now both resolve from one shared --library-panel-gap variable. verify-a11y.mjs asserts the bridge is never a pseudo-element of the scrolling panel, and that both measurements still trace back to that one variable. [Practice: Multi-pass, independent review](https://customlabs.io/agentic-delivery/#rt-multi-pass-independent) 08 ### A rewrite satisfied the rule-of-three gate by reshaping triads instead of cutting them. `7df0e2b` **Shipped** A pass at the copy gate deleted Oxford commas and recast lists after colons. It also rewrote conjunctions to move a triad out of the detector's view. None of it actually shortened the list underneath. **Caught by** Review stage **Root cause** The gate matched one literal pattern. Any rewrite that kept the same three items in a different shape passed clean, whether or not the underlying list actually got shorter. **Guard added** The rewrite was redone from scratch, item by item, against the real prose instead of the regex. verify-copy.mjs now names comma deletion and disguised conjunctions as evasions, never as fixes. A ratchet holds the new counts down, so a future pass can only shrink them further. [Practice: Machine review first](https://customlabs.io/agentic-delivery/#rt-machine-review-first) 09 ### A mobile overflow fix turned two scroll containers into ones a keyboard could not reach. `6a78cd8` **Shipped** Giving two containers min-width: 0 made their overflow-x: auto rule finally engage, turning them into live scroll regions on every architecture page. Neither one carried a tabindex, so a keyboard user could not reach either. **Caught by** Review stage **Root cause** A scroll container that cannot shrink never actually scrolls, so the earlier accessibility sweep never saw a live region there. Fixing the overflow made the region real and exposed the gap. **Guard added** tabindex="0" now ships on every affected container and on every fenced code block. A new check derives live scroll regions straight from the CSS. Any selector that can shrink and sets overflow-x must carry tabindex="0" on every matching element in the built HTML. [Practice: Humans review decisions](https://customlabs.io/agentic-delivery/#rt-humans-review-decisions) 10 ### A diagram lane-label guard estimated text width from font size, and passed while a label overflowed. `e37c44d` **Shipped** A build-time check assumed 6.5px per character for a lane label. A label rendered wider than that assumption allowed. It overflowed past its lane, and the check said nothing. **Caught by** Review stage **Root cause** The constant was a guess, never checked against the label's real face. A 29-character label measured 217px in a 210px lane and the guard read it as narrow enough. **Guard added** The constant now comes from a real measurement of the rendered text: 7.5px per character. The corrected guard caught four labels genuinely over budget, and each one was shortened. [Practice: Name the verification command](https://customlabs.io/agentic-delivery/#td-name-verification-command) 11 ### A copy squeeze cut six real product facts to buy headroom the file did not need. `4315949` **Shipped** A pass at trimming products.ts deleted concrete claims. One cut broke a FAQ answer outright, and the file sat well under its own triad allowance the whole time. **Caught by** Review stage **Root cause** Cutting a real fact and cutting a decorative one both lower the same count. Nothing separated a load-bearing claim from a headroom-buying one until a reviewer read each cut against its own product page. **Guard added** Every fact came back, and the ratchet baseline now locks in the restored counts. products.ts cannot fall below them again without a reviewer approving the drop line by line. [Practice: Machine-checkable acceptance criterion](https://customlabs.io/agentic-delivery/#td-acceptance-criterion) 12 ### Permalinks for the new deep-link layer landed under the sticky section strip. `2cac532` **Shipped** 261 of 408 permalink targets resolved a scroll offset of zero. A reader following one of those links landed with the heading hidden under the strip, or scrolled past it. **Caught by** Review stage **Root cause** The offset rule matched only one heading shape, a direct child of
. Every id this layer actually added sat one level deeper, so most of them never got the offset at all. **Guard added** The offset now rides on an explicit attribute carried by the exact element each permalink points at, not on how deep that element sits. verify-seo.mjs asserts the attribute and its offset rule both still exist, and that every permalink target carries the attribute. [Practice: Write it down](https://customlabs.io/agentic-delivery/#dm-write-it-down) No incidents match that filter. Clear it to see all 12. 03: Every bug became an invariant ## 13 checks, each one because something broke. Named with the file that enforces it, and the exact failure it now makes impossible to reintroduce. ### OG image byte-hash uniqueness `scripts/verify-seo.mjs` A social-card render silently collapsing to the same blank PNG for every route — the URL-uniqueness check alone would have passed while every card was byte-identical. ### Non-text 3:1 contrast floor on --focus-ring `scripts/verify-theme.mjs` A focus indicator that clears contrast on dark and fails it on light (or any future surface) shipping unnoticed — axe-core has no check for this at all. ### Capture-phase listener grep on the search trigger `scripts/verify-seo.mjs` The header search anchor navigating to /search/ and opening the command palette on top of it at the same time — a runtime race with nothing in the built HTML to assert against otherwise. ### Text-contrast floor (4.5:1) across every token pair `scripts/verify-theme.mjs` A text color quietly failing WCAG AA against its own surface — the fix for a specific --text-dim-as-text regression (2.85:1), generalized to every text-and-surface pairing in both themes. ### Search-index coverage invariant `src/lib/search-index.ts` A published page or entry with no way to find it through site search — the fix for a 39-route hole that had gone unnoticed across case studies, glossary, topics, tools, pricing, and the diagnostic pages. ### Inline document-weight ceiling `scripts/verify-seo.mjs` Something large getting inlined into every page again — the search index used to add roughly 47 KB to every single page's HTML before it moved to a static endpoint. ### Search-index anchor resolution `scripts/verify-seo.mjs` A search result promising a specific row and landing the reader at the top of the page instead. Every record whose URL carries a "#" must match a real id in the built HTML — the check this page itself was rejected for missing. ### Typo and alias recovery fixtures `scripts/verify-search.mjs` A real query returning zero hits because it was misspelled or phrased with an industry alias instead of the record's own wording. Every alias also gets its own integrity check, so a renamed or removed target fails the build instead of quietly resolving to nothing. ### External source register coverage `scripts/verify-sources.mjs` A guide citing only its own site as evidence for a claim that needs an outside source. Fixed the reference layer that gave every guide a real, named citation instead of a self-referential loop. ### Markdown-twin coverage `scripts/verify-md.mjs` A page shipping with no plain-text Markdown counterpart for a crawler or an LLM to read. Closed the gap where llms-full.txt carried only a quarter of the site. ### Shrinkable scroll regions must be keyboard-reachable `scripts/verify-responsive.mjs` A container that gains real horizontal scroll once it can shrink, with no tabindex added alongside the fix. Derived straight from the CSS: any selector that can shrink and sets overflow-x must carry tabindex="0" on every element it matches. ### Reading-scale snapshot ratchet `scripts/reading-scale.mjs` A page's published read-time badge drifting from its actual word count after a later content edit, on a page that never carried one at all. ### Rule-of-three density ratchet `scripts/verify-copy.mjs` A fixed rule-of-three tell creeping back in one file at a time. Also blocks a rewrite that satisfies the gate by reshaping a triad instead of genuinely cutting or splitting it. 04: Before you copy this ## What this doesn't prove. Read this section before the numbers above, not after. - One repository, one static marketing site. It says nothing about how a fleet performs on a distributed system or a regulated one. - No regulated or sensitive data ever passed through any of these tasks. - The numbers are self-reported: this studio wrote the tasks, ran the fleet, and is now publishing its own git history. Nobody independent audited it. - A sample of 163 tasks over 63 days on one codebase — not a controlled study, and not necessarily representative of a different codebase, team, or task mix. - A defect counts here only if a commit recorded it. A mistake caught and fixed inside the same branch, before it ever reached review, leaves no trace in this record at all — which means the 12 incidents on this page are a floor, not a ceiling, on what actually went wrong along the way. - The review stage did real, load-bearing work in every one of the 12 incidents above — this is an argument for keeping it, not for needing it less. Fleet throughput is a function of the gates, not a replacement for them. Read the model this evidences The Agentic Delivery Playbook is the 22-practice operating model behind every task on this page. CodeHerder is the product that runs it day to day. [The Agentic Delivery Playbook →](https://customlabs.io/agentic-delivery/)[See CodeHerder →](https://customlabs.io/products/codeherder/)[Book a Ship Audit →](https://customlabs.io/diagnostic/ship-audit/) Questions ## 05: Before you ask. What people ask us about publishing this. 01 Did agents write all of it? + Most of the code, yes — plan, code, and several rounds of review and verify run as agent stages. Of the 12 commits above, 6 carry the agent's own author name and 6 carry a human one; the record draws from both. 02 Doesn't this prove agents need heavy supervision? + Yes, and that's the point. Every one of the 12 incidents on this page was caught by a gate, not by the agent that wrote the code catching its own mistake. Take the gates away and this page is a list of 12 things that shipped broken instead of a list of 12 things a check caught. 03 Why publish your own bugs? + Because a claim about how well a delivery model catches defects is only worth something if it names actual defects, not a hypothetical failure rate. 12 real incidents, with the real root cause and the real guard that came out of each one, is the strongest evidence we have for the operating model on /agentic-delivery/. 04 Can we see the repo? + No — it's private. The short SHAs on this page are evidence text, not links; nothing here resolves to a URL you can open. 05 Does this transfer to our codebase? + The pattern does; the numbers don't. One task per branch, a fixed stage sequence, and a review stage that actually looks for problems is the transferable part — see the practices this page links out to on /agentic-delivery/. Our own count of merged tasks and follow-up branches is specific to this repository.