Repository navigation
refactor(metadata-protocol): move the save door's refusals out of protocol.ts into protocol-save-door-refusals.ts (#25467 cut 6) - #25623
Conversation
…tocol.ts into protocol-save-door-refusals.ts Nine private save-door refusal methods of ObjectStackProtocolImplementation move unedited into a new module under the shape-B host pattern, with the five lock-family declarations only they read. refuseUnmintableMetaType, metaTypeNamespaceExists and viewContainerNameCollisionRefusal stay, held by the durability read-seam census and the lookupArtifactItem call-site pin. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8pUyVs5eas1AjMdReJM7C
📓 Docs Drift CheckThis PR changes 1 package(s): 44 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 15 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. 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 38f02eca6add46f37b68fb967d613be481670544 && git checkout 38f02eca6add46f37b68fb967d613be481670544
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin f7b02989688255549339747d03a42d65940b2c19 04c063af57c5da225a4828bcd97f52cd057a1716 && git checkout -B drift-repro f7b02989688255549339747d03a42d65940b2c19 && git merge --no-ff 04c063af57c5da225a4828bcd97f52cd057a1716
node scripts/docs-audit/affected-docs.mjs --json f7b02989688255549339747d03a42d65940b2c19
|
|
os-dev-report |
席位核对 · ACCEPT · 2026-10-24T11:15Z
Generated by Claude Code |
Requested by Sales · project thread
Part of #25467
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6270097840
Cut 6 of the
protocol.tssplit (#24586 ruling A, recorded in6270097840). Cuts 1–5 landed as #25494, #25518, #25538, #25589 and #25601. The claim is6383176261; the seat agreed the scope before it, including the two narrowings below, and asked for the anchor-entry check and the re-measure on merged main, both answered in the claim and below.Nine PRIVATE
ObjectStackProtocolImplementationmethods, the save door's refusals, move unedited into a new module,packages/metadata-protocol/src/protocol-save-door-refusals.ts, with the five lock-family declarations only they read. They are one contiguous run of the class, less three members that stay.It is move-only, and the card stays open for the later cuts. Branch:
claude/project-thread-uasfag, the harness-pinned branch for this session, restarted fromorigin/mainat60d8fd2ea6after cut 5 merged. The branch names no issue, so the claim comment is the identity record.Serial with the file's in-flight PRs. Measured just before this PR was opened, on main
7265b33e77. None of the 11 open PRs touchesprotocol.ts,protocol-save-door-refusals.tsor the bracketed-refusal pin (each PR's diff read against its merge base), andgit merge-treeof this head with each of them, and with main, is clean. Since60d8fd2ea6, main has touched onlybuild-probes.tsand its test in this package.What moves
refuseUngrammaticalMetaItemName:19858defaultRecordPageSaveRefusal:20040externalBindingSaveRefusal:20155externalBindingDatasourceDefinition:20197objectsBoundExternallyTo:20213anonymousElevatedFlowRefusal:20286authoredLockFamily:20603saveWriteBinding:20666objectNamespacePrefixViolation:20710All nine are
private, so none is on the series' skip list of public members with inferred return types.Stay in the class, inside the run, narrowed out during the trial before the claim:
refuseUnmintableMetaTypeandmetaTypeNamespaceExists.scripts/check-durability-degradation-log-level.mjsfollows the chainsaveMetaItem -> refuseUnmintableMetaType -> metaTypeNamespaceExists -> engine.findOne(its own table, rows 3 and 5), and its--listcarries ametaTypeNamespaceExistsread seam. This is the rule that keptpackagelessAddressin cut 5.viewContainerNameCollisionRefusal, with its one helperoverlaidShippedContainerViewNames.protocol.lookup-artifact-item-call-sites.test.tsreadsprotocol.tsand records this member'slookupArtifactItem(site.The shape (#23050 shape B, as cuts 1–5 apply it)
async. Each body is now one host literal plusfn.call(host, …), marked[#25467 cut 6].SaveDoorRefusalHosttypes every member as the class member itself (ObjectStackProtocolImplementation['m']). Each moved function types itsthisas thePickof the host over exactly the members its body reads, measured by AST. Each stub annotates its literal asThisParameterType<typeof fn>. There is no cast, and no member becomes public or protected.engineandgetServicesRegistry(the constructor-supplied function field, passed as cut 4 passed it), as getters, so each read happens when the body makes it.(...a) => this.m(...a)):artifactLockLayerAt,externalBindingDatasourceDefinition,getOverlayRepo,objectsBoundExternallyTo,overlayLockLayerAt,readActiveOverlayRows,readMetaItem,rethrowUnlessMetadataStoreUnprovisionedandstoredOverlayEntries. A spy or double set on the instance is still the one the body reaches.isSystem, and the host carries no elevation member.Module-level declarations, by reader
Each declaration the moved bodies read was checked by an AST walk over the whole of base
protocol.ts. The walk finds every identifier reference outside the declaration itself and takes the transitive closure over the moved set.Move with the bodies, byte-identical and unexported. Each has 0 readers outside the moved code and carries exactly its own docblock. None is a class or a type:
LOCK_FAMILY_KEYS,lockFamilyOf,sameLockFamily,withLockFamily,authoredLockFamilyRefusal.item-lock.tsdeclares its own, separateLOCK_FAMILY_KEYS, untouched.Stay in
protocol.tsand gainexportin place, the only edit to each:MetadataIssueEntrypermissionSetOwnerBindingRefusal,protectionBlockRefusal,publishBackfillRefusal,readPublishBackfillRequestMetadataWriteFacespecValidationFindings,destructiveChangeRemedy,flowSaveReplaysRetired,saveMetaItemspecValidationFindingssaveMetaItemoverlaySchemaDeclaredKey, also read by the moved code, is already exported.src/index.tsexports from./protocol.jsby name, so none is published (measured below).Imports narrowed in
protocol.ts, each having lost its last reader:METADATA_ITEM_NAME_PATTERN,defaultRecordPageObject,MetadataProtectionFields,validateObjectNamespacePrefix, and the whole@objectstack/spec/apivalue import. That import's 3-line[ADR-0138 D2b]comment moves with it onto the new module's import of the same names.protocol.tsgains one statement, the import of the new module.The published
.d.tsUnder the series bar (ruling
6348891160), measured first on merged main as the seat asked, on the final layout, at base60d8fd2ea6and at head. Both ends were built withpnpm --filter @objectstack/metadata-protocol buildagainst the same dependency tree (turbo run build --filter='@objectstack/metadata-protocol^...'at base first).dist/index.d.tsanddist/index.d.cts:25da084d43455d125bfd41b85b1e70477ef7caf77f2cb7da23143b325e51a14eat base and at head, both files. That is raw identity: no moved declaration prints anywhere new, and no docblock splices onto a neighbour where a declaration gainsexport.import()andrequireof the built bundles). The sorted list hashese47ac7c753bcb8bee1e79c1a5f79f7394cf030bd526de81ea8bcbfcb71fa024aon all four, as at cuts 1–5. None ofMetadataIssueEntry,MetadataWriteFace,specValidationFindingsor the moved declarations appears.No changeset:
skip-changeset, per ruling6348891160.Proof of move-only
getChildrenleaves). For each moved function, the parameters (less the addedthis), return type and body have the same token sequence as the base method. Each moved declaration has the same tokens, and its own docblock is byte-identical. 2,966 tokens compared, 0 differ. Negative control: one changed token makes the check report a difference.async.protocol.ts. 230 of the 243 base statements other than the class are byte-identical with their leading comments. The other 13 are the 5 moved declarations, the 3 that gainexport, and the 5 import statements narrowed or removed. The one new statement is the import of the new module.protocol.tsgoes from 30,548 to 30,312 lines, andprotocol-save-door-refusals.tshas 464.Readers of the moved lines
protocol.bracketed-refusal-opener-absence.test.ts,PRODUCERS). 5new Error(sites move. The new module is listed with its measured count as its floor,'protocol-save-door-refusals.ts': 5, as cuts 3 and 5 listed theirs. That is the only edit outside the move. No moved site opens with a bracketed tag.check-durability-degradation-log-level --list): identical at both ends apart from line numbers (159 lines), with the two members above kept.check:adr-anchors: 85 → 85 anchored files. Decision-letter citations on the anchored surface go 1,871 → 1,868, measured exactly at both ends. The three that leave:ADR-0138 D2bin the moved import comment,ADR-0138 D2binanonymousElevatedFlowRefusal's body, andADR-0131 D6in a moved body.scripts/adr-anchors/packages__metadata-protocol__src__protocol.ts.jsongoverns ADR-0005/0029/0087/0119/0126 and namesapplyObjectRegistryMutation,loadMetaFromDb,removeObjectOverlay, theOBJECT_OVERLAY_PACKAGE_MISMATCHproducer,batchData/transaction(,saveMetaItem/projectStorableViewBody/VIEW_CONSOLE_ROUND_TRIP_KEYS,hydrateOverlayIntoRegistry,readFlattenedMetaItemsandisShippedFlowName/isStoredFlowEntryOfShippedName. None appears in the new module (0 hits), and bothOBJECT_OVERLAY_PACKAGE_MISMATCHproducers stay inprotocol.ts. The new module gets no entry.check-adr-symbol-anchors,check-platform-checklist(protocol.ts#objectNamespacePrefixViolationresolves on the shell, which stays; not edited),check-system-context-census,check-tenant-audit-census,check-query-options-erasure-ratchet(no counted site moves; no file key added), and speccheck-liveness.check-engine-double-contractdiffers only inproductionFiles+1 (the new file).check-governed-merges --branchon the final 3-path list: NOT governed. 872 changed lines, under the 3,000-line human-merge bar.protocol.restore-doors-save-refusal-family.test.ts,protocol.item-name-every-door.test.ts,protocol.item-name-grammar.test.ts, objectqldefault-record-page-save-door.test.ts, service-datasource'sdatasource-admin-service.tsdocblock, the platform checklist) name it in prose or exercise it through the instance. None reads the moved lines by path, and all pass.Verification
tsc --noEmit(package) exit 0.eslintonprotocol.tsandprotocol-save-door-refusals.tsexit 0.packages/metadata-protocolsuite, base and head, compared per test name and status. Base60d8fd2ea6: 21,490 tests (21,471 passed, 0 failed, 19 skipped), 266 files. Head: 21,491 (21,472 passed, 0 failed, 19 skipped), 266 files. None lost, none changed status, one added: the newPRODUCERSrow,protocol-save-door-refusals.ts raises no message opening with a bracketed lowercase tag(passed).protocol.tsby path or name these methods, run at head, all pass:corerow-serving-door-exposure.pinandsecond-object-read-exposure.pin(7, at both ends);objectqlcore-boundary.ratchet,protocol-publish-canonical-foldanddefault-record-page-save-door(46);specmetadata-type-registry-allow-org-override-absenceandscripts/liveness/evidence(44);clientandrestdiscovery-double-retired-key(3 + 2).check-adr-anchors,check-adr-symbol-anchors,check-platform-checklist,check-system-context-census,check-tenant-audit-census,check-query-options-erasure-ratchet,check-durability-degradation-log-level --list, and speccheck-liveness.dispatch-gates --commands --changedderives 59 gates on the final tree (3 changed paths). All 59 exit 0 at head, and--ranreconciles 59 of 59 with 0 NOT-MEASURED. The full list and the--ranreconcile are in the report on this PR.Carry-forward
These stay in
protocol.tsin this series:getDiscovery,getMetaTypes,getMetaItems,getMetaItemsForExecution,getMetaItem,getMetaItemForExecution,getUiView,findData,getData,validateData,createData,cloneData,updateData,deleteDataandsaveMetaItem.probeRecord(per-file erasure-baseline site);getMetaItemCached(the Three read-side/metaverbs (history, audit, references) never reachcanonicalizeMetaRequestType— they still derive their key from the MANIFEST map #9157 pin reads its body by path);packagelessAddress,refuseUnmintableMetaType,metaTypeNamespaceExists(the durability read-seam census);viewContainerNameCollisionRefusalandoverlaidShippedContainerViewNames(thelookupArtifactItem(call-site pin).The inferred-return
.d.tsstill depends onprotocol.tsbyte offsets (cut 3's series note), so each cut measures it.🤖 Generated with Claude Code
https://claude.ai/code/session_01J8pUyVs5eas1AjMdReJM7C