Skip to content

refactor(metadata-protocol): move the metadata item reads and the layered read through the protocol host (#25467 E2 cut 1b) - #29590

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-xniw22
Nov 2, 2026
Merged

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

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steve · project thread

Part of #25467

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:把 protocol.ts 里“元数据读取”一节的后半(单项读取 getMetaItem、getMetaItemForExecution 及二者共享的私有 readMetaItem,外加分层读取 packagelessLayeredReadRefusal、getMetaItemLayered)的方法体,经 E1 的宿主机制原样搬进两个新模块;5 个方法仍留在类上(签名与文档不变),方法体变成一行转发。
  • 为什么改:[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 裁决 E 的 E2 第 1 节后半(1b),接在已合并的 1a(refactor(metadata-protocol): move the metadata list reads, the audit read and the UI-view read through the protocol host (#25467 E2 cut 1a) #29548)之后,在声明的 protocol.ts 冻结日内;第 1 节到此搬完。
  • 风险与回滚:低。只做搬移:工具逐个证明 5 个方法体与原方法体在“this. 读作 host.”之外 AST 与文本全同;对外 index.d.ts(ESM 与 CJS)与 main 构建出的逐字节相同,getMetaTypes() 的推断类型块也逐字节相同。回滚即整体 revert。
  • 先看:packages/metadata-protocol/src/protocol-meta-item-reads.ts 文件头;protocol.ts 里 5 个方法的转发体与类 static {} 块新增的宿主条目;protocol.lookup-artifact-item-call-sites.test.ts 的改动。
  • 两分钟验证:cd packages/metadata-protocol && node scripts/host-split.mjs check origin/main readMetaItem protocol-meta-item-reads.ts,预期 "ok":true,"textIdentical":true。
  • 需要你做的:无(约 2,575 行,低于 3,000 行线,席位自审)。

What changes

Step E2, section 1 "metadata reads", part 1b of ruling E (6537939895), on the protocol.ts freeze day seat 5 declared (#28677). It follows 1a (#29548) and finishes section 1. This is a pure application of the E1 host pattern: no logic changes, and no new rewrite kind. Before cutting, the director's #29465 A condition was checked: no protocol.ts codemod card has been claimed (the one codemod card, #29520, is the sql-driver.ts pilot).

member moved to rewrite sites (all this.x to host.x)
getMetaItem protocol-meta-item-reads.ts 1
getMetaItemForExecution protocol-meta-item-reads.ts 1
readMetaItem (private, 684 lines) protocol-meta-item-reads.ts 46
packagelessLayeredReadRefusal protocol-meta-layered-reads.ts 1
getMetaItemLayered (496 lines) protocol-meta-layered-reads.ts 24

Each method keeps its docblock, modifiers and signature on the class; its body becomes return fn(protocolHost(this), …). ProtocolHost and the class's static block gain 22 entries, all call-time closures (the other members these bodies read were already on the host). node scripts/host-split.mjs check origin/main MEMBER MODULE reads ok: true, textIdentical: true for all five, and the tool refused none. Negative control, with code === null changed to !== in getMetaItemLayered's moved body, then restored:

PROBLEM protocol-meta-layered-reads.ts:183: ExclamationEqualsEqualsToken where the base has EqualsEqualsEqualsToken (`===`)
PROBLEM protocol-meta-layered-reads.ts: getMetaItemLayered's body text differs from the base body rewritten and re-indented, first at body line 64

protocol.ts drops ten import names only the moved bodies used: isTenantAuthored, storedDraftChanges, computeViewReferenceDiagnostics, decorateMetadataItem, withFormLayoutWarnings, withPublishVerdict, isObjectOfDisabledPackage, noPendingDraftError, objectPackageDisabledError and envelopePackageId. Each module imports what its bodies read from where protocol.ts imports it. Two import comments belonged to dropped names, and each moves with its name rather than being lost:

  • the [#21059] note on isTenantAuthored now stands on that import in protocol-meta-layered-reads.ts;
  • the [#24395] note's half about the draft row's per-key provenance (storedDraftChanges) now stands in protocol-meta-item-reads.ts, and protocol.ts keeps the half about the authoring surface.

Forced test edit

One by-path pin reads through the split. What it asserts is unchanged.

src/protocol.lookup-artifact-item-call-sites.test.ts:

  • The three readMetaItem site rows carry file: 'protocol-meta-item-reads.ts', and the getMetaItemLayered row carries file: 'protocol-meta-layered-reads.ts', where those bodies now stand.
  • "Both read doors take their envelope from one rule" required protocol.ts to import envelopePackageId from protocol-package-bindings.ts. Neither door stands in protocol.ts any more, so it now requires the item read's module to import that one definition and to define no copy, as 1a did for the list read's module. protocol.ts must still define no copy.

Ablation, with the item read's envelopePackageId(request.packageId, item) argument changed to request.packageId in the module, then restored: Tests 1 failed | 5 passed (6), a site with no recorded disposition … expected [ Array(1) ] to deeply equal [].

The read-verb pin, the hydrateOverlayIntoRegistry caller-set pin (1a's edit already reads the modules) and the read-seam census needed no edit. Read-verb ablation, dropping the fold from getMetaItemLayered's moved body, then restored: Tests 1 failed | 17 passed (18), expected [ 'getMetaItemLayered' ] to deeply equal []. The census reads 100 seams, the same as main.

The published .d.ts

Built from main 85f77e9 (1a's merge, this branch's base) and from this head. index.d.ts is byte-identical: raw sha256 97e36a54…d6c680 on both sides, ESM equal to CJS, normaliser 2 b73fbce4…a55114 on both. The raw diff of getMetaTypes()'s emitted block (793 lines, its return type still inferred per the seat's E1 ruling) is empty. The declaration-emit comment leak that struck 1a did not strike this cut, so no comment length was adjusted. Before the replay onto 85f77e9, the same cut stacked on 1a's head read byte-identical to main 399df5b too (450c9334…5d744e).

Serial

1a (#29548) landed as one squashed commit, 85f77e9. This branch was restarted from main at dbca3ef and the three 1b commits were replayed onto it. host-split check was re-run against the new main for all five members, and the suite, the dependents, the .d.ts and the gates below were re-run on the replayed head. Re-read just before opening against main d3175d5, 9 commits later. One of those, #29437, touches protocol-save-door-refusals.ts only. git merge-tree with main is clean.

Open PRs whose own diff touches protocol.ts or a protocol-*.ts module:

Seat 3's #29390 work (branch claude/project-thread-gvqm55, head d776e25, no PR yet) touches the restore limb, which is outside the moved section. git merge-tree with this head is clean.

Gates

On 3912b13 (the replayed head):

  • node scripts/pm/dispatch-gates.mjs --commands derived 61 commands, and each records exit 0.
  • --ran reports 61 derived, 61 run, 0 NOT-MEASURED, 0 UNRUN.
  • The package's typecheck and test, through os-verify-lock, read Test Files 307 passed, 4 skipped; Tests 22232 passed, 26 skipped.
  • The 11 direct dependents' typecheck exits 0.
  • Lint (eslint packages/metadata-protocol --no-inline-config) exits 0.
  • The census reads 100 seams.

The same battery was green before the replay (62 of 62, on the stack over 1a). CI is not read.


Generated by Claude Code

…ered reads through the protocol host

getMetaItem, getMetaItemForExecution and readMetaItem move to
protocol-meta-item-reads.ts; packagelessLayeredReadRefusal and
getMetaItemLayered move to protocol-meta-layered-reads.ts. Each body is
the method's own, with this.x read as host.x (73 sites); each method
stays on the class as a stub. protocol.ts drops the import names only
the moved bodies read, and the two import comments they carried move
with them.

Claude-Session: https://claude.ai/code/session_01ADHkmR4MjTzeUv5x6tNkbk
Co-authored-by: Claude <noreply@anthropic.com>
…he item and layered reads where their bodies now stand

Claude-Session: https://claude.ai/code/session_01ADHkmR4MjTzeUv5x6tNkbk
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/xl documentation Improvements or additions to documentation tests tooling labels Nov 2, 2026
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

34 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 d3175d59d036d3c2819d5e7913c8c406c1ea634d.

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

What this run could not see
  • the SDK route bridge reached 60 of 216 client-bound route-ledger rows — the other 156 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 156: 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; 101 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 — 10 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 d3175d59d036d3c2819d5e7913c8c406c1ea634d → packageMentionDocs.

Which tree this was computed on

This run read content/docs from b87e9ff024aaaf1d67e074ae726924cc154b5b2c — the merge of head 3912b131ffced8c309325b9fa42caa09c59116de into base d3175d59d036d3c2819d5e7913c8c406c1ea634d, 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 b87e9ff024aaaf1d67e074ae726924cc154b5b2c && git checkout b87e9ff024aaaf1d67e074ae726924cc154b5b2c
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin d3175d59d036d3c2819d5e7913c8c406c1ea634d 3912b131ffced8c309325b9fa42caa09c59116de && git checkout -B drift-repro d3175d59d036d3c2819d5e7913c8c406c1ea634d && git merge --no-ff 3912b131ffced8c309325b9fa42caa09c59116de

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

⚠️ 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 d3175d59d036d3c2819d5e7913c8c406c1ea634d → 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

domain:server#5 · os-steve · session_01ADHkmQKwKFCp1m6Pb6Q8c1

维护者速读

  • 改了什么:protocol.ts 拆分 E2 第 1 段后半(1b):元数据单项读取和分层读取 5 个成员(getMetaItem、getMetaItemForExecution、readMetaItem、packagelessLayeredReadRefusal、getMetaItemLayered)的方法体搬到 protocol-meta-item-reads.ts 和 protocol-meta-layered-reads.ts,类上保留声明和桩。至此第 1 段全部搬完。
  • 为什么改:[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 裁决 E 的第 2 阶段,按段搬出 protocol.ts,本段在 protocol.ts 冻结窗口内。
  • 风险与回滚:无行为变化。发布的 index.d.ts 与 main 原始字节一致。回滚即 revert。
  • 先看:packages/metadata-protocol/src/protocol-meta-item-reads.ts;protocol-host.ts 新增的宿主成员。
  • 两分钟验证:pnpm --filter @objectstack/metadata-protocol test,全绿。
  • 需要你做的:无,席位落地(2,575 行,未过 3000 行线)。合入后本席发 protocol.ts 解冻通知。

席位意见:与 E2 派发相符。被迫改动的只有调用点钉住测试改读新模块,断言内容不变。

席位核对

ACCEPT · domain:server seat 5 · os-steve · session_01ADHkmQKwKFCp1m6Pb6Q8c1 · 2026-11-02T20:25Z · head 3912b131ff · Part of #25467 (E2 section 1, part 1b)

  1. Shape: draft against main, Part of #25467. A patch changeset for @objectstack/metadata-protocol. Clause-②: no, Metadata-protocol: none. Not governed. 2,575 changed lines, 6 files, face TIER_DEFAULT.
  2. Against the order: ruling E, E2, on the declared freeze ([PM seat] domain:server · seat 5 — ⏳ vacant #28677). The branch was replayed onto main after 1a's squash merge (85f77e93d7). host-split check reads ok, with textIdentical for all five members across 73 sites, all kind 1 and none refused. index.d.ts and the getMetaTypes() block are raw byte-identical to main. The census stays at 100. The ProtocolHost additions are readonly mirrors of existing class members; the interface is internal to the package and does not appear in index.d.ts.
  3. Accepted deviations: one forced pin edit. The lookupArtifactItem call-site pin reads its readMetaItem and getMetaItemLayered rows from the new modules, and the envelope check requires the item read's module to import envelopePackageId. What it asserts is unchanged, and an ablation is quoted. Two import comments ([metadata: once a stored flow row under a name no package ships is hydrated, the layered read reports it as the code layer, against the spec's "null when no artifact ships this item" #21059] and half of [metadata-protocol: the draft save records draftChanges (per-key provenance: which surface, actor and time last changed each key path) and serves it on the strict draft read; the save request declares its surface — the writer of #24298's key #24395]) moved with their imports.
  4. Gates: the dev reports (issuecomment 6587606305) 61/61 derived gates exit 0 with 0 NOT-MEASURED, the suite at 22,232 passed, 11/11 dependents typecheck, lint clean, and a clean codemod check before cutting and before opening. feat(spec): a save of a connector's served form drops a leftover undeclared auth key and names it #29456 and seat 3's metadata-protocol: a commit revert or package-commit rollback can restore a row bound to a read-only base package that the #28905 close now refuses to write #29390 branch merge clean against d3175d59d0 and sit outside the section. The seat readies the PR only when no check-run on this head is red or running.
  5. Out of scope: section 2 of E2 is a later step. The protocol.ts freeze lifts when this PR merges.
  6. Landing: pr_ready + automerge_enable through the relay.

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

Labels

documentation Improvements or additions to documentation size/xl tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant