Repository navigation
refactor(metadata-protocol): move the lock gate and the OCC write addresses out of protocol.ts into protocol-lock-version-gates.ts (#25467 cut 5) - #25601
Conversation
…resses out of protocol.ts into protocol-lock-version-gates.ts Move-only: the effective-lock read, the write/delete lock gates with their audit rows, the version-token reads and the read/draft row addresses the conflict check runs on move unedited into protocol-lock-version-gates.ts (LockVersionGateHost); the class keeps each method's name, docblock and signature. packagelessAddress and the private-static readers stay. The bracketed-refusal pin lists the new module with its measured floor. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8pUyVs5eas1AjMdReJM7C
📓 Docs Drift CheckThis PR changes 1 package(s): 18 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 9 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 40da60d9e314ba5bcf1cc856ad584ce828e6ccba && git checkout 40da60d9e314ba5bcf1cc856ad584ce828e6ccba
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 9f390945ebbf34696f71806d0247df47cfeaef1c 11a1c9186be16f3c881d7221f7d3efeda7b20fbd && git checkout -B drift-repro 9f390945ebbf34696f71806d0247df47cfeaef1c && git merge --no-ff 11a1c9186be16f3c881d7221f7d3efeda7b20fbd
node scripts/docs-audit/affected-docs.mjs --json 9f390945ebbf34696f71806d0247df47cfeaef1c
|
|
os-dev-report |
席位核对 · ACCEPT · 2026-10-24T05:09Z
Generated by Claude Code |
Requested by Sales · project thread
Part of #25467
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6270097840
Cut 5 of the
protocol.tssplit (#24586 ruling A, recorded in6270097840). Cuts 1–4 landed as #25494, #25518, #25538 and #25589. The claim is6379699184; the seat agreed the scope before it, and its two pre-claim conditions (the.d.tson the trial build, the governed-surface predicate) are answered in the claim and below.Sixteen PRIVATE
ObjectStackProtocolImplementationmethods, the lock gate and the optimistic-concurrency write addresses, move unedited into a new module,packages/metadata-protocol/src/protocol-lock-version-gates.ts, with the two declarations only they read. On baseba6912c1adthat is 278 body lines, 122 of them from the last 30 days.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/mainatba6912c1adafter cut 4 merged. The branch names no issue, so the claim comment is the identity record.Release freeze. Sales paused merges at 03:57Z for a release. This PR is opened as a draft and is not readied, armed or queued until the coordinator says merges resume.
Serial with the file's in-flight PRs. Measured just before this PR was opened, on main
a57643d3de. None of the 11 open PRs touchesprotocol.ts,protocol-lock-version-gates.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.origin/mainhas not touchedpackages/metadata-protocolsince this branch's baseba6912c1ad.What moves
getEffectiveLock:17113readLockGateOverlayLayer:17150recordMetadataAudit:17259lockWriteRefusal:17338assertLockAllowsWrite:17396assertLockAllowsDelete:17416storedHashDigest:17520receiptVersion:17532storedHeadAt:17559readVersionToken:17598packagelessReadAddress:17635strictDraftReadAddress:17661packagelessDraftAddress:17798storedParentForToken:17839metadataConflictRefusal:17879recordPendingDenialAudit:17966All sixteen are
private, so none is on the series' skip list of public members with inferred return types.Stay in the class, beside the moved methods:
recordOptimisticConflictAuditand the staticoptimisticConflictAuditEntry. The first reads a private static, which a module function cannot reach (TS2341; ruling6364006498precedent).packagelessAddress, narrowed out during the trial, before the claim.scripts/check-durability-degradation-log-level.mjs's read-seam rule follows itsfindEnvironmentRowsread. It also follows the four callers that guard it insideprotocol.ts:applyObjectRegistryMutation,deleteMetaItem,deletePackageandloadMetaFromDb.The shape (#23050 shape B, as cuts 1–4 apply it)
async. Each body is now one host literal plusfn.call(host, …), marked[#25467 cut 5].LockVersionGateHosttypes 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.engine, as a getter, so each read happens when the body makes it.(...a) => this.m(...a)):artifactLockLayerAt,getEffectiveLock,getOverlayRepo,lockWriteRefusal,overlayLockLayerAt,packagelessAddress,packagelessDraftAddress,readLockGateOverlayLayer,receiptVersion,recordMetadataAudit,rethrowUnlessMetadataStoreUnprovisioned,storedHashDigestandstoredHeadAt. A spy or double set on the instance (for exampleprotocol.delete-rewrap-envelope.test.ts's wrapper aroundassertLockAllowsDelete) is still the one the body reaches.{ isSystem: true }context, exactly as before.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:
InboundVersionConflictError(class):3679storedParentForToken(throws it),metadataConflictRefusal(instanceof). One stub docblock that stays names it in{@link}prose.ErrorWithPendingAudit(type):6192There is still exactly one class, so the
instanceofcheck meets the same constructor the throw uses.Stay in
protocol.tsand gainexportin place, the only edit to each:canonicalMetaType(:417)canonicalizeMetaRequestType,governServedItem,stripServedSystemColumns,bundleMemberOfMetadataAuditEntry(:6164)withPendingAudit,optimisticConflictAuditEntrysrc/index.tsexports from./protocol.jsby name, so neither is published (measured below). No import ofprotocol.tsloses its last reader.protocol.tsgains one statement, the import of the new module.The published
.d.tsUnder the series bar (ruling
6348891160), measured last, on the final layout, at baseba6912c1adand at head. This is the first cut that moves a class and a type, and the seat asked for this reading before the claim. 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, 770,690 bytes each. That is raw identity:canonicalMetaType's docblock does not splice onto a neighbour once it gainsexport;InboundVersionConflictErrorin{@link}prose prints byte-identical.ff7d6892b9f1161da356208d51301816c48dc021051544b9c28a3aa14329d57e. The normaliser, run frompackages/metadata-protocol:dist/index.d.ts: making line 1361,private engine;, public (engine;) gives raw4bea7ae0…and normalisedbe016197…. Both differ from the real hashes.import()andrequireof the built bundles). The sorted list hashese47ac7c753bcb8bee1e79c1a5f79f7394cf030bd526de81ea8bcbfcb71fa024aon all four, as at cuts 1–4. None ofcanonicalMetaType,MetadataAuditEntryorInboundVersionConflictErrorappears.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,139 tokens compared, 0 differ. Negative control: one changed token makes the check report a difference.async.protocol.ts. 240 of the 244 base statements other than the class are byte-identical with their leading comments. The other 4 are the 2 moved declarations and the 2 that gainexport. The one new statement is the import of the new module.protocol.tsgoes from 30,718 to 30,548 lines, andprotocol-lock-version-gates.tshas 547.Readers of the moved lines
protocol.bracketed-refusal-opener-absence.test.ts,PRODUCERS). 4new Error(sites move, soprotocol.tsgoes 87 → 83 against its floor of 5. The new module is listed with its measured count as its floor,'protocol-lock-version-gates.ts': 4, as cut 3 listed its module. That is the only edit outside the move. No moved site opens with a bracketed tag.check-durability-degradation-log-level). It gives identical output at both ends, withpackagelessAddresskept (above).check:adr-anchors: 84 → 84 anchored files. Decision-letter citations on the anchored surface go 1,883 → 1,882, measured exactly at both ends.ADR-0110 D3comment citation inreadLockGateOverlayLayer's body.protocol.ts's anchor entry governs ADR-0005/0029/0087/0119/0126. None of its paragraphs describes these bodies, so the new module gets no entry.check-adr-symbol-anchors,check-platform-checklist(protocol.ts#anchors on the moved methods resolve on the shells, which stay; 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 in the line numbers of theupdateData/deleteDataseams inprotocol.ts, plusproductionFiles+1 (the new file).check-governed-merges --branchon the final 3-path list: NOT governed. 968 changed lines, under the 3,000-line human-merge bar.protocol.tsnext to a moved method name (protocol.delete-rewrap-envelope.test.ts,protocol.lifecycle-audit-rows.test.ts,sys-metadata-repository.package-writability.test.ts, objectqlprotocol-publish-canonical-fold.test.ts, the durability checker's comment table) name it in prose or spy on the instance. None reads the moved lines by path, and all pass.Verification
tsc --noEmit(package) exit 0.eslintonprotocol.tsandprotocol-lock-version-gates.tsexit 0.packages/metadata-protocolsuite, base and head, compared per test name and status. Baseba6912c1ad: 21,489 tests (21,470 passed, 0 failed, 19 skipped), 266 files. Head: 21,490 (21,471 passed, 0 failed, 19 skipped), 266 files. None lost, none changed status, one added: the newPRODUCERSrow,protocol-lock-version-gates.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.ratchetandprotocol-publish-canonical-fold(12);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, 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.check-adr-symbol-anchors,check-livenessand the durability checker's full run are not derived and were run by hand (above). 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(the durability read-seam census, this cut).The inferred-return
.d.tsstill depends onprotocol.tsbyte offsets (cut 3's series note), so each cut measures it last.🤖 Generated with Claude Code
https://claude.ai/code/session_01J8pUyVs5eas1AjMdReJM7C