Repository navigation
refactor(rest): move the /meta history family into meta-item-history-routes.ts (#23050 slice 13d) - #24304
Conversation
…routes.ts (#23050 slice 13d) The five history-family statements of registerMetadataEndpointsInner (GET /history, GET /audit, POST /publish, POST /rollback, GET /diff) move, re-indented, into registerMetaItemHistoryRoutes. The inner method builds the host literal at their old position and passes the one existing scope. Readers are re-pointed in the following commits. Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T Co-authored-by: Claude <noreply@anthropic.com>
…m-history-routes.ts (#23050 slice 13d) Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T Co-authored-by: Claude <noreply@anthropic.com>
…ly (#23050 slice 13d) The registrar-list readers re-read their sums with the module on the list, the dogfood census controls the pass-through module on registerPerItemRoute(, check:route-envelope declares the module with the five string-error and one sibling-code bodies that moved, system-context.mdx row 50 trades the inner anchor for the module's, the studio-authoring #toVersion pointer resolves to the moved function, and a new adr-anchors entry restores the decision-letter count. One patch changeset on @objectstack/rest. Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T Co-authored-by: Claude <noreply@anthropic.com>
…eted tracker citation (#23050 slice 13d) The diff-scoped issue-citation gate reads the moved body as added lines, and one comment cited a tracker number that no longer resolves on the board (deleted). Re-anchored to the commit that landed that pattern, cccbe51; comment text only, no token of code changed. Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 23 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 11 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 7b8c766c68204f978ff5ae6a3a9deb6011a31e4a && git checkout 7b8c766c68204f978ff5ae6a3a9deb6011a31e4a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 21070a2f0ac944e930ab8c269e04d024d4a21eea 03ac3135eeac7a6d457129fabc761fe9e5d7d927 && git checkout -B drift-repro 21070a2f0ac944e930ab8c269e04d024d4a21eea && git merge --no-ff 03ac3135eeac7a6d457129fabc761fe9e5d7d927
node scripts/docs-audit/affected-docs.mjs --json 21070a2f0ac944e930ab8c269e04d024d4a21eea
|
席位核对ACCEPT ·
Generated by Claude Code |
Part of #23050
Clause-②: no
Sub-slice 13d of the
rest-server.tssplit: the sixth/metagroup. Group G6 ofRestServer#registerMetadataEndpointsInner, the history family, is five statements of 820 lines (baserest-server.ts:5218–:6037at93b4acb57, after the separator line:5217), every one aregisterPerItemRoute({ … }):GET {metaPath}/:type/:name/history:5224–:5356:5217–:5356GET {metaPath}/:type/:name/audit:5366–:5518:5357–:5518POST {metaPath}/:type/:name/publish:5522–:5710:5519–:5710POST {metaPath}/:type/:name/rollback:5714–:5830:5711–:5830GET {metaPath}/:type/:name/diff:5834–:6037:5831–:6037They move, re-indented one level, to a new module,
packages/rest/src/meta-item-history-routes.ts, asregisterMetaItemHistoryRoutes. Like 13c's module, it is aregisterPerItemRoutepass-through: it registers nothing on the route manager itself.This follows the slicing plan (
os-dev-report6239704287, sub-slice 13d), seat 1's ruling on it6239783526(quoted below), static-receiver ruling A6205442867, 13c'shandover_13d(report6245538958), seat 2's hand-off6246649897and the claim6247249133. PR #24257 (13c,e9bc60b5a) 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,327 to 6,545 lines on the claim's base (7,357 to 6,575 onorigin/maind537a318b, the merge head's). G7 and G8 (13e), the umbrellaregisterMetadataEndpointsand its guarded swap, the inner head's bindings andregisterPerItemRouteitself, every handler body, the class head and its members,meta-item-read-gate.ts,docs/adr/**andpackages/spec/src/**are untouched. #23050 stays open for 13e.The basis for the
Clause-②: noline above: this is a move. The route table, the inner registrations, every wire answer, the.d.tsand the export list stay identical. The one declaration change isexporton the module-level helperrefuseNonAuthoringCaller(ruling Q6 B), andpackages/rest/src/index.tsdoes not re-export it: measured,dist/index.d.tsandindex.d.ctsare sha256e0a7f9586d1d8802…at base, head and the first merge head, ande027d7941ba1908e…at the final head, byte-identical to a build ofmaind537a318b; the entry's 39 export names (ESM and CJS) contain norefuseNonAuthoringCaller. The reader edits change evidence paths only.The ruling this follows (seat 1,
6239783526, verbatim)The maintainer's rule on this card, verbatim: 「每片只搬代码、路由表前后一致、门禁和文档锚点同 PR 迁完。」
The shape
Moved, at its position. In the inner method, right after 13c's
registerMetaItemWriteRoutes.call(itemWriteHost, scope);, the head now builds the host literalitemHistoryHostand callsregisterMetaItemHistoryRoutes.call(itemHistoryHost, scope)with the ONE existingscope(no second one is built). Registration order is unchanged: after the per-item writes, above the object FSM read (G7).The host,
MetaItemHistoryRouteHost: 15 members in first-read order (a symbol-resolved walk of G6 with the TypeScript 6.0.3 compiler API, the plan's method; no barethis, nothis[...], nofunctionkeyword, no assignment to athismember, noarguments, nosuper):resolveExecCtx(...a) => this.resolveExecCtx(...a), spelled exactly as the execctx census's forwarderresolveProtocoleventDoorRefusalwalledCatalogRefusalresolveMetaWriteActormetaTypeSingular(private static)(...a) => RestServer.metaTypeSingular(...a)resolveObjectMaskergatesPerCaller(private static)fetchCurrentMetaDocumentgatesOnItsOwnKey(private static)diffSides(private static)metaItemReadGateSTORED_VERSION_DOOR_POLICY(private static readonly field)diffEmittedFrom(private static)maskObjectDocumentNo
routeManagermember. All five 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 all five routes still mount behind the wrapping registrar and still answer tometadata.endpoints.item, which the same closure reads. No member is a getter: the body reads no instance field at request time.The six ruled receiver tokens (ruling A
6205442867, Q4 A), all in thediffhandler:RestServer.metaTypeSingular(→this.metaTypeSingular(,RestServer.gatesPerCaller(→this.gatesPerCaller(,RestServer.gatesOnItsOwnKey(→this.gatesOnItsOwnKey(,RestServer.diffSides(→this.diffSides(,RestServer.STORED_VERSION_DOOR_POLICY→this.STORED_VERSION_DOOR_POLICY,RestServer.diffEmittedFrom(→this.diffEmittedFrom(. Each static reads nothing but its arguments (gatesPerCallerstill asksgatesOnItsOwnKeyon the class).Module-level names.
rest-server.tsand gainsexport(Q6 B):refuseNonAuthoringCaller(history, audit and diff call it), beside its calleemayReadAuthoringTrail, thesystem-context.mdx:108anchor; a one-paragraph pointer is added to its docblock. Row 108 is unchanged../rest-server.js: the five closed setsMETA_ITEM_HISTORY_PARAMS,META_ITEM_AUDIT_PARAMS,META_ITEM_PUBLISH_PARAMS,META_ITEM_ROLLBACK_PARAMS,META_ITEM_DIFF_PARAMS(the door tests import them from there),readDeclaredQueryNumberandUNDECLARED_WHOLE_NUMBER_PARAM(approvals, data-action and search import them from there),metaItemPackageBindingandsendMetaItemAbsent. Each is read only at request time.rest-server.tswith the body (six, measured):HistoryMetaItemRequestSchemaandAuditMetaItemRequestSchema(the whole value import), the typesPublishMetaItemRequest,AuditMetaItemRequest,HistoryMetaItemRequest, andmetaMemberSelector. The plan named five;metaMemberSelectoris the sixth because its other readers left with 13b and 13c, so G6 held its last three reads (noUnusedLocalswould red the leftover import). A pointer comment stands at each old position, and thethrownAnswerIsBareNotFoundimport comment now says the diff door's catch moved too and the class's event-door refusal still reads it.rest-server.tsimports it from;MetaRouteScopeandTransportScopedMetaRequestfrom./meta-collection-routes.js.Proof
Builds, suites, dumps, controls and ablations ran through
os-verify-lock, every exit captured before any pipe; the shorttsxprobes ran unlocked (see Deviations). The base is93b4acb57(the claim's). The head is56a51a837; the merge head93027d839adds one merge oforigin/main1e001c7df(#24270, #24269:packages/spec,packages/metadata-protocol,packages/runtime,packages/client,packages/objectqltests), with no path in common with this diff;2c02e0a0dis the comment edit above (legs 1–4 re-run there: the source dump byte-identical to the head's in all 80 files, the rebuilt bundle equal to base under the declared normalization,.d.tsunchanged). The final head03ac3135emergesorigin/maind537a318ba second time, because it brought PR #24267 (the class head ofrest-server.ts,metaItemReadGateSourcesandserveMetaItemLayered, andmeta-item-read-gate.ts) and PR #24274 (row 29b ofsystem-context.mdx), both textually disjoint from this diff, as the claim recorded; the merge was clean and this branch's delta againstmainis still exactly its 17 files, +1210 / −853. Re-measured against thatmain(built from a detached checkout ofd537a318b):index.d.ts/index.d.ctsare byte-identical tomain's, the 39-name export list is unchanged, and the source and bundle dumps of all 20 configs equalmain's: 60 of 60 full-boot files and 688 of 688 inner digests under the same mapping and normalization (raw, onlyGET …/diff's 36 differ, the receivers), with the concatenation hashes quoted below, whichmain's merge moved none of. The bundle identifier-set diff againstmain's ESM bundle is the same five head-only names, none lost.1. The moved text. Base
rest-server.ts:5218–:6037, with one 4-space indent removed, againstmeta-item-history-routes.ts:177–:996(the body after the destructuring line), at the final head: the rawdiffexits 1 on exactly seven lines, the six receivers and one comment line; with the sixthis.Xmapped back toRestServer.Xand that comment line mapped back,diffexits 0 over all 820 lines, both sides sha25651dc0cccdc000123dbd57fa5fb528ed2a5a96c61dd73c357ef74fa28024134cc. Every non-empty line (814) carried the 8-space indent; no tab, no trailing whitespace.The one comment edit. The audit door's moved comment called
auditMetaItem's declaration "the #11006-pattern catch-up".check-issue-citationsjudges the lines a change ADDS, so the move made that pre-existing citation an added line, and it does not resolve:--probe-causereads it[deleted]("minted, gone from the board, and the web endpoint 404s too"), exit 2. The gate's own remedy is to name a target that resolves, and the re-anchor sweeps that cleanedpackages/rest/srcused the deciding commit: the line now reads "(the commit-cccbe51bf-pattern",cccbe51bfbeing the landing of that card's ruling ("feat(spec): declare publishMetaItem as optional MetadataProtocol member with PublishMetaItemRequest", read through the REST API, since this clone's history starts after it). Comment text only: esbuild drops comments, and every source and bundle digest at the final head equals the one before the edit. With it the gate reads77 resolves, 1 resolves-as-pull-requestand exits 0.2.
.d.tsand exports.index.d.tsandindex.d.ctsare sha256e0a7f9586d1d8802b2b2922b957401a02f03818db56779dfa347534db20732caat base, at head, at the first merge head and at2c02e0a0d; at the final head they aree027d7941ba1908e700d18bcd37ae6b26241e4bca7a4fcb11364305e3b204fd9, byte-identical to a build ofmaind537a318b(#24267 moved them, not this diff). The head-only markerregisterMetaItemHistoryRouteshits 2 in each ofindex.js/index.cjsat head and merge head, 0 at base. Both bundles load with 39 exports and one sorted name list, sha256b3246be6a1718700…, ESM == CJS, base and head (13c's reading too).3. Full-boot legs, 20 configurations: slice 12's thirteen, then the
/metaswitches under scoped-optional (metadata.endpoints.types,.items,.item,.maintenanceeach false; all four false;metadata.prefix: '/metadata';api.enableMetadata: false). Route counts 75 / 150 / 75 / 75 / 73 / 73 / 142 / 148 / 148 / 138 / 144 / 138 / 150 / 146 / 148 / 126 / 144 / 114 / 150 / 112, the same on both trees.tsxboot ofsrc/rest-server.ts):routes.json,calls.jsonandhandlers.jsonbyte-identical in all 20 configs, 60 of 60, concatenation sha256e73a487e4cfc05ab…on both trees. A second base run was identical to the first (diff -rexit 0).dist/index.js, the base bundle loaded from a copy): 60 of 60 identical, concatenationd1db493b81aaf53e…, 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 exactlyitemHistoryHost,registerMetaItemHistoryRoutesand three renumbered aliases (ObjectSchemaMaskEvaluationError4,metaWriteCapabilityVerdict3,rethrowAuthzStoreUnavailable6) and loses none; those three names are the ones normalized. Unnormalized, the 19 configs that mount/metadiffer only inhandlers.json(the umbrella wrapper spellsrethrowAuthzStoreUnavailableunder a shifted suffix). The CJS bundle gainsitemHistoryHost,registerMetaItemHistoryRoutes,import_core39andimport_metadata_core18.4. The inner-registration leg. Each config builds a
RestServerwith a recordingrouteManagerand callsregisterMetadataEndpointsInner(basePath)directly for/api/v1and/api/v1/environments/:environmentId: 688 recorded registrations over the 20 configs (13c's count), digested whitespace-free with the ruled receiver tokens of 13a–13d mapped back, together with method, path, metadata and arity.2fab0c3853495542…on both trees. Unnormalized, exactly 36 digests differ:GET …/diffon both bases in the 18 configs that mount it, the six receivers. The other four moved routes are identical raw.0dcff1d8b81a295d…on both trees (unnormalized,GET …/published, G8, also differs: the same alias shift, in a body this PR does not touch).scripts/ablation-replace.mjs, anchor 1 → 0): the audit door's 501 message gained a!(module blob6b11bab3ccac→cdb207236e6f), then, separately, the publish door's (→7f57a79d8125). 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-boot files stayed 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 byte-identical:endpoints.itemon: all ten mounts answer401 UNAUTHENTICATEDwith zero protocol calls, and all ten server-visible handlers are the umbrella's wrapper.endpoints.item: false: the five routes are gone on both bases (150 → 126 routes, 0 moved mounts), on both trees.6. The guard ablation (the plan's shape for 13c, 13d and 13e-published). Three literal anchors, nested: the umbrella stashes its
realRouteManagercaptured above the swap (rest-server.tsblobcb30c8a7e5b6→e5933a89b85f),itemHistoryHostcarries it as arouteManagermember (→f019c09637fa), and the module replaces the scope'sregisterPerItemRoutewith a module-local registrar that honours the same switch but registers on that host member (module blob6b11bab3ccac→9614ca62b428).403 FORBIDDENfrom the doors' own authoring and capability gates, not401, with zero protocol calls, and none of the ten 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 3 failed | 2 passed (5),Tests 21 failed | 109 passed (130):meta-type-read-capability.test.tsred 12 times ([security] A datasource read path serves connection topology to signed-in members below the capability the datasource admin door requires — detail withheld pending maintainer #21087, the datasource-family read shapes for member, other-grant and author),meta-type-write-capability.test.tsred 8 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 write shapes and the existing-vs-absent byte identity),rest-meta-auth.test.tsred once (把 public 从"全局开关的副产品"升级为声明式能力,然后删掉 api.requireAuth 开关 #3963 / [finding]metadata.endpoints.itemsgates four routes — the_migrate-storedwrite door and the diagnostics sweep among them — while its declared meaning names only the type listing #15542, the helper-routed per-item route's anonymous401).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 9 instance methods are planted on the server and the 5 static methods on the class before
registerRoutes(), as recorders; seven request shapes are driven over the five moved routes (history and diff on anobjectand on aview, audit, publish, rollback), each answering 200, then everything is planted again and the shapes are driven again.MEASURElines byte-identical to base): all 14 closure members are reached before and after the re-plant,early calls after re-plant: 0.eventDoorRefusal: this.eventDoorRefusal.bind(this)(blobcb30c8a7e5b6→601b3610bc89) givesearly calls after re-plant: 3 ["early:eventDoorRefusal"]and 13 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-history-routes.tsinREST_SERVER_REGISTRAR_FILES(length 16 → 17) and in the named/metasubsetREST_SERVER_META_ROUTE_FILES(3 → 4). The dogfood control counts.call(inside the inner method, now 4, so the subset and the call moved together.execctx-consumer-census.test.tsrest-server.tsgoes 55 → 52. Seventeen forwarders = (17 − 1) + 3 − 2meta-draft-read-door-census.test.tsrest-server-query-number-census.test.tsNumber(toVersionRaw)(an exemption row keyed by route) moved; no ledger row changedrest-server-canonical-query-ast.test.ts(repo project)query:slot; floor 0rest-server-docblock-position.test.tsrest-server.tskeeps its 161ui-view-route-identity/-tenancymeasurement teststhis.enforceAuth(60 unchanged,this.resolveExecCtx(78 → 79/metahost literal forwardsresolveExecCtxonly; the ownership guard is still 1 call site and 1 forwarderauthz-conformance.test.tsauthz-probe-blind-spot.census.tsregisterPerItemRoute((5), as 13c's is (Q3); the whole-populationregisterPerItemRoute(control stays 8 (1 inrest-server.ts, G8's, + 2 + 5);const registerPerItemRoute =1,forwarder slice:1,this.routeManager.register(63 andenforceAuth112 unchanged; population rule text names the module and the sixth groupscripts/check-route-envelope.mjs(MODULES)dialectOnly+ ratchet #9559 at stringError 5 / siblingCode 1 (the four 501 bodies of history, publish, rollback and diff, and the rollback's 400INVALID_REQUEST, which is the one sibling-code body);rest-server.tsbanks 7 → 2 and 3 → 2, the two class-head sitescontent/docs/permissions/system-context.mdxrow 50meta-item-history-routes.ts#registerMetaItemHistoryRoutesis added andrest-server.ts#registerMetadataEndpointsInneris dropped:publishandrollbackheld the inner method's lastisSystemreadsdocs/qa/platform-checklist/areas/studio-authoring.json:459rest-server.ts#toVersion→meta-item-history-routes.ts#registerMetaItemHistoryRoutes(the 13a precedent for#route)scripts/adr-anchors/packages__rest__src__meta-item-history-routes.ts.json(new)Red before the re-points, in two stages (each reader read the readers' base text).
337889b10, list not grown: the six list readersTests 7 failed | 121 passed (128)(execctx 57 vs 62 sites, caught same-line 9 vs 12, §7 control 9 vs at least 12, §8 control 2 vs at least 4; query-number: the rollback row names no site, its positive control false, 8 vs 9 sites); dogfoodTests 2 failed | 106 passed (108)(population 65 vs 70;.call(4 vs a subset of 3);check:route-envelopeexit 1 (NOT DECLARED, andrest-server.tsfound 2 vs declared 7 and 2 vs 3);check-system-context-censusexit 1 ([file-without-a-row]the module, 2 reads in 1 symbol;[anchor-is-not-a-read-site]rest-server.ts#registerMetadataEndpointsInner);check-adr-anchorssilently green at 1765 decision letters vs base 1783.099ef9a27, readers at base text: localTests 7 failed | 123 passed (130), repoTests 2 failed | 93 passed | 17 skipped (112), dogfoodTests 2 failed | 106 passed (108)(the length pins and the new module's control).scripts/symbol-anchors.mjs#symbolResolutionClassreadsrest-server.ts#toVersionasdeclarationat base (G6'sconst toVersion) and asliteralat head (the'toVersion'ofMETA_ITEM_ROLLBACK_PARAMS): still resolving, now about the wrong thing. The new anchor readsdeclarationin the module.packages/runtime/src/domains/meta-list-projection-parity.test.tsderives the item, tree and layers GET handlers by path (G6 holds none);packages/spec/liveness/*.json(theendpoints.itemevidence names the inner head'sregisterPerItemRoute, which stays; nopackages/specedit);system-context.mdxrow 108 anddocs/adr/0119:118#NOT_IMPLEMENTED(resolve outside G6).Verification at the final head
03ac3135eUnder
os-verify-lock, each exit captured before any pipe (wall clocks are shared-box readings):pnpm --filter @objectstack/rest typecheck: exit 0 (check:test-typecheck: OK, 0 file(s) / 0 error(s)).@objectstack/restlocal(vitest run --project local): exit 0,Test Files 295 passed (295),Tests 6049 passed | 326 skipped (6375).@objectstack/restrepo: exit 0,Test Files 5 passed (5),Tests 274 passed | 17 skipped (291).authz-probe-blind-spot.test.ts+authz-conformance.test.ts: exit 0,Tests 108 passed (108).@objectstack/runtimetest:repo: exit 0,Tests 808 passed (808)(meta-list-projection-parityamong them);@objectstack/coretest:repo: exit 0,Tests 85 passed (85).93027d839and (rest and dogfood) at2c02e0a0d;@objectstack/dogfoodtypecheckexit 0 at93027d839.Gates, unlocked:
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no paths) at03ac3135ederives 119 commands over 17 paths against merge based537a318b, 2,063 changed lines (+1,210 / −853), under the 3,000 threshold. All 119 ran sequentially at03ac3135e, exit codes recorded before any pipe: all 119 exit 0.--ran: "Run reconciliation — 119 derived, 119 run, 0 NOT-MEASURED, 0 UNRUN.", exit 0. Readings:check:route-envelope28 modules (9 conformant, 18 ratcheted, 1 exempt);check:adr-anchors74 anchored files, 1,783 decision letters;check-system-context-censusOK, 66 files, 123 symbols, 136 of 136 cited, 159 anchors;check:cross-package-test-inputsOK;check:doc-authoringclean;check:dual-build-cjs-loads111 entry points over 69 packages;check:pm-dispatch-gates1,913 cases;check-issue-citationsexit 0. The first union, at93027d839, read 118 of 119 exit 0 andcheck-issue-citationsexit 2: the dead citation the comment edit above re-anchored.origin/mainmoved to21070a2f0after the second merge (#24302, #24292, #24275, #24290:packages/spec,packages/lint,docs/qa); none of its paths is in this diff, so it was not merged a third time.Also:
node scripts/check-platform-checklist.mjs --changed-from origin/mainexit 0 (10 anchors judged, 0 lost);pnpm exec eslint --no-inline-configover the 13 changed.ts/.mjsfiles exit 0, no output;node scripts/pm/check-governed-merges.mjs --branch HEADexit 0 (0 of 17 paths governed, 2,063 at most 3,000); a control-byte scan of every changed file finds none. Not run locally:check:dev-prereqsandcheck:skill-frame-freshness(local-only; not triggered: no spec build input, no four-axis frame file). The repo-widepnpm lintis CI's.Acceptance notes
rest-server.tsand the inner method's order as they stood. The module header says so rather than editing moved text.registerPerItemRoutedocblock still says "The first four of those are inside theifblock further down" (stale since 13b moved that block) and "spread across ~1200 lines". Inner-head text is a hold-off for this slice; carried to 13e.GET …/published) now readsthis.objectQLProvidertwice at request time (viawiredEngineOrLoud, since metadata-protocol: a by-name /meta read of a non-object item (app, view, page, …) serves a disabled package's item while the list omits it; #24097 closes the object half only #24210's second half, PR fix(rest,runtime,metadata-protocol)!: /published, REST /state, _drafts and the event-door absence body answer a disabled package's item as the by-name read does #24247), which the plan's G8 host (6 members, no getter) predates: 13e's published host needs that getter too, andobjectql-slot-consumer-census.test.tssees both G7's and G8's consumers move.Deviations
tsxprobes (H2 on base and head, the late-binding probe on base and head) ran outsideos-verify-lock, a few seconds each; dumps, controls, ablations, builds and suites ran under it. The base legs of those probes boot the baserest-server.tsfrom an untracked copy beside it insrc/(deleted after each run); the base bundle leg loadsdistcopied underpackages/rest/node_modules/.s13d-base/(gitignored).pnpm turbo run build --concurrency=2(77 tasks) ran after the merge, for the dist-reading gate families.#11006citation re-anchored to commitcccbe51bf, proof 1), beyond the six ruled receivers: the diff-scopedcheck-issue-citationsreads moved lines as added, and a byte-identical move kept it at exit 2. No code token changed.repoproject, the runtime and coretest:repoand the dogfood readers ran locally: this diff edits arepo-project test, and the runtime and corerepoprojects readrestsources from disk.Co-Authored-Byand a robot-emoji PR footer. Per the dispatch and AGENTS.md, the model-free trailers (merge commit included) and the session-URL footer are used.Generated by Claude Code