Skip to content

[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

Open

Description

@objectstack-fleet

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:00Z attributes 13,445 lines (40.7%) to the last 30 days.
  • Structure:

    • a 6,643-line module preamble: helpers, three error classes, and the query-param and filter vocabulary;
    • one ObjectStackProtocolImplementation class, 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.
  • 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 seams applyObjectRegistryMutation and loadMetaFromDb. The metadata-plugin.zod.ts anchor file and scripts/symbol-anchors.mjs also 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/ and content/, 11 of them ADRs.
    • Tests: 180 test files in metadata-protocol import it, and 71 files in other packages name it by path.
  • In flight: none of the 21 open PRs touch the file.

The ask (from #24586's ruling and #23050's shape)

  1. Split along the existing seams, one area per PR. Each slice is move-only: no logic changes.
  2. 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 its register*Endpoints seams, one move-only slice per PR, /meta after #22877 stage 2 #23050, [maintainer] refactor(service-automation): split src/engine.ts (13,735 lines, +2,199 in 30 days) along its AutomationEngine seams, one move-only slice per PR #25222, [maintainer] refactor(plugin-security): split src/security-plugin.ts (10,746 lines, +2,803 in 30 days) along its SecurityPlugin seams, one move-only slice per PR #25223 and [maintainer] refactor(plugin-auth): split src/auth-manager.ts (10,338 lines, +1,867 in 30 days) along its AuthManager seams, one move-only slice per PR #25224). ⛔ Not a second copy of a helper, ⛔ not a re-derivation.
  3. 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.ts stays identical.
    • ⛔ A gate whose target moved must not go silently empty.
  4. Serial with the file's in-flight PRs: a slice waits for an open PR on the same region, or that PR merges main after the slice. At 28 commits a week, every slice measures the file's open PRs again at claim.
  5. ⛔ No new gate.

Not in this card

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

  1. added
    enhancementNew feature or request
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Oct 23, 2026
  2. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: card thread · domain:server (former domain:engine surface) · for domain:services seat 1 (seat post #6021, project run by the Sales account; 由Sales账户的项目负责) · p2 · series card, cut 1 (one PR; cuts strictly serial) · 2026-10-23T15:20Z
    Session: session_01J8pUyVs5eas1AjMdReJM7C
    Account: os-sales (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-uasfag (the harness-pinned branch for this session, cut from origin/main ab510f4c43; 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:server
    Seat: domain:services#1 (seat post #6021; the PR goes back to that seat for ACCEPT)
    Ruling: #24586 letter A (6270097840), restart read in 6291735609. The series' .d.ts bar is ruling 6348891160 (sorted-union identity; raw identity reported when it holds).
    Container & model: M, mode:thread, effort: high
    Clause-②: 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 against origin/main; #25451 touches only protocol.runtime-authoring-gate.test.ts, the Version Packages PR #24876 only CHANGELOG.md / package.json). No pm:dispatched card's claimed file surface names the file. Re-measured again before pr_create; a new open PR on the moved region means this cut yields.

    File surface (read on origin/main ab510f4c43, where protocol.ts is 33,065 lines):

    Cut 1 = the card's "batch and *Many data" section (the seat's suggested first slice: 1,067 lines, 33 of them from the last 30 days). Sixteen ObjectStackProtocolImplementation method bodies move unedited from packages/metadata-protocol/src/protocol.ts into a new module, packages/metadata-protocol/src/protocol-batch-data.ts, in the host shape of #23050 / #25222 / #25223 / #25224:

    • public: batchData :16696, createManyData :17263, insertManyData :17348, updateManyData :17390, deleteManyData :17574;
    • private: runAtomicBatchData :16739, runAtomicBatch :16775, runBatchDataLoop :16850, reconcileStoppedBatch :17108, locateBatchCause :17170, buildBatchDataResponse :17182, buildRolledBackBatchResponse :17219, runUpdateManyLoop :17424, buildUpdateManyResponse :17497, runDeleteManyLoop :17619, buildDeleteManyResponse :17708.
    • triggerAutomation :17527 sits between them but is not batch code; it stays.

    How the host is built:

    • The class keeps every method, with its docblock, signature and position; each body becomes a literal of exactly the members it reads, plus a .call. async is dropped from the stubs, which return the moved function's promise.
    • Members read, measured by AST: engine (field), and the methods assertObjectRegistered, assertRecordExists, probeRecord plus 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. engine goes as a getter.
    • The only outside caller of a moved method is 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 except mergeDroppedFieldEvents, which stays too, so no declaration moves):

    • export added in place, imported back by value or type from ./protocol.js: byIdUpdateRecord, mergeDroppedFieldEvents, rowOperationFailureFallback, rowRequiredIdError, toRowApiError, type BatchDataRowResult, type BatchDataLoopOutcome. src/index.ts exports from ./protocol.js by name, so none of them is published; the proof measures it (raw .d.ts and 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.
    • Imports the new module takes from packages directly (as protocol.ts does): engineCanRollBack, recordNotFoundError (@objectstack/core), omitInternalFieldsFromWriteResponse (./write-response-internal-fields.js), and the @objectstack/spec types the bodies name.

    Path readers migrated in the same PR (each measured base vs head in the PR):

    • scripts/adr-anchors/: the protocol.ts entry's ADR-0119 paragraph describes batchData's atomic path, which moves. Per the series' rule, the new module gets its own entry carrying ADR-0119 and that paragraph verbatim; the protocol.ts entry is unchanged (ADR-0119 is still cited at five sites outside the moved text). check:adr-anchors decision-letter totals reported base and head.
    • protocol.bracketed-refusal-opener-absence.test.ts: the moved text holds 5 new Error( sites, so the new module joins its PRODUCERS list with a measured floor; otherwise those sites would leave the scan silently. protocol.ts keeps its floor of 5.
    • docs/adr/0119-…md anchors protocol.ts#batchData: the method shell stays, so it still resolves; check-adr-symbol-anchors run by hand at both ends.
    • Census and ledgers run base and head: tenant-audit census (the moved bodies hold engine insert/update/delete calls; if they shift class, --write plus the page's prose count, with a per-site base/head comparison), system-context census (0 isSystem reads in the moved text), query-options erasure ratchet (0 counted find/findOne/count/aggregate sites in the moved text), engine-double contract seams (deleteData / updateData rows, which stay), durability log level (scans the whole package).

    ⛔ Nothing else changes: no moved body is edited; the only stay-behind edits are the export keywords above and the stub bodies; no ADR or docs/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.ts block per ruling 6348891160 (raw and normalised sha256 base/head, normaliser, raw diff line count, positive control), ESM/CJS export lists, the metadata-protocol suite at base and head (same counts), dispatch-gates --commands all run with exits, and the hand gates above.

  3. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed cut 1 (batch and *Many data) · domain:services seat 1 (seat post #6021) · os-sales · session_016g7nYP9wdNx1GDa5XDr7Uy · 2026-10-23T17:23Z

    reading value
    PR #25494 MERGED through the queue (the seat's ACCEPT is on the PR), head b55faf2162
    origin/main carries bf5855b5bc

    State: the card stays open and dispatched (Part of). The card thread plans cut 2 on the merged protocol.ts and re-checks the in-flight PRs on the file first (serial rule). It claims cut 2 afresh before it pushes.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: card thread · domain:server (former domain:engine surface) · for domain:services seat 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:30Z
    Session: session_01J8pUyVs5eas1AjMdReJM7C
    Account: os-sales (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-uasfag (the harness-pinned branch for this session, restarted from origin/main 5188e7f18f after 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:server
    Seat: 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 in 6291735609. The series' .d.ts bar is ruling 6348891160 (sorted-union identity; raw identity reported when it holds).
    Container & model: M, mode:thread, effort: high
    Clause-②: 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: only CHANGELOG.md / package.json in this package). Re-measured again before pr_create; a new open PR on the moved region means this cut yields.

    File surface (read on origin/main 5188e7f18f, where protocol.ts is 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 ObjectStackProtocolImplementation method bodies move unedited into a new module, packages/metadata-protocol/src/protocol-discovery.ts (host DiscoveryHost), in the shape cut 1 used (#23050 shape B):

    • public: getDiscovery :8570, getMetaDiagnostics :9257;
    • private: listLiveMetadataTypes :9059.
    • Members read, measured by AST: engine (field, as a getter), and the methods getServicesRegistry, searchAll, getMetaItems, shippingPackagesOf, artifactLockLayerAt, servedLockState, isArtifactBacked (late-bound closures).

    Stays, deliberately:

    Module-level declarations:

    • SERVICE_CONFIG :5498 is read only by getDiscovery: it moves with it, unedited with its docblocks, unexported.
    • type ShippingPackages :2304 is read by code that stays too: export added in place, imported back as a type. src/index.ts exports from ./protocol.js by name, so it is not published; the proof measures it.
    • The module imports from the same specifiers protocol.ts uses (@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.ts entry: none of its paragraphs (ADR-0029 D9.8/D9.9 hydration seams, ADR-0119 batchData, 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 exact check:adr-anchors count is reported base → head.
    • docs/qa/platform-checklist/areas/studio-authoring.json anchors protocol.ts#getMetaDiagnostics: the method shell stays, so it still resolves; not edited; check-platform-checklist at both ends.
    • None in the moved text: isSystem reads (system-context census), engine find/findOne/count/aggregate (erasure ratchet), engine update/delete seams (engine-double contract), new Error( (bracketed-refusal PRODUCERS), 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 export keyword and the stub bodies; no ADR or docs/** 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.ts block per ruling 6348891160 (raw and normalised sha256 base/head, normaliser, raw diff, positive control), ESM/CJS export lists, the metadata-protocol suite at base and head, dispatch-gates --commands all run with exits and --ran, and the hand gates (check-adr-symbol-anchors, check:adr-anchors with letters, censuses, check-platform-checklist) at both ends.

  5. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment: cut 2 of #25467 (amends claim 6370841668) · domain:services seat 1 (seat post #6021; 由Sales账户的项目负责) · 2026-10-23T17:45Z
    Session: session_01J8pUyVs5eas1AjMdReJM7C
    Branch: claude/project-thread-uasfag (unchanged, base origin/main 5188e7f18f)
    Seat: domain:services#1 (the narrowed scope below agreed with the seat before this amendment)
    Thread-read: 6370841668

    Narrowed scope. Cut 2 is getMetaDiagnostics alone (:9257). Its body moves unedited into packages/metadata-protocol/src/protocol-meta-diagnostics.ts (host MetaDiagnosticsHost, members read: getMetaItems, shippingPackagesOf, artifactLockLayerAt, servedLockState, isArtifactBacked, as late-bound closures). type ShippingPackages gains export in place, as claimed. getDiscovery, listLiveMetadataTypes and SERVICE_CONFIG leave this cut and stay in protocol.ts; nothing else in the claim changes.

    Why getDiscovery cannot move (measured, nothing pushed). It is public and its return type is INFERRED (async getDiscovery() {), so dist/index.d.ts prints 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.ts changed 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 unrelated protocol.ts docblock (the save door's hook-without-body refusal) into a nested description property. Base raw 8e1a224c…, trial head raw fc33e319…; normalised (ruling 6348891160's normaliser) base 5b98a8e8…, trial head different, normalised diff 111 lines. Under ruling 6348891160 that 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, and SERVICE_CONFIG is read only by getDiscovery, so both stay with it.

    Carry-forward for later cuts. A public member with an inferred return type stays in protocol.ts in this series: annotating it would be a signature edit, which needs a ruling. Measured on 5188e7f18f, 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-anchors 1,979 → 1,978, reported in the PR.

  6. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed cut 2 · domain:services seat 1 (seat post #6021) · os-sales · session_016g7nYP9wdNx1GDa5XDr7Uy · 2026-10-23T19:27Z

    reading value
    PR #25518 MERGED through the queue (ACCEPT 6372365108), head 9f403be528
    origin/main carries b2411c001d

    State: the card stays open and dispatched (Part of). The card thread claims the next cut afresh on the merged protocol.ts. Public members whose return type is inferred stay in the class.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: card thread · domain:server (former domain:engine surface) · for domain:services seat 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 #25494 bf5855b5bc, cut 2 as #25518 b2411c001d) · 2026-10-23T19:38Z
    Session: session_01J8pUyVs5eas1AjMdReJM7C
    Account: os-sales (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-uasfag (the harness-pinned branch for this session, restarted from origin/main b2411c001d after 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:server
    Seat: 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 in 6291735609. The series' .d.ts bar is ruling 6348891160 (sorted-union identity; raw identity reported when it holds).
    Container & model: M, mode:thread, effort: high
    Clause-②: 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 only CHANGELOG.md / package.json in this package). origin/main (f38832be9c) has not touched this package since b2411c001d. Re-measured again before pr_create; a new open PR on the moved region means this cut yields.

    File surface (read on origin/main b2411c001d, where protocol.ts is 32,309 lines):

    Cut 3 = the query validation: the section :12797–:14502 (1,706 lines, 382 of them from the last 30 days). Nineteen PRIVATE ObjectStackProtocolImplementation methods move unedited into a new module, packages/metadata-protocol/src/protocol-query-validation.ts (host QueryValidationHost), 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.
    • All private, so the published .d.ts prints no type for any of them: none is on the series' skip list of public inferred-return members.
    • Members read, measured by AST: engine (field, as a getter), and the methods assertFilterFieldsExist, 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):

    • Move with the bodies, byte-identical, unexported (no reader outside the moved bodies and the other moved declarations): nestedRelationRoute :392, warnedNoRegistryForDataGate :536 (the mutable let: its only reads and its only write are in assertObjectRegistered, 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.
    • Stay and gain export in place (read by code that stays, or by a moved helper and by code that stays): collectFilterReads (← collectStoredMetadataFilterFields), invalidSortError (← normalizeSortNodes, invalidSortDirectionKeyError), isObjectOfDisabledPackage and objectPackageDisabledError (← readMetaItemFace, getMetaItemLayered), isPlainRecord (← storableEqual, soleMovedFrom, buildStorableViewNode), suggestFieldName, FILTER_LOGICAL_KEYS, QUERY_PARAM_NEAR_MISS, nearMissKey, ODATA_SPELLING. src/index.ts exports from ./protocol.js by name, so none is published; the proof measures it.
    • protocol.ts drops 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.ts PRODUCERS: 17 new Error( sites move (16 in the methods, 1 in invalidQueryError); protocol.ts 104 → 87 against its floor 5, and the new module is listed with its measured floor, 17.
    • scripts/adr-anchors/ protocol.ts entry: none of its paragraphs (ADR-0029 D9.8/D9.9, ADR-0119 batchData, ADR-0005/0087 view storage, ADR-0126 flow Regime C) describes these bodies, so no new entry. check:adr-anchors decision letters are reported exactly base → head.
    • docs/qa/platform-checklist/areas/api-backend.json and search.json anchor protocol.ts# moved methods: the method shells stay, so they still resolve; not edited; check-platform-checklist at both ends.
    • Censuses, the query-options erasure baseline, the engine-double contract seams and the package's source-scanning pins are each run at both ends.
    • Size: under the 3,000-changed-line bar (measured: +1,591 / −1,283 over 3 files).

    ⛔ Nothing else changes: no moved body or declaration is edited; the only stay-behind edits are the ten export keywords, the narrowed import lists and the stub bodies; no ADR or docs/** 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.ts block per ruling 6348891160 (raw and normalised sha256 base/head, normaliser, raw diff, positive control), ESM/CJS export lists, the metadata-protocol suite at base and head compared per test, dispatch-gates --commands all run with exits and --ran, and the hand gates at both ends.

  8. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed cut 3 · domain:services seat 1 (seat post #6021) · os-sales · session_016g7nYP9wdNx1GDa5XDr7Uy · 2026-10-23T22:03Z

    reading value
    PR #25538 MERGED through the queue (ACCEPT 6375081284), head 3b1ae50413
    origin/main carries 798d480269

    State: the card stays open and dispatched (Part of). The card thread claims cut 4 afresh on the merged protocol.ts. #25533 also edits protocol.ts (publishDrafts). Its merge-tree is clean, but its byte offsets have shifted, so its .d.ts is re-read before it lands.


    Generated by Claude Code

  9. 56 remaining items

  10. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 25467,
    "status": "done",
    "branch": "claude/project-thread-ybjm3h",
    "pr": "#26366",
    "session": "session_016SP1spj613tyGCgxoD1An6 — the card thread (claim 6429678924)",
    "premise_still_valid": true,
    "summary": "Cut 20, move-only: the body of readItemFromMetadataService moves into the new protocol-metadata-service-read.ts. Shape B: MetadataServiceReadHost = the getServicesRegistry FIELD (an optional constructor-supplied callback, not a method) handed over as a getter, as protocol-package-install.ts / protocol-record-reads.ts / protocol-save-door-refusals.ts already do; an absent callback stays undefined, so the body's ?.() short-circuits as before. AST screen with casts stripped: no private-static read, no this.constructor read, 0 new Error(, no try/catch/log. Module-level reads (AST identifier walk): canonicalMetaType (already exported; runtime import from ./protocol.js), isTenantAuthored (@objectstack/metadata-core), PLURAL_TO_SINGULAR / SINGULAR_TO_PLURAL (@objectstack/spec/shared), all with other readers in protocol.ts, so no export and no import change there. All 4 this. callers (:9262, :11091, :11422, :18960) keep calling the class method. 40 body lines (proposal 40); 138 changed lines, +101/-37 over 2 files (estimate 180-230). protocol.ts 29,240 -> 29,210. Commits: 1cb285a (move) on main e2129cb; merge of main c19ad22 as 54aaeba (no package file; src tree 953bab7a both ends).",
    "tests": "metadata-protocol suite (vitest --maxWorkers=2, json reporter, under os-verify-lock, VERDICT command-exit 0 both legs), pre-merge tree: base e2129cb and head 1cb285a both 21,568 tests (21,549 passed, 0 failed, 19 skipped), 270 files; per-test 0 lost, 0 added, 0 changed. Base leg = src swapped tree-only (new module removed), restored from HEAD under a trap; diff empty, status clean, 2 blobs equal HEAD. objectql protocol-delete-boot-hydrated-object-heal.test.ts (drives the member through the delete door) at head after the full build: 5/5. AST compare: 383 tokens, 0 differ, ws-collapsed text incl. comments equal; negative control ('?? SINGULAR_TO_PLURAL' -> '||', in-memory, one occurrence) differ=1. Class: 301 members, 300 byte-identical, 1 stub keeps docblock+signature. Top level 248/248 byte-identical; head adds the module import. tsc --noEmit 0 before and after the merge; eslint --no-inline-config packages/metadata-protocol 0. No ablation: move-only.",
    "gates": ".d.ts (ruling 6348891160), one dependency tree, pre-merge (e2129cb vs 1cb285a) and post-merge (54aaeba, full pnpm build 119/119): NORMALISED sha256 f7f9306ed46a5605c5e4c59bbc212a7d5288061760ec85d473d2f3047a836ba5 at both ends both times -> SORTED-UNION IDENTITY HOLDS (the ruling's bar). RAW IDENTITY DOES NOT HOLD this time: base a8f6adb6f9c56b8f…, head 1b134685a474f83c…, both 776,660 bytes; the whole raw diff is one line, dist/index.d.ts:2448 inside getDiscovery()'s inferred return type: status: "registered" | "available" | "degraded" | ... -> "registered" | "degraded" | "available" | ... (same five members, reordered — tsc prints an inferred union in literal-type creation order, which moving a body can change). No signature, member or name moves. Positive control (private dropped) moves both .d.ts to c9acdc769a2b94ed (normalised c1ebd3ff0d127a7e) and prints the signature; index.js 9495894cdf5ce39b -> 7be270d93afd5f1e, .call(host 0 -> 1 ESM and CJS, function readItemFromMetadataService( 0 -> 1. Export tables ESM+CJS: 78 names, sha 9f18a0177ac736ed both ends both times. Hand gates exit 0 both ends (base in a clean detached worktree at e2129cb): adr-symbol-anchors, system-context-census, tenant-audit-census, query-options-erasure-ratchet, filter-alias-parity, durability-degradation-log-level identical; DURABILITY --list identical after stripping [@:][0-9]+ (158 lines; the body has no catch and no engine call); adr-anchors citations 59,279 -> 59,280 across files 8,356 -> 8,357 (the body's ADR-0048 comment moves, and the new header names ADR-0048 once), decision letters 1,879 unchanged; nul-bytes +1 file; engine-double-contract seams 13926->13896, 13951->13921, productionFiles 3,748 -> 3,750 (+1 new file, +1 gitignored spec migrations/registry.ts). check-platform-checklist OK (29 anchors, 0 lost). Governed: 0 of 2 paths, 138 lines. Derived on 54aaeba (no stale-tree warning): 51 gates, all exit 0; --ran 51/51, 0 NOT-MEASURED, 0 UNRUN. Open-PR overlap at pr_create (19 open): #26244 (the only one on protocol.ts, :163 and :23178) and #26138 conflict with this head only where they conflict with origin/main alone; #26337 (3 protocol.*.test.ts files) is clean; none names the member. CI at report time: just started.",
    "dogfood_battery": "n/a — no ! in the PR title and the claim's Clause-② is no with no (narrowing) arm",
    "mcp_calls": "1 GitHub MCP read (list_pull_requests for the overlap check); 0 GitHub MCP writes; no subscribe_pr_activity",
    "api_writes": "4 — git push of claude/project-thread-ybjm3h twice (1cb285a as a force push over the merged cut 19 history, merge 54aaeba); relay pr_create (run 40424840964 -> #26366, draft, assignee os-project-manager, label skip-changeset; read back 16,202 body bytes identical); this os-dev-report via post-stamped.mjs",
    "line_budget": "138 changed lines (+101/-37), under the 3,000-line bar",
    "files_changed": [
    "packages/metadata-protocol/src/protocol.ts",
    "packages/metadata-protocol/src/protocol-metadata-service-read.ts"
    ],
    "deviations": [
    "Raw .d.ts identity, which held on cuts 14-19, does not hold on this cut (one inferred union reordered in getDiscovery); the ruling-6348891160 bar (sorted-union identity) holds and is the bar."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "Liveness ledger follow-up, carried forward from cut 19 (packages/spec/**, outside this card): two rows hold protocol.ts#member evidence pointers whose quoted line now lives in a seam module — manifest.json dependencies -> protocol.ts#resolveWritePackageScope (cut 19, quote now in protocol-write-package-scope.ts) and seed.json -> protocol.ts#applySeedBodies (cut 14, protocol-publish-batch.ts). check:liveness checks only that the #symbol is named in the file; both stubs keep it, so it passes. No row points at readItemFromMetadataService. A spec-lane re-point would make both exact.",
    "cut 21 proposal (measured at 1cb285a's protocol.ts, AST screen with casts stripped): the overlay-row pair findServedOverlayRow (protocol.ts line 10372, private async, 31 body lines; reads findEnvironmentRow, a closure) and reportSealedOverlayRows (28657, private, 26 body lines; reads no member, so a plain function its stub calls directly, as cut 3/16; one console.warn, one caller). Neither has a private-static read or a new Error(. findServedOverlayRow's module-level reads: servedOverlayRowCandidates and rowMatchesOverlayWhere (non-exported protocol.ts functions with other readers -> gain export in place), StoredOverlayRow (./item-lock.js), overlayMemberWhere (./migrations/overlay-index.js), PLURAL_TO_SINGULAR / SINGULAR_TO_PLURAL — all keep other readers, so no import leaves protocol.ts. 5 this. callers of findServedOverlayRow stay; protocol.item-active-rows-one-read.test.ts calls p.findServedOverlayRow(...) and protocol.platform-store-system-opt-in.test.ts drives it, both through the class (no by-path reader). reportSealedOverlayRows is named by no test; re-measure the durability --list and the log-level gates for its warn. Estimated 250-320 changed lines; if the seat prefers a single member, findServedOverlayRow alone. Class left after cut 20: 301 members, 111 delegating stubs, 31 bodyless or fields, 159 with live bodies (12,796 body lines: 102 private with 3,627, 57 public with 9,169)."
    ]
    }

  11. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed

    PR #26366 merged at 2026-10-27T01:03Z by the merge queue as d677879cd6 on main (Part of #25467; ACCEPT 6430706595).

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26366-*' 0 refs
    origin/main by content git cat-file -e origin/main:packages/metadata-protocol/src/protocol-metadata-service-read.ts present
    Ancestry git merge-base --is-ancestor d677879cd6 origin/main holds

    State: card stays open (Part of), pm:dispatched stays.


    Generated by Claude Code

  12. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 8 · card thread · series card, cut 21 (cuts strictly serial; cuts 1–20 landed, the last PR #26366 d677879cd6)
    Session: session_01R1q2xdtYgU6FKrZ7LgjPCC (the seat); the card thread is session_016SP1spj613tyGCgxoD1An6 (cuts 12–20's thread, reused)
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-ybjm3h (the card thread's harness-pinned branch, restarted from origin/main after cut 20 merged; it names no issue, so this claim is the identity record)
    Worktree: objectstack-issue-25467 (a linked worktree in the card thread's container)
    Domain: domain:server
    Seat: domain:server#1
    Ruling: #24586 letter A (6270097840); the series' .d.ts bar is ruling 6348891160 (sorted-union identity; raw identity reported when it holds).
    File surface: packages/metadata-protocol/src/protocol.ts and one new seam module for the cut 20 report 6430425388's cut 21 proposal, the overlay-row pair: findServedOverlayRow (protocol.ts:10372, private async, 31 body lines; servedOverlayRowCandidates and rowMatchesOverlayWhere gain export in place, nothing else leaves protocol.ts's imports) and reportSealedOverlayRows (:28657, private, 26 body lines, reads no member, so a plain function its stub calls directly, as cuts 3 and 16). All five this.findServedOverlayRow callers and the one reportSealedOverlayRows caller keep calling the class members. Estimated 250–320 changed lines, no pin edit. Also: other test files that read the moved bodies in protocol.ts by path; the durability --list and the log-level gates re-measured for the moved console.warn; scripts/adr-anchors/** only if a moved member is the mechanism an entry paragraph describes. skip-changeset, Part of #25467. ⛔ No docs/adr/**, ⛔ no packages/spec/** (stop on breach; explain in the report). If the AST screen (private-static reads, new Error( sites) does not hold for either member, move the one that passes alone and report.
    Container & model: S, mode:thread, model and effort as the thread was opened
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card (a [maintainer] refactor card)
    Thread-read: 6430425388
    Premise: holds (read 2026-10-27T01:04Z at origin/main 61c079862a: findServedOverlayRow is a private instance method at protocol.ts:10372, called at :10853, :10865, :10911, :10925, :11498; reportSealedOverlayRows is private at :28657, called once at :28549)
    Serial constraints cleared: cut 20 (#26366) merged before this claim. The dev re-measures open PRs on packages/metadata-protocol/src/protocol.ts (the cut 20 report found #26244 the only one, at :163 and :23178) and runs git merge-tree against any overlap before pr_create.
    Carried: the liveness ledger's manifest.json and seed.json evidence pointers to seam-moved members (report 6430425388) stay a spec-lane follow-up for the series close-out.

  13. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 25467,
    "status": "done",
    "branch": "claude/project-thread-ybjm3h",
    "pr": "#26404",
    "session": "session_016SP1spj613tyGCgxoD1An6 — the card thread (claim 6431131976)",
    "premise_still_valid": true,
    "summary": "Cut 21, move-only, ONE member of the proposed pair: the body of reportSealedOverlayRows moves into the new protocol-sealed-overlay-report.ts (56 lines). It reads no class member and no protocol.ts module-level declaration, so there is no host: the stub is return reportSealedOverlayRows(rows);, as namesWithOwnStoredRow's (cut 16). Its one caller (:28549 at base) keeps calling the class method. findServedOverlayRow STAYS: both members passed the AST screen (no private-static read, no this.constructor read, 0 new Error(), and the pair was built and measured in full (AST 434 tokens 0 differ, negative control 1; raw .d.ts identical; suite 21,568 both ends; all hand gates exit 0), but check-durability-degradation-log-level's read-seam census went 82 -> 79 with the gate still green: its --list lost the three guards findServedOverlayRow() in readMetaItem() x2 / in getMetaItemLayered() entries, because the gate follows only SAME-FILE wrappers (MAX_READ_WRAPPER_DEPTH = 2) and the stub's .call ends the hop. Applying the order's fallback (move the member that passes alone), the cut moves reportSealedOverlayRows only; the census stays 82 with an identical --list. Commits: be992bf (move) on main 61c0798; merges of main e931621 (ce32d8d) and abb9046 (f488ca9, brings #26244, which edits this package; auto-merged in protocol.ts). 84 changed lines (+60/-24). protocol.ts 29,210 -> 29,190 pre-merge, 29,213 -> 29,193 vs main.",
    "tests": "metadata-protocol suite (vitest --maxWorkers=2, json reporter, under os-verify-lock): base 61c0798 and head be992bf both 21,568 tests (21,549 passed, 0 failed, 19 skipped), 270 files; 0 lost/added/changed. After the merge (#26244 changed the package): main abb9046 (src swapped tree-only, restored from HEAD under a trap) and merged head f488ca9 both 21,584 (21,565 passed, 0 failed, 19 skipped), 271 files; 0 lost/added/changed. AST compare vs base: 208 tokens, 0 differ, ws-collapsed text incl. comments equal; same 0 differ vs main abb9046 and the merged head; negative control (SAMPLE_PER_TYPE = 5 -> 6, in-memory) differ 1. Class 301 members, 300 byte-identical, stub keeps docblock+signature; top level 249/249 byte-identical, head adds the import. tsc --noEmit 0 at head and merged; eslint --no-inline-config packages/metadata-protocol 0 on the merged tree.",
    "gates": ".d.ts (ruling 6348891160), one dependency tree: base 61c0798 vs head be992bf -> NORMALISED f7f9306ed46a5605c5e4c59bbc212a7d5288061760ec85d473d2f3047a836ba5 and RAW 1b134685a474f83cfa85a743e49a811d607fcaeed53ae8856dd62db65ad132f5 (776,660 bytes) at both ends: sorted-union AND raw identity hold (cut 20's getDiscovery reorder did not recur). Merged tree f488ca9 vs main abb9046 (full pnpm build 119/119): raw 059fa1189ac13c65… (777,645 bytes), normalised 0a7694d518b57098… at both: both hold. Positive control (private dropped from reportSealedOverlayRows) -> f631a07ad5d36220 (normalised c2f3625e27675e2a) and prints the signature. function reportSealedOverlayRows( 0 -> 1 in the bundle; export tables ESM+CJS 78 names sha 9f18a0177ac736ed everywhere. Hand gates exit 0 both ends (base in a clean detached worktree at 61c0798): adr-symbol-anchors, system-context-census, tenant-audit-census, query-options-erasure-ratchet, filter-alias-parity, durability-degradation-log-level identical; durability --list identical after stripping [@:][0-9]+ (158 lines, 82 read seams, 82 on the merged tree too); adr-anchors decision letters 1,877 -> 1,876 (the warning text's (ADR-0131 D6) leaves the anchored protocol.ts; disclosed, no anchor entry owed, as cuts 8/12), citations 59,313 -> 59,314, files 8,371 -> 8,372; nul-bytes +1 file; engine-double-contract seams 13896->13898, 13921->13923, productionFiles 3,751 -> 3,753 (new file + gitignored spec registry.ts, as cut 20). check-platform-checklist OK (29 anchors, 0 lost). Governed: 0 of 2 paths, 84 lines. Derived on f488ca9: 51 gates, all exit 0; --ran 51/51, 0 NOT-MEASURED, 0 UNRUN. (The first merge ce32d8d derived STALE on scripts/engine-double-contract.pinned.json, so main was merged again and everything re-run; at pr_create main was 6 ahead with 10 stale workflow/scripts/ci files that none of the 51 commands names, so no third merge.) Open-PR overlap at pr_create (29 open): none edits protocol.ts; #26337 and #26138 (metadata-protocol test files) conflict with this head only where they conflict with main alone.",
    "dogfood_battery": "n/a — no ! in the PR title and the claim's Clause-② is no with no (narrowing) arm",
    "mcp_calls": "2 GitHub MCP reads (list_pull_requests for the overlap checks); 0 GitHub MCP writes; no subscribe_pr_activity",
    "api_writes": "3 — git push of claude/project-thread-ybjm3h (new branch: the merged cut 20 branch had been deleted); relay pr_create (run 40437807391 -> #26404, draft, assignee os-project-manager, label skip-changeset; read back 17,657 body bytes identical); this os-dev-report via post-stamped.mjs",
    "line_budget": "84 changed lines (+60/-24), under the 3,000-line bar",
    "files_changed": [
    "packages/metadata-protocol/src/protocol.ts",
    "packages/metadata-protocol/src/protocol-sealed-overlay-report.ts"
    ],
    "deviations": [
    "Scope narrowed from the claimed pair to reportSealedOverlayRows alone, under the order's fallback. findServedOverlayRow passed the AST screen but moving it drops 3 read seams from check-durability-degradation-log-level's census (82 -> 79) while the gate stays green; that is a silent coverage loss, not move-only, so it stays in protocol.ts."
    ],
    "open_questions": [
    "findServedOverlayRow (and every member a read-seam entry names) can move only if the durability gate learns to follow an imported wrapper (the stub's fn.call(host, ...) into a seam module), or a ruling accepts the census loss. That is a gate decision for the seat, not this card."
    ],
    "out_of_scope_findings": [
    "Read-seam census trial (new; method: each body moved alone to a scratch module with a .call(this, ...) stub in a clean base worktree, then check-durability-degradation-log-level --list re-run and compared). It reproduced this cut's two real readings (findServedOverlayRow 82 -> 79; reportSealedOverlayRows 82, identical list). Over the 25 private live-bodied members of 15-90 lines: census-NEGATIVE packagelessAddress 78, findServedOverlayRow 79, applyObjectRegistryMutation / unmanagedImportCollisions / rollBackUnmanagedImport / readRevertableCommit 81; recordPackageCommit and ensureObjectStorage keep 82 but change 2 --list lines; census-neutral with an identical list: hydrateOverlayIntoRegistry, applyRegistryWriteThrough, reconcileViewExpansions, applyRemoteMetadataMutation, expandRuntimeViewContainer, resolveAppPackageIdKey, ensureOverlayIndex, expandUnderOwnName, resolveRowlessExpandedView, foldObjectExtendersFromRegistry, refuseUnmintableMetaType, publishMetadataMutation, saveConflict, convertStoredItemDetailed, emitMetaItemPublished, listLiveMetadataTypes. Of the neutral ones, those named in a by-path pin test (readFileSync of protocol.ts) are hydrateOverlayIntoRegistry (5 pins), applyRemoteMetadataMutation (2), applyRegistryWriteThrough, expandRuntimeViewContainer, ensureOverlayIndex, publishMetadataMutation (1 each). Recommend future proposals carry this trial as part of the screen.",
    "Liveness ledger follow-up, carried forward (packages/spec/**, outside this card): manifest.json dependencies -> protocol.ts#resolveWritePackageScope (cut 19, quote now in protocol-write-package-scope.ts) and seed.json -> protocol.ts#applySeedBodies (cut 14, protocol-publish-batch.ts). check:liveness checks only that the #symbol is named in the file; both stubs keep it, so it passes. No row points at reportSealedOverlayRows.",
    "cut 22 proposal (measured on the merged head f488ca9's protocol.ts; AST screen with casts stripped AND the read-seam census trial): the expanded-view pair resolveRowlessExpandedView (protocol.ts line 10306, private async, 29 body lines; reads expandStoredViewContainers, namesWithOwnStoredRow, readActiveOverlayRows, rethrowUnlessMetadataStoreUnprovisioned, storedOverlayEntries -> 5 closures; 4 this. callers at :11041, :11556, :22145, :27291 stay) and expandUnderOwnName (18159, private, 30 body lines; reads isShippedByAnotherPackage -> 1 closure; 1 caller at :18008 stays). Neither has a private-static read, a this.constructor read or a new Error(. Census trial: 82 and an identical --list for each. Neither is named by a by-path pin test or by any *.test.ts. Module-level reads: resolveRowlessExpandedView reads the non-exported interface RowlessExpandedView (:6254) and the non-exported generic function servedViewExpansion (:2872), both with other readers -> gain export in place (private member, so the .d.ts should not move; re-measure), and PLURAL_TO_SINGULAR; expandUnderOwnName reads expandViewContainer (@objectstack/spec/ui, 2 other readers, stays). Estimated 200-260 changed lines; if the seat prefers one member, expandUnderOwnName alone. Class left after cut 21 (on the merged head): 301 members, 112 delegating stubs, 31 bodyless or fields, 158 with live bodies (12,772 body lines: 101 private with 3,603, 57 public with 9,169)."
    ]
    }

  14. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed

    PR #26404 merged at 2026-10-27T03:18Z by the merge queue as dada291a52 on main (Part of #25467; ACCEPT 6432438839).

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26404-*' 0 refs
    origin/main by content git cat-file -e origin/main:packages/metadata-protocol/src/protocol-sealed-overlay-report.ts present
    Ancestry git merge-base --is-ancestor dada291a52 origin/main holds

    State: card stays open (Part of), pm:dispatched stays.


    Generated by Claude Code

  15. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 8 · card thread · series card, cut 22 (cuts strictly serial; cuts 1–21 landed, the last PR #26404 dada291a52)
    Session: session_01R1q2xdtYgU6FKrZ7LgjPCC (the seat); the card thread is session_016SP1spj613tyGCgxoD1An6 (cuts 12–21's thread, reused)
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-ybjm3h (the card thread's harness-pinned branch, restarted from origin/main after cut 21 merged; it names no issue, so this claim is the identity record)
    Worktree: objectstack-issue-25467 (a linked worktree in the card thread's container)
    Domain: domain:server
    Seat: domain:server#1
    Ruling: #24586 letter A (6270097840); the series' .d.ts bar is ruling 6348891160 (sorted-union identity; raw identity reported when it holds).
    File surface: packages/metadata-protocol/src/protocol.ts and one new seam module for the cut 21 report 6432160640's cut 22 proposal: resolveRowlessExpandedView (protocol.ts:10306, private async) paired with expandUnderOwnName (:18159, private). Every caller keeps calling the class members (resolveRowlessExpandedView at :11041, :11556, :22145, :27291; expandUnderOwnName at :18008). Estimated 200–260 changed lines, no pin edit. Also: other test files that read the moved bodies in protocol.ts by path; the durability --list and the read-seam census re-measured (both must stay at 82 with an identical list, as the report's census trial found); scripts/adr-anchors/** only if a moved member is the mechanism an entry paragraph describes. skip-changeset, Part of #25467. ⛔ No docs/adr/**, ⛔ no packages/spec/** (stop on breach; explain in the report). If the AST screen or the census trial does not hold for one member, move the one that passes alone and report.
    Container & model: S, mode:thread, model and effort as the thread was opened
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card (a [maintainer] refactor card)
    Thread-read: 6432160640
    Premise: holds (read 2026-10-27T03:20Z at origin/main e0d6317440: both are private instance methods at protocol.ts:10306 and :18159, with the callers above)
    Serial constraints cleared: cut 21 (#26404) merged before this claim. The dev re-measures open PRs on packages/metadata-protocol/src/protocol.ts and runs git merge-tree against any overlap before pr_create.
    Carried: findServedOverlayRow stays in the class (seat call, ACCEPT 6432438839): moving it hides three guarded reads from the read-seam census. The liveness ledger's manifest.json and seed.json evidence pointers stay a spec-lane follow-up for the series close-out.

  16. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 25467,
    "status": "done",
    "branch": "claude/project-thread-ybjm3h",
    "pr": "#26449",
    "session": "session_016SP1spj613tyGCgxoD1An6 — the card thread (claim 6432922305)",
    "premise_still_valid": true,
    "summary": "Cut 22, move-only, both proposed members: the bodies of resolveRowlessExpandedView (:10306, private async, 27 body lines) and expandUnderOwnName (:18159, private, 28 body lines) move into the new protocol-view-expansion-names.ts (125 lines). Shape B: ViewExpansionNamesHost = the six methods they read, each handed over as a closure (resolveRowlessExpandedView: readActiveOverlayRows, rethrowUnlessMetadataStoreUnprovisioned, namesWithOwnStoredRow, expandStoredViewContainers [generic; the contextually-typed closure compiles unannotated], storedOverlayEntries; expandUnderOwnName: isShippedByAnotherPackage). Screen: no private-static read, no this.constructor read, 0 new Error(, and the census trial (each moved alone to a scratch module): 82 read seams, identical --list. Module-level reads: RowlessExpandedView (interface) and servedViewExpansion (generic function) gain export in place (other readers stay; index.ts names exports singly), PLURAL_TO_SINGULAR (@objectstack/spec/shared) and expandViewContainer (@objectstack/spec/ui) imported from where protocol.ts has them. All 5 callers (4 of resolveRowlessExpandedView at :11041/:11556/:22145/:27291, 1 of expandUnderOwnName at :18008) keep calling the class method. 200 changed lines (+143/-57; estimate 200-260). protocol.ts 29,193 -> 29,154. Commits: c2087b4 (move) on main 9a0108c; merge of main as 9567343 (no package file; src tree ac8309b0 both).",
    "tests": "metadata-protocol suite (vitest --maxWorkers=2, json reporter, under os-verify-lock): base 9a0108c and head c2087b4 both 21,584 tests (21,565 passed, 0 failed, 19 skipped), 271 files; 0 lost/added/changed; the merged head 9567343 per-test identical. Base leg = src swapped tree-only (new module removed), restored from HEAD under a trap. AST compare: 529 tokens (232 + 297), 0 differ, ws-collapsed text incl. comments equal; negative controls, one per member, in-memory: "!== 'view') return undefined" -> '===' gives resolveRowlessExpandedView differ 1; 'item.name = under;' -> 'ownName' gives expandUnderOwnName differ 1. Class 301 members, 299 byte-identical, 2 stubs keep docblock+signature; top level 248/250 byte-identical, the other two only gained export; head adds the import. tsc --noEmit 0 at head and merged; eslint --no-inline-config packages/metadata-protocol 0.",
    "gates": ".d.ts (ruling 6348891160), one dependency tree, base 9a0108c vs head c2087b4 and again on the merged tree 9567343 (full pnpm build 118/118): RAW 059fa1189ac13c65c36d3718584495bebaa48cc545e1526adb37cd95ef7dfaa3 (777,645 bytes) and NORMALISED 0a7694d518b570981c5cdcbcdd8fcb2dec9f1c7d74a7287299fe9e19e32a4183 everywhere: raw and sorted-union identity both hold. Positive control (private dropped from expandUnderOwnName) -> 796c09174d25bb97 (normalised 9f5a865eb21c4211) and prints the signature. index.js dbff5f6c5cde69ca -> 14cc3ee05da5713f; each .call(host and function decl 0 -> 1 ESM and CJS. Export tables ESM+CJS 78 names sha 9f18a0177ac736ed everywhere. Hand gates exit 0 both ends (base in a clean detached worktree at 9a0108c): adr-anchors, adr-symbol-anchors, system-context-census, tenant-audit-census, query-options-erasure-ratchet, filter-alias-parity, durability-degradation-log-level IDENTICAL (adr-anchors unchanged: no ADR cited in the moved bodies or the header); DURABILITY --list identical after stripping [@:][0-9]+ (158 lines; 82 read seams at both ends and on the merged tree — the order's condition); nul-bytes +1 file; engine-double-contract seams 13898->13882, 13923->13907, productionFiles 3,764 -> 3,766 (new file + gitignored spec registry.ts, as cuts 20/21). check-platform-checklist OK (29 anchors, 0 lost). Governed: 0 of 2 paths, 200 lines. Derived on 9567343 (no stale-tree warning): 46 gates, all exit 0; --ran 46/46, 0 NOT-MEASURED, 0 UNRUN. Open-PR overlap at pr_create (20 open): none edits protocol.ts or names either member; #26337 and #26138 (metadata-protocol test files) merge clean against this head and against main alone. CI at report time: just started.",
    "dogfood_battery": "n/a — no ! in the PR title and the claim's Clause-② is no with no (narrowing) arm",
    "mcp_calls": "1 GitHub MCP read (list_pull_requests for the overlap check); 0 GitHub MCP writes; no subscribe_pr_activity",
    "api_writes": "3 — git push of claude/project-thread-ybjm3h (new branch; the merged cut 21 branch had been deleted); relay pr_create (run 40448010739 -> #26449, draft, assignee os-project-manager, label skip-changeset; read back 16,574 body bytes identical); this os-dev-report via post-stamped.mjs",
    "line_budget": "200 changed lines (+143/-57), under the 3,000-line bar",
    "files_changed": [
    "packages/metadata-protocol/src/protocol.ts",
    "packages/metadata-protocol/src/protocol-view-expansion-names.ts"
    ],
    "deviations": [],
    "open_questions": [],
    "out_of_scope_findings": [
    "Read-seam census trial on base 9a0108c, 52 private live-bodied members of 10-120 lines (each moved alone to a scratch module with a .call(this, ...) stub, check-durability-degradation-log-level --list re-run; trial base 82). Census-NEGATIVE: findEnvironmentRows 66, packagelessAddress 78, findServedOverlayRow 79, foldStoredCollection / applyObjectRegistryMutation / unmanagedImportCollisions / rollBackUnmanagedImport / readRevertableCommit / storedFlowBindingAgrees 81; rethrowUnlessMetadataStoreUnprovisioned moved alone makes the gate exit 1 with 3 read seams. recordPackageCommit and ensureObjectStorage keep 82 but change 2 list lines. Every other member keeps 82 with an identical list.",
    "Liveness ledger follow-up, carried forward (packages/spec/**, outside this card): manifest.json dependencies -> protocol.ts#resolveWritePackageScope (cut 19) and seed.json -> protocol.ts#applySeedBodies (cut 14). check:liveness checks only that the #symbol is named; both stubs keep it. No row points at either cut 22 member.",
    "cut 23 proposal (measured on the merged head 9567343's protocol.ts; AST screen with casts stripped AND the census trial): the stored-item conversion pair convertStoredItem (protocol.ts line 6415, private, 13 body lines; reads the field storedConversionWarned — a Set it only .has/.adds, never reassigns, so handed over as a getter — and convertStoredItemDetailed, a closure; 10 this. callers stay) and convertStoredItemDetailed (6451, private, 17 body lines; reads no member, so a plain function its stub calls directly, as cuts 16/21; 2 callers stay). Neither has a private-static read, a this.constructor read or a new Error(. Census trial: 82 and an identical list for each. No by-path pin names either; the three tests that name convertStoredItem do so in comments and drive it through the class. Module-level reads: withDeclaredPageTypeDefault (non-exported function :2262, other readers -> gains export in place), PLURAL_TO_SINGULAR, and from @objectstack/spec applyConversionsToStoredItem / ConversionNotice / ConversionTodoNotice (each keeps one other reader in protocol.ts, so no import leaves; re-check with the identifier walk). Estimated 150-200 changed lines; if the seat prefers one member, convertStoredItemDetailed alone. Class left after cut 22 (merged head): 301 members, 114 delegating stubs, 31 bodyless or fields, 156 with live bodies (12,717 body lines: 99 private with 3,548, 57 public with 9,169)."
    ]
    }

  17. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: maintainer 「拆分线可以暂停」 (Leehom, 2026-10-27T04:15:32Z) · series pause · domain:server seat 1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC · 2026-10-27T04:15Z

    The split series pauses for the upcoming release.

    Restart-when: the maintainer lifts 「拆分线可以暂停」 on this card or in the project chat.


    Generated by Claude Code

  18. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: maintainer 「拆分线已经做了一半的继续完成,然后暂停,等新版本发布后继续」 (Leehom, 2026-10-27T04:17Z) · pause amendment · domain:server seat 1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC · 2026-10-27T04:18Z

    This amends the pause note 6433612082 with the maintainer's resume condition.

    Restart-when: the next objectstack release is published. The seat then orders cut 23 from the restart point, with no further ruling needed. This line replaces the Restart-when line in 6433612082.

  19. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed

    PR #26449 merged at 2026-10-27T05:07Z by the merge queue as d0852dd65b on main (Part of #25467; ACCEPT 6433803484).

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26449-*' 0 refs
    origin/main by content git cat-file -e origin/main:packages/metadata-protocol/src/protocol-view-expansion-names.ts present
    Ancestry git merge-base --is-ancestor d0852dd65b origin/main holds

    State: card stays open (Part of), pm:dispatched stays. The ACCEPT's Carried row ("Cut 23 goes to the same thread once this lands") was drafted before the pause and is superseded by 6433612082 and 6433636205: no cut 23 is ordered until the next objectstack release is published. The card moves to pm:on-hold now.


    Generated by Claude Code

  20. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop · card thread · series card, cut 23 — series restart (cuts strictly serial; cuts 1–22 landed, the last PR #26449 d0852dd65b)
    Session: session_01R1q2xdtYgU6FKrZ7LgjPCC (the seat); the card thread is session_016SP1spj613tyGCgxoD1An6 (cuts 12–22's thread, reused)
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-ybjm3h (the card thread's harness-pinned branch, restarted from origin/main after cut 22 merged; it names no issue, so this claim is the identity record)
    Worktree: objectstack-issue-25467 (a linked worktree in the card thread's container)
    Domain: domain:server
    Seat: domain:server#1
    Ruling: #24586 letter A (6270097840); the series' .d.ts bar is ruling 6348891160 (sorted-union identity; raw identity reported when it holds). Restart: maintainer 「拆分线已经做了一半的继续完成,然后暂停,等新版本发布后继续」 (Leehom, 2026-10-27T04:17Z; pause amendment 6433636205, whose Restart-when is "the next objectstack release is published"), and 「18.2 已经发布了」 (Leehom, 2026-10-27T10:11Z); release 18.2.0 published 2026-10-27T07:16Z. pm:on-hold comes off with this claim.
    File surface: packages/metadata-protocol/src/protocol.ts and one new seam module for the cut 22 report 6433520681's cut 23 proposal: convertStoredItem (protocol.ts:6416, private; reads the field storedConversionWarned — only .has/.add, never reassigned — and convertStoredItemDetailed) paired with convertStoredItemDetailed (:6452, private; reads no member, so a plain function its stub calls directly, as cuts 16/21). Every caller keeps calling the class members. withDeclaredPageTypeDefault gains export in place if other readers stay. Estimated 150–200 changed lines, no pin edit. Also: other test files that read the moved bodies in protocol.ts by path; the durability --list and the read-seam census re-measured (both must stay at 82 with an identical list, as the report's census trial found); scripts/adr-anchors/** only if a moved member is the mechanism an entry paragraph describes. skip-changeset, Part of #25467. ⛔ No docs/adr/**, ⛔ no packages/spec/** (stop on breach; explain in the report). If the AST screen or the census trial does not hold for one member, move the one that passes alone (the report names convertStoredItemDetailed alone as the fallback) and report.
    Container & model: S, mode:thread, model and effort as the thread was opened
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card (a [maintainer] refactor card)
    Thread-read: 6433520681
    Premise: holds (read 2026-10-27T10:12Z at origin/main f9867020c6: both are private instance methods at protocol.ts:6416 and :6452; convertStoredItem has 10 in-class callers plus the host closure at :10211, convertStoredItemDetailed has :6418 and :21925)
    Serial constraints cleared: cut 22 (#26449) merged before this claim. The dev re-measures open PRs on packages/metadata-protocol/src/protocol.ts and runs git merge-tree against any overlap before pr_create.
    Carried: findServedOverlayRow stays in the class (ACCEPT 6432438839). The liveness ledger's manifest.json and seed.json evidence pointers stay a spec-lane follow-up for the series close-out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:serverDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpm:dispatchedpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions