Skip to content

fix(compilers/openapi)!: record $self on the document's source - #732

Open
fuad-daoud wants to merge 7 commits into
mainfrom
relevo/build-614
Open

fuad-daoud wants to merge 7 commits into
mainfrom
relevo/build-614

Conversation

@fuad-daoud

@fuad-daoud fuad-daoud commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • ir.SourceInfo gains SelfURI (json:"selfURI,omitempty"), and the OpenAPI compiler fills it from doc.GetSelf(). It sits on the source entry beside format, path and hash because $self is a fact about one input file, not about the document: several may be loaded, each may declare its own, and a document-level field could not say which file declared it.
  • The URI is recorded at every supported minor, not gated to 3.2. The library parses the keyword at every 3.x minor and reports no finding for it, so a version gate would silently drop a value a document wrote. A 3.1 document that writes $self is the case that would have been dropped; the recorded value is the declared one either way.
  • $self: "" and an unset $self are one state: an empty URI reference is not a base URI (RFC 3986 §5.1), it identifies nothing when documents are combined, and nothing downstream can act on the difference. That is why the field is a plain string with omitempty.
  • Deliberately out of scope, stated here and in the field's GoDoc: resolving relative references through the URI (GitHub engine: multi-file specs — bounded load-and-bundle and a sources-based entry point #74 owns that wiring), and any diagnostic for a $self written by a dialect that does not define it — the analogous location check for allowReserved is openapi: allowReserved on a path or header parameter is kept without a warning #628, not this change. This change adds no diagnostic code.
  • Nothing else moves: no openapi.Options, pass/, engine/, CLI or irverify change.
  • D5 — IRVersion stays 0.6.0. docs/ir-design.md §2.1 moves the version for "a key renamed or removed, an encoding changed, or the meaning of an existing key changed"; a new optional member is none of those, and the one pure field addition in the history (Property.Constraints, ecd2e78) landed without one. Counter-reading, stated not hidden: ir/document.go warns that a shape change reaching main without a bump leaves a consumer pinned to the old version accepting a document it cannot read, and a 0.6.0 build handed a document carrying selfURI does fail to decode it — loudly, on the unknown member. This PR takes the §2.1 enumeration. If the batch owner rules the other way, the follow-up is mechanical and touches nothing else here: bump the constant to 0.7.0 with a log paragraph, re-anchor TestCompatibleVersion's three neighbour literals, run the -update sweep, and title the PR feat(ir)!: ….

Test plan

  • go test ./ir -run TestSourceInfo — the wire shape: a declared URI under selfURI byte-exact beside format/path/hash, and no key at all when unset; each row also decoded back.
  • go test ./compilers/openapi -run TestParse_RecordsSelfURI — five rows: 3.2 with $self, 3.2 without, 3.2 with $self: "", 3.1 with, 3.0 without; each asserting no error diagnostic, one source, and Sources[0].SelfURI.
  • Corpus: testdata/conformance/openapi/self-uri.yaml (3.2.0, $self, info, paths: {}) with {"self-uri", assertSelfURI, nil} and its golden; go test ./compilers/openapi green, unwitnessed.golden.txt unchanged.
  • Planted mutations: deleting SelfURI: doc.GetSelf() reddens TestParse_RecordsSelfURI/3.2_with_$self, /3.1_with_$self and TestConformance/self-uri; deleting $self: from the fixture reddens TestConformance/self-uri on the capability assertion and leaves the golden unrewritten — require.False(t, t.Failed()) guards the snapshot from being rewritten behind a regression — while a byte-deleted selfURI key is restored byte-identically by -update.
  • make gate green on 804b9ae, with main merged in: coverage at exactly 100%, golangci-lint 0 issues. The two doc comments over the 100-word cap that failed the earlier CI run are rewritten.
  • The 0.8.0 bump regenerates every golden; the only change in each is the irVersion line, and TestCompatibleVersion's neighbour rows are re-anchored.

Breaking

ir.IRVersion moves from 0.7.0 to 0.8.0. SourceInfo gained selfURI, and ir-design §2.1 moves the version on any change to a Document's JSON shape: a consumer built against 0.7.0 refuses the new member, so a document carrying it is unreadable there. The version history in docs/ir-design.md records the entry. #734 and #735 also claim 0.8.0, so whichever of the three merges later moves to the next version.

ir.SourceInfo gains SelfURI, the URI a document declares for itself, and the
OpenAPI compiler fills it from doc.GetSelf(). It sits on the source entry rather
than on the Document because it is a fact about one input file: several may be
loaded, each may declare its own, and a document-level field could not say which
file declared it.

The URI is recorded at every supported minor, not gated to 3.2. The library
parses `$self` at every 3.x minor and reports no finding for it, so a version
gate would drop a declared value without reporting it — the defect this closes.

An empty `$self` and an unset one are one state and one field value: an empty
URI reference is not a base URI (RFC 3986 §5.1), so it identifies nothing when
documents are combined.

Out of scope, stated in the field's GoDoc: resolving relative references through
the URI (GitHub #74 owns that wiring), and reporting a `$self` written by a
dialect that does not define it. The field raises no diagnostic of its own.

IRVersion stays 0.6.0: a new optional member is none of the shape changes
docs/ir-design.md §2.1 moves the version for.
@fuad-daoud fuad-daoud self-assigned this Sep 30, 2026
@fuad-daoud fuad-daoud changed the title fix(compilers/openapi): record $self on the document's source fix(compilers/openapi): record $self on the document's source (#614) Sep 30, 2026
@fuad-daoud fuad-daoud changed the title fix(compilers/openapi): record $self on the document's source (#614) fix(compilers/openapi): record $self on the document's source Sep 30, 2026
fuad-daoud and others added 5 commits October 7, 2026 21:04
Plans and agent working notes are not part of the repository; what a
reviewer needs is in the PR body, the commits and the linked issues.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SourceInfo.SelfURI's doc comment was 144 words and assertSelfURI's 109,
so TestDocComments_StayUnderTheCap failed the gate. Both keep their
reasoning in fewer words.
The fixture predates the idSpaces declaration main introduced with IR
0.7.0. Only irVersion and idSpaces change.
SourceInfo gained selfURI. ir-design §2.1 moves the version on any change
to a Document's JSON shape, and a decoder pinned to 0.7.0 refuses the new
member, so a document carrying it is unreadable there.

BREAKING CHANGE: documents are stamped irVersion 0.8.0; consumers built
against 0.7.0 refuse them.
@fuad-daoud fuad-daoud changed the title fix(compilers/openapi): record $self on the document's source fix(compilers/openapi)!: record $self on the document's source Oct 11, 2026
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