Repository navigation
Commit ffecf03
<!-- 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 16 of the `protocol.ts` split (#24586 ruling A, recorded in
`6270097840`). Cuts 1–15 landed as #25494, #25518, #25538, #25589,
#25601, #25623, #25642, #25719, #25731, #25740, #25797, #25939, #25972,
#26014 and #26104. The claim is `6417245092`; the scope is the cut 16
proposal of the cut 15 report (`6415780867`), as the server seat
approved it in its dispatch order. All four members moved unedited, so
no member was left behind.
Four `ObjectStackProtocolImplementation` members move unedited into a
new module,
`packages/metadata-protocol/src/protocol-stored-overlay-reads.ts`
(#23050 shape B). They are the stored-overlay row reads:
- `readActiveOverlayRows`: a type's active `sys_metadata` rows, through
the cross-request overlay cache.
- `storedOverlayEntries`: each row parsed as the list read parses it.
- `namesWithOwnStoredRow`: the names that have a stored row of their
own.
- `readItemActiveRows`: one item's active rows.
`protocol.ts` loses 113 net lines (29,440 to 29,327). 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, restarted from `main` `95294be389` after cut 15 merged. It
names no issue, so the claim comment is the identity record. It holds
the move commit `2b680ef22` and the merge of `main` `601c77384`
(`afd0fc791`). That merge touches no file of
`packages/metadata-protocol/`: the package's `src/` tree is `d9c112bc`
at both ends.
**Serial with the file's in-flight PRs.** Measured just before this PR
was opened: of the 36 open PRs, one touches
`packages/metadata-protocol/src/`. #26005 edits
`protocol.meta-types-degenerate-derivation.test.ts`, which does not
overlap this cut. No open PR edits `protocol.ts` or the new module.
## The order's `new Error(` question
The `new Error(` near these members is at base line `:10741`, inside
`resolveAppPackageIdKey`, which does not move. None of the four moved
bodies constructs an error (0 `new Error(`, no other error constructor),
so no `PRODUCERS` row is owed. The only `catch` in the range (`:10497`)
is in `resolveRowlessExpandedView`, which also stays.
## What moves
| Member | Base line | Visibility | Body lines | AST tokens (params +
return + body) |
|---|---|---|---|---|
| `readActiveOverlayRows` | `:10262` | private async | 77 | 330 |
| `storedOverlayEntries` | `:10349` | private | 29 | 166 |
| `namesWithOwnStoredRow` | `:10431` | private | 9 | 98 |
| `readItemActiveRows` | `:10662` | private async | 24 | 235 |
139 body lines (the proposal said about 139).
## The shape (#23050 shape B, as cuts 1–15 apply it)
- **The class keeps every member** with its name, docblock, signature
and position. Each body now delegates, marked `[#25467 cut 16]`.
- **Typing.** `StoredOverlayReadHost` types every member as the class
member itself (an indexed access on
`ObjectStackProtocolImplementation`). 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` of `typeof
fn`. No member changes visibility.
- **Members read, measured by AST walk** (property and element accesses
on `this`, with `as` casts, parentheses and `!` stripped; bare `this`
checked too):
- `readActiveOverlayRows` and `readItemActiveRows` read `engine` (a live
getter; the overlay cache keys its bucket on the engine) and
`findEnvironmentRows` (a closure).
- `storedOverlayEntries` reads `convertStoredItem` (a closure).
- `namesWithOwnStoredRow` reads **no** member. It is a plain function,
and its method calls it directly, the way cut 3's `orderByFieldNames`
and `groupByFieldNames` stubs do. There is no host and no `.call`.
- **No private-static read.** The AST walk found no access on the
`ObjectStackProtocolImplementation` identifier and none on
`this.constructor`, in any of the four bodies.
- **Every other caller still calls the class method.** That covers the
list and by-name reads in `protocol.ts` (20 `this.` call sites) and
`protocol-save-door-refusals.ts`, whose own host hands
`readActiveOverlayRows` and `storedOverlayEntries` over as closures to
the class methods.
## Module-level declarations, by reader
- **Two gain `export` in place, none moves.** `addressPackages` (read by
`namesWithOwnStoredRow`; its other reader stays) and the
`StoredOverlayEntry` interface (the return type of
`storedOverlayEntries`; `RowlessExpandedView` still names it). Neither
is re-exported from `index.ts`, so the package's export table and
`.d.ts` do not change (below). The new module's import from
`./protocol.js` of `addressPackages` is a runtime import; earlier
modules already use that cycle (`protocol-publish-batch.ts`,
`protocol-drafts.ts`), and it reads only a function declaration, at call
time.
- **Imports in `protocol.ts`.** The overlay-cache reads lose their last
readers and leave the `./meta-overlay-cache.js` import, which keeps
`bumpWriteEpoch`:
- `metaOverlayCacheTtlMs`
- `readMetaOverlayCache`
- `readOverlayCacheGeneration`
- `writeMetaOverlayCache`
- the type `MetaOverlayCacheKey`
The new module imports them from there, and `PLURAL_TO_SINGULAR` /
`SINGULAR_TO_PLURAL` and the type `StoredOverlayRow` from where
`protocol.ts` does; those keep other readers in `protocol.ts`. The one
new statement in `protocol.ts` is the import of the new module.
## The durability `--list` (the order's re-measure)
The order expected the members' `engine.find` seams to change file.
Measured, they do not. Neither read calls the engine directly: both
route through `this.findEnvironmentRows(...)`, which stays in the class
and holds the find. `check-durability-degradation-log-level` exits 0 at
both ends with identical output, and its `--list` is **identical once
`[@:][0-9]+` is stripped** (159 lines; no entry changes file).
## The published `.d.ts`
The series bar is ruling `6348891160`, sorted-union identity, measured
first. Base `95294be389` and head `2b680ef22` were built with `pnpm
--filter @objectstack/metadata-protocol build` against one dependency
tree. The closure was built at head by a full `pnpm build` (119/119).
For the base build, the package's `src/` was swapped tree-only to base
and restored from `HEAD` under a trap; `git diff HEAD` was empty, `git
status` clean, and both touched blobs equal to `HEAD`'s after. Measured
twice: on the pre-merge tree (base `95294be389`, head `2b680ef22`) and
after merging `main` (head `afd0fc791`, closure rebuilt by a full `pnpm
build`, 119/119). The readings below hold for both.
- **Raw sha256**:
`08914e65f936a2b031c3f3f215481a97f53d132eefd869e4f42d928947ebe173` at
base and at head, on both `dist/index.d.ts` and `dist/index.d.cts`,
775,874 bytes each. **Raw identity holds**, so sorted-union identity
holds too. All four members stay `private NAME;` lines. The newly
exported `addressPackages` and `StoredOverlayEntry` do not appear.
- **Normalised sha256**:
`46ccd7e5c4db673652513d1801ec9c9f06bf34a0a7fb6ba97fb2531ef0cc544b` at
both ends (80 string-literal union runs sorted; the cut 12 normaliser).
- **The two builds differ where they should**: `index.js` hashes
`5671669a82bc3837…` at base and `bfb1ef96fc8499bc…` at head. The
`.call(host` sites of `readActiveOverlayRows`, `storedOverlayEntries`
and `readItemActiveRows` occur 0 times in the base bundles and once in
the head bundles (ESM and CJS alike); `function namesWithOwnStoredRow(`
appears 0 times at base and once at head.
- **Positive control** on the head tree: `private` was dropped from
`readActiveOverlayRows` (on disk, restored from `HEAD` under a trap) and
the package rebuilt. Both `.d.ts` files move to `626578dcab46fa8f…` and
print `readActiveOverlayRows(request: { type: string; packageId?:
string; }): Promise<any[]>;`, 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 four. No moved function, the host
type, `addressPackages` or `StoredOverlayEntry` appears.
No changeset: `skip-changeset`, per ruling `6348891160`.
## Proof of move-only
**Bodies, by AST token** (the TypeScript compiler's AST leaf tokens,
JSDoc skipped, over parameters less the added `this`, return type and
body), base `protocol.ts` at `95294be389` against the head module:
```
readActiveOverlayRows: base tokens 330, head tokens 330, differ 0, text-equal(ws-collapsed, comments incl.) true
storedOverlayEntries: base tokens 166, head tokens 166, differ 0, text-equal(ws-collapsed, comments incl.) true
namesWithOwnStoredRow: base tokens 98, head tokens 98, differ 0, text-equal(ws-collapsed, comments incl.) true
readItemActiveRows: base tokens 235, head tokens 235, differ 0, text-equal(ws-collapsed, comments incl.) true
TOTAL tokens=829 differ=0 members=4
CLASS members base=300 head=300 order-same=true byte-identical=296 stubs-with-identical-docblock+signature=4 other=[]
TOP base=244 head=245 byte-identical=241
```
**Negative control**, one token changed in an in-memory copy of the head
module (`overlayCacheTtlMs > 0 ?` to `overlayCacheTtlMs >= 0 ?`, one
occurrence):
```
MUTATED packages/metadata-protocol/src/protocol-stored-overlay-reads.ts "overlayCacheTtlMs > 0 ? readOverlayCacheGeneration" -> "overlayCacheTtlMs >= 0 ? readOverlayCacheGeneration"
readActiveOverlayRows: base tokens 330, head tokens 330, differ 1, text-equal(ws-collapsed, comments incl.) false
storedOverlayEntries: base tokens 166, head tokens 166, differ 0, text-equal(ws-collapsed, comments incl.) true
namesWithOwnStoredRow: base tokens 98, head tokens 98, differ 0, text-equal(ws-collapsed, comments incl.) true
readItemActiveRows: base tokens 235, head tokens 235, differ 0, text-equal(ws-collapsed, comments incl.) true
TOTAL tokens=829 differ=1 members=4
```
- **Class side.** 300 members at base and at head, in the same order.
The 296 that did not move are byte-identical to base, leading comments
included. Each of the 4 stubs sits at its base position and keeps its
docblock and signature byte-identical (everything before the body's
opening brace).
- **Top level of `protocol.ts`.** 241 of the 244 base statements are
byte-identical, leading comments included. The other three:
- the `./meta-overlay-cache.js` import, losing the five names above;
- `addressPackages`, gaining `export`;
- `StoredOverlayEntry`, gaining `export`.
Head adds one statement, the new module's import.
- **Size.** +241 / −136 over 2 files, 377 changed lines (the proposal's
estimate was 400–480). `protocol-stored-overlay-reads.ts` has 218 lines.
## Readers of the moved lines
Every test and script that reads `protocol.ts` by path was grepped for
the four member names and for the overlay-cache names their bodies use.
So was every test file in `packages/` and `ui/`, and `docs/qa/`.
- **By path: none.** No by-path reader names a moved member or reads a
moved body's text. `scripts/docs-audit/affected-docs.mjs` matched only
because its self-test carries inline excerpts (a `MetaOverlayCacheKey`
struct, an `auditMetaItem` signature); it does not read the moved
bodies.
- **Behaviour through the class method, no edit owed:**
- `protocol.platform-store-system-opt-in.test.ts` calls
`protocol.readActiveOverlayRows(...)` at line 265.
- `protocol.item-active-rows-one-read.test.ts` calls
`p.readItemActiveRows(...)` at lines 114 and 123.
Both pass at both ends (in the package suite). `storedOverlayEntries`
and `namesWithOwnStoredRow` are named by no test.
- No hit in `docs/qa/`.
- **ADR anchors and decision letters.** `check-adr-anchors` exits 0 at
both ends: 88 anchored files, 59,105 citations, files 8,299 → 8,300, and
**1,879 → 1,877** decision-letter citations. The two that leave the
anchored file are the `[ADR-0131 D6/D7]` comments in
`readActiveOverlayRows`' and `storedOverlayEntries`' bodies
(`protocol.ts` `ADR-0131 D6` 113 → 111). The `protocol.ts` anchor entry
does not cover ADR-0131, and no entry paragraph describes these reads,
so the new module gets no entry (disclosure only, as cuts 8, 12, 13 and
14).
- **Engine-double contract** (`check-engine-double-contract`): exits 0
at both ends. The `updateData`/`deleteData` seams keep their entries at
new line numbers (14087 → 13974, 14112 → 13999). `productionFiles` is
3,725 at base and 3,727 at head: +1 is the new file, +1 is the
gitignored `packages/spec/src/migrations/registry.ts` the spec build
writes in the head tree.
- **Identical output at both ends:** `check-adr-symbol-anchors`,
`check-system-context-census`, `check-tenant-audit-census`,
`check-query-options-erasure-ratchet`, `check-filter-alias-parity`,
`check-durability-degradation-log-level`. `check-nul-bytes` differs only
in the scanned file count, +1. The base-end readings were taken in a
clean detached worktree at `95294be389`.
- **Governed surface.** `check-governed-merges --branch
claude/project-thread-ybjm3h`: 0 of 2 paths hit the register, NOT
governed; 377 changed lines, under the 3,000-line human-merge bar.
## Verification
- `tsc --noEmit` in `packages/metadata-protocol` exits 0 before and
after the merge. `pnpm exec eslint --no-inline-config
packages/metadata-protocol` (the whole touched package; it has no `lint`
script, these are the root `lint` script's flags) exits 0, no output.
- **`packages/metadata-protocol` suite**, base and head, compared per
test name and status (vitest `--maxWorkers=2`, JSON reporter, each run
under the shared verify lock, `VERDICT command-exit 0` both legs), on
the pre-merge tree (the merge changed no file of the package):
- Base `95294be389`: 21,558 tests (21,539 passed, 0 failed, 19 skipped),
269 files.
- Head `2b680ef22`: 21,558 tests (21,539 passed, 0 failed, 19 skipped),
269 files.
- None lost, none added, none changed status. The base leg is the
package `src/` swapped tree-only from `95294be389` (the new module
removed) and restored from `HEAD` under a trap.
- No test outside the package names a moved member, so no cross-package
run is owed.
- `check-platform-checklist --changed-from origin/main` (merged tree):
OK, 1 anchored file in the change set, 29 anchors judged, 0 lost.
- **Derived gates.** `dispatch-gates --commands --repo
objectstack-ai/objectstack` derives 53 gates on 2 changed paths from the
merged tree `afd0fc791`, with no stale-tree warning; all 53 exit 0 after
the full `pnpm build` (119/119). `dispatch-gates --ran`: 53 derived, 53
run, 0 NOT-MEASURED, 0 UNRUN, exit 0.
## Carry-forward
Unchanged from cut 15. These stay in `protocol.ts`:
- 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
`readCodeLayerForCarryForward`.
- The private-static readers: `refusePackagedBaseRemoval`,
`packagedBaseRefusal`, `runPublishSideEffects`,
`promoteDraftForPublish`, `publishPackageDrafts` and
`discardPackageDrafts`.
- The field writers: `warnClosureReadUnavailable`.
The overlay-row family's other members stay for now:
- `overlayLockLayerAt` is named by the by-path kit
`protocol.lock-one-resolution.kit.test.ts`.
- `findServedOverlayRow`, `expandStoredViewContainers` and
`resolveRowlessExpandedView` were outside this order.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_016SP1spj613tyGCgxoD1An6
Co-authored-by: Claude <noreply@anthropic.com>
1 parent f143cd8 commit ffecf03
2 files changed
Lines changed: 241 additions & 136 deletions
| 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 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
0 commit comments