Repository navigation
[maintainer] refactor(rest): split packages/rest/src/rest-server.ts (13,701 lines, 70 commits in 30 days) along its register*Endpoints seams, one move-only slice per PR, /meta after #22877 stage 2 #23050
Description
Filing gate ③: a task the maintainer dispatched, quoted verbatim below.
Filed by domain:cli seat 2 (#22648) · os-steve · session session_01VoSxBQujKLZKPwK2u5ehQ6, on the maintainer's instruction in that session's chat. ⛔ Not a claim.
The maintainer's words, verbatim: 「这个文件经常改,为什么不分拆?rest-server.ts」. After the seat's measurement, the maintainer chose 「立卡,等 #22877 后 (推荐)」, an option the seat put as:
立一张 domain:cli 重构卡分片做。/meta 那块等 engine 车道的 #22877 第 2 阶段合入后再拆,免得双方重做合并;不碰 /meta 的区段可以先拆。每片只搬代码、路由表前后一致、门禁和文档锚点同 PR 迁完。
Reader who acts: the domain:cli seat (packages/rest is this lane's), one dispatch per slice.
Measured (on origin/main 38d98d8d83, 2026-10-12)
- Size and churn: 13,701 lines. 24 commits in 7 days, 70 in 30 days, 321 in total.
git blame --since=2026-09-12attributes 3,077 of its lines (22%) to the last 30 days.- Other lanes edit it too: engine seat 2's [finding] email_template: a Studio save of the same template in a second locale replaces the first locale's overlay at the next boot (sys_metadata keeps one overlay row per type and name) #22877 stage 2 declared into this lane today (
6123998192).
- Structure: one
RestServerclass with about 20register*Endpointsmethods, one per domain, over a block of shared private helpers. The hottest sections in the last 30 days:
| section | lines | lines from the last 30 days |
|---|---|---|
registerMetadataEndpointsInner (/meta) |
2,911 | 959 |
class head + shared helpers (enforceAuth, resolveExecCtx, computeExecCtx, metaListSource, translateMeta*, …) |
2,698 | 722 |
| module-level helpers before the class | 1,879 | 481 |
registerDataActionEndpoints |
1,181 | 174 |
registerFormEndpoints |
444 | 118 |
registerBatchEndpoints |
644 | 76 |
- What reads it by path (the cost of a split):
- 16
scripts/files, includingcheck-route-envelope,check-single-authz-resolver,check-system-context-census,check-meta-type-normalized,check-rest-log-declaredandcheck-durability-degradation-log-level; - the ADR anchor file
scripts/adr-anchors/packages__rest__src__rest-server.ts.json; - 41 files under
content/anddocs/; - 334 test files that mention
rest-server.
- 16
The ask
- Split along the existing seams, one area per PR. Each slice is move-only: no handler's logic changes.
- Shared state stays explicit: the moved routes reach the class's shared helpers through one named context object. ⛔ Not by a second copy of a helper, and ⛔ not by re-deriving one.
- Every slice proves it moved nothing:
RestServer.getRoutes()(and the route ledger the gates read) is byte-identical before and after;- every gate that reads
rest-server.tsby path, the ADR anchors and the docs anchors are migrated IN THE SAME PR and stay green. ⛔ A gate whose target moved must not go silently empty: the dead-pin shape this repo has paid for before (validateOrgAxisRedLines 读的 sharing-rule 键是 spec 拒收的:ADR-0105 D6 ① 在 criteria 路径上从不触发 #4984, fix(lint): 删除 validateOrgAxisRedLines 里 spec 合法 stack 到不了的四条分支 (#5009) #5018).
- Order:
- sections that do not touch
/metafirst (data actions, batch, forms, approvals, sharing and the like); registerMetadataEndpointsInneronly after [finding] email_template: a Studio save of the same template in a second locale replaces the first locale's overlay at the next boot (sys_metadata keeps one overlay row per type and name) #22877 stage 2 (claude/issue-22877-member-selector,domain:engineseat 2) lands, so neither side redoes a merge.
- sections that do not touch
- ⛔ No new gate. The proof is the existing gates staying green on the moved code, plus the route-table equality.
Not in this card
Any behaviour change in a handler. A design change to the shared helpers beyond giving them an explicit context. Splitting other large files.
Dedupe
MCP search_issues on this repository, closed included:
split rest-server.ts into modules large file refactor route registration per domain: 3 hits (The mirroredmakeRes()census in packages/rest names three files, but a fourth instance lives insiderest.test.tsitself — and it is the last uncheckedroute.handlercall in that file #15584, Route audit tranche 3: autonomously-mounted service routes (service-storage / service-i18n) — #3587 follow-up #3636, Route audit tranche 2: the @objectstack/rest surface (search / forms / reports / sharing / …) — #3563 follow-up #3587), none about splitting the file.rest-server.ts god file decompose extract: 0 hits.- CONTROL: the first query returns the
packages/restroute-audit cards (Route audit tranche 2: the @objectstack/rest surface (search / forms / reports / sharing / …) — #3563 follow-up #3587, Route audit tranche 3: autonomously-mounted service routes (service-storage / service-i18n) — #3587 follow-up #3636), so the instrument reaches the package.
Dedupe words: rest-server split; RestServer register endpoints modules; rest-server.ts refactor move-only.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 12, 2026
Triage: first grade,
tech-debt·priority:p2·domain:cli·area:api, intopm:queue. One move-only slice per dispatch./metawaits for #22877 stage 2Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-12T14:54Z. ⛔ Not a claim, ⛔ not a dispatch.domain:cliseat claims one slice at a time. Each claim names itsregister*Endpointssection and file surface. The card stays open across slices./metaslice (registerMetadataEndpointsInner) waits for [finding] email_template: a Studio save of the same template in a second locale replaces the first locale's overlay at the next boot (sys_metadata keeps one overlay row per type and name) #22877 stage 2 (dispatched,os-steve) to land.getRoutes()and the route ledger are byte-identical, and every gate, ADR anchor and docs citation that reads the file by path moves in the same PR.rest-server.tsgoes first. A slice claim reads the in-flight claims before it starts.packages/rest/src(domain:cli); rationale: one package, maintainer-directed.objectstack-fleet commentedon Oct 12, 2026
Claim: PM loop round 6 (#23050 slice 1:
registerDataActionEndpointsmoves out ofrest-server.ts, and the split's pattern is set) · 2026-10-12T22:57ZSession:
session_01VoSxBQujKLZKPwK2u5ehQ6Account:
os-steve(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23050-s1-data-action-endpointsWorktree:
objectstack-issue-23050-s1Domain:
domain:cliSeat:
domain:cli#2(seat post #22648)File surface (read on
origin/main36b2889cdd; stop on a breach and explain it in the report). This is a move-only slice, per triage6126748916:packages/rest/src/rest-server.ts: theregisterDataActionEndpointsmethod (about:9107-:10287, 1181 lines) leaves this file for ONE new module beside it underpackages/rest/src/. The class keeps only the call..d.tsof@objectstack/restdoes not change: no private member becomes public or protected onRestServer. If no move-only shape keeps it, stop and returnneeds_decision.scripts/adr-anchors/packages__rest__src__rest-server.ts.jsonand any other), docs citation and test that reads the moved lines by path or line moves in the same PR. ⛔ No gate is loosened to follow a move.skip-changeset). Otherwise the dev stops.register*Endpointssection;registerMetadataEndpointsInner(meta doors: the bundle-member selectormemberis dropped silently by the runtime dispatcher GET, by PUT, and by the by-name doors outside the ruling (no closed query sets); honour it or refuse it loudly #23072's doors; it waits for a later slice); any behaviour.Container & model:
L(1181 lines moved, every reader by path re-pointed, the pattern set),mode:subagent,model: default tier(dispatch-gates --tier --repo objectstack-ai/objectstack: "no path-derived mandate"). No contract-review face:Clause-②: no. A move with byte-identical routes, route ledger and.d.tsmoves no accept set, export orspeckey.check-governed-merges --testover the claimed paths: not governed.Clause-②: no
Responsibility: n/a — not a defect card
Thread-read: 6126748916
Serial constraints cleared:
rest-server.ts, have both landed. No in-flight claim namesrest-server.tsnow, and no open PR touches it (the file lists of all open PRs were read in this act).memberis dropped silently by the runtime dispatcher GET, by PUT, and by the by-name doors outside the ruling (no closed query sets); honour it or refuse it loudly #23072 (pm:queue) will edit thePUTand by-name/metadoors inregisterMetadataEndpointsInner. That region is disjoint from this slice, and whichever lands second mergesmain. They stay serial, not folded: this slice is move-only, and meta doors: the bundle-member selectormemberis dropped silently by the runtime dispatcher GET, by PUT, and by the by-name doors outside the ruling (no closed query sets); honour it or refuse it loudly #23072 changes behaviour.timeout(the hook runs unbounded) andloadTranslationsserves three retired translation keys — the #23029 family's closing card #23090 (packages/runtime/src/app-plugin.ts), and PR feat(verify): the parent-derived write reach family, runnable as os verify --parent-write-reach (#15953 slice 4) #23091 (packages/verify, waiting on hourly full run: red on main (CI) #23084).Generated by Claude Code
refactor(rest): move registerDataActionEndpoints' body to data-action…
refactor(rest): move the ServerScopedDataRequest alias with the data-…
test(rest): re-point the path readers of the moved data-action body (#…
test: re-point the remaining readers of the moved data-action lines (#…
objectstack-fleet commentedon Oct 13, 2026
os-dev-report
{
"issue": 23050,
"status": "done",
"branch": "claude/issue-23050-s1-data-action-endpoints",
"pr": "#23116",
"session": "session_01VoSxBQujKLZKPwK2u5ehQ6 (mode:subagent, the dispatching PM's session)",
"premise_still_valid": true,
"summary": "Slice 1 is done and move-only. The body of RestServer#registerDataActionEndpoints (1029 lines: clone, sync and async import, the import-job reads, undo and cancel, the streaming export) moved unedited, re-indented one level, to packages/rest/src/data-action-routes.ts as registerDataActionEndpoints(this: DataActionRouteHost, basePath). The class keeps the private method (name, JSDoc and position are in the published d.ts). Its body builds a DataActionRouteHost literal of the 13 members the body reads and calls the moved function with it. Measured at the final head: dist/index.d.ts and index.d.cts are byte-identical (sha256 991a8fc9...), getRoutes() and the ordered server registrations are byte-identical under 3 configs, the route ledgers are untouched, and every reader of the moved lines by path is re-pointed with sums unchanged. Draft PR #23116 is open, assigned to os-steve, labelled skip-changeset.",
"pattern": {
"members_read": "fields config :1959, routeManager :1960, cancelledImportJobs :2064 (readonly); methods resolveProtocol :2338, enforceAuth :2390, enforceApiAccess :2572, enforceExportPermission :2675, enforceImportTemplateGates :2736, resolveExecCtx :2785, resolveMessageTranslator :3890, translateMetaItem :3912, answerImportTemplate :10161, resolveSecurityService :10267 (line numbers at base 36b2889, found by an AST walk of the body).",
"shapes_compared": [
"A. Delete the method and keep only the call at registerRoutes. d.ts NOT identical: tsup emits private members with their JSDoc, so base dist/index.d.ts lines 3153-3163 (the docblock plus 'private registerDataActionEndpoints;') would go.",
"C. The class passes itself as a narrow interface: registerDataActionEndpoints.call(this as unknown as DataActionRouteHost, basePath). Measured at 5a05b4b via scripts/ablation-replace.mjs, auto-restored, 'git diff HEAD' empty after. tsc --noEmit exits 2 with exactly 5 TS6133 errors, because root noUnusedLocals stops seeing the reads made through the cast: cancelledImportJobs, enforceExportPermission, enforceImportTemplateGates, resolveMessageTranslator, answerImportTemplate. The tsup DTS build fails too (exit 1). Not viable without the class reading every member some other way.",
"B (chosen). The class builds a host literal. tsc exits 0 and the d.ts is byte-identical. There is no cast and no visibility change. Every interface member is typed as an indexed access (RestServer['m']), so a misspelled member is a compile error. Methods are passed as late-bound closures (...a) => this.m(...a), so test doubles and spies on the instance or prototype still take effect. Fields are passed by value, which is valid here only because cancelledImportJobs is readonly and config/routeManager are read only during registration; a later slice whose body reads a reassignable field at request time passes a getter, checked per field."
],
"rule_for_later_slices": "(1) AST-list the this.X members the body reads. (2) Move the body to a new FILE-routes.ts as 'export function registerXEndpoints(this: XRouteHost, basePath)', unedited and re-indented. (3) Declare XRouteHost with one 'm: RestServer[m]' member per member read. (4) Keep the private method, with its JSDoc, as a host literal plus .call. (5) export the module-level helpers it needs from rest-server.ts. Exported functions and constants leave the d.ts unchanged; an exported TYPE ALIAS does not (measured: one blank line), so a type alias moves with the body instead. (6) Re-point every reader whose reading includes a moved line.",
"deviation_from_claim_range": "The claim's :9107-:10287 (1181 lines) covered three members. Moved: registerDataActionEndpoints' body, 9107-10137. Left in place: answerImportTemplate (10139-10253); it is section-private, but its name and JSDoc are pinned in the d.ts and the tests spy on it on the instance, so it is reached through the host. Also left in place: resolveSecurityService (10255-10281), a shared helper with 4 callers in the class head. Moved in addition: the ServerScopedDataRequest alias block (base 311-372), forced by the d.ts measurement."
},
"dts_identity": "packages/rest/dist/index.d.ts and index.d.cts are byte-identical to base 36b2889: sha256 991a8fc9cae955b56745db0b3b978a60d0d3a8f918a3a05e39ee8176601e5998 for both, before and after; cmp is silent at 5a05b4b after a fresh build. The ESM bundle's export list is unchanged (34 names), and the CJS and ESM bundles load with 34 exports each. The JS bundle bytes differ (code moved within it).",
"route_identity": "tsx boots a source RestServer on a recording mock server. getRoutes() (functions recorded as arity) and the ordered server.get/post/... calls are byte-identical base vs 5a05b4b, 6 of 6 dumps. default: routes sha256 1e1859c0ff1641540875991fc175e5378345cc7d529068a21afd9073664babd2, calls bc7196b91265731a25ef300bf9769a2919e340d2a3eaa1a1866448a7213fef8e (75 routes, 9 data-action). scoped-optional: d79275a35e12ac7c409fe0e4ffbf9e4a6685263f1b122e3cedeb932724d74b09 / 2fa050c0d6e01affa994c2bf11a1b4abe033c48814aabde114d076deb1ad3650 (150, 18). scoped-required: 066d85bfcdefd48e4c393abcf99f343d7fba8dd5947baf6af809656bdcaa5fc6 / 7595d734a01438a7d3b30649f7b9c71bcd4caa5976466fd5e243dcb4808775e7 (75, 9). Route ledgers (rest-route-ledger.ts, runtime route-ledger.ts) are untouched, and check:route-ledger-census output is identical base vs head.",
"moved_block_accounting": "git diff --color-moved=plain --color-moved-ws=allow-indentation-change 36b2889 HEAD over the two source files: 1098 deleted and 1115 added lines are detected as moved. Without ws allowance only 232/209 are, because of the re-indent. Non-moved hunks in rest-server.ts: (1) the stub body, 20 lines (comment + host literal + .call). (2) The new import line plus a 1-line comment, replacing the runImport/prepareImportRequest import lines. (3) A 3-line pointer comment where the ServerScopedDataRequest alias was. (4) 'export' added to 12 declarations (UNDECLARED_WHOLE_NUMBER_PARAM, readDeclaredQueryNumber, IMPORT_JOB_OBJECT, IMPORT_JOB_UNDO_MAX_ROWS, newImportJobId, capImportResults, parseUndoLog, importJobUndoable, importJobToProgress, importJobToSummary, rowsToCsv, createXlsxStream). (5) Removal of the imports the move left unused: ListImportJobsRequestSchema; IMPORT_JOB_MAX_ROWS and its 3-line comment; referenceFieldNames, formatRowForJson, cellFontColor, readTemplateMode, runImport, prepareImportRequest. (6) The [#20061] schema-import comment changed from 'three doors' to 'two of the three' plus a pointer (4 lines). Non-moved hunks in data-action-routes.ts: the module docblock, the imports, the 4-line note plus 'export' on the moved alias line, the DataActionRouteHost interface with its docblock, and the function docblock plus signature.",
"readers_repointed": [
"scripts/check-route-envelope.mjs: data-action-routes.ts is declared dialectOnly, ratchet #9559, stringError 13, siblingCode 15, measured by the gate. rest-server.ts stringError 39->26 and siblingCode 54->39, both noted as a MOVE. The sums are unchanged. --self-test passes.",
"packages/rest/src/execctx-consumer-census.test.ts: sites keyed file:line over both files (62 = 53+9; 16 caught / 46 bare unchanged). Stack attribution steps over the one host-literal forwarder frame, whose line is pinned (FORWARDER_LINE > 0). Mentions 77->81: the +4 are the forwarder and the interface member, not consumers. catchArguments reads both files.",
"packages/rest/src/rest-server-query-number-census.test.ts: coercion sites over both files. The ledger is unchanged, because keys are route/function anchors, not files.",
"packages/rest/src/rest-server-canonical-query-ast.test.ts: CENSUS rest-server.ts minQuerySlots 4->1, plus data-action-routes.ts 3 under the same door rule. The two by-name literals are asserted on the new module.",
"packages/rest/src/ui-view-route-identity.measurement.test.ts and ui-view-route-tenancy.measurement.test.ts: the whole-file spelling reverse checks count over both files (enforceAuth 49, resolveExecCtx 63, enforceEnvironmentOwnership 1).",
"packages/rest/src/rest-server-docblock-position.test.ts: the no-stacked-docblock rule also reads data-action-routes.ts, floor 4 (its measured count), because the alias docblock moved there.",
"packages/qa/dogfood/test/authz-probe-blind-spot.census.ts: the rest-server row's registration population reads both files, so 70/19/51 is unchanged; the 9 moved routes are still RestServer's and all are in the blind spot. New control 'data-action-routes.ts: this.routeManager.register(' = 9. The 'this.routeManager.register(' control stays 63. enforceAuth 57->61 re-anchored: the 4 new occurrences are the seam, and no call site was added.",
"docs/qa/platform-checklist/areas/records-forms.json: the clone item's source anchor rest-server.ts#registerDataActionEndpoints is now data-action-routes.ts#registerDataActionEndpoints."
],
"readers_examined_zero_contribution": "Measured 0 matches from the moved lines in each: the dogfood realtime TRIPWIREs on rest-server.ts (0 mechanics hits, 0 route hits in the module); objectql-slot-consumer-census (0 provider reads; a new one would need a host-literal entry in rest-server.ts, where it reads); meta-draft-read-door-census (0 draft switches); auth-gate-allowlist-fault-window, execctx-authz-input-seam-reachability and runtime meta-list-projection-parity (they slice other members). These gates' output is identical base vs head except +1 scanned file: check-durability-degradation-log-level, check-system-context-census, check-single-authz-resolver, check-undeclared-dep-imports, check-dispatcher-error-vocabulary, check-meta-type-normalized. The ADR anchor packages__rest__src__rest-server.ts.json (ADR-0045 filterAppForUser) is unaffected. No path:line citation in the repo points into the moved ranges (base 9107-10137, 311-372).",
"tests": "At 5a05b4b, all through os-verify-lock. pnpm --filter @objectstack/rest test: 'Test Files 275 passed (275)' before (36b2889) and after; Tests 5759 passed | 326 skipped (6085) before, 5761 passed | 326 skipped (6087) after (+2 = the docblock pin's new describe); VERDICT command-exit 0. pnpm --filter @objectstack/rest test:repo: 'Test Files 5 passed (5)' before and after; Tests 209|1 skipped (210) before, 213|2 skipped (215) after (+5 = the canonical-query-ast census's new file entry); VERDICT command-exit 0. pnpm --filter @objectstack/rest typecheck: VERDICT command-exit 0 (tsc --noEmit plus check:test-typecheck: 0 files / 0 errors). dogfood test/authz-probe-blind-spot.test.ts plus test/authz-conformance.test.ts: 2 files, 92 passed, VERDICT command-exit 0. Before the re-point, the census was red (expected 61 to be 70). Before the re-points, the rest suite showed the readers red: Tests 8 failed (execctx census x4, query-number census x2, ui-view x2); all green after. Shape-C measurement: ablation-replace mutation landed (blob d5a5f618619b -> c0caf3fe736f), tsc exit 2 with 5 x TS6133, build exit 1. Restored: blob == HEAD, 'git diff HEAD' empty; then rest was rebuilt and the d.ts is identical again. Lint, proven narrowing: eslint --no-inline-config --format json over the 10 touched lintable files gives 10 results, 0 errors, 0 warnings. ESLint isPathIgnored is false for all 10, and calculateConfigForFile gives 2-6 rules each. There is no parserOptions.project (no type-aware lint), and the config's only file inputs (eslint.config.mjs, scripts/slot-lookup-baseline.json, scripts/query-options-erasure-baseline.json) are untouched, so no untouched file's verdict can move.",
"gates": {
"head": "5a05b4bde6",
"derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths: 79 commands, against PM's 57 at dispatch. It grew with the readers touched: declaration-mirrors, scripts-symbol-anchors, self-test-wired, the check:liveness family, platform-checklist, pm-dispatch-gates, type-check-coverage/debt and others.",
"reconciliation": "--ran with exit annotations: 'Run reconciliation — 79 derived, 78 run, 1 NOT-MEASURED, 0 UNRUN.' 77 exit 0.",
"red_not_mine": "pnpm check:platform-checklist exit 1: the same 8 findings on base 36b2889 (metadata-protocol protocol.ts #anonymousFormIntake*/#envWideRawViewRows/#countable, service-storage #canEdit, the attachments-storage anchor floor). None are in records-forms.json, and the output is identical base vs head.",
"not_measured": "check:dual-build-cjs-loads: NOT MEASURED, reason: PREREQUISITE NOT MET (exit 3; 19 workspace packages have no dist/ in this container; a whole-workspace build queued twice behind other agents' runs, VERDICT queue-timeout exit 99). Narrow stand-in measured: packages/rest/dist/index.cjs and index.js both load, 34 exports each. CI runs the gate over a full build.",
"per_command": [
"node scripts/check-ci-filter-parity.mjs => exit 0 | OK: all 21 build input(s) turbo.json declares outside the packages (itself, 2 globalDependencies, and every
$TURBO_ROOT$input of a build Build Core runs) and all 11 script(s) th","node scripts/check-closing-keyword-parity.mjs => exit 0 | check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords and both measured separators; sweep found 5 file(s) carrying the grammar across 11128 tracked file(s), all regis",
"node scripts/check-closing-keyword-parity.mjs --self-test => exit 0 | ✓ check-closing-keyword-parity --self-test: 40 assertions, 5 mutations of the shipped parsers each driven to red.",
"node scripts/check-comment-mask-adoption.mjs => exit 0 | OK check:comment-mask-adoption — 14 private comment-stripper(s) under packages/** + examples/, all 14 recorded and every recorded row still reached (13 unconverted, 1 specimen). ",
"node scripts/check-comment-mask-adoption.mjs --self-test => exit 0 | PASS check-comment-mask-adoption --self-test (0 failure(s))",
"node scripts/check-comment-mask-corpus.mjs => exit 0 | ✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 8901 files, 0 disagree, 0 unparseable, 117.7s (comparator self-test: 26 cases pass).",
"node scripts/check-declaration-mirrors.mjs => exit 0 | OK: 10 hand-written declaration(s) agree with their modules on name, kind and required arity.",
"node scripts/check-declaration-mirrors.mjs --self-test => exit 0 | All 29 self-test cases passed.",
"node scripts/check-dts-emitted.mjs --self-test => exit 0 | check-dts-emitted self-test: all assertions passed.",
"node scripts/check-issue-citations.mjs => exit 0 | ✅ check-issue-citations: every citation this change adds resolves (or is a declared cross-repo reference).",
"node scripts/check-keyed-text-bounds.mjs => exit 0 | ✓ check:keyed-text-bounds: 112 .object.ts files under packages/ + apps/* + examples/** (walk is repo-wide; 0 outside), 117 object declarations, 242 declared index entries, 591 ",
"node scripts/check-keyed-text-bounds.mjs --self-test => exit 0 | PASS check-keyed-text-bounds --self-test (0 failure(s))",
"node scripts/check-platform-object-tenancy-census.mjs => exit 0 | ✓ platform-object tenancy census matches the tree: 84 platform-namespace objects, 49 in the machinery's reach, 35 outside it, every exclusion explained by a declaration on its own ",
"node scripts/check-platform-object-tenancy-census.mjs --self-test => exit 0 | ✓ check-platform-object-tenancy-census self-test: all checks pass (84 objects, 35 outside the machinery)",
"node scripts/check-plugin-teardown-shape.mjs => exit 0 | ✓ check:plugin-teardown-shape: 75 Plugin implementation(s) across 8315 source(s) under packages/; every teardown-shaped method (stop / shutdown / close / dispose) sits beside a r",
"node scripts/check-plugin-teardown-shape.mjs --self-test => exit 0 | ✓ check-plugin-teardown-shape self-test: 48 cases pass (real pre-#10375 fixture reds, the repaired file and both delegating-alias directions stay green, every roster name reds, eve",
"node scripts/check-registry-log-declared.mjs => exit 0 | OK: 73 vitest-running package(s) walked, 10 selected as engine-booting, every one declares a recognised registry log level (debug/info/warn/error/silent).",
"node scripts/check-registry-log-declared.mjs --self-test => exit 0 | self-test OK: 17 cases + level-vocabulary read + population declaration + real-tree selection floor.",
"node scripts/check-rest-log-spy-declared.mjs => exit 0 | OK: 32 of 281 test file(s) beside packages/rest/src/log.ts observe the fault log, and every one of them declares its own OS_REST_LOG level.",
"node scripts/check-rest-log-spy-declared.mjs --self-test => exit 0 | check-rest-log-spy-declared self-test reached its verdict: 23 case(s), 0 failure(s).",
"node scripts/check-scripts-symbol-anchors.mjs => exit 0 | ✅ check-scripts-symbol-anchors: 3842 anchors across 285 scripts resolve — 52 symbol (52 declaration, 0 literal), 3790 file-level, 0 cross-repo, 1 exempt, 2 continuation. 0 line anc",
"node scripts/check-scripts-symbol-anchors.mjs --self-test => exit 0 | ✅ check-scripts-symbol-anchors --self-test: every finding class provoked, comment-prose projection wired, declined shapes counted not missed, allowance rows exact both ways, popula",
"node scripts/check-self-test-wired.mjs => exit 0 | ✓ check-self-test-wired: every one of the 233 script(s) CI runs that ship a
--self-testhas that self-test run by CI, and every one of the 169 root package.json alias(es) declari","node scripts/check-self-test-wired.mjs --self-test => exit 0 | check-self-test-wired --self-test: 3 live ledger row(s) verified, plus the comment mask, the right boundary, alias resolution, the declared-alias population and both audit directio",
"node scripts/check-self-test-workflow-commands.mjs => exit 0 | ✓ check-self-test-workflow-commands: no self-test CI runs prints a line the Actions runner would parse as a workflow command.",
"node scripts/check-self-test-workflow-commands.mjs --self-test => exit 0 | check-self-test-workflow-commands --self-test: both measured parse rules pinned (legacy form anywhere in a line, current form only at line start), the innocent-output and Perl-name",
"node scripts/check-system-context-census.mjs => exit 0 | check-system-context-census: OK — 131 elevation read sites in 20 packages across 59 files, living in 111 symbol(s); the page cites 124 symbol(s) against 124 required, over 147 anch",
"node scripts/check-system-context-census.mjs --self-test => exit 0 | check-system-context-census --self-test: all cases passed",
"node scripts/check-undeclared-dep-imports.mjs => exit 0 | ✓ check:undeclared-dep-imports: 81 workspace packages under packages/ + apps/** + examples/, 3048 non-test src files, 2551 @objectstack/* specifiers (0 assembled, not judged); ",
"node scripts/check-undeclared-dep-imports.mjs --self-test => exit 0 | PASS check-undeclared-dep-imports --self-test (0 failure(s))",
"node scripts/check-whole-set-label-write.mjs => exit 0 | ✓ check-whole-set-label-write: 0 violations — 351 file(s) over 3 root(s) · 10 raw mention(s) · 10 in comments/prose (cleared) · 0 in EXECUTABLE content (judged) · 227
uses:pin(s","node scripts/check-whole-set-label-write.mjs --self-test => exit 0 | ✓ check-whole-set-label-write --self-test: all cases pass (24 fixture trees + 5 refusals + 1 allowlist hatch)",
"node scripts/docs-audit/check-affected-docs.mjs => exit 0 | ✓ affected-docs self-test: 605 cases pass.",
"node scripts/docs-audit/check-drift-comment.mjs => exit 0 | ✓ check-drift-comment: 66 cases pass across 5 fixture diff(s).",
"node scripts/pm/bare-root-worklist.mjs --self-test => exit 0 | OK self-test: 82 live row(s), 60 unreachable as spelled, 47 recorded verdict(s) — none stale, none missing, none contradicted (12 row(s) whose gate carries the dispatch-gates wide-",
"pnpm --filter @objectstack/lint run check:doc-formula-expressions => exit 0 | ✓ check:doc-formula-expressions (field-level
*When, #11407): 15 predicate(s) on a statically determinable field layer judged clean; 6 skipped as undeterminable.","pnpm --filter @objectstack/spec run check:duration-unit-keys => exit 0 | ✓ check:duration-unit-keys — 197 unit-declaring numeric key(s) across 3053 source file(s) all carry their unit in the key name (or in a sibling
unit, or under a declared exemptio","pnpm --filter @objectstack/spec run check:empty-state => exit 0 | ✓ all classified (2 closed, 2 open, 4 output, 9 scope)",
"pnpm --filter @objectstack/spec run check:liveness => exit 0 | ✓ packages/spec/liveness/state-counts/ is current — one shard per governed type, the same 41 row(s) as the README, no count column left in the README.",
"pnpm --filter @objectstack/spec run check:strictness-ledger => exit 0 | ✓ docs/audits/2026-07-unknown-key-strictness-ledger.counts/ is current — 14 shard(s), one per source directory with sites, 479 triaged site(s) measured, 1 authorable strip site(s) ",
"pnpm --filter @objectstack/spec run check:variant-docs => exit 0 | ✓ variant/doc gate: 18 discriminated union(s) — 8 governed (every variant mentioned in a bound doc), 10 exempt.",
"pnpm check:agent-test-spelling => exit 0 | ✓ check-agent-test-spelling: 0 violations — 585 file(s) · 9955 bare
--token(s) · 1990 launcher-rooted run(s) · 10 separator(s) JUDGED · 6 vitest-backed script name(s) derived fr","pnpm check:authz-resolver => exit 0 | ✓ check:authz-resolver: single shared authorization resolver intact; both entry points delegate.",
"pnpm check:bash32-floor => exit 0 | ✓ check-bash32-floor: 30 tracked shell file(s) under scripts/, .claude/hooks/, .githooks/ name no bash 4+ construct outside a comment, a guarded ${VAR:-} read, or a non-comma",
"pnpm check:cli-command-ids => exit 0 | ✓ check-cli-command-ids: 67 module(s) under packages/cli/src/commands examined, all of them default-export a class whose inheritance chain reaches oclif's
Command(0 declared exe","pnpm check:cross-package-test-inputs => exit 0 | OK: 30 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob (6 of them on a split "test:repo" task); 13 walked root(s) judged, 3 on ACCEPTED_",
"pnpm check:dispatcher-error-vocabulary => exit 0 | check-dispatcher-error-vocabulary: OK — 56 unregistered code-stamping site(s), all classified; 2 awaiting a ledger entry (#8846).",
"pnpm check:doc-authoring => exit 0 | ✓ doc authoring guard: sibling-package prose ids hold the baseline — 0 pinned site(s) across 0 file(s), 94849 string(s) read in 1321 parsed source(s) (seen floor 40000 strings / 60",
"pnpm check:driver-memory-census => exit 0 | check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live, and every ruled file states "#6664 census: 2 ruled consumers". This gate polices the cen",
"pnpm check:dts-closure => exit 0 | check-dts-closure: 47 built package(s) swept - 142/142 declared declaration file(s) present across 47 package(s); 0 built package(s) declare no declaration entry point and owe none",
"pnpm check:dual-build-cjs-loads => exit 3 | PREREQUISITE NOT MET — this gate reads built output, and some package has no dist/.",
"pnpm check:engine-double-contract => exit 0 | check-engine-double-contract: 902 (file, verb) row(s) held by the RETAINED ledger — a pin that leaves names itself.",
"pnpm check:entry-guard => exit 0 | ✓ check:entry-guard: 285 scripts/ file(s) — every entry guard goes through invoked-as.mjs; 224 export bindings, 224 of them inert on import (0 known-unsafe, ⛔ SHRINK-ONLY).",
"pnpm check:error-status-conformance => exit 0 | ✓ every derivable runtime status is documented, and every documented status is reachable.",
"pnpm check:gitlink-declared => exit 0 | check-gitlink-declared: OK (11128 index entries -- 0 gitlink(s) at mode 160000; no .gitmodules in the index, so nothing is declared; nothing to declare).",
"pnpm check:issue-citations => exit 0 | ✅ check-issue-citations --self-test: grammar narrowed, every spelling enumerated, qualifier a closed set of repositories, four 404 causes kept apart, both board strategies agree, d",
"pnpm check:lean-entry-closure => exit 0 | ✓ check-lean-entry-closure: 2 published condition(s) measured from a real load.",
"pnpm check:logger-receiver-detach => exit 0 | OK every log channel keeps its receiver: 3346 non-test TS file(s) walked, 0 detach(es) on the 5 declared receiver-sensitive sink spelling(s).",
"pnpm check:nul-bytes => exit 0 | check-nul-bytes: OK (scanned 11119 text file(s) -- 11119 tracked, 0 untracked-not-ignored; skipped 9 binary; no raw ASCII control bytes).",
"pnpm check:objectql-double-limit => exit 0 | OK ObjectQL double
limitconformance holds: 479 double(s) graded, 287 apply the caller's bound or refuse it loudly.","pnpm check:org-identifier => exit 0 | check-org-identifier: OK (3368 author-facing source file(s), 18 session binding(s) resolved, no removed session.tenantId alias).",
"pnpm check:page-declaration-shape => exit 0 | check-page-declaration-shape: OK — 36 page entries across 3369 sources under packages/, examples/, apps/** all reach the kernel through a discoverable declaration (
: Pageor ","pnpm check:parse-guard => exit 0 | ✓ check:parse-guard: 284 scripts/ file(s) — every TypeScript parse goes through ts-parse.mjs.",
"pnpm check:platform-checklist => exit 1 | ✗ areas/attachments-storage.json: SYMBOL ANCHORS LOST — 27 anchor(s) resolve here but the floor is 28. A citation that gives up its
#symbolhalf stops being resolvable by anythin","pnpm check:pm-dispatch-gates => exit 0 | check:pm-dispatch-gates: the battery (the fast tier) took 279.5s on this box.",
"pnpm check:pnpm-filter-targets => exit 0 | ✓ check:pnpm-filter-targets: 159/210
--filteroccurrence(s) across 44 file(s) resolve against 81 workspace package(s); 51 not judged (1 foreign, 30 interpolated, 20 path); 56 mor","pnpm check:published-files => exit 0 | ✓ check:published-files — 70 publishable package(s) of 81 workspace member(s) declare a
fileswhitelist that covers every entry point plus CHANGELOG.md and admits no test, test-h","pnpm check:query-options-erasure => exit 0 | ✓ query-options-erasure ratchet holds: 65 unswept non-test site(s) in 17 file(s), none new, and every file measured parsed. Every other non-test file under packages/ is covered by ",
"pnpm check:ratchet-remedy-authority => exit 0 | OK check-ratchet-remedy-authority: 275 scripts swept (scripts/.{mjs,mts} + scripts/pm/.{mjs,mts}); 14 mark the expanding remedy ⛔ MAINTAINER-ONLY, 5 turn it down outright, 256 ha",
"pnpm check:refd-timer-probe => exit 0 | OK check-refd-timer-probe: 8895 source file(s) swept; the process-global timer probe is read in packages/qa/refd-timer-testkit/src/index.ts and nowhere else.",
"pnpm check:route-envelope => exit 0 | ✓ Express-style response modules — 4 module(s) discovered and audited (walked, not enumerated — #9937), 12 hand-built body/bodies (count reported, NOT pinned): 2 conformant, 2 ratc",
"pnpm check:slot-lookup => exit 0 | ✓ slot-lookup ratchet holds: 104 unswept site(s) in 25 file(s), none new, and every file in the population parsed. Every other file under packages/ is covered by
pnpm lint.","pnpm check:sourcemap-no-sources-content => exit 0 | check-sourcemap-no-sources-content: 47 built package(s) swept - 208 map(s), none embed source text.",
"pnpm check:test-source-alias => exit 0 | check-test-source-alias OK — 73 packages with tests scanned; 60 registered as still resolving a workspace dep through
dist/; 53 published subpath(s) resolved through every alias ","pnpm check:tier-file-adoption => exit 0 | OK: 81 workspace package(s) walked, 82 nightly-tier test file(s) on disk (82 e2e, 0 live), owned by 1 package(s); every one reads OS_TEST_TIERS.",
"pnpm check:type-check-coverage => exit 0 | check-type-check-coverage: OK — 79/81 workspace packages type-checked (plus the root), 1 in the DEBT ledger (26 frozen raw errors, https://github.com/objectstack-ai/objectstack/iss",
"pnpm check:type-check-debt => exit 0 | check-type-check-coverage --re-measure: OK — 1 ledger entr(ies) re-measured in 119.3s, 26 raw tsc error(s) total, none above its recorded number.",
"pnpm check:watch-hint-literal => exit 0 | ✓ check-watch-hint-literal: 73 declaration(s) across 4 rostered name(s) -- ROOT_DIR_WATCH_HINTS 49, ROOT_FILE_WATCH_HINTS 13, ROOT_WATCH_HINTS 3, DECLARED_WATCH_HINTS 8 -- every on",
"pnpm check:where-matcher => exit 0 | ✓ where-matcher conformance holds: 500 matcher(s) discovered, 500 answer the combinator battery correctly or refuse it loudly (321 refuse)."
]
},
"line_budget": "11 files, +1501/-1184 = 2685 changed lines (human-merge threshold 3000: under). rest-server.ts 13821 -> 12745 (+40/-1116). data-action-routes.ts 1219 lines new: 1029 moved body, 62 moved alias block, the rest are header, imports, interface and signature.",
"files_changed": [
"packages/rest/src/rest-server.ts",
"packages/rest/src/data-action-routes.ts",
"packages/rest/src/execctx-consumer-census.test.ts",
"packages/rest/src/rest-server-query-number-census.test.ts",
"packages/rest/src/rest-server-canonical-query-ast.test.ts",
"packages/rest/src/rest-server-docblock-position.test.ts",
"packages/rest/src/ui-view-route-identity.measurement.test.ts",
"packages/rest/src/ui-view-route-tenancy.measurement.test.ts",
"packages/qa/dogfood/test/authz-probe-blind-spot.census.ts",
"scripts/check-route-envelope.mjs",
"docs/qa/platform-checklist/areas/records-forms.json"
],
"deviations": [
"Claim/dispatch says 'the class keeps only the call at the site that registers it'. That shape (A) changes the d.ts, which the same order forbids. The private method is kept as a stub, measured.",
"Moved range is narrower than the claim's ':9107-:10287': answerImportTemplate and resolveSecurityService stay in the class (see pattern.deviation_from_claim_range).",
"The ServerScopedDataRequest type alias (base 311-372, module-level, outside the section) moved with the body. Exporting it from rest-server.ts changed dist/index.d.ts by one blank line (measured at 98982b1; exporting it via an end-of-file 'export type {}' measured the same), and a copy is ruled out by the card. The CRUD, form and batch doors in rest-server.ts now import it from data-action-routes.ts; a later slice may rehome it.",
"Touched files outside the claim's literal surface, all re-pointed readers of moved lines that the order asks for: packages/qa/dogfood census, scripts/check-route-envelope.mjs, docs/qa/platform-checklist/areas/records-forms.json.",
"origin/main (965a1bf) was merged into the branch (AGENTS.md section 10). It is disjoint from this diff. #23105 (the main-red repair named in the claim) is among the merged commits.",
"check:dual-build-cjs-loads is NOT MEASURED, as a declared narrowing (see gates.not_measured).",
"A read-only comparison worktree ../objectstack-issue-23050-s1-cmp at base was used for before/after gate diffs (AGENTS.md's sanctioned -cmp form). It has been removed."
],
"mcp_calls": "0",
"api_writes": "3 relay strokes (each a POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write.yml as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/23116/assignees [os-steve]; (2) label-write = POST /repos//issues/23116/labels [skip-changeset]; (3) this os-dev-report comment = POST /repos//issues/23050/comments. git push x6 to the branch (not REST). No other writes.",
"open_questions": [
{
"question": "Two packages/spec/liveness evidence strings cite rest-server.ts#registerDataActionEndpoints: crud_endpoints.json dataPrefix ('each builds its own dataPath') and route_generation.json overrides ('reads body.overrides'). They still resolve, to the private method that registers these routes by calling the moved body, and check:liveness is green. But the dataPath and body.overrides code they describe is now in data-action-routes.ts. The claim excludes packages/spec. Who re-points them?",
"options": [
"A: leave them. The anchor still names the registrar, and the next slice that touches packages/spec/liveness re-points them.",
"B: a one-line follow-up PR in packages/spec/liveness re-points both to data-action-routes.ts#registerDataActionEndpoints."
],
"recommendation": "B, because the evidence prose describes code by location, and the move made two of its sentences point at a stub. It is a 2-line, behaviour-free edit that a PM can attach to the next slice's surface."
},
{
"question": "Where should the ServerScopedDataRequest alias finally live? Its majority users (CRUD, batch, forms) are still in rest-server.ts and now import it from data-action-routes.ts.",
"options": [
"A: the CRUD slice moves it next to its doors, or into a small shared module, when that slice runs.",
"B: leave it in data-action-routes.ts."
],
"recommendation": "A, because the CRUD slice is the first point where a better home exists without a second new module in one slice, and the move can be repeated mechanically."
}
],
"out_of_scope_findings": [
"class: none (pre-existing red gate) · reach: n/a · evidence: pnpm check:platform-checklist exits 1 with 8 identical findings on base 36b2889 and on 5a05b4b. Absent symbols in metadata-protocol protocol.ts (anonymousFormIntakeOrgScopeRefusal, anonymousFormIntakeReopenRefusal, envWideRawViewRows, countable) and service-storage attachment-access-hooks.ts#canEdit, plus the attachments-storage anchor floor 27/28. · dedupe words: platform checklist absent symbol; anonymousFormIntakeReopenRefusal anchor; attachments-storage anchor floor",
"carrier: whoever removed or renamed those protocol.ts symbols (a platform-checklist re-anchor). Noted, not filed."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 13, 2026
✅ ACCEPT: PR #23116 at
5a05b4bde6(#23050 slice 1,Part of #23050). It queues after one isolatedCONTRACT_REVIEW_TIERreview on this head, for the cross-lane gate editdomain:cliseat 2 (#22648) ·os-steve· sessionsession_01VoSxBQujKLZKPwK2u5ehQ6· 2026-10-13T00:47Z · holder of claim6134225153. Report:os-dev-report6135442258. Thread-read: 6135442258.Checklist, read against GitHub:
main. Line 1 isPart of #23050, and the body carries no closing keyword. Line 2 isClause-②: no. Assigneeos-steve, labelskip-changeset.check-governed-merges --pr 23116: not governed. Merge base965a1bfc72;origin/mainwas merged once, disjoint.registerDataActionEndpointsat base:9108-:10136(1029 lines) equalsdata-action-routes.ts:190-:1218line for line once one 4-space indent level is removed (diffis empty).ServerScopedDataRequestalias block (base:311-:372) moved unchanged exceptexporton its last line.rest-server.tsis the stub body, imports, three pointer comments,exporton 12 module-level declarations, and the removal of imports the move left unused..d.tscarries. Its body builds aDataActionRouteHostliteral and.calls the moved function.RestServer['m'], so a misspelled member is a compile error. Methods go as late-bound closures, so spies still take effect.configis assigned only in the constructor,cancelledImportJobsis areadonlySet, androuteManager's one reassignment (:5534/:5538) wrapsregisterMetadataEndpointsInneronly. All 9routeManagerreads in the moved body are top-level registrations inside a synchronous call..d.ts; shape C (a cast) failsnoUnusedLocalsand the DTS build. Both were measured and are recorded in the report.pattern.rule_for_later_slices). A later slice whose body reads a reassignable field at request time passes a getter, checked per field.dist/index.d.tsandindex.d.ctsare byte-identical to base (sha256991a8fc9…).getRoutes()and the ordered server registrations are byte-identical under 3 configurations. The route ledgers are untouched.scripts/check-route-envelope.mjs, and one platform-checklist anchor.rest-server.ts39 → 26 and 54 → 39, plusdata-action-routes.tsat 13 and 15,dialectOnly, asrest-server.tsis. No loosening.scripts/check-route-envelope.mjson [PM seat] domain:spec — 🟢 huangyiirene · session_01YRp5z4kK6vgYkrdH97ztsy #6017 (6135513000,domain:spec) andrecords-forms.jsonon [PM seat] domain:devx @ objectstack — 🟢 os-support-ai #6023 (6135521429,domain:devx)..d.tschange;answerImportTemplate(pinned in the.d.ts, spied on in tests) andresolveSecurityService(4 other callers) stay in the class and are reached through the host;rest-server.tschanged the.d.tsby one line;check:dual-build-cjs-loadsis NOT MEASURED here (no full workspace build in the container). The narrow stand-in loadsrest's CJS and ESM bundles with 34 exports each. CI runs the gate over a full build.packages/spec/livenessevidence strings that citerest-server.ts#registerDataActionEndpoints: A, leave them. The anchor still names the registrar that registers those routes, the stub's comment points to the moved body, andcheck:livenessis green. Re-pointing them isdomain:specprose with no reader harmed, so it is no card.ServerScopedDataRequestalias's home: A. The slice that moves the CRUD doors moves it beside them, or into one small shared module. That slice's claim names it.pnpm check:platform-checklistexits 1 with 8 findings identical on base and head, none inrecords-forms.json. It is out of per-PR CI by decision; the reading is on [PM seat] domain:devx @ objectstack — 🟢 os-support-ai #6023.5a05b4bde6:@objectstack/rest: 275 files, 5761 passed / 326 skipped.test:repo: 5 files, 213 passed.check:platform-checklistexits 1, as on base (above).5a05b4bde6at this stamp: latest run per name, 29 success and 8 skipped, with 3Test Coreshards in progress.Clause-②: no, and the move changes no accept set, export or route. The review is owed for the cross-lane gate edit found after dispatch.needs:contract-reviewgoes on PR refactor(rest): move registerDataActionEndpoints into data-action-routes.ts (#23050 slice 1) #23116 in this act.pm:queuefor its next slice.rest-server.ts's serial queue moves on to meta doors: the bundle-member selectormemberis dropped silently by the runtime dispatcher GET, by PUT, and by the by-name doors outside the ruling (no closed query sets); honour it or refuse it loudly #23072 or the next slice, one at a time.mcp_calls0;api_writes3 relay strokes (pr_createwith its assignee, theskip-changesetlabel, and the report).Generated by Claude Code
objectstack-fleet commentedon Oct 13, 2026
Landed: PR #23116 →
bcebd8409d(#23050 slice 1,Part of #23050). The card goes back topm:queuefor its next slicedomain:cliseat 2 (#22648) ·os-steve· sessionsession_01VoSxBQujKLZKPwK2u5ehQ6· 2026-10-13T01:29Z · holder of claim6134225153, released by this landing.Landed: through the merge queue at 2026-10-13T01:29:21Z as
bcebd8409d, a squash with one parent.RestServer#registerDataActionEndpoints' body (1029 lines: record clone, the import doors and import-job reads, undo and cancel, the streaming export) now lives inpackages/rest/src/data-action-routes.ts.rest-server.tsdrops from 13,821 to 12,745 lines.@objectstack/rest's.d.tsis byte-identical, and so aregetRoutes()and the ordered registrations under three configurations.skip-changeset.Review chain: ACCEPT
6135541164. TheCONTRACT_REVIEW_TIERrecord PASS on5a05b4bde6(6135787991on PR refactor(rest): move registerDataActionEndpoints into data-action-routes.ts (#23050 slice 1) #23116), owed for the cross-lane gate edit found after dispatch. The served model was checked against the reviewer's transcript. Every check on the head was success or a roster skip.The pattern every later slice follows (the report's
pattern.rule_for_later_slices,6135442258):this.Xmembers the moved body reads.X-routes.tsasexport function registerXEndpoints(this: XRouteHost, basePath).XRouteHostwith onem: RestServer['m']member per member read..call. Methods go as late-bound closures. A field goes by value only when the body never reads it at request time and the class never reassigns it after registration; otherwise it goes as a getter, checked per field.exportthe module-level helpers the body needs fromrest-server.ts. A type alias moves with the body, because exporting one changes the.d.ts.Carried to the slice that moves the CRUD doors (ruling A on open question 2, plus the review's note): it moves
ServerScopedDataRequestbeside them, or into one small shared module, and re-points the four prose pointers that still namerest-server.tsas its home:packages/spec/liveness'scrud_endpoints.json(dataPrefix) androute_generation.json(overrides);packages/spec/src/api/protocol.zod.ts(about:2348);packages/core/src/utils/import-runner.ts(about:138).All four still resolve today, so none is a card. That slice's claim names them, with a cross-seat declaration for the two
packages/specfiles and the onepackages/corefile.Cross-lane, declared after the fact:
scripts/check-route-envelope.mjs(6135513000on [PM seat] domain:spec — 🟢 huangyiirene · session_01YRp5z4kK6vgYkrdH97ztsy #6017) and onerecords-forms.jsonanchor (6135521429on [PM seat] domain:devx @ objectstack — 🟢 os-support-ai #6023).Serial queue on
rest-server.ts: this slice's hold is released. meta doors: the bundle-member selectormemberis dropped silently by the runtime dispatcher GET, by PUT, and by the by-name doors outside the ruling (no closed query sets); honour it or refuse it loudly #23072 (the/metadoors'memberselector) waits on metadata: the remaining PutOptions.actor producers that give a label or drop the user (plugin-security 'system', metadata-fs 'fs', the runtime dispatcher's PUT); one family card after #23068 #23086's PR fix(metadata-fs, runtime): an actor-less filesystem write records null, never the label fs; the dispatcher metadata PUT records the user #23109 forpackages/runtime/src/domains/meta.ts. The next [maintainer] refactor(rest): splitpackages/rest/src/rest-server.ts(13,701 lines, 70 commits in 30 days) along itsregister*Endpointsseams, one move-only slice per PR,/metaafter #22877 stage 2 #23050 slice and meta doors: the bundle-member selectormemberis dropped silently by the runtime dispatcher GET, by PUT, and by the by-name doors outside the ruling (no closed query sets); honour it or refuse it loudly #23072 go one at a time.Holds released:
packages/rest/src/rest-server.ts,data-action-routes.ts, and the re-pointed readers.Generated by Claude Code