How immutable pipeline versions work
The problem: an LLM content pipeline changes constantly — prompts, gates, step order. If the code that produced yesterday’s thousand articles can be edited in place, you lose the ability to answer the only question that matters when quality regresses: what exactly produced this article?
The naive answer — “check git history” — fails operationally: a running fleet doesn’t execute git history, it executes whatever is on disk, and a “small fix” deployed at noon silently changes what the nightly run does.
Layer 1 — a version is a directory, not a ref
Section titled “Layer 1 — a version is a directory, not a ref”Every pipeline version is a complete, immutable code directory:
pipelines/{id}/{variant}/{version}/ with its own manifest.yaml. Once
registered, the directory is never edited. A change — however small —
becomes a carve: byte-copy the parent version, apply the change,
register the new version in the catalog.
The manifest is the contract: the dispatcher reads it — steps, required environment, entrypoints — and never introspects the code. Old versions stay listed and stay runnable.
Layer 2 — resolution and pins
Section titled “Layer 2 — resolution and pins”Which version runs is resolved at dispatch time:
explicit request → per-contract pin → catalog latest. The nightly
production run additionally pins its Collect/Generate versions explicitly,
which turns promotion into a deliberate two-step: land the version, then
move the pin. A regression discovered between those steps never touches the
fleet.
Layer 3 — what this buys
Section titled “Layer 3 — what this buys”- Forensics. Every run records its version; the version can never change under it. “Which code wrote this sentence” has an exact answer, months later.
- Instant rollback. Move the pointer back. No revert commits, no redeploys of changed files, no “mostly the same” ambiguity.
- Safe parallelism. Multiple agents carve future versions while production stays pinned; nothing they do can destabilize the running code.
- Honest A/B. Two versions coexisting in the catalog can run against live contracts and be compared on output, because neither is a moving target.
The trade-offs, honestly
Section titled “The trade-offs, honestly”Immutability accumulates directories. The retention policy keeps the HEAD
tree small — live-pinned versions, latest and its predecessor, and named
rollback targets survive; everything else is deleted from the tree by an
explicit, owner-acknowledged cleanup (history stays in git, and every
removed version leaves a tag it can be restored from). Version numbering
carries meaning: a new major marks an architectural generation (for
Collect, v3.x is the vector-ranking generation; v2.x — the keyword one —
remains listed as the emergency fallback).
See it in two minutes
Section titled “See it in two minutes”Fetch the catalog surface and the current pins through the API, or simply
read the machine-readable manifest of this documentation build — the same
philosophy applies to these docs: versions.json +
manifest.json with content hashes, at the root of this portal.
Specs: SPEC-054 (catalog + manifest=contract), SPEC-063 (native execution), SPEC-120 (carve retention).