Repository navigation
[maintainer] refactor(metadata-protocol): split src/protocol.ts (33,065 lines, +10,169 in 30 days) along its ObjectStackProtocolImplementation seams, one move-only slice per PR #25467
Description
Filing gate ③: a task the maintainer dispatched, quoted verbatim below. Filed by domain:services seat 1 (seat post #6021) · os-sales · session session_016g7nYP9wdNx1GDa5XDr7Uy, as the domain:engine half of #24586's restart act. That half was handed over unfiled in 6341834009, and the engine surface is now this project's, folded into domain:server by PR #25247. ⛔ Not a claim.
The maintainer's words, verbatim (#24586, recorded in 6270097840): 「24586 同意A,是否建议这波分拆等 v18 发布之后再处理。」 Triage read the restart condition (npm @objectstack/spec latest ≥ 18.0.0) as true in 6291735609. The ruling's restart act: "one [maintainer] card per file over 10,000 lines into its owning lane … Each card starts with a fresh seam measurement taken at that time, in #23050's shape", and "protocol.ts goes first".
Reader who acts: the domain:server lane, engine surface (packages/metadata-protocol was domain:engine's). One dispatch per slice.
Measured (on origin/main b2c0752900, 2026-10-23)
-
Size and churn:
- 33,065 lines, up from 22,896 thirty days ago (
dabf8d795e, the last commit before 2026-09-23T15:00Z): +10,169, +44.4%. - 28 commits in 7 days and 184 in 30 days.
git blame --since=2026-09-23T15:00Zattributes 13,445 lines (40.7%) to the last 30 days.
- 33,065 lines, up from 22,896 thirty days ago (
-
Structure:
- a 6,643-line module preamble: helpers, three error classes, and the query-param and filter vocabulary;
- one
ObjectStackProtocolImplementationclass, lines 6644–32941 (26,298 lines, 267 members); - a 124-line trailer of package-persist helpers.
The sections, by contiguous member ranges:
| section | lines | lines from the last 30 days |
|---|---|---|
| module preamble (helpers, error classes, query-param and filter vocabulary) | 6,643 | 2,255 |
| class head, flow/SDUI resolvers, registration hooks, authoring gates, mutation pub/sub, overlay index | 1,961 | 707 |
| discovery, types, diagnostics, packaged bases, credential carry-forward | 1,578 | 339 |
metadata reads (getMetaItems, readFlattenedMetaItems, overlay rows, readMetaItem, layered, audit, getUiView) |
2,872 | 1,696 |
query validation (assert*FieldsExist, refuseInternal*) |
1,643 | 358 |
data CRUD (findData … readAsCaller) |
1,393 | 274 |
searchAll + meta cache |
605 | 160 |
batch and *Many data |
1,067 | 33 |
| write gates (overlay/code-only/organization/sealed/packaged-base, locks, version tokens, conflict audit) | 2,619 | 1,772 |
| registry hydration, view expansion, write-through, object storage | 1,996 | 1,112 |
save refusals, saveMetaItem (1,535 lines alone), saveConflict, migrateStoredMetadata |
2,960 | 1,666 |
history, publish, drafts, publish backfill (publishPackageDrafts 969 lines) |
2,600 | 828 |
package revert/delete/duplicate/import, orphans, commits, revertCommit, rollback |
2,837 | 1,335 |
diff, deleteMetaItem, loadMetaFromDb, load reports, findReferencesToMeta |
1,831 | 624 |
| install/update package + module trailer | 460 | 286 |
- Shared state a split must pass:
- The fields are
engine(149 refs),getServicesRegistry(16),environmentId(11), the cluster pub/sub trio (clusterPubSub,clusterNodeId,clusterUnsubscribe), the two listener sets,authoringChannel, and about 20 warn-once and cache flags. - Coupling is mostly method-to-method: 597
this.X(calls over 206 distinct members. Reads, write gates and saves call one another across the sections above.
- The fields are
- What reads it by path:
- The ADR anchor file
scripts/adr-anchors/packages__metadata-protocol__src__protocol.ts.json. It holds ADR-0005, 0029, 0087, 0119 and 0126, and its invariant names the two object-hydration seamsapplyObjectRegistryMutationandloadMetaFromDb. Themetadata-plugin.zod.tsanchor file andscripts/symbol-anchors.mjsalso name the file. - 10 more files under
scripts/:check-durability-degradation-log-level.mjs,check-engine-double-contract.mjs(+.pinned.json,.seams.json),check-filter-alias-parity.mjs,check-nul-bytes.mjs,check-system-context-census.mjs,docs-audit/affected-docs.mjs,objectql-double-limit.baseline.json,query-options-erasure-baseline.json. - 22 files under
docs/andcontent/, 11 of them ADRs. - Tests: 180 test files in
metadata-protocolimport it, and 71 files in other packages name it by path.
- The ADR anchor file
- In flight: none of the 21 open PRs touch the file.
The ask (from #24586's ruling and #23050's shape)
- Split along the existing seams, one area per PR. Each slice is move-only: no logic changes.
- Shared state stays explicit: moved code reaches the class's shared members through one named context object (the host pattern of [maintainer] refactor(rest): split
packages/rest/src/rest-server.ts(13,701 lines, 70 commits in 30 days) along itsregister*Endpointsseams, one move-only slice per PR,/metaafter #22877 stage 2 #23050, [maintainer] refactor(service-automation): splitsrc/engine.ts(13,735 lines, +2,199 in 30 days) along itsAutomationEngineseams, one move-only slice per PR #25222, [maintainer] refactor(plugin-security): splitsrc/security-plugin.ts(10,746 lines, +2,803 in 30 days) along itsSecurityPluginseams, one move-only slice per PR #25223 and [maintainer] refactor(plugin-auth): splitsrc/auth-manager.ts(10,338 lines, +1,867 in 30 days) along itsAuthManagerseams, one move-only slice per PR #25224). ⛔ Not a second copy of a helper, ⛔ not a re-derivation. - Every slice proves it moved nothing:
- every gate, baseline, ADR anchor and docs anchor that reads the file by path is migrated in the same PR and stays green;
- the ADR-0029 D9.8/D9.9 invariant's two seams keep a resolving anchor;
- the package's public
.d.tsstays identical. - ⛔ A gate whose target moved must not go silently empty.
- Serial with the file's in-flight PRs: a slice waits for an open PR on the same region, or that PR merges
mainafter the slice. At 28 commits a week, every slice measures the file's open PRs again at claim. - ⛔ No new gate.
Not in this card
- Any behaviour change.
- A design change to the shared members beyond giving them an explicit context.
objectql/src/engine.ts(23,903 lines) anddriver-sql/src/sql-driver.ts(22,096 lines). They are the other two engine-surface files under the same ruling, and they are filed once this card's first slices have landed ([Decision] Split the platform's largest, fastest-growing source files (protocol.ts 32,428 lines, +10,002 in 30 days) the way rest-server.ts was split, or leave them #24586's order:protocol.tsfirst).spec/src/conversions/registry.ts, which belongs todomain:spec.
Dedupe
MCP search_issues on this repository, closed included, with two queries:
- "split protocol.ts metadata-protocol move-only maintainer refactor"
- "refactor split objectql engine.ts sql-driver.ts large file"
The hits were #24586 (the ruling this card carries out), #25222, #25223 and #25224 (the domain:services files), and #23050 (closed, rest-server.ts). None covers protocol.ts. New.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 23, 2026
Claim: card thread ·
domain:server(formerdomain:enginesurface) · fordomain:servicesseat 1 (seat post #6021, project run by the Sales account; 由Sales账户的项目负责) · p2 · series card, cut 1 (one PR; cuts strictly serial) · 2026-10-23T15:20ZSession:
session_01J8pUyVs5eas1AjMdReJM7CAccount:
os-sales(the seat's linked user; the card's assignee)Branch:
claude/project-thread-uasfag(the harness-pinned branch for this session, cut fromorigin/mainab510f4c43; it names no issue, so the Duplicate Fix Guard's branch-name hint will not match — this claim is the identity record)Worktree:
objectstack-wt(a linked worktree in this session's container)Domain:
domain:serverSeat:
domain:services#1(seat post #6021; the PR goes back to that seat for ACCEPT)Ruling: #24586 letter A (
6270097840), restart read in6291735609. The series' .d.ts bar is ruling6348891160(sorted-union identity; raw identity reported when it holds).Container & model:
M,mode:thread,effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (a
[maintainer]refactor card).Thread-read: none
Serial constraints cleared: none of the 21 open PRs touches
packages/metadata-protocol/src/protocol.ts(each PR's file list read in this act againstorigin/main; #25451 touches onlyprotocol.runtime-authoring-gate.test.ts, the Version Packages PR #24876 onlyCHANGELOG.md/package.json). Nopm:dispatchedcard's claimed file surface names the file. Re-measured again beforepr_create; a new open PR on the moved region means this cut yields.File surface (read on
origin/mainab510f4c43, whereprotocol.tsis 33,065 lines):Cut 1 = the card's "batch and
*Manydata" section (the seat's suggested first slice: 1,067 lines, 33 of them from the last 30 days). SixteenObjectStackProtocolImplementationmethod bodies move unedited frompackages/metadata-protocol/src/protocol.tsinto a new module,packages/metadata-protocol/src/protocol-batch-data.ts, in the host shape of #23050 / #25222 / #25223 / #25224:batchData:16696,createManyData:17263,insertManyData:17348,updateManyData:17390,deleteManyData:17574;runAtomicBatchData:16739,runAtomicBatch:16775,runBatchDataLoop:16850,reconcileStoppedBatch:17108,locateBatchCause:17170,buildBatchDataResponse:17182,buildRolledBackBatchResponse:17219,runUpdateManyLoop:17424,buildUpdateManyResponse:17497,runDeleteManyLoop:17619,buildDeleteManyResponse:17708.triggerAutomation:17527sits between them but is not batch code; it stays.How the host is built:
.call.asyncis dropped from the stubs, which return the moved function's promise.engine(field), and the methodsassertObjectRegistered,assertRecordExists,probeRecordplus the moved methods' calls to one another. Methods go as late-bound closures, so a spy or double set on the instance is still the one a body reaches.enginegoes as a getter.applyPublishBackfill(this.updateManyData(), which keeps calling the class method.Module-level declarations the moved bodies read (all stay in
protocol.ts; each has readers outside the moved text exceptmergeDroppedFieldEvents, which stays too, so no declaration moves):exportadded in place, imported back by value or type from./protocol.js:byIdUpdateRecord,mergeDroppedFieldEvents,rowOperationFailureFallback,rowRequiredIdError,toRowApiError,type BatchDataRowResult,type BatchDataLoopOutcome.src/index.tsexports from./protocol.jsby name, so none of them is published; the proof measures it (raw.d.tsand ESM/CJS export lists base vs head). Every value import is read only inside function bodies, so the module cycle is evaluation-safe; the PR lists each read site.protocol.tsdoes):engineCanRollBack,recordNotFoundError(@objectstack/core),omitInternalFieldsFromWriteResponse(./write-response-internal-fields.js), and the@objectstack/spectypes the bodies name.Path readers migrated in the same PR (each measured base vs head in the PR):
scripts/adr-anchors/: theprotocol.tsentry's ADR-0119 paragraph describesbatchData's atomic path, which moves. Per the series' rule, the new module gets its own entry carrying ADR-0119 and that paragraph verbatim; theprotocol.tsentry is unchanged (ADR-0119 is still cited at five sites outside the moved text).check:adr-anchorsdecision-letter totals reported base and head.protocol.bracketed-refusal-opener-absence.test.ts: the moved text holds 5new Error(sites, so the new module joins itsPRODUCERSlist with a measured floor; otherwise those sites would leave the scan silently.protocol.tskeeps its floor of 5.docs/adr/0119-…mdanchorsprotocol.ts#batchData: the method shell stays, so it still resolves;check-adr-symbol-anchorsrun by hand at both ends.insert/update/deletecalls; if they shift class,--writeplus the page's prose count, with a per-site base/head comparison), system-context census (0isSystemreads in the moved text), query-options erasure ratchet (0 countedfind/findOne/count/aggregatesites in the moved text), engine-double contract seams (deleteData/updateDatarows, which stay), durability log level (scans the whole package).⛔ Nothing else changes: no moved body is edited; the only stay-behind edits are the
exportkeywords above and the stub bodies; no ADR ordocs/adr/**text is edited; no new gate. One PR,skip-changeset(no behaviour change),Part of #25467.Proof the PR carries: AST leaf-token identity of every moved body (with a one-token negative control),
.d.tsblock per ruling6348891160(raw and normalised sha256 base/head, normaliser, raw diff line count, positive control), ESM/CJS export lists, themetadata-protocolsuite at base and head (same counts),dispatch-gates --commandsall run with exits, and the hand gates above.objectstack-fleet commentedon Oct 23, 2026
Landed cut 1 (batch and
*Manydata) ·domain:servicesseat 1 (seat post #6021) ·os-sales·session_016g7nYP9wdNx1GDa5XDr7Uy· 2026-10-23T17:23Zb55faf2162origin/mainbf5855b5bcState: the card stays open and dispatched (
Part of). The card thread plans cut 2 on the mergedprotocol.tsand re-checks the in-flight PRs on the file first (serial rule). It claims cut 2 afresh before it pushes.Generated by Claude Code
objectstack-fleet commentedon Oct 23, 2026
Claim: card thread ·
domain:server(formerdomain:enginesurface) · fordomain:servicesseat 1 (seat post #6021, project run by the Sales account; 由Sales账户的项目负责) · p2 · series card, cut 2 (one PR; cuts strictly serial; cut 1 landed as #25494,bf5855b5bc) · 2026-10-23T17:30ZSession:
session_01J8pUyVs5eas1AjMdReJM7CAccount:
os-sales(the seat's linked user; the card's assignee)Branch:
claude/project-thread-uasfag(the harness-pinned branch for this session, restarted fromorigin/main5188e7f18fafter cut 1 merged; it names no issue, so this claim is the identity record)Worktree:
objectstack-wt(a linked worktree in this session's container)Domain:
domain:serverSeat:
domain:services#1(seat post #6021; scope agreed with the seat before this claim; the PR goes back to that seat for ACCEPT)Ruling: #24586 letter A (
6270097840), restart read in6291735609. The series' .d.ts bar is ruling6348891160(sorted-union identity; raw identity reported when it holds).Container & model:
M,mode:thread,effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (a
[maintainer]refactor card).Thread-read: none
Serial constraints cleared: none of the 12 open PRs touches
packages/metadata-protocol/src/protocol.ts(each PR's file list read in this act, the Version Packages PR #24876 paged through all 395 files: onlyCHANGELOG.md/package.jsonin this package). Re-measured again beforepr_create; a new open PR on the moved region means this cut yields.File surface (read on
origin/main5188e7f18f, whereprotocol.tsis 32,468 lines):Cut 2 = the discovery and diagnostics bodies from the card's "discovery, types, diagnostics, packaged bases, credential carry-forward" section: about 800 lines, 42 of them from the last 30 days (5%, the coldest slice left). Three
ObjectStackProtocolImplementationmethod bodies move unedited into a new module,packages/metadata-protocol/src/protocol-discovery.ts(hostDiscoveryHost), in the shape cut 1 used (#23050 shape B):getDiscovery:8570,getMetaDiagnostics:9257;listLiveMetadataTypes:9059.engine(field, as a getter), and the methodsgetServicesRegistry,searchAll,getMetaItems,shippingPackagesOf,artifactLockLayerAt,servedLockState,isArtifactBacked(late-bound closures).Stays, deliberately:
getMetaTypes:9077, between them: its body reads the private staticObjectStackProtocolImplementation.envWritableTypes(), which a module function cannot reach unedited (private statics stay, as in [maintainer] refactor(plugin-auth): splitsrc/auth-manager.ts(10,338 lines, +1,867 in 30 days) along itsAuthManagerseams, one move-only slice per PR #25224).TYPE_TO_FORM,HAND_CRAFTED_SCHEMASandtoJsonSchemaSafe, read by it, stay with it. It keeps callinglistLiveMetadataTypesthrough the class.getProjectId:8566: its body is no longer than its stub would be.Module-level declarations:
SERVICE_CONFIG:5498is read only bygetDiscovery: it moves with it, unedited with its docblocks, unexported.type ShippingPackages:2304is read by code that stays too:exportadded in place, imported back as a type.src/index.tsexports from./protocol.jsby name, so it is not published; the proof measures it.protocol.tsuses (@objectstack/spec/api,/system,/kernel,@objectstack/core,./discovery-version.js,./metadata-diagnostics.js,./item-lock.js).Readers (measured; the PR reports each base vs head):
scripts/adr-anchors/protocol.tsentry: none of its paragraphs (ADR-0029 D9.8/D9.9 hydration seams, ADR-0119batchData, ADR-0005/0087 view storage, ADR-0126 flow Regime C) describes these bodies, so no new entry. The decision letters inside the moved bodies leave the anchored surface; the exactcheck:adr-anchorscount is reported base → head.docs/qa/platform-checklist/areas/studio-authoring.jsonanchorsprotocol.ts#getMetaDiagnostics: the method shell stays, so it still resolves; not edited;check-platform-checklistat both ends.isSystemreads (system-context census), enginefind/findOne/count/aggregate(erasure ratchet), engineupdate/deleteseams (engine-double contract),new Error((bracketed-refusalPRODUCERS), and none of the package's source-scanning pins' patterns.⛔ Nothing else changes: no moved body is edited; the only stay-behind edits are the one
exportkeyword and the stub bodies; no ADR ordocs/**text is edited; no new gate. One PR,skip-changeset,Part of #25467.Proof the PR carries, as cut 1: AST leaf-token identity of every moved body (with a negative control),
.d.tsblock per ruling6348891160(raw and normalised sha256 base/head, normaliser, raw diff, positive control), ESM/CJS export lists, themetadata-protocolsuite at base and head,dispatch-gates --commandsall run with exits and--ran, and the hand gates (check-adr-symbol-anchors,check:adr-anchorswith letters, censuses,check-platform-checklist) at both ends.objectstack-fleet commentedon Oct 23, 2026
Claim amendment: cut 2 of #25467 (amends claim
6370841668) ·domain:servicesseat 1 (seat post #6021; 由Sales账户的项目负责) · 2026-10-23T17:45ZSession:
session_01J8pUyVs5eas1AjMdReJM7CBranch:
claude/project-thread-uasfag(unchanged, baseorigin/main5188e7f18f)Seat:
domain:services#1(the narrowed scope below agreed with the seat before this amendment)Thread-read: 6370841668
Narrowed scope. Cut 2 is
getMetaDiagnosticsalone (:9257). Its body moves unedited intopackages/metadata-protocol/src/protocol-meta-diagnostics.ts(hostMetaDiagnosticsHost, members read:getMetaItems,shippingPackagesOf,artifactLockLayerAt,servedLockState,isArtifactBacked, as late-bound closures).type ShippingPackagesgainsexportin place, as claimed.getDiscovery,listLiveMetadataTypesandSERVICE_CONFIGleave this cut and stay inprotocol.ts; nothing else in the claim changes.Why
getDiscoverycannot move (measured, nothing pushed). It is public and its return type is INFERRED (async getDiscovery() {), sodist/index.d.tsprints the type the compiler infers. With its body moved in this series' shape, the stub's type is inferred from the new module, and the emitted.d.tschanged in two ways that are not union-member order: it dropped a property docblock (@deprecated Use name. Removed in protocol 18 (#4828).), and it spliced about 100 lines of an unrelatedprotocol.tsdocblock (the save door's hook-without-body refusal) into a nesteddescriptionproperty. Base raw8e1a224c…, trial head rawfc33e319…; normalised (ruling6348891160's normaliser) base5b98a8e8…, trial head different, normalised diff 111 lines. Under ruling6348891160that is a stop, not a pass. The token proof and the package suite were clean on that trial; only the published surface moved.listLiveMetadataTypes' body is barely longer than its stub, andSERVICE_CONFIGis read only bygetDiscovery, so both stay with it.Carry-forward for later cuts. A public member with an inferred return type stays in
protocol.tsin this series: annotating it would be a signature edit, which needs a ruling. Measured on5188e7f18f, the public members with no declared type:getDiscovery,getMetaTypes,getMetaItems,getMetaItemsForExecution,getMetaItem,getMetaItemForExecution,getUiView,findData,getData,validateData,createData,cloneData,updateData,deleteData,saveMetaItem.Decision letters: one leaves the anchored surface with the body (ADR-0110 D3); measured
check:adr-anchors1,979 → 1,978, reported in the PR.objectstack-fleet commentedon Oct 23, 2026
Landed cut 2 ·
domain:servicesseat 1 (seat post #6021) ·os-sales·session_016g7nYP9wdNx1GDa5XDr7Uy· 2026-10-23T19:27Z6372365108), head9f403be528origin/mainb2411c001dState: the card stays open and dispatched (
Part of). The card thread claims the next cut afresh on the mergedprotocol.ts. Public members whose return type is inferred stay in the class.Generated by Claude Code
objectstack-fleet commentedon Oct 23, 2026
Claim: card thread ·
domain:server(formerdomain:enginesurface) · fordomain:servicesseat 1 (seat post #6021, project run by the Sales account; 由Sales账户的项目负责) · p2 · series card, cut 3 (one PR; cuts strictly serial; cut 1 landed as #25494bf5855b5bc, cut 2 as #25518b2411c001d) · 2026-10-23T19:38ZSession:
session_01J8pUyVs5eas1AjMdReJM7CAccount:
os-sales(the seat's linked user; the card's assignee)Branch:
claude/project-thread-uasfag(the harness-pinned branch for this session, restarted fromorigin/mainb2411c001dafter cut 2 merged; it names no issue, so this claim is the identity record)Worktree:
objectstack-wt(a linked worktree in this session's container)Domain:
domain:serverSeat:
domain:services#1(seat post #6021; scope A agreed with the seat before this claim, with its conditions carried below; the PR goes back to that seat for ACCEPT)Ruling: #24586 letter A (
6270097840), restart read in6291735609. The series' .d.ts bar is ruling6348891160(sorted-union identity; raw identity reported when it holds).Container & model:
M,mode:thread,effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (a
[maintainer]refactor card).Thread-read: none
Serial constraints cleared: none of the 9 open PRs touches
packages/metadata-protocol/src/protocol.ts(each PR's diff against its merge base read in this act; the Version Packages PR #24876 touches onlyCHANGELOG.md/package.jsonin this package).origin/main(f38832be9c) has not touched this package sinceb2411c001d. Re-measured again beforepr_create; a new open PR on the moved region means this cut yields.File surface (read on
origin/mainb2411c001d, whereprotocol.tsis 32,309 lines):Cut 3 = the query validation: the section
:12797–:14502(1,706 lines, 382 of them from the last 30 days). Nineteen PRIVATEObjectStackProtocolImplementationmethods move unedited into a new module,packages/metadata-protocol/src/protocol-query-validation.ts(hostQueryValidationHost), in the shape cuts 1–2 used (#23050 shape B):assertObjectRegistered:12861,resolveQueryFields:12933,assertQueryParamsAreFields:12961,assertFilterFieldsExist:13064,assertSortFieldsExist:13358,assertProjectionFieldsExist:13546,assertExpandTargetsExist:13670,assertSearchFieldsAreSearchable:13793,assertGroupByFieldsExist:13988,assertAggregationFieldsExist:14103,assertNoInternalFieldEvaluated:14283,refuseInternalInFilter:14313,refuseUnservedRelationTarget:14346,refuseInternalInExpand:14373,servedExpand:14429,servesExpansionTarget:14454,orderByFieldNames:14460,groupByFieldNames:14469,refuseInternalNames:14478..d.tsprints no type for any of them: none is on the series' skip list of public inferred-return members.engine(field, as a getter), and the methodsassertFilterFieldsExist,groupByFieldNames,orderByFieldNames,refuseInternalInExpand,refuseInternalInFilter,refuseInternalNames,refuseUnservedRelationTarget,resolveQueryFields,servedExpand,servesExpansionTarget(late-bound closures, so the recursive walks still go through the protocol).Module-level declarations, each measured by an AST reader walk over all of
protocol.ts(identifier references outside the declaration itself):nestedRelationRoute:392,warnedNoRegistryForDataGate:536(the mutablelet: its only reads and its only write are inassertObjectRegistered, so the state moves whole and is never copied),AGGREGATION_FUNCTIONS:4489,DATE_GRANULARITIES:4490,UNMATERIALIZED_SORT_TYPES:4892,invalidQueryError:4988,suggestQueryParam:5131,collectFilterFieldKeys:5217,INTERNAL_FIELD_WALK_DEPTH:5321,EXPANSION_TARGET_OPERATION:5337,RELATION_CONDITION_TARGET_OPERATION:5348. Their initialisers read only package imports or nothing, so module evaluation order is unaffected.exportin place (read by code that stays, or by a moved helper and by code that stays):collectFilterReads(←collectStoredMetadataFilterFields),invalidSortError(←normalizeSortNodes,invalidSortDirectionKeyError),isObjectOfDisabledPackageandobjectPackageDisabledError(←readMetaItemFace,getMetaItemLayered),isPlainRecord(←storableEqual,soleMovedFrom,buildStorableViewNode),suggestFieldName,FILTER_LOGICAL_KEYS,QUERY_PARAM_NEAR_MISS,nearMissKey,ODATA_SPELLING.src/index.tsexports from./protocol.jsby name, so none is published; the proof measures it.protocol.tsdrops the import names that lose every reader (noUnusedLocals); the module imports them from the same specifiers.Readers (measured; the PR reports each base vs head):
protocol.bracketed-refusal-opener-absence.test.tsPRODUCERS: 17new Error(sites move (16 in the methods, 1 ininvalidQueryError);protocol.ts104 → 87 against its floor 5, and the new module is listed with its measured floor, 17.scripts/adr-anchors/protocol.tsentry: none of its paragraphs (ADR-0029 D9.8/D9.9, ADR-0119batchData, ADR-0005/0087 view storage, ADR-0126 flow Regime C) describes these bodies, so no new entry.check:adr-anchorsdecision letters are reported exactly base → head.docs/qa/platform-checklist/areas/api-backend.jsonandsearch.jsonanchorprotocol.ts#moved methods: the method shells stay, so they still resolve; not edited;check-platform-checklistat both ends.⛔ Nothing else changes: no moved body or declaration is edited; the only stay-behind edits are the ten
exportkeywords, the narrowed import lists and the stub bodies; no ADR ordocs/**text is edited; no new gate. One PR,skip-changeset,Part of #25467.Proof the PR carries, as cuts 1–2: AST leaf-token identity of every moved body and declaration (with a negative control), the declaration reader table,
.d.tsblock per ruling6348891160(raw and normalised sha256 base/head, normaliser, raw diff, positive control), ESM/CJS export lists, themetadata-protocolsuite at base and head compared per test,dispatch-gates --commandsall run with exits and--ran, and the hand gates at both ends.objectstack-fleet commentedon Oct 23, 2026
Landed cut 3 ·
domain:servicesseat 1 (seat post #6021) ·os-sales·session_016g7nYP9wdNx1GDa5XDr7Uy· 2026-10-23T22:03Z6375081284), head3b1ae50413origin/main798d480269State: the card stays open and dispatched (
Part of). The card thread claims cut 4 afresh on the mergedprotocol.ts. #25533 also editsprotocol.ts(publishDrafts). Its merge-tree is clean, but its byte offsets have shifted, so its.d.tsis re-read before it lands.Generated by Claude Code
objectstack-fleet commentedon Oct 23, 2026
Claim: card thread ·
domain:server(formerdomain:enginesurface) · fordomain:servicesseat 1 (seat post #6021, project run by the Sales account; 由Sales账户的项目负责) · p2 · series card, cut 4 (one PR; cuts strictly serial; cut 1 landed as #25494bf5855b5bc, cut 2 as #25518b2411c001d, cut 3 as #25538798d480269) · 2026-10-23T22:33ZSession:
session_01J8pUyVs5eas1AjMdReJM7CAccount:
os-sales(the seat's linked user; the card's assignee)Branch:
claude/project-thread-uasfag(the harness-pinned branch for this session, restarted fromorigin/main798d480269after cut 3 merged; it names no issue, so this claim is the identity record)Worktree:
objectstack-wt(a linked worktree in this session's container)Domain:
domain:serverSeat:
domain:services#1(seat post #6021; scope C agreed with the seat before this claim, with its five conditions carried below; the PR goes back to that seat for ACCEPT)Ruling: #24586 letter A (
6270097840), restart read in6291735609. The series' .d.ts bar is ruling6348891160(sorted-union identity; raw identity reported when it holds).Container & model:
M,mode:thread,effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (a
[maintainer]refactor card).Thread-read: none
Serial constraints cleared: of the 9 open PRs, only #25533 (publish-drafts widget probes) touches
packages/metadata-protocol/src/protocol.ts; its two hunks sit inpublishPackageDrafts(≈:26263/:27146on its own basedc3e5b9d7b), ~11,000 lines past the last line this cut changes (:15284), so the two are disjoint. No open PR touchespackages/core/src/security/row-serving-door-exposure.pin.test.ts.origin/main(now4df174bcc4) has not touchedpackages/metadata-protocolor that pin since798d480269. Re-measured again beforepr_create(withgit merge-treeagainst main and #25533); a new open PR on the moved region means this cut yields.File surface (read on
origin/main798d480269, whereprotocol.tsis 31,223 lines):Cut 4 = the record reads (scope C, narrowed during the trial — see below). Six
ObjectStackProtocolImplementationmethods move unedited into a new module,packages/metadata-protocol/src/protocol-record-reads.ts(hostRecordReadHost), in the shape cuts 1–3 used (#23050 shape B):omitInternalWriteFields:14488(public, annotated: void),assertRecordExists:14562(private),assertVersionOf:14624(private),assertVersionMatch:14675(private),readAsCaller:14693(private),searchAll:14811(public, annotated: Promise<{…}>).engineandgetServicesRegistry(as getters), and the methodsassertVersionOf,getMetaItems,probeRecord,readAsCaller(late-bound closures).RecordReadHosttherefore carries no elevation member; each function'sthisis aPickof only what it reads.Narrowed during the trial, before this claim (a strict subset of the agreed scope C; both members stay in the class exactly as they are):
probeRecordstays. Its system-contextengine.findOneis one ofprotocol.ts's 6 sites inscripts/query-options-erasure-baseline.json, which is keyed by file and only shrinks, so the body cannot change files unedited (thequery-options/no-any-erasurelint refuses it in the new file). It stays as a host member the moved bodies call through the protocol. This also keeps the cut's oneisSystemsite where it is: the system-context census reads identically at both ends.getMetaItemCachedstays.protocol.read-verb-canonical-fold.test.ts(the Three read-side/metaverbs (history, audit, references) never reachcanonicalizeMetaRequestType— they still derive their key from the MANIFEST map #9157 pin) derives the/metarequest-boundary verbs from the method bodies inprotocol.tsitself and requires each to callcanonicalizeMetaRequestType; with the body moved, the stub no longer folds and the pin reds. Re-teaching that pin to follow a stub into another module is a change to the pin, not a move, so the body stays where the pin reads it. With it staysimpleHashandmetadataItemNotFoundError(only it reads them), andcanonicalizeMetaRequestTypeneeds noexport.Module-level declarations, each measured by an AST reader walk over all of
protocol.ts(identifier references outside the declaration itself; transitive closure over the moved set):assertVersionTokenNotMalformed:3175,NormalisedVersion:3207,normaliseVersionToken:3299,versionTokensAgree:3326. Each carries exactly one docblock (its own; leading-trivia blocks checked). None is read during module evaluation.exportin place:canonicalVersionInstant:3245(←assertVersionOf, moved, andauditInstantMs:3349, which stays).src/index.tsexports from./protocol.jsby name, so it is not published; the proof measures it.ConcurrentUpdateErrorandMalformedVersionTokenErrorare already exported and are imported as values.protocol.tsdrops the import names that lose every reader (canServeApiOperation,ISecurityService,resolveI18nLabel;noUnusedLocals); the module imports them from the same specifiers.Readers (measured in the trial; the PR reports each base vs head):
packages/core/src/security/row-serving-door-exposure.pin.test.ts(seat condition 1):searchAll'scanReadObjectcall and itscanServeApiOperationdecision both move, so theCALLERSkey and thedecisionSiteof the cross-object-search row are repointed toprotocol-record-reads.ts. The row keeps its door, operation and behaviour pin (protocol.search-api-exposure.test.ts, unchanged). No wiring line of this door stays inprotocol.ts: thecanReadObjectcall matcher no longer fires there, so keepingprotocol.tsas a key would red the pin's stale-entry check. 7/7 core pin tests pass at both ends (second-object-read-exposure.pinneeds no edit this cut).readAsCaller'sfindOne,searchAll'sfind) are typed and not counted; the counted one stays withprobeRecord.check-adr-symbol-anchors,check-platform-checklist(theprotocol.ts#searchAllanchors resolve on the method shell, which stays) and spec liveness (object.jsoncitesprotocol.ts#searchAll; its key-mention check passes on the stay-behind docblock): identical output at both ends. The blanking check before scope C found no anchor that resolves only inside the moved bodies (seat condition 4).check:adr-anchorsdecision letters, exact: 1,954 → 1,949 at798d480269→ head. The 5 that leave are letter citations inside moved code (ADR-0110 D3×2,ADR-0079 D3,ADR-0131 D6,ADR-0090 D2);protocol.ts's anchor entry governs ADR-0005/0029/0087/0119/0126 and none of its paragraphs describes these bodies, so the new module gets no entry and those citations leave the anchored surface unedited.protocol.bracketed-refusal-opener-absence.test.tsPRODUCERS: nonew Error(site moves (protocol.ts87 → 87), so no row is added.scripts/adr-anchors/,docs/qa/platform-checklist/**: not edited.⛔ Nothing else changes: no moved body or declaration is edited; the only stay-behind edits are the one
exportkeyword, the narrowed import lists and the stub bodies, plus the one pin row above; no ADR ordocs/**text is edited; no new gate. One PR,skip-changeset,Part of #25467.Proof the PR carries, as cuts 1–3: AST leaf-token identity of every moved body and declaration (with a negative control), the declaration reader table, the
readAsCaller/searchAlltoken identity and hostPicks (seat condition 3),.d.tsblock per ruling6348891160measured last on the final layout (raw and normalised sha256 base/head, normaliser, raw diff, positive control), ESM/CJS export lists, themetadata-protocolsuite at base and head compared per test,dispatch-gates --commandsall run with exits and--ran, and the hand gates at both ends.objectstack-fleet commentedon Oct 24, 2026
Landed cut 4 (record reads) ·
domain:servicesseat 1 (seat post #6021) ·os-sales·session_016g7nYP9wdNx1GDa5XDr7Uy· 2026-10-24T03:39Z6379127763), head034fbb27f8origin/mainba6912c1adState: the card stays open and dispatched (
Part of). On the mergedprotocol.ts, the card thread either claims the next cut afresh or posts the series' final report.probeRecord(erasure baseline) andgetMetaItemCached(the #9157 pin) stay.Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
Claim: card thread ·
domain:server(formerdomain:enginesurface) · fordomain:servicesseat 1 (seat post #6021, project run by the Sales account; 由Sales账户的项目负责) · p2 · series card, cut 5 (one PR; cuts strictly serial; cuts 1–4 landed as #25494bf5855b5bc, #25518b2411c001d, #25538798d480269, #25589ba6912c1ad) · 2026-10-24T04:11ZSession:
session_01J8pUyVs5eas1AjMdReJM7CAccount:
os-sales(the seat's linked user; the card's assignee)Branch:
claude/project-thread-uasfag(the harness-pinned branch for this session, restarted fromorigin/mainba6912c1adafter cut 4 merged; it names no issue, so this claim is the identity record)Worktree:
objectstack-wt(a linked worktree in this session's container)Domain:
domain:serverSeat:
domain:services#1(seat post #6021; scope agreed with the seat before this claim, with its two pre-claim conditions answered below; the PR goes back to that seat for ACCEPT)Ruling: #24586 letter A (
6270097840), restart read in6291735609. The series' .d.ts bar is ruling6348891160(sorted-union identity; raw identity reported when it holds).Container & model:
M,mode:thread,effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (a
[maintainer]refactor card).Thread-read: none
Serial constraints cleared: none of the 9 open PRs touches
packages/metadata-protocol/src/protocol.tsorprotocol.bracketed-refusal-opener-absence.test.ts(each PR's diff against its merge base read in this act).origin/main(nowa57643d3de) has not touchedpackages/metadata-protocolsinceba6912c1ad. Re-measured again beforepr_createwithgit merge-tree; a new open PR on these files means this cut yields. A release freeze is in force (Sales, 03:57Z): the PR stays a draft and is not readied, armed or queued until the coordinator says merges resume.File surface (read on
origin/mainba6912c1ad, whereprotocol.tsis 30,718 lines):Cut 5 = the lock gate and the optimistic-concurrency write addresses. Sixteen PRIVATE
ObjectStackProtocolImplementationmethods move unedited into a new module,packages/metadata-protocol/src/protocol-lock-version-gates.ts(hostLockVersionGateHost), in the shape cuts 1–4 used (#23050 shape B). 278 body lines, 122 of them from the last 30 days:getEffectiveLock:17113,readLockGateOverlayLayer:17150,recordMetadataAudit:17259,lockWriteRefusal:17338,assertLockAllowsWrite:17396,assertLockAllowsDelete:17416;storedHashDigest:17520,receiptVersion:17532,storedHeadAt:17559,readVersionToken:17598;packagelessReadAddress:17635,strictDraftReadAddress:17661,packagelessDraftAddress:17798;storedParentForToken:17839,metadataConflictRefusal:17879,recordPendingDenialAudit:17966.engine(a getter) and the methodsartifactLockLayerAt,getEffectiveLock,getOverlayRepo,lockWriteRefusal,overlayLockLayerAt,packagelessAddress,packagelessDraftAddress,readLockGateOverlayLayer,receiptVersion,recordMetadataAudit,rethrowUnlessMetadataStoreUnprovisioned,storedHashDigest,storedHeadAt(late-bound closures). No field is assigned; the host carries no elevation member.Stay in the class (between or beside the moved methods):
recordOptimisticConflictAuditand the staticoptimisticConflictAuditEntry: the first reads a private static (TS2341 from a module function; ruling6364006498precedent).packagelessAddress, narrowed out during the trial:scripts/check-durability-degradation-log-level.mjs's read-seam rule follows itsfindEnvironmentRowsread and the four callers that guard it insideprotocol.ts(applyObjectRegistryMutation,deleteMetaItem,deletePackage,loadMetaFromDb). Moved, the census drops from 83 read seams to 79; kept, the seam list is identical at both ends.Module-level declarations, each measured by an AST reader walk over all of
protocol.ts(transitive closure over the moved set):ErrorWithPendingAudit:6192(type) andInboundVersionConflictError:3679(class; also named in one stub docblock's{@link}prose, which stays).exportin place:canonicalMetaType:417(←canonicalizeMetaRequestType,governServedItem,stripServedSystemColumns,bundleMemberOf) andMetadataAuditEntry:6164(←withPendingAudit,optimisticConflictAuditEntry).src/index.tsnames its exports, so neither is published.Seat's pre-claim conditions, measured on the trial build:
.d.ts(ruling6348891160), baseba6912c1ad(deps built withturbo run build --filter='@objectstack/metadata-protocol^...') vs the trial head:dist/index.d.tsanddist/index.d.ctsraw25da084d43455d12…at both ends (770,690 bytes), normalisedff7d6892b9f1161d…at both ends. Raw identity: the moved class and type print nowhere new, andcanonicalMetaType's docblock does not splice onto a neighbour. Re-measured last on the final layout in the PR.check-governed-merges --branchon the trial file list (3 paths): NOT governed, 968 changed lines (+674 / −294).Readers (measured in the trial; the PR reports each base vs head):
protocol.bracketed-refusal-opener-absence.test.tsPRODUCERS: 4new Error(sites move (protocol.ts87 → 83 against its floor 5); the new module is listed with its measured floor,'protocol-lock-version-gates.ts': 4, as cut 3 listed its module.check:adr-anchorsdecision letters, exact: 1,883 → 1,882. The one that leaves is anADR-0110 D3comment citation inreadLockGateOverlayLayer; no paragraph ofprotocol.ts's anchor entry describes these bodies, so no new entry.check-adr-symbol-anchors,check-platform-checklist,check-system-context-census,check-tenant-audit-census,check-query-options-erasure-ratchet, speccheck-liveness,check-durability-degradation-log-level(withpackagelessAddresskept), corerow-serving-door-exposure.pin+second-object-read-exposure.pin(7/7).check-engine-double-contractdiffers only in the line numbers of theupdateData/deleteDataseams andproductionFiles+1 (the new file).metadata-protocolsuite: 21,489 tests at both ends, 0 per-test differences. Cross-package path readers (objectqlcore-boundary.ratchet+protocol-publish-canonical-fold, spec liveness evidence + allow-org-override-absence, client/rest discovery-double-retired-key) pass.⛔ Nothing else changes: no moved body or declaration is edited; the only stay-behind edits are the two
exportkeywords, the stub bodies and the one import of the new module, plus the onePRODUCERSrow; no ADR ordocs/**text is edited; no new gate. One PR,skip-changeset,Part of #25467.Proof the PR carries, as cuts 1–4: AST leaf-token identity of every moved body and declaration (trial: 2,139 tokens, 0 differ, with a negative control), the declaration reader table, the
.d.tsblock measured last, ESM/CJS export lists, the suite at base and head compared per test,dispatch-gates --commandsall run with exits and--ran, and the hand gates at both ends.objectstack-fleet commentedon Oct 24, 2026
Claim: card thread ·
domain:server(formerdomain:enginesurface) · fordomain:servicesseat 1 (seat post #6021, project run by the Sales account; 由Sales账户的项目负责) · p2 · series card, cut 6 (one PR; cuts strictly serial; cuts 1–5 landed as #25494bf5855b5bc, #25518b2411c001d, #25538798d480269, #25589ba6912c1ad, #2560160d8fd2ea6) · 2026-10-24T10:35ZSession:
session_01J8pUyVs5eas1AjMdReJM7CAccount:
os-sales(the seat's linked user; the card's assignee)Branch:
claude/project-thread-uasfag(the harness-pinned branch for this session, restarted fromorigin/main60d8fd2ea6after cut 5 merged; it names no issue, so this claim is the identity record)Worktree:
objectstack-wt(a linked worktree in this session's container)Domain:
domain:serverSeat:
domain:services#1(seat post #6021; scope agreed with the seat before this claim, as in-hand series work under Sales's 08:24Z word that this card continues to merge; the PR goes back to that seat for ACCEPT)Ruling: #24586 letter A (
6270097840), restart read in6291735609. The series' .d.ts bar is ruling6348891160(sorted-union identity; raw identity reported when it holds).Container & model:
M,mode:thread,effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (a
[maintainer]refactor card).Thread-read: none
Serial constraints cleared: none of the 11 open PRs touches
packages/metadata-protocol/src/protocol.ts, the new module orprotocol.bracketed-refusal-opener-absence.test.ts(each PR's diff against its merge base read in this act), andgit merge-treeof the cut head with each of them and with main7265b33e77is clean.origin/mainhas not touchedprotocol.tssince60d8fd2ea6(the three commits since touch onlybuild-probes.tsand its test in this package). Re-measured again beforepr_create; a new open PR on these files means this cut yields.File surface (read on
origin/main60d8fd2ea6, whereprotocol.tsis 30,548 lines):Cut 6 = the save door's refusals. Nine PRIVATE
ObjectStackProtocolImplementationmethods, one contiguous run of the class, move unedited into a new module,packages/metadata-protocol/src/protocol-save-door-refusals.ts(hostSaveDoorRefusalHost), in the shape cuts 1–5 used (#23050 shape B):refuseUngrammaticalMetaItemName:19858;defaultRecordPageSaveRefusal:20040;externalBindingSaveRefusal:20155,externalBindingDatasourceDefinition:20197,objectsBoundExternallyTo:20213;anonymousElevatedFlowRefusal:20286;authoredLockFamily:20603,saveWriteBinding:20666,objectNamespacePrefixViolation:20710.engineandgetServicesRegistry(getters; the second is the constructor-supplied function field, passed as cut 4 passed it) and the methodsartifactLockLayerAt,externalBindingDatasourceDefinition,getOverlayRepo,objectsBoundExternallyTo,overlayLockLayerAt,readActiveOverlayRows,readMetaItem,rethrowUnlessMetadataStoreUnprovisioned,storedOverlayEntries(late-bound closures). No field is assigned; no moved body namesisSystem; the host carries no elevation member.Stay in the class (inside the run; narrowed out in the trial, before this claim, with the seat's agreement):
refuseUnmintableMetaTypeandmetaTypeNamespaceExists:check-durability-degradation-log-levelfollows the chainsaveMetaItem -> refuseUnmintableMetaType -> metaTypeNamespaceExists -> engine.findOne(its own table rows 3 and 5), and--listcarries ametaTypeNamespaceExistsread seam — the rule that keptpackagelessAddressin cut 5.viewContainerNameCollisionRefusaland its one helperoverlaidShippedContainerViewNames:protocol.lookup-artifact-item-call-sites.test.tsreadsprotocol.tsand records this member'slookupArtifactItem(site.Module-level declarations, each measured by an AST reader walk over all of
protocol.ts(transitive closure over the moved set):LOCK_FAMILY_KEYS,lockFamilyOf,sameLockFamily,withLockFamily,authoredLockFamilyRefusal. (item-lock.tsdeclares its own, separateLOCK_FAMILY_KEYS, untouched.)exportin place:MetadataIssueEntry(←permissionSetOwnerBindingRefusal,protectionBlockRefusal,publishBackfillRefusal,readPublishBackfillRequest),MetadataWriteFace(←specValidationFindings,destructiveChangeRemedy,flowSaveReplaysRetired,saveMetaItem),specValidationFindings(←saveMetaItem).overlaySchemaDeclaredKeyis already exported.src/index.tsnames its exports, so none is published.protocol.ts(lost their last reader):METADATA_ITEM_NAME_PATTERN,defaultRecordPageObject,MetadataProtectionFields,validateObjectNamespacePrefix, and the whole@objectstack/spec/apivalue import, whose 3-line[ADR-0138 D2b]comment moves with it onto the new module's import.Anchor entry (seat note):
scripts/adr-anchors/packages__metadata-protocol__src__protocol.ts.jsonnamesapplyObjectRegistryMutation,loadMetaFromDb,removeObjectOverlay, theOBJECT_OVERLAY_PACKAGE_MISMATCHproducer,batchData/transaction(,saveMetaItem/projectStorableViewBody/VIEW_CONSOLE_ROUND_TRIP_KEYS,hydrateOverlayIntoRegistry,readFlattenedMetaItems,isShippedFlowName/isStoredFlowEntryOfShippedName. None appears in the new module (0 hits); bothOBJECT_OVERLAY_PACKAGE_MISMATCHproducers stay inprotocol.ts. No new entry.Re-measured on merged main
60d8fd2ea6(the seat's order: d.ts, then letters, then governed):.d.ts(ruling6348891160): deps rebuilt at base withturbo run build --filter='@objectstack/metadata-protocol^...', thendist/index.d.tsanddist/index.d.ctsraw25da084d43455d12…at base60d8fd2ea6and at head, both files. Raw identity. ESM and CJS export lists: 78 names, sorted-list hashe47ac7c7…on all four.check:adr-anchorsdecision letters, exact: 1,871 → 1,868 (85 → 85 anchored files). The three that leave:ADR-0138 D2bin the moved import comment,ADR-0138 D2binanonymousElevatedFlowRefusal's body,ADR-0131 D6in a moved body; none governsprotocol.ts's entry (above).check-governed-merges --branchon the final 3-path list: NOT governed, 872 changed lines (+551 / −321).async;check-durability-degradation-log-level --listidentical modulo line numbers (159 lines);check-adr-symbol-anchors,check-platform-checklist, both censuses, the erasure ratchet, spec liveness and the core pins (7/7) identical;check-engine-double-contractdiffers only inproductionFiles+1; suite 21,490 → 21,491 tests, 0 per-test changes, the one added being the newPRODUCERSrow ('protocol-save-door-refusals.ts': 5, 5new Error(sites move);dispatch-gates --commands --changed59 derived, 59 exit 0,--ran59/59, 0 NOT-MEASURED.⛔ Nothing else changes: no moved body or declaration is edited; the only stay-behind edits are the three
exportkeywords, the stub bodies, the narrowed imports and the one import of the new module, plus the onePRODUCERSrow; no ADR ordocs/**text is edited; no new gate. One PR,skip-changeset,Part of #25467.objectstack-fleet commentedon Oct 24, 2026
Landed cut 5 (lock gate and OCC write addresses) ·
domain:servicesseat 1 (seat post #6021) ·os-sales·session_016g7nYP9wdNx1GDa5XDr7Uy· 2026-10-24T11:08Z6380213413, held through the 18.1 release freeze, readied and armed after merges resumed), head11a1c9186borigin/main60d8fd2ea6State: the card stays open and dispatched (
Part of). The card thread claimed cut 6 afresh on the mergedprotocol.ts(claim6383176261); it is PR #25623, under seat review.Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
Landed cut 6 (save-door refusals) ·
domain:servicesseat 1 (seat post #6021) ·os-sales·session_016g7nYP9wdNx1GDa5XDr7Uy· 2026-10-24T11:51Z6383538346), head04c063af57origin/main9d9a06ea38State: the card stays open and dispatched (
Part of). On the mergedprotocol.ts, the card thread either claims the next cut afresh or posts the series' final report. The carry-forward list in #25623 still stands.Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
Claim: card thread ·
domain:server(formerdomain:enginesurface) · fordomain:servicesseat 1 (seat post #6021, project run by the Sales account; 由Sales账户的项目负责) · p2 · series card, cut 7 (one PR; cuts strictly serial; cuts 1–6 landed as #25494bf5855b5bc, #25518b2411c001d, #25538798d480269, #25589ba6912c1ad, #2560160d8fd2ea6, #256239d9a06ea38) · 2026-10-24T12:21ZSession:
session_01J8pUyVs5eas1AjMdReJM7CAccount:
os-sales(the seat's linked user; the card's assignee)Branch:
claude/project-thread-uasfag(the harness-pinned branch for this session, restarted fromorigin/main9d9a06ea38after cut 6 merged; it names no issue, so this claim is the identity record)Worktree:
objectstack-wt(a linked worktree in this session's container)Domain:
domain:serverSeat:
domain:services#1(seat post #6021; scope agreed with the seat before this claim, both of its calls answered below; the PR goes back to that seat for ACCEPT)Ruling: #24586 letter A (
6270097840), restart read in6291735609. The series' .d.ts bar is ruling6348891160(sorted-union identity; raw identity reported when it holds).Container & model:
M,mode:thread,effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (a
[maintainer]refactor card).Thread-read: none
Serial constraints cleared: none of the 14 open PRs touches
packages/metadata-protocol/src/protocol.ts, the new module orprotocol.bracketed-refusal-opener-absence.test.ts(each PR's diff against its merge base read in this act), andgit merge-treeof the cut head with each of them and with mainca80f05ec5is clean.origin/mainhas not touchedpackages/metadata-protocolsince9d9a06ea38. Re-measured again beforepr_create; a new open PR on these files means this cut yields.File surface (read on
origin/main9d9a06ea38, whereprotocol.tsis 30,312 lines):Cut 7 = package install and update. Four
ObjectStackProtocolImplementationmembers, the tail of the class, move unedited into a new module,packages/metadata-protocol/src/protocol-package-install.ts(hostPackageInstallHost), in the shape cuts 1–6 used (#23050 shape B):installPackage:29853andupdatePackage:30106: PUBLIC with ANNOTATED return types, so not on the series' skip list of public members with inferred return types; the class keeps both signatures byte-identical.packagePersistService:30137andpackageInstallUndo:30165: private.engineandgetServicesRegistry(getters) and the methodspackagePersistServiceandpackageInstallUndo(late-bound closures). No field is assigned; the host carries no elevation member.Module-level declarations, each measured by an AST reader walk over all of
protocol.ts:persistPackageManifest,snapshotPackageRow,restorePackageRow.exportin place:packagePersistFailureError(←deletePackage) and the interfacePackagePersistService(← thepackagePersistServicestub's signature, which stays).src/index.tsnames its exports, so neither is published.PackageInstallManifestSchemaimport loses its last reader inprotocol.ts; its 2-line[#24086]comment moves with it onto the new module's import.Seat's two calls (scope OK, 11:52Z):
.d.ts: raw identity does NOT hold; sorted-union identity does. The only raw change is one union reordered insidegetDiscovery's inferred return (environment: "production" | "development" | "sandbox"printed as"sandbox" | "production" | "development"), the offset-dependent printing cut 3 met. The PR reports the raw hashes, the full raw diff and a positive control that moves the normalised hash.ADR-0087 D1(the protocol handshake) andADR-0087 D2(the authoring door runs no forward conversion) leave withinstallPackage's body.protocol.ts's entry paragraph for ADR-0087 anchors addendum 2026-08-01b (saveMetaItem's storable view body), not the install handshake, andprotocol.tskeeps 26 ADR-0087 citations: no new entry (cut 13 rule, disclosed).Re-measured on merged main
9d9a06ea38(the seat's order: d.ts, then letters, then governed):.d.ts(ruling6348891160): deps rebuilt at base withturbo run build --filter='@objectstack/metadata-protocol^...'. Rawdist/index.d.tsanddist/index.d.cts: base25da084d43455d12…, head2d66df37f8e4614d…(770,690 bytes both sides). Normalisedff7d6892b9f1161d…at both ends, both files: sorted-union identity holds. The full raw diff is one line,getDiscovery's inferred return at:2407,environment: "production" | "development" | "sandbox";→environment: "sandbox" | "production" | "development";. Positive control on a copy of the headindex.d.ts(line 1361private engine;madeengine;): rawfee7168c…, normalisedbe016197…, both moved. ESM and CJS export lists: 78 names,e47ac7c7…on all four.check:adr-anchorsdecision letters, exact: 1,868 → 1,866 (85 → 85 anchored files):ADR-0087 D1andADR-0087 D2leave withinstallPackage's body (above).check-governed-merges --branchon the final 3-path list: NOT governed, 766 changed lines (+427 / −339).async;check-durability-degradation-log-level --listidentical modulo line numbers (159 lines);check-adr-symbol-anchors,check-platform-checklist, both censuses, the erasure ratchet, spec liveness and the core pins (7/7) identical;check-engine-double-contractdiffers only inproductionFiles+1; suite 21,493 → 21,494 tests, 0 per-test changes, the one added being the newPRODUCERSrow ('protocol-package-install.ts': 3); out-of-package readers pass (runtime packages domain and integration 190, objectql 61, client 7, rest 2, spec 44, cloud-connection 29);dispatch-gates --commands --changed59 derived, 59 exit 0,--ran59/59, 0 NOT-MEASURED.⛔ Nothing else changes: no moved body or declaration is edited; the only stay-behind edits are the two
exportkeywords, the stub bodies, the moved import and the one import of the new module, plus the onePRODUCERSrow; no ADR ordocs/**text is edited; no new gate. One PR,skip-changeset,Part of #25467.objectstack-fleet commentedon Oct 24, 2026
Seat pointer ·
domain:serverseat 1 (seat post #6367) ·os-sales·session_01JrXUZYyTV4i588KLZRxSvJ· ⛔ not a claimThe maintainer voided
domain:servicesseat 1 (#6021) in the Sales account's project and summoneddomain:serverseat 1 there; #6021 is now an archive of #6367. The reviewing seat for claim6384152373(card threadsession_01J8pUyVs5eas1AjMdReJM7C) is therefore seat post #6367, same account. The claim, its session, branch and file surface are unchanged. ACCEPT and landing for cut 7 PR #25642 (ACCEPT already on the PR) and the cut 8 scope approved under it come from #6367.Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
Landed (cut 7, claim
6384152373) ·domain:serverseat 1 (seat post #6367) · sessionsession_01JrXUZYyTV4i588KLZRxSvJ· 2026-10-24T15:01Zmerged: true, merge commit5aafc8237f, merged 2026-10-24T15:01:15Z through the merge queueorigin/main5aafc8237fis an ancestor oforigin/main, single parent (squash)gh-readonly-queue/main/*head for PR 25642 remainsState: card stays open (
Part of #25467). Cut 8, the scope agreed under the same claim, is next from the card thread on a branch from today'smain.pm:dispatchedstays.Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
Release: session
session_01J8pUyVs5eas1AjMdReJM7Creleases #25467 (last live claim6384152373, cut 7) · because: the owning account (Sales,os-sales) is out of token budget and ordered a handoff · to:pm:queue, no assignee; the next claimant resumes from the branch belowProvenance: who: Sales (
os-sales, card owner) · said: 「那还是让他们尽快结束,然后移交。」 ("wrap it up as soon as possible, then hand it over") · where: the Sales project chat, relayed to this session by the project coordinatorResume-from:
claude/project-thread-uasfag@65b6d71d38Handoff — protocol.ts split under ruling A (6270097840)
Merged (cuts 1–7), all move-only, one PR per cut, each ACCEPTed by the server seat:
protocol-lock-version-gates.tsprotocol-save-door-refusals.tsprotocol-package-install.ts(merge5aafc8237f)Cut 8: built and pushed, NOT claimed, NO PR.
claude/project-thread-uasfag@65b6d71d38, one commit on maindc6c7ee738. protocol.ts is unchanged between5aafc8237fanddc6c7ee738.restoredBodyDerivation,restoredBodyWriter,refuseRestoredBodyTheSaveDoorRefuses,runAuthoringGate,assertRuntimeAuthoringRules→ newprotocol-authoring-gate.ts(shape B host: gettersengine,authoringChannel,authoringGates).permissionSetOwnerBindingRefusalandruntimeHookWithoutBodyRefusalare exported in place. Imports in protocol.ts are narrowed.new Error().[#8862]pin inprotocol.object-registry-write-through-spelling.test.ts. It now reads protocol.ts plus the new module as one text and keeps the exact "one executable'objects'literal" assertion.got +0;'objects'literal fails withgot 2;this.applyRegistryWriteThrough(sites in protocol.ts stay at 7.--list, hand gates, engine-double and core pins are the same;The seat's condition stands: re-measure .d.ts raw and normalised on merged main before claiming.
Stays in the class, and why:
this.wrappers the checker follows:packagelessAddress,refuseUnmintableMetaType+metaTypeNamespaceExists. They can only move once the durability checker learns shape B.probeRecord: per-file erasure baseline site.getMetaItemCachedandfindReferencesToMeta: the Three read-side/metaverbs (history, audit, references) never reachcanonicalizeMetaRequestType— they still derive their key from the MANIFEST map #9157 fold pin reads their bodies in protocol.ts.viewContainerNameCollisionRefusal+overlaidShippedContainerViewNames: the lookup-artifact-item-call-sites pin.reportPageRequiresAbsentAtLoad: spec livenesspage.json(spec lane).applyRegistryWriteThroughcallers: the spelling pin counts them in protocol.ts.How to pick this up:
Resume-fromabove. Re-check open PRs touching protocol.ts; none did at release."a" | "b"string-literal unions; ruling 6348891160), then letters, then governed. Then ESM/CJS export tables, the durability--listdiff (strip[@:][0-9]+), hand gates, engine-double, and the package suite at both ends.Keep each under 3,000 changed lines. Per cut: anchor entry
scripts/adr-anchors/packages__metadata-protocol__src__protocol.ts.json(new entry only when a moved body is the mechanism an entry paragraph describes), PRODUCERS rows, and the cross-package pins that read protocol.ts by path.