Repository navigation
refactor(metadata-protocol): move the registry materialize/strip pair out of protocol.ts into protocol-registry-materialize.ts (#25467 cut 11) - #25797
Conversation
… out of protocol.ts (#25467 cut 11) Move-only. The bodies of materializeFromRegistry, governServedObject, stripMaterializedFromRegistry and stripServedObjectColumns move into the new protocol-registry-materialize.ts (host shape B: an `engine` getter and callbacks for materializeFromRegistry / stripMaterializedFromRegistry). Every member keeps its name, docblock and signature in the class as a stub that delegates. governServedItem and stripServedSystemColumns gain an `export` in place so the new module can import them; index.ts names its exports one by one, so the published surface does not move. Claude-Session: https://claude.ai/code/session_011WCU5ZbGMk9LUhayKvYPsx Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check9 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 11 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 4dfbb2ade5e334085db6347a55de7a23602dbd21 && git checkout 4dfbb2ade5e334085db6347a55de7a23602dbd21
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 0790d0a4696a26135f350d39b1cf4cc6a1af860f f081d777722712adf55e165517987501e6e8df1f && git checkout -B drift-repro 0790d0a4696a26135f350d39b1cf4cc6a1af860f && git merge --no-ff f081d777722712adf55e165517987501e6e8df1f
node scripts/docs-audit/affected-docs.mjs --json 0790d0a4696a26135f350d39b1cf4cc6a1af860f |
席位核对 · ACCEPT ·
|
| item | reading |
|---|---|
| Shape | draft, base main, Part of #25467 (no closing keyword), skip-changeset label, Clause-②: no line-initial. |
| Files (2, +165/−53) | protocol.ts and the new protocol-registry-materialize.ts: exactly the claim's surface; no test file, no packages/spec/**, no packages/objectql/**, no docs/adr/**. Not governed (check-governed-merges --pr 25797), 218 changed lines. |
| Move-only | report's AST proof: 294 leaf tokens, 0 differ; one-token negative control reads DIFFERENT. Seat's own read on the diff: the four class methods keep name, docblock and signature; each is a host literal plus .call — engine as a live getter for the two registry bodies, a protocol-bound closure for the one member each wrapper calls (materializeFromRegistry, stripMaterializedFromRegistry), so a spy on the instance is still reached. (fn<T>).call keeps T (plain .call erases it, TS2322, per the report). |
| Exports | governServedItem and stripServedSystemColumns gain export in place in protocol.ts (cut 8's precedent); index.ts names its re-exports one by one, so the published export table is unchanged (78 names both ends). |
.d.ts |
raw byte-identical at base and head (325970c1…); normalised identical. Ruling 6348891160 holds. |
| Gates | dev 53/53 derived exit 0, --ran 0 gaps; hand gates identical at both ends; package suite 21,509 tests both ends, 0 lost/changed/added. No new Error( moved, so no PRODUCERS row. CI at this act: in progress; Lint & Repo Gates and Type Check owed success before ready. |
| Noted, not filed | the two partial-registry-double fallback arms (provisionSearchCompanionOnto, stripProvisionedSearchCompanionFrom) are reached by no test (the seam tests build a real SchemaRegistry). Pre-existing; this cut moves them unchanged. |
| Landing | ready + auto-merge through the relay once every check on this head is green or an expected skip. Cut 12 per the report (backfill pair + listDrafts + discardDraftInItsScope) is the next claim. |
Generated by Claude Code
Requested by Leehom · project thread
Part of #25467
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6270097840
Cut 11 of the
protocol.tssplit (#24586 ruling A, recorded in6270097840). Cuts 1–10 landed as #25494, #25518, #25538, #25589, #25601, #25623, #25642, #25719, #25731 and #25740. The claim is6397346543; the scope is the registry materialize/strip group the cut 10 report (6393303455) proposed from Release6385903828, as the server seat approved it in its dispatch order.Four
ObjectStackProtocolImplementationmembers move unedited into a new module,packages/metadata-protocol/src/protocol-registry-materialize.ts(#23050 shape B, oneenginegetter).protocol.tsloses 22 net lines (29,791 to 29,769). The cut is move-only, and the card stays open for later cuts.Branch
claude/project-thread-f0qmfais the harness-pinned branch for this thread. It names no issue, so the claim comment is the identity record. It holds one commit,f081d777, onmain0790d0a469(cut 10's merge2c86039515is in its history).Serial with the file's in-flight PRs. Measured just before this PR was opened: none of the 12 open PRs touches
packages/metadata-protocol/src/(each file list read in full; the release PR #25640's 226 files include the package'sCHANGELOG.mdandpackage.jsononly).git log 0790d0a469..origin/mainis empty at that moment.What moves
materializeFromRegistry:9071governServedObject:9109stripMaterializedFromRegistry:9134stripServedObjectColumns:9165The shape (#23050 shape B, as cuts 1–10 apply it)
.call, marked[#25467 cut 11].RegistryMaterializeHosttypes every member as the class member itself (an indexed access onObjectStackProtocolImplementation). Each moved function keeps the method's type parameterTand types itsthisas thePickof the host over exactly the members its body reads. Each stub annotates its literal asThisParameterTypeoftypeof fn. No cast, and no member changes visibility.Tin,Tout).Function.prototype.callon a generic function erasesTtounknown, whichtscrejects against the method's declaredTreturn (TS2322). So each stub instantiates the function first: the stub calls.callon the parenthesised instantiation expression of the function atT(tscrefuses an instantiation expression followed directly by a property access, TS1477, hence the parentheses). The emitted JavaScript is a plain.call(host, …); cuts 1–10 moved no generic member, so no earlier cut needed it.materializeFromRegistryandstripMaterializedFromRegistryread the fieldengine, handed over as a GETTER so the read happens when the body makes it (tests replaceengineon a constructed protocol).governServedObjectcallsmaterializeFromRegistryandstripServedObjectColumnscallsstripMaterializedFromRegistry, each through a late-bound closure on the protocol. No private-static member, and nothing on the Release's stay list. The order's hypothesis holds.governServedObjectread exits (one inreadFlattenedMetaItems, three inreadMetaItem, one ongetMetaItemLayered's effective layer) and the onestripServedObjectColumnswrite site insaveMetaItem.Module-level declarations, by reader
export, none moves. The bodies read three module-level functions ofprotocol.ts:canonicalMetaType(already exported), andgovernServedItemandstripServedSystemColumns, which gainexportin place, as cut 8 exportedpermissionSetOwnerBindingRefusalandruntimeHookWithoutBodyRefusal. The new module imports all three fromprotocol.js; the cycle is evaluation-safe because each is read only inside a function body.index.tsnames what it publishes fromprotocol.tsone by one, so the published surface does not move (measured below).protocol.ts; the moved bodies were their only callers at base too. They stay there because the class's read and write paths cite them by name in prose (for example thegetMetaItemLayeredcomment on whygovernServedItemnever runs onoverlay). Moving them is noted below, not done here.protocol.ts. No import loses its last reader. The one new statement is the import of the new module.The published
.d.tsThe series bar is ruling
6348891160, sorted-union identity, measured first. Base0790d0a469and headf081d777were built withpnpm --filter @objectstack/metadata-protocol buildagainst one dependency tree (the closure built once at head, then the package'ssrc/swapped tree-only to base for the base build and restored fromHEADunder a trap;git diff HEADempty andgit statusclean after, both blobs equal toHEAD's).325970c1661efaa6a3762ce7de9e6bb205ea16099784f2b6c5950d62d175b331at base and at head, on bothdist/index.d.tsanddist/index.d.cts, 772,838 bytes each (the hash cuts 8–10 reported).cmpexits 0 on both pairs. Raw identity holds, so sorted-union identity holds too. The four members are private, so each stays aprivate NAME;line.9562749edf7b8bba67ed2f1779799a68b3d6934a8605074934572d9507c55ba6at both ends (109 string-literal union runs sorted; this run's own normaliser).index.jshashesb99c5148b08d3fc5…at base (cut 10's head hash) andbbe1a227b80604e0…at head; the four functions'.call(sites occur 0 times in the base bundles and 4 times in the head bundles (ESM and CJS alike).HEADunder a trap, hash equal toHEAD's after):privatedropped fromstripServedObjectColumnsand the package rebuilt. Both.d.tsfiles move to06884ae21a4b72b4…and print the member's full generic signature (type parameterT, then(type: string, item: T): T;), so the bar can see a change on this member.9f18a0177ac736ed…on all four. None of the moved functions, the two newly exported helpers or the host type appears.No changeset:
skip-changeset, per ruling6348891160.Proof of move-only
this, return type and body): 294 tokens compared, 0 differ. The type-parameter, parameter, return-type and body text, comments included, is also equal with whitespace collapsed, for all four. Negative control: one changed token instripMaterializedFromRegistry's body (item === nulltoitem !== null, on a copy) makes the check reportdiffer=1.protocol.ts. 236 of the 238 base statements other than the class are byte-identical, leading comments included. The other two aregovernServedItemandstripServedSystemColumns, which gain theexportkeyword and nothing else. Head adds one statement, the new module's import.protocol-registry-materialize.tshas 134 lines.Readers of the moved lines
Every test and script that reads
protocol.tsby path, and every test file inpackages/andscripts/, was grepped for the four member names, forgovernServedItemandstripServedSystemColumns, and for the four registry seam names the bodies call (materializeServedObjectOnto,provisionSearchCompanionOnto,stripMaterializedStampsFrom,stripProvisionedSearchCompanionFrom).protocol.tsthe member names occur only in prose:metadata-diagnostics.ts(a comment naminggovernServedObject's docblock), twoCHANGELOG.mdentries, and comments inpackages/objectqlandpackages/resttests. No gate, baseline or ADR anchor names them.packages/objectql/src/protocol-meta-effective-schema.test.ts,registry-deployment-platform-global.test.ts,registry-tenant-index-author-declared-column.test.ts,registry-tenant-index-follows-wall.test.ts,meta-object-primary-designation-roundtrip.test.ts, andpackages/rest/src/meta-object-materialization-agreement.test.ts. Each builds the protocol over a REALSchemaRegistry(which defines all four seam methods,packages/objectql/src/registry.ts) or calls the registry directly; none readsprotocol.tsby path, and none builds a double that answers only the narrowerprovisionSearchCompanionOnto/stripProvisionedSearchCompanionFromspelling. Verdict: the fallback arms move verbatim and no in-repo test reaches them (see Acceptance notes). At head, those six files plusmeta-object-search-companion-roundtrip.test.tspass: objectql 6 files / 57 tests, rest 1 file / 12 tests, eachVERDICT command-exit 0.PRODUCERS): no row owed. The four bodies hold nonew Error((0 by count in base lines 9032–9167);protocol.tskeeps its 74 such sites.check-adr-anchorsexits 0 at both ends with identical output: 85 anchored files, 52,707 citations across 6,638 files, 1,846 → 1,846 decision-letter citations. Theprotocol.tsanchor file names none of the four members, and the moved bodies are not the mechanism of any entry paragraph, so the new module gets no entry.check-durability-degradation-log-level --list): identical at both ends once[@:][0-9]+is stripped (159 lines). The gate exits 0 at both ends with identical output. The movedtry/catcharms wrap registry seam calls, not storage reads, so neither rule reads them.check-engine-double-contract): exits 0 at both ends. TheupdateData/deleteDataseams keep their entries at new line numbers (14044 → 14022, 14069 → 14047).productionFilesis 3,690 at base and 3,692 at head: +1 is the new file, +1 is the gitignoredpackages/spec/src/migrations/registry.ts, which the spec build writes in the head tree and the clean base tree had not built.check-adr-symbol-anchors,check-system-context-census,check-tenant-audit-census,check-query-options-erasure-ratchet,check-filter-alias-parity.check-nul-bytesdiffers only in the scanned file count, +1. The base-end readings were taken in a clean detached worktree at0790d0a469.check-platform-checklist --changed-from origin/main: OK, 29 anchors judged, 0 lost.check-governed-merges --branch claude/project-thread-f0qmfa: 0 of 2 paths hit the register, NOT governed; 218 changed lines, under the 3,000-line human-merge bar.Verification
All at head
f081d777.tsc --noEmitinpackages/metadata-protocolexits 0.pnpm exec eslint --no-inline-configon the two changed files exits 0, no output.packages/metadata-protocolsuite, base and head, compared per test name and status (vitest--maxWorkers=2, JSON reporter, each run under the shared verify lock,VERDICT command-exit 0both legs):0790d0a469: 21,509 tests (21,490 passed, 0 failed, 19 skipped), 266 files.f081d777: 21,509 tests (21,490 passed, 0 failed, 19 skipped), 266 files.src/swapped tree-only from0790d0a469(the new module removed from the tree) and restored fromHEADunder a trap.dispatch-gates --commands --repo objectstack-ai/objectstackderives 53 gates on 2 changed paths; all 53 exit 0.check:dual-build-cjs-loadsandcheck:lean-entry-closurefirst answered PREREQUISITE NOT MET (exit 3, unbuiltdist/) and exit 0 after a fullpnpm build(76/76 tasks,VERDICT command-exit 0); the plugin-teardown fixture commit was fetched before the first run.dispatch-gates --ran: 53 derived, 53 run, 0 NOT-MEASURED, 0 UNRUN, exit 0.Acceptance notes
materializeFromRegistryandstripMaterializedFromRegistry(the narrowerprovisionSearchCompanionOnto/stripProvisionedSearchCompanionFromspellings for partial registry doubles) are reached by no test in this repository: every protocol in the six named test files is built over a realSchemaRegistry, which answers the wider seam first. They move verbatim; whether to keep them is not this cut's question. Not class a/b/c.governServedItemandstripServedSystemColumnsnow have their only callers inprotocol-registry-materialize.ts. A later cut could move them there; it would re-point the{@link}references in the class docblocks and the prose comments that name them.Carry-forward
Unchanged from cut 10: public members whose return type is inferred, the bodies kept by a reader (
probeRecord,getMetaItemCached,findReferencesToMeta,packagelessAddress,refuseUnmintableMetaType,metaTypeNamespaceExists,viewContainerNameCollisionRefusalwithoverlaidShippedContainerViewNames,reportPageRequiresAbsentAtLoad, the 7applyRegistryWriteThroughcallers,readCodeLayerForCarryForward), and the private-static readers stay inprotocol.ts.Generated by Claude Code