Repository navigation
Commit 88fb255
<!-- claude-projects-attribution: {"github_login":"os-project-manager"}
-->
_Requested by **Leehom** · [project
thread](https://claude.ai/code/project/chan_01TenzsRopZj4jMbvjX8uz1X?thread=cmsg_01TenzsRopZj4jMbvjX8uz1X7JKgiM29GUcitRvoGGj5BU)_
Part of #25467
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6270097840
Cut 24 of the `protocol.ts` split (#24586 ruling A, recorded in
`6270097840`). Cuts 1–23 landed as #25494, #25518, #25538, #25589,
#25601, #25623, #25642, #25719, #25731, #25740, #25797, #25939, #25972,
#26014, #26104, #26168, #26264, #26317, #26350, #26366, #26404, #26449
and #26654. The claim is `6441745164`. It takes the cut 24 proposal of
the cut 23 report (`6440919239`). As the claim orders, the two members
are not one theme, so each moves into its own module. Both passed the
AST screen and the read-seam census, and both moved unedited.
Two `ObjectStackProtocolImplementation` members move unedited, each into
a new module (#23050 shape B):
- `saveConflict` →
`packages/metadata-protocol/src/protocol-save-conflict.ts`: the
optimistic-save conflict answer. It builds the save door's 409 for a
`ConflictError` through the one conflict builder and writes its
decision-audit row (#21207, #23406).
- `listLiveMetadataTypes` →
`packages/metadata-protocol/src/protocol-live-metadata-types.ts`: the
live metadata-type listing. It returns the engine SchemaRegistry's types
plus the `metadata` service's, de-duplicated (#6992).
`protocol.ts` loses 13 net lines (29,165 to 29,152). The cut is
move-only, and the card stays open for later cuts.
Branch `claude/project-thread-ybjm3h` is the harness-pinned branch for
this thread. It was restarted from `main` `fe53769a8e` (cut 23's merge).
It names no issue, so the claim comment is the identity record. It holds
the move commit `34b0e4a3c9` and one merge of `main`, `f430c6a947` (8
commits). The merge touches no file of `packages/metadata-protocol/`.
The package's `src/` tree is `917e56be` at the move commit and at the
merge.
## Serial with the file's in-flight PRs
Measured just before this PR was opened, against the merged head
`f430c6a947`: of the 16 open PRs, **none edits `protocol.ts`**, and none
names either member or either new module. Three touch
`packages/metadata-protocol/src/` test files: **#26337** (3 files, among
them `protocol.recovery-doors-emit-mutation.test.ts`), **#26628**
(`protocol.meta-types-degenerate-derivation.test.ts`) and **#26701**
(`protocol.metadata-store-outage.test.ts`). Each one's `git merge-tree`
is clean against this head. #26628's test drives `getMetaTypes`, so
`listLiveMetadataTypes` runs through the class method there. It stubs
`getRegisteredTypes` and does not read `protocol.ts` by path.
`main` moved one commit after the merge: #26682 (`4373103165`, auth
sign-out). It touches no file of this package, `git merge-tree` with
this head is clean, and the derivation found nothing stale, so `main`
was not merged again.
## The order's screen (private statics, `new Error(`, the read-seam
census)
Both members passed:
- **No private-static read.** The AST walk found no access on the
`ObjectStackProtocolImplementation` identifier and none on
`this.constructor`.
- **No error constructed.** Neither body has `new Error(`.
`saveConflict` returns the refusal that `metadataConflictRefusal`
builds. No `PRODUCERS` row is owed.
- **Read-seam census.** `check-durability-degradation-log-level --list`
was taken on the base and again on the cut: `82 read seam(s)` and an
identical list once `[@:][0-9]+` is stripped. The full readings are
under "The durability `--list`".
## What moves
| Member | Base line | Visibility | Body lines | AST tokens (params +
return + body) | New module |
|---|---|---|---|---|---|
| `listLiveMetadataTypes` | `:8494` | private | 15 | 105 |
`protocol-live-metadata-types.ts` (66 lines) |
| `saveConflict` | `:21469` | private | 16 | 163 |
`protocol-save-conflict.ts` (68 lines) |
## The shape (#23050 shape B, as cuts 1–23 apply it)
- **The class keeps both members.** Each keeps its name, docblock,
signature and position. Each body now delegates, marked `[#25467 cut
24]`.
- **`saveConflict` reads two members, both methods.** `SaveConflictHost`
types each as the class member itself
(`ObjectStackProtocolImplementation['…']`). The function types its
`this` as their `Pick`, and the stub annotates its literal as
`ThisParameterType<typeof saveConflict>`. `metadataConflictRefusal` and
`recordOptimisticConflictAudit` are handed over as closures, so the
body's calls reach the class methods exactly as before.
- **`listLiveMetadataTypes` reads two members, both fields.**
`LiveMetadataTypesHost` types them the same way. `engine` (a `private`
field) and `getServicesRegistry` (the constructor-supplied optional
function field) are handed over as getters. This is the hand-over cut 20
used for `getServicesRegistry`. So the body reads the protocol's own
values at call time, and the `?.()` on an absent registry behaves as
before.
- **No member changes visibility.**
- **Every caller still calls the class method.** `getMetaTypes`'
`this.listLiveMetadataTypes()` (`:8513`, base) does not change, and
neither do the save door's two `throw await this.saveConflict(err,
request, writeSource)` sites (`:21243`, `:21454`).
## Module-level declarations, by reader
Measured by an AST walk over each body's identifiers, against
`protocol.ts`'s top-level declarations and import bindings (property
names excluded):
| Name | Where `protocol.ts` has it | Other readers in `protocol.ts` |
What this cut does |
|---|---|---|---|
| `ConflictError` (type position, `saveConflict`'s parameter) | the
`@objectstack/metadata-core` import | yes (7: five `instanceof` sites,
among them the save door's two, `metadataConflictRefusal`'s parameter
and the stub's signature) | stays; the new module imports it as a type
from there too |
`listLiveMetadataTypes`' body reads no module-level declaration. Its
module imports nothing but the class's type. No import of `protocol.ts`
loses its last reader, and no declaration gains `export`.
**The `:172` comment is not touched.** The claim allowed correcting the
stale `[commit ece4dad]` emitted-specifier comment (disclosed in cut
23) if this cut touched that import block. This cut adds its two imports
after cut 23's import and does not touch the `@objectstack/spec` block,
so the comment stays for a later edit.
## The durability `--list`
`check-durability-degradation-log-level` exits 0 at both ends with
identical output: `82 read seam(s)` at both ends. Its `--list` is
**identical once `[@:][0-9]+` is stripped** (158 lines, and no entry
changes file).
- `listLiveMetadataTypes` has a `try` around the `metadata` service's
`getRegisteredTypes()`. That callee is outside the gate's read
vocabulary (`find`/`findOne`/`count`), so the catch was not a read seam
before the move and is not one after it.
- `saveConflict` has no `try`.
- On the merged tree the verdict still reads `82 read seam(s)`.
## The published `.d.ts`
The series bar is ruling `6348891160`: sorted-union identity, measured
first, with raw identity reported when it holds. **Both hold for this
cut.**
Base `fe53769a8e` and head `34b0e4a3c9` were built with `pnpm --filter
@objectstack/metadata-protocol build` against one dependency tree. The
closure was built at head by a full `pnpm build` (116/116). For the base
build, the package's `src/` was swapped tree-only to base (both new
modules removed) and restored from `HEAD` under a trap. Afterwards `git
diff HEAD` was empty, `git status` was clean, and all three touched
blobs equalled `HEAD`'s.
- **Normalised sha256** (the ruling's bar):
`310d157f1455a7b76c3d9a60e905ac5e07debb23ec4a6a615b510870341bdbec` at
both ends, on `dist/index.d.ts` and `dist/index.d.cts`. The normaliser
sorted 80 string-literal union runs. **Sorted-union identity holds.**
- **Raw sha256**:
`724eaa784128c37a7e4b59d85e21212ba6378a5b07279853c97828cd8368e932` at
both ends, 777,143 bytes. **Raw identity holds.**
- **Again on the merged tree** `f430c6a947` (closure rebuilt by a full
`pnpm build`, 116/116): the same raw and normalised sha256, and the same
`index.js`/`index.cjs` hashes, as the pre-merge head.
- **The two builds differ where they should.**
- `index.js` hashes `8cc705b2d0a6a59b…` at base and `0cb9bc1754636851…`
at head (`index.cjs` `8af96d570232787c…` → `40c568bf03d0672b…`).
- `listLiveMetadataTypes.call(host` and `saveConflict.call(host` each
occur 0 times in the base bundles and once in the head bundles (ESM and
CJS alike).
- `function listLiveMetadataTypes(` and `function saveConflict(` each go
0 → 1.
- **Positive control** on the head tree. `private` was dropped from
`saveConflict` on disk (restored from `HEAD` under a trap) and the
package rebuilt. Both `.d.ts` files move to `980c4b207280c4e8…`
(normalised `f5a4a75faae310fd…`, which differs from the bar's
`310d157f…`). So the bar can see a change on these members.
- **Export tables.** The ESM and CJS bundles, loaded at runtime from the
package, each export the same 78 names at base and head. The sorted list
hashes to `9f18a0177ac736ed…` on all of them. Neither moved function nor
either `…Host` interface appears.
No changeset: `skip-changeset`, per ruling `6348891160`.
## Proof of move-only
**Bodies, by AST token.** The compare reads the TypeScript compiler's
AST leaf tokens, with JSDoc skipped, over the parameters (less the added
`this`), the return type and the body. It compares base `protocol.ts` at
`fe53769a8e` against the two head modules:
```
listLiveMetadataTypes: base tokens 105, head tokens 105, differ 0, text-equal(ws-collapsed, comments incl.) true
saveConflict: base tokens 163, head tokens 163, differ 0, text-equal(ws-collapsed, comments incl.) true
TOTAL tokens=268 differ=0 members=2
CLASS members base=301 head=301 order-same=true byte-identical=299 stubs-with-identical-docblock+signature=2 other=[]
TOP base=252 head=254 byte-identical=252
```
**Negative controls**, one per member. Each changed one token in an
in-memory copy of a head module:
```
MUTATED packages/metadata-protocol/src/protocol-live-metadata-types.ts "getRegisteredTypes()" -> "getRegisteredTypez()"
listLiveMetadataTypes: base tokens 105, head tokens 105, differ 1, text-equal(ws-collapsed, comments incl.) false
saveConflict: base tokens 163, head tokens 163, differ 0, text-equal(ws-collapsed, comments incl.) true
MUTATED packages/metadata-protocol/src/protocol-save-conflict.ts "return conflict;" -> "return err;"
listLiveMetadataTypes: base tokens 105, head tokens 105, differ 0, text-equal(ws-collapsed, comments incl.) true
saveConflict: base tokens 163, head tokens 163, differ 1, text-equal(ws-collapsed, comments incl.) false
```
- **Class side.** There are 301 members at base and at head, in the same
order. The 299 that did not move are byte-identical to base, leading
comments included. Both stubs sit at their base positions and keep their
docblocks and signatures byte-identical.
- **Top level of `protocol.ts`.** All 252 base statements are
byte-identical, leading comments included. Head adds two statements, the
new modules' imports.
- **Size.** +152 / −31 over 3 files, 183 changed lines.
## Readers of the moved lines
The tests and scripts that read `protocol.ts` by path (the files that
name `protocol.ts` and call `readFileSync`) were grepped for both member
names and for the bodies' text: `metadataConflictRefusal`,
`recordOptimisticConflictAudit`, `has been modified since you loaded
it`, `schemaTypes`, `runtimeTypes`, `MetadataService not available`. So
were the test files in `packages/`, `docs/qa/` and the
`@objectstack/spec` liveness ledgers.
- **By path: none reads the moved bodies.** Of the 26 such files, the
one textual hit is a `// MetadataService not available` comment inside
an inline fixture of
`scripts/check-durability-degradation-log-level.mjs`. That fixture is
its own code string and does not read `protocol.ts`.
- **By name, outside the package:**
`packages/spec/src/meta-spelling/metadata-url-spelling.ts` names
`listLiveMetadataTypes()` in a comment only. No edit is owed.
- **The liveness ledgers.** No row points at either member. Carried
forward: `manifest.json`'s `dependencies` row →
`protocol.ts#resolveWritePackageScope` (cut 19), and `seed.json` →
`protocol.ts#applySeedBodies` (cut 14). Both still quote lines that
moved to a seam module. `check:liveness` checks only that the `#symbol`
is named in the file, and both stubs keep it. Re-pointing them is a
`packages/spec/**` edit, outside this card.
- **ADR anchors.** `check-adr-anchors` gives identical output at both
ends: 1,871 decision-letter citations, and 59,671 citations across 8,363
files. Neither moved body cites an ADR. `listLiveMetadataTypes`'
docblock (ADR-0131 D6) stays on the stub, and neither new module's
header cites one.
- **Engine-double contract** (`check-engine-double-contract`): exits 0
at both ends.
- The `updateData`/`deleteData` seams keep their entries at new line
numbers (13866 → 13863, 13891 → 13888).
- `productionFiles` is 3,777 at base and 3,780 at head. The +3 are the
two new files and the gitignored
`packages/spec/src/migrations/registry.ts` that the spec build writes in
the head tree, as in cuts 20–23.
- **Identical output at both ends:** `check-adr-anchors`,
`check-adr-symbol-anchors`, `check-system-context-census`,
`check-tenant-audit-census`, `check-query-options-erasure-ratchet`,
`check-filter-alias-parity` and
`check-durability-degradation-log-level`. `check-nul-bytes` differs only
in the scanned file count, +2. The base-end readings were taken in a
clean detached worktree at `fe53769a8e`.
## Verification
- `tsc --noEmit` in `packages/metadata-protocol` exits 0 at head and on
the merged tree.
- `pnpm exec eslint --no-inline-config packages/metadata-protocol` exits
0 with no output (the whole touched package, with the root `lint`
script's flags).
- **`packages/metadata-protocol` suite**, base and head, compared per
test name and status. Each leg ran vitest `--maxWorkers=2` with the JSON
reporter under the shared verify lock.
- Base `fe53769a8e`: 21,599 tests (21,580 passed, 0 failed, 19 skipped),
272 files.
- Head `34b0e4a3c9`: 21,599 tests (21,580 passed, 0 failed, 19 skipped),
272 files.
- None lost, none added, none changed status. The base leg is the
package `src/` swapped tree-only from `fe53769a8e` (both new modules
removed) and restored from `HEAD` under a trap.
- The merged head `f430c6a947` gives the same 21,599 tests, per test
identical to the pre-merge head (0 lost, 0 added, 0 changed).
- `check-platform-checklist --changed-from origin/main` (merged tree):
OK. 1 anchored file is in the change set, 29 anchors were judged, and 0
were lost.
- **Governed surface.** `check-governed-merges --branch
claude/project-thread-ybjm3h` finds 0 of 3 paths in the register (13
surfaces), so the PR is NOT governed. It has 183 changed lines, under
the 3,000-line human-merge bar.
- **Derived gates.** `dispatch-gates --commands --repo
objectstack-ai/objectstack` derives 46 gates on 3 changed paths from
`f430c6a947`, with no stale-tree finding, and all 46 exit 0 after the
full `pnpm build` (116/116). `dispatch-gates --ran` reports 46 derived,
46 run, 0 NOT-MEASURED and 0 UNRUN, and exits 0.
- `check-durability-degradation-log-level --list` on `f430c6a947`: `82
read seam(s)`.
## Carry-forward
These stay in `protocol.ts`:
- **The read-seam members** (cut 21). A member named in a `protocol.ts`
read-seam entry of `check-durability-degradation-log-level --list`, as
the guarded wrapper or the guarding member, stays until the gate follows
imported wrappers or a ruling accepts the loss. The census-negative set
is the one cuts 22–23 measured (this cut re-trialled only its own
members and the cut 25 candidates): `findEnvironmentRows`,
`packagelessAddress`, `findServedOverlayRow`, `foldStoredCollection`,
`applyObjectRegistryMutation`, `unmanagedImportCollisions`,
`rollBackUnmanagedImport`, `readRevertableCommit` and
`storedFlowBindingAgrees`. `rethrowUnlessMetadataStoreUnprovisioned`
cannot move at all.
- Public members whose return type is inferred.
- **The bodies kept by a by-path reader:**
- `probeRecord`, `getMetaItemCached`, `findReferencesToMeta`,
`refuseUnmintableMetaType` and `metaTypeNamespaceExists`.
- `viewContainerNameCollisionRefusal` with
`overlaidShippedContainerViewNames`, and
`reportPageRequiresAbsentAtLoad`.
- The 7 `applyRegistryWriteThrough` callers (among them
`applyRemoteMetadataMutation`), `readCodeLayerForCarryForward` and
`ensureObjectStorage`.
- `emitMetadataMutation`: its body is one of the two
`this.notifyMutationListenersLocal(` sites that
`protocol.recovery-doors-emit-mutation.test.ts` counts in `protocol.ts`.
- The private-static readers: `refusePackagedBaseRemoval`,
`packagedBaseRefusal`, `runPublishSideEffects`,
`promoteDraftForPublish`, `publishPackageDrafts` and
`discardPackageDrafts`.
- The field writers: `warnClosureReadUnavailable`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_016SP1spj613tyGCgxoD1An6
Co-authored-by: Claude <noreply@anthropic.com>
1 parent dc9d1ff commit 88fb255
3 files changed
Lines changed: 152 additions & 31 deletions
File tree
- packages/metadata-protocol/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
413 | 413 | | |
414 | 414 | | |
415 | 415 | | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
416 | 420 | | |
417 | 421 | | |
418 | 422 | | |
| |||
8492 | 8496 | | |
8493 | 8497 | | |
8494 | 8498 | | |
8495 | | - | |
8496 | | - | |
8497 | | - | |
8498 | | - | |
8499 | | - | |
8500 | | - | |
8501 | | - | |
8502 | | - | |
8503 | | - | |
8504 | | - | |
8505 | | - | |
8506 | | - | |
8507 | | - | |
8508 | | - | |
8509 | | - | |
| 8499 | + | |
| 8500 | + | |
| 8501 | + | |
| 8502 | + | |
| 8503 | + | |
| 8504 | + | |
| 8505 | + | |
| 8506 | + | |
8510 | 8507 | | |
8511 | 8508 | | |
8512 | 8509 | | |
| |||
21471 | 21468 | | |
21472 | 21469 | | |
21473 | 21470 | | |
21474 | | - | |
21475 | | - | |
21476 | | - | |
21477 | | - | |
21478 | | - | |
21479 | | - | |
21480 | | - | |
21481 | | - | |
21482 | | - | |
21483 | | - | |
21484 | | - | |
21485 | | - | |
21486 | | - | |
21487 | | - | |
21488 | | - | |
21489 | | - | |
| 21471 | + | |
| 21472 | + | |
| 21473 | + | |
| 21474 | + | |
| 21475 | + | |
| 21476 | + | |
21490 | 21477 | | |
21491 | 21478 | | |
21492 | 21479 | | |
| |||
0 commit comments