Repository navigation
refactor(rest): move the /meta per-item write routes into meta-item-write-routes.ts (#23050 slice 13c) - #24257
Conversation
…outes.ts
Sub-slice 13c, the move commit. The fifth /meta group of
RestServer#registerMetadataEndpointsInner, the two registerPerItemRoute
statements registering PUT and DELETE {metaPath}/:type/:name (the item
save and the reset), moves re-indented to the new module as
registerMetaItemWriteRoutes(this: MetaItemWriteRouteHost, scope:
MetaRouteScope). The inner method builds the itemWriteHost literal at the
statements' old position and passes the one existing scope, through which
the inner head's own per-item registrar reaches the module. The host
carries no routeManager: the module registers only through that closure,
which reads the server's route manager at call time.
The one private-static receiver, RestServer.metaSaveVerdict, becomes
this.metaSaveVerdict through the host. The four imports only the moved
body read (the save's closed set, its request mapping and the two declared
request types) leave rest-server.ts. The readers follow in later commits.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QyoWKK9RwUNxBxmevy9Neb
…he /meta subset Sub-slice 13c, the list commit. REST_SERVER_REGISTRAR_FILES grows 15 to 16 and its named /meta subset REST_SERVER_META_ROUTE_FILES 2 to 3, with the inner method's module calls (3) beside it. The list's readers are re-pointed in the next commit, so this one measures them red at their base text. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QyoWKK9RwUNxBxmevy9Neb
…able and the row-50 anchor at meta-item-write-routes.ts Sub-slice 13c, the readers commit. Every reader of the registrar list follows it to 16 files with its sum unchanged: the execctx census (62 sites, 141 mentions, sixteen forwarders), the draft census (8, the reset's state=draft now in the module), the query-number census (9), the canonical-query-ast floors (4), the docblock floors (62 over fifteen modules), the ui-view identity and tenancy measurements (60 / 78) and the dogfood tripwire (0 over sixteen). The dogfood blind-spot census stays 70 / 19 / 51 by 13a's rule. Its per-module control counts the helper's call spelling for a module with no direct site (meta-item-write-routes.ts: 2), and the whole-population registerPerItemRoute( control is re-anchored over the population rule's own haystack, where it stays 8. check-route-envelope declares the module at 0 / 0 (rest-server.ts keeps 7 / 3). system-context.mdx row 50 gains the module's anchor, since the reset's isSystem read moved with it. A new ADR anchor restores check-adr-anchors' decision-letter reading, which the move had narrowed from 1783 to 1775 with the gate green. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QyoWKK9RwUNxBxmevy9Neb
Sub-slice 13c. The published index.js / index.cjs bytes change (the new module is bundled); the declarations and the export list do not. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QyoWKK9RwUNxBxmevy9Neb
Brings in cbfa5e4 (#24244, packages/runtime only); no path overlaps this branch. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QyoWKK9RwUNxBxmevy9Neb
…outes MODULES note Only the item save builds a 400 body of its own; the reset's 400s come from the shared query guards. Comment only. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QyoWKK9RwUNxBxmevy9Neb
📓 Docs Drift CheckThis PR changes 1 package(s): 33 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 10 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. 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 b6bec0d548ba3a2c0bd33b25a1092a7eff840052 && git checkout b6bec0d548ba3a2c0bd33b25a1092a7eff840052
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin f5ef054a72e743723101d7ff15120b35c7a19b68 892a86538dcc0b491942657ec426e06c0e7d4a56 && git checkout -B drift-repro f5ef054a72e743723101d7ff15120b35c7a19b68 && git merge --no-ff 892a86538dcc0b491942657ec426e06c0e7d4a56
node scripts/docs-audit/affected-docs.mjs --json f5ef054a72e743723101d7ff15120b35c7a19b68
|
席位核对 — ACCEPT · PR #24257 at
|
Part of #23050
Clause-②: no
Sub-slice 13c of the
rest-server.tssplit: the fifth/metagroup. Group G5 ofRestServer#registerMetadataEndpointsInneris two statements, the per-item writes, of 405 lines (baserest-server.ts:5284–:5688at9975c26ae):registerPerItemRoute({ method: 'PUT', … })at:5288(the item save,PUT {metaPath}/:type/:name) andregisterPerItemRoute({ method: 'DELETE', … })at:5528(the reset to the artifact default,DELETE {metaPath}/:type/:name). They move, re-indented one level, to a new module,packages/rest/src/meta-item-write-routes.ts, asregisterMetaItemWriteRoutes. It is the firstregisterPerItemRoutepass-through: the module registers nothing on the route manager itself.This follows the slicing plan (
os-dev-report6239704287, sub-slice 13c), seat 1's ruling on it6239783526(quoted below), static-receiver ruling A6205442867, 13b'shandover_13clist (report6244193505) and the claim6244810707. PR #24240 (13b,646303eae) is the shape copied.Nothing else moves:
dist/index.d.ts/index.d.ctsare byte-identical, and so are both bundles' 39-name export lists;rest-server.tsgoes from 7,746 to 7,363 lines. G4 and G6–G8, the umbrellaregisterMetadataEndpointsand its guarded swap, the inner head's bindings andregisterPerItemRouteitself, every handler body, the class head,meta-item-read-gate.ts,docs/adr/**andpackages/spec/src/**are untouched. #23050 stays open for 13d–13e.The ruling this follows (seat 1,
6239783526, verbatim)The shape
Moved, at its position. In the inner method, right after 13b's
registerMetaItemReadRoutes.call(itemReadHost, scope);, the head now builds the host literalitemWriteHostand callsregisterMetaItemWriteRoutes.call(itemWriteHost, scope)with the ONE existingscope(no second one is built). Registration order is unchanged: after the per-item reads, above the history family.The host,
MetaItemWriteRouteHost: 5 members in first-read order (a symbol-resolved walk of G5 with the TypeScript 6.0.3 compiler API, 13b's method; H1 of the dispatch holds:PUTat:5288–:5523,DELETEat:5528–:5688, the history family's first statement at:5696, the one static receiver at:5340):resolveExecCtx(...a) => this.resolveExecCtx(...a), spelled exactly as the execctx census's forwardermetaSaveVerdict(private static)(...a) => RestServer.metaSaveVerdict(...a), typed(typeof RestServer)['metaSaveVerdict']walledCatalogRefusalresolveProtocolresolveMetaWriteActorNo
routeManagermember (the plan's 5, H1). The body reads the route manager nowhere: both statements register throughregisterPerItemRoute, which reaches the module inscopeas the inner head's ONE closure (Q1 A, ⛔ no module-local copy). That closure reads the server'sthis.routeManagerat call time; every call runs during the inner call, inside the umbrella's swap, so both routes still mount behind the wrapping registrar and still answer tometadata.endpoints.item, which the same closure reads. The module header and the comment above the literal say why. The walk found no barethis, nothis[...], nofunctionkeyword and no assignment to athismember, and the body reads no instance FIELD at request time, so no member is a getter.Host placement (binding). The literal is built inside
registerMetadataEndpointsInner, at G5's old position. It is not built inregisterRoutes, the constructor, an instance cache or the umbrella above the swap. For a pass-through module the swap is read throughregisterPerItemRoute's call-timethis.routeManager, so the guard ablation below plants the wrong shape this module could take: a module-local registrar reading a manager captured above the swap.The scope (Q1 A). The module opens with
const { metaPath, isScoped, registerPerItemRoute } = scope;, the three bindings it reads. It does not readmetadata: the per-item switch is read insideregisterPerItemRoute, where it always was.The one changed token (ruling A, named in the claim). At base
rest-server.ts:5340the save door callsRestServer.metaSaveVerdict(ctx). It is nowthis.metaSaveVerdict(ctx)through the host (module:187). The static reads nothing but its argument, so the receiver is the whole difference.Module-level names (the same walk, base vs head):
./rest-server.js:META_ITEM_RESET_PARAMS(stays:rest-server-meta-member-selector.test.tsimports it from there) andmetaItemPackageBinding(on the package entry). Both are read only at request time, so the two modules importing each other cannot see one uninitialised.rest-server.ts(read only by the moved code, sonoUnusedLocalswould refuse them; a pointer comment is left at each): the localMETA_ITEM_SAVE_PARAMSimport (./meta-item-read-gate.js; the re-export that names it stays),metaSaveRequestOptions(./meta-save-request.js), andSaveMetaItemRequestandDeleteMetaItemRequest(@objectstack/spec/api). Exactly the plan's four.META_ITEM_RESET_PARAMSstays, as the plan says.rethrowAuthzStoreUnavailable,metaWriteCapabilityVerdict,handleRouteError,META_ITEM_MEMBER_PARAM,metaMemberSelector,refuseUnknownQueryParams,refuseRepeatedQueryParams) is imported from the modulerest-server.tsimports it from, and is still read there too.MetaRouteScopeandTransportScopedMetaRequestcome from./meta-collection-routes.js.Proof
All runs went through
os-verify-lock, with every exit captured before any pipe, unless noted. The base is9975c26ae, measured in a read-only comparison worktree. The head is3750ddecc; the merge head39912f9e1adds one merge oforigin/maincbfa5e433(#24244), which touchespackages/runtimeonly, outside@objectstack/rest's dependency closure (core,metadata,metadata-core,observability,platform-objects,service-package,spec,types), so main vs merge head reads as base vs head; the final commit892a86538is a comment in a gate script.1. The moved text.
git show 9975c26ae:packages/rest/src/rest-server.ts | sed -n 5284,5688p, with one 4-space indent removed, was compared withmeta-item-write-routes.ts:131–:535, the body after the destructuring line.diffexits 1 on exactly one line: the receiver token (RestServer.metaSaveVerdict(ctx)→this.metaSaveVerdict(ctx)).this.metaSaveVerdictmapped back toRestServer.metaSaveVerdict,diffexits 0 over all 405 lines. Both sides are sha256a8935ad228caf0c790c7c1314782c6eb4405ca639cd95d8f5b453982f8069bb6.2.
.d.tsand exports.index.d.tsandindex.d.ctsare sha25602f1c167ccbea3298a15ea77ac634b50500346fc489efec21828eb5a7ab5928aat base, at head and at the merge head.registerMetaItemWriteRouteshits 2 in each ofindex.js/index.cjsat head and at the merge head, and 0 at base.b3246be6a1718700…, ESM == CJS, base and head.3. Full-boot legs (slice 12's method), 20 configurations: slice 12's thirteen, then the
/metaswitches under scoped-optional:metadata.endpoints.types,.items,.itemand.maintenanceeach false; all four false;metadata.prefix: '/metadata';api.enableMetadata: false.tsxboot ofsrc/rest-server.ts):routes.json,calls.jsonandhandlers.jsonare byte-identical in all 20 configs: 60 of 60 files, concatenation sha256bd4f6685175a61ec…on both trees.dist/index.js): 60 of 60 identical, concatenation20103136b32ff534…, under one declared normalization: esbuild's numeric alias suffix on an import name two bundled modules share. Measured by an identifier-set diff of the two bundles, the ESM head gains exactlyitemWriteHost,registerMetaItemWriteRoutesand two renumbered aliases (rethrowAuthzStoreUnavailable5,metaWriteCapabilityVerdict2), and loses none; those two names are the ones normalized. (The CJS bundle gainsitemWriteHost,registerMetaItemWriteRoutes,import_core38andimport_metadata_core17.)4. The inner-registration leg (the plan's
proof_method). Each config builds aRestServerwith a recordingrouteManagerand callsregisterMetadataEndpointsInner(basePath)directly for/api/v1and/api/v1/environments/:environmentId: 688 recorded registrations over the 20 configs, digested whitespace-free with the ruled receiver tokens mapped back (13b's three plusmetaSaveVerdict), together with method, path, metadata and arity.4f306a2a19ffdd181b36b43e4d8b49d0844dc396c50a3144e8221aeab48b4511on both trees (13b's reading too). Unnormalized, exactly 36 digests differ:PUT …/:type/:nameon both bases in the 18 configs that mount it, the receiver token. TheDELETEdigests are identical raw.535abfd10375066c385a596bf97dd8039252b8fe3f38ebb7fc78e073cf8f98c6on both trees.scripts/ablation-replace.mjs, anchor 1 → 0): thePUTdoor's 501 message gained a!(blob395d5e6ec2c9→82dd302865c5), then, separately, theDELETEdoor's (→7b4819a6f8d5). Each moved the inner digests of exactly its own route, on both bases, in the 18 configs that mount it: 36 of 688 each, and nowhere else. All 20 configs' full-bootroutes/calls/handlersstayed byte-identical (60 of 60): the blind spot the inner leg covers. Restored each time: the blob equalsHEADandgit diff HEADis empty.5. H2: the handed-over closure is the inner method's own. An anonymous request at each moved route on both bases (one-off
tsxprobe, scoped-optional), base and head identical:endpoints.itemon:PUTandDELETEanswer401 UNAUTHENTICATEDwith zero protocol calls (4 of 4), and all four server-visible handlers are the umbrella's wrapper.endpoints.item: false: both routes are gone on both bases (150 → 126 routes, 0PUT/DELETEitem mounts), on both trees.6. The guard ablation (the plan's shape for 13c, 13d and 13e-published). Two literal anchors, nested: the umbrella stashes its
realRouteManager(captured above the swap) anditemWriteHostcarries it as arouteManagermember (rest-server.tsblob2816281785c6→1528afc7f2dd, a 281-line anchor from the umbrella'sconst realRouteManager = this.routeManager;throughitemWriteHost's opening line), and the module replaces the scope'sregisterPerItemRoutewith a module-local registrar that honours the same switch but registers on that host member (meta-item-write-routes.tsblob395d5e6ec2c9→6fdf0913c66a).PUTandDELETEon both bases answer403 FORBIDDENfrom the door's own capability gate, not401, and none of the four handlers is the wrapper. Underendpoints.item: falsethe routes are still gone, so the switch alone cannot tell the two shapes apart; the gate can.Test Files 1 failed | 4 passed (5),Tests 9 failed | 121 passed (130):meta-type-write-capability.test.tsis red 9 times ([security] A datasource write path admits callers below the capability the datasource admin door requires for create/update — detail withheld pending maintainer #21124: the datasource and datasources write shapes for member, other-grant and author, the existing-vs-absent byte identity, and the admin-door parity for the author bearer).rest-meta-auth.test.ts,meta-type-read-capability.test.ts,rest-config-mount-table.pin.test.tsandmeta-route-registration-order.test.tsstay green.HEADandgit diff HEADis empty. No permanent test was added.7. The late-binding ablation (one-off script). The 4 instance methods are planted on the server and the static on the class before
registerRoutes(), as recorders that delegate to the originals. Six request shapes are driven over the two moved routes (a plain save,?mode=draft,?force=truewithIf-Match, a plain reset,?state=draft,?dropStorage=truewithIf-Match), each answering 200 after the expected protocol call. Then everything is planted again and the shapes are driven again.MEASURElines to base): all 5 closure members are reached before and after the re-plant, withearly calls after re-plant: 0.walledCatalogRefusal: this.walledCatalogRefusal.bind(this)(blob2816281785c6→fde53002af3c) givesearly calls after re-plant: 6 ["early:walledCatalogRefusal"]and 4 late members, exit 1. Restored: the blob equalsHEADandgit diff HEADis empty.Readers re-pointed (sums unchanged, no gate loosened)
rest-server-registrar-files.tsgainsmeta-item-write-routes.tsinREST_SERVER_REGISTRAR_FILES(length 15 → 16) and in the named/metasubsetREST_SERVER_META_ROUTE_FILES(2 → 3). The dogfood control counts.call(inside the inner method, now 3, so the subset and the call moved together.execctx-consumer-census.test.tsrest-server.tsstays at 55 mentions (two sites out, one forwarder's two in); the module carries 4. Sixteen forwarders: (16 − 1) + 3 − 2meta-draft-read-door-census.test.ts?state=draft(awriterow) moved; keys name routes, so no ledger row changedrest-server-query-number-census.test.tsrest-server-canonical-query-ast.test.ts(repo)meta-item-write-routes.ts: 0(the save mapping's onequerykey sits mid-line)rest-server-docblock-position.test.tsrest-server.tskeeps its 161 blocksui-view-route-identity/-tenancymeasurement teststhis.enforceAuth(60,this.resolveExecCtx(77 → 78authz-conformance.test.tsauthz-probe-blind-spot.census.tsregisterPerItemRoute(instead"): the module's own control ismeta-item-write-routes.ts: registerPerItemRoute(2 (itsthis.routeManager.register(count is 0, which this census reads as instrument failure); the derivation now emits one control per spelling a module spells, so a module that stops spelling its recorded one makes that control vanish, loudly. The whole-populationregisterPerItemRoute(control is re-anchored over the population rule's own haystack (this file plus every module on the list), where it stays 8 = 6 + 2; overrest-server.tsalone it would read 6./meta subset ↔ .call(3;this.routeManager.register(63,private register*Endpoints(16,const registerPerItemRoute =1 andenforceAuth112 unchangedReaders outside the list:
scripts/check-route-envelope.mjs(MODULESonly; declared on [PM seat] domain:spec — ⏳ vacant #6017,6244817361).meta-item-write-routes.tsis declareddialectOnlywith ratchet [tracking] Envelope-position convergence line for packages/rest's flat dialect — the live ratchet owner #9559 atstringError 0/siblingCode 0: both doors' 403, 400 and 501 bodies are the nested{ error: { code, message } }.rest-server.tskeeps7/3. Output: 26 → 27 modules audited, 16 → 17 ratcheted;--self-testexit 0.content/docs/permissions/system-context.mdxrow 50 (declared on [PM seat] domain:devx · seat 2 — 🟢 os-sales · session_016PVjjuVPte5XEJvaQx1E4t · serial (maintainer) #20163,6244820755; H4 holds). The reset'sisSystemread (metaWriteCapabilityVerdict({ isSystem: ctx?.isSystem === true, … })) moved with it, so at the move commitcheck-system-context-censusexited 1:[file-without-a-row] packages/rest/src/meta-item-write-routes.ts holds 1 elevation read site(s) in 1 symbol(s) (registerMetaItemWriteRoutes). Row 50 gainspackages/rest/src/meta-item-write-routes.ts#registerMetaItemWriteRoutesbeside the inner anchor, which keeps resolving (publish and rollback still read there). Made green by the anchor, ⛔ not by aNON_READ_ANCHORSrow:142 elevation read sites … across 65 files, living in 123 symbol(s); the page cites 136 symbol(s) against 136 required, over 159 anchors(base: 64 files, 122 symbols, 135 / 135, 158 anchors).scripts/adr-anchors/packages__rest__src__meta-item-write-routes.ts.json(NEW; declared as possible on [PM seat] domain:spec — ⏳ vacant #6017).check-adr-anchorschecksADR-NNNN Dkletters only in anchored files. The move took G5's eight letter citations (ADR-0066 D1 ×2, ADR-0131 D3 ×2, ADR-0131 D6 ×4) out of the anchoredrest-server.ts, and the gate read 1783 → 1775 while green: a reader that narrowed silently. This anchors ADR-0066, ADR-0131 and ADR-0106; its invariant adds no letter citation; the reading is back to 1783 (73 anchored file(s)).packages/runtime/src/domains/meta-list-projection-parity.test.tsderivesGEThandlers only (the item, tree, layers and list reads); G5 holds none, and the test was green at the move commit (Tests 739 passed (739)).packages/spec/liveness/metadata_endpoints.json(the plan: "No liveness edit"): theendpoints.itemrow's second citation,rest-server.ts#registerMetadataEndpointsInner(registerPerItemRoutegates the per-itemPUT/DELETEand the history family), stays true, because the switch is read in that closure, which stays in the inner head.check:livenesswas green at the move commit and at head.docs/qa/platform-checklist/areas/api-backend.json' inner anchor ("metaPath and registerPerItemRoute") stays true;check:platform-checklistwas green at the move commit. No other checklist or docs anchor names a G5 symbol.Red before the re-points, each measured with the readers at their base text:
344cb18d8:Test Files 2 failed | 4 passed (6),Tests 5 failed | 121 passed (126). The execctx census failed three times (expected 60 to be 62, the caught splitexpected 10 to be 12, and §7's controlexpected 10 to be greater than or equal to 12); the draft census twice (expected [ …(7) ] to deeply equal [ …(8) ],to have a length of 8 but got 7).Tests 2 failed | 106 passed (108): populationexpected 68 to be 70, and/meta subset ↔ .call(expected 3 to be 2.check:route-envelopeexited 1:meta-item-write-routes.tsNOT DECLARED.check-system-context-censusexited 1 (above).check-adr-anchorsstayed green at 1775 (base 1783);check:liveness,check:platform-checklist, the runtime parity test andrepo(Tests 266 passed | 15 skipped (281)) stayed green. Nine standing behaviour pins of the moved doors readTests 205 passed (205).9ce268e26(the list grown, the readers not yet re-pointed): seven list readers readTest Files 6 failed | 1 passed (7),Tests 7 failed | 127 passed (134)(the length pins and the unfloored module);reporeadTests 2 failed | 268 passed | 16 skipped (286); the dogfood pair readTests 2 failed | 106 passed (108)(registrar list lengthand the tripwire length).cbd7d7a4c, then the merge head).Changeset
.changeset/23050-s13c-meta-item-write-routes-move.mdis a@objectstack/restpatch (Clause-②: no, move-only). The shippedindex.js/index.cjsbytes change (the marker above); the declarations and exports do not.skip-changesetdoes not apply.Acceptance notes
MODULESat 0 / 0 and the row-50 anchor. Beyond it, the ADR anchor (the handover's conditional item) was owed: the letter count dropped by 8. No reader outside the plan's list and 13b's handover read anything G5 held.PUTtwins", "next door" and "a few hundred lines up" describe the inner method's order as it was, in whichPOST {metaPath}/_migrate-stored(now inmeta-collection-routes.ts) sat above these doors. The module header says so rather than editing moved text.registerPerItemRoutedocblock still says the first four members of the per-item face "are inside theifblock further down" (13b moved that block tometa-item-read-routes.ts). It is the inner head's text, a hold-off for this slice, and is left for the slice that re-reads that head.FOLLOW-UPS.md:613(E1) prose,ui-routes.ts' "52 sites" comment andemail-routes.ts' double-mount header.Gates and tests
The final head is
892a86538: one merge oforigin/maincbfa5e433(#24244,packages/runtimeonly), then a comment-only fix to the newMODULESnote inscripts/check-route-envelope.mjs. The tests below ran at the merge head39912f9e1; that last commit changes no file any test reads. The gate union ran at892a86538.pnpm turbo run build --filter=@objectstack/rest... --concurrency=2exited 0 (Tasks: 25 successful, 25 total). At the move commit,pnpm turbo run build --filter=@objectstack/rest... --filter=@objectstack/dogfood... --filter=@objectstack/runtime... --concurrency=2exited 0 (Tasks: 66 successful, 66 total). At the merge head, a whole-workspacepnpm turbo run build --concurrency=2exited 0 (Tasks: 77 successful, 77 total), for the dist readers. No package source was edited while turbo built it; the base dist reads 0 head-only markers.pnpm --filter @objectstack/rest typecheckexits 0 (check:test-typecheck: OK … 0 file(s) / 0 error(s)).pnpm --filter @objectstack/dogfood typecheckexits 0.@objectstack/rest.local:Test Files 294 passed (294),Tests 6032 passed | 326 skipped (6358), includingmeta-route-registration-order.test.ts,rest-config-mount-table.pin.test.tsand the moved doors' pins (meta-type-write-capability,rest-server-meta-member-selector,rest-server-meta-door-closed-sets,meta-501-envelope,meta-write-actor-identity,meta-write-door-capability-enumeration).repo(itstest:repo, run locally because this diff editsrest-server-canonical-query-ast.test.ts):Test Files 5 passed (5),Tests 270 passed | 16 skipped (286).authz-probe-blind-spot.test.ts,authz-conformance.test.ts):Test Files 2 passed (2),Tests 108 passed (108). The dogfood shards skip on PRs and in the queue, so this local run is the evidence.test:repo.@objectstack/runtime:Test Files 3 passed (3),Tests 808 passed (808),meta-list-projection-parity.test.tsamong them.@objectstack/core:Test Files 6 passed (6),Tests 86 passed (86)(its security tests readrest-server.tsfrom disk).pnpm exec eslint --no-inline-configover the 13 changed.ts/.mjsfiles exits 0, with no output. The repo-widepnpm lintbelongs to CI.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no paths) at892a86538derives 117 commands; its stderr names the commit, and the--repoassertion holds. The change set is 16 paths vs merge basecbfa5e433, 1,152 changed lines (+722 / −430), under 3,000.--ran:Run reconciliation — 117 derived, 117 run, 0 NOT-MEASURED, 0 UNRUN., exit 0. It also printed a STALE TREE note:origin/mainmoved tof5ef054a7(feat(core): resolveRequestExecutionContext, the one request-to-ExecutionContext composition; the runtime dispatcher's door calls it #24248) after the merge, and changedscripts/check-single-authz-resolver.mjs, whose newDELEGATORSrow keysrest-server.tsonresolveAuthzContext(the class head, untouched here). No path of that commit is one of this diff's 16, so it was not merged again; PR CI runs the merge ref.check:route-envelope(27 route module(s) audited: 9 conformant, 17 ratcheted, 1 exempt);check:adr-anchors(73 anchored file(s),1783 decision-letter citation(s));node scripts/check-system-context-census.mjs(… across 65 files, living in 123 symbol(s); the page cites 136 symbol(s) against 136 required, over 159 anchors);check:liveness(947 pointer(s) … 947 naming a symbol,737 … asked, 736 anchored, 1 exempt, as at base);check:undeclared-dep-imports;check:cross-package-test-inputs;check:authz-resolver;check:durability-log-level;check:dispatcher-error-vocabulary;check:error-status-conformance;check:dual-build-cjs-loads(111 published require entry point(s) across 69 package(s) load);check:pm-dispatch-gates(1884 cases pass);check:type-check-coverage;check:type-check-debt;check:nul-bytes.node scripts/check-platform-checklist.mjs --changed-from origin/main:10 anchor(s) judged, 0 lost.check:dev-prereqsandcheck:skill-frame-freshness(local-only families). This diff touches nopackages/specbuild input and no four-axis frame file.check-governed-merges --branch HEAD:0 of 16 path(s) hit the register, and the size is under the human-merge threshold.Commits:
344cb18d8, the move;9ce268e26, the list and the/metasubset;cbd7d7a4c, the re-points, with the module's ADR anchor and the row-50 anchor;3750ddecc, the changeset;39912f9e1, the merge;892a86538, a comment-only fix to the newMODULESnote (which door builds the 400).Generated by Claude Code