Found while implementing #11292 (which removes the sibling override on /discovery). Filed, not fixed: #11292's declared surface is the discovery seam, and this site is a different document with a different convention, so it carries a real design question rather than being a mechanical extension of that card.
What was measured
packages/rest/src/rest-server.ts:3622-3629, on main at daacc107:
// Surface the runtime version so consumers don't pin to// the spec package's compile-time version.if(enriched.info){enriched.info={
...enriched.info,version: this.config.api.version||enriched.info.version,};}The comment states the intent — the runtime version, so consumers don't pin to a compile-time value. The line does something else: config.api.version is the API version identifier, which normalizeConfig() in the same file defaults to 'v1' (api.version ?? 'v1'), which packages/spec/src/api/plugin-rest-api.zod.ts declares as z.string().default('v1').describe('API version identifier'), and which getApiBasePath() uses to build the mount (api.apiPath ?? \${api.basePath}/${api.version}`→/api/v1`).
So GET /api/v1/openapi.json advertises info.version: "v1" on every build of every release. It is neither the runtime version the comment promises nor the spec package's compile-time version it says it is avoiding — the || enriched.info.version fallback, which would yield the latter, is unreachable in every default configuration because 'v1' is always truthy.
Why this is not simply #11292 repeated
#11292 removes discovery.version = this.config.api.version because DiscoverySchema declares version under "System Identity" — the "what server is this" question, settled by #10993. That reading does not transfer here by itself:
- OpenAPI's
info.version is defined by the OpenAPI spec as "the version of the OpenAPI document" / of the described API — so an API-version identifier is a defensible value there, unlike on DiscoverySchema.version. - Which means the defect here is narrower and sharper: the comment and the code disagree, and one of them has to move. Either the value becomes the runtime version the comment promises (
resolveDiscoveryVersion() from @objectstack/metadata-protocol, or the same OS_RUNTIME_VERSION stamp /health and both discovery producers now read), or the comment is rewritten to say the API version is deliberate and the fallback is dead.
That choice is a triage/maintainer call, not a dev call, which is why this is filed rather than folded into #11292.
Scope note
Not measured here: whether any consumer reads openapi.json's info.version by value. #11292's consumer survey covered discovery version, not this field, and its finding does not carry over.
Found while implementing #11292 (which removes the sibling override on
/discovery). Filed, not fixed: #11292's declared surface is the discovery seam, and this site is a different document with a different convention, so it carries a real design question rather than being a mechanical extension of that card.What was measured
packages/rest/src/rest-server.ts:3622-3629, onmainatdaacc107:The comment states the intent — the runtime version, so consumers don't pin to a compile-time value. The line does something else:
config.api.versionis the API version identifier, whichnormalizeConfig()in the same file defaults to'v1'(api.version ?? 'v1'), whichpackages/spec/src/api/plugin-rest-api.zod.tsdeclares asz.string().default('v1').describe('API version identifier'), and whichgetApiBasePath()uses to build the mount (api.apiPath ?? \${api.basePath}/${api.version}`→/api/v1`).So
GET /api/v1/openapi.jsonadvertisesinfo.version: "v1"on every build of every release. It is neither the runtime version the comment promises nor the spec package's compile-time version it says it is avoiding — the|| enriched.info.versionfallback, which would yield the latter, is unreachable in every default configuration because'v1'is always truthy.Why this is not simply #11292 repeated
#11292 removes
discovery.version = this.config.api.versionbecauseDiscoverySchemadeclaresversionunder "System Identity" — the "what server is this" question, settled by #10993. That reading does not transfer here by itself:info.versionis defined by the OpenAPI spec as "the version of the OpenAPI document" / of the described API — so an API-version identifier is a defensible value there, unlike onDiscoverySchema.version.resolveDiscoveryVersion()from@objectstack/metadata-protocol, or the sameOS_RUNTIME_VERSIONstamp/healthand both discovery producers now read), or the comment is rewritten to say the API version is deliberate and the fallback is dead.That choice is a triage/maintainer call, not a dev call, which is why this is filed rather than folded into #11292.
Scope note
Not measured here: whether any consumer reads
openapi.json'sinfo.versionby value. #11292's consumer survey covered discoveryversion, not this field, and its finding does not carry over.