Release 6.4.0: freshness heartbeat, citation drift, API existence checks

Added

  • freshness-heartbeat component: publish what the last scheduled freshness tripwire said, and when. It resolves the report from the newest scheduled pipeline on the default branch regardless of status, picks the job by name, and emits freshness.json plus a badge for the deploy to serve. It checks nothing and never fails.

  • check-freshness pin and a content-drift layer, compared release to release. pin writes .gitlab/freshness.lock.json, fingerprinting each docs.gitlab.com citation from the docs archive of the stamped version where one is published, and the default run compares that against the archive of the newest released minor. Every pinned citation grades unchanged, drifted, unpinned or undetermined; a drifted citation is a finding at exit 1, a page absent at the newer release counts as drifted, a stamp with no archive keeps the default-page comparison, and no lock means no drift layer.

  • check-freshness drift, a subcommand for a project running its own checker. JSON in on stdin, JSON out on stdout, exit 0 always, so the caller decides severity. Each input URL may carry its own version, for a ledger graded per record rather than per file.

  • Rot findings now name the paths that cite the URL. collectCitations returns [{url, paths}], and a rot or drift finding carries cited_by in both the log and freshness.json.

Changed

  • The adoption profile pins catalog components by major (@6) rather than by full tag, so a patch to a component reaches its consumers without an MR in each one. Minors and patches resolve to the newest matching catalog release at pipeline time; a major bump stays a deliberate edit, reviewed against the breaking section of this file.

    • This reverses a posture, and the reversal is narrow. 5.0.0 fixed templates/paper/README.md for teaching @~latest in three places, "a floating ref in the one document a new consumer copies from". That finding still holds: ~latest and main float across majors, so a breaking release arrives with no diff to explain it. @6 does not cross a major, and majors are where this catalog's input contracts break.
    • Review gating moves rather than lifts. Estate-authored catalog components float within the pinned major, because the people who write a component write the consumers that include it. Third-party dependencies keep the review gate and the 7-day minimum release age.
  • freshness now checks gitlab.com blob, issue and work-item citations at the API rather than on the web. A missing blob does not 404 on the web: a deleted file answers 302 to /-/tree/<ref> on the same host, and the rot rule is a 404, a 410, or a redirect that leaves the cited host, so a deleted file read as fresh. The files API answers an honest 404, which turns a silent false negative into a finding. Per-host pacing is unchanged.

  • Renovate tracks reference design-system pins in versioned published URLs. A .../public-sector/reference/design/vX.Y.Z/ path in an .astro, .html or .md file was invisible to every manager Renovate ships, so it never bumped and its silence read as up-to-date.

Fixed

  • The catalog said images are tagged X.Y.Z "v-stripped to match $[[ component.version ]] interpolation". They are pushed under both X.Y.Z and vX.Y.Z, and component.version renders the v form under a @6 pin. Both README:44 and the changelog header carried the claim.

Merge request reports

Loading
Loading