You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 43faa22
Browse filesBrowse the repository at this point in the historyBrowse files
refactor(metadata-protocol): spell the inferred return types of the eight protocol.ts doors the facade keeps (.d.ts byte-equal) (#30516)
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgKd8GqhzWbGWABewb5SLGNm)_
domain:server#5 · os-bill · session_01Utp6CYVV6fcAQrNTDQRvPb
## 维护者速读
- 改了什么:`protocol.ts` 门面上 8
个因返回类型靠推断而留在类上的公开方法(`getDiscovery`、`findData`、`getData`、`cloneData` 和四个
`*MetaItem`)把返回类型写明在签名上,类型逐字取自它今天被推断进的 `.d.ts`;方法体一行未动。
- 为什么改:返回类型靠推断时,方法体一挪走,`.d.ts` 就会经新位置重新推断(拆分时实测 `getDiscovery` 丢过一个
`@deprecated` 注释),所以它们只能留在门面上;写明之后类型不再取决于方法体放在哪。
- 风险与回滚:没有行为变化,公开 `index.d.ts` / `index.d.cts` 改前改后逐字节相同;只有 source map
随新增行变动。回滚即撤本 PR。
- 先看:`packages/metadata-protocol/src/protocol.ts` 里 `getDiscovery`
的新签名(最长的一段),再看 `scripts/facade-delegation-registry.json` 改了理由的 8 行。
- 两分钟验证:`pnpm --filter @objectstack/metadata-protocol exec vitest run
src/protocol.facade-door-return-types.pin.test.ts`,预期 9 条全绿;在 main 的
`protocol.ts` 上其中 8 条是红的。
- 需要你做的:无,席位落地。方法体搬进 facet 这一步本 PR 没做(codemod 已不能在拆好的文件上重跑,见 Acceptance
notes),`engine.ts` 那一半排在 #30055 之后。
Part of #30054 (the `protocol.ts` half, step 1 only: the return types
are spelled; the bodies stay, and the `engine.ts` half is owed. Both are
listed under Acceptance notes.)
Clause-②: no — the published `index.d.ts` and `index.d.cts` of
`@objectstack/metadata-protocol` are byte-equal before and after, so no
exported member changes.
Metadata-protocol: none
Skills-docs: none — an internal refactor of eight method signatures
whose printed types do not change; no skill text names them.
## What changes
- **`packages/metadata-protocol/src/protocol.ts`.** The eight doors the
#30019 gate lists as `inferred-return-type` exceptions on card #30054
now declare their return type: `getDiscovery`, `findData`, `getData`,
`cloneData`, `saveMetaItem`, `publishMetaItem`, `rollbackMetaItem`,
`deleteMetaItem`. Each type is copied, text for text, from the line the
base build printed for that method in `dist/index.d.ts`: the type
literals, their docblocks (the `@deprecated` on `getDiscovery`'s
`apiName`, the ones `publishMetaItem` carries), the double-quoted string
unions and the `| undefined` the printer writes are all kept, so the
declaration emit reprints them unchanged. No body, parameter or modifier
changes. `tsc --noEmit` accepts every body against its spelled type.
- **`scripts/facade-delegation-registry.json`.** The eight rows stay
(their bodies are still on the class, and the gate refuses a row whose
member is already a delegation). Their `reason` no longer says "stays
until the return type is spelled", which is now false; it says the type
is spelled and why the body still stays.
- **Pin.** `protocol.facade-door-return-types.pin.test.ts` parses
`protocol.ts` and requires each of the eight doors to carry a return
type annotation, so an edit cannot quietly drop one before a later move
would re-infer it.
- **Changeset.** `@objectstack/metadata-protocol` patch: the published
declarations are byte-equal, but the shipped source maps move with the
new lines, so the package's published files do change.
## Tests
- New pin: 9/9 pass at head. On `origin/main`'s `protocol.ts` (restored
unstaged, then put back from `HEAD`, `git diff HEAD` empty) 8 of 9 fail,
one per door.
- Ablation (once, through `scripts/ablation-replace.mjs`):
`rollbackMetaItem`'s annotation removed, anchor 1 → 0, blob `0a87e4f8` →
`ec11148a`; the pin goes 1 failed / 8 passed, naming `rollbackMetaItem`;
restored to the `HEAD` blob with `git diff HEAD` empty.
- `@objectstack/metadata-protocol` full suite at head `1777fb2d2`: 317
files passed, 4 skipped; 22,434 tests passed, 26 skipped. `pnpm
typecheck` exit 0. (The same suite ran at `63a626492`, before the second
merge: 316 files, 22,419 tests, all passing.)
- `pnpm lint` (`eslint . --no-inline-config`) exit 0 at `63a626492`; at
head `1777fb2d2`, eslint `--no-inline-config` over the two changed
source files exit 0.
## Acceptance notes
- **The move (step 2) is not mechanical today, so it is not in this
PR.** `scripts/codemod-split-protocol.mjs` cannot re-run on the landed
facade: on `origin/main` it refuses with "protocol.ts already carries
[#29985 codemod] stubs: run the script on an unsplit file". Its
regenerate-from-base route no longer holds either: `--verify --base
48914fd^` (the #29985 split's base) now reports 79/85 moved bodies
identical and 71/78 host-split checks passing, because later PRs edited
moved bodies in the facet modules (#30293, #30353, #30380, #30414), and
two facet modules gained top-level statements that are not facet methods
(`PackagedArtifactBaseType` in `protocol-discovery-and-bases.ts`,
`storedGrantObjectKeys` in `protocol-package-commits.ts`), which the
facade layer's unlift refuses. Moving the eight bodies needs a pass over
the landed facade, as the engine codemod has (`--scoped`, `--hand-docs`,
and #30055's `--members`). That is an edit to
`scripts/codemod-split-protocol.mjs`, outside this card's file surface;
carrier: the seat.
- **Rows still owed on #30054.** `protocol.ts` (body move):
`getDiscovery`, `findData`, `getData`, `cloneData`, `saveMetaItem`,
`publishMetaItem`, `rollbackMetaItem`, `deleteMetaItem`. `engine.ts`
(types and move, serial behind #30055): `registerApp`, `registerHook`,
`registerDriver`, `init`, `triggerHooks`, `destroy`,
`setDatasourceMapping`, `getStatus`.
- **A spelled type is now the published shape, so it must move with the
body.** TypeScript does not refuse a body that returns a wider object
than its signature (a non-literal return gets no excess-property check),
and the `.d.ts` prints the signature, not the body. Measured on this
branch: `origin/main` gained `seedApplied.landed` on the publish receipt
(#30427, `a7b8876f5`) while this PR was open; the branch's first
spelling (copied at `c5800818`) merged with no conflict, and would have
dropped `landed` from the published `publishMetaItem` type. The type was
re-copied from `a1d0b1ee9`'s build (commit `1777fb2d2`), and the proof
below is against that base. A later change to what one of these doors
returns edits the signature too.
- No `packages/objectql` file changes, so its declaration files are not
re-proved here.
## Verification
Head `1777fb2d2` (branch merged with `origin/main` `a1d0b1ee9`), base
`a1d0b1ee9`.
<details><summary>Declaration-file proof</summary>
- Base: `origin/main` `a1d0b1ee9`'s `protocol.ts` restored into the
merged tree (the merged file differs from it only by the eight
annotations), `turbo run build
--filter=@objectstack/metadata-protocol...`, `dist/index.d.ts` and
`dist/index.d.cts` copied aside. The eight types were copied from that
`index.d.ts`.
- Head `1777fb2d2`: `pnpm build` in `packages/metadata-protocol` (tsup
with DTS, then `check-dts-emitted`: 2/2 declaration files present);
`cmp` against the base copies: `index.d.ts` byte-equal, `index.d.cts`
byte-equal (`index.d.ts` sha256 `f7c56a2155a2b77a…` on both sides).
- The same proof ran first at base `c5800818` (byte-equal, sha256
`2f93f627839cccd7…`), before the merge that brought #30427.
- The diff of the emitted declarations is empty.
</details>
<details><summary>Gates</summary>
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` at head `1777fb2d2`: 69 derived commands
(change set: 4 paths, +251 / -16, under the 3,000 threshold). Each was
run with its exit code recorded before any pipe; all 69 exit 0. `--ran`
reconciles 69 derived, 69 run, 0 NOT-MEASURED, 0 UNRUN.
`check-plugin-teardown-shape --self-test` needed `git fetch origin
621a487…` first (shallow clone).
- The first pass at `63a626492` (same 69 commands) had 68 exit 0 and
`check:dual-build-cjs-loads` exit 3 (no full workspace build then); at
the final head it ran and passed.
- `pnpm check:facade-delegation-only`: "5 facade class(es) in 3 file(s)
hold delegations only", exit 0; the registry still carries the eight
rows.
- eslint over the two changed source files exit 0 at head; `pnpm lint`
exit 0 at `63a626492`.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CXZTh9qvT24wTN6dd6)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
refactor(metadata-protocol): the eight `ObjectStackProtocolImplementation` doors that kept an inferred return type spell it on the signature
6
+
7
+
Clause-②: no
8
+
Metadata-protocol: none
9
+
10
+
-`getDiscovery`, `findData`, `getData`, `cloneData`, `saveMetaItem`, `publishMetaItem`, `rollbackMetaItem` and `deleteMetaItem` now declare their return type, copied from the published declaration file it was inferred into. The built `index.d.ts` and `index.d.cts` are byte-equal before and after, and no behaviour changes; only the source maps move with the new lines. Nothing to do on upgrade.
"reason": "inferred-return-type (#29985 report: stays on the class until the return type is spelled)"
34
+
"reason": "returntype spelled on the signature (#30054 step 1, public .d.ts byte-equal); the body stays until the protocol.ts codemod can move a member of the landed facade (it refuses its own output, and the split no longer re-proves from its #29985 base)"
"reason": "inferred-return-type (#29985 report: stays on the class until the return type is spelled)"
40
+
"reason": "returntype spelled on the signature (#30054 step 1, public .d.ts byte-equal); the body stays until the protocol.ts codemod can move a member of the landed facade (it refuses its own output, and the split no longer re-proves from its #29985 base)"
"reason": "inferred-return-type (#29985 report: stays on the class until the return type is spelled)"
46
+
"reason": "returntype spelled on the signature (#30054 step 1, public .d.ts byte-equal); the body stays until the protocol.ts codemod can move a member of the landed facade (it refuses its own output, and the split no longer re-proves from its #29985 base)"
"reason": "inferred-return-type (#29985 report: stays on the class until the return type is spelled)"
52
+
"reason": "returntype spelled on the signature (#30054 step 1, public .d.ts byte-equal); the body stays until the protocol.ts codemod can move a member of the landed facade (it refuses its own output, and the split no longer re-proves from its #29985 base)"
"reason": "inferred-return-type (#29985 report: stays on the class until the return type is spelled)"
58
+
"reason": "returntype spelled on the signature (#30054 step 1, public .d.ts byte-equal); the body stays until the protocol.ts codemod can move a member of the landed facade (it refuses its own output, and the split no longer re-proves from its #29985 base)"
"reason": "inferred-return-type (#29985 report: stays on the class until the return type is spelled)"
64
+
"reason": "returntype spelled on the signature (#30054 step 1, public .d.ts byte-equal); the body stays until the protocol.ts codemod can move a member of the landed facade (it refuses its own output, and the split no longer re-proves from its #29985 base)"
"reason": "inferred-return-type (#29985 report: stays on the class until the return type is spelled)"
70
+
"reason": "returntype spelled on the signature (#30054 step 1, public .d.ts byte-equal); the body stays until the protocol.ts codemod can move a member of the landed facade (it refuses its own output, and the split no longer re-proves from its #29985 base)"
"reason": "inferred-return-type (#29985 report: stays on the class until the return type is spelled)"
76
+
"reason": "returntype spelled on the signature (#30054 step 1, public .d.ts byte-equal); the body stays until the protocol.ts codemod can move a member of the landed facade (it refuses its own output, and the split no longer re-proves from its #29985 base)"
0 commit comments