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.ts17.2.0
the served documentGET {base}/openapi.json, overridden at serve time with config.api.versionv1

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

optionwhat it costs
Aleave the override (what #11641 shipped) — served info.version stays the declared API version identifierzero behaviour change on every working config; the two faces keep saying different things
Bremove the override — served info.version becomes SPEC_VERSION, matching the published artifact and the twin's stated invarianta real behaviour change on a public document ⇒ Clause-② yes, contract review
Cput info.version behind an explicit config key so a deployment states which fact it publishesnew 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

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions