Repository navigation
Commit 0479cd6
<!-- 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 13 of the `protocol.ts` split (#24586 ruling A, recorded in
`6270097840`). Cuts 1–12 landed as #25494, #25518, #25538, #25589,
#25601, #25623, #25642, #25719, #25731, #25740, #25797 and #25939. The
claim is `6409240079`; the scope is the cut 13 proposal of the cut 12
report (`6408535757`), as the server seat approved it in its dispatch
order, **narrowed by one member** (below).
Two `ObjectStackProtocolImplementation` members move unedited into a new
module,
`packages/metadata-protocol/src/protocol-packaged-base-refusal.ts`
(#23050 shape B): the package door's save refusal
`refusePackagedBaseOverride` and the origin-gated removal verdict
`originGatedRemovalRefusal`. `protocol.ts` loses 61 net lines (29,681 to
29,620). The cut is move-only, and the card stays open for later cuts.
## The scope narrowed: `refusePackagedBaseRemoval` stays in the class
The proposal (my cut 12 report) named three members and said none reads
a private-static member. That reading was wrong for one of them: it
grepped the one-line spelling `ObjectStackProtocolImplementation.NAME`,
and `refusePackagedBaseRemoval` breaks that spelling across two lines
(`ObjectStackProtocolImplementation` then
`.mergesOverlayAtRead(request.type)`). `mergesOverlayAtRead` is `private
static`, and the Release's stay list keeps the private-static readers in
the class, which this order's rulings hold. So
`refusePackagedBaseRemoval` stays, unedited, and the re-measure below
walks the AST (a property access on the class identifier), not the text.
The two members that move read no static member at all.
**Does `packagedBaseRefusal` ride along?** No. It is not a small private
helper: it is a public member (the `/automation` domain of
`@objectstack/runtime` calls it), it reads the private static
`isPackagedBaseRefusal`, and it calls `refusePackagedBaseRemoval`, which
stays. It stays in the class and is handed to the moved
`originGatedRemovalRefusal` as a closure.
Branch `claude/project-thread-ybjm3h` is the harness-pinned branch for
this thread, restarted from `main` after cut 12 merged. It names no
issue, so the claim comment is the identity record. It holds the move
commit `ed0ca2d57` and the pin commit `1c09db420`, both on `main`
`7a04ba288d` (cut 12's merge `efe35983f8` and #25935 are in its
history), and the merge of `main` `59d9181ed` (`b1ac1d8a9`). That merge
brought six commits, none of which touches `packages/metadata-protocol/`
(the package's `src/` tree is `761912e9` at both ends of the range).
**Serial with the file's in-flight PRs.** Measured just before this PR
was opened: of the 14 open PRs, one touches
`packages/metadata-protocol/src/`: #25941 edits
`metadata-diagnostics.ts` and adds its memo test, disjoint from
`protocol.ts`. #25826 is no longer open. The release PR #25640's file
list could not be paged through this container's proxy; at cut 11 it
touched only the package's `CHANGELOG.md` and `package.json`. No open PR
edits `protocol.ts`.
## What moves
| Member | Base line | Visibility | AST tokens (params + return + body)
|
|---|---|---|---|
| `refusePackagedBaseOverride` | `:16370` | private | 136 |
| `originGatedRemovalRefusal` | `:16534` | private | 43 |
(`refusePackagedBaseOverride`'s 72 body lines are mostly its record
comment; comments are not AST tokens, and the comparison below checks
them as text.)
## The shape (#23050 shape B, as cuts 1–12 apply it)
- **The class keeps every member** with its name, docblock, signature
and position. Each body is now one host literal plus a `.call`, marked
`[#25467 cut 13]`.
- **Typing.** `PackagedBaseRefusalHost` 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 cast, no generic member (so the plain `.call` spelling), and no
member changes visibility.
- **Members read, measured.** `refusePackagedBaseOverride` reads
`isSealedManagedItem` and `isWritablePackage`;
`originGatedRemovalRefusal` reads `packagedBaseRefusal`. Each goes as a
closure on the protocol. No field is read, so there is no getter.
- **Every other caller still calls the class method**: `saveMetaItem`
and `packagedBaseRefusal` call `refusePackagedBaseOverride`;
`deleteMetaItem` calls `originGatedRemovalRefusal`.
## Module-level declarations, by reader
- **None gains `export`, none moves.** The bodies read no module-level
declaration of `protocol.ts`. They read `SysMetadataRepository` (its
static `readOnlyBaseOverrideError`), `managedItemSealedSentence` and
`isOriginGatedType`, which the new module imports from where
`protocol.ts` imports them (`./sys-metadata-repository.js`,
`./packaged-base-regime.js`). The new module's only import from
`protocol.js` is a type import, so it adds no runtime cycle.
- **Imports in `protocol.ts`.** One name loses its last reader and is
dropped: `isOriginGatedType` from `./packaged-base-regime.js` (at base:
the import, the body of `originGatedRemovalRefusal`, and a `{@link}` in
its docblock, which stays as prose). 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. Base `7a04ba288d` and head were built with `pnpm --filter
@objectstack/metadata-protocol build` against one dependency tree (the
closure built at head by a full `pnpm build`, 119/119, then the
package's `src/` swapped tree-only to base for the base build and
restored from `HEAD` under a trap; `git diff HEAD` empty, `git status`
clean and all three touched blobs equal to `HEAD`'s after). Measured
twice: on the pre-merge tree (base `7a04ba288d`, head `1c09db420`) and
after the merge (merged base, head `b1ac1d8a9`, 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. Both members stay `private NAME;` lines.
- **Normalised sha256**:
`46ccd7e5c4db673652513d1801ec9c9f06bf34a0a7fb6ba97fb2531ef0cc544b` at
both ends (80 string-literal union runs sorted; this series' cut 12
normaliser).
- **The two builds differ where they should**: `index.js` hashes
`53d93de18be521db…` at base and `4d3c4c7364445db0…` at head; each of the
two functions' `.call(host` sites occurs 0 times in the base bundles and
once in the head bundles (ESM and CJS alike).
- **Positive control** on the head tree (on disk, restored from `HEAD`
under a trap, hash equal to `HEAD`'s after): `private` dropped from
`originGatedRemovalRefusal` and the package rebuilt. Both `.d.ts` files
move to `fec45eed6afc2fff…`, 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. Neither moved function nor
the host type 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): 179 tokens compared, **0 differ**. The parameter, return-type and
body text, comments included, is also equal with whitespace collapsed,
for both. Negative control: one changed token in
`refusePackagedBaseOverride`'s body (`namedBase &&` to `namedBase ||`,
on an in-memory copy) makes the check report `differ=1` on that member
and 0 on the other.
- **Class side.** 300 members at base and at head, in the same order.
The 298 that did not move are byte-identical to base, leading comments
included. Each of the 2 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`.** 240 of the 241 base statements other
than the class are byte-identical, leading comments included. The other
one is the `./packaged-base-regime.js` import, which loses
`isOriginGatedType`. Head adds one statement, the new module's import.
- **Size.** +157 / −75 over 3 files, 232 changed lines (the order's
estimate was 250–320 for three members; the narrowed cut is smaller).
`protocol-packaged-base-refusal.ts` has 140 lines.
## Readers of the moved lines
Every test and script that reads `protocol.ts` by path, and every test
file in `packages/` and `scripts/`, was grepped for the three proposed
member names and the host name; so was `docs/qa/`, which cites methods
by name.
- `protocol.packaged-base-refusal.test.ts` (lines 9, 225, 231),
`protocol.package-door-before-gates.test.ts` (line 7) and objectql
`engine-security-catalog-package-door.test.ts` (line 13) name
`refusePackagedBaseOverride` / `refusePackagedBaseRemoval` **in comments
only**; none reads `protocol.ts` by path or asserts on the bodies' text.
Verdict: no edit owed; all three pass at head (see Verification).
- `docs/qa/platform-checklist/areas/access-security.json` cites
`packages/metadata-protocol/src/protocol.ts#refusePackagedBaseOverride`
as an anchor (line 1517) and in prose (line 1459). The method keeps its
name in `protocol.ts`, and `check-platform-checklist --changed-from
origin/main` judges it: OK, 1 anchored file in the change set, 29
anchors judged, 0 lost.
- No other hit outside `CHANGELOG.md` entries.
- **Bracketed-refusal pin** (`PRODUCERS`):
`refusePackagedBaseOverride`'s one `new Error(` moves with its body, so
the new module gets a row, `'protocol-packaged-base-refusal.ts': 1`, the
module's own count (the order's "two" counted the one in
`refusePackagedBaseRemoval`, which stays). `protocol.ts` goes from 72 to
71 such sites, still above its floor of 5. Control: with that throw
changed to `new TypeError(` (on disk, restored from `HEAD` under a trap,
hash equal to `HEAD`'s after; on-disk counts read first: 0 `new Error(`,
1 `new TypeError(`), the new row fails with
"protocol-packaged-base-refusal.ts no longer constructs errors here —
this pin is scanning the wrong file: expected 0 to be greater than or
equal to 1" (1 failed, 14 passed); restored, 15/15 pass.
- **ADR anchors and decision letters.** `check-adr-anchors` exits 0 at
both ends: 85 anchored files, 58,860 citations, files 8,259 → 8,260, and
**1,847 → 1,843** decision-letter citations. The four that leave the
anchored file are comments in `refusePackagedBaseOverride`'s body: three
`ADR-0131 D6` and one `ADR-0070 D1`. The `protocol.ts` anchor entry's
four paragraphs (ADR-0029 D9.8/D9.9 object hydration, ADR-0119 atomic
batches, ADR-0005 appendix (c) view storage, ADR-0126 §2 / §3 flow
regime) do not describe the package door, so the new module gets no
entry (disclosure only, as cuts 8 and 12 disclosed theirs). `ADR-0005`,
which the moved comments also cite, stays referenced from `protocol.ts`
(the gate's "every governing ADR still referenced" holds).
- **Durability checker**: `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): the moved bodies hold no
`try`/`catch`.
- **Engine-double contract** (`check-engine-double-contract`): exits 0
at both ends. The `updateData`/`deleteData` seams keep their entries at
new line numbers (14083 → 14085, 14108 → 14110). `productionFiles` is
3,707 at base and 3,709 at head: +1 is the new file, +1 is the
gitignored `packages/spec/src/migrations/registry.ts`, which the spec
build writes in the head tree and the clean base tree had not built.
- **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-nul-bytes` differs only in the scanned file count, +1. The
base-end readings were taken in a clean detached worktree at
`7a04ba288d`.
- **Governed surface.** `check-governed-merges --branch
claude/project-thread-ybjm3h`: 0 of 3 paths hit the register, NOT
governed; 232 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 `7a04ba288d`: 21,537 tests (21,518 passed, 0 failed, 19 skipped),
267 files.
- Head `1c09db420`: 21,538 tests (21,519 passed, 0 failed, 19 skipped),
267 files.
- None lost, none changed status, one added: the new `PRODUCERS` row's
case. The base leg is the package `src/` swapped tree-only from
`7a04ba288d` (the new module removed from the tree) and restored from
`HEAD` under a trap.
- **Cross-package pin named in prose.** objectql
`engine-security-catalog-package-door.test.ts` at head `b1ac1d8a9`,
under the verify lock: 1 file, 18/18 passed, `VERDICT command-exit 0`.
The two metadata-protocol pins named above ran inside the package suite
and pass at both ends.
- **Derived gates.** `dispatch-gates --commands --repo
objectstack-ai/objectstack` derives 59 gates on 3 changed paths, the
same list before and after the merge; all 59 exit 0 on the merged tree
`b1ac1d8a9`, after the full `pnpm build` and with the plugin-teardown
fixture commit fetched first. `dispatch-gates --ran`: 59 derived, 59
run, 0 NOT-MEASURED, 0 UNRUN, exit 0.
## Acceptance notes
- `refusePackagedBaseRemoval` and `refusePackagedBaseOverride` now live
in two files, though their docblocks describe them as twins (one
predicate, `isSealedManagedItem`). The removal twin can follow only once
private-static readers can move (the stay list's reason); until then the
class docblocks, which did not move, still name each other with
`{@link}`.
- The proposal's static-read screen was a text grep and missed a
two-line spelling; this cut's screen walks the AST. The cut 14 proposal
in the report was screened the same way.
## Carry-forward
Unchanged from cut 12: 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 the private-static readers (now
named among them: `refusePackagedBaseRemoval` and `packagedBaseRefusal`,
besides `runPublishSideEffects`, `promoteDraftForPublish`,
`publishPackageDrafts` and `discardPackageDrafts`) stay in
`protocol.ts`.
---
_Generated by [Claude
Code](https://claude.ai/code/session_016SP1spj613tyGCgxoD1An6)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent cdd4eea commit 0479cd6
3 files changed
Lines changed: 157 additions & 75 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 | + | |
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
90 | 90 | | |
91 | 91 | | |
92 | 92 | | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
93 | 96 | | |
94 | 97 | | |
95 | 98 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
62 | | - | |
| 62 | + | |
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
| |||
396 | 396 | | |
397 | 397 | | |
398 | 398 | | |
| 399 | + | |
| 400 | + | |
399 | 401 | | |
400 | 402 | | |
401 | 403 | | |
| |||
16370 | 16372 | | |
16371 | 16373 | | |
16372 | 16374 | | |
16373 | | - | |
16374 | | - | |
16375 | | - | |
16376 | | - | |
16377 | | - | |
16378 | | - | |
16379 | | - | |
16380 | | - | |
16381 | | - | |
16382 | | - | |
16383 | | - | |
16384 | | - | |
16385 | | - | |
16386 | | - | |
16387 | | - | |
16388 | | - | |
16389 | | - | |
16390 | | - | |
16391 | | - | |
16392 | | - | |
16393 | | - | |
16394 | | - | |
16395 | | - | |
16396 | | - | |
16397 | | - | |
16398 | | - | |
16399 | | - | |
16400 | | - | |
16401 | | - | |
16402 | | - | |
16403 | | - | |
16404 | | - | |
16405 | | - | |
16406 | | - | |
16407 | | - | |
16408 | | - | |
16409 | | - | |
16410 | | - | |
16411 | | - | |
16412 | | - | |
16413 | | - | |
16414 | | - | |
16415 | | - | |
16416 | | - | |
16417 | | - | |
16418 | | - | |
16419 | | - | |
16420 | | - | |
16421 | | - | |
16422 | | - | |
16423 | | - | |
16424 | | - | |
16425 | | - | |
16426 | | - | |
16427 | | - | |
16428 | | - | |
16429 | | - | |
16430 | | - | |
16431 | | - | |
16432 | | - | |
16433 | | - | |
16434 | | - | |
16435 | | - | |
16436 | | - | |
16437 | | - | |
16438 | | - | |
16439 | | - | |
16440 | | - | |
16441 | | - | |
16442 | | - | |
16443 | | - | |
16444 | | - | |
| 16375 | + | |
| 16376 | + | |
| 16377 | + | |
| 16378 | + | |
| 16379 | + | |
| 16380 | + | |
16445 | 16381 | | |
16446 | 16382 | | |
16447 | 16383 | | |
| |||
16532 | 16468 | | |
16533 | 16469 | | |
16534 | 16470 | | |
16535 | | - | |
16536 | | - | |
| 16471 | + | |
| 16472 | + | |
| 16473 | + | |
| 16474 | + | |
| 16475 | + | |
16537 | 16476 | | |
16538 | 16477 | | |
16539 | 16478 | | |
| |||
0 commit comments