Repository navigation
Commit 52ff308
Part of #23050
Clause-②: no
Sub-slice **13d** of the `rest-server.ts` split: the sixth `/meta`
group. Group G6 of `RestServer#registerMetadataEndpointsInner`, the
history family, is five statements of 820 lines (base
`rest-server.ts:5218`–`:6037` at `93b4acb57`, after the separator line
`:5217`), every one a `registerPerItemRoute({ … })`:
| route | statement | range with its leading comments |
|---|---|---|
| `GET {metaPath}/:type/:name/history` | `:5224`–`:5356` |
`:5217`–`:5356` |
| `GET {metaPath}/:type/:name/audit` | `:5366`–`:5518` | `:5357`–`:5518`
|
| `POST {metaPath}/:type/:name/publish` | `:5522`–`:5710` |
`:5519`–`:5710` |
| `POST {metaPath}/:type/:name/rollback` | `:5714`–`:5830` |
`:5711`–`:5830` |
| `GET {metaPath}/:type/:name/diff` | `:5834`–`:6037` | `:5831`–`:6037`
|
They move, re-indented one level, to a new module,
`packages/rest/src/meta-item-history-routes.ts`, as
`registerMetaItemHistoryRoutes`. Like 13c's module, it is a
`registerPerItemRoute` pass-through: it registers nothing on the route
manager itself.
This follows the slicing plan (`os-dev-report` `6239704287`, sub-slice
13d), seat 1's ruling on it `6239783526` (quoted below), static-receiver
ruling A `6205442867`, 13c's `handover_13d` (report `6245538958`), seat
2's hand-off `6246649897` and the claim `6247249133`. PR #24257 (13c,
`e9bc60b5a`) is the shape copied.
Nothing else moves:
- the route table, the ordered server registrations, every
server-visible handler and every INNER registration (method, path,
metadata, arity, handler digest) are identical, base vs head, in 20
configurations;
- the published `dist/index.d.ts` / `index.d.cts` are byte-identical,
and so are both bundles' 39-name export lists;
- six code tokens of the moved body changed, the ruled receivers, and
one comment token was re-anchored because the move made a dead tracker
citation an added line for the issue-citation gate (both below).
`rest-server.ts` goes from 7,327 to 6,545 lines on the claim's base
(7,357 to 6,575 on `origin/main` `d537a318b`, the merge head's). G7 and
G8 (13e), the umbrella `registerMetadataEndpoints` and its guarded swap,
the inner head's bindings and `registerPerItemRoute` itself, every
handler body, the class head and its members, `meta-item-read-gate.ts`,
`docs/adr/**` and `packages/spec/src/**` are untouched. #23050 stays
open for 13e.
The basis for the `Clause-②: no` line above: this is a move. The route
table, the inner registrations, every wire answer, the `.d.ts` and the
export list stay identical. The one declaration change is `export` on
the module-level helper `refuseNonAuthoringCaller` (ruling Q6 B), and
`packages/rest/src/index.ts` does not re-export it: measured,
`dist/index.d.ts` and `index.d.cts` are sha256 `e0a7f9586d1d8802…` at
base, head and the first merge head, and `e027d7941ba1908e…` at the
final head, byte-identical to a build of `main` `d537a318b`; the entry's
39 export names (ESM and CJS) contain no `refuseNonAuthoringCaller`. The
reader edits change evidence paths only.
## The ruling this follows (seat 1, `6239783526`, verbatim)
> - **Q1, A.** The four head bindings (`metadata`, `metaPath`,
`isScoped`, `registerPerItemRoute`) reach each module as ONE `scope:
MetaRouteScope` parameter, built once in the inner head. Each module
destructures only what it uses, and body tokens are unchanged. The host
stays class members only.
> - `registerPerItemRoute` stays one closure that reads RestServer's
guarded `routeManager` at call time. ⛔ No module-local copy: that would
be a second copy of a helper (rule 2).
> - **Q3, A.** `rest-server-registrar-files.ts` exports a named subset,
the `/meta` modules. The dogfood census's reachable count becomes "the
umbrella's sites plus every site in that subset", and a control pins the
subset against the number of module calls inside the inner method. This
is declared at 13a with the anonymous-`401` ablation as the runtime
proof.
> - From 13c on, a module with no direct register site is controlled on
`registerPerItemRoute(` instead.
> - ⛔ No naming convention, and ⛔ never "let blindSpot rise".
> - **Q4, A.** `STORED_VERSION_DOOR_POLICY`, a `private static readonly`
field set once at class evaluation, is handed over by value. 13b and 13d
name it in their claims, together with each sub-slice's static-receiver
tokens (13 in all, ruling A `6205442867`).
> - **Q6.** […] B for `refuseNonAuthoringCaller` (13d): it stays and is
exported, because its callee `mayReadAuthoringTrail` is a docs anchor
(`system-context.mdx:108`). […]
>
> **Binding on every sub-slice (from the plan's measurements):**
> - **Hosts are built inside `registerMetadataEndpointsInner`**, at the
position of the statements they replace, with `routeManager` passed by
value. ⛔ Never in `registerRoutes`, the constructor, an instance cache
or the umbrella above the swap: those capture the real manager, and the
moved routes would mount outside the anonymous-deny gate (#3963) and the
type-level admissions (#21087, #21124).
> - Each sub-slice proves this with the guard ablation in the plan: an
anonymous request at every moved route gets `401` on head, and the
ablation does not.
> - **The proof gains an inner-registration leg.** Slice 12's handler
digest is blind to `/meta`, because every route's server-visible handler
is the same guard wrapper. So each sub-slice digests the inner handlers
through a recording `routeManager` and a direct
`registerMetadataEndpointsInner(basePath)` call per base, with the ruled
receiver tokens mapped back. A one-character positive control must move
exactly that route's inner digest.
> - The full-boot legs stay: `getRoutes()`, ordered registrations,
`.d.ts`/`.d.cts`, and the 39-name export list.
> - The config matrix is slice 12's 13 configs plus the `/meta` switches
the plan names.
> - **Readers move in the same PR**, loud and silent alike, as the plan
lists per sub-slice. […] The `system-context.mdx` rows change with the
sub-slice that moves their code.
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 literal `itemHistoryHost` and calls
`registerMetaItemHistoryRoutes.call(itemHistoryHost, scope)` with the
ONE existing `scope` (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 bare `this`, no `this[...]`, no `function`
keyword, no assignment to a `this` member, no `arguments`, no `super`):
| member | reads | handed over as |
|---|---:|---|
| `resolveExecCtx` | 5 | closure `(...a) => this.resolveExecCtx(...a)`,
spelled exactly as the execctx census's forwarder |
| `resolveProtocol` | 5 | closure |
| `eventDoorRefusal` | 2 (history, audit) | closure |
| `walledCatalogRefusal` | 2 (publish, rollback) | closure |
| `resolveMetaWriteActor` | 2 (publish, rollback) | closure |
| `metaTypeSingular` (private static) | 1 (diff) | closure `(...a) =>
RestServer.metaTypeSingular(...a)` |
| `resolveObjectMasker` | 1 (diff) | closure |
| `gatesPerCaller` (private static) | 1 (diff) | closure on the class |
| `fetchCurrentMetaDocument` | 1 (diff) | closure |
| `gatesOnItsOwnKey` (private static) | 1 (diff) | closure on the class
|
| `diffSides` (private static) | 1 (diff) | closure on the class |
| `metaItemReadGate` | 1 (diff) | closure |
| `STORED_VERSION_DOOR_POLICY` (private static readonly field) | 1
(diff) | BY VALUE (Q4 A) |
| `diffEmittedFrom` (private static) | 1 (diff) | closure on the class |
| `maskObjectDocument` | 1 (diff) | closure |
**No `routeManager` member.** All five statements register through
`registerPerItemRoute`, which reaches the module in `scope` as the inner
head's ONE closure (Q1 A, ⛔ no module-local copy). That closure reads
the server's `this.routeManager` at 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 to
`metadata.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
the `diff` handler:** `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
(`gatesPerCaller` still asks `gatesOnItsOwnKey` on the class).
**Module-level names.**
- **Stays in `rest-server.ts` and gains `export` (Q6 B):**
`refuseNonAuthoringCaller` (history, audit and diff call it), beside its
callee `mayReadAuthoringTrail`, the `system-context.mdx:108` anchor; a
one-paragraph pointer is added to its docblock. Row 108 is unchanged.
- **Already exported, imported from `./rest-server.js`:** the five
closed sets `META_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),
`readDeclaredQueryNumber` and `UNDECLARED_WHOLE_NUMBER_PARAM`
(approvals, data-action and search import them from there),
`metaItemPackageBinding` and `sendMetaItemAbsent`. Each is read only at
request time.
- **Imports that left `rest-server.ts` with the body (six, measured):**
`HistoryMetaItemRequestSchema` and `AuditMetaItemRequestSchema` (the
whole value import), the types `PublishMetaItemRequest`,
`AuditMetaItemRequest`, `HistoryMetaItemRequest`, and
`metaMemberSelector`. The plan named five; `metaMemberSelector` is the
sixth because its other readers left with 13b and 13c, so G6 held its
last three reads (`noUnusedLocals` would red the leftover import). A
pointer comment stands at each old position, and the
`thrownAnswerIsBareNotFound` import comment now says the diff door's
catch moved too and the class's event-door refusal still reads it.
- Every other name is imported from the module `rest-server.ts` imports
it from; `MetaRouteScope` and `TransportScopedMetaRequest` from
`./meta-collection-routes.js`.
## Proof
Builds, suites, dumps, controls and ablations ran through
`os-verify-lock`, every exit captured before any pipe; the short `tsx`
probes ran unlocked (see Deviations). The base is `93b4acb57` (the
claim's). The head is `56a51a837`; the merge head `93027d839` adds one
merge of `origin/main` `1e001c7df` (#24270, #24269: `packages/spec`,
`packages/metadata-protocol`, `packages/runtime`, `packages/client`,
`packages/objectql` tests), with no path in common with this diff;
`2c02e0a0d` is 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.ts` unchanged). The
final head `03ac3135e` merges `origin/main` `d537a318b` a second time,
because it brought PR #24267 (the class head of `rest-server.ts`,
`metaItemReadGateSources` and `serveMetaItemLayered`, and
`meta-item-read-gate.ts`) and PR #24274 (row 29b of
`system-context.mdx`), both textually disjoint from this diff, as the
claim recorded; the merge was clean and this branch's delta against
`main` is still exactly its 17 files, +1210 / −853. Re-measured against
that `main` (built from a detached checkout of `d537a318b`):
`index.d.ts` / `index.d.cts` are byte-identical to `main`'s, the 39-name
export list is unchanged, and the source and bundle dumps of all 20
configs equal `main`'s: 60 of 60 full-boot files and 688 of 688 inner
digests under the same mapping and normalization (raw, only `GET
…/diff`'s 36 differ, the receivers), with the concatenation hashes
quoted below, which `main`'s merge moved none of. The bundle
identifier-set diff against `main`'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, against `meta-item-history-routes.ts:177`–`:996`
(the body after the destructuring line), at the final head: the raw
`diff` exits 1 on exactly seven lines, the six receivers and one comment
line; with the six `this.X` mapped back to `RestServer.X` and that
comment line mapped back, `diff` exits 0 over all 820 lines, both sides
sha256
`51dc0cccdc000123dbd57fa5fb528ed2a5a96c61dd73c357ef74fa28024134cc`.
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-citations` judges the lines a change ADDS, so the move made
that pre-existing citation an added line, and it does not resolve:
`--probe-cause` reads 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 cleaned
`packages/rest/src` used the deciding commit: the line now reads "(the
commit-cccbe51bf-pattern", `cccbe51bf` being 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 reads `77
resolves, 1 resolves-as-pull-request` and exits 0.
**2. `.d.ts` and exports.** `index.d.ts` and `index.d.cts` are sha256
`e0a7f9586d1d8802b2b2922b957401a02f03818db56779dfa347534db20732ca` at
base, at head, at the first merge head and at `2c02e0a0d`; at the final
head they are
`e027d7941ba1908e700d18bcd37ae6b26241e4bca7a4fcb11364305e3b204fd9`,
byte-identical to a build of `main` `d537a318b` (#24267 moved them, not
this diff). The head-only marker `registerMetaItemHistoryRoutes` hits 2
in each of `index.js` / `index.cjs` at head and merge head, 0 at base.
Both bundles load with 39 exports and one sorted name list, sha256
`b3246be6a1718700…`, ESM == CJS, base and head (13c's reading too).
**3. Full-boot legs, 20 configurations:** slice 12's thirteen, then the
`/meta` switches under scoped-optional (`metadata.endpoints.types`,
`.items`, `.item`, `.maintenance` each 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.
- **Source leg** (a `tsx` boot of `src/rest-server.ts`): `routes.json`,
`calls.json` and `handlers.json` byte-identical in all 20 configs, 60 of
60, concatenation sha256 `e73a487e4cfc05ab…` on both trees. A second
base run was identical to the first (`diff -r` exit 0).
- **Bundle leg** (the same dump against the built `dist/index.js`, the
base bundle loaded from a copy): 60 of 60 identical, concatenation
`d1db493b81aaf53e…`, 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 exactly
`itemHistoryHost`, `registerMetaItemHistoryRoutes` and three renumbered
aliases (`ObjectSchemaMaskEvaluationError4`,
`metaWriteCapabilityVerdict3`, `rethrowAuthzStoreUnavailable6`) and
loses none; those three names are the ones normalized. Unnormalized, the
19 configs that mount `/meta` differ only in `handlers.json` (the
umbrella wrapper spells `rethrowAuthzStoreUnavailable` under a shifted
suffix). The CJS bundle gains `itemHistoryHost`,
`registerMetaItemHistoryRoutes`, `import_core39` and
`import_metadata_core18`.
**4. The inner-registration leg.** Each config builds a `RestServer`
with a recording `routeManager` and calls
`registerMetadataEndpointsInner(basePath)` directly for `/api/v1` and
`/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.
- **Source leg:** 688 of 688 identical, same order; digest-list sha256
`2fab0c3853495542…` on both trees. Unnormalized, exactly 36 digests
differ: `GET …/diff` on both bases in the 18 configs that mount it, the
six receivers. The other four moved routes are identical raw.
- **Bundle leg:** 688 of 688 identical under the three alias names;
digest-list sha256 `0dcff1d8b81a295d…` on both trees (unnormalized, `GET
…/published`, G8, also differs: the same alias shift, in a body this PR
does not touch).
- **Positive controls** (one character each, through
`scripts/ablation-replace.mjs`, anchor 1 → 0): the audit door's 501
message gained a `!` (module blob `6b11bab3ccac` → `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 equals `HEAD` and `git
diff HEAD` is 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 `tsx`
probe, scoped-optional), base and head byte-identical:
- `endpoints.item` on: all ten mounts answer `401 UNAUTHENTICATED` with
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
`realRouteManager` captured above the swap (`rest-server.ts` blob
`cb30c8a7e5b6` → `e5933a89b85f`), `itemHistoryHost` carries it as a
`routeManager` member (→ `f019c09637fa`), and the module replaces the
scope's `registerPerItemRoute` with a module-local registrar that
honours the same switch but registers on that host member (module blob
`6b11bab3ccac` → `9614ca62b428`).
- **Ablation:** an anonymous request at all ten mounts answers `403
FORBIDDEN` from the doors' own authoring and capability gates, not
`401`, with zero protocol calls, and none of the ten handlers is the
wrapper. Under `endpoints.item: false` the routes are still gone, so the
switch alone cannot tell the two shapes apart; the gate can.
- **Standing pins under the ablation:** `Test Files 3 failed | 2 passed
(5)`, `Tests 21 failed | 109 passed (130)`:
`meta-type-read-capability.test.ts` red 12 times (#21087, the
datasource-family read shapes for member, other-grant and author),
`meta-type-write-capability.test.ts` red 8 times (#21124, the write
shapes and the existing-vs-absent byte identity),
`rest-meta-auth.test.ts` red once (#3963 / #15542, the helper-routed
per-item route's anonymous `401`). `rest-config-mount-table.pin.test.ts`
and `meta-route-registration-order.test.ts` stay green.
- Restored, both files: each blob equals `HEAD` and `git diff HEAD` is
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 an `object` and on a
`view`, audit, publish, rollback), each answering 200, then everything
is planted again and the shapes are driven again.
- **Head** (`MEASURE` lines byte-identical to base): all 14 closure
members are reached before and after the re-plant, `early calls after
re-plant: 0`.
- **Ablation:** `eventDoorRefusal: this.eventDoorRefusal.bind(this)`
(blob `cb30c8a7e5b6` → `601b3610bc89`) gives `early calls after
re-plant: 3 ["early:eventDoorRefusal"]` and 13 late members, exit 1.
Restored: the blob equals `HEAD` and `git diff HEAD` is empty.
## Readers re-pointed (sums unchanged, no gate loosened)
`rest-server-registrar-files.ts` gains `meta-item-history-routes.ts` in
`REST_SERVER_REGISTRAR_FILES` (length 16 → 17) and in the named `/meta`
subset `REST_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.
| reader | sum over the list | change |
|---|---|---|
| `execctx-consumer-census.test.ts` | 62 sites = 5 + 9 + 5 + 7 + 8 + 1 +
5 + 2 + 1 + 1 + 1 + 0 + 6 + 3 + 1 + 2 + 5; mentions 141 → 145 | The five
sites moved, all locally caught as before (audit, publish, rollback on
their invocation lines; history and diff on their continuation lines,
two of §7's and §8's four). The four new mentions are the seam: the
forwarder, two, and the host interface's member, two. `rest-server.ts`
goes 55 → 52. Seventeen forwarders = (17 − 1) + 3 − 2 |
| `meta-draft-read-door-census.test.ts` | 8 = … + 3 + 2 + 1 + 0 | The
history family reads no draft switch |
| `rest-server-query-number-census.test.ts` | 9 = 7 + 1 + 0 ×14 + 1 |
The rollback's `Number(toVersionRaw)` (an exemption row keyed by route)
moved; no ledger row changed |
| `rest-server-canonical-query-ast.test.ts` (repo project) | 4,
unchanged | The module builds no `query:` slot; floor 0 |
| `rest-server-docblock-position.test.ts` | 65 = 62 + 3 | The module
carries three TSDoc blocks (header, host interface, function);
`rest-server.ts` keeps its 161 |
| `ui-view-route-identity` / `-tenancy` measurement tests |
`this.enforceAuth(` 60 unchanged, `this.resolveExecCtx(` 78 → 79 | The
fourth `/meta` host literal forwards `resolveExecCtx` only; the
ownership guard is still 1 call site and 1 forwarder |
| dogfood `authz-conformance.test.ts` | realtime tripwires read 0 over
17 files | List length 16 → 17 |
| dogfood `authz-probe-blind-spot.census.ts` | 70 / 19 / 51 unchanged |
The module is controlled on `registerPerItemRoute(` (5), as 13c's is
(Q3); the whole-population `registerPerItemRoute(` control stays 8 (1 in
`rest-server.ts`, G8's, + 2 + 5); `const registerPerItemRoute =` 1,
`forwarder slice:` 1, `this.routeManager.register(` 63 and `enforceAuth`
112 unchanged; population rule text names the module and the sixth group
|
| `scripts/check-route-envelope.mjs` (`MODULES`) | stringError 39,
siblingCode 54, sums unchanged | The module is declared `dialectOnly` +
ratchet #9559 at stringError 5 / siblingCode 1 (the four 501 bodies of
history, publish, rollback and diff, and the rollback's 400
`INVALID_REQUEST`, which is the one sibling-code body); `rest-server.ts`
banks 7 → 2 and 3 → 2, the two class-head sites |
| `content/docs/permissions/system-context.mdx` row 50 | census OK | The
module's anchor
`meta-item-history-routes.ts#registerMetaItemHistoryRoutes` is added and
`rest-server.ts#registerMetadataEndpointsInner` is dropped: `publish`
and `rollback` held the inner method's last `isSystem` reads |
| `docs/qa/platform-checklist/areas/studio-authoring.json:459` | anchor
resolves to G6 | `rest-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) | 1783 decision letters, restored | ADR-0067, ADR-0106, ADR-0066
and ADR-0131, with the invariant the bodies' citations carry |
**Red before the re-points, in two stages (each reader read the readers'
base text).**
- **Move commit `337889b10`, list not grown:** the six list readers
`Tests 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); dogfood `Tests 2 failed | 106 passed (108)`
(population 65 vs 70; `.call(` 4 vs a subset of 3);
`check:route-envelope` exit 1 (NOT DECLARED, and `rest-server.ts` found
2 vs declared 7 and 2 vs 3); `check-system-context-census` exit 1
(`[file-without-a-row]` the module, 2 reads in 1 symbol;
`[anchor-is-not-a-read-site]`
`rest-server.ts#registerMetadataEndpointsInner`); `check-adr-anchors`
silently green at 1765 decision letters vs base 1783.
- **List grown `099ef9a27`, readers at base text:** local `Tests 7
failed | 123 passed (130)`, repo `Tests 2 failed | 93 passed | 17
skipped (112)`, dogfood `Tests 2 failed | 106 passed (108)` (the length
pins and the new module's control).
- **The silent reader, measured:**
`scripts/symbol-anchors.mjs#symbolResolutionClass` reads
`rest-server.ts#toVersion` as `declaration` at base (G6's `const
toVersion`) and as `literal` at head (the `'toVersion'` of
`META_ITEM_ROLLBACK_PARAMS`): still resolving, now about the wrong
thing. The new anchor reads `declaration` in the module.
- **Examined, not edited:**
`packages/runtime/src/domains/meta-list-projection-parity.test.ts`
derives the item, tree and layers GET handlers by path (G6 holds none);
`packages/spec/liveness/*.json` (the `endpoints.item` evidence names the
inner head's `registerPerItemRoute`, which stays; no `packages/spec`
edit); `system-context.mdx` row 108 and `docs/adr/0119:118`
`#NOT_IMPLEMENTED` (resolve outside G6).
## Verification at the final head `03ac3135e`
Under `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/rest` `local` (`vitest run --project local`): exit 0,
`Test Files 295 passed (295)`, `Tests 6049 passed | 326 skipped (6375)`.
- `@objectstack/rest` `repo`: exit 0, `Test Files 5 passed (5)`, `Tests
274 passed | 17 skipped (291)`.
- dogfood `authz-probe-blind-spot.test.ts` +
`authz-conformance.test.ts`: exit 0, `Tests 108 passed (108)`.
- `@objectstack/runtime` `test:repo`: exit 0, `Tests 808 passed (808)`
(`meta-list-projection-parity` among them); `@objectstack/core`
`test:repo`: exit 0, `Tests 85 passed (85)`.
- The same rest, dogfood, runtime and core runs were green at
`93027d839` and (rest and dogfood) at `2c02e0a0d`;
`@objectstack/dogfood` `typecheck` exit 0 at `93027d839`.
Gates, unlocked: `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` (no paths) at `03ac3135e` derives 119
commands over 17 paths against merge base `d537a318b`, 2,063 changed
lines (+1,210 / −853), under the 3,000 threshold. All 119 ran
sequentially at `03ac3135e`, 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-envelope` 28
modules (9 conformant, 18 ratcheted, 1 exempt); `check:adr-anchors` 74
anchored files, 1,783 decision letters; `check-system-context-census`
OK, 66 files, 123 symbols, 136 of 136 cited, 159 anchors;
`check:cross-package-test-inputs` OK; `check:doc-authoring` clean;
`check:dual-build-cjs-loads` 111 entry points over 69 packages;
`check:pm-dispatch-gates` 1,913 cases; `check-issue-citations` exit 0.
The first union, at `93027d839`, read 118 of 119 exit 0 and
`check-issue-citations` exit 2: the dead citation the comment edit above
re-anchored. `origin/main` moved to `21070a2f0` after 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/main` exit 0 (10 anchors judged, 0 lost); `pnpm exec eslint
--no-inline-config` over the 13 changed `.ts` / `.mjs` files exit 0, no
output; `node scripts/pm/check-governed-merges.mjs --branch HEAD` exit 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-prereqs` and
`check:skill-frame-freshness` (local-only; not triggered: no spec build
input, no four-axis frame file). The repo-wide `pnpm lint` is CI's.
## Acceptance notes
- The moved comments keep their deixis ("the reset door above", "a few
hundred lines up", "on this file"): they describe `rest-server.ts` and
the inner method's order as they stood. The module header says so rather
than editing moved text.
- The inner head's `registerPerItemRoute` docblock still says "The first
four of those are inside the `if` block 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.
- G8 (`GET …/published`) now reads `this.objectQLProvider` twice at
request time (via `wiredEngineOrLoud`, since #24210's second half, PR
#24247), which the plan's G8 host (6 members, no getter) predates: 13e's
published host needs that getter too, and
`objectql-slot-consumer-census.test.ts` sees both G7's and G8's
consumers move.
## Deviations
- The short `tsx` probes (H2 on base and head, the late-binding probe on
base and head) ran outside `os-verify-lock`, a few seconds each; dumps,
controls, ablations, builds and suites ran under it. The base legs of
those probes boot the base `rest-server.ts` from an untracked copy
beside it in `src/` (deleted after each run); the base bundle leg loads
`dist` copied under `packages/rest/node_modules/.s13d-base/`
(gitignored).
- A whole-workspace `pnpm turbo run build --concurrency=2` (77 tasks)
ran after the merge, for the dist-reading gate families.
- One comment token of the moved body was edited (the dead `#11006`
citation re-anchored to commit `cccbe51bf`, proof 1), beyond the six
ruled receivers: the diff-scoped `check-issue-citations` reads moved
lines as added, and a byte-identical move kept it at exit 2. No code
token changed.
- The rest `repo` project, the runtime and core `test:repo` and the
dogfood readers ran locally: this diff edits a `repo`-project test, and
the runtime and core `repo` projects read `rest` sources from disk.
- The harness attribution reminder asked for a model-named
`Co-Authored-By` and 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](https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0b44840 commit 52ff308
17 files changed
Lines changed: 1210 additions & 853 deletions
File tree
- .changeset
- content/docs/permissions
- docs/qa/platform-checklist/areas
- packages
- qa/dogfood/test
- rest/src
- scripts
- adr-anchors
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
181 | 181 | | |
182 | 182 | | |
183 | 183 | | |
184 | | - | |
| 184 | + | |
185 | 185 | | |
186 | 186 | | |
187 | 187 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
456 | 456 | | |
457 | 457 | | |
458 | 458 | | |
459 | | - | |
| 459 | + | |
460 | 460 | | |
461 | 461 | | |
462 | 462 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1637 | 1637 | | |
1638 | 1638 | | |
1639 | 1639 | | |
1640 | | - | |
| 1640 | + | |
| 1641 | + | |
1641 | 1642 | | |
1642 | 1643 | | |
1643 | 1644 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
541 | 541 | | |
542 | 542 | | |
543 | 543 | | |
544 | | - | |
| 544 | + | |
545 | 545 | | |
546 | 546 | | |
547 | 547 | | |
548 | 548 | | |
549 | 549 | | |
550 | | - | |
| 550 | + | |
551 | 551 | | |
552 | 552 | | |
553 | | - | |
554 | | - | |
| 553 | + | |
| 554 | + | |
555 | 555 | | |
556 | 556 | | |
557 | 557 | | |
| |||
891 | 891 | | |
892 | 892 | | |
893 | 893 | | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
894 | 913 | | |
895 | 914 | | |
896 | 915 | | |
897 | | - | |
| 916 | + | |
898 | 917 | | |
899 | 918 | | |
900 | 919 | | |
| |||
912 | 931 | | |
913 | 932 | | |
914 | 933 | | |
| 934 | + | |
| 935 | + | |
915 | 936 | | |
916 | 937 | | |
917 | 938 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
133 | 133 | | |
134 | 134 | | |
135 | 135 | | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
136 | 143 | | |
137 | 144 | | |
138 | 145 | | |
| |||
150 | 157 | | |
151 | 158 | | |
152 | 159 | | |
153 | | - | |
| 160 | + | |
154 | 161 | | |
155 | 162 | | |
156 | 163 | | |
| |||
782 | 789 | | |
783 | 790 | | |
784 | 791 | | |
785 | | - | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
786 | 806 | | |
787 | | - | |
| 807 | + | |
788 | 808 | | |
789 | 809 | | |
790 | 810 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
276 | 276 | | |
277 | 277 | | |
278 | 278 | | |
279 | | - | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
280 | 284 | | |
281 | 285 | | |
282 | 286 | | |
| |||
0 commit comments