Skip to content

Commit 860df72

Browse files
refactor(metadata-protocol): move the object-owner verdicts out of protocol.ts into protocol-object-owner.ts (#25467 cut 17) (#26264)
<!-- 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 17 of the `protocol.ts` split (#24586 ruling A, recorded in `6270097840`). Cuts 1–16 landed as #25494, #25518, #25538, #25589, #25601, #25623, #25642, #25719, #25731, #25740, #25797, #25939, #25972, #26014, #26104 and #26168. The claim is `6421301816`; the scope is the cut 17 proposal of the cut 16 report (`6418840219`), as the server seat approved it in its dispatch order. Both members passed the AST screen and moved unedited, so no member was left behind. `ensureObjectStorage` stays where it is, per the order. Two `ObjectStackProtocolImplementation` members move unedited into a new module, `packages/metadata-protocol/src/protocol-object-owner.ts` (#23050 shape B). They are the object-owner verdicts: - `classifyObjectContribution`: which contributor kind (`own`, `overlay` or `mismatch`) a stored object row registers as, judged against the registry's packaged owner of that name, or its runtime owner when there is none. - `releaseAdoptedObjectOwner`: hands an adopted object's name from the `'sys_metadata'` sentinel owner to its rebound row. `protocol.ts` loses 37 net lines (29,327 to 29,290). 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, restarted from `main` `df8aac41f2` after cut 16 merged. It names no issue, so the claim comment is the identity record. It holds the move commit `4d5121bee` and three merges of `main`: `f2e7083695` (`1c5dda251`), then `81bba6c3f5` (`2c409efd84`) and `3d50a43bcb` (`5e5bf4438e`), the last two because `dispatch-gates` printed STALE TREE for gate sources that `main` had changed. No merge touches a file of `packages/metadata-protocol/src/`: the package's `src/` tree is `575f85d7` at the move commit and at every merge. The merges do change `packages/metadata-protocol/package.json` (`sideEffects: false` and the repository URL) and its `tsconfig.json` (now extends `tsconfig.base.json`), so the workspace was rebuilt in full after them and the package re-measured (below). **Serial with the file's in-flight PRs.** Measured just before this PR was opened: of the 36 open PRs, two touch `packages/metadata-protocol/src/`. - #26244 edits `protocol.ts` (+5 / −2): the import block at `:163` and a hunk at `:23178`. Neither is in a moved member or its stub, and `git merge-tree` of this branch with #26244's head is clean. - #26138 edits seven `protocol.*.test.ts` files, none of which names a moved member. No open PR edits the new module. ## The order's screen (private statics, `new Error(`) Both members passed: - **No private-static read.** The AST walk found no access on the `ObjectStackProtocolImplementation` identifier and none on `this.constructor` in either body. - **No error constructed.** Neither body has a `new Error(` or any other error constructor, so no `PRODUCERS` row is owed. `releaseAdoptedObjectOwner` has one `catch`, which logs through `console.error` and answers `false`; it moves with its body (see the durability `--list` below). ## What moves | Member | Base line | Visibility | Body lines | AST tokens (params + return + body) | |---|---|---|---|---| | `classifyObjectContribution` | `:17512` | private | 29 | 221 | | `releaseAdoptedObjectOwner` | `:26125` | private | 22 | 185 | 51 body lines (the proposal said about 55). ## The shape (#23050 shape B, as cuts 1–16 apply it) - **The class keeps every member** with its name, docblock, signature and position. Each body now delegates, marked `[#25467 cut 17]`. - **Typing.** `ObjectOwnerHost` types its one member as the class member itself (`ObjectStackProtocolImplementation['engine']`). Each moved function types its `this` as `Pick<ObjectOwnerHost, 'engine'>`, and each stub annotates its literal as `ThisParameterType` of `typeof fn`. No member changes visibility. - **Members read, measured by AST walk** (property and element accesses on `this`, with `as` casts, parentheses and `!` stripped; bare `this` checked too): both bodies read `engine` only (through `(this.engine as any)?.registry`). It 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**: `classifyObjectContribution` from `applyObjectRegistryMutation`, `saveMetaItem`, `promoteDraftForPublish` and `loadMetaFromDb` (4 `this.` call sites), and `releaseAdoptedObjectOwner` from `reassignOrphanedMetadata` (1). ## Module-level declarations - **None moves and none gains `export`.** Neither body reads a module-level declaration of `protocol.ts`, and neither reads an import. The new module imports only the class type (`import type` from `./protocol.js`), so it adds no runtime edge to the `protocol.ts` cycle. - **Imports in `protocol.ts`.** No import loses its last reader. The one new statement is the import of the new module. ## The durability `--list` `releaseAdoptedObjectOwner`'s `catch` moved file, so the list was read at both ends. `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; no entry changes file, and no entry names either moved member at either end). The `catch` guards `registry.unregisterObject`, a registry call, and the list names no entry for it at either end. ## The published `.d.ts` The series bar is ruling `6348891160`, sorted-union identity, measured first. Base `df8aac41f2` and head `4d5121bee` 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; `git diff HEAD` was empty, `git status` clean, and both touched blobs equal to `HEAD`'s after. Measured on the pre-merge tree, and again after each merge of `main` (heads `1c5dda251`, `2c409efd84` and `5e5bf4438e`, the last two after a full `pnpm build`, 119/119). The readings below hold for every one. - **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; the cut 12 normaliser). - **The two builds differ where they should**: `index.js` hashes `bfb1ef96fc8499bc…` at base and `8732ec7d7e0d5cd5…` at head. The `.call(host` sites of `classifyObjectContribution` and `releaseAdoptedObjectOwner` occur 0 times in the base bundles and once each in the head bundles (ESM and CJS alike). - **Positive control** on the head tree: `private` was dropped from `classifyObjectContribution` (on disk, restored from `HEAD` under a trap) and the package rebuilt. Both `.d.ts` files move to `c685a8419f36b078…` (normalised `524c41057de3c18c…`) and print `classifyObjectContribution(name: string, rowPackageId: string | null | undefined): { kind: 'own' | 'overlay'; …`, 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 `ObjectOwnerHost` 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), base `protocol.ts` at `df8aac41f2` against the head module: ``` classifyObjectContribution: base tokens 221, head tokens 221, differ 0, text-equal(ws-collapsed, comments incl.) true releaseAdoptedObjectOwner: base tokens 185, head tokens 185, differ 0, text-equal(ws-collapsed, comments incl.) true TOTAL tokens=406 differ=0 members=2 CLASS members base=300 head=300 order-same=true byte-identical=298 stubs-with-identical-docblock+signature=2 other=[] TOP base=245 head=246 byte-identical=245 ``` **Negative control**, one token changed in an in-memory copy of the head module (`binding !== ownerPackageId` to `binding === ownerPackageId`, one occurrence): ``` MUTATED packages/metadata-protocol/src/protocol-object-owner.ts "binding !== ownerPackageId" -> "binding === ownerPackageId" classifyObjectContribution: base tokens 221, head tokens 221, differ 1, text-equal(ws-collapsed, comments incl.) false releaseAdoptedObjectOwner: base tokens 185, head tokens 185, differ 0, text-equal(ws-collapsed, comments incl.) true TOTAL tokens=406 differ=1 members=2 ``` - **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`.** All 245 base statements are byte-identical, leading comments included. Head adds one statement, the new module's import. - **Size.** +125 / −51 over 2 files, 176 changed lines (the proposal's estimate was 200–260). `protocol-object-owner.ts` has 111 lines. ## Readers of the moved lines Every test and script that reads `protocol.ts` by path was grepped for the two member names. So was every test file in `packages/` and `ui/`, and `docs/qa/`. - **By path: none reads a moved body.** `protocol.object-registry-write-through-spelling.test.ts` names `releaseAdoptedObjectOwner` only in a comment (line 67); neither moved body holds a spelling it counts, and it passes at both ends (in the package suite). - **Behaviour through the class method, no edit owed.** Three `packages/objectql` tests name `classifyObjectContribution` in their headers and drive it through the save and hydration doors: `protocol-runtime-owner-overlay-refusal.test.ts`, `protocol-sentinel-owner-draft-save-address.test.ts` and `protocol-sentinel-owner-package-save-refusal.test.ts`. Run at head after the full build: 3 files, 27 tests passed. - No hit in `docs/qa/`. - **ADR anchors and decision letters.** `check-adr-anchors` exits 0 with identical output at both ends. Neither body cites an ADR; their `[#23416]` and `[#23514]` comments are issue citations, which move with them. - **Engine-double contract** (`check-engine-double-contract`): exits 0 at both ends. The `updateData`/`deleteData` seams keep their entries at new line numbers (13974 → 13976, 13999 → 14001; the two-line import comes before them). `productionFiles` is 3,733 at base and 3,735 at head: +1 is the new file, +1 is the gitignored `packages/spec/src/migrations/registry.ts` 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`, `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 `df8aac41f2`. - **Governed surface.** `check-governed-merges --branch claude/project-thread-ybjm3h`: 0 of 2 paths hit the register, NOT governed; 176 changed lines, under the 3,000-line human-merge bar. ## Verification - `tsc --noEmit` in `packages/metadata-protocol` exits 0 before and after the merges. `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 (no merge changed a file of the package's `src/`): - Base `df8aac41f2`: 21,558 tests (21,539 passed, 0 failed, 19 skipped), 269 files. - Head `4d5121bee`: 21,558 tests (21,539 passed, 0 failed, 19 skipped), 269 files. - None lost, none added, none changed status. The base leg is the package `src/` swapped tree-only from `df8aac41f2` (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 53 gates on 2 changed paths from the merged tree `5e5bf4438e`, with no stale-tree warning; all 53 exit 0 after the full `pnpm build` (119/119). `dispatch-gates --ran`: 53 derived, 53 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. (The same 53 also all exited 0 on the first merged tree `1c5dda251`, before the STALE TREE re-merges.) ## Carry-forward Unchanged from cut 16. 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, and `readCodeLayerForCarryForward`. - The private-static readers: `refusePackagedBaseRemoval`, `packagedBaseRefusal`, `runPublishSideEffects`, `promoteDraftForPublish`, `publishPackageDrafts` and `discardPackageDrafts`. - The field writers: `warnClosureReadUnavailable`. - `ensureObjectStorage`, the object-owner family's other member, stays per the order (its pin would need widening). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_016SP1spj613tyGCgxoD1An6 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 96635f5 commit 860df72

2 files changed

Lines changed: 125 additions & 51 deletions

File tree

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
2+
3+
/**
4+
* [#25467 cut 17] The object-owner verdicts of
5+
* `ObjectStackProtocolImplementation`: which contributor kind a stored object
6+
* row registers as against the registry's owner of that name
7+
* (`classifyObjectContribution`), and handing an adopted object's name from the
8+
* `'sys_metadata'` sentinel owner to its rebound row
9+
* (`releaseAdoptedObjectOwner`), moved out of `protocol.ts` whole.
10+
*
11+
* A MOVE, not a redesign. Each function below is the body of the
12+
* `ObjectStackProtocolImplementation` method of the same name as it stood,
13+
* re-indented one level and otherwise unedited: the same registry reads in the
14+
* same order, the same verdicts, and the same logged line.
15+
*
16+
* ## How the moved bodies reach the class
17+
*
18+
* The shape #23050 set for `rest-server.ts` (its `data-action-routes.ts`
19+
* header carries the full reasoning), as `protocol-batch-data.ts` applies it.
20+
* The class keeps every method — the published `dist/*.d.ts` lists each one's
21+
* name, docblock and declared signature — and each body is one literal of
22+
* exactly the {@link ObjectOwnerHost} members that method reads, plus a
23+
* `.call`. The engine is handed over as a getter, so the body reads the
24+
* protocol's engine (and so its registry) at call time. Every other reader of
25+
* these two methods keeps calling the class method.
26+
*
27+
* Neither body reads a module-level declaration of `protocol.ts`, and neither
28+
* imports anything, so this module imports only the class type. Nothing
29+
* re-exports this module, so the published surface does not move.
30+
*/
31+
32+
import type { ObjectStackProtocolImplementation } from './protocol.js';
33+
34+
/**
35+
* The `ObjectStackProtocolImplementation` members the functions below read —
36+
* every one of them, and no other; each function's `this` is the `Pick` of the
37+
* members IT reads. Each is typed AS the class member (an indexed access on
38+
* the class), so a change to a member's signature on the class is a change
39+
* here too, and naming a member the class does not have is a compile error.
40+
*/
41+
export interface ObjectOwnerHost {
42+
readonly engine: ObjectStackProtocolImplementation['engine'];
43+
}
44+
45+
/** The body of `ObjectStackProtocolImplementation#classifyObjectContribution`; the method's docblock there is its contract. */
46+
export function classifyObjectContribution(
47+
this: Pick<ObjectOwnerHost, 'engine'>,
48+
name: string,
49+
rowPackageId: string | null | undefined,
50+
):
51+
| { kind: 'own' | 'overlay'; packageId: string }
52+
| { kind: 'mismatch'; packageId: string; ownerPackageId: string } {
53+
// `||`, not `??`: an empty-string binding is "no package", the same
54+
// normalisation both hydration seams apply to `package_id`.
55+
const binding = rowPackageId || '';
56+
const registry: any = (this.engine as any)?.registry;
57+
const owner = typeof registry?.getPackagedObjectOwner === 'function'
58+
? registry.getPackagedObjectOwner(name)
59+
: undefined;
60+
const ownerPackageId: unknown = owner?.packageId;
61+
if (typeof ownerPackageId !== 'string' || ownerPackageId === '') {
62+
// [#23416] No packaged owner: the runtime-authored one, if any.
63+
const runtimeOwner = typeof registry?.getObjectOwner === 'function'
64+
? registry.getObjectOwner(name)
65+
: undefined;
66+
const runtimeOwnerPackageId: unknown = runtimeOwner?.packageId;
67+
// [#23514] The `'sys_metadata'` sentinel owner is judged too: see the header.
68+
if (
69+
binding !== ''
70+
&& typeof runtimeOwnerPackageId === 'string'
71+
&& runtimeOwnerPackageId !== ''
72+
&& binding !== runtimeOwnerPackageId
73+
) {
74+
return { kind: 'mismatch', packageId: binding, ownerPackageId: runtimeOwnerPackageId };
75+
}
76+
return { kind: 'own', packageId: binding || 'sys_metadata' };
77+
}
78+
if (binding !== '' && binding !== ownerPackageId) {
79+
return { kind: 'mismatch', packageId: binding, ownerPackageId };
80+
}
81+
return { kind: 'overlay', packageId: binding || 'sys_metadata' };
82+
}
83+
84+
/** The body of `ObjectStackProtocolImplementation#releaseAdoptedObjectOwner`; the method's docblock there is its contract. */
85+
export function releaseAdoptedObjectOwner(
86+
this: Pick<ObjectOwnerHost, 'engine'>,
87+
name: string, item: unknown, targetPackageId: string,
88+
): boolean {
89+
const registry: any = (this.engine as any)?.registry;
90+
if (typeof registry?.registerObject !== 'function') return false;
91+
if (!item || typeof item !== 'object' || typeof (item as { name?: unknown }).name !== 'string') return false;
92+
const owner: { packageId?: unknown } | undefined = typeof registry.getObjectOwner === 'function'
93+
? registry.getObjectOwner(name)
94+
: undefined;
95+
if (owner === undefined) return true;
96+
if (owner.packageId !== 'sys_metadata' || typeof registry.unregisterObject !== 'function') return false;
97+
try {
98+
registry.unregisterObject(name);
99+
return true;
100+
} catch (err: any) {
101+
console.error(
102+
`[Protocol] reassignOrphanedMetadata: object '${name}' was adopted into package `
103+
+ `'${targetPackageId}' in sys_metadata, but the registry keeps its package-less definition `
104+
+ `(owner 'sys_metadata') until the next restart: ${err?.message ?? err}. Until then the data `
105+
+ `plane serves the pre-adoption definition, and a save of the object naming '${targetPackageId}' `
106+
+ 'answers success without going live. Fix: restart the server; the boot registers the object '
107+
+ `under '${targetPackageId}'.`,
108+
);
109+
return false;
110+
}
111+
}

‎packages/metadata-protocol/src/protocol.ts‎

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ import { applySeedBodies, collectBatchPendingDeclarations } from './protocol-pub
397397
import { artifactLockLayerAt, lookupArtifactItem, shippedArtifactsOf, shippingPackagesOf } from './protocol-artifact-lookup.js';
398398
// [#25467 cut 16] The stored-overlay row reads: a type's active rows, their parsed entries, the names with a row of their own, and one item's rows.
399399
import { namesWithOwnStoredRow, readActiveOverlayRows, readItemActiveRows, storedOverlayEntries } from './protocol-stored-overlay-reads.js';
400+
// [#25467 cut 17] The object-owner verdicts: which contributor kind a stored object row registers as, and handing an adopted object's name to its rebound row.
401+
import { classifyObjectContribution, releaseAdoptedObjectOwner } from './protocol-object-owner.js';
400402

401403
/**
402404
* Canonical Zod schema per metadata type lives in
@@ -17515,35 +17517,12 @@ export class ObjectStackProtocolImplementation implements
1751517517
):
1751617518
| { kind: 'own' | 'overlay'; packageId: string }
1751717519
| { kind: 'mismatch'; packageId: string; ownerPackageId: string } {
17518-
// `||`, not `??`: an empty-string binding is "no package", the same
17519-
// normalisation both hydration seams apply to `package_id`.
17520-
const binding = rowPackageId || '';
17521-
const registry: any = (this.engine as any)?.registry;
17522-
const owner = typeof registry?.getPackagedObjectOwner === 'function'
17523-
? registry.getPackagedObjectOwner(name)
17524-
: undefined;
17525-
const ownerPackageId: unknown = owner?.packageId;
17526-
if (typeof ownerPackageId !== 'string' || ownerPackageId === '') {
17527-
// [#23416] No packaged owner: the runtime-authored one, if any.
17528-
const runtimeOwner = typeof registry?.getObjectOwner === 'function'
17529-
? registry.getObjectOwner(name)
17530-
: undefined;
17531-
const runtimeOwnerPackageId: unknown = runtimeOwner?.packageId;
17532-
// [#23514] The `'sys_metadata'` sentinel owner is judged too: see the header.
17533-
if (
17534-
binding !== ''
17535-
&& typeof runtimeOwnerPackageId === 'string'
17536-
&& runtimeOwnerPackageId !== ''
17537-
&& binding !== runtimeOwnerPackageId
17538-
) {
17539-
return { kind: 'mismatch', packageId: binding, ownerPackageId: runtimeOwnerPackageId };
17540-
}
17541-
return { kind: 'own', packageId: binding || 'sys_metadata' };
17542-
}
17543-
if (binding !== '' && binding !== ownerPackageId) {
17544-
return { kind: 'mismatch', packageId: binding, ownerPackageId };
17545-
}
17546-
return { kind: 'overlay', packageId: binding || 'sys_metadata' };
17520+
// [#25467 cut 17] The body moved to `protocol-object-owner.ts` (see `ObjectOwnerHost`).
17521+
const readEngine = () => this.engine;
17522+
const host: ThisParameterType<typeof classifyObjectContribution> = {
17523+
get engine() { return readEngine(); },
17524+
};
17525+
return classifyObjectContribution.call(host, name, rowPackageId);
1754717526
}
1754817527

1754917528
/**
@@ -26123,28 +26102,12 @@ export class ObjectStackProtocolImplementation implements
2612326102
* for a body with no name, which register nothing.
2612426103
*/
2612526104
private releaseAdoptedObjectOwner(name: string, item: unknown, targetPackageId: string): boolean {
26126-
const registry: any = (this.engine as any)?.registry;
26127-
if (typeof registry?.registerObject !== 'function') return false;
26128-
if (!item || typeof item !== 'object' || typeof (item as { name?: unknown }).name !== 'string') return false;
26129-
const owner: { packageId?: unknown } | undefined = typeof registry.getObjectOwner === 'function'
26130-
? registry.getObjectOwner(name)
26131-
: undefined;
26132-
if (owner === undefined) return true;
26133-
if (owner.packageId !== 'sys_metadata' || typeof registry.unregisterObject !== 'function') return false;
26134-
try {
26135-
registry.unregisterObject(name);
26136-
return true;
26137-
} catch (err: any) {
26138-
console.error(
26139-
`[Protocol] reassignOrphanedMetadata: object '${name}' was adopted into package `
26140-
+ `'${targetPackageId}' in sys_metadata, but the registry keeps its package-less definition `
26141-
+ `(owner 'sys_metadata') until the next restart: ${err?.message ?? err}. Until then the data `
26142-
+ `plane serves the pre-adoption definition, and a save of the object naming '${targetPackageId}' `
26143-
+ 'answers success without going live. Fix: restart the server; the boot registers the object '
26144-
+ `under '${targetPackageId}'.`,
26145-
);
26146-
return false;
26147-
}
26105+
// [#25467 cut 17] The body moved to `protocol-object-owner.ts` (see `ObjectOwnerHost`).
26106+
const readEngine = () => this.engine;
26107+
const host: ThisParameterType<typeof releaseAdoptedObjectOwner> = {
26108+
get engine() { return readEngine(); },
26109+
};
26110+
return releaseAdoptedObjectOwner.call(host, name, item, targetPackageId);
2614826111
}
2614926112

2615026113
// ─────────────────────────────────────────────────────────────────────

0 commit comments

Comments
 (0)