Repository navigation
Commit d0852dd
<!-- 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 22 of the `protocol.ts` split (#24586 ruling A, recorded in
`6270097840`). Cuts 1–21 landed as #25494, #25518, #25538, #25589,
#25601, #25623, #25642, #25719, #25731, #25740, #25797, #25939, #25972,
#26014, #26104, #26168, #26264, #26317, #26350, #26366 and #26404. The
claim is `6432922305`. The scope is the cut 22 proposal of the cut 21
report (`6432160640`), which the server seat approved in its dispatch
order, with the order's condition that the read-seam census stays at 82
with an identical list. Both members passed the AST screen and the
census trial, and both moved unedited.
Two `ObjectStackProtocolImplementation` members move unedited into a new
module,
`packages/metadata-protocol/src/protocol-view-expansion-names.ts`
(#23050 shape B):
- `resolveRowlessExpandedView`: the by-name read's answer for a view
name that no stored row holds but a stored view container expands
(#21442). It is the list read's own answer by construction: the same
rows, parse, expansion and selection (#21967).
- `expandUnderOwnName`: the expansion of a container on another
package's object under the container's own name (#21334, #21980).
`protocol.ts` loses 39 net lines (29,193 to 29,154). 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` `9a0108cdc2` after cut 21
merged. It names no issue, so the claim comment is the identity record.
It holds the move commit `c2087b4c49` and the merge of `main`
(`95673433d1`). That merge touches no file of
`packages/metadata-protocol/`: the package's `src/` tree is `ac8309b0`
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
`95673433d1`: of the 20 open PRs, **none edits `protocol.ts`** and none
names either member. Two touch `packages/metadata-protocol/src/` test
files: **#26337** (3 files) and **#26138** (7 files). Each was checked
with `git merge-tree`: both are clean against this head and against
`origin/main` alone. No open PR edits the new module.
## 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(`, so no
`PRODUCERS` row is owed.
- **Read-seam census** (added to the screen after cut 21). Each member
was moved alone to a scratch module in a clean worktree and
`check-durability-degradation-log-level --list` re-run: 82 read seams
and an identical list for each. The real cut measures the same; see "The
durability `--list`".
## What moves
| Member | Base line | Visibility | Body lines | AST tokens (params +
return + body) |
|---|---|---|---|---|
| `resolveRowlessExpandedView` | `:10306` | private async | 27 | 232 |
| `expandUnderOwnName` | `:18159` | private | 28 | 297 |
## The shape (#23050 shape B, as cuts 1–21 apply it)
- **The class keeps both members.** Each keeps its name, docblock,
signature and position. Each body now delegates, marked `[#25467 cut
22]`.
- **Typing.** `ViewExpansionNamesHost` types each of its six members as
the class member itself (`ObjectStackProtocolImplementation['…']`). Each
function types its `this` as the `Pick` of the members it reads. Each
stub annotates its literal as `ThisParameterType<typeof fn>`. No member
changes visibility.
- **Members read, measured by AST walk** (property and element accesses
on `this`, with `as` casts, parentheses and `!` stripped, and bare
`this` checked too). All are methods, each handed over as a closure
`(...a) => this.x(...a)`:
- `resolveRowlessExpandedView` reads `readActiveOverlayRows`,
`rethrowUnlessMetadataStoreUnprovisioned`, `namesWithOwnStoredRow`,
`expandStoredViewContainers` and `storedOverlayEntries`. Three of these
are themselves cut 16 stubs, so the call reaches
`protocol-stored-overlay-reads.ts` through the class, as before.
`expandStoredViewContainers` is generic (`<E …>`); its closure is
contextually typed by the class member, and `tsc` accepts it with no
annotation.
- `expandUnderOwnName` reads `isShippedByAnotherPackage`.
- **Every caller still calls the class method.** There are four
`this.resolveRowlessExpandedView(` sites (`:11041`, `:11556`, `:22145`,
`:27291` at base) and one `this.expandUnderOwnName(` site (`:18008`,
inside `expandRuntimeViewContainer`). None changes.
## 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 |
|---|---|---|---|
| `RowlessExpandedView` | non-exported interface, `:6254` | yes (2) |
gains `export` in place; the new module imports it as a type |
| `servedViewExpansion` | non-exported generic function, `:2872` | yes
(2) | gains `export` in place; the new module imports it from
`./protocol.js` |
| `PLURAL_TO_SINGULAR` | the `@objectstack/spec/shared` import | yes
(59) | stays; the new module imports it from there too |
| `expandViewContainer` | the `@objectstack/spec/ui` import | yes (2) |
stays; imported from there too |
`index.ts` names its exports one by one, so the two in-place `export`s
do not reach the published surface (cuts 8, 11, 18 and 19 did the same).
The one new statement in `protocol.ts` is the import of the new module.
## The durability `--list`
`check-durability-degradation-log-level` exits 0 at both ends with
identical output: `82 read seam(s)` at both ends, the order's condition.
Its `--list` is **identical once `[@:][0-9]+` is stripped** (158 lines,
and no entry changes file). No entry of the base `--list` names either
member. `resolveRowlessExpandedView`'s `try` guards
`this.readActiveOverlayRows(...)`, which is already a cut 16 stub, and
the gate did not count it as a read seam at base either. Its `catch`
rethrows through `rethrowUnlessMetadataStoreUnprovisioned` (#5532),
unedited. 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 `9a0108cdc2` and head `c2087b4c49` were built with `pnpm --filter
@objectstack/metadata-protocol build` against one dependency tree. The
closure was built at head by a full `pnpm build` (118/118). For the base
build, the package's `src/` was swapped tree-only to base and restored
from `HEAD` under a trap. Afterwards `git diff HEAD` was empty, `git
status` was clean, and both touched blobs equalled `HEAD`'s.
- **Normalised sha256** (the ruling's bar):
`0a7694d518b570981c5cdcbcdd8fcb2dec9f1c7d74a7287299fe9e19e32a4183` 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**:
`059fa1189ac13c65c36d3718584495bebaa48cc545e1526adb37cd95ef7dfaa3` at
both ends, 777,645 bytes. **Raw identity holds.**
- **Again on the merged tree** `95673433d1` (closure rebuilt by a full
`pnpm build`, 118/118): 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 `dbff5f6c5cde69ca…` at base and `14cc3ee05da5713f…`
at head (`index.cjs` `919b8129becaf027…` → `c75e50d7513a93c9…`).
- Each function's `.call(host` site occurs 0 times in the base bundles
and once in the head bundles (ESM and CJS alike), and each `function
NAME(` declaration goes 0 → 1.
- **Positive control** on the head tree. `private` was dropped from
`expandUnderOwnName` on disk (restored from `HEAD` under a trap) and the
package rebuilt. Both `.d.ts` files move to `796c09174d25bb97…`
(normalised `9f5a865eb21c4211…`, which differs from the bar's
`0a7694d5…`) and print `expandUnderOwnName(type: string, object: string,
container: Record<string, any>, ownPackageId: string | undefined):
Record<string, unknown>[];`. 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. None of the moved
functions, `ViewExpansionNamesHost`, `servedViewExpansion` or
`RowlessExpandedView` 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
`9a0108cdc2` against the head module:
```
resolveRowlessExpandedView: base tokens 232, head tokens 232, differ 0, text-equal(ws-collapsed, comments incl.) true
expandUnderOwnName: base tokens 297, head tokens 297, differ 0, text-equal(ws-collapsed, comments incl.) true
TOTAL tokens=529 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=250 head=251 byte-identical=248
```
The two top-level statements that are not byte-identical are
`servedViewExpansion` and `RowlessExpandedView`, which gained `export`
and nothing else.
**Negative controls**, one per member, each one token changed in an
in-memory copy of the head module:
```
MUTATED … "!== 'view') return undefined" -> "=== 'view') return undefined"
resolveRowlessExpandedView: base tokens 232, head tokens 232, differ 1, text-equal(ws-collapsed, comments incl.) false
expandUnderOwnName: base tokens 297, head tokens 297, differ 0, text-equal(ws-collapsed, comments incl.) true
MUTATED … "item.name = under;" -> "item.name = ownName;"
resolveRowlessExpandedView: base tokens 232, head tokens 232, differ 0, text-equal(ws-collapsed, comments incl.) true
expandUnderOwnName: base tokens 297, head tokens 297, 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`.** Of the 250 base statements, 248 are
byte-identical, leading comments included; the other two gained
`export`. Head adds one statement, the new module's import.
- **Size.** +143 / −57 over 2 files, 200 changed lines (the proposal's
estimate was 200–260). `protocol-view-expansion-names.ts` has 125 lines.
## Readers of the moved lines
The tests and scripts that read `protocol.ts` by path (33 files that
name `protocol.ts` and call `readFileSync`) were grepped for both member
names and for the bodies' text: `servedViewExpansion`,
`RowlessExpandedView`, `expandViewContainer(`, `standInRows`,
`underIsShipped`, `bareSpelled`. So were the test files in `packages/`,
`docs/qa/` and the `@objectstack/spec` liveness ledgers.
- **By path: none reads the moved bodies.** No by-path reader matches
any of those strings.
- **No test names either member.** The behaviour is driven through the
class by the view-container expansion tests in the package suite, which
pass at both ends.
- **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) 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,876 decision letters, 59,344 citations across 8,385 files).
Neither body nor the new header cites an ADR.
- **Engine-double contract** (`check-engine-double-contract`): exits 0
at both ends. The `updateData`/`deleteData` seams keep their entries at
new line numbers (13898 → 13882, 13923 → 13907). `productionFiles` is
3,764 at base and 3,766 at head: the new file, and the gitignored
`packages/spec/src/migrations/registry.ts` the spec build writes in the
head tree (as in cuts 20 and 21).
- **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, +1. The base-end readings were taken in a
clean detached worktree at `9a0108cdc2`.
## 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 `9a0108cdc2`: 21,584 tests (21,565 passed, 0 failed, 19 skipped),
271 files.
- Head `c2087b4c49`: 21,584 tests (21,565 passed, 0 failed, 19 skipped),
271 files.
- None lost, none added, none changed status. The base leg is the
package `src/` swapped tree-only from `9a0108cdc2` (the new module
removed) and restored from `HEAD` under a trap.
- The merged head `95673433d1` gives the same 21,584 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 2 paths in the register (13
surfaces), so the PR is NOT governed. It has 200 changed lines, under
the 3,000-line human-merge bar.
- **Derived gates.** `dispatch-gates --commands --repo
objectstack-ai/objectstack` derives 46 gates on 2 changed paths from the
merged tree `95673433d1`, with no stale-tree warning; all 46 exit 0
after the full `pnpm build` (118/118). `dispatch-gates --ran`: 46
derived, 46 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. When this PR was
opened, `main` was one commit past the merge (`ui/packages/app-shell`
and a changeset), with no stale-tree warning.
- `check-durability-degradation-log-level --list` on the merged tree:
`82 read seam(s)`, the list identical to the pre-merge head'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
guarded wrapper or guarding member, stays until the gate follows
imported wrappers or a ruling accepts the loss. The census trial on this
base measured `findEnvironmentRows` 82 → 66, `packagelessAddress` → 78,
`findServedOverlayRow` → 79, and `foldStoredCollection`,
`applyObjectRegistryMutation`, `unmanagedImportCollisions`,
`rollBackUnmanagedImport`, `readRevertableCommit` and
`storedFlowBindingAgrees` → 81.
`rethrowUnlessMetadataStoreUnprovisioned` cannot move at all: moved
alone, the gate exits 1 and finds 3 read seams.
- Public members whose return type is inferred.
- The bodies kept by a reader: `probeRecord`, `getMetaItemCached`,
`findReferencesToMeta`, `refuseUnmintableMetaType`,
`metaTypeNamespaceExists`, `viewContainerNameCollisionRefusal` with
`overlaidShippedContainerViewNames`, `reportPageRequiresAbsentAtLoad`,
the 7 `applyRegistryWriteThrough` callers,
`readCodeLayerForCarryForward` and `ensureObjectStorage`.
- 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 21a13f1 commit d0852dd
2 files changed
Lines changed: 143 additions & 57 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
408 | 408 | | |
409 | 409 | | |
410 | 410 | | |
| 411 | + | |
| 412 | + | |
411 | 413 | | |
412 | 414 | | |
413 | 415 | | |
| |||
2869 | 2871 | | |
2870 | 2872 | | |
2871 | 2873 | | |
2872 | | - | |
| 2874 | + | |
2873 | 2875 | | |
2874 | 2876 | | |
2875 | 2877 | | |
| |||
6251 | 6253 | | |
6252 | 6254 | | |
6253 | 6255 | | |
6254 | | - | |
| 6256 | + | |
6255 | 6257 | | |
6256 | 6258 | | |
6257 | 6259 | | |
| |||
10306 | 10308 | | |
10307 | 10309 | | |
10308 | 10310 | | |
10309 | | - | |
10310 | | - | |
10311 | | - | |
10312 | | - | |
10313 | | - | |
10314 | | - | |
10315 | | - | |
10316 | | - | |
10317 | | - | |
10318 | | - | |
10319 | | - | |
10320 | | - | |
10321 | | - | |
10322 | | - | |
10323 | | - | |
10324 | | - | |
10325 | | - | |
10326 | | - | |
10327 | | - | |
10328 | | - | |
10329 | | - | |
10330 | | - | |
10331 | | - | |
10332 | | - | |
10333 | | - | |
10334 | | - | |
10335 | | - | |
| 10311 | + | |
| 10312 | + | |
| 10313 | + | |
| 10314 | + | |
| 10315 | + | |
| 10316 | + | |
| 10317 | + | |
| 10318 | + | |
| 10319 | + | |
10336 | 10320 | | |
10337 | 10321 | | |
10338 | 10322 | | |
| |||
18162 | 18146 | | |
18163 | 18147 | | |
18164 | 18148 | | |
18165 | | - | |
18166 | | - | |
18167 | | - | |
18168 | | - | |
18169 | | - | |
18170 | | - | |
18171 | | - | |
18172 | | - | |
18173 | | - | |
18174 | | - | |
18175 | | - | |
18176 | | - | |
18177 | | - | |
18178 | | - | |
18179 | | - | |
18180 | | - | |
18181 | | - | |
18182 | | - | |
18183 | | - | |
18184 | | - | |
18185 | | - | |
18186 | | - | |
18187 | | - | |
18188 | | - | |
18189 | | - | |
18190 | | - | |
18191 | | - | |
18192 | | - | |
| 18149 | + | |
| 18150 | + | |
| 18151 | + | |
| 18152 | + | |
| 18153 | + | |
18193 | 18154 | | |
18194 | 18155 | | |
18195 | 18156 | | |
| |||
0 commit comments