Repository navigation
Commit a59d00a
fix(scripts,objectql): codemod-split-engine --members reads hand-written facet headers and inverts its import edits; move registerApp, registerDriver and registerHook (#30716)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} -->
_Requested by **Elon** · [project
thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9D6AnW6Yh9CRooCGz4c48JoP)_
domain:devx#3 · os-elon-musk · session_016WV4cwSsWgu5WEWLNtFrf3
Fixes #30572
Refs #30054
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:`scripts/codemod-split-engine.mjs --members` 现在接受「模块头被手工续写过」的
facet 模块,并且在搬移改动了接收模块 import 块时,仍能逐字节证明撤销;随后用它把
`registerApp`、`registerDriver`、`registerHook` 三个方法体搬进各自的
facet,并删掉登记表里对应的三行例外。
- 为什么改:#30054 的 PR #30571 搬了五个方法体,这三个被 codemod
拒绝(`engine-registration.ts` 的模块头被手改过;`registerHook` 的撤销证明在 import
块处失败),只能留在类上当例外。
- 风险与回滚:纯搬移,运行时行为不变;`@objectstack/objectql` 构建出的三个 `.d.ts`
在搬移前后逐字节相同。撤销证明仍是逐字节比较,没有做任何空白或 import 归一化。回滚即 revert 本 PR。
- 先看:`scripts/codemod-split-engine.mjs` 的 `headerNamesOf` 与
`importEditsOf`;`packages/objectql/src/engine-hooks-and-functions.ts` 的
import 块。
- 两分钟验证:`node scripts/codemod-split-engine.mjs --members --verify --base
origin/main`,预期最后一行写 "undoing the moves does rebuild the base engine.ts
and its modules byte-for-byte",exit 0;`node
scripts/codemod-split-engine.mjs --self-test` 预期 129 cases pass。
- 需要你做的:无,席位落地。
## What changes
- **`scripts/codemod-split-engine.mjs`, fourth pass (`--members`), two
shapes it used to refuse:**
- **A header a hand edit wrote on after.** `engine-registration.ts`'s
header carries a sentence written by hand after the generated one
(`isExternalWriteForbidden` was written there by hand). `headerNamesOf`
now reads the words after the header sentence, in the same paragraph, as
a `tail`, and accepts the header only when `moduleHeaderLines(title,
names, tail)` rewraps to it byte for byte. The pass rewrites the
sentence it owns (the list grows) and carries the tail over unedited;
the undo rewraps the same tail. A tail that does not rewrap as the pass
wraps it is still refused.
- **An import edit the prune cannot take back.** `registerHook`'s
parameter docblock links `HookEntry`, so the move adds `HookEntry` to
the module's `import type` from `./engine-top-level.js`. The base module
already carried an unresolved `{@link
HookEntry.dispatchUnscopedMultiWrite}` in a staying docblock; once the
binding exists, that link resolves, so "prune what nothing reads" keeps
it and the undo stopped one line short of the base. `importEditsOf` now
reads the edits the move made off the base and head import blocks
(bindings added, and bindings widened from type-only to value) and the
undo inverts exactly those, then prunes as before. Each inverted edit is
checked: a moved member's own text must read the name, and a head that
dropped or narrowed a base binding fails, since no undo could restore
it. The lines left are rendered as the first pass writes them, and the
result is still compared with the base byte for byte.
- **The three moves**, written by the codemod on the latest `main`:
`registerApp` and `registerDriver` into `engine-registration.ts`,
`registerHook` into `engine-hooks-and-functions.ts`. The stubs, facet
members, host interfaces, host factories and imports are the pass's own
output. `engine.ts` goes from 11,309 to 11,086 lines.
- **`scripts/facade-delegation-registry.json`**: the three `#30054` rows
for these members are removed; `check:facade-delegation-only` is green
with 53 named exceptions.
- **`.changeset/30572-objectql-registration-bodies.md`**:
`@objectstack/objectql` patch, following PR #30571's changeset.
## Tests
The codemod's self-test (`node scripts/codemod-split-engine.mjs
--self-test`): 129 cases in 9 batteries pass. The fourth-pass battery
gains five cases, and its pinned floor goes from 18 to 23:
1. a header a hand edit wrote on after is accepted: the list grows, the
hand's words follow it unedited, and the moves prove;
2. a hand tail that does not rewrap as the pass wraps it refuses;
3. one edited character in the hand's words at head fails;
4. a base docblock link that a moved body's import comes to resolve: the
undo drops the binding the move added, and the moves prove byte for
byte;
5. a binding the head added that only a staying docblock links, and no
moved member reads, fails.
<details><summary>Reverse verification (one-time, run on the committed
fix, restored to the HEAD blob)</summary>
- `importEditsOf` made to return no edits: case 4 goes red ("undoing the
moves out of engine-lifecycle.ts does not rebuild its base (first
difference at line 41)"), and `--members registerHook` on the real tree
fails again at line 46 of `engine-hooks-and-functions.ts`, the card's
refusal.
- `headerNamesOf` made to accept no tail: the self-test stops at
"engine-lifecycle.ts: its header is not as the first pass wrote it", and
`--members registerApp` on the real tree refuses again with the card's
message.
- After each, `git checkout HEAD -- scripts/codemod-split-engine.mjs`
and `git status --porcelain` empty.
</details>
## Verification
Final head is the merge of `origin/main` `a2437b56` (which edited
`registerApp`'s body in #30656) into this branch; the moves were
regenerated on that `main` rather than text-merged.
- Before (`main` `f4d568ba`): `--members registerApp` / `registerDriver`
refused with "engine-registration.ts: its header is not as the first
pass wrote it" (exit 2); `--members registerHook` failed the undo proof
at line 46 of `engine-hooks-and-functions.ts` (exit 1; the card recorded
line 44 on an older `main`).
- After: `node scripts/codemod-split-engine.mjs --members --verify
--base a2437b5` exits 0: "3 moved method(s) (registerHook,
registerApp, registerDriver); engine.ts 11309 -> 11086 lines; undoing
the moves does rebuild the base engine.ts and its modules byte-for-byte
once the 7 import binding(s) only moved bodies read are pruned from the
base".
- Public `.d.ts` for `@objectstack/objectql`: built at base `a2437b56`
and at head; `dist/index.d.ts`, `dist/core.d.ts` and
`dist/util-B0RqjNMv.d.ts` are byte-equal (sha256 `4d00ae43…`,
`a0cdd71a…`, `69f1c293…` on both sides). Control:
`RegistrationFacet.registerApp` occurs 0 times in the base
`dist/index.js` and once in the head's, so each side's build is its own.
- `pnpm --filter @objectstack/objectql typecheck`: exit 0 (including
`check:test-typecheck`). `pnpm --filter @objectstack/objectql test`: 556
files, 11068 tests passed (lock VERDICT command-exit 0), at head
`3e387e33`.
- `node scripts/pm/dispatch-gates.mjs --commands`: 73 families derived
at head `3e387e33`; 72 exit 0. `pnpm check:dual-build-cjs-loads` is NOT
MEASURED locally (exit 3, PREREQUISITE NOT MET: it reads every package's
`dist/`, and only the `@objectstack/objectql` closure was built here);
CI runs it in `Lint & Repo Gates`. `--ran`: 73 derived, 72 run, 1
NOT-MEASURED, 0 UNRUN. The codemod's own self-test (above) is outside
the derived set and was run separately.
## Acceptance notes
- The undo is no longer computed from the head alone for the import
block: it reads the base's binding names to know which bindings the move
added. That is the information the head cannot carry (two different
bases give the same head when a staying docblock links a name a moved
body imports). The comparison itself is unchanged, byte for byte, and
every edit it inverts must be one a moved member's text reads.
- Sibling #30518 edits `scripts/codemod-split-protocol.mjs` and other
rows of `scripts/facade-delegation-registry.json`; this PR does not
touch that codemod. Whichever lands second merges `main`.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(Not touched.)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` is CI's run.
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (Not touched.)
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English (the 维护者速读 block is the
lane's maintainer summary).
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
---
_Generated by [Claude
Code](https://claude.ai/code/session_016WV4cwSsWgu5WEWLNtFrf3)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 2038c56 commit a59d00a
7 files changed
Lines changed: 477 additions & 316 deletions
File tree
- .changeset
- packages
- objectql/src
- spec/liveness
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
46 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
47 | 50 | | |
48 | 51 | | |
49 | 52 | | |
| |||
95 | 98 | | |
96 | 99 | | |
97 | 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 | + | |
98 | 178 | | |
99 | 179 | | |
100 | 180 | | |
| |||
0 commit comments