Repository navigation
refactor(rest): move registerDiscoveryEndpoints and registerOpenApiEndpoints into discovery-routes.ts (#23050 slice 7) - #23763
Conversation
…discovery-routes.ts Move only. The bodies of RestServer#registerDiscoveryEndpoints and RestServer#registerOpenApiEndpoints move, re-indented one level, to one new module; the class keeps both private methods as a host literal plus .call. routeManager goes by value, config as a getter. The one changed token is the OpenAPI body's call of the private static overlayDocumentationInfo, now reached through the host. The registrar list gains the module (7 -> 8). Readers are re-pointed in the following commit. Claude-Session: https://claude.ai/code/session_01Q9PZ5Pzqcus4woVvTZwWNU Co-authored-by: Claude <noreply@anthropic.com>
…API lines Each reader keeps its sum: the registrar-list readers pin length 8, the execctx census counts the discovery registrar as one that reads no resolveExecCtx, the dogfood census row gains its module control, the route-envelope gate declares the module at 0 / 0 (and its slice-6 history entry says four arms, not two), a new ADR anchor restores the decision-letter reading, and the checklist and prose pointers name the module. Claude-Session: https://claude.ai/code/session_01Q9PZ5Pzqcus4woVvTZwWNU Co-authored-by: Claude <noreply@anthropic.com>
…-discovery-endpoints
📓 Docs Drift CheckThis PR changes 1 package(s): 13 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 18 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 6f0e0502015d1a54a2891ce52fad725e1bae17cc && git checkout 6f0e0502015d1a54a2891ce52fad725e1bae17cc
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 29c7157af4fed4738b3da14bbfb008496cbd1f6a 9ddffc0baad2ca64051703b98f8fc8032d05ebe5 && git checkout -B drift-repro 29c7157af4fed4738b3da14bbfb008496cbd1f6a && git merge --no-ff 9ddffc0baad2ca64051703b98f8fc8032d05ebe5
node scripts/docs-audit/affected-docs.mjs --json 29c7157af4fed4738b3da14bbfb008496cbd1f6a
|
Contract reviewServed-tier: Face: the declaration face. This is a move-only refactor of
The 17-file list holds no published schema and no governed path. Inputs:
The reviewer is an isolated agent working read-only. Every count below was read off the git objects of the merge-base and the head with these tools:
Nothing was built, tested or re-run. The merge-base's ① Derived judgmentsNo accept set and no public surface changes. Each change the diff makes is judged below.
② Semver level
③ Boundary flagsEvery dev flag is answered or escalated. The flags come from the PR body and from the report's (
Implemented-by: VERDICT: PASS Generated by Claude Code |
席位核对✅ ACCEPT: PR #23763 at
Checklist, read against GitHub and
Cross-lane, declared before review:
Accepted deviations:
The review's non-blocking notes: the reworded Carried, not edited here:
Landing: Generated by Claude Code |
Part of #23050
Clause-②: no
Slice 7 of the
rest-server.tssplit, by slice 1's pattern (landed note6136102437, steps 1–6), slice 2's getter refinement (6189011700) and slices 3–6's shape (PR #23670, PR #23705 and PR #23729's two registrars in one module, PR #23719): the bodies ofRestServer#registerDiscoveryEndpoints(GET {basePath}andGET {basePath}/discovery) andRestServer#registerOpenApiEndpoints(GET {basePath}/openapi.jsonand itsGET {basePath}/docsviewer) move to ONE new module,packages/rest/src/discovery-routes.ts. Routes, the ordered registrations, the publisheddist/*.d.tsand both bundles' export lists are byte-identical, and every reader whose reading included a moved line now reads it where it is, with its sum unchanged.One deviation, named up front: one token of the OpenAPI body is not byte-identical. The body called the class's PRIVATE STATIC
overlayDocumentationInfoasRestServer.overlayDocumentationInfo(…), a spelling that does not compile outside the class. It now reaches the static through the host, asthis.overlayDocumentationInfo(…). So theopenapi.jsonhandler's digest differs from base, by that receiver alone (measured below). The seat is asked to confirm the shape (see the end of this body).rest-server.tsgoes from 10,636 to 10,090 lines (base3b46855fb9). The card stays open for the later slices.The pattern, applied
Members the moved bodies read, from an AST walk of each method (TypeScript compiler API, symbol-resolved, base
3b46855fb9):registerDiscoveryEndpoints(JSDoc:4910, method:4913-:5236, body:4914-:5235) andregisterOpenApiEndpoints(JSDoc:5277, method:5323-:5591, body:5324-:5590).config:2011, private, notreadonlyrouteManagerregistercalls:2012, privateresolveProtocol:2390, privateprobeMcpServeable:4886, privategetDirectMountRouteBases:10534getMountedEmailRouteBase:10596resolveExecCtx:2858, privateenforceAuth:2458, privateloadOpenApiSpec:5599, privategetRoutes:10630resolveEndpointMatchAuthority:2193, privatenotifyMissingEndpointAuthority:2269, privateoverlayDocumentationInfo, read asRestServer.overlayDocumentationInfo:5262, private staticNeither body has a bare
this, an element access onthis, or athis-rebindingfunction. Their module-level reads:rest-server.ts(AST count outside both methods):handleRouteError(19) andlogError(7). They stay there; the module imports the same names from the same modules.isMcpServerEnabled(@objectstack/types),enrichOpenApiWithEndpoints(./openapi-endpoints.js),buildBuiltinPaths(./openapi-builtin-paths.js),selectServedEndpoints(./served-endpoints.js) andsendThrownError(./error-response.js). They moved with the bodies, as slices 3, 5 and 6 moved theirs, and each left a pointer comment. Leaving them would failnoUnusedLocals.rest-server.ts:DISCOVERY_ROUTE_KEY_TO_SERVICE_SLOTS(already exported) and the typeRestProtocol(already exported). The module imports both from./rest-server.js; noexportwas added anywhere. The table is aconst, read only inside the discovery handler at request time, so the two modules importing each other cannot see it uninitialised (the bundle is one scope).Host shape (slice 1's shape B, twice, as slices 4 and 6):
DiscoveryRouteHost(6 members) andOpenApiRouteHost(10 members) list exactly the members each body reads, typedRestServer['m']; the static is typed(typeof RestServer)['overlayDocumentationInfo']. The class keeps both private methods with their names, docblocks and positions. Each body is now a host literal plus.call(host, basePath). Methods go as late-bound closures,(...a) => this.m(...a), and the static as(...a) => RestServer.overlayDocumentationInfo(...a). The call sites inregisterRoutes'registerForBase(:4781-:4786at base, underenableDiscovery/enableOpenApi) are unchanged.Fields, checked one by one:
routeManagerregistercalls, top-level statements of the two bodies):5721/:5725at base) wrapsregisterMetadataEndpointsInner, not these registrarsconfig:2156), but notreadonlyThe getter is measured, not argued. A one-off vitest file (copied in, run, deleted) boots a source
RestServer, drives the door, assigns a NEWconfigobject on the instance AFTERregisterRoutes()(a new object, never a mutation, which a by-value hand-over would see through the shared reference), and drives it again:a9073d822b):GET /api/v1/discoveryanswerscapabilities.transactionalBatch.enabledtrue, thenfalseafterenableBatch: false.GET /api/v1/openapi.jsonanswersinfo.title"ObjectStack REST API"(the artifact's), then"Late Title"afterdocumentation: { title: 'Late Title' }. A spy set onRestServer.overlayDocumentationInfoafterregisterRoutes()is called once per serve, with the authored documentation, so the static is reached through the host at request time.Tests 3 passed (3).scripts/ablation-replace.mjs, each host literal's getter in turn replaced byconfig: this.config,with a multi-line anchor naming its literal. Each landed (anchor 1 → 0, replacement 0 → 1, blob8f098de155→dcd5b2791e/4e218d1382). The ablated door freezes at registration: discovery readstruethentrue; OpenAPI reads the artifact's title then the artifact's title again. Each run:Tests 1 failed | 2 passed (3). Restored by the tool and a trap: blob8f098de155equalsHEAD,git diff HEADempty, the one-off file deleted. Source path (relative import), so nodistleg applies.Mechanism hypotheses from the dispatch, measured:
this.configandresolveProtocol, as hypothesised. The discovery body does not readthis.protocol: the field appears in it only inside comments ([#9292], which says the handler stopped reading it); the AST walk finds nothis.protocolaccess, and the protocol is reached throughresolveProtocol. Soconfigis the one request-time field, and it goes as a getter by measurement (above). The walk also found the private staticoverlayDocumentationInfo, which the hypothesis did not list (next section).basePath,realBase,unscopedBase, the/docspage'sreqPath/apiBase) moved unedited; the scoped-optional and scoped-required route dumps below are identical, and every discovery and/docshandler's source is byte-identical.ADR-NNNN Dkcitations (ADR-0057 D10, ADR-0076 D12 ×2 in discovery; ADR-0056 D2 and ADR-0138 D2 in OpenAPI). They left the anchoredrest-server.ts(94 → 89), socheck-adr-anchorsread 1761 decision-letter citations at base and 1756 at the move-only commit234537d1ad, green both times: the silent narrowing the card forbids. A new anchor (below) restores 1761.check-affected-docsdiscovers the module by its*-routes.tsname (route sources 25 → 26) with no edit;check-route-envelope's tables and the platform checklist needed one each.The one token that changed, and why no unedited shape exists
The OpenAPI body's step 5 overlays the publisher's identity through the class's PRIVATE STATIC: base
rest-server.ts:5525readenriched.info = RestServer.overlayDocumentationInfo(enriched.info, this.config.api.documentation);. Outside the class that spelling does not compile, measured with two throwaway files added topackages/rest/srcand removed:tsc --noEmitexits 1 withTS2341: Property 'overlayDocumentationInfo' is private and only accessible within class 'RestServer'(value import), andTS1361plusTS2341(the type-only import the module uses). The alternatives each break something the slice must keep:.d.ts(it is listed there asprivate static overlayDocumentationInfo;), and the dispatch keeps every class method in place this slice;RestServerthat is not the class would keep the text byte-identical, and give every later reader of the module an identifier that lies about what it is.So the static is reached the way the dispatch's ruling reaches every class member these bodies use: through the host, as a late-bound closure.
discovery-routes.ts:655readsenriched.info = this.overlayDocumentationInfo(enriched.info, this.config.api.documentation);. The member is pure (its only inputs are its two arguments, and it reads nothis), so the receiver is the whole difference, and the module header records it.The registrar list
packages/rest/src/rest-server-registrar-files.tsgainsdiscovery-routes.tswith a[#23050 slice 7]comment (length 7 → 8). Every reader that pins its length re-reads its number, and every sum is unchanged:rest-server-query-number-census.test.tsrest-server-canonical-query-ast.test.tsquery:slotsdiscovery-routes.ts: 0, length 7 → 8meta-draft-read-door-census.test.tsrest-server-docblock-position.test.tsdiscovery-routes.ts: 5(header, two host interfaces, two functions; neither body held a TSDoc block);rest-server.tskeeps 164 blocks, floor 100; length 7 → 8execctx-consumer-census.test.tsrest-server.tsstays 57). Forwarders 9 = (8 − 1) +EXTRA_MOVED_REGISTRARS3 −MOVED_REGISTRARS_READING_NO_EXECCTX1; see the note belowui-view-route-identity.measurement.test.ts/ui-view-route-tenancy.measurement.test.tsthis.enforceAuth(56,this.resolveExecCtx(71 over the list (55 / 70 before, +1 each for the OpenAPI literal's forwarder); ownership guard 1authz-conformance.test.ts(realtime tripwires)authz-probe-blind-spot.census.ts,rest-server.tsrowthis.routeManager.register(63 = 23 + 9 + 5 + 7 + 8 + 1 + 6 + 4;private register*Endpoints(16discovery-routes.ts: this.routeManager.register(4;registrar list length8;enforceAuth92 → 96 re-anchored (the OpenAPI pair's two call sites moved and are counted in both readings; the four new occurrences are the seam once; no call site added);populationRulenames the new moduleThe execctx forwarder control, measured rather than inherited. The dispatch expected this census to count two registrars in one module, as slices 4 and 6 did. It does, and it also had to learn that the two registrars here do not both forward
resolveExecCtx: the discovery body resolves no caller (the document is served to anyone), so its host literal names noresolveExecCtxmember. The control pins forwarders as one per moved registrar whose body reads the seam:EXTRA_MOVED_REGISTRARSgainsdiscovery-routes.ts: 1(two registrars in one module, as slices 4 and 6), and a new map,MOVED_REGISTRARS_READING_NO_EXECCTX, holdsdiscovery-routes.ts: 1, pinned at exactly 1. The count stays exact: a respelt forwarder, or a discovery body that starts reading the seam, reds it.Each number above was also counted statically on the tree (
grep -oFper file).Proof of move-only
.d.ts:packages/rest/dist/index.d.tsandindex.d.ctsbuilt at base3b46855fb9(this worktree, before any edit), ata9073d822band at the merge head9ddffc0baaare byte-identical: sha2567489de84bc6feccb7cb1f28bcbe4a97775324959c61c9bfc35e8a8c45a6f3bc9for all six files,cmpsilent. The head bundles carry a head-only marker (readConfig: 4 hits in each ofindex.jsandindex.cjs, 0 at base), so the declaration was rebuilt from the moved source, not replayed.DiscoveryRouteHost,OpenApiRouteHostanddiscovery-routesappear 0 times in the.d.ts;src/index.tsis untouched.b3246be6a171…on all six). None of the two functions, the two host types orDISCOVERY_ROUTE_KEY_TO_SERVICE_SLOTSis among them.RestServeron a recording mock server, with a protocol that answers every member, dumped under seven configs: default; scoped-optional; scoped-required; every provider set;enableDiscovery: false;enableOpenApi: false; and both off under scoped-optional. Each dump holdsgetRoutes()(functions as arity), the ordered server registration calls, and a whitespace-free sha256 of every handler's source.getRoutes()and the ordered calls: 14 of 14 byte-identical, base vs head and base vs merge head. default: routes6931d1a5d182…, callsccb3bd12f10b…(75 routes, 4 of them these doors); scoped-optional275c72f46c30…/339e8c3abc05…(150, 8); scoped-requireda2aa8183e213…/734f33133150…(75, 4); every-provider-set equals default; discovery-off51f8ed92bb85…/50d8d124f3b8…(73, 2); openapi-off07cd86e4661a…/cb8c93c76044…(73, 2); both-off4525bbdb0f79…/e7108e133e9a…(142, 0). A second base run was identical to the first.307d066c0008…, both-off2e2b275dc162…). In the other five they differ in exactly theopenapi.jsonhandler of each mounted base (6 handlers in all) and in nothing else. With the one receiver mapped back (this.overlayDocumentationInfo(→RestServer.overlayDocumentationInfo(), all 6 sources equal base byte for byte; the 18 discovery and/docshandler sources equal base with no mapping.docs viewer error:→!, throughablation-replace.mjs; anchor 1 → 0, blob8bf688c0d6→91786677f8). Routes and calls were unchanged in all seven configs, and the handler list differed in exactlyGET {base}/docsfor each mounted base, nothing in the two configs without it. Restored, blob8bf688c0d6equalsHEAD.rest-server.tslines 4914-5235 and 5324-5590, one 4-space indent removed, againstdiscovery-routes.tslines 123-444 and 454-720 (322 + 267 lines). The discoverydiffexits 0. The OpenAPIdiffshows exactly one line, the receiver above. The viewer page's HTML is a template literal whose continuation lines (base 5564-5574) sit at column 0: they are runtime text, and they moved byte for byte, unindented. Every other odd-backtick line in the ranges is a comment, so no other template literal spans a cut.git diff --color-moved=plain --color-moved-ws=allow-indentation-changebase → move commit over the two files: 589 deleted and 601 added lines detected as moved.rest-server.tsis +46 / −593 there: the two stub bodies (host literal plus.call), the module's import and its comment, and three import-pointer comments.Readers re-pointed (sums unchanged, no gate loosened)
scripts/check-route-envelope.mjs(a gate's target paths,domain:spec):discovery-routes.tsis discovered by the*-routes.tsconvention and declareddialectOnlywith ratchet [tracking] Envelope-position convergence line for packages/rest's flat dialect — the live ratchet owner #9559, as the six earlier modules are, at its measuredstringError 0,siblingCode 0(the gate compares both counts exactly in both directions). The discovery handler's one refusal path is the sharedhandleRouteError, and the OpenAPI document's one hand-built refusal is the nested{ error: { code, message } }. Sorest-server.tsstays at 17 / 17, and the sums 17 + 13 + 8 + 1 + 0 + 0 + 0 + 0 = 39 and 17 + 15 + 8 + 9 + 4 + 1 + 0 + 0 = 54 are unchanged. Output differs from base only in the new row (17 → 18 modules, 8 → 9 ratcheted).--self-testgreen. Carried from slice 6 into the same comment block: itssiblingCodeentry said "the two arms [finding]registerSecurityEndpointsanswers THREE different error-envelope shapes on the same three routes (ADR-0112) #7981 and [finding] the two registrars ADJACENT to #7981 still answer the retired flat / bare-string error dialects (ADR-0112) #8073 converted … 77 → 73"; it is four arms, and the entry now says "four".scripts/adr-anchors/packages__rest__src__discovery-routes.ts.json(new, ADR-0076 + ADR-0056 + ADR-0138;domain:devx):check-adr-anchorsdecision-letter citations on the anchored surface 1761 (base) → 1756 (move) → 1761 (head); anchored files 68 → 69. Every listed id appears in the module, and every cited letter is a decision of its record (the gate's own check, green). The invariant writes "its D12", never the citation form, so it adds no citation of its own (the gate's regex: 0). ADR-0057 is cited in the module but not listed: its number is shared by two records, and listing it would add a fourth entry to the gate's ambiguous-number note for nothing the letter check does not already read.docs/qa/platform-checklist/areas/api-backend.json(domain:devx): thecrud_endpointsandmetadata_endpointsitems' source lists namedrest-server.tsfor "registerDiscoveryEndpoints—discovery.routes.data/.metadatabuilt from" the prefix. Each now points atpackages/rest/src/discovery-routes.ts#registerDiscoveryEndpoints, slice 2's+form.check:platform-checklist: symbol anchors 733/743 → 735/745 resolved (the two new anchors resolve; unresolved 10 → 10), cited sources 346 → 347..d.ts: theDISCOVERY_ROUTE_KEY_TO_SERVICE_SLOTSdocblock (rest-server.ts) said "the discovery handler below";openapi-builtin-paths.ts' module docblock andbuildBuiltinPaths' docblock saidrest-server.tsinstalls and calls it. Each now namesdiscovery-routes.ts. The dogfood matrix rowanonymous-deny-api-descriptionnamedrest/rest-server.ts registerOpenApiEndpointsas the enforcement site of the two handlers; it namesrest/discovery-routes.ts(no test reads that row's path).Red before the re-points, each measured with the move in place (
234537d1ad): the sixlocallist readers readTest Files 6 failed (6),Tests 7 failed | 105 passed (112)(five length pins, plus the docblock pin's length pin and its new module with no floor).rest-server-canonical-query-ast.test.ts(repo) readTests 2 failed | 57 passed | 8 skipped (67). The dogfood pair readTests 2 failed | 106 passed (108)(list length; the census row'sregistrar list lengthcontrol).tsc --noEmitwas clean, butcheck:test-typecheckfound 2 type errors, the two typed floor tables without the new module.check:route-envelopereaddiscovery-routes.ts NOT DECLARED(MODULES and EXPRESS_RESPONSE_MODULES).check-adr-anchorswas green at 1756.Readers examined and not re-pointed
packages/specreaders whose reading includes a moved line (stopped at, per the dispatch, not edited):packages/spec/liveness/rest_api.jsoncitesrest-server.ts#registerDiscoveryEndpointsseven times, and five of those evidence strings quote code that now lives indiscovery-routes.ts(enabled: runtimeSupportsTx && this.config.api.enableBatch !== false,enabled: !!caps.search?.enabled && this.config.api.enableSearch,scoping.enabled,scoping.resolution, and the advertised switches); its ten#overlayDocumentationInforows say the static is "called by theopenapi.jsonhandler registerOpenApiEndpoints builds".metadata_endpoints.jsonandcrud_endpoints.jsoneach cite#registerDiscoveryEndpointsonce (routes.metadata,routes.data). Every anchor still resolves (the private methods stay), andcheck:livenessis green. They go to the seat, to carry with the CRUD slice's pointers.docs/adr/0138-…citesrest-server.ts#RestServer.registerDiscoveryEndpointsand#RestServer.registerOpenApiEndpoints. Both still resolve (the private methods stay). It is a governed surface, and is not edited here.content/docs/releases/implementation-status.mdxnamesrest-server.ts — registerDiscoveryEndpoints: release-owned, not edited in a code PR, and the name still resolves.rest-server.ts'parseDeclaredApiConfigdocblock, in itsprojectResolutionhistory (about:4578), says "the discovery handler below copies the value intodiscovery.scoping.resolution". That docblock ships in the published.d.ts, so editing it would break the byte-identity this slice must keep. Not edited.packages/core/src/qa/http-adapter.ts(and its test),packages/runtime/src/dispatcher-plugin.ts(about:1098),packages/metadata-protocol/src/discovery-realtime-channel.pin.test.ts, thepackages/restdiscovery and OpenAPI tests,showcase-anonymous-deny-surfaces.dogfood.test.ts, the dogfood census row's dated[#22430]entry, and the checklist's clause text andFOLLOW-UPS.md.rest-server.ts:NNNNline citation in the tree falls inside the moved ranges.REST_ROUTE_LEDGERnames routes, not files.3b46855fb9vs head, from the same scan: see the gates section.Acceptance notes
[#22430]comment the OpenAPI body carries ("the same body the/dataand/metaroutes answer") and the[#9292]comment in the discovery body ("~30 sibling handlers in this file") moved verbatim; indiscovery-routes.ts"this file" is the module. A move-only slice may not edit the bodies.openapi-builtin-paths.tssays the handler handsbuildBuiltinPaths"routeManager.getAll()"; it has handed itgetRoutes()(RouteManager's table plus the direct mounts) since rest 的 9 条 direct-mount 路由对RestServer不可枚举 —— 因此进不了/openapi.json,也进不了任何运行时自省 #5822. Pre-existing, not part of this move, left as it was.docs/adr/0076-…(status line and D11) anddocs/adr/0111-…(Consumers line) are still carried to the maintainer by the seat; this slice adds nothing to them.Gates and tests
Measured at this branch: base
3b46855fb9, the move234537d1ad, the re-pointsa9073d822b, and one merge oforigin/main2906cd8d2e(9ddffc0baa: three commits incli,driver-sqlandmetadata-protocol/objectql, no file in this diff). All builds and tests went throughos-verify-lock. Every exit code was captured to a file before any pipe.9ddffc0baa:pnpm install --frozen-lockfileexit 0; the@objectstack/restand@objectstack/verifyclosures built, exit 0; thenpnpm turbo run build --concurrency=2, the whole workspace, exit 0 (76 tasks, 74 cached), after which the@objectstack/rest.d.ts/.d.ctsstill equal base.pnpm --filter @objectstack/rest typecheck: exit 0 (tsc --noEmit, thencheck:test-typecheck: 0 file(s) / 0 error(s)), ata9073d822band at9ddffc0baa.pnpm --filter @objectstack/rest exec vitest run --project local --maxWorkers=2: Test Files 285 passed (285), Tests 5876 passed / 326 skipped (6202), at both heads.pnpm --filter @objectstack/rest exec vitest run --project repo --maxWorkers=2: Test Files 5 passed (5), Tests 238 passed / 8 skipped (246), at both heads.pnpm --filter @objectstack/dogfood exec vitest run test/authz-probe-blind-spot.test.ts test/authz-conformance.test.ts: Test Files 2 passed (2), Tests 108 passed (108), at both heads.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths, at the final head9ddffc0baa(stderr names that commit; the--repoassertion holds; 17 paths against merge base2906cd8d2e): 81 commands, all run at9ddffc0baa. 80 exited 0 on the first pass;pnpm check:dual-build-cjs-loadsexited 3 (PREREQUISITE NOT MET: 19 packages had nodist), and exited 0 after the whole-workspace build above.--ran:Run reconciliation — 81 derived, 81 run, 0 NOT-MEASURED, 0 UNRUN.Among them:pnpm check:route-envelope,pnpm check:adr-anchors,pnpm check:platform-checklist,pnpm --filter @objectstack/spec run check:liveness,pnpm check:durability-log-level,pnpm check:dispatcher-error-vocabulary,pnpm check:dts-closure,pnpm check:published-filesandpnpm check:pm-dispatch-gates.3b46855fb9vs the merge head, diffed: identical forcheck-single-authz-resolver,check-system-context-census,check-rest-log-declared,check:rest-log-spy-declared,check:test-source-alias,check-filter-alias-parityandcheck:liveness. Differing only by this diff's new file:check-meta-type-normalized(35 → 36 files),check-undeclared-dep-imports(+1 file and +1 specifier, read at the move commit;mainadds one more file),check-affected-docs(route sources 25 → 26),check-route-envelope(the new row),check-scripts-symbol-anchors(+4 file-level anchors, the gate's new comments) andcheck:platform-checklist(735/745, above).check-adr-anchorsreads 1764 at the merge head: 1761 from this diff (above) plus 3 thatmain'smetadata-protocol/src/protocol.tsadded (278 → 281 in that anchored file). The rest moved withmain's three commits (file counts incheck:nul-bytes,check:doc-authoring,check:cross-package-test-inputs,check:dispatcher-error-vocabulary,check:error-status-conformance;check-durability-degradation-log-level78 → 80 read seams).eslint --no-inline-config --format jsonoverpackages/rest, the three dogfood files,scripts/check-route-envelope.mjs, the new anchor JSON and the checklist JSON: 333 files, 0 errors, 0 lint warnings. Its two warnings areFile ignored because no matching configuration was supplied, for the two JSON files, whicheslint .never reads. All 17 changed files are in the result set, the 15 code files at 0 / 0. The published.d.tsis byte-identical, so no consumer outsidepackages/restcan lint differently. Repo-widepnpm lintis CI's.check:dev-prereqsandcheck:skill-frame-freshness(local-only) were not run: nopackages/specbuild input and no four-axis frame file is touched..d.ts, export lists and routes above).skip-changesetis the seat's to apply on its own check.Cross-lane files in this diff:
scripts/check-route-envelope.mjs(domain:spec, a gate's target paths),scripts/adr-anchors/packages__rest__src__discovery-routes.ts.json(a new entry incheck-adr-anchors' registry,domain:devx),docs/qa/platform-checklist/areas/api-backend.json(domain:devx), and the dogfood files (packages/qa/dogfood/test/authz-conformance.test.ts,authz-conformance.matrix.ts,authz-probe-blind-spot.census.ts).For the seat: one question
The dispatch rules the bodies move unedited with every handler digest identical, and every class member the bodies call reached through the host. The OpenAPI body's call of the private static cannot satisfy both: it is reached through the host here, and that changes one token of one handler. Options: (A) accept the receiver change as this slice's shape (recommended: the static stays private and in place, the
.d.tsis untouched, and the dependency is declared onOpenApiRouteHostlike every other member); (B) a module-level binding namedRestServerthat forwards the static, which keeps the text byte-identical but names something that is not the class; (C) a later slice movesoverlayDocumentationInfoout of the class, which changes the.d.tsby one private line and needs its own ruling.Generated by Claude Code