Repository navigation
Commit b0376ed
<!-- 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
This is cut 19 of the `protocol.ts` split (#24586 ruling A, recorded in
`6270097840`). Cuts 1–18 landed as #25494, #25518, #25538, #25589,
#25601, #25623, #25642, #25719, #25731, #25740, #25797, #25939, #25972,
#26014, #26104, #26168, #26264 and #26317.
The claim is `6427907689`. The scope is the cut 19 proposal of the cut
18 report (`6426921154`), as the server seat approved it in its dispatch
order. The member passed the AST screen and moved unedited.
One `ObjectStackProtocolImplementation` member moves unedited into a new
module, `packages/metadata-protocol/src/protocol-write-package-scope.ts`
(#23050 shape B):
- `resolveWritePackageScope` resolves a package write's validation
scope. That is the written package plus the closure of the dependencies
its manifest declares, read from the registry. It answers `undefined`
wherever the registry cannot be read.
`protocol.ts` loses 30 net lines (29,270 to 29,240). 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` `77dc7062e5` after cut 18
merged. It names no issue, so the claim comment is the identity record.
The branch holds the move commit `c5f1351978` and the merge of `main`
`a8e7393dda` (`f4eb4330f3`). That merge touches no file of
`packages/metadata-protocol/`: the package's `src/` tree is `e8f66938`
at both ends.
**Serial with the file's in-flight PRs.** Measured just before this PR
was opened: of the 29 open PRs, two touch
`packages/metadata-protocol/src/`, and neither names
`resolveWritePackageScope`. Each was checked with `git merge-tree`
against this branch's head (`f4eb4330f3`).
- **#26244** (draft, head `c33b95d89f`) edits `protocol.ts` at `:163`
(imports) and `:23178`, far from `:7361`. Its merge-tree conflicts in
`protocol.ts` and in
`packages/spec/src/type-alias-convention.pin.test.ts`. Both conflicts
are ones #26244 has with `main` alone: a merge-tree of #26244 with
`origin/main` reports the same two files. The `protocol.ts` one is the
import-line conflict with cut 18's `ALL_CONVERSIONS` drop, whose union
resolution #26317 spelled out. This cut adds no conflict.
- **#26138** edits seven `protocol.*.test.ts` files. Its two conflicts
(`visibility-alias-keys-retirement.test.ts`,
`scripts/sdui-manifest.sources/core.json`) are likewise with `main`
alone.
No open PR edits the new module.
## The order's screen (private statics, `new Error(`)
The member passed:
- **No private-static read.** The AST walk found no access on the
`ObjectStackProtocolImplementation` identifier and none on
`this.constructor`.
- **No error constructed.** There is no `new Error(` and no other error
constructor, so no `PRODUCERS` row is owed. There is no log line.
- **One silent `catch`** around the registry reads. It answers
`undefined`, meaning "an unreadable registry means an unnarrowed gate".
It moves with the body. See the durability `--list` below.
## What moves
| Member | Base line | Visibility | Body lines | AST tokens (params +
return + body) |
|---|---|---|---|---|
| `resolveWritePackageScope` | `:7361` | private | 40 | 252 |
The proposal also said 40 body lines.
## The shape (#23050 shape B, as cuts 1–18 apply it)
- **The class keeps the member** with its name, docblock, signature and
position. Its body now delegates, marked `[#25467 cut 19]`.
- **Typing.** `WritePackageScopeHost` types its one member as the class
member itself (`ObjectStackProtocolImplementation['engine']`). The
function types its `this` as `Pick<WritePackageScopeHost, 'engine'>`,
and the stub annotates its literal as `ThisParameterType<typeof
resolveWritePackageScope>`. No member changes visibility.
- **Members read.** The AST walk covers property and element accesses on
`this`, with `as` casts, parentheses and `!` stripped, and bare `this`
checked too. It finds `engine` only, read as `this.engine.registry`. The
engine is handed over as a live getter, so the body reads the protocol's
engine, and so its registry, at call time.
- **Every other caller still calls the class method**, as the order
asks:
- The authoring gate's host literal at `:7107` (cut 8,
`assertRuntimeAuthoringRules` → `protocol-authoring-gate.ts`) is
unchanged. It still hands over `resolveWritePackageScope: (...a) =>
this.resolveWritePackageScope(...a)`, which reaches the class stub and
then the moved body.
- `tenantAuthoredWriteRefusal` (`:16132`) is the other caller, through
`this.`.
## Module-level declarations
- **None.** The body reads no module-level declaration of `protocol.ts`
and no import binding, measured by an AST identifier walk against the
file's top-level declarations and imports. Nothing gains `export`, and
no import of `protocol.ts` changes.
- The new module imports only the class type (`import type` from
`./protocol.js`), so it adds no runtime edge to the `protocol.ts` cycle.
The one new statement in `protocol.ts` is the import of the new module.
## The durability `--list` (the order's re-measure)
The silent `catch` moved file, so the list was read at both ends.
- `check-durability-degradation-log-level` exits 0 at both ends with
identical output.
- Its `--list` is **identical once `[@:][0-9]+` is stripped**: 159
lines, and no entry changes file.
- Neither end has an entry naming `resolveWritePackageScope` or the new
module. The `catch` guards registry reads (`registry.getPackage`), not
an engine call the list enumerates.
## The published `.d.ts`
The series bar is ruling `6348891160`, sorted-union identity, measured
first.
**How it was built.** Base `77dc7062e5` and head `c5f1351978` 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. Afterwards `git diff HEAD` was
empty, `git status` was clean, and both touched blobs equalled `HEAD`'s.
The `.d.ts` was measured twice: on the pre-merge tree, and after merging
`main` (head `f4eb4330f3`, closure rebuilt by a full `pnpm build`,
119/119). The readings below hold for both. The base `.d.ts` differs
from cut 18's readings because #26305 landed in between.
- **Raw sha256**:
`a8f6adb6f9c56b8f441b7224ca8c4d43b84891bce0373446e1577a7884079dd8` at
base and at head, on both `dist/index.d.ts` and `dist/index.d.cts`,
776,660 bytes each. **Raw identity holds**, so sorted-union identity
holds too. The member stays a `private NAME;` line.
- **Normalised sha256**:
`f7f9306ed46a5605c5e4c59bbc212a7d5288061760ec85d473d2f3047a836ba5` at
both ends (80 string-literal union runs sorted; the cut 12 normaliser).
- **The two builds differ where they should**:
- `index.js` hashes `4f35935b2eaf7f2b…` at base and `9495894cdf5ce39b…`
at head.
- The `.call(host` site of `resolveWritePackageScope` occurs 0 times in
the base bundles and once in the head bundles (ESM and CJS alike).
- `function resolveWritePackageScope(` appears 0 times at base and once
at head.
- **Positive control** on the head tree: `private` was dropped from
`resolveWritePackageScope` (on disk, restored from `HEAD` under a trap)
and the package rebuilt. Both `.d.ts` files move to `cf7f37aa818a9795…`
(normalised `a7662435fc695cad…`) and print
`resolveWritePackageScope(packageId: string | null | undefined): {
packageId: string; dependencies: string[]; } | undefined;`. So the bar
can see a change on this member.
- **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. Neither the moved function
nor `WritePackageScopeHost` appears.
No changeset: `skip-changeset`, per ruling `6348891160`.
## Proof of move-only
**Body, by AST token.** The compare uses the TypeScript compiler's AST
leaf tokens, with JSDoc skipped. It covers the parameters (less the
added `this`), the return type and the body. Base `protocol.ts` at
`77dc7062e5` is compared against the head module:
```
resolveWritePackageScope: base tokens 252, head tokens 252, differ 0, text-equal(ws-collapsed, comments incl.) true
TOTAL tokens=252 differ=0 members=1
CLASS members base=301 head=301 order-same=true byte-identical=300 stubs-with-identical-docblock+signature=1 other=[]
TOP base=247 head=248 byte-identical=247
```
**Negative control.** One token was changed in an in-memory copy of the
head module (`if (dep === packageId ||` to `if (dep !== packageId ||`,
one occurrence):
```
MUTATED packages/metadata-protocol/src/protocol-write-package-scope.ts "if (dep === packageId ||" -> "if (dep !== packageId ||"
resolveWritePackageScope: base tokens 252, head tokens 252, differ 1, text-equal(ws-collapsed, comments incl.) false
TOTAL tokens=252 differ=1 members=1
```
- **Class side.** There are 301 members at base and at head, in the same
order. The 300 that did not move are byte-identical to base, leading
comments included. The stub 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`.** All 247 base statements are
byte-identical, leading comments included. Head adds one statement, the
new module's import.
- **Size.** +96 / −38 over 2 files, 134 changed lines (the proposal's
estimate was 150–200). `protocol-write-package-scope.ts` has 88 lines.
## Readers of the moved lines
I grepped every test and script that reads `protocol.ts` by path (70
files) for the member name and for its body's text (`getPackage`,
`frontier`, the `catch` comment). I also grepped every test file in
`packages/` and `ui/`, and `docs/qa/`.
- **By path: none reads the moved body.** Thirteen of them match
`getPackage`, but as a registry test double (`getPackage: () =>
undefined` and the like) or a direct registry call
(`package-dependencies-patch.integration.test.ts`), not as the moved
text.
- **Comment-only mentions, no edit owed.**
`protocol-publish-drafts-closure.test.ts` (line 228),
`packages/core/src/artifact-packages.ts` (line 130) and
`packages/lint/src/validate-list-view-field-refs.ts` (line 272) name the
method in comments. It still exists, on the class.
- **The `@objectstack/spec` liveness ledger.**
`packages/spec/liveness/manifest.json` (`dependencies` row) carries the
evidence pointer
`packages/metadata-protocol/src/protocol.ts#resolveWritePackageScope
(\`const declared = manifest?.dependencies\` inside the frontier loop
…)`.
- `check:liveness` checks that the `#symbol` is named in the file. The
method is still declared in `protocol.ts`, so the pointer resolves and
`pnpm --filter @objectstack/spec check:liveness` exits 0 at head.
- The quoted line itself now lives in `protocol-write-package-scope.ts`.
That is the same state cut 14 left `seed.json`'s
`protocol.ts#applySeedBodies` pointer in.
- Re-pointing the row is a `packages/spec/**` edit, which this card does
not make. It is disclosed here and in the report as a follow-up.
- No hit in `docs/qa/`.
- **ADR anchors.** `check-adr-anchors` exits 0 with identical output at
both ends.
- **Engine-double contract** (`check-engine-double-contract`). It exits
0 at both ends.
- The `updateData`/`deleteData` seams keep their entries at new line
numbers (13956 → 13926, 13981 → 13951).
- `productionFiles` is 3,743 at base and 3,745 at head. One of the +2 is
the new file; the other is the gitignored
`packages/spec/src/migrations/registry.ts` that 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` 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 `77dc7062e5`.
- **Governed surface.** `check-governed-merges --branch
claude/project-thread-ybjm3h` finds 0 of 2 paths in the register, so
this is NOT governed. It has 134 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` exits
0 with no output. It covers the whole touched package, which has no
`lint` script; these are the root `lint` script's flags.
- **`packages/metadata-protocol` suite**, base and head, compared per
test name and status. Both runs used vitest `--maxWorkers=2` with the
JSON reporter under the shared verify lock, with `VERDICT command-exit
0` on both legs. They ran on the pre-merge tree; the merge changed no
file of the package.
- Base `77dc7062e5`: 21,568 tests (21,549 passed, 0 failed, 19 skipped),
270 files.
- Head `c5f1351978`: 21,568 tests (21,549 passed, 0 failed, 19 skipped),
270 files.
- None lost, none added, none changed status. The base leg is the
package `src/` swapped tree-only from `77dc7062e5` (the new module
removed) and restored from `HEAD` under a trap.
- `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 51 gates on 2 changed paths from the
merged tree `f4eb4330f3`. All 51 exit 0 after the full `pnpm build`
(119/119). `dispatch-gates --ran`: 51 derived, 51 run, 0 NOT-MEASURED, 0
UNRUN, exit 0.
- The derivation flags the tree as behind `main` only for
`scripts/sdui-manifest.sources/plugin-grid.json`, which feeds none of
these 51 families. The list is the same 51 as cut 18's, so `main` was
not merged again.
- `pnpm --filter @objectstack/spec check:liveness` exits 0 at head (see
the liveness ledger above).
## Carry-forward
Unchanged from cut 18. 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,
`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 66d5cd6 commit b0376ed
2 files changed
Lines changed: 96 additions & 38 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
402 | 402 | | |
403 | 403 | | |
404 | 404 | | |
| 405 | + | |
| 406 | + | |
405 | 407 | | |
406 | 408 | | |
407 | 409 | | |
| |||
7361 | 7363 | | |
7362 | 7364 | | |
7363 | 7365 | | |
7364 | | - | |
7365 | | - | |
7366 | | - | |
7367 | | - | |
7368 | | - | |
7369 | | - | |
7370 | | - | |
7371 | | - | |
7372 | | - | |
7373 | | - | |
7374 | | - | |
7375 | | - | |
7376 | | - | |
7377 | | - | |
7378 | | - | |
7379 | | - | |
7380 | | - | |
7381 | | - | |
7382 | | - | |
7383 | | - | |
7384 | | - | |
7385 | | - | |
7386 | | - | |
7387 | | - | |
7388 | | - | |
7389 | | - | |
7390 | | - | |
7391 | | - | |
7392 | | - | |
7393 | | - | |
7394 | | - | |
7395 | | - | |
7396 | | - | |
7397 | | - | |
7398 | | - | |
7399 | | - | |
7400 | | - | |
7401 | | - | |
| 7366 | + | |
| 7367 | + | |
| 7368 | + | |
| 7369 | + | |
| 7370 | + | |
| 7371 | + | |
7402 | 7372 | | |
7403 | 7373 | | |
7404 | 7374 | | |
| |||
0 commit comments