Repository navigation
refactor(metadata-protocol): move the lock-state group out of protocol.ts into protocol-lock-state.ts (#25467 cut 10) - #25740
Conversation
…l.ts into protocol-lock-state.ts (#25467 cut 10) Move-only. The bodies of servedLockState, isShippedFlowName, isStoredFlowEntryOfShippedName, declinesStoredRow, isUnservedSealedOverlay and isStoredEntryOfDeclinedName move to the new protocol-lock-state.ts (shape B: every method keeps its name, docblock and declared signature in the class; each body is a LockStateHost literal plus a .call). The bracketed-refusal pin follows the moved throw site with a PRODUCERS row. Claude-Session: https://claude.ai/code/session_01RobcokwdH6frowqrsE1fRc Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check18 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 6debba99709999cf4df4a17a51385dbb6f5d52a1 && git checkout 6debba99709999cf4df4a17a51385dbb6f5d52a1
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 5cf1b9d2e880c061f7f4ddc6899b1db61d60a5b0 3ebaea9729a4fcc79b1a1eb7e40b782020aefc0d && git checkout -B drift-repro 5cf1b9d2e880c061f7f4ddc6899b1db61d60a5b0 && git merge --no-ff 3ebaea9729a4fcc79b1a1eb7e40b782020aefc0d
node scripts/docs-audit/affected-docs.mjs --json 5cf1b9d2e880c061f7f4ddc6899b1db61d60a5b0 |
席位核对 · ACCEPT ·
|
| item | reading |
|---|---|
| Shape | draft, base main, Part of #25467 (no closing keyword), skip-changeset label, Clause-②: no and Metadata-protocol: none line-initial. |
| Files (3, +198/−44) | protocol.ts, the new protocol-lock-state.ts, and the bracketed-refusal pin protocol.bracketed-refusal-opener-absence.test.ts (one PRODUCERS row for the moved throw, as cuts 6–7 did). Exactly the claim's surface; no packages/spec/**, no docs/adr/**. Not governed (check-governed-merges --pr 25740), 242 changed lines. |
| Move-only | report's AST proof: 451 tokens, 0 differ; one-token negative control reads differ=1. Seat's read of the six stubs: every host literal carries only callbacks to class members (packagedBaseRefusal, packagedArtifactOwner, isShippedFlowName, isDeclaredCodeDatasource, isUnservedSealedOverlay, isSealedManagedItem, declinesStoredRow), no field by value, so nothing can go stale. Each method keeps its name and declared signature in the class. |
| Readers | the six test files that name these members call or spy on them; none reads a body in protocol.ts by path (report, verdict per file). |
| ADR anchor | no new entry: the ADR-0126 paragraph names the two flow predicates, but the paths it describes stay in protocol.ts. Accepted. |
.d.ts |
raw identity at both ends (325970c1…), normalised equal; export tables 78/78. Ruling 6348891160 holds. |
| Gates | dev 59 derived, 59/59 exit 0, --ran reconciled; package suite 21,504 → 21,505 (+1, the PRODUCERS case), 0 lost; letters 1,846 → 1,846; hand gates and durability --list identical. CI at this act: in progress. Lint & Repo Gates and Type Check owed success before ready. |
| Landing | ready + auto-merge through the relay once every check on this head is green or an expected skip. Cut 11 (registry materialize/strip, per the report) is the next claim on this card after this merges. |
Generated by Claude Code
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40163192259 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40164208512 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
Queue ejection triage · Removed from the merge queue at 2026-10-25T05:36:19Z after its second red queue build (40163192259, then 40164208512). Both reds are the same signature and neither is in this PR's files:
Disposition: the same signature has ejected this PR twice, so it is ⛔ not re-enqueued now. It waits on #25750. The seat re-arms auto-merge once #25750 has a fix on Generated by Claude Code |
|
Re-armed · Auto-merge is enabled again on head Generated by Claude Code |
Requested by Leehom · project thread
Part of #25467
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6270097840
Cut 10 of the
protocol.tssplit (#24586 ruling A, recorded in6270097840). Cuts 1–9 landed as #25494, #25518, #25538, #25589, #25601, #25623, #25642, #25719 and #25731. The claim is6392807595; the scope is the lock-state group the cut 9 report (6392271625) proposed from Release6385903828, as the server seat approved it.Six
ObjectStackProtocolImplementationmembers move unedited into a new module,packages/metadata-protocol/src/protocol-lock-state.ts(#23050 shape B; no getter).protocol.tsloses 4 net lines (29,795 to 29,791). The cut is move-only, and the card stays open for later cuts.Branch
claude/project-thread-5tpuo2is the harness-pinned branch for this thread. It names no issue, so the claim comment is the identity record. It holds one commit,3ebaea97, onmainec4ef94ead.Why this group alone. The order allowed adding registry materialize/strip if this group was too small to stand alone. It is the size of cut 9 (451 body tokens against cut 9's 496; 242 changed lines against 299), it is one closed group (the six call only one another and four class members that stay), and the claim's file surface names one module for it. So this cut carries the group alone, and registry materialize/strip is proposed as cut 11 in the report.
Serial with the file's in-flight PRs. Measured just before this PR was opened: of the 17 open PRs, only #25737 touches
packages/metadata-protocol/src/, inprotocol.runtime-authoring-gate.test.ts, a test that reads no source by path and names no moved member, outside this cut's file surface. The release PR #25640 touches the package'sCHANGELOG.mdandpackage.jsononly. #25718's 9,211-file list was read bygit diff --name-onlyagainst its merge base: 0 paths underpackages/metadata-protocol/src/.origin/mainmoved toe2b40a264bafter the base;git log ec4ef94ead..origin/main -- packages/metadata-protocolis empty, andgit merge-treeof this head withorigin/mainis clean.What moves
servedLockState:15893isShippedFlowName:15972isStoredFlowEntryOfShippedName:15987declinesStoredRow:16048isUnservedSealedOverlay:16070isStoredEntryOfDeclinedName:16084The shape (#23050 shape B, as cuts 1–9 apply it)
fn.call(host, …), marked[#25467 cut 10].servedLockStatekeeps itsstoredRowServed = falsedefault in the class signature and in the module function's parameter list, and the stub passes the parameter through.LockStateHosttypes every member as the class member itself (ObjectStackProtocolImplementation['m']). Each moved function 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.packagedBaseRefusal,packagedArtifactOwner,isDeclaredCodeDatasourceandisSealedManagedItem(which stay in the class), andisShippedFlowName,isUnservedSealedOverlayanddeclinesStoredRow(moved bodies calling one another through the protocol). No field is read, so the host has no getter.protocol.ts(getMetaItem,readFlattenedMetaItems,getMetaItemLayered,restoreArtifactRegistryView,loadMetaFromDband others), cut 2'sMetaDiagnosticsHost(itsservedLockStateclosure), and the published doors inpackages/rest/src/meta-item-history-routes.tsandpackages/runtime/src/domains/meta.ts, which askdeclinesStoredRowon the protocol instance.Module-level declarations, by reader
export. The one module-level declaration ofprotocol.tsthe bodies read iscanonicalMetaType(inisUnservedSealedOverlay), already exported; the new module imports it fromprotocol.jsas cut 5'sprotocol-lock-version-gates.tsdoes. The cycle is evaluation-safe: it is read only inside a function body.protocol.tsimports it from:@objectstack/spec/kernel(extractProtection,evaluateLockForWrite,evaluateLockForDelete,MetadataLockSchema, andresolveLockStateas a type),./packaged-base-regime.js(isOriginGatedType),@objectstack/metadata-core(isCodeArtifactBody),@objectstack/spec/shared(PLURAL_TO_SINGULAR),./item-lock.js(ItemLock, type).protocol.ts.extractProtection,evaluateLockForWrite,evaluateLockForDeleteandMetadataLockSchemalose their last reader and leave the@objectstack/spec/kernelimport list;resolveLockStatekeeps a reader (the class signature ofservedLockState) and stays.isOriginGatedType,isCodeArtifactBody,PLURAL_TO_SINGULARandcanonicalMetaTypekeep other readers. 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. Baseec4ef94eadand head3ebaea97were 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,protocol.tsblob equal toHEAD's).325970c1661efaa6a3762ce7de9e6bb205ea16099784f2b6c5950d62d175b331at base and at head, on bothdist/index.d.tsanddist/index.d.cts, 772,838 bytes each (the hash cuts 8 and 9 reported).cmpexits 0 on both pairs. Raw identity holds, so sorted-union identity holds too. The two public members keep their declaredbooleanreturn type, so their declarations do not move (declinesStoredRow(type: string, name: unknown): boolean;), and the four private ones stayprivate NAME;lines.9562749edf7b8bba67ed2f1779799a68b3d6934a8605074934572d9507c55ba6at both ends, both files (109 string-literal union runs sorted). This run's normaliser is its own script; its figure happens to equal cut 9's.index.jshashesa41e81cf2349514e…at base (cut 9's head hash) andb99c5148b08d3fc5…at head;servedLockState.callanddeclinesStoredRow.calleach occur 0 times in the base bundle and once in the head bundle (ESM and CJS alike).index.d.ts,declinesStoredRow(type: string, name: unknown)changed toname: string: rawc74ae751a3cb7a09…, normalisedfd072bd9d1ab499a…. Both move.9f18a0177ac736ed…on all four. None of the moved functions or the host type appears.No changeset:
skip-changeset, per ruling6348891160.Proof of move-only
this, return type and body): 451 tokens compared, 0 differ. Leaf tokens rather than the raw scanner because the scanner, run without template rescanning, swallows the rest ofservedLockState's body into one template-tail token after its error message's first${…}, which would compare whitespace. The parameter, return type and body text, comments included, is also equal with whitespace collapsed, for all six. Negative control: one changed token inisUnservedSealedOverlay's body (=== 'permission'to!==, on a copy) makes the check reportdiffer=1.protocol.ts. 236 of the 237 base statements other than the class are byte-identical, leading comments included. The other one is the@objectstack/spec/kernelimport that loses four names. Head adds one statement, the new module's import.protocol-lock-state.tshas 155 lines.Readers of the moved lines
Every test and script that reads
protocol.tsby path was grepped for each moved member's name and for the calls their bodies make (packagedBaseRefusal,packagedArtifactOwner,isDeclaredCodeDatasource,isSealedManagedItem,isCodeArtifactBody,isOriginGatedType,evaluateLockFor*,extractProtection,MetadataLockSchema, the error message).protocol.tsby path. The hypothesis holds, and every member moves:protocol.code-defined-datasource-door.test.ts:declinesStoredRownamed in a comment only.protocol.declines-stored-row-published.test.ts: callsprotocol.isShippedFlowName(…)andprotocol.declinesStoredRow(…).protocol.reads-environment-only.test.ts: callsprotocol.declinesStoredRow(…).packages/plugins/plugin-security/src/security-catalog-echo.test.ts:servedLockStatenamed in a comment only. 19/19 pass at head.packages/rest/src/meta-published-overlay.test.ts: callsprotocol.isShippedFlowName(…)and hidesdeclinesStoredRowbehind aProxyto pin that the door asks that one predicate. The stub's closures call throughthis, the method stays on the class, and 16/16 pass at head.packages/runtime/src/domains/meta-published-runtime-publish.test.ts: the same two shapes as the REST test. 12/12 pass at head.protocol.flow-by-name-shipped-name.test.tsandprotocol.flow-layered-shipped-name.test.ts(docblocks),packages/qa/dogfood/test/flow-shipped-name-published-door.dogfood.test.ts(a comment),protocol-meta-diagnostics.ts(the cut 2 host type and its call),item-lock.ts(a comment).PRODUCERS):servedLockState's unreachable-statethrow new Error(moves with its body, so the new module gets a row,'protocol-lock-state.ts': 1, the module's ownnew Error(count, beside the rows cuts 1, 3, 5, 6 and 7 added.protocol.tsgoes from 75 to 74 such sites, still above its floor of 5. Control: with the module's throw changed tonew TypeError((on disk, restored fromHEADunder a trap, hash equal toHEAD's after), the new row fails with "protocol-lock-state.ts no longer constructs errors here … expected 0 to be greater than or equal to 1" (1 failed, 12 passed); restored, 13/13 pass.protocol.read-verb-canonical-fold.test.tslists the members whose body folds throughcanonicalizeMetaRequestType(request). None of the six does; the list is unchanged and green.docs/qa/platform-checklist/areas/studio-authoring.jsoncites "protocol.ts servedLockState". The method keeps its name inprotocol.ts;check-platform-checklist --changed-from origin/main: OK, 29 anchors judged, 0 lost.check:adr-anchorsexits 0 at both ends: 85 anchored files, 52,570 citations, 1,846 → 1,846 decision-letter citations; the only difference in its output is the file count, 6,623 → 6,624. Theprotocol.tsanchor entry's ADR-0126 §2 / §3 paragraph namesisShippedFlowName/isStoredFlowEntryOfShippedName, but the mechanism it describes,hydrateOverlayIntoRegistryregistering a stored flow row without the envelope andreadFlattenedMetaItemsserving the loader's entries alone, stays inprotocol.ts, and both names stay there as class members. So the new module gets no entry (see Acceptance notes).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.check-engine-double-contract): exits 0 at both ends. TheupdateData/deleteDataseams keep their entries at new line numbers (14039 → 14044, 14064 → 14069).productionFilesis 3,686 at base and 3,688 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 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 atec4ef94ead.check-governed-merges --branch claude/project-thread-5tpuo2: 0 of 3 paths hit the register, NOT governed; 242 changed lines, under the 3,000-line human-merge bar.Verification
All at head
3ebaea97.pnpm --filter @objectstack/metadata-protocol typecheckexits 0.pnpm exec eslint --no-inline-config packages/metadata-protocolexits 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):ec4ef94ead: 21,504 tests (21,485 passed, 0 failed, 19 skipped), 266 files.3ebaea97: 21,505 tests (21,486 passed, 0 failed, 19 skipped), 266 files.PRODUCERSrow's case. The base leg is the packagesrc/swapped tree-only fromec4ef94ead(the new module removed from the tree) and restored fromHEADunder a trap;git diff HEADempty andgit statusclean after.dispatch-gates --commands --repo objectstack-ai/objectstackderives 59 gates on 3 changed paths; all 59 exit 0.check-plugin-teardown-shape --self-test,check:dual-build-cjs-loadsandcheck:lean-entry-closurefirst answered PREREQUISITE NOT MET (exit 3: a pinned fixture commit outside the shallow clone; unbuiltdist/) and exit 0 once the commit was fetched andpnpm buildran.dispatch-gates --ran: 59 derived, 59 run, 0 NOT-MEASURED, 0 UNRUN, exit 0.Acceptance notes
protocol.ts. If the seat reads the predicates themselves as the mechanism, the fix is apackages__metadata-protocol__src__protocol-lock-state.ts.jsonentry citing ADR-0126; the letter count does not move either way.origin/mainmoved toe2b40a264bafter the base (8 commits, none inpackages/metadata-protocol, merge-tree clean); not merged before this PR, so the suite and gates measuredec4ef94ead-based trees. The merge queue rebuilds on currentmain.Carry-forward
Unchanged from cut 9: 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