feat(engine): RELEASE-CURRENT — the version page a stranger actually reads

A release is not a ref, so `git ls-remote` cannot answer this one. It is
therefore the third API call per invocation, and the only new one the
acquisition model adds.

Both sides come from the forge, never the clone: comparing a local tag to a
published release would report portfolio-optimiser as stale when the real
defect is a tag that was never pushed — REMOTE-SYNC's subject, not this one.

Measured across all 22 registered repos before the rule was locked: 4 have no
tags, 2 tag without ever publishing a release, 11 are current, 5 lag. Those 2
are why zero releases is an OK and not a finding — nothing in a repo says which
of the two legitimate conventions it follows, the same measurement that
rejected VERSION-DRIFT. Lagging is a WARN because the remedy is safe, and
because this repo is the org's worst offender: an ERROR would have let the gate
settle an operator question by exiting 1 on its own author.

The shell that produced that baseline sorted tags lexically and put v0.9.0
above v0.10.0 — the exact defect compareTags exists to fix, reproduced in the
tool meant to validate it. Recorded as an invariant: derive "newest" with the
engine's own comparator or the measurement is fiction.

CLAUDE.md's API-call count moves from two to three in this same commit; that
line has now gone stale twice. The unmarked "429 at ~40" figure is marked
unusable — its endpoint class was never recorded, and org-ops measured ~110
raw reads at 0.4s with zero 429 the same day.

205 tests (was 196).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WWc4piM4QW6Jxfky2Rw4Z8
This commit is contained in:
Kjell Tore Guttormsen 2026-08-12 22:57:35 +02:00
commit a563035feb
4 changed files with 275 additions and 9 deletions

View file

@ -41,6 +41,7 @@ import {
loadRegister,
groupSkips,
skipsOf,
checkReleaseCurrent,
} from './repo-standard-check.mjs';
const REGISTER = {
@ -2005,3 +2006,81 @@ test('headerLine still prints the pre-0.8.0 line for a result with no skip split
const line = headerLine({ name: 'okr', klass: 'plugin', traits: [], status: 'OK', notChecked: 1 }, '0.8.0');
assert.match(line, /1 not checked/);
});
// ---------------------------------------------------------- RELEASE-CURRENT
//
// Levels come from the corpus, not from taste. Measured 2026-08-12 across all
// 22 registered repos (forge releases API vs `git ls-remote --tags`):
// 4 have no tags at all, 2 have tags and publish no releases,
// 11 are current, 5 lag their newest tag.
// A rule that failed the 2 tag-only repos would fail a correct repository —
// the mechanism that got VERSION-DRIFT rejected one check over.
test('a release listing that could not be fetched is a SKIP, never a pass', () => {
const f = checkReleaseCurrent({ forgeTagsSelf: ['v1.0.0'], releases: null });
assert.equal(f[0].level, 'SKIP');
assert.equal(f[0].skip, 'notRun');
});
test('refs that could not be read are a SKIP too — a missing side is not agreement', () => {
const f = checkReleaseCurrent({ forgeTagsSelf: null, releases: ['v1.0.0'] });
assert.equal(f[0].level, 'SKIP');
assert.equal(f[0].skip, 'notRun');
});
test('no tags on the forge is an OK — the check ran and found no subject', () => {
// The VERSION-NONE / TAGS-NONE shape: nothing could have been released, so
// there is nothing here to be wrong. Measured on 4 of 22 repos.
const f = checkReleaseCurrent({ forgeTagsSelf: [], releases: [] });
assert.equal(f[0].level, 'OK');
assert.equal(f[0].code, 'RELEASE-NONE');
});
test('tags with no releases is an OK — tag-only is a convention, not a defect', () => {
// ktg-plugin-marketplace (9 tags) and llm-security-commons (8) publish no
// releases at all. Nothing in a clone says which convention a repo follows.
const f = checkReleaseCurrent({ forgeTagsSelf: ['v0.1.0', 'v0.4.3'], releases: [] });
assert.equal(f[0].level, 'OK');
assert.equal(f[0].code, 'RELEASE-TAGS-ONLY');
assert.match(f[0].msg, /no release/i);
});
test('the newest release matching the newest tag is current', () => {
const f = checkReleaseCurrent({ forgeTagsSelf: ['v7.8.2', 'v7.8.3'], releases: ['v7.8.3'] });
assert.equal(f[0].level, 'OK');
assert.equal(f[0].code, 'RELEASE-CURRENT');
});
test('a release behind the newest tag is a WARN naming both versions', () => {
// repo-standard itself: v0.9.0 tagged, v0.3.0 published. The remedy — publish
// a release for a tag that already exists — is safe, unlike force-moving a
// published ref, so this is a WARN and not an ERROR.
const f = checkReleaseCurrent({ forgeTagsSelf: ['v0.3.0', 'v0.9.0'], releases: ['v0.2.2', 'v0.3.0'] });
assert.equal(f[0].level, 'WARN');
assert.equal(f[0].code, 'RELEASE-STALE');
assert.equal(f[0].bucket, 'weakening');
assert.match(f[0].msg, /v0\.9\.0/);
assert.match(f[0].msg, /v0\.3\.0/);
});
test('newest is version order, not lexical — v0.10.0 outranks v0.9.0', () => {
// The defect this repo already fixed once in compareTags, and reproduced a
// second time in the shell that MEASURED this check's baseline. okr is the
// live case: tag v1.10.0, release v1.9.0.
const stale = checkReleaseCurrent({ forgeTagsSelf: ['v1.9.0', 'v1.10.0'], releases: ['v1.9.0'] });
assert.equal(stale[0].code, 'RELEASE-STALE');
const current = checkReleaseCurrent({ forgeTagsSelf: ['v1.9.0', 'v1.10.0'], releases: ['v1.10.0'] });
assert.equal(current[0].code, 'RELEASE-CURRENT');
});
test('a pre-release tag published as a release is current', () => {
// llm-ingestion-okf sits on v0.5.0a2 in both places. A repo on a pre-release
// could never reach 0 findings if the suffix were truncated away.
const f = checkReleaseCurrent({ forgeTagsSelf: ['v0.4.0', 'v0.5.0a1', 'v0.5.0a2'], releases: ['v0.5.0a2'] });
assert.equal(f[0].code, 'RELEASE-CURRENT');
});
test('a release ahead of every known tag is not reported as stale', () => {
const f = checkReleaseCurrent({ forgeTagsSelf: ['v1.0.0'], releases: ['v1.1.0'] });
assert.equal(f[0].level, 'OK');
});