Version Pins as Snapshot, No In-Repo Automation¶
Context¶
A prescriptive technology guide that names specific versions of Go, Node.js, MkDocs Material, react-router, and other dependencies confronts a hard tension: the guide MUST be specific enough to be actionable (naming versions, not just packages) but MUST also remain accurate as the named versions age. The two failure modes are symmetrical: a guide too generic to be actionable ("use a modern Go") gives engineers no signal, while a guide whose specifics silently rot ("Go 1.21" three years after 1.25 ships) actively misleads them.
The industry pattern that resolves this tension is a periodic review
cadence anchored to a last-reviewed: YYYY-MM-DD per-page field. The
review answers "are these recommendations still current as of this
date?" and bumps the date whether or not the prose changes. Adopting
orgs reading the guide MAY look at the last-reviewed field to gauge
freshness without reading the prose.
The mechanically tempting alternative is in-repo automation: a
versions.yaml file with CI hooks that update version pins from
upstream sources (the Go release page, the npm registry, the GitHub
releases API). Several reasons argue against this for the current
artifact. First, the guide MUST NOT do work in the donor reference
repository — adding Makefile targets, versions.yaml, or CI hooks
violates the explicit constraint that the guide is built from the
donor reference, not in it. Second, automated version bumps without
human review re-introduce silent rot in a new form: the version updates,
but the surrounding prose ("react-router v7 Data Mode is canonical")
does not, and the recommendation drifts out from under the date stamp.
Third, the early lifecycle of this artifact does not justify the
automation cost — a quarterly human review is cheaper than a CI
maintenance burden for a guide that exists at organisational scale, not
hyperscale.
The decision is therefore to treat version pins as a snapshot at the
last-reviewed date, with no in-repo automation. The quarterly review
is the contract; the date field is the visible signal.
Decision Drivers¶
- The guide MUST name specific versions to be actionable.
- The guide MUST signal freshness to readers without forcing them to read every paragraph.
- The guide MUST NOT introduce automation or modify the donor reference repository.
- Version changes SHOULD pass through a human reviewer who can update surrounding prose if the recommendation itself changes.
- The maintenance burden SHOULD be proportional to the artifact's scale — a small artifact MUST NOT carry hyperscale tooling.
Considered Options¶
- Snapshot pins with
last-reviewedper-page frontmatter, quarterly human review, no automation - Automated version bumps via a
versions.yamlfile plus Renovate or Dependabot - Generic recommendations with no version pins ("use a recent stable Go")
- Version pins in a separate
versions.yamlfile with CI cross-checks but no automated bumps
Decision Outcome¶
Chosen option: "Snapshot pins with last-reviewed per-page frontmatter,
quarterly human review, no automation", because it is the only option
that gives readers specific actionable versions while keeping the
maintenance contract human and proportionate. The last-reviewed field
is the trust signal: a reader who sees last-reviewed: 2026-04-15 knows
the guide was actively reviewed within the last quarter and MAY trust
its specifics; a reader who sees a six-quarter-old date knows to verify
externally. The quarterly cadence is documented in the README and is the
maintainers' explicit obligation.
Positive Consequences¶
- Readers MAY gauge freshness per page without reading prose.
- Maintainers MAY update versions and surrounding prose together in a single human pass, avoiding drift between version and recommendation.
- The donor reference repository remains unmodified, satisfying the separation-of-artifact constraint.
Negative Consequences¶
- Version pins WILL fall behind upstream between reviews; readers MUST
treat the
last-revieweddate as a freshness ceiling. - A skipped quarterly review WILL silently extend the staleness window; the convention depends on maintainer discipline.
Consequences¶
After this decision, every chapter file MUST carry a
last-reviewed: YYYY-MM-DD field in its YAML frontmatter. The README
MUST document the quarterly review cadence and MUST name the
responsible maintainer role (not a specific person). The CHANGELOG MUST
record review passes that touched recommendations, distinct from
review passes that only bumped the date. No automation infrastructure
is added to the guide repository or to the donor reference repository.
Pros and Cons of the Options¶
Snapshot pins with last-reviewed frontmatter, quarterly human review¶
A per-page last-reviewed date plus a documented review cadence.
- Good, because readers MAY gauge freshness at a glance.
- Good, because version and recommendation MUST be updated together by a human, preventing drift.
- Good, because no automation infrastructure is added to either repository.
- Bad, because the convention depends on maintainer discipline; a skipped review WILL silently stale the artifact.
Automated version bumps via versions.yaml plus Renovate or Dependabot¶
A machine-readable version file with bot-driven pull requests.
- Good, because version pins stay current without human cadence.
- Bad, because surrounding prose does NOT auto-update with version bumps, so recommendations silently drift from their pins.
- Bad, because the automation MUST live somewhere — either in the donor repository (forbidden) or in a third repository (more infrastructure).
Generic recommendations with no version pins¶
Recommendations such as "use a recent stable Go release".
- Good, because the guide never goes stale on version specifics.
- Bad, because engineers cannot scaffold a project from generic recommendations — the guide loses its action value.
Version pins in a separate versions.yaml with CI cross-checks¶
Versions live in a single file; CI fails if chapter prose references a different version.
- Good, because version drift between chapters is mechanically prevented.
- Bad, because the cross-check infrastructure is non-trivial to author and maintain.
- Bad, because the underlying problem (versions age) is not solved — only the within-guide consistency is.
Links¶
- Keep a Changelog convention: https://keepachangelog.com/en/1.1.0/
- See also ADR 0002 (site generator), ADR 0001 (hybrid structure).