Skip to content

feat: add system.v4, reporting the Node.js version a site declares - #14

Merged
Coysh merged 1 commit into
mainfrom
feat/system-v4-node
Oct 21, 2026
Merged

Coysh merged 1 commit into
mainfrom
feat/system-v4-node

Conversation

@Coysh

@Coysh Coysh commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Adds system.v4, which is system.v3 plus a required top-level node object, and releases as 1.10.0.

"node": { "declared": ">=18.17 <21", "source": "package.json" }

What it carries. declared is the Node.js version or range exactly as a site's .nvmrc, .node-version or package.json engines.node writes it. source is which of those three files it came from. Both are nullable.

Declared, not observed. The running version would mean executing a binary on the site's server, which this protocol does not ask a connector to do. The schema has no field for it.

What it refuses.

  • declared is at most 32 characters, from the characters a version or range is written in (digits, letters, .+^~<>=*|, space), with a slash allowed only inside an lts/ alias. A path, URL, shell fragment or sentence fails the pattern and is refused rather than truncated.
  • source is one of the three file names, never a path. .npmrc and the lockfile are not accepted.
  • node has additionalProperties: false.

Why node is required. {declared: null, source: null} means the connector looked and nothing is declared. No node means a connector that predates v4. Making it required keeps those two distinguishable, so the platform can say "Not declared" for one and nothing for the other.

Validator change. The schema uses "type": ["string", "null"], which SchemaValidator did not support: it cast the list to the string "Array", which no type check recognises, so it accepted any value. It now treats a list as "any of these". No published schema used a list, so nothing that validated before validates differently. There is a test for it that includes non-string values.

Add-only. system.v1 to system.v3, the signing fixtures and every existing fixture are untouched. v3 still rejects a node key.

Verification. composer test passes (435 tests, 2966 assertions, including the new v4 fixtures, pattern and length cases, null handling and the validator test). composer phpstan is clean. Version is 1.10.0 in CHANGELOG.md, composer.json and Protocol::VERSION, which VersionTest checks.

Release order. Connector and platform changes that use system.v4 can't go green until this is tagged v1.10.0 and on Packagist, since the schema ships inside the package.

A site's project files already say which Node.js version it needs, in
.nvmrc, .node-version or package.json's engines.node, and nothing in the
runtime report carried it. system.v4 adds a required node object holding
that declaration and the name of the file it came from.

The value is what the file says and not what is installed. Observing the
running version would mean executing a binary on somebody's server, which
this protocol does not ask a connector to do. declared is held to 32
characters from the set a version or range is written in, with a slash
permitted only inside an lts/ alias, so a path, a URL or a sentence in the
file is refused rather than forwarded. source is one of the three file
names, never a path to the file.

node is required and both members are nullable, so the two absences stay
distinguishable: null and null is a connector that looked and found nothing
declared, and no node at all is a connector that predates this version.

That needed the validator to read type as a list. A list was cast to the
word "Array", which no type check recognises and therefore accepts, so a
schema written ["string", "null"] would have validated any value at all.
No published schema used one, so nothing that validated before changes.

system.v1 to v3 are untouched.
@Coysh
Coysh merged commit 5427974 into main Oct 21, 2026
3 checks passed
@Coysh
Coysh deleted the feat/system-v4-node branch October 21, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant