Skip to content

[finding] the served openapi.json overrides the info.version that packages/spec owns, so the published artifact says 17.2.0 and the served document says v1 #11646

Description

@os-zhuang

Raised by the dev seat on #11546 / PR #11641 as an open question, and routed here rather than
answered: it is a public-document contract shape, which sits on the manual floor. ⛔ Not graded
and not decided by the routing seat. Filed unassigned.

PR #11641 corrected the comment on this line and removed a fallback; it deliberately did not
change the served value. This card is the question it left open.

The split, measured

info.version
the published artifact@objectstack/spec's ./openapi.json export, set by packages/spec/scripts/build-openapi.ts to SPEC_VERSION, pinned by openapi-self-consistency.test.ts 17.2.0
the served documentGET {base}/openapi.json, overridden at serve time with config.api.version v1

Same field name, same package family, two different kinds of fact. The route's own test twin already
asserts that the info block is "the half packages/spec owns" and that "serve-time enrichment
must not touch it"
— with the assertion narrowed to info.title alone, precisely because
version is overridden
. So the invariant is stated and then excepted, in the same file.

The three shapes

option what it costs
A leave the override (what #11641 shipped) — served info.version stays the declared API version identifier zero behaviour change on every working config; the two faces keep saying different things
B remove the override — served info.version becomes SPEC_VERSION, matching the published artifact and the twin's stated invariant a real behaviour change on a public document ⇒ Clause-② yes, contract review
C put info.version behind an explicit config key so a deployment states which fact it publishes new public surface for a demand nobody has expressed

What is already measured, so nobody re-derives it

  • Consumer survey — zero. No consumer reads this document's info.version by value in
    objectstack, objectui, cloud, or cloud-v1. The one v{info.version} render in cloud-v1
    (apps/cloud/components/api-docs/api-docs-viewer.tsx) reads cloud's own
    generateOpenAPISpec() document, not this one. So there is no consumer pull in either direction.
  • OpenAPI 3.1.0 does not adjudicate between the two. Its Info Object says version is "the
    version of the OpenAPI document (which is distinct from the OpenAPI Specification version or the
    API implementation version)"
    . That text excludes the runtime/implementation version — which is
    what settled @objectstack/rest openapi.json sets info.version to config.api.version ('v1') under a comment promising "the runtime version" — the comment is falsified by the line it introduces #11546's original fork — but it does not choose between v1 and 17.2.0.
  • The static artifact carries no paths. It is the contract half rather than a usable document,
    which is the strongest argument that the two faces are allowed to differ.

The axis the dev seat named as the weakest point of its own choice

Recorded verbatim rather than smoothed over, because it is the honest half of an A recommendation:

Long-term soundness: contract-first genuinely favours B (a consumer-side override rewriting a
producer-owned contract field is the shape the rule warns about), and this is the one axis where A
is the weaker answer — I am flagging that rather than smoothing it.

Against that: with a measured zero consumer pull, changing a served value on a public document is
the speculative widening the startup-scope axis exists to refuse, and #11546 was split out precisely
to avoid it.

Routing note

If this is graded as work, note that the field is owned by packages/spec's build
(build-openapi.ts, openapi-self-consistency.test.ts) while the override lives in packages/rest
— so the landing package depends on which option is chosen, and B in particular reads as a
domain:spec change rather than the domain:cli lane that filed it.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions