Repository navigation
Commit e5cf9f0
<!-- 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
- packages/metadata-protocol/src
0 commit comments