Skip to content

Change lifecycle

A change to this site is a push. What happens after the push is a fixed sequence: the data snapshots are rebuilt, the corpus slice is rendered, the publish controls scan the source, the bundle is built and scanned again, the dependency tree is scanned and its inventory proved ingested, the bundle is uploaded, and only then does a browser open the live site and assert on what it actually rendered. Every step below is that sequence, with its real timings.

Change lifecycle — 6 real publishes of this site, step by step

Snapshot taken — build-time, not live
  • 25steps in a run
  • 7of them are gates
  • 11m 12smedian run
  • 2m 27smedian queue
25 of 25
  1. committed23 Aug 2026, 08:22 AEST
  2. queued 4swaiting for a free agent on a two-agent pool
  3. ran 11m 38s7 of 25 steps were gates, 7m 11s of them
  4. live50h 49m from commit to serving
Initialize job1s
Checkout arronpitman-site (fresh per-run workspace)2s
Sync the pitlab-docs corpus and the gate checkout2s
Emit the build-time data snapshots (fail-closed, sanitisation asserted)16s
Render the public corpus slice into Starlight pages2s
Scrub gate — rendered source (fail-closed)2s
Decide whether the published set actually changed0s
Stage the checkout onto docker01 (control01/runners stay clean)4s
npm ci (pinned Node image)40s
Pre-render every Mermaid diagram to both-theme SVG1m 24s
astro build27s
Scrub gate — built bundle (fail-closed, on the real artifact)9s
Prove the scrub gate reads the set-piece data (red on a fixture per panel)48s
Trivy scan the built dependency tree and prove Dependency-Track ingested it30s
Pre-deploy artifact gate (rendered title + Pages free-tier limits)2s
Bundle gate — mermaid absent from the shipped JavaScript2s
wrangler pages deploy (direct upload)19s
Post-deploy acceptance — live page serves the rendered title1s
Rendered-DOM acceptance in a headless browser (live site)35s
Diagram legibility at a 390px viewport (live site, both themes, no-JS)1m 23s
Functional acceptance gate (service test plan)34s
Lighthouse — record the scores and hold the measured floors3m 58s
Clean up the docker01 staging directory6s
Post-job: Checkout arronpitman-site (fresh per-run workspace)1s
Finalize Job0s

A run executes 25 steps against the 22 the pipeline declares: the difference is the agent's own job scaffolding — initialising, tearing the workspace down, finalising — which is real time on the clock and is shown rather than netted out. Real timings from each run's own timeline, not a diagram of the intended process. A gate is marked because of the script it runs, matched against the same gate map the CI gate panel is built from — never because its name contains the word. Two of these runs share a commit: the pipeline is triggered by pushes to two repositories, so one change can legitimately publish twice.

The queue is the part worth looking at. Median run is 11m 12s and median queue is 2m 27s, but the spread on the queue is far wider than the spread on the run — the pool has two agents and every session in the estate shares them. Lead time for changes is a property of the queue at least as much as of the build, which is why the two are measured separately rather than summed into one reassuring number.

A step is marked as a gate because of the scripts it runs, matched against the same derived gate map the CI gates panel is built from — one derivation behind two panels, so they cannot come to disagree about what a gate is.

The alternative was to match the word “gate” in the step’s display name, and it is worth saying why that was rejected: it would label a step called Bundle gate and miss Rendered-DOM acceptance in a headless browser, which is the strictest gate in the run. An assertion that labels the easy cases correctly and misses the important one is the shape this estate calls an assertion that cannot fail.

Median run and median queue are measured separately and never summed into one number, because they are different problems with different fixes. The build is bounded by what the build does. The queue is bounded by how many agents the pool has — two — and by every other piece of work in the estate competing for them. Lead time for changes is a property of the queue at least as much as of the pipeline, and an estate that reports only the run time is reporting the half it controls.

Post-deploy assertion, not pre-deploy hope

Section titled “Post-deploy assertion, not pre-deploy hope”

The last four steps all run after the bundle is live. That ordering is deliberate. A check that terminates before the edge has repeatedly been green while the page was broken — a 200 from a cached error page, a script tag that proves a file was linked rather than that anything ran, a string present in server-sent HTML that survives a failed client render. So the acceptance gates here open a real browser against the real deployment and assert on the rendered result. If they refuse, the previous deployment is still the one being served.