Skip to content

refactor(rest): move the /meta object state-machine read and the published read out of rest-server.ts (#23050 slice 13e) - #24330

Merged
objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/issue-23050-s13e-meta-object-state-published
Oct 18, 2026
Merged

objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/issue-23050-s13e-meta-object-state-published

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #23050
Clause-②: no

Sub-slice 13e of the rest-server.ts split, the last /meta sub-slice. The seventh and eighth groups of RestServer#registerMetadataEndpointsInner move out, each called at its old position:

group route base range (52ff308b8, leading comments included) moves to
G7 GET {metaPath}/object/:name/state/:field (one direct register statement, in no per-family switch) rest-server.ts:5287–:5439 (statement :5315–:5439), 153 lines new packages/rest/src/meta-object-state-routes.ts, registerMetaObjectStateRoute
G8 GET {metaPath}/:type/:name/published (one bare block holding one per-item registration) rest-server.ts:5441–:5722 (block :5466–:5722), 282 lines packages/rest/src/meta-item-history-routes.ts, a second export registerMetaItemPublishedRoute

This follows the slicing plan (os-dev-report 6239704287, entry 13e), seat 1's ruling on it 6239783526, static-receiver ruling A 6205442867, the provider-getter ruling 6215084478, 13d's handover_13e (report 6248737371, binding where it measured) and the claim 6249541908. PR #24304 (13d) 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;
  • one code token of the moved text changed, the ruled receiver in the published read (below); the state read's 153 lines are byte-identical after one indent level.

rest-server.ts goes from 6,575 to 6,196 lines (+70 / −449). The umbrella registerMetadataEndpoints and its guarded swap, the inner head's bindings and registerPerItemRoute itself (only its docblock's stale text is re-worded, below), every handler body, the class head and its members, meta-item-read-gate.ts, docs/adr/** and packages/spec/src/** are untouched.

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 (measured below), no declaration gained or lost an export, and the reader edits change evidence paths only.

The rulings this follows

The maintainer's rule on this card, verbatim: 「每片只搬代码、路由表前后一致、门禁和文档锚点同 PR 迁完。」

Seat 1's ruling 6239783526, verbatim in the parts that bind this slice:

  • 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. […]
    • From 13c on, a module with no direct register site is controlled on registerPerItemRoute( instead.
    • ⛔ No naming convention, and ⛔ never "let blindSpot rise".
  • Hosts are built inside registerMetadataEndpointsInner, at the position of the statements they replace, with routeManager passed by value. […]
  • The proof gains an inner-registration leg. […] A one-character positive control must move exactly that route's inner digest.

The provider-getter ruling 6215084478: "A provider field keeps the getter shape, unbound, as slices 2–8 did."

The shape

Moved, at its positions. Right after 13d's history call, the inner method now declares one arrow, const readObjectQLProvider = () => this.objectQLProvider; (what both getters below read), then builds objectStateHost and calls registerMetaObjectStateRoute with it, then builds itemPublishedHost and calls registerMetaItemPublishedRoute with it, each with the ONE existing scope (no second scope literal). Registration order is unchanged: history family, object state read, published read, then the tail comment on the retired compound twins.

MetaObjectStateRouteHost, 3 members in first-read order (a symbol-resolved walk with the TypeScript compiler API, slice 12's method; no bare this, no this[...], no function keyword, no assignment to a this member):

member reads handed over as
routeManager 1 (registration time, the one register statement) BY VALUE, captured inside the inner method, so it is the umbrella's wrapping registrar
objectQLProvider 2 (request time, through wiredEngineOrLoud) GETTER onto the class's field (the provider-getter ruling)
resolveProtocol 1 (the disabled-package refusal) closure

MetaItemPublishedRouteHost, 7 members in first-read order, no routeManager (13d's hand-off corrected the plan's 6):

member reads handed over as
metaTypeSingular (private static) 1 closure on the class, (...a) => RestServer.metaTypeSingular(...a)
resolveObjectMasker 1 closure
resolveProtocol 2 closure
metaItemReadGate 1 closure
maskObjectDocument 1 closure
objectQLProvider 2 (request time, the disabled-owner check PR #24247 added) GETTER
resolveMetadataService 1 closure

The published read registers through registerPerItemRoute, which reaches the module in scope as the inner head's ONE closure (Q1 A, no module-local copy); it still reads the server's route manager at call time, inside the umbrella's swap, and still reads metadata.endpoints.item.

The one ruled receiver token (ruling A 6205442867): RestServer.metaTypeSingular(type) became this.metaTypeSingular(type) in the published read. The static reads nothing but its argument.

Module-level names.

  • wiredEngineOrLoud and the RestProtocol type stay in rest-server.ts and are imported from it (both read only at request time).
  • Imports that left rest-server.ts with the bodies (five, measured by tsc --noEmit's noUnusedLocals): META_ITEM_PUBLISHED_PARAMS (its re-export there stays), canonicalMetaUrlType, relateObjectSchemaMaskPosture, refuseUnknownQueryParams and handleRouteError. The plan named two; refuseUnknownQueryParams had the published read as its last reader in that file, and handleRouteError had exactly these two doors. A one-line pointer comment stands at each old position. ObjectSchemaMaskEvaluationError stays: the class head's resolveObjectMasker docblock links it, and both tsc and eslint count that use.
  • The dynamic import('@objectstack/objectql') moved with the state read.

Inner-head docblock. The registerPerItemRoute docblock's two stale sentences (13d's out-of-scope note) now say where the per-item members live: the first four in the if block that moved to meta-item-read-routes.ts, the later ones registered by three calls in two modules, with the state read registered between the last two. The .d.ts does not carry it (it is inside the method body).

Proof

Builds, suites, dumps, controls and ablations ran through os-verify-lock, every exit captured before any pipe; the short tsx probes ran unlocked (Deviations). Base is 52ff308b8 (the claim's). The move is 1ed1f29bc; the registrar list grows at 7684c634e; the readers are re-pointed at 7c625ffe7; the changeset is ea3f421d8; f2c84cc6f merges origin/main 2b7fc52c3 (eight commits, no path in common with this diff, and packages/rest byte-identical across 52ff308b8..2b7fc52c3).

1. The moved text. G7, base :5287–:5439 against the module's body with one 4-space indent removed: identical over all 153 lines (sha256 fbdd10f74c51… both sides). G8, base :5441–:5722 against registerMetaItemPublishedRoute's body: the raw comparison differs on exactly one line (the receiver); with this.metaTypeSingular( mapped back it is identical over all 282 lines (sha256 79f1e7c77c4f… both sides). Every non-empty line carried the 8-space indent; no tab, no trailing whitespace.

2. .d.ts and exports. index.d.ts and index.d.cts are sha256 e027d7941ba1908e… at base, at 7c625ffe7 and at the merge head (byte-identical, cmp exit 0). Both bundles load with 39 exports and one sorted name list, sha256 b3246be6a1718700…, ESM == CJS, base and head. The head-only markers registerMetaObjectStateRoute and registerMetaItemPublishedRoute hit 2 each in index.js and index.cjs at head, 0 at base.

3. Full-boot legs, 20 configurations (slice 12's thirteen, plus the /meta switches under scoped-optional: metadata.endpoints.types, .items, .item, .maintenance each false, all four false, metadata.prefix: '/metadata', api.enableMetadata: false):

  • 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…, at the move commit and at the merge head.
  • Bundle leg (the same dump against the built dist/index.js, the base bundle loaded from a gitignored copy): 60 of 60 identical, concatenation cd64ab2234f144bd…, with no normalization.

4. The inner-registration leg. A recording routeManager and a direct registerMetadataEndpointsInner(basePath) call per base and per config: 688 recorded registrations, digested whitespace-free with the ruled receiver tokens of 13a–13e mapped back, together with method, path, metadata and arity.

  • Source leg: 688 of 688 identical, same order. Raw, exactly 36 differ: GET …/published on both bases in the 18 configs that mount it, the receiver.
  • Bundle leg: 688 of 688 identical under one declared normalization, esbuild's numeric alias suffix on two import names the published read's body spells, found by a token diff of that handler's bundled text: ObjectSchemaMaskEvaluationError (4 → 3) and canonicalMetaUrlType (3 → 2). The token diff shows exactly three changes in that handler, the receiver and those two aliases.
  • Positive controls (one character each, through scripts/ablation-replace.mjs, anchor 1 → 0): the state read's 501 message gained a ! (module blob 58cd7759387a → 0a91d9fe3459): exactly 40 of 688 inner digests moved, that route on both bases in all 20 configs, and nowhere else. Then, separately, the published read's 501 message (module blob 5e850bcc6a62 → 6efca2bac7d6): exactly 36 of 688 moved, that route only. All 20 configs' full-boot files stayed byte-identical (60 of 60) under both. Restored each time: the blob equals HEAD and git diff HEAD is empty.

5. H2: both routes still mount behind the umbrella's gate. An anonymous request at each moved route on both bases (one-off tsx probe, scoped-optional), base and head output byte-identical (diff exit 0):

  • endpoints.item on: all four mounts answer 401 UNAUTHENTICATED with zero protocol calls and zero provider calls, and all four server-visible handlers are the umbrella's wrapper.
  • endpoints.item: false: 150 → 126 routes; the two published mounts are gone and the two state mounts remain (the state read is in no per-family switch), still 401.

6. The guard ablation (the plan's shapes for 13e-state and 13e-published, four nested ablation-replace anchors, none occurring inside its own replacement): the umbrella stashes its realRouteManager captured above the swap; objectStateHost carries THAT as its routeManager (13e-state); itemPublishedHost carries it too, and registerMetaItemPublishedRoute replaces the scope's registrar with a module-local one that honours the same switch but registers on that host member (13e-published).

  • Ablation: the anonymous state request is SERVED (200, the provider called once) and the anonymous published request reaches the protocol (501 NOT_IMPLEMENTED, one protocol call); none of the four handlers is the wrapper. Under endpoints.item: false the published mounts are still gone.
  • Standing pins under the ablation: Test Files 2 failed | 5 passed (7), Tests 17 failed | 135 passed (152): meta-type-read-capability.test.ts red 16 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 /published read shape for the four datasource-family type spellings, for member, other-grant and author, plus each spelling's existing-vs-absent byte identity), and meta-state-route-engine-outage.test.ts red once ("the route is behind the anonymous-deny gate"), so the state read does have a standing anonymous pin (the plan read none). rest-meta-auth.test.ts, meta-type-write-capability.test.ts, rest-config-mount-table.pin.test.ts, meta-route-registration-order.test.ts and meta-disabled-package-doors.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 five instance methods and the provider field are planted on the server, and the static on the class, before registerRoutes(), as recorders; four request shapes are driven over the two moved routes, then everything is planted again and the shapes are driven again.

  • Head (MEASURE lines byte-identical to base): all 7 members, the provider field included, are reached late after the re-plant, early calls after re-plant: 0.
  • Ablation (a), the getter: objectStateHost's getter turned into a value copied at host-build time gives early calls after re-plant: 2 ["early:objectQLProvider"], exit 1.
  • Ablation (b), a closure: resolveMetadataService: this.resolveMetadataService.bind(this) gives early calls after re-plant: 2 ["early:resolveMetadataService"], exit 1.
  • Restored after each: 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-object-state-routes.ts in REST_SERVER_REGISTRAR_FILES (length 17 → 18) and in REST_SERVER_META_ROUTE_FILES (4 → 5); meta-item-history-routes.ts was already on both, and its comments now name the published read.

reader reading change
execctx-consumer-census.test.ts 62 sites / 145 mentions, unchanged Neither moved door resolves a caller itself, and neither host names a resolveExecCtx member. Still seventeen forwarders: (18 − 1) + 4 − 4, the published read counted as the history module's second registrar in EXTRA_MOVED_REGISTRARS and in MOVED_REGISTRARS_READING_NO_EXECCTX (the discovery module's precedent), the new module in the latter
meta-draft-read-door-census.test.ts 8, unchanged No draft switch moved
rest-server-query-number-census.test.ts 9, unchanged No numeric coercion moved
rest-server-canonical-query-ast.test.ts (repo project) 4, unchanged The new module's floor is 0
rest-server-docblock-position.test.ts 65 → 70 over seventeen The new module carries 3 blocks; the history module 3 → 5 (the published host interface and function); rest-server.ts keeps its 161
ui-view-route-identity / -tenancy measurement tests this.enforceAuth( 60, this.resolveExecCtx( 79, unchanged Neither host literal forwards either
objectql-slot-consumer-census.test.ts five consumers, unchanged, over four files SLOT_FILES gains both modules; the getter pin (SLOT_FILES.length - 1) reads 3 (batch, state, published); HOST_MEMBER_TYPE is 1 in each module; the comment-dropping CONTROL reads the retired-spelling comment where it now lives, meta-object-state-routes.ts, with a positive read of that same file beside it
meta-state-route-engine-outage.test.ts comment only Its two pointers to the dynamic import() now name meta-object-state-routes.ts
dogfood authz-conformance.test.ts realtime tripwires 0 over the list Length 17 → 18
dogfood authz-probe-blind-spot.census.ts 70 / 19 / 51, unchanged The state module's control this.routeManager.register( = 1; the history module's registerPerItemRoute( 5 → 6; whole-population registerPerItemRoute( stays 8 (0 + 2 + 6); this.routeManager.register( stays 63. One control re-keyed, not relaxed: the inner method now calls the history module twice, so .call( inside it reads 6 against a subset of 5 files; it is recorded as REST_SERVER_META_ROUTE_FILES.length + 1, so a /meta module called without joining the subset, or a subset entry no longer called, still moves it
scripts/check-route-envelope.mjs (MODULES only) new module 0 / 0; history module stays 5 / 1; rest-server.ts stays 2 / 2 The six moved response sites (three each) are all nested envelopes or served documents
scripts/check-undeclared-dep-imports.mjs (LEDGER) 1 row, evidence intact The @objectstack/objectql optional-runtime-probe row's file follows the dynamic import to meta-object-state-routes.ts; its why now says "query-multiplicity.ts and rest-server.ts duck-type the same seam" (was "the rest of rest-server.ts")
scripts/adr-anchors/packages__rest__src__meta-object-state-routes.ts.json (new) decision letters 1783 → 1782 at the move → 1785 The state read's ADR-0020 D3.3 left the anchored surface silently; the anchor puts the module on it (its header, its moved body and the anchor's invariant each cite D3.3)
content/docs/permissions/system-context.mdx not edited check-system-context-census reads OK before and after (142 sites, 136/136 symbols, 159 anchors): neither moved door holds an isSystem read

Red before re-point, measured. At the move commit 1ed1f29bc (list not grown): the slot census Tests 4 failed | 156 passed (160) over its eight-file set; dogfood Tests 2 failed | 45 passed (47) (population 69 against 70, the state read's site out of reach; a control off); check:route-envelope exit 1 (meta-object-state-routes.ts NOT DECLARED); check:undeclared-dep-imports exit 1 (the row stale, the import unledgered); check-adr-anchors exit 0 at 1782 (the silent drop the anchor repairs); check-system-context-census exit 0, unchanged. At 7684c634e (list grown, readers at base text): rest local Tests 11 failed | 151 passed (162), rest repo Tests 2 failed | 105 passed | 18 skipped (125), dogfood Tests 1 failed | 46 passed (47). At 7c625ffe7: Tests 162 passed (162), Tests 107 passed | 18 skipped (125), Tests 108 passed (108). (Dogfood authz-conformance.test.ts could not load @objectstack/verify before the whole-workspace build at the first two commits: NOT MEASURED there, measured green at 7c625ffe7.)

Tests and gates at the final head

At the final head f2c84cc6f (the merge), under os-verify-lock, every exit captured before any pipe:

  • pnpm --filter @objectstack/rest typecheck: exit 0 (check:test-typecheck: OK — … 0 file(s) / 0 error(s)).
  • rest local (whole project): exit 0, Test Files 295 passed (295), Tests 6051 passed | 326 skipped (6377) (436.87 s on a shared box).
  • rest repo (this diff edits one of its tests): exit 0, Test Files 5 passed (5), Tests 278 passed | 18 skipped (296).
  • pnpm --filter @objectstack/dogfood typecheck: exit 0. Dogfood authz-probe-blind-spot.test.ts + authz-conformance.test.ts: exit 0, Tests 108 passed (108).
  • runtime repo, narrowed to src/domains/meta-list-projection-parity.test.ts (the one runtime test that reads rest-server.ts from disk): exit 0, Tests 739 passed (739). The rest of runtime's and core's repo projects are CI's (Test Core).

Gates: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths) at f2c84cc6f derives 92 commands over this branch's 19 paths against merge base 2b7fc52c3 (1,444 changed lines, +942 / −502). All 92 ran sequentially: 92 exit 0. --ran: Run reconciliation — 92 derived, 92 run, 0 NOT-MEASURED, 0 UNRUN. Readings: check:route-envelope 29 route modules (9 conformant, 19 ratcheted, 1 exempt); check:adr-anchors 75 anchored files, 1785 decision letters; check-system-context-census OK (142 sites, 136/136 symbols, 159 anchors); check:undeclared-dep-imports 1 ledger row, evidence intact; check-issue-citations 49 judged across 4 files, 48 resolve and 1 resolves as a pull request; check:cross-package-test-inputs OK; check:nul-bytes OK; check:dual-build-cjs-loads 111 entry points across 69 packages. Beside the union: 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 17 changed .ts / .mjs files, exit 0 with no output; node scripts/pm/check-governed-merges.mjs --branch HEAD exit 0, 0 of 19 paths governed. The repo-wide pnpm lint is CI's.

origin/main has since moved to 117301705 (#24319, #24317: packages/adapters/hono, packages/platform-objects), no path in common with this diff; not merged again.

Acceptance notes

  • The moved comments are moved text and keep their deixis ("here", "below", "the dispatcher branch this mirrors"); both module headers say so rather than editing moved text.
  • rest-server-audit-org-scope.test.ts:23 says "the /published route's comment in rest-server.ts records that inventing org plumbing … would be a smuggled seam". The published read's comment has not said that since its [ADR-0131 D6] paragraph replaced it, so the pointer was already dead before this move; not edited here, carrier: none.
  • packages/spec/liveness/metadata_endpoints.json's endpoints.item evidence says the inner method's registerPerItemRoute gates "the per-item PUT/DELETE and the history family"; still true of the gate (the closure stays in the inner head), and the published read now joins those call sites in meta-item-history-routes.ts. The spec seat's file, still resolving, not edited (13d's note, carrier: none).
  • After this PR registerMetadataEndpointsInner is its head (the three bindings, registerPerItemRoute and the scope), six host literals with their six calls, and the tail comment on the retired compound twins. ADR-0076's D11 status line and its section 4 size note are the maintainer's Tier H carry, due now; nothing under docs/adr/ is touched here.

Generated by Claude Code

…ad out of rest-server.ts (#23050 slice 13e, move only)

G7 (`GET {metaPath}/object/:name/state/:field`) moves to the new
`meta-object-state-routes.ts` as `registerMetaObjectStateRoute`; G8
(`GET {metaPath}/:type/:name/published`) joins `meta-item-history-routes.ts`
as `registerMetaItemPublishedRoute`. Each is called at its old position in
`registerMetadataEndpointsInner` with a host literal built there and the one
existing scope. The registrar list and its readers are re-pointed in the
next commits.

Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T
Co-authored-by: Claude <noreply@anthropic.com>
…3050 slice 13e)

The list and its named /meta subset gain the object state-machine read's
module; its readers are re-pointed in the next commit.

Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T
Co-authored-by: Claude <noreply@anthropic.com>
…ed reads (#23050 slice 13e)

The registrar-list readers learn the new module (length 17 -> 18, sums
unchanged), the objectQLProvider slot census reads its two moved consumers
where they now live, the dogfood blind-spot census keeps 70 / 19 / 51 with
the state module's direct control and the history module's per-item control
5 -> 6, the route-envelope table declares the new module 0 / 0, the
undeclared-dep ledger row follows the dynamic objectql import, and an ADR-0020
anchor restores the decision-letter count the move dropped.

Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T
Co-authored-by: Claude <noreply@anthropic.com>
…lished read move (#23050 slice 13e)

Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T
Co-authored-by: Claude <noreply@anthropic.com>
…state-published

No path in common with this branch.

Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/xl documentation Improvements or additions to documentation tests tooling labels Oct 18, 2026
@github-actions

github-actions Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/rest, touching 42 documentable anchor(s).

13 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/api/client-sdk.mdx (via NOT_IMPLEMENTED (literal, a string literal in registerMetaItemPublishedRoute; a string literal in registerMetaObjectStateRoute; a string literal in registerMetadataEndpointsInner), diffItem (sdk, the bare tail of client method meta.diffItem, bound to GET /api/v1/meta/:type/:name/diff), meta.diffItem (sdk, the route ledger binds it to GET /api/v1/meta/:type/:name/diff, selected by route anchor /:type/:name/diff))
  • content/docs/api/data-api.mdx (via NOT_IMPLEMENTED (literal, a string literal in registerMetaItemPublishedRoute; a string literal in registerMetaObjectStateRoute; a string literal in registerMetadataEndpointsInner))
  • content/docs/api/error-catalog.mdx (via NOT_IMPLEMENTED (literal, a string literal in registerMetaItemPublishedRoute; a string literal in registerMetaObjectStateRoute; a string literal in registerMetadataEndpointsInner))
  • content/docs/api/wire-format.mdx (via NOT_IMPLEMENTED (literal, a string literal in registerMetaItemPublishedRoute; a string literal in registerMetaObjectStateRoute; a string literal in registerMetadataEndpointsInner), /meta/object/:name (route, a path literal in a comment in registerMetaObjectStateRoute; a path literal in a comment in registerMetadataEndpointsInner))
  • content/docs/automation/flows.mdx (via NOT_IMPLEMENTED (literal, a string literal in registerMetaItemPublishedRoute; a string literal in registerMetaObjectStateRoute; a string literal in registerMetadataEndpointsInner))
  • content/docs/concepts/metadata-lifecycle.mdx (via /meta/object/:name (route, a path literal in a comment in registerMetaObjectStateRoute; a path literal in a comment in registerMetadataEndpointsInner))
  • content/docs/deployment/production-readiness.mdx (via /meta/object/:name (route, a path literal in a comment in registerMetaObjectStateRoute; a path literal in a comment in registerMetadataEndpointsInner))
  • content/docs/kernel/contracts/metadata-service.mdx (via getPublished (sdk, the bare tail of client method meta.getPublished, bound to GET /api/v1/meta/:type/:name/published; the bare tail of client method meta.getPublished, bound to GET /meta/:type/:name/published))
  • content/docs/kernel/runtime-services/sharing-service.mdx (via NOT_FOUND (literal, a string literal in registerMetaItemPublishedRoute; a string literal in registerMetaObjectStateRoute; a string literal in registerMetadataEndpointsInner))
  • content/docs/permissions/authentication.mdx (via NOT_IMPLEMENTED (literal, a string literal in registerMetaItemPublishedRoute; a string literal in registerMetaObjectStateRoute; a string literal in registerMetadataEndpointsInner))
  • content/docs/protocol/kernel/http-protocol.mdx (via /meta/object/:name (route, a path literal in a comment in registerMetaObjectStateRoute; a path literal in a comment in registerMetadataEndpointsInner))
  • content/docs/protocol/objectql/state-machine.mdx (via /meta/object/:name (route, a path literal in a comment in registerMetaObjectStateRoute; a path literal in a comment in registerMetadataEndpointsInner), /meta/object/:name/state/:field (route, a path literal in a comment in registerMetaObjectStateRoute; a path literal in a comment in registerMetadataEndpointsInner), /object/:name/state/:field (route, a path literal in a comment in REST_SERVER_META_ROUTE_FILES; a path literal in a comment in registerMetadataEndpointsInner; a path literal in a comment on a changed line; a path literal in registerMetaObjectStateRoute; a path literal in registerMetadataEndpointsInner; bridged from symbol objectQLProvider — its route source's handler names it))
  • content/docs/ui/forms.mdx (via /meta/object/:name (route, a path literal in a comment in registerMetaObjectStateRoute; a path literal in a comment in registerMetadataEndpointsInner))

⛔ 8 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v15.mdx (via RestProtocol (symbol, a top-level type))
  • content/docs/releases/v17/17-0.mdx (via NOT_IMPLEMENTED (literal, a string literal in registerMetaItemPublishedRoute; a string literal in registerMetaObjectStateRoute; a string literal in registerMetadataEndpointsInner), getLegalNextStates (sdk, the bare tail of client method meta.getLegalNextStates, bound to GET /api/v1/meta/object/:name/state/:field; the bare tail of client method meta.getLegalNextStates, bound to GET /meta/object/:name/state/:field), meta.getLegalNextStates (sdk, the route ledger binds it to GET /api/v1/meta/object/:name/state/:field, selected by route anchor /object/:name/state/:field; the route ledger binds it to GET /meta/object/:name/state/:field, selected by route anchor /object/:name/state/:field), /meta/object/:name (route, a path literal in a comment in registerMetaObjectStateRoute; a path literal in a comment in registerMetadataEndpointsInner))
  • content/docs/releases/v17/17-1.mdx (via /:type/:name/diff (route, bridged from symbol metaItemReadGate — its route source's handler names it; bridged from symbol metaTypeSingular — its route source's handler names it; bridged from symbol resolveObjectMasker — its route source's handler names it), /meta/object/:name (route, a path literal in a comment in registerMetaObjectStateRoute; a path literal in a comment in registerMetadataEndpointsInner))
  • content/docs/releases/v17/17-2.mdx (via getLegalNextStates (sdk, the bare tail of client method meta.getLegalNextStates, bound to GET /api/v1/meta/object/:name/state/:field; the bare tail of client method meta.getLegalNextStates, bound to GET /meta/object/:name/state/:field), meta.getLegalNextStates (sdk, the route ledger binds it to GET /api/v1/meta/object/:name/state/:field, selected by route anchor /object/:name/state/:field; the route ledger binds it to GET /meta/object/:name/state/:field, selected by route anchor /object/:name/state/:field))
  • content/docs/releases/v17/17-3.mdx (via /:type/:name/published (route, a path literal in a comment in registerMetadataEndpointsInner; a path literal in a comment on a changed line; a path literal in registerMetaItemPublishedRoute; a path literal in registerMetadataEndpointsInner; bridged from symbol maskObjectDocument — its route source's handler names it; bridged from symbol metaItemReadGate — its route source's handler names it; bridged from symbol metaTypeSingular — its route source's handler names it; bridged from symbol objectQLProvider — its route source's handler names it; bridged from symbol resolveObjectMasker — its route source's handler names it), /:type/:section/:name/published (route, a path literal in a comment in registerMetaItemPublishedRoute; a path literal in a comment in registerMetaObjectStateRoute; a path literal in a comment in registerMetadataEndpointsInner), /meta/:type/:name/published (route, a path literal in a comment in registerMetaItemPublishedRoute; a path literal in a comment in registerMetadataEndpointsInner))
  • content/docs/releases/v17/17-5.mdx (via NOT_IMPLEMENTED (literal, a string literal in registerMetaItemPublishedRoute; a string literal in registerMetaObjectStateRoute; a string literal in registerMetadataEndpointsInner), /:type/:name/diff (route, bridged from symbol metaItemReadGate — its route source's handler names it; bridged from symbol metaTypeSingular — its route source's handler names it; bridged from symbol resolveObjectMasker — its route source's handler names it))
  • content/docs/releases/v17/17-6.mdx (via NOT_IMPLEMENTED (literal, a string literal in registerMetaItemPublishedRoute; a string literal in registerMetaObjectStateRoute; a string literal in registerMetadataEndpointsInner))
  • content/docs/releases/v17/17-7.mdx (via NOT_IMPLEMENTED (literal, a string literal in registerMetaItemPublishedRoute; a string literal in registerMetaObjectStateRoute; a string literal in registerMetadataEndpointsInner), /meta/object/:name (route, a path literal in a comment in registerMetaObjectStateRoute; a path literal in a comment in registerMetadataEndpointsInner))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 2 cross-cutting symbol(s) contributed no route anchor: routeManager (19 routes), resolveProtocol (26 routes)
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 18 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 33f700b87bd1e0c9a610418b0e573c3bf3958abf → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 013d5a9c46dc69d1cb9cd1d87bb62effd9fd2e28 — the merge of head 30a3bccfdc6792d37ec3c493c4096e1f3b335d5e into base 33f700b87bd1e0c9a610418b0e573c3bf3958abf, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 013d5a9c46dc69d1cb9cd1d87bb62effd9fd2e28 && git checkout 013d5a9c46dc69d1cb9cd1d87bb62effd9fd2e28
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 33f700b87bd1e0c9a610418b0e573c3bf3958abf 30a3bccfdc6792d37ec3c493c4096e1f3b335d5e && git checkout -B drift-repro 33f700b87bd1e0c9a610418b0e573c3bf3958abf && git merge --no-ff 30a3bccfdc6792d37ec3c493c4096e1f3b335d5e

node scripts/docs-audit/affected-docs.mjs --json 33f700b87bd1e0c9a610418b0e573c3bf3958abf

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 33f700b87bd1e0c9a610418b0e573c3bf3958abf → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 — REWORK (patch round 1: a split-off Tier H anchor PR)

domain:cli seat 1 (seat post #6024) · zhuangjianguo · session session_01SYEJqDL3NXxrJRBVqaMu9T · 2026-10-18T13:16Z · on head f2c84cc6f · #23050 sub-slice 13e (claim 6249541908, report 6250320763). This is the seat's own review at the default tier (Clause-②: no, no packages/spec path), read against GitHub, not the report.

The move is accepted as it stands. It was measured here independently with git's moved-line detection (--color-moved=plain --color-moved-ws=allow-indentation-change, merge base 2b7fc52c3):

  • 470 lines leave rest-server.ts and meta-item-history-routes.ts, and 435 of them are detected as moved: G7's 153 and G8's 282.
  • The 35 not detected are module and import comments, five import names, and the one ruled receiver (RestServer.metaTypeSingular → this.metaTypeSingular).
  • This agrees with the report's per-handler identity (688/688), the byte-identical .d.ts, and the 39-name export list.
  • Every reader the plan named moved in this PR. The three scripts/** rows are declared on [PM seat] domain:spec — ⏳ vacant #6017 (6249549069).

One item blocks it, and this PR cannot fix it.

  • CI is red: Lint · docs & code guards → ADR symbol anchors resolve (job 117683703796): "[unresolved-symbol] docs/adr/0119-plugin-reachable-transactions-and-honest-atomic-batch.md:118 packages/rest/src/rest-server.ts#NOT_IMPLEMENTED — NOT_IMPLEMENTED has no declaration site or string-literal token in packages/rest/src/rest-server.ts."
  • The anchor names "the cross-object /batch route's existing precedent". That route has lived in packages/rest/src/batch-routes.ts (:177, code: 'NOT_IMPLEMENTED') since slice 2 (a647783d4, PR refactor(rest): move registerBatchEndpoints into batch-routes.ts (#23050 slice 2) #23642).
  • The anchor has resolved since then only on G7's and G8's 501 tokens, which this move takes out of the file. It was stale already; this PR exposes it.
  • The checker names the remedy: "fix the anchor", never the exemption, which is maintainer-only.

The route:

  • The one token goes to packages/rest/src/batch-routes.ts#NOT_IMPLEMENTED, in its own PR on a second branch of this claim (amended in place). docs/adr/** is Tier H, and a mixed diff would put this 1,444-line move behind a human approval, so the anchor gets its own PR.
  • That PR is a draft with a ## 维护者速读(草稿) section. The seat finalises the record and requests review from both authorised approvers.
  • This PR lands after it, once a merge of main re-runs the lint lane on this head. ⛔ No NOT_IMPLEMENTED token is kept in rest-server.ts to keep the anchor resolving.
  • Any red Test Core shard on this head is folded into this round.

Out-of-scope notes: the three carrier: none notes stay in the PR's Acceptance notes. The fourth (ADR-0076 D11's status line and §4 size note) is the maintainer's Tier H carry, due once this slice lands; nothing is filed.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · domain:cli seat 1 (seat post #6024) · zhuangjianguo · session session_01SYEJqDL3NXxrJRBVqaMu9T · 2026-10-18T14:43Z · on head 30a3bccfd · #23050 sub-slice 13e (claim 6249541908, amended in place; report 6250320763; patch round 6250559765). This is the seat's own review at the default tier (Clause-②: no), read against GitHub, not the report.

  1. The move is accepted, as recorded in REWORK 6250370051:
    • git's moved-line detection finds 435 of the 470 deleted lines moved: G7's 153 and G8's 282.
    • The other 35 are comments, five import names, and the one ruled receiver.
    • This agrees with the report's 688/688 per-handler identity, the byte-identical .d.ts, and the 39-name export list. Every reader the plan named moved in this PR.
  2. The blocker is resolved outside this PR, as routed:
  3. This head: 30a3bccfd is GitHub's update-branch merge of main (33f700b87) into f2c84cc6f, run through the relay op pr_update_branch, so no history was rewritten.
    • Read before the merge: no file in common between main's side and this PR's side since the merge base 2b7fc52c3, and git merge-tree clean.
    • The PR's own surface is still the reviewed 19 files, +942 / −502.
  4. Gates:
    • On f2c84cc6f, 41 check-runs completed: 33 success, 6 roster skips, and the anchor lane plus its aggregate red.
    • On this head CI is re-running at this stamp. ⛔ Not ready until every check on it is green.
  5. Deviations accepted: those listed in the report: the five imports, the dogfood control re-keyed to the list length + 1, the execctx census rows, the outage test's comment pointers, and the LEDGER prose. Also the split-off Tier H PR on the claim's second branch.
  6. Out of scope: the three carrier: none notes stay in the PR's Acceptance notes. ADR-0076 D11's status line and §4 size note are the maintainer's Tier H carry, due now that the /meta series completes; they are reported in the seat's round report. Nothing is filed.
  7. Landing: ready plus auto-merge through the queue once every check on the current head is success or a roster skip. The PR is Part of #23050, so the card's state is settled in the landing record.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 18, 2026 15:11
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 18, 2026 15:11
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 18, 2026
Merged via the queue into main with commit d1f082d Oct 18, 2026
42 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-23050-s13e-meta-object-state-published branch October 18, 2026 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/xl tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants