Skip to content

Commit e5cf9f0

Browse files
refactor(metadata-protocol): move the runtime authoring gate and the restored-body doors out of protocol.ts into protocol-authoring-gate.ts (#25467 cut 8) (#25719)
<!-- claude-projects-attribution: {"github_login":"os-project-manager"} --> _Requested by **Leehom** · [project thread](https://claude.ai/code/project/chan_01TenzsRopZj4jMbvjX8uz1X?thread=cmsg_01TenzsRopZj4jMbvjX8uz1X8pA24ebcFji3bEBewae3AB)_ Part of #25467 Clause-②: no Metadata-protocol: none Ruling-ref: 6270097840 Cut 8 of the `protocol.ts` split (#24586 ruling A, recorded in `6270097840`). Cuts 1–7 landed as #25494, #25518, #25538, #25589, #25601, #25623 and #25642. The claim is `6390712113`; it resumes the work handed over in Release `6385903828` (`claude/project-thread-uasfag@65b6d71`), whose scope the server seat approved. Five `ObjectStackProtocolImplementation` members, the runtime authoring gate and the restored-body doors, move unedited into a new module, `packages/metadata-protocol/src/protocol-authoring-gate.ts` (#23050 shape B; getters `engine`, `authoringChannel`, `authoringGates`). `protocol.ts` loses 189 net lines (30,010 to 29,821). The cut is move-only, and the card stays open for later cuts. Branch `claude/project-thread-dxdvqf` is the harness-pinned branch for this thread. It names no issue, so the claim comment is the identity record. It holds two commits on `main` `47af3dde4`: the picked-up commit `65b6d71d38` (cherry-picked unchanged), and one that writes the new module's header, which the picked-up commit had left as a placeholder line. **Serial with the file's in-flight PRs.** Measured just before this PR was opened: none of the 18 open PRs touches `protocol.ts`, `protocol-authoring-gate.ts` or the `[#8862]` pin (each PR's file list read in full; #25718's 9,205-file list was checked by `git diff --name-only` against its merge base, since the files API caps at 3,000). `git log 47af3dd..origin/main -- packages/metadata-protocol/` is empty at `f6ba1343ba`. ## What moves | Member | Base line | Visibility | Tokens (params + return + body) | |---|---|---|---| | `restoredBodyDerivation` | `:6876` | private | 42 | | `restoredBodyWriter` | `:6913` | private | 118 | | `refuseRestoredBodyTheSaveDoorRefuses` | `:6983` | private | 209 | | `runAuthoringGate` | `:7022` | private | 203 | | `assertRuntimeAuthoringRules` | `:7085` | private | 540 | ## The shape (#23050 shape B, as cuts 1–7 apply it) - **The class keeps every member** with its name, docblock, signature and position, less `async`. Each body is now one host literal plus `fn.call(host, …)`, marked `[#25467 cut 8]`. - **Typing.** `AuthoringGateHost` types every member as the class member itself (`ObjectStackProtocolImplementation['m']`). Each moved function types its `this` as the `Pick` of the host over exactly the members its body reads. Each stub annotates its literal as `ThisParameterType<typeof fn>`. No cast, and no member changes visibility. - **Members read:** the fields `engine`, `authoringChannel` and `authoringGates`, as getters; the methods `anonymousElevatedFlowRefusal`, `assertRuntimeAuthoringRules`, `credentialChannelFor`, `defaultRecordPageSaveRefusal`, `externalBindingSaveRefusal`, `foldStoredCollection`, `isArtifactBacked`, `orgWallEnforced`, `refuseRestoredBodyTheSaveDoorRefuses`, `resolveSduiManifest`, `resolveWritePackageScope`, `restoredBodyDerivation`, `rlsMembershipResolverKeys`, `runAuthoringGate` and `tenancyPostureInForce`, as late-bound closures. No field is assigned. ## Module-level declarations, by reader - **None moves.** No module-level declaration is read by the moved bodies alone. - **Stay in `protocol.ts` and gain `export` in place** (the only edit to each): `permissionSetOwnerBindingRefusal` and `runtimeHookWithoutBodyRefusal`, both read by code that stays (the save door). `src/index.ts` exports from `./protocol.js` by name, so neither is published (measured below). - **Imports.** In `protocol.ts`, `evaluateRuntimeAuthoringGate` and the type `IObjectQLEngine` lose their last reader and are dropped from their import lists. The one new statement is the import of the new module. ## The published `.d.ts` The series bar is ruling `6348891160`, sorted-union identity, measured first on merged main as the seat asked. Base `47af3dde4` and head `6cbd26bd7d` were built with `pnpm --filter @objectstack/metadata-protocol build` against the same dependency tree (`turbo run build --filter='@objectstack/metadata-protocol^...'` once, then the package's `src/` swapped tree-only between the two builds and restored from `HEAD`, `git diff HEAD` empty after). - **Raw sha256**: `325970c1661efaa6a3762ce7de9e6bb205ea16099784f2b6c5950d62d175b331` at base and at head, on both `dist/index.d.ts` and `dist/index.d.cts`, 772,838 bytes each. `diff` exits 0. **Raw identity holds**, so sorted-union identity holds too. - **Normalised sha256** (cut 7's normaliser, unchanged): `aa05995b9d9a32f69b3416eac92ef86b46d79593001a37bf1bb529ed7a9f8952` at both ends, both files. - **The two builds differ** where they should: `index.js` hashes `8ef7591738381e3e…` at base and `12c3ff329045d303…` at head, and `restoredBodyDerivation.call` occurs 0 times in the base bundle and once in the head bundle. - **Positive control** on a copy of the head `index.d.ts`, the first `private engine;` changed to `engine;`: raw `3c2a24456c659dbf…`, normalised `86fb565ea19f9768…`. Both move. - **Export tables.** The ESM and CJS bundles, loaded at runtime, each export the same 78 names at base and head; the sorted list hashes to `e47ac7c753bcb8be…` on all four (the same hash cut 7 reported). Neither `permissionSetOwnerBindingRefusal`, `runtimeHookWithoutBodyRefusal` nor any moved function appears. No changeset: `skip-changeset`, per ruling `6348891160`. ## Proof of move-only - **Bodies, by AST token.** For each moved function, the parameters (less the added `this`), the return type and the body have the same token sequence as the base method: 1,112 tokens compared, 0 differ. The body and parameter text, comments included, is also equal with whitespace collapsed, for all five. Negative control: one changed token in `assertRuntimeAuthoringRules`'s body makes the check report `differ=1`. - **Class side.** 299 members at base and at head. The 294 that did not move are byte-identical to base. Each of the 5 stubs sits at its base position and keeps its docblock and signature byte-identical, less `async`. - **Top level of `protocol.ts`.** 231 of the 235 base statements other than the class are byte-identical, leading comments included. The other 4 are the two import statements that lose a name and the two declarations that gain `export`. Head adds one statement, the new module's import. - **Size.** +468 / −250 over 3 files, 718 changed lines. `protocol-authoring-gate.ts` has 404 lines. ## Readers of the moved lines - **The `[#8862]` pin** (`protocol.object-registry-write-through-spelling.test.ts`). `assertRuntimeAuthoringRules` holds the collection pair it counts, so the scan now reads `protocol.ts` and `protocol-authoring-gate.ts` as one text and keeps the exact "one executable `'objects'` literal" assertion. That is the only edit outside the move. The diff: ```diff - const code = executableTextOf(readFileSync( - fileURLToPath(new URL('./protocol.ts', import.meta.url)), + // [#25467 cut 8] `assertRuntimeAuthoringRules`, which holds the collection + // pair, moved whole into `protocol-authoring-gate.ts`; the scan reads both + // files as one, so the population it counts is the one it always counted. + const code = executableTextOf(['./protocol.ts', './protocol-authoring-gate.ts'].map((path) => readFileSync( + fileURLToPath(new URL(path, import.meta.url)), 'utf8', - )); + )).join('\n')); ``` Both controls, re-run on this head through `scripts/ablation-replace.mjs` (mutation proven on disk, restored to the `HEAD` blob `7d8b3ff36eba`, `git diff HEAD` empty after each): - **blanked module** (the whole file deleted): `AssertionError: expected [] to have a length of 1 but got +0` (the file's 12 tests: 7 fail, because the other suites import the blanked module too); - **an added `'objects'` literal** (`listCollection('permission', 'permissions')` spelled with `'objects'`): `expected [ '\'objects\'', '\'objects\'' ] to have a length of 1 but got 2`, 1 failed, 11 passed. - Unmutated: 12 of 12 pass. `this.applyRegistryWriteThrough(` sites in `protocol.ts` stay at 7. - **Bracketed-refusal pin** (`PRODUCERS`): the new module has no `new Error(` (0), so it gets no row. - **ADR anchors and decision letters.** `check:adr-anchors`: 85 → 85 anchored files. Decision-letter citations on the anchored surface go **1,847 → 1,846**: the one that leaves is `ADR-0090 D11` in `assertRuntimeAuthoringRules`'s `[#7674]` comment. ADR-0090 is not among `protocol.ts`'s anchored ADRs, and no paragraph of that anchor entry describes the authoring gate, so the new module gets no entry (disclosure only, as cut 7 did). - **Durability checker** (`check-durability-degradation-log-level --list`): identical at both ends once `[@:][0-9]+` is stripped (159 lines). None of the five members holds a seam. The gate itself exits 0 at both ends with identical output. - **Engine-double contract** (`check-engine-double-contract`): exits 0 at both ends. The `updateData`/`deleteData` seams keep their entries at new line numbers (14254 → 14065, 14279 → 14090). `productionFiles` is 3,682 at base and 3,684 at head: +1 is the new file, +1 is the gitignored `packages/spec/src/migrations/registry.ts`, which the spec build writes and the base tree had not built. - **Identical output at both ends:** `check-adr-symbol-anchors`, `check-platform-checklist`, `check-system-context-census`, `check-tenant-audit-census`, `check-query-options-erasure-ratchet`, `check-filter-alias-parity`. `check-nul-bytes` differs only in the scanned file count, +1. - **Governed surface.** `check-governed-merges --branch claude/project-thread-dxdvqf`: 0 of 3 paths hit the register, NOT governed; 718 changed lines, under the 3,000-line human-merge bar. ## Verification - `pnpm --filter @objectstack/metadata-protocol typecheck` exits 0. `eslint --no-inline-config packages/metadata-protocol` exits 0. - **`packages/metadata-protocol` suite**, base and head, compared per test name and status: - Base `47af3dde4`: 21,504 tests (21,485 passed, 0 failed, 19 skipped), 266 files. - Head `6cbd26bd7d`: 21,504 tests (21,485 passed, 0 failed, 19 skipped), 266 files. - None lost, none added, none changed status. The suite includes `protocol.runtime-authoring-gate.test.ts`, which `main` changed after the picked-up commit was cut. - **Derived gates.** `dispatch-gates --commands --repo objectstack-ai/objectstack` derives 59 gates on the final tree (3 changed paths). 58 exit 0 at head. `check-plugin-teardown-shape --self-test` and `check:lean-entry-closure` first answered PREREQUISITE NOT MET (a pinned fixture commit outside the shallow clone; an unbuilt `objectql/dist`) and exit 0 once those were fetched and built. `check:dual-build-cjs-loads` is NOT MEASURED locally: it needs every package's `dist/` (72 absent here) and is left to CI; the CJS bundle of this package was loaded directly above. `--ran` reconciles 59 of 59: 58 run, 1 NOT-MEASURED, 0 UNRUN. ## Acceptance notes - `packages/metadata-protocol/src/protocol-package-install.ts` (cut 7, on `main`) still carries its placeholder header line (`[#25467 cut 7] HEADER PLACEHOLDER`), while its host interface's docblock says "See the module header for which members are getters". This PR writes the cut 8 module's header and does not touch cut 7's file, which is outside this claim's file surface. Carrier: #25467. ## Carry-forward Unchanged from cut 7: public members whose return type is inferred, the bodies kept by a reader (`probeRecord`, `getMetaItemCached`, `findReferencesToMeta`, `packagelessAddress`, `refuseUnmintableMetaType`, `metaTypeNamespaceExists`, `viewContainerNameCollisionRefusal` with `overlaidShippedContainerViewNames`, `reportPageRequiresAbsentAtLoad`, the 7 `applyRegistryWriteThrough` callers), and the private-static readers stay in `protocol.ts`. --- _Generated by [Claude Code](https://claude.ai/code/session_014vzV3bUKh27BRiihG8aCqR)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 1252db9 commit e5cf9f0

3 files changed

Lines changed: 468 additions & 250 deletions

File tree

0 commit comments

Comments
 (0)