You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[finding] The MOUNT half of every RestServerConfig switch is unpinned — the tests assert what a switch normalizes to, never that the route leaves the table #15544
Filed unassigned and unlabelled for triage, from the capability-coverage work on #14961 (PR #15541). Not that PR's change and not addressed there.
Measured on origin/main6f944589
Nine live RestServerConfig switches gate route mounts:
crud.operations.{create,read,update,delete,list} in packages/rest/src/rest-server.ts#registerCrudEndpoints
batch.enableBatchEndpoint and batch.operations.{createMany,updateMany,deleteMany} in #registerBatchEndpoints
metadata.endpoints.{types,items,item} in #registerMetadataEndpointsInner
What the test suite pins:
packages/rest/src/rest-sub-config-parse-not-cast.test.ts §D asserts what each switch normalizes to — normalized({ crud: { operations: { list: false } } }).crud.operations equals the expected object, and so on. §E asserts the retired keys refuse.
packages/rest/src/rest-batch-size-cap.test.ts asserts the effect of batch.maxBatchSize on all five bulk doors.
What nothing pins: that a false switch removes its route from the mounted table. No test constructs a server with a switch off and asserts the absence in RestServer#getRoutes() — even though that method is public, is already used by rest-batch-size-cap.test.ts to find routes, and makes the assertion a two-line one.
Why it is worth a decision
The unpinned direction is the dangerous one. A refactor that stops reading a switch at the registrar — or reads the wrong one — leaves every existing test green: the normalized config is still correct, the cap still works, and the route is simply still mounted. That is precisely the declared-not-enforced state ADR-0049 exists to catch, and here the switch would be config an operator sets while nothing honours it.
Two shapes worth pinning in the same test, both read out of the registrars and both easy to break silently:
crud.operations.list gates two mounts (GET {dataPrefix}/:object and POST {dataPrefix}/:object/query); the query door has no switch of its own.
The four batch gates are each switch AND protocol member (operations.createMany && this.protocol.createManyData), so a mount can be absent for two different reasons.
Options (not decided here)
Add the mount-table pins to rest-sub-config-parse-not-cast.test.ts (or a sibling): per switch, construct, registerRoutes(), diff getRoutes() against the all-true baseline, assert the difference is exactly the expected paths.
docs/qa/platform-checklist/FOLLOW-UPS.md §10b E3, and in the knownGaps of the three new config items, which say the harness is the only observation until such a pin exists.
Filed unassigned and unlabelled for triage, from the capability-coverage work on #14961 (PR #15541). Not that PR's change and not addressed there.
Measured on
origin/main6f944589Nine live
RestServerConfigswitches gate route mounts:crud.operations.{create,read,update,delete,list}inpackages/rest/src/rest-server.ts#registerCrudEndpointsbatch.enableBatchEndpointandbatch.operations.{createMany,updateMany,deleteMany}in#registerBatchEndpointsmetadata.endpoints.{types,items,item}in#registerMetadataEndpointsInnerWhat the test suite pins:
packages/rest/src/rest-sub-config-parse-not-cast.test.ts§D asserts what each switch normalizes to —normalized({ crud: { operations: { list: false } } }).crud.operationsequals the expected object, and so on. §E asserts the retired keys refuse.packages/rest/src/rest-batch-size-cap.test.tsasserts the effect ofbatch.maxBatchSizeon all five bulk doors.What nothing pins: that a
falseswitch removes its route from the mounted table. No test constructs a server with a switch off and asserts the absence inRestServer#getRoutes()— even though that method is public, is already used byrest-batch-size-cap.test.tsto find routes, and makes the assertion a two-line one.Why it is worth a decision
The unpinned direction is the dangerous one. A refactor that stops reading a switch at the registrar — or reads the wrong one — leaves every existing test green: the normalized config is still correct, the cap still works, and the route is simply still mounted. That is precisely the declared-not-enforced state ADR-0049 exists to catch, and here the switch would be config an operator sets while nothing honours it.
Two shapes worth pinning in the same test, both read out of the registrars and both easy to break silently:
crud.operations.listgates two mounts (GET {dataPrefix}/:objectandPOST {dataPrefix}/:object/query); the query door has no switch of its own.switch AND protocol member(operations.createMany && this.protocol.createManyData), so a mount can be absent for two different reasons.Options (not decided here)
rest-sub-config-parse-not-cast.test.ts(or a sibling): per switch, construct,registerRoutes(), diffgetRoutes()against the all-true baseline, assert the difference is exactly the expected paths.api-backend.rest-*-config-contractitems each carry a mount clause, so a checklist run observes it.check:platform-checklisthas no reporting channel — it is deliberately not CI-wired, so its red is visible to nobody until a runner reads it #11730), so this route means a break is caught at the next run, not on the PR that causes it.Where it is already captured
docs/qa/platform-checklist/FOLLOW-UPS.md§10b E3, and in theknownGapsof the three new config items, which say the harness is the only observation until such a pin exists.Generated by Claude Code