Skip to content

refactor(metadata-protocol): move the bulk data writes (batchData, the *ManyData verbs) out of protocol.ts into protocol-batch-data.ts (#25467 cut 1) - #25494

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-uasfag
Oct 23, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-uasfag

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Sales · project thread

Part of #25467
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6270097840

Cut 1 of the protocol.ts split (#24586 ruling A, recorded in 6270097840): 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). The claim is 6368300459. Sixteen ObjectStackProtocolImplementation method bodies move unedited into a new module, packages/metadata-protocol/src/protocol-batch-data.ts:

  • public: batchData (with its ADR-0119 atomic path), createManyData, insertManyData, updateManyData, deleteManyData;
  • private: runAtomicBatchData, runAtomicBatch, runBatchDataLoop, reconcileStoppedBatch, locateBatchCause, buildBatchDataResponse, buildRolledBackBatchResponse, runUpdateManyLoop, buildUpdateManyResponse, runDeleteManyLoop, buildDeleteManyResponse.

triggerAutomation sits between them in the class but is not batch code, and stays.

It is move-only, and the card stays open for the later cuts. Branch: claude/project-thread-uasfag, the harness-pinned branch for this session, cut from origin/main at ab510f42e7 (the claim's ab510f4c43 is a typo for this commit). It names no issue, so the claim comment is the identity record.

Serial with the file's in-flight PRs. At claim, none of the 21 open PRs touched protocol.ts (each PR's file list read against origin/main; #25451 touches only protocol.runtime-authoring-gate.test.ts). Re-measured just before this PR was opened, on all 18 open PRs: none touches protocol.ts (the Version Packages PR only CHANGELOG.md and package.json in this package).

The shape (#23050 shape B, as #25222, #25223 and #25224 apply it)

  • The class keeps each method with its name, signature, docblock and position, because tsup emits members with their JSDoc into the .d.ts. Each body is now one host literal plus fn.call(host, …), marked [#25467 cut 1]; locateBatchCause reads no member and is called directly. The async methods drop async and return the moved function's promise.
  • BatchDataHost is new. It types every member as the class member itself (ObjectStackProtocolImplementation['m']). Each moved function types its this as the Pick of the host over exactly the members its body reads (measured by AST), and the stub annotates its literal as ThisParameterType<typeof fn>. No cast, and no member becomes public or protected.
  • Methods go in as late-bound closures ((...a) => this.m(...a)), so a spy or double set on the instance is still the one a body reaches, and the moved bodies that call one another (batchData → runAtomicBatchData → runAtomicBatch → the loop → the builders) do so through the protocol, as before. The members passed this way: assertObjectRegistered, assertRecordExists, probeRecord, and the moved methods themselves.
  • The one field read, engine, goes as a getter, so each read happens when the body makes it (tests replace it on a constructed protocol).
  • The one caller of a moved method outside the moved code, applyPublishBackfill (this.updateManyData(), still calls the class method.

Module-level declarations.

  • mergeDroppedFieldEvents and rowOperationFailureFallback are read only by the moved bodies. They move with them, unedited, docblocks included, and stay unexported.
  • byIdUpdateRecord, rowRequiredIdError, toRowApiError, type BatchDataRowResult and type BatchDataLoopOutcome are also read by code that stays, so they stay and gain export in place, the only edit to each. The module imports them back from ./protocol.js.
    • src/index.ts exports from ./protocol.js by name, so none of them is published. Measured below: the .d.ts and the export lists do not move.
    • Each value import is read only inside a function body, at call time, never while either module evaluates, so the module cycle is evaluation-safe.
  • The module imports engineCanRollBack and recordNotFoundError (@objectstack/core), omitInternalFieldsFromWriteResponse (./write-response-internal-fields.js) and the spec types the bodies name, from the same specifiers protocol.ts uses. protocol.ts keeps all its imports (each still has readers there).

The published .d.ts does not change

Under the series bar (ruling 6348891160), measured on base ab510f42e7 and on the head, both built against the same dependency tree (a full turbo run build at base, 77/77 tasks, then pnpm --filter @objectstack/metadata-protocol build at head):

  • Raw sha256 of dist/index.d.ts and dist/index.d.cts, base and head, all four the same: 8e1a224c7d5a800c65c0174f9bc2245b70e0bab2106ab8dbf8a4b2dedd4ca35f. The raw diff is 0 lines.
  • Normalised sha256, base and head the same: 5b98a8e857554959f7561563d6a0742110c5d3d8ad6119065ed5a69b0bc06f95. The normaliser, run from packages/metadata-protocol:
node -e 'const s=require("fs").readFileSync(process.argv[1],"utf8");process.stdout.write(s.replace(/"[^"\n]*"(?:\s*\|\s*"[^"\n]*")+/g,r=>r.split(/\s*\|\s*/).sort().join(" | ")))' dist/index.d.ts | sha256sum
  • Positive control on a copy of the head dist/index.d.ts: line 1348, private engine;, made public (engine;) gives raw 66d80e4206a14b2b7e76dc37496d347d9dd39f53c66d016966844e707992e5ac and normalised f40390e5c426e0c6e24523cd6908726d3f3cab87f9a4ac36df20992bec04da95, both different from the real hashes.
  • Export tables: the ESM and CJS bundles each export the same 78 names at base and head, loaded at runtime (import() and require of the built bundles). The sorted list hashes e47ac7c753bcb8bee1e79c1a5f79f7394cf030bd526de81ea8bcbfcb71fa024a on all four.

No changeset: skip-changeset, per ruling 6348891160.

Proof of move-only

  • Bodies, by AST token (recursive getChildren leaves, so template literals scan correctly): each moved function's parameters (less the added this), return type and body have the same token sequence as the base method, and each body line is the base line with four leading spaces removed. async matches on all sixteen. The two moved declarations are token-identical and their docblocks byte-identical. 3,982 tokens compared, 0 differ. Negative control: one changed token in batchData makes the check report a difference.
  • Class side: the class has 298 members at base and head. The 282 members that did not move are byte-identical to base. Each of the 16 stubs keeps its docblock and signature byte-identical, less async.
  • Top level of protocol.ts: 249 of the 256 base statements other than the class are byte-identical. The others: the five export additions above, and the two declarations that moved. The one new statement is the import of the new module.
  • Size: +1,093 / -735 over 4 files, under the 3,000-line manual-merge line. protocol.ts goes from 33,065 to 32,468 lines (each stub keeps its docblock and carries its host literal, so the file shrinks by less than the bodies' length); protocol-batch-data.ts has 944.

Readers of the moved lines, migrated in this PR

  • ADR anchors. The protocol.ts entry in scripts/adr-anchors/ carries an ADR-0119 paragraph that describes batchData's atomic path, which now lives in the module. As in the [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 cuts, the module gets its own entry (packages__metadata-protocol__src__protocol-batch-data.ts.json) carrying ADR-0119 and that paragraph verbatim. The protocol.ts entry is unchanged, and ADR-0119 is still cited in protocol.ts outside the moved text. check:adr-anchors: 80 → 81 anchored files, decision-letter citations on the anchored surface 2,001 → 2,001.
  • protocol.bracketed-refusal-opener-absence.test.ts. It scans each producer file's source for refusals opening with a bracketed tag, with a per-file new Error( floor so a scan that finds nothing cannot pass for free. The moved text holds 4 new Error( sites, so the module joins PRODUCERS with a floor of 4. Without it those throw sites would have left the scan silently. protocol.ts keeps its floor of 5.
  • Read and not edited:
    • docs/adr/0119-…md anchors protocol.ts#batchData twice. The method shell stays, so it still resolves (check-adr-symbol-anchors at both ends below).
    • protocol.write-response-internal-fields.tripwire.test.ts enumerates *Data methods on the prototype at runtime; the stubs keep every name.
    • protocol.read-verb-canonical-fold.test.ts and the other source scans that read ./protocol.ts (register-item, lookup-artifact-item and view-expansion-reconcile call-site pins, query-transport-dialect, object-registry-write-through-spelling, hydrate-overlay-canonical-type, the two recovery-door pins): none of their patterns occurs in the moved text, and all pass at head.
    • scripts/engine-double-contract.seams.json names protocol.ts rows for deleteData and updateData only, which stay.
    • scripts/query-options-erasure-baseline.json counts protocol.ts at 6: the moved text has no engine find / findOne / count / aggregate call, so no counted site moves.
    • No isSystem read sits in the moved text (system-context census).
    • The tenant-audit census places no metadata-protocol write site (238 sites at base and head, 0 in this package); it exits 0 at both ends with no --write.

Verification

🤖 Generated with Claude Code

https://claude.ai/code/session_01J8pUyVs5eas1AjMdReJM7C

…l.ts into protocol-batch-data.ts

Sixteen ObjectStackProtocolImplementation method bodies (batchData and its
atomic path, createManyData, insertManyData, updateManyData, deleteManyData,
the three per-row loops and the response builders) move unedited into
protocol-batch-data.ts, in the host shape rest-server.ts's split set. The
class keeps every method, docblock and signature; each body becomes a literal
of the members it reads plus a .call. mergeDroppedFieldEvents and
rowOperationFailureFallback, read only by the moved bodies, move with them;
byIdUpdateRecord, rowRequiredIdError, toRowApiError, BatchDataRowResult and
BatchDataLoopOutcome gain `export` in place (index.ts exports from
protocol.ts by name).

Move-only: no behaviour change.

Claude-Session: https://claude.ai/code/session_01J8pUyVs5eas1AjMdReJM7C
Co-authored-by: Claude <noreply@anthropic.com>
…-refusal scan at protocol-batch-data.ts

The batchData atomic path the protocol.ts ADR anchor entry's ADR-0119
paragraph describes now lives in protocol-batch-data.ts, so that module gets
its own entry carrying the paragraph verbatim (the protocol.ts entry is
unchanged; ADR-0119 is still cited there). The bracketed-refusal opener scan
follows the moved throw sites with a per-file floor.

Claude-Session: https://claude.ai/code/session_01J8pUyVs5eas1AjMdReJM7C
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 23, 2026
@objectstack-fleet
objectstack-fleet Bot requested a review from os-sales October 23, 2026 15:53
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/metadata-protocol, touching 56 documentable anchor(s).

16 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: node scripts/docs-audit/affected-docs.mjs --json ea33919f56a9879f95a00d45418385ff7dbb974f.

⛔ 8 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails.

What this run could not see
  • 1 anchor(s) matched too much of the corpus to be a work list: VALIDATION_FAILED (literal, 32 pages)
  • 1 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 11 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json ea33919f56a9879f95a00d45418385ff7dbb974f → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 1e8ce95e439bc71ea15309f8c02217be6c10a526 — the merge of head b55faf2162692c6ad242840692a7e00e29361487 into base ea33919f56a9879f95a00d45418385ff7dbb974f, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 1e8ce95e439bc71ea15309f8c02217be6c10a526 && git checkout 1e8ce95e439bc71ea15309f8c02217be6c10a526
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin ea33919f56a9879f95a00d45418385ff7dbb974f b55faf2162692c6ad242840692a7e00e29361487 && git checkout -B drift-repro ea33919f56a9879f95a00d45418385ff7dbb974f && git merge --no-ff b55faf2162692c6ad242840692a7e00e29361487

node scripts/docs-audit/affected-docs.mjs --json ea33919f56a9879f95a00d45418385ff7dbb974f

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs ea33919f56a9879f95a00d45418385ff7dbb974f → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

os-dev-report
{
"issue": 25467,
"status": "done",
"branch": "claude/project-thread-uasfag",
"pr": "#25494",
"session": "session_01J8pUyVs5eas1AjMdReJM7C — this run's harness-stamped id, on the Claude-Session: trailer of every commit on the branch",
"premise_still_valid": true,
"summary": "Cut 1 of the protocol.ts split (#24586 ruling A, 6270097840; d.ts bar 6348891160): the card's batch and Many data section. Claim 6368300459. Sixteen ObjectStackProtocolImplementation method bodies moved unedited to the new module packages/metadata-protocol/src/protocol-batch-data.ts (host BatchDataHost): batchData, createManyData, insertManyData, updateManyData, deleteManyData (public) and runAtomicBatchData, runAtomicBatch, runBatchDataLoop, reconcileStoppedBatch, locateBatchCause, buildBatchDataResponse, buildRolledBackBatchResponse, runUpdateManyLoop, buildUpdateManyResponse, runDeleteManyLoop, buildDeleteManyResponse (private). triggerAutomation, between them in the class, stays. Shape B as in #25222, #25223 and #25224: each method keeps name, signature, docblock and position less async and hands its body one host literal typed ThisParameterType of the moved function, whose this is the Pick of BatchDataHost over exactly the members its body reads; methods as late-bound closures, engine as a getter; locateBatchCause reads no member and is called directly. Module level: mergeDroppedFieldEvents and rowOperationFailureFallback, read only by the moved bodies, moved byte-identical and unexported; byIdUpdateRecord, rowRequiredIdError, toRowApiError and the types BatchDataRowResult and BatchDataLoopOutcome, also read by code that stays, gained export in place (src/index.ts exports protocol.js by name, so none is published). Two path readers migrated in the same PR: a scripts/adr-anchors entry for the module carrying ADR-0119 and the protocol.ts entry's ADR-0119 paragraph verbatim (it describes the batchData atomic path), and a PRODUCERS row in protocol.bracketed-refusal-opener-absence.test.ts with floor 4 (the module's new Error( count). Published d.ts byte-identical to base. Serial rule (Sales, 10-23 15:12Z): at claim none of 21 open PRs touched protocol.ts; re-measured before pr_create, none of 18. The claim names the base ab510f4c43, a typo for ab510f4; the PR body says so. No open question.",
"tests": "pnpm --filter @objectstack/metadata-protocol test under os-verify-lock. Base ab510f4: 21,466 tests (21,447 passed, 0 failed, 19 skipped), 1,181 files. Head 5fce393: 21,467 (21,448 passed, 0 failed, 19 skipped), 1,181 files. Compared per test name and status from the JSON reporters: no test lost, none changed status; the one added test is the new PRODUCERS row's case. After merging origin/main ea33919 (head b55faf2, #25451 had added one test file in this package): 21,476 (21,457 passed, 0 failed, 19 skipped), 1,182 files. Move-only, so no ablation. Package tsc --noEmit exit 0 at both heads; eslint on protocol.ts and protocol-batch-data.ts exit 0. Out-of-package tests that read protocol.ts by path, at head, all pass: core row-serving-door-exposure.pin and second-object-read-exposure.pin (7), objectql core-boundary.ratchet (2), spec metadata-type-registry-allow-org-override-absence (2) and scripts/liveness/evidence (42), client and rest discovery-double-retired-key (3 + 2); spec check:liveness exit 0. Move proof: each moved function's parameters (less the added this), return type and body have the same TypeScript AST leaf-token sequence (recursive getChildren) as the base method, each body line is the base line minus four leading spaces, async matches on all sixteen; the two moved declarations are token-identical with byte-identical docblocks; 3,982 tokens compared, 0 differ. Negative control: one changed token in batchData makes the check fail. Class: 298 members at base and head; the 282 that did not move byte-identical; the 16 stubs keep docblock and signature byte-identical less async. Top level of protocol.ts: 249 of 256 base statements byte-identical, the others the five export additions and the two moved declarations; one new statement, the module import. +1,093 / -735 over 4 files; protocol.ts 33,065 to 32,468 lines, the module 944.",
"dts_block": {
"files": "packages/metadata-protocol dist/index.d.ts and dist/index.d.cts, base ab510f4 (full turbo run build, 77/77) and head (package build against the same dependency tree); after the main merge the head d.ts was rebuilt and re-hashed",
"raw_sha256": "base index.d.ts 8e1a224c7d5a800c65c0174f9bc2245b70e0bab2106ab8dbf8a4b2dedd4ca35f · head index.d.ts the same · base and head index.d.cts the same hash · head b55faf2 index.d.ts the same",
"normalised_sha256": "base 5b98a8e857554959f7561563d6a0742110c5d3d8ad6119065ed5a69b0bc06f95 · head the same",
"normaliser": "node -e 'const s=require("fs").readFileSync(process.argv[1],"utf8");process.stdout.write(s.replace(/"[^"\n]
"(?:\s*\|\s*"[^"\n]")+/g,r=>r.split(/\s\|\s*/).sort().join(" | ")))' dist/index.d.ts | sha256sum",
"raw_diff_lines": 0,
"positive_control": "head index.d.ts line 1348, private engine; made public (engine;): raw 66d80e4206a14b2b7e76dc37496d347d9dd39f53c66d016966844e707992e5ac, normalised f40390e5c426e0c6e24523cd6908726d3f3cab87f9a4ac36df20992bec04da95, both different from the real hashes.",
"exports": "ESM and CJS bundles loaded at runtime (import and require of the built bundles): 78 names each at base and head; sorted-list sha256 e47ac7c753bcb8bee1e79c1a5f79f7394cf030bd526de81ea8bcbfcb71fa024a on all four.",
"note": "No changeset (skip-changeset label), per 6348891160. The five new in-place exports are not re-exported by src/index.ts, which lists protocol.js names explicitly."
},
"adr_anchor_block": {
"gate": "node scripts/check-adr-symbol-anchors.mjs, run by hand at base ab510f4 and head, exit 0 at both, 2,384 anchors resolve at both. ADR-0119 anchors protocol.ts#batchData twice; the method shell stays in the class, so both still resolve as declarations.",
"adr_anchors": "pnpm check:adr-anchors exit 0 at base and head; anchored files 80 to 81 (the new protocol-batch-data.ts entry); decision-letter citations on the anchored surface 2,001 to 2,001. The protocol.ts entry is unchanged, and ADR-0119 is still cited in protocol.ts outside the moved text."
},
"gates": "Local on head b55faf2 (5fce393 merged with origin/main ea33919): dispatch-gates --commands --changed derives 67 commands, the same list as on 5fce393 (diffed, identical); each run with its exit captured before any pipe; all 67 exit 0. --ran: 67 derived, 67 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero). The same 67 also ran on 5fce393 before the merge, all exit 0, --ran 67/67. Run by hand, not derived, at base ab510f4 and head, all exit 0 at both: check-adr-symbol-anchors (2,384 resolve), check:adr-anchors (80 to 81 files, letters 2,001 to 2,001), check-tenant-audit-census (238 write sites at both, 0 in metadata-protocol, no --write), check-platform-checklist; spec check:liveness exit 0 at head. Erasure ratchet: scripts/query-options-erasure-baseline.json counts protocol.ts at 6; the moved text has no engine find/findOne/count/aggregate call, so no counted site moves. No isSystem read in the moved text. scripts/engine-double-contract.seams.json names protocol.ts rows for deleteData and updateData only, which stay. Merge check: origin/main has moved to 6308143 since the merge; it touches nothing under packages/metadata-protocol and git merge-tree with this head is clean. Serial re-check at 16:43Z: 20 open PRs, each file list read (the Version Packages PR #24876 paged through all 395 files): none but this one touches protocol.ts. CI on head b55faf2, all completed, none failed: Auto Label success (a second run skipped by its filter), Build Core success, Check Changeset success (a second run skipped), Check Documentation Links success, Check PR Size success (a second run skipped), Dogfood Regression Gate success, filter success, Flag docs affected by code changes success, Governed Surface Queue Guard success, Lint · CI, release & engine gates success, Lint · docs & code guards success, Lint · ESLint success, Lint · PM dispatch-gates success, Lint · repo & tooling gates success, Lint · scoped · query-options erasure success, Lint · scoped · slot lookup & corpus success, Lint · scoped · tooling self-tests success, Lint & Repo Gates success, No other open PR may claim the same issue success, No other open PR may claim the same single-writer path success, Part-of PR must not also close its card success, Test Core success, Test Core (1/6) to (6/6) success, The card this PR closes must claim this branch success, Type Check · consumer gates success, Type Check · debt ledger success, Type Check · source gates success, Type Check · workspace success, TypeScript Type Check success; skipped by their own filters: 18.x upgrade harness (opt-in) x2, Build Docs, Console Pin Gate, the sharded Dogfood Regression Gate matrix, Dogfood Verify CLI, Packed-tarball smoke (opt-in) x2, Temporal Conformance (live PG + MySQL). 46 check runs, 0 failed.",
"docs_drift": "Advisory. Re-derived with node scripts/docs-audit/affected-docs.mjs --json ea33919 on head b55faf2: 24 pages (16 hand-written, 8 release-owned) from 56 anchors, the same as the bot comment 6368972275. Every page is reached through a name the move relocated, not through a changed behaviour: the client methods and routes bound to the moved verbs (updateMany 13, deleteMany 10, /:object/batch 7, createMany 6, and the data.* and /:object/*Many rows), the moved method names (batchData 5, createManyData 3, deleteManyData 3, insertManyData 3, updateManyData 2) and string literals inside the moved bodies (NOT_IMPLEMENTED 10, NOT_ATTEMPTED 4, ROLLED_BACK 4). Each method keeps its name, signature, docblock and behaviour, and each literal moved unedited, so no page goes stale. No page reads the moved lines by path.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "No MCP write tool. GitHub reads through gh api GET and the GitHub MCP read tools (issue_read, list_issues, list_pull_requests, search_issues, pull_request_read get_check_runs). Also claude-code-remote subscribe_pr_activity on #25494 (a session subscription, not a GitHub write).",
"api_writes": "6 strokes, all through the scripts/pm relay or git: (1) fleet-write assign os-sales, labels_remove pm:queue, labels_add pm:dispatched on #25467 (relay run 39977285134); (2) post-stamped claim comment 6368300459 on #25467 (relay run 39977392596; read back identical, 6,438 bytes); (3) git push of claude/project-thread-uasfag (3209711, 5fce393, then the main merge b55faf2); (4) fleet-write pr_create, PR #25494 draft with assignee os-sales and label skip-changeset (relay run 39981948442; body read back identical, 11,166 bytes); (5) fleet-write pr_request_reviewers os-sales (relay run 39982054846); (6) this report, via post-stamped.",
"open_questions": [],
"out_of_scope_findings": []
}

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · 2026-10-23T16:53Z

domain:services seat 1 (seat post #6021) · os-sales · session_016g7nYP9wdNx1GDa5XDr7Uy · card #25467 cut 1, batch and *Many data (claim 6368300459; os-dev-report 6369962360) · reviewed head b55faf2162 · merge base ea33919f56

  • Shape: 16 ObjectStackProtocolImplementation method bodies move unedited into protocol-batch-data.ts, as shape B, the same way as in [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. The public ones are batchData and the four *ManyData verbs; the other 11 are private helpers.
    • Every class member keeps its name, signature, docblock and position.
    • engine goes in as a getter, and methods go in as late-bound closures.
    • mergeDroppedFieldEvents and rowOperationFailureFallback move along with the bodies and stay unexported.
    • Five shared declarations stay in protocol.ts and gain export in place. index.ts exports from ./protocol.js by name, so none of them is published (the .d.ts below confirms it).
    • 4 files, +1,093 / −735.
  • .d.ts, ruling 6348891160 item 1, re-run by the seat in its own worktree:
    • turbo run build --filter=@objectstack/metadata-protocol at ea33919f56 and at this head.
    • dist/index.d.ts and dist/index.d.cts are raw 8e1a224c7d5a800c65c0174f9bc2245b70e0bab2106ab8dbf8a4b2dedd4ca35f and normalised 5b98a8e857554959f7561563d6a0742110c5d3d8ad6119065ed5a69b0bc06f95 at both ends. The raw diff is 0 lines.
    • Positive control: head line 1348, private engine;, made public moves both hashes, to raw 66d80e4206a14b2b… and normalised f40390e5c426e0c6….
    • CJS exports: 78 at base and at head.
  • Gates re-run by the seat, all exit 0 at base and at head:
    • check-adr-symbol-anchors: 2384 … 466 symbol at both.
    • check-tenant-audit-census: 238 sites.
    • check-system-context-census: 148 sites.
    • check-adr-anchors
    • check-dispatcher-error-vocabulary
    • check-platform-checklist
  • Decision letters, read by the seat: 2001 at base and 2001 at head. Anchored files go from 80 to 81: the new module carries the ADR-0119 paragraph verbatim, as the anchor-entry rule requires when a paragraph describes a moved body.
  • Path readers migrated in the same PR: the ADR anchor entry, and the bracketed-refusal pin's PRODUCERS row with a floor of 4 for the 4 new Error( sites that moved. The PR lists the readers it read and left unedited.
  • Tests and gates (report):
    • The suite gives the same results at both ends: 21,466 tests at base and 21,467 at head, the +1 being the new PRODUCERS case, with 0 failed.
    • AST token identity over 3,982 tokens, with a negative control.
    • 67/67 derived gates.
    • CI on this head: 34 success and 12 expected skips, with none failed or pending (46 runs).
  • Serial rule: at 16:43Z no other open PR touched protocol.ts. git merge-tree onto today's main (4c8f40a196) is clean.
  • Body: the attribution header, both footers and the os-sales reviewer are present. The claim's base typo (ab510f4c43 for ab510f42e7) is disclosed in the body. Accepted.
  • Declarations: refactor(metadata-protocol), Clause-②: no, Metadata-protocol: none, skip-changeset, Ruling-ref: 6270097840. No contract-review record or dogfood battery is owed. Out-of-scope findings: none.
  • Landing: not governed (check-governed-merges --pr 25494: 1,828 lines). Ready + auto-merge through the relay. The card stays open and dispatched. Cut 2 is claimed afresh on the merged main, after re-checking the in-flight PRs on protocol.ts.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 23, 2026 16:54
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 23, 2026 16:54
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 23, 2026
Merged via the queue into main with commit bf5855b Oct 23, 2026
47 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-uasfag branch October 23, 2026 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants