Repository navigation
Commit 48914fd
refactor(metadata-protocol): generate the protocol.ts section split with a deterministic codemod (#29998)
<!-- claude-projects-attribution: {"github_login":"os-support-ai"} -->
_Requested by **Yibo Wang** · [project
thread](https://claude.ai/code/project/chan_01BVUyyPie8gHwoPM18iABwB?thread=cmsg_01BVUyyPie8gHwoPM18iABwB7J3TmFTYMYQrfpye6GQNg9)_
Part of #29985
## 维护者速读
- 改了什么:codemod `scripts/codemod-split-protocol.mjs` 按裁决
6624345766(门面形态,方案 A)生成 `protocol.ts`
的拆分。`ObjectStackProtocolImplementation` 成为门面:85 个成员各留一行委派,方法体移入 10 个无状态
facet 类(`<Module>Facet`,静态方法,首参是 host);私有成员的文档块随方法体移走(54
个),公开成员的文档块留在门面;只读参数的私有静态方法也移出(7 个)。状态全部留在门面。生成文件未手改。
- 为什么改:#29465 大文件拆分;裁决 6624258595 把目标改为门面形态,6624345766 把 `.d.ts`
门槛改为「公开面相等」。
- 风险与回滚:纯搬移。85/85 方法体逐字节还原;`--verify` 先把门面形态逆提回 (a) 的模块形态,再逆推出 base 的
`protocol.ts` 和 `protocol-host.ts` 逐字节相同。公开面 `.d.ts` 相等(对照抓到)。测试 base
22,346 → head 22,347(+1 条非空检查)。回滚即 revert。
- 先看:① 「门面读数」一节的例外清单(#30019 门禁的初始白名单);② codemod 的 `lift` / `unlift`;③
`check-durability-degradation-log-level.mjs` 对 `<X>Facet.fn(...)` 存根的跟随和
3 条自测。
- 两分钟验证:`pnpm install --frozen-lockfile` 后运行 `node
scripts/codemod-split-protocol.mjs --verify --base eee4149`,预期 `85/85
moved bodies restore to the base body exactly`、`23135 -> 13647
lines`,退出码 0;`--self-test` 55 例通过。
- 需要你做的:超过 3,000 行,需您批准,并在您定的窗口冻结 `protocol.ts` 后落地;本 PR 保持草稿。
Clause-②: no
Metadata-protocol: none
## What changes
- **`scripts/codemod-split-protocol.mjs`**, three additions over the
module form PR #29998 had before:
- **The facade layer** (`lift`, ruling 6624345766). Each section
module's functions become the static methods of one stateless facet
class, `<Module>Facet` (`protocol-save.ts` → `ProtocolSaveFacet`). A
method still takes the host as its first parameter, so its body is the
E1 body re-indented back to the class's depth. A facet holds no state:
every field stays on the class and is read through the host. Each stub
on the class calls `<Facet>.<member>(…)`.
- **Docblock ownership.** A private member's docblock moves verbatim
onto its facet method, and the class keeps one line: `/** Docblock and
body: {@link <Facet>.<member>} in \`<file>\` [#29985 codemod]. */`. A
public member's docblock stays on the facade, as the ruling requires, so
the published `.d.ts` and consumers' hover text are unchanged.
- **Private-static-through-host.** A private static whose body reads
nothing of the class (no `this`, `super`, `arguments` or class name)
moves to its section's facet with no host parameter. The class keeps the
delegation, so moved instance bodies still reach it as `host.<static>`.
- The pilot's `no-yield` rule (a body no longer than its stub stays) is
dropped: under the facade rule the class keeps delegations only.
- **The proof of the layer is its inverse** (`unlift`). `--verify` reads
the head alone, turns it back into the module form, and refuses anything
the lift would not have written: a public docblock moved, a stub calling
another facet, a facet member that is not a static method, a body line
the lift did not indent. It then runs every earlier proof on that module
form, `host-split.mjs`'s `checkMove` included.
- `--self-test`: 55 cases in 7 pinned batteries (a new `facade layer`
battery of 10).
- **The generated split** is `--write` on `main` `eee41490`, unedited.
Its modules are `protocol-class-head.ts`,
`protocol-discovery-and-bases.ts`, `protocol-data-crud.ts` (new),
`protocol-search-and-cache.ts`, `protocol-write-gates.ts`,
`protocol-registry-hydration.ts`, `protocol-save.ts`,
`protocol-history-and-publish.ts`, `protocol-package-commits.ts` and
`protocol-diff-delete-load.ts`. Nothing re-exports them.
- **Readers widened** (ruling 6597555122 point 3) to the facet form:
- `register-item`, `lookup-artifact-item` and `view-expansion-reconcile`
census headers accept a facet's `static` member.
- `read-verb-canonical-fold` follows `<Facet>.<fn>` stubs.
- The receive-path test reads `applyRemoteMetadataMutation` as a static
method.
- Two newly moved members are re-keyed: `isShippedByAnotherPackage` gets
a `file` row. `anotherPackageShips` is read as its delegation plus its
facet body.
- **`scripts/check-durability-degradation-log-level.mjs`**: a
`<X>Facet.fn(protocolHost(this), …)` stub, or a private static's
`<X>Facet.fn(…)`, is followed into the facet's static method. Without
that, 3 read seams left the census (102 → 99). There are three new
self-test rows, and the read-seam floor goes 70 → 73.
## Verification
| Reading | Base `eee41490` | Head |
|:--|:--|:--|
| `protocol.ts` lines | 23,135 | **13,647** |
| Byte-identity | | 85/85 bodies; `checkMove` 78/78 instance (statics
compared directly); the unlift, then the undo, rebuilds both base files
|
| Determinism | | output tree sha256
`85bbdf726e8fbb750229627f744bb152aa79fcfa02d95b939885bbdf3430fe92` on
two runs; regeneration reproduces the committed tree |
| `metadata-protocol` `typecheck` | exit 0 | exit 0 |
| `metadata-protocol` `test` | 312 files, 22,346 passed, 26 skipped |
312 files, 22,347 passed, 26 skipped |
| `check:durability-log-level` | 51 seams (9 propagating), 102 read
seams (13 discriminated) | the same, and the output is byte-identical |
| core / objectql / spec `test:repo`, `pnpm lint`, `pnpm build` | | core
94, objectql 5, spec 1,539 passed; lint exit 0; build exit 0 |
| `dispatch-gates --commands` (73) | | 73 derived, 73 run, every exit 0;
`--ran`: 0 NOT-MEASURED, 0 UNRUN |
### `.d.ts`: ruling 6624345766 item 1, "public surface EQUAL"
The reading is `dts-public.mjs`, in the project files at
`issue-29985/dts-public.mjs`, sha256
`211b32062250606e658acd7fb8880e0079b4043121fb7b970c658b4b57bf5020`. It
is dtsnorm (6441032442 B) with one step added first: every private class
member, together with its docblock, is cut from both texts. Everything
else must then be equal statement for statement, which is stricter than
item 1.
| Reading | `index.d.ts` | `index.d.cts` |
|:--|:--|:--|
| raw | differs (private docblocks, and one union order) | differs (the
same) |
| private members cut, union order, second normalisation | **equal** |
**equal** |
| declared surface | equal | equal |
- The control that edits one public docblock is caught.
- The control that drops one private member passes.
- The facet classes do not appear in the `.d.ts`.
- 6441032442 B as written reads DIFFER, from the private docblocks only.
That is what the ruling allows.
### Facade reading (the #30019 gate's starting allow-list)
- **85 members** delegate to 10 facets:
| Facet | Members | Docblocks moved |
|:--|--:|--:|
| ClassHead | 17 | 7 |
| DiscoveryAndBases | 12 | 6 |
| DataCrud | 1 | 1 |
| SearchAndCache | 1 | 0 |
| WriteGates | 18 | 17 |
| RegistryHydration | 14 | 14 |
| Save | 4 | 3 |
| HistoryAndPublish | 5 | 3 |
| PackageCommits | 9 | 2 |
| DiffDeleteLoad | 4 | 1 |
- **190 hand-series delegations** in their own forms: `.call(host, …)`
162, plain 12, `protocolHost(this)` 16. Their docblocks stay on the
class, because their modules are the hand series' and are not facets.
- **26 methods with a body stay** as named exceptions, plus the
constructor (15 lines) and the static block (the host factory, 203
lines):
- **`inferred-return-type`** (a public type the `.d.ts` would re-infer):
`getDiscovery` 460 lines, `findData` 751, `getData` 75, `cloneData` 105,
and `saveMetaItem`, `publishMetaItem`, `rollbackMetaItem`,
`deleteMetaItem` at 7 lines each.
- **`closed-set`** (outside E1's rewrite set): `publishPackageDrafts`
993 lines (a bare `this`), `reconcileViewExpansions` 53,
`packagelessOverlayWriteRefusal` 14, `namedBaseOverlayWriteRefusal` 12.
- **`static-reads-class`**: `mergesOverlayAtRead`,
`registryAllowsOverlay`, `isOverlayAllowed`, `isRuntimeCreateAllowed`,
`codeOnlySourceHint`, `codeOnlyCreateError`, `codeOnlyOverrideError`,
`refuseOrganizationScopedWrite`, `overlayPackageMismatchError`.
- **`no-host-read`**: `rethrowUnlessMetadataStoreUnprovisioned`,
`triggerAutomation`.
- **`name-taken`**: `objectExtensionItemRefusal`.
- **`host-entry-predicate`**: `packagedBaseRefusal`.
- **`static-shape`** (public static): `resetEnvWritableCache`.
### Ablations
- The facade battery's public-docblock case goes red when `unlift`'s
public-docblock check is removed.
- The durability gate's two facet rows go red when the facet branch is
removed, and the census drops to 99.
- The facade battery also checks that a one-character edit in a moved
docblock, a stub calling another facet, an extra facet member and an
unindented body line each fail.
### Findings outside this PR
`protocol-packageless-overlay-migration.ts` is #30000; it is unchanged
here.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01WGufzgddMBbTQd9yVo4Yuz
<!-- signed: domain:server#6 · os-support-ai ·
session_01WGufzgddMBbTQd9yVo4Yuz -->
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 9ebca94 commit 48914fd
25 files changed
Lines changed: 14256 additions & 10166 deletions
File tree
- packages/metadata-protocol/src
- scripts
- adr-anchors
Large diffs are not rendered by default.
| 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 | + | |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| 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 | + | |
0 commit comments