S0251-cli-runtime-1: declare a Node range the CI matrix actually exercises - #54
Open
NSchatz wants to merge 1 commit into
Open
S0251-cli-runtime-1: declare a Node range the CI matrix actually exercises#54NSchatz wants to merge 1 commit into
NSchatz wants to merge 1 commit into
Conversation
…cises `engines.node` said `>=22.0.0` while the test matrix ran 22 and 24 only. Node 26 is supported upstream, sat inside that range, and was exercised by nothing, so an install on Node 26 was a combination nobody here had run and the manifest said nothing about it. The claim narrows to the tested set rather than the tested set widening to the claim. Each matrix cell emits a required status-check context named in a GitHub ruleset with no bypass actors, and no commit in this repository can edit it: a cell added without its context arrives NOT REQUIRED (a red X that blocks nothing) and a cell removed leaves a required context nothing emits, which makes every pull request unmergeable by anyone. Widening starts outside this repository: ruleset first, matrix second, range third. - `engines.node` becomes `>=22.0.0 <26.0.0`: the minimal narrowing that excludes the offending line and nothing more, since a published range is corrected only by another publish. - `.github/workflows/ci.yml` passes `node-versions: '["22", "24"]'` explicitly. Same two values the shared workflow already defaults to, so the runs and every context name are unchanged; what changes is that the tested set is a fact stated in this repository rather than an input default resolved in another one. - `test/node-release-schedule.json` carries the upstream release schedule with its source URL, accessed date and sha256, so the guard derives support from a primary record instead of a number typed into a test. - `test/node-support.test.ts` reds when the range and the matrix disagree in either direction, when the range admits a major the schedule does not carry, when the range has no upper bound, and when the contributor guide or the installation page restates either one differently. It refuses to report agreement over an absent, empty or provenance-less record, and every failure direction is proved over a constructed input at an injected run date. - `CLAUDE.md` and `docs-content/installation.md` state the bound too, so no surface still promises a runtime the suite never runs. No `src/` change: no runtime version check, no startup diagnostic, no new exit code. `fuzz.yml` and `release.yml` keep their own `node-version: 22` pins.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spec:
work/specs/S0251-cli-runtime-1/spec.md(umbrella).The gap
engines.nodedeclared>=22.0.0. The test matrix runs 22 and 24. Node 26 issupported upstream, was admitted by that range, and was exercised by nothing, so
an install on Node 26 was a combination nobody here had run and the manifest said
nothing about it.
The direction, and why it is not symmetric
The claim narrows; the matrix does not grow. Each matrix cell emits a required
status-check context (
ci / verify (22, ubuntu-latest),ci / verify (24, ubuntu-latest)) named in theci-required-checksruleset withbypass_actors: [], and no commit in any repository can edit that ruleset.nothing. That has happened here for real once (
prepublish, 2026-08-05).rather than failing, and leaves every pull request unmergeable by anyone,
admin included, including the one that would undo it.
So widening is a three-step change that starts outside this repository: ruleset
first, matrix second, range third. This PR does none of it.
No status-check name changes here. The caller passes the same two values the
shared workflow already defaults to, so the runs and every context name are
byte-identical to the run before this change.
What changed
package.json:engines.nodebecomes>=22.0.0 <26.0.0. The minimalnarrowing that excludes the offending line and nothing more, because a
published range is corrected only by another publish, never by a retraction.
.github/workflows/ci.yml: passesnode-versions: '["22", "24"]'explicitly, so the tested set is a fact stated in this repository rather than
an input default resolved in another one. The comment records why the values
are not free to change.
test/node-release-schedule.json: the upstreamnodejs/Releaseschedule,with its source URL, accessed date and sha256 recorded beside it, so support is
derived from a primary record rather than a number typed into a test.
test/node-support.test.ts: the guard.CLAUDE.mdanddocs-content/installation.md: state the bound too, sono surface still promises a runtime the suite never runs.
What the guard does
It derives the supported set at the run date (
start <= today < end) from thecommitted record, and reds on:
message names the major, the range and the matrix);
strands a tested line;
than unsupported;
differently.
It refuses to report agreement over an absent, empty or provenance-less record,
and asserts it opened a real one first. Every failure direction is proved over a
constructed input at an injected run date, and the LTS-to-Maintenance transition
(v24, 2026-10-20) is proved not to change anything while an
enddate is provedto stop requiring a line in the matrix.
The guard was watched failing against the pre-change tree: reverting
enginesto
>=22.0.0reportsrange-unbounded-aboveandrange-admits-untested-majornaming Node 26, the range and the matrix.
Out of scope, deliberately
No
src/change: no runtime version check, no startup diagnostic, no exit code.Nothing in
cosyte/.githubis edited. Theci-required-checksruleset isuntouched. The
uses: ...@mainreference is left alone (a real finding, aseparate item).
fuzz.ymlandrelease.ymlkeep their ownnode-version: 22pins. Nothing asserts how a package manager reacts to an
enginesmismatch.