Phase 2b of epic #343: flip ref from optional to required on all five producing schemas (AlbumSearchResult, BinLibraryDetails, Rotation, LibrarySearchItem, AlbumInfoResponse), then publish. Only after the two BS emit tickets (Phase 3a + 3b) are deployed everywhere — a required property the server doesn't emit yet fails every consumer decode.
What a green check:breaking does NOT tell you
Adding a required response property is not oasdiff-flagged (recorded in the CatalogExportRow description in api.yaml), so a green check is not evidence of safety — verify consumers by hand. With /proxy/library/search declared in Phase 2 this reasoning covers LibrarySearchItem too; before that declaration the schema was an orphan oasdiff never diffed at all.
LibrarySearchItem's inclusion is safe because the LML proxy now mints ref on every proxied row (Phase 3b, per the epic's decision record). Had the pass-through been left alone, a required ref here would have been a false contract that check:breaking stays green on.
The flip breaks eight literals across two trees — enumerate, don't discover
In the published test-utils (compile error in the package itself and in every downstream repo importing @wxyc/shared/test-utils on its next bump — both files ship in dist and are covered by npm run lint):
In tests/ — which Phase 2's tsconfig.e2e.json widening is precisely what armed — six generated-types.test.ts literals: :517, :530, :1015, :1037 (AlbumSearchResult) and :542, :570 (LibrarySearchItem).
Verified non-exposure, scoped to src/test-utils/ only: testRotation (fixtures.ts:237) is typed RotationEntry, not the legacy Rotation schema this epic edits, and no BinLibraryDetails or LibrarySearchItem fixture exists there.
Fixture ref values must be well-formed (lib:<id> matching the fixture's own id) — a fixture whose ref disagrees with its id masks exactly the divergence this epic eliminates.
Acceptance criteria
Related
Phase 2b of epic #343: flip
reffrom optional to required on all five producing schemas (AlbumSearchResult,BinLibraryDetails,Rotation,LibrarySearchItem,AlbumInfoResponse), then publish. Only after the two BS emit tickets (Phase 3a + 3b) are deployed everywhere — a required property the server doesn't emit yet fails every consumer decode.What a green
check:breakingdoes NOT tell youAdding a required response property is not oasdiff-flagged (recorded in the
CatalogExportRowdescription inapi.yaml), so a green check is not evidence of safety — verify consumers by hand. With/proxy/library/searchdeclared in Phase 2 this reasoning coversLibrarySearchItemtoo; before that declaration the schema was an orphan oasdiff never diffed at all.LibrarySearchItem's inclusion is safe because the LML proxy now mintsrefon every proxied row (Phase 3b, per the epic's decision record). Had the pass-through been left alone, a requiredrefhere would have been a false contract thatcheck:breakingstays green on.The flip breaks eight literals across two trees — enumerate, don't discover
In the published test-utils (compile error in the package itself and in every downstream repo importing
@wxyc/shared/test-utilson its next bump — both files ship indistand are covered bynpm run lint):src/test-utils/fixtures.ts:92—testAlbumSearchResult: AlbumSearchResult, norefsrc/test-utils/factories.ts:93—createTestAlbumSearchResultspreads itIn
tests/— which Phase 2'stsconfig.e2e.jsonwidening is precisely what armed — sixgenerated-types.test.tsliterals::517,:530,:1015,:1037(AlbumSearchResult) and:542,:570(LibrarySearchItem).Verified non-exposure, scoped to
src/test-utils/only:testRotation(fixtures.ts:237) is typedRotationEntry, not the legacyRotationschema this epic edits, and noBinLibraryDetailsorLibrarySearchItemfixture exists there.Fixture
refvalues must be well-formed (lib:<id>matching the fixture's own id) — a fixture whoserefdisagrees with itsidmasks exactly the divergence this epic eliminates.Acceptance criteria
refin therequiredset of all five schemas;info.version+ its pin (tests/api-spec.test.ts:102) bumped.npm run lintandlint:e2egreen.Related
refbecomes the only library row identity #343 · Blockers: Phase 3a + Phase 3b (deployed, not merely merged)