Skip to content

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-reviewed per-page frontmatter, quarterly human review, no automation
  • Automated version bumps via a versions.yaml file plus Renovate or Dependabot
  • Generic recommendations with no version pins ("use a recent stable Go")
  • Version pins in a separate versions.yaml file 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-reviewed date 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.