Skip to content

feat(spec)!: retire the unserved Virtual ObjectQL request protocol (#27028) - #27324

Merged
os-zhuang merged 9 commits into
mainfrom
claude/project-thread-9f4fjb
Oct 29, 2026
Merged

os-zhuang merged 9 commits into
mainfrom
claude/project-thread-9f4fjb

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Yibo Wang · project thread
Fixes #27028

Ruling-ref: 6472013580
Claim: 6472028553
Clause-②: no (narrowing)
Metadata-protocol: narrowed
Skills-docs: none — REASON: skills/** names none of the retired exports (git grep for the 16 names on base: 0 hits; the _index.md files point at data-engine.zod.ts by its header line, which stays, and check:generated --fix left them unchanged). The one hand-written docs page that taught the protocol, content/docs/kernel/contracts/data-engine.mdx, is corrected in this diff.

维护者速读

  • 改了什么: 删除 data-engine.zod.ts 里没人用的「Virtual ObjectQL」远程请求协议,包括 DataEngineRequestSchema 和它的 9 个分支、DataEngineContractSchema、5 个类型和 5 个私有辅助。同时登记 10 条 RETIRED_DEFS_BY_MAJOR[18] 和一条 D3 条目 data-engine-rpc-protocol-retired,并修好文档页里还在教已退役 engine.batch?.() 的段落。
  • 为什么改: 按您在 [Decision] Retire the unserved "Virtual ObjectQL" wire protocol in data-engine.zod.ts (A), or keep it as a planned contract (B)? (#27028) #27274 上的裁决 A。这套协议在仓内和 hotcrm、objectui、docs.objectos.ai 里都没有读者。按发布出去的样子,它还允许调用方自带 isSystem,execute 分支能直传原始 SQL,留着就是一个假入口。
  • 风险与回滚: 运行时行为不变。只影响 TypeScript 导入(升级后报 TS2305)和 npm 包里那 10 个 json-schema/data/DataEngine*Request.json 文件。回滚就是 revert 本 PR,没有存量数据和 conversion 要处理。
  • 先看: packages/spec/src/migrations/entries/semantic/18.data-engine-rpc-protocol-retired.ts、packages/spec/src/data/data-engine.zod.ts(第 8 节和第 9 节末尾的说明)、packages/spec/src/data/data-engine-rpc-protocol-retirement.test.ts。
  • 两分钟验证: 运行 git grep -nE 'DataEngine(Find|FindOne|Insert|Update|Delete|Count|Aggregate|Execute|VectorFind)?Request(Schema|Parsed)?\b|DataEngineContractSchema' -- packages ui skills content ':!**/CHANGELOG.md',应该只剩退役登记、退役 pin 和说明性注释。
  • 需要您做的: 契约复审 PASS 后,请审批并合并(Tier H)。原因:docs/adr/0119 第 61 行锚定的 DataEngineRequest 被本 PR 删除,check:adr-symbol-anchors 要求修锚。1a50dca1e 保留名字,把锚改成文件级锚,并按该 ADR 自己 2026-08-05 的写法补一条带日期的编辑注。ADR 的决定本身没有改动。skills/*/references/_index.md 没有变化。

What changes

  • Spec (@objectstack/spec, minor, BREAKING for TypeScript imports and the published JSON Schema files only). packages/spec/src/data/data-engine.zod.ts loses:

    • the ten request schemas: DataEngineRequestSchema and its arms DataEngine{Find,FindOne,Insert,Update,Delete,Count,Aggregate,Execute,VectorFind}RequestSchema;
    • DataEngineContractSchema;
    • the types DataEngineRequest, DataEngineRequestParsed, DataEngineExecuteRequest, DataEngineInsertRequest and DataEngineVectorFindRequest;
    • the private helpers RpcQueryOptionsSchema, foldRpcQueryOptions, RpcLegacyFilterMixin, foldRpcLegacyFilter and RPC_WHERE_SLOT.

    Two in-file notes stand where the block stood: section 8, and the end of section 9 beside the older DataEngineBatchRequestSchema note, which they absorb. RPC_QUERY_ALIAS_SLOTS, foldQueryAliasSlots, aliasConflictIssue, every *OptionsSchema and the query-transport schemas stay. Route 3 of the spec-property-retirement kit (the spec(field): retire the @deprecated CurrencyValueSchema (still exported at field.zod.ts:581) — ADR-0104 D1 says deleted; prerequisite of the multi-currency epic #8345 #27182 and chore(spec): retire IDataEngine.batch? per ADR-0119 D3 — declared-but-unimplemented, zero callers #4618 precedent): no metadata source authors these shapes, so there is no retiredKey() tombstone and no D2 conversion.

  • ADR-0087: registered. Ten retired-defs/18.data__DataEngine*Request.ts files, plus the D3 semantic entry semantic/18.data-engine-rpc-protocol-retired.ts, which names the doors that exist: IDataEngine in process, ctx.api.object(name) in a hook or action body, the REST data routes and POST {basePath}/batch on the wire. The changeset carries the FROM → TO table and the registered data-engine-rpc-protocol-retired marker.

  • Generated and ledgers. json-schema.manifest/data.json loses 10 defs and authorable-surface/data.json 35 rows. The build required both deletions, deliberately; authorable-surface.base.json is untouched. Further moves: authorable-defaults/data.json −1, dropped-refinements.baseline.json −8 entries (measured totals 252 → 244 schemas, 900 → 892 sites), unemitted-schemas.baseline.json −1 (DataEngineContractSchema), docs-import-surface.baseline.json −6 and variant-docs.json −1 (the method: union). api-surface, export-origins, declaration-map, the reference page and index (1560 → 1550 schemas), the strictness-ledger counts and test-typecheck-debt.json were regenerated.

  • Pins that move. data-engine.test.ts drops the ten request suites, the two integration cases that parsed request literals, and the request rows of the spec: RpcQueryOptionsSchema.select and EngineQueryOptionsSchema.fields still admit an empty projection — decide ADR-0049 enforce-or-remove, then align with the shared projection rule (found reviewing #26909) #26954 projection-parity table. type-alias-convention.pin.test.ts drops three Iso_data_dataEngine__*RequestSchema rows, and its census goes 799 → 796 (header, title, toHaveLength with the history line).

  • New pin. packages/spec/src/data/data-engine-rpc-protocol-retirement.test.ts, listed in vitest.repo-tests.json, asserts five things:

    • the ten defs and the D3 entry are registered;
    • the eleven value exports are gone from /data and from the root entry;
    • the option bags and RPC_QUERY_ALIAS_SLOTS survive (the lit control);
    • nothing in the declared radius still uses a retired name (a tree-scoped absence walk);
    • the matcher catches real uses and ignores neighbours (an anti-vacuity test).
  • Docs and prose. content/docs/kernel/contracts/data-engine.mdx:

    • drops the DataEngineRequest import and the retired batch? member from its IDataEngine listing;
    • replaces the copyable engine.batch?.([...]) example with the real alternatives (IObjectQLEngine.transaction(cb), batchData with options.atomic, POST {basePath}/batch);
    • stops calling the legacy-alias normalizer "the RPC layer".

    Comment-only rewords where the retired names were cited: contracts/data-engine.ts, ui/view-grouping-query.ts, data-engine.zod.ts and packages/objectql/src/engine.ts (@objectstack/objectql patch). The two DEVELOPMENT_PLAN.md rows are struck through.

Why

The maintainer's ruling A on #27274 (record 6472013580): retire the block rather than keep it as a planned contract. The phase-1 measurement is on the decision card. It found zero readers in this repo outside packages/spec/src/data/ and zero in hotcrm 353dace, objectui b2c0ade and docs.objectos.ai cab35fd, against controls of 311, 2095 and 74 files that import @objectstack/spec. The one real cross-VM engine boundary (the QuickJS sandbox) uses a different shape, and the published JSON Schema admitted a caller-supplied context.isSystem and a raw-SQL execute arm.

Tests

  • New: data-engine-rpc-protocol-retirement.test.ts, 16 cases.
  • Moved: data-engine.test.ts (request suites removed; the option-bag and transport suites are unchanged) and type-alias-convention.pin.test.ts (census 796).

Acceptance notes

  • scripts/def-key-collisions.test.ts (--project repo) fails locally with MODULE_NOT_FOUND before reaching its guard. Its fixture symlinks packages/spec/node_modules into a tmp clone, and the pnpm .bin/tsx shim resolves a relative path that does not exist there. The failure sits in the fixture's tsx resolution, before the guard runs, and this diff touches neither the fixture, build-schemas.ts nor http.zod.ts. NOT MEASURED locally; Test Core runs it.
  • IDataEngine's doc comments still mention "remote/virtual engines" as hypothetical implementers that may omit optional members. That is about the TypeScript contract, not the retired protocol, so it is left as is.

Verification

Base origin/main a0aa8a1f3 (merged in); head 644adb1e7.

Build and generated artifacts (merged head)
  • pnpm --filter @objectstack/spec build → exit 0. Before that, the build refused three times as designed: the manifest lines, the unemitted-schemas entry and the 8 dropped-refinements entries.
  • pnpm --filter @objectstack/spec check:generated → exit 0, 14 of 14 fresh. No skills/*/references/_index.md moved.
Typecheck and tests
  • pnpm --filter @objectstack/spec typecheck → exit 0 (merged head).
  • pnpm --filter @objectstack/spec test → Test Files 748 passed (748), Tests 22293 passed | 1 todo (merged head).
  • pnpm --filter @objectstack/spec test:repo → 82 of 83 files passed, 1370 of 1371 tests. The one failure is def-key-collisions.test.ts (MODULE_NOT_FOUND, see Acceptance notes). The new pin passes: 32 of 33 in the targeted re-run on the merged head, the one failure again def-key-collisions.
  • pnpm --filter @objectstack/objectql typecheck → exit 0, after pnpm --filter '@objectstack/objectql^...' build.
  • Full dogfood (pnpm --filter @objectstack/dogfood test, final head 644adb1e7, after pnpm --filter '@objectstack/dogfood^...' build): Test Files 348 passed | 3 skipped (351), Tests 2806 passed | 20 skipped (2826). Lock verdict command-exit 0.
Derived gates (dispatch-gates --commands, 111 families)
  • 111 families run; 99 exited 0 on the first pass. The 11 that exited 3 (a prerequisite: dist predated an edited test file) and check:generated (stale dist, plus the test-typecheck ledger re-record) were re-run after a rebuild, and all exit 0.
  • check-adr-0087-registration --base origin/main → ✓ registered data-engine-rpc-protocol-retired (new here).
  • check-changeset-no-major --base origin/main → ✓ no major; the narrowing ships minor.
  • check:spec-parsed-alias, check:cross-package-test-inputs, check:variant-docs, check:doc-authoring, check:role-word, check:liveness, check:exported-any, check:dual-source-exports → exit 0.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic.
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes (CI-owned run).
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: its generated artifacts are regenerated and committed.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.
  • The Before Submitting list in CONTRIBUTING.md is done.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WGufziUAPh2YojDuNQpVXp


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · review owed · domain:spec seat 1 (#6017) · session session_01WGufzfhobWEgUUrjz4rrbh · 2026-10-28T16:58Z

Head 644adb1e7. Card #27028, maintainer decision #27274 (A, retire), claim 6472028553, dev report 6475233405.

  • Owed: a contract review at CONTRACT_REVIEW_TIER, narrowing face. The diff removes published packages/spec/src/** exports, and the changeset says Clause-②: no (narrowing). Scope is the whole diff outside the prose faces.
  • Who serves it: by the maintainer's standing word, this seat starts no contract review itself; the review waits for triage. The seat labels the PR needs:contract-review.
  • Landing: check-governed-merges --pr 27324: NOT governed, +517/−1458. The seat ACCEPTs at Tier S and arms once a same-form PASS is on file for the current head and CI is green.

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/objectql, @objectstack/spec, touching 28 documentable anchor(s). ⚠️ 26 changed file(s) yielded no anchor (packages/objectql/src/engine.ts, packages/spec/DEVELOPMENT_PLAN.md, packages/spec/api-surface/data.json, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

27 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 74801d190f5f528712ae3ebd9e4cbef81d3f13fe.

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

What this run could not see
  • 26 changed file(s) yielded no anchor (packages/objectql/src/engine.ts, packages/spec/DEVELOPMENT_PLAN.md, packages/spec/api-surface/data.json, …) — pages documenting those are invisible to this run
  • 1 anchor(s) matched too much of the corpus to be a work list: /data/:object (route, 72 pages)
  • 8 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 56 of 208 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 — 167 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 74801d190f5f528712ae3ebd9e4cbef81d3f13fe → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json 74801d190f5f528712ae3ebd9e4cbef81d3f13fe

⚠️ 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 74801d190f5f528712ae3ebd9e4cbef81d3f13fe → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…bol anchor (#27028)

`check:adr-symbol-anchors` reds once `DataEngineRequest` leaves
`data/data-engine.zod.ts`: ADR-0119's "Rot found on the way" anchored it
as `data-engine.zod.ts#DataEngineRequest`. The gate's remedy is to fix the
anchor, so the sentence keeps the name, points at the file, and an
editorial note (the record's own 2026-08-05 precedent) says the protocol
has since been retired and where it is registered. The finding itself is
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGufziUAPh2YojDuNQpVXp
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract-review-claim: session_01AavokzJ5DndAwitDXvKy4U · head 1a50dca1e895d6e93e82f7cc2623a339de477f5e · 2026-10-29T00:47Z

Triage seat, taking needs:contract-review on this head (#27062 (a)). The review runs at CONTRACT_REVIEW_TIER. If the lane claims or posts a record on this head first, triage withdraws.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 1a50dca1e895d6e93e82f7cc2623a339de477f5e
Local-runs: none
Scope: packages/spec/src/contracts/data-engine.ts, packages/spec/src/data/data-engine.zod.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineAggregateRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineCountRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineDeleteRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineExecuteRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineFindOneRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineFindRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineInsertRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineUpdateRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineVectorFindRequest.ts, packages/spec/src/migrations/entries/semantic/18.data-engine-rpc-protocol-retired.ts, packages/spec/src/ui/view-grouping-query.ts, docs/adr/0119-plugin-reachable-transactions-and-honest-atomic-batch.md + packages/spec/src/migrations/types.ts, packages/spec/scripts/build-migration-registry.ts, packages/spec/scripts/build-upgrade-guide.ts, packages/spec/scripts/build-schemas.ts, packages/spec/src/migrations/entries/semantic/17.data-engine-batch-retired.ts, packages/spec/src/migrations/entries/semantic/18.document-schemas-retired.ts, packages/spec/src/migrations/entries/retired-defs/18.data__Document.ts, packages/spec/src/api/batch.zod.ts, packages/rest/src/batch-routes.ts, packages/runtime/src/sandbox/quickjs-runner.ts, packages/metadata-protocol/src/protocol.ts, packages/spec/src/contracts/objectql-engine.ts, packages/spec/src/contracts/data-engine.test.ts, packages/spec/package.json, packages/spec/src/kernel/protocol-version.ts, packages/spec/src/data/data-engine-rpc-protocol-retirement.test.ts, packages/spec/src/data/data-engine.test.ts, packages/spec/authorable-surface.base.json, packages/spec/json-schema.manifest/data.json, scripts/check-adr-symbol-anchors.mjs, scripts/check-changeset-no-major.mjs, scripts/pm/check-governed-merges.mjs, scripts/cross-package-test-inputs.mjs, docs/audits/2026-07-unknown-key-strictness-ledger.md, content/docs/kernel/contracts/data-engine.mdx, .changeset/27028-data-engine-rpc-protocol-retired.md, AGENTS.md

Inputs read in full: card #27028 (body, triage 6459409175, claim 6472028553, dev report 6475233405), decision card #27274 (body, director 6471654872, ruling record 6472013580: maintainer chose A), PR #27324 body, file list (37 files), net diff vs main at this head (+520 / -1459), the three PR comments, and the 54 check-runs on 1a50dca1e895d6e93e82f7cc2623a339de477f5e: every one completed, 40 success, 14 skipped (matrix parents and opt-in lanes), none failure, none pending. The gate verdicts are green: Test Core (8 shards), TypeScript Type Check (all four gates), Lint & Repo Gates (all nine sub-lanes), Check Changeset, PR-body guards, Governed Surface Queue Guard, Spec property liveness, Build Core, Build Docs, Build & E2E UI, Type Check UI, Dogfood Regression Gate, Check Documentation Links. Head read with git show prr-27324:...; nothing built, run or re-run.

① Derived judgments

Every accept-set and public-surface change the diff implies, each judged against the head tree:

  1. @objectstack/spec/data and the root entry lose 11 value exports and 5 type exports — DataEngineRequestSchema, its nine DataEngine{Find,FindOne,Insert,Update,Delete,Count,Aggregate,Execute,VectorFind}RequestSchema arms, DataEngineContractSchema; types DataEngineRequest, DataEngineRequestParsed, DataEngineExecuteRequest, DataEngineInsertRequest, DataEngineVectorFindRequest. Right. This is exactly the set the maintainer's ruling A ([Decision] Retire the unserved "Virtual ObjectQL" wire protocol in data-engine.zod.ts (A), or keep it as a planned contract (B)? (#27028) #27274, 6472013580) retires, no more and no less. api-surface/data.json, export-origins/data.json and declaration-map/data.json shrink by the same names. A head-wide grep for the 16 names and the 5 private helpers (CHANGELOGs and content/docs/releases/ excluded) finds only the retirement kit, the new pin, prose notes, authorable-surface.base.json (see 6) and the chore(spec): retire IDataEngine.batch? per ADR-0119 D3 — declared-but-unimplemented, zero callers #4618 D3 entry's history sentence. ui/ has zero hits; skills/ has zero hits (so Skills-docs: none holds).
  2. The published JSON Schema loses 10 defs (data/DataEngineRequest and the nine arm defs): json-schema.manifest/data.json −10, and each def is registered in RETIRED_DEFS_BY_MAJOR[18] through one retired-defs/18.data__*.ts file whose filename and entry string agree under shardNameFor (/ → __, build-migration-registry.ts). Right: the manifest deletion gate (json-schema.manifest.json 的「deliberate removal」删行仍是纪律而非门禁 —— #4650 的同类洞,上移一层(整 schema 级) #4725, build-schemas.ts) requires exactly this declaration, and the build passed with it.
  3. The authorable-surface ratchet loses 35 keys over the nine arm defs (authorable-surface/data.json), authorable-defaults/data.json loses data/DataEngineVectorFindRequest:limit = 5. Right: the keys belonged to defs that no longer exist, the deletion is adjudicated by the retired-def registration, and the ledger row count moved under a Metadata-protocol: narrowed declaration, which is the only kind that may move it.
  4. Shrink-only ledgers shrink and never grow: dropped-refinements.baseline.json −8 entries (252 → 244 schemas, 900 → 892 sites), unemitted-schemas.baseline.json −1 (Data.DataEngineContractSchema), docs-import-surface.baseline.json −6, variant-docs.json −1 (the method: union). Right; every move is a removal of a row about a retired def.
  5. No runtime accept set changes. Nothing parsed the retired schemas (measured on the decision card and re-measured here: no parser or importer outside packages/spec/src/data/; the QuickJS sandbox speaks ctx.api.object(name), quickjs-runner.ts:17; the wire batch validates with CrossObjectBatchRequestSchema / BatchUpdateRequestSchema, rest/src/batch-routes.ts:243,442). RPC_QUERY_ALIAS_SLOTS, QUERY_TRANSPORT_ALIAS_SLOTS, foldQueryAliasSlots, aliasConflictIssue, QueryTransportParamsSchema, QueryWithTransportSchema and every *OptionsSchema stay, and QueryWithTransportSchema still folds by the table (data-engine.zod.ts:1025). Right: the retirement removes a declaration, not a behaviour.
  6. authorable-surface.base.json is untouched and still carries the 35 rows. Right by that file's own header: it is the deletion gate's pinned anchor at baseRev, "written only by gen:schema, only from a git-resolved baseline — never from the build that is being checked"; a PR that edited it to hide a deletion would go red. The spec(field): retire the @deprecated CurrencyValueSchema (still exported at field.zod.ts:581) — ADR-0104 D1 says deleted; prerequisite of the multi-currency epic #8345 #27182 precedent (data/Document*, 4 rows still in the anchor) followed the same path.
  7. @objectstack/objectql: one comment moves (engine.ts:600-601, RpcQueryOptionsSchema → QueryWithTransportSchema). No surface change. Right: QueryWithTransportSchema is the schema that folds the four non-engine alias pairs at parse (data-engine.zod.ts:1291-1299).
  8. ADR-0087 chain: one D3 semantic entry data-engine-rpc-protocol-retired in major 18 (PROTOCOL_VERSION = '18.0.0', protocol-version.ts:22), no D2 conversion, no retiredKey() tombstone. Right: route 3 of spec-property-retirement as ruled; no metadata source authors these shapes (the keys were never under a stack.zod.ts key or a registered type) so a tombstone would prescribe through a parse that never runs. Same shape as 17.data-engine-batch-retired and 18.document-schemas-retired.

② Semver level

  • Changeset .changeset/27028-data-engine-rpc-protocol-retired.md: @objectstack/spec: minor, @objectstack/objectql: patch; Clause-②: no (narrowing); Metadata-protocol: narrowed; marker adr-0087: registered data-engine-rpc-protocol-retired; a BREAKING banner, a FROM → TO table covering all 16 names, and the one-line fix (TS2305 after upgrade). The PR body carries the same two declaration lines.
  • Level matches what the diff publishes. Under ruling A of 2026-10-21 (mechanized in check-changeset-no-major.mjs, "The LEVEL axis"), the level follows the Metadata-protocol: kind alone: narrowed requires at least one moved package at minor or above (spec, minor: met); major is refused in the launch window and ADR-0087 lets the pre-GA break land one-step as a chain step (the D3 entry: present). objectql patch is right for a comment-only edit in a published package. authorable-surface/ and authorable-defaults/ shards moved, which rules out none; narrowed is the kind for a key removed. Check Changeset, Lint · PM dispatch-gates and Lint · repo & tooling gates are green on this head.
  • Clause-②: line. no (narrowing) is the spelling this review's own face is cut on (the record shape names it as the narrowing face) and the one the gates read: the (narrowing) arm is the ADR-0087 breaking signal (check-adr-0087-registration.mjs:718), and narrowed beside a line without that arm is a contradiction the level gate refuses. The spelling is the repo's established one for an accept-set or export narrowing (packages/spec/CHANGELOG.md:88,143,162,9945; pending .changeset/26954-engine-projection-empty.md). The decision card's draft wrote yes (narrowing); the claim, the director's workload line and the PR all wrote no (narrowing). The arm, not the yes/no, is what every reader consumes, so the discrepancy is immaterial to the verdict; noted for the record.
  • skip-changeset is not involved. The feat(spec)!: title carries the breaking marker. PASS on ②.

③ Boundary flags

Dev flags (report 6475233405, PR body "Acceptance notes"), each answered or escalated:

  1. scripts/def-key-collisions.test.ts NOT MEASURED locally (MODULE_NOT_FOUND in the fixture's tsx shim). Answered by the gate: Test Core (all 8 shards) is success on this head, and turbo run test test:repo is what those shards run (ci.yml:1253), so the repo-project suite including this test and the new pin ran green in CI. No local re-run is owed.
  2. IDataEngine doc comments still say "remote/virtual engines" as hypothetical implementers that may omit optional members. Answered: lines 354, 369, 404, 516 of contracts/data-engine.ts are about optional-member TypeScript posture, not the retired wire protocol, and may stand. But lines 172-173 of the same file still read "nothing here crosses the RPC / Virtual Data Engine boundary" — the exact phrase this PR rewrote at line 61. That is a stale reference to the retired protocol inside a hits file; see ④.1 (should-fix).
  3. open_questions: [] — none to answer.
  4. Tier. The seat's 席位核对 (6475302405, head 644adb1e7) found check-governed-merges --pr 27324 NOT governed and ACCEPTed at Tier S. That reading predates 1a50dca1e, which edits docs/adr/0119-...md. docs/adr/** is a GOVERNED_TIER_H register row (check-governed-merges.mjs:1201), and one Tier H path makes the whole PR Tier H (AGENTS.md Prime Directive 14). The PR body says so (“请审批并合并(Tier H)”). Escalated: landing on this head is the maintainer's hand or an authorized APPROVED review; the seat's Tier S ACCEPT is stale on this head and must not arm the queue. This record is the contract-tier review the Tier H landing also wants; it does not substitute for the maintainer's approval. Governed Surface Queue Guard is green (it guards the queue, not the landing).
  5. PR is still a draft (draft: true, mergeable_state: clean). Not a contract matter; the lane seat marks it ready when the record is on file.
  6. Third-party npm consumers UNMEASURED. Stated in the D3 reason and on the decision card; the maintainer ruled A with that stated. Accepted as declared, not re-opened.
  7. Skills-docs: none. Verified: zero hits for the 16 names under skills/** on the head; no _index.md moved (the file list has none).
  8. Outside hits, for the lane seat (not reviewed here, read only): docs/audits/2026-07-unknown-key-strictness-ledger.md:718 is the hand-written row whose arithmetic the regenerated counts file (data-engine.zod.ts 16 → 6 sites) now summarizes; its note still reads "engine contract shapes (was 14 — DataEngineBatchRequestSchema retired …, chore(spec): retire IDataEngine.batch? per ADR-0119 D3 — declared-but-unimplemented, zero callers #4618)" and does not mention that ten more sites left with spec: the Virtual Data Engine wire protocol block (DataEngineRequestSchema and its arms) has zero readers — decide ADR-0049 enforce-or-remove; its note says "tracked separately" but nothing tracks it #27028. The ratchet test passed, so nothing is red; a one-clause note on that row would keep the ledger's prose honest. Lane remainder, should-fix at most.

④ Design judgment

Each hits file, judged against the code it cites and the scenario it is accepted against (ruling A on #27274; the published spec on main; its first consumer).

  1. packages/spec/src/contracts/data-engine.ts (comment-only, line 61). Holds: WriteObservabilityOptions is a TS-contract-only bag; "a function is unrepresentable in JSON Schema and cannot be serialized, so remote callers (REST, the client SDK) simply never receive these events" is true of the tree (the serializable bags are Engine*OptionsSchema; REST and the client SDK are the remote callers that exist). Tried to break it: searched the file for every other naming of the retired boundary. Should-fix: lines 172-173 (strictReadonlyWrites docblock, "In-process only — what a REMOTE caller observes") still say "crosses the RPC / Virtual Data Engine boundary or is reachable from a REST/wire body". With the protocol retired in this same PR there is no RPC / Virtual Data Engine boundary in the spec to cross; the sentence should read as line 61 now does ("cannot be serialized … REST/wire body"). Same class as the edit the PR made, one occurrence missed; no behaviour, no export, no gate touched. Not a must-fix.
  2. packages/spec/src/data/data-engine.zod.ts. The deletion is exactly the ruled set; every surviving neighbour the arms depended on is still consumed (aliasConflictIssue and foldQueryAliasSlots by QueryWithTransportSchema, transportProjectionArray by DataEngineQueryOptionsSchema.select:219 and the transport dialect, FilterConditionSchema by the filter schemas). The section-8 note's claims about DataEngineContractSchema hold against the deleted code and the contract: its find/findOne/count inputs were [string, Options?] with no trailing options?: BaseEngineOptions (IDataEngine.find:301, count:322), it declared neither vectorFind? (:328) nor execute? (:343), and it never emitted (unemitted-schemas.baseline.json, cause function). The section-9 note names the doors that exist, each verified: QuickJS sandbox ctx.api.object(name) (quickjs-runner.ts:17), wire batch via CrossObjectBatchRequestSchema / BatchUpdateRequestSchema (batch-routes.ts:243,442). The spec: RpcQueryOptionsSchema.select and EngineQueryOptionsSchema.fields still admit an empty projection — decide ADR-0049 enforce-or-remove, then align with the shared projection rule (found reviewing #26909) #26954 projection comment is corrected to the two engine-side declarations that remain. The RPC_QUERY_ALIAS_SLOTS docblock now points at QueryWithTransportSchema and QUERY_TRANSPORT_ALIAS_SLOTS (:750, which extends the table with filters / $filter / $expand): true. The word "RPC" survives only in the table's name and its two-line description, which the ruling kept by name. Tried to break it: does anything author these shapes (stack key, registered type, Studio form, CLI)? No — the keys were in the authorable ratchet only because the schema was published, not because any carrier reached them; so route 3 (no tombstone) is the right route and a retiredKey() here would be unreachable noise. No finding.
  3. The ten retired-defs/18.data__DataEngine*Request.ts files. Filename ↔ entry string agree under shardNameFor; major 18 is the current protocol major; each def is one the manifest on main published and this diff removes (ten manifest lines removed, ten entries added; data/DataEngineRequest plus nine arms, none missing, none extra). The header note states the ruling, the measurement trees and the route. First consumer (build-schemas.ts manifest deletion gate, json-schema.manifest.json 的「deliberate removal」删行仍是纪律而非门禁 —— #4650 的同类洞,上移一层(整 schema 级) #4725) accepted them: build green. No finding.
  4. semantic/18.data-engine-rpc-protocol-retired.ts. Conforms to SemanticMigration (id, surface, replacement, reason, acceptanceCriteria; conversionIds and relevantWhen omitted, as in the two precedents and as types.ts prescribes for a surface not under stack keys). surface carries no backticks and no pipe, which build-upgrade-guide.ts:135 needs (it renders surface inside a code span). replacement names only doors that exist: IDataEngine at @objectstack/spec/contracts (package.json exports ./contracts), ctx.api.object(name).find(...), REST /data/:object and POST /data/:object/query (metadata-protocol/protocol.ts:4884), POST {basePath}/batch with the two batch schemas; "DataEngineContractSchema has no replacement schema: the engine contract is the IDataEngine interface" is true. acceptanceCriteria is checkable and is checked (the new pin asserts TS2305 is named, the defs are absent from the manifest, and the lit controls survive). Should-fix (prose precision, not a prescription change): reason says "every arm admitted a caller-supplied context (isSystem included)". Against the deleted code, seven of the nine arms did (their query / options bags extend BaseEngineOptionsSchema, whose context: ExecutionContextSchema.partial().optional(), :76); execute carried an untyped options record and vectorFind carried vector / where / fields / limit / threshold and no context at all. The decision card's wording ("every read and write arm") was exact; the entry and the changeset generalize it to "every arm". The judgment the upgrader owes does not change, so this is a should-fix in a load-bearing prose field, not a must-fix.
  5. packages/spec/src/ui/view-grouping-query.ts (comment-only). "in process the same body is IDataEngine.aggregate's EngineAggregateOptions" holds: aggregate(objectName: string, query: EngineAggregateOptions, options?: BaseEngineOptions) (contracts/data-engine.ts:323). The route it still names (client.data.query() → the hasGroupBy || hasAggregations branch) is unchanged by this PR. No finding.
  6. docs/adr/0119-plugin-reachable-transactions-and-honest-atomic-batch.md. The edit replaces one path#DataEngineRequest symbol anchor, which this PR makes unresolvable, with a file-level anchor on packages/spec/src/data/data-engine.zod.ts (the [unresolved-symbol] remedy check-adr-symbol-anchors.mjs itself prescribes when the symbol is gone), and adds a dated editorial note in the ADR's own 2026-08-05 style, naming the registering entry by path (a second file-level anchor, resolving). The decision (D3: batch? retired) is unchanged, and its first consumer agrees: contracts/data-engine.ts:330-338 records batch? as retired under ADR-0119 D3 and points at the same three replacements the D3 entry and the kernel docs page now name (IObjectQLEngine.transaction, objectql-engine.ts:533; batchData options.atomic, protocol.ts:14577; POST {basePath}/batch). The other anchors on the edited paragraph still resolve (IDataEngine, packages/spec/src/contracts/data-engine.test.ts exists). Lint · docs & code guards (which runs check:adr-symbol-anchors, lint.yml:2425) is green. Not re-deciding anything, no new rule: a maintenance edit to a Tier H surface, correct as written. No finding.

Must-fix findings: none. Should-fix: ④.1 (one stale "RPC / Virtual Data Engine boundary" sentence at contracts/data-engine.ts:172-173), ④.4 ("every arm" → "every read and write arm" in the D3 reason and the changeset), ③.8 (the strictness ledger's hand-written row note, lane remainder).

Implemented-by: claude/project-thread-9f4fjb
Reviewed-by: session_01AavokzJ5DndAwitDXvKy4U

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · domain:spec seat 1 (#6017) · session session_01WGufzfhobWEgUUrjz4rrbh · 2026-10-29T01:10Z

Head 1a50dca1e895d6e93e82f7cc2623a339de477f5e. Card #27028, maintainer decision #27274 (A, retire, 6472013580), claim 6472028553, dev report 6475233405. This supersedes the seat's note 6475302405 at 644adb1e7, which named Tier S.

  • Contract review: owed at CONTRACT_REVIEW_TIER, narrowing face. Record 6485025305 at this head is a PASS with no must-fix. The retired set is exactly the ruled one: 11 value exports, 5 type exports and 10 manifest defs, each registered in RETIRED_DEFS_BY_MAJOR[18]. The ratchets and ledgers only shrink, and no runtime accept set changes. The no (narrowing) / narrowed / spec minor declarations match what the diff publishes. Route 3 (one D3 entry, no D2, no tombstone) is right for shapes no carrier authors. The ADR-0119 edit is a maintenance anchor fix that check:adr-symbol-anchors prescribes, with the decision unchanged.
  • Should-fixes: ④.1 (a stale "RPC / Virtual Data Engine boundary" sentence at contracts/data-engine.ts:172-173), ④.4 ("every arm" should read "every read and write arm" in the D3 reason and the changeset) and ③.8 (the strictness-ledger row note). All three are prose. The seat routes them to follow-up [finding] three prose should-fixes from the Virtual ObjectQL protocol retirement review (PR #27324): a stale "RPC / Virtual Data Engine boundary" docblock, "every arm" in the D3 reason, and the strictness-ledger row note #27346, to land after this PR, instead of pushing here. A push would move the head off this PASS and owe a delta re-review while the PR waits on a governed approval.
  • Delta since 644adb1e7: 1a50dca1e fixes the ADR-0119 L61 symbol anchor. It is now file-level, with a dated editorial note in the ADR's 2026-08-05 style, because the PR deletes DataEngineRequest. This is what made Lint · docs & code guards red on 644adb1e7. The seat updated the body's 维护者速读 line to ask for the Tier H merge.
  • Dev readings: build, check:generated 14/14, typecheck, spec test 748/748 files, the 111 derived gates and full dogfood (348 files, 2806 tests passed) are all green. The one local red, def-key-collisions.test.ts, is from the tsx shim in the worktree install, and that file is green in CI (Test Core 8/8).
  • Gates: check-runs on this head are 40 success, 14 skipped and 0 red, per the review's read. mergeable_state is clean.
  • Landing: check-governed-merges --pr 27324: GOVERNED (1 of 37 paths, docs/adr/**), +520/−1459. Tier H. The seat neither flips it ready nor arms it. It lands by the maintainer's hand, or through an APPROVED review from a governed approver, after which this seat arms it. The seat removes needs:contract-review now that a same-form PASS is on file for this head.

Conflicts: type-alias-convention.pin.test.ts (census 799 -> 798 from
#27182 stacks with this branch's -3: 795, both history lines kept),
vitest.repo-tests.json (both new pins, sorted). Generated references
index and strictness-ledger counts take main's side and are regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGufziUAPh2YojDuNQpVXp
os-regen-merge step 4. The driver took main's side of the five data
shards both sides moved; the hand-kept json-schema.manifest and
authorable-surface deletions are re-applied from this branch, and
check:generated --fix regenerates api-surface, export-origins,
declaration-map, the references index (1559 -> 1549) and the
strictness-ledger counts on top of main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGufziUAPh2YojDuNQpVXp
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · domain:spec seat 1 (#6017) · session session_01WGufzfhobWEgUUrjz4rrbh · 2026-10-29T02:17Z

Head 609a2715b06aac84ac1709d7b8144c8b92f010e9. Card #27028. This supersedes the seat's ACCEPT 6485073139 at 1a50dca1e.

@os-zhuang
os-zhuang added this pull request to the merge queue Oct 29, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract-review-claim: session_01AavokzJ5DndAwitDXvKy4U · head 609a2715b06aac84ac1709d7b8144c8b92f010e9 · 2026-10-29T02:54Z

Triage seat, under gap rule (b) (#27062): this head is over 60 minutes old with no record and no claim; a delta re-review from triage's PASS on 1a50dca1. The review runs at CONTRACT_REVIEW_TIER. If the lane claims or posts a record on this head first, triage withdraws.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 609a2715b06aac84ac1709d7b8144c8b92f010e9
Local-runs: none
Scope: packages/spec/src/contracts/data-engine.ts, packages/spec/src/data/data-engine.zod.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineAggregateRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineCountRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineDeleteRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineExecuteRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineFindOneRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineFindRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineInsertRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineUpdateRequest.ts, packages/spec/src/migrations/entries/retired-defs/18.data__DataEngineVectorFindRequest.ts, packages/spec/src/migrations/entries/semantic/18.data-engine-rpc-protocol-retired.ts, packages/spec/src/ui/view-grouping-query.ts, docs/adr/0119-plugin-reachable-transactions-and-honest-atomic-batch.md + packages/spec/src/migrations/types.ts, packages/spec/scripts/build-migration-registry.ts, packages/spec/scripts/build-upgrade-guide.ts, packages/spec/scripts/build-schemas.ts, packages/spec/src/migrations/entries/semantic/17.data-engine-batch-retired.ts, packages/spec/src/api/batch.zod.ts, packages/rest/src/batch-routes.ts, packages/runtime/src/sandbox/quickjs-runner.ts, packages/metadata-protocol/src/protocol.ts, packages/spec/src/contracts/objectql-engine.ts, packages/spec/src/contracts/data-engine.test.ts, packages/spec/src/kernel/protocol-version.ts, packages/spec/src/data/data-engine-rpc-protocol-retirement.test.ts, packages/spec/src/data/data-engine.test.ts, packages/spec/src/type-alias-convention.pin.test.ts, packages/spec/vitest.repo-tests.json, packages/spec/authorable-surface.base.json, packages/spec/json-schema.manifest/data.json, packages/spec/authorable-surface/data.json, packages/spec/api-surface/data.json, packages/spec/export-origins/data.json, packages/spec/declaration-map/data.json, content/docs/references/index.mdx, docs/audits/2026-07-unknown-key-strictness-ledger.counts/data.md, docs/audits/2026-07-unknown-key-strictness-ledger.md, scripts/check-adr-symbol-anchors.mjs, scripts/pm/check-governed-merges.mjs, content/docs/kernel/contracts/data-engine.mdx, .changeset/27028-data-engine-rpc-protocol-retired.md

Re-review on a moved head. Triage's prior record (6485025305, PASS at 1a50dca1e895d6e93e82f7cc2623a339de477f5e) is the baseline; this is a fresh, full record on 609a2715b06aac84ac1709d7b8144c8b92f010e9.

Inputs read in full: card #27028 (body, triage 6459409175, claim 6472028553, dev report 6475233405), the ruling record on decision card #27274 (6472013580: maintainer chose A, retire, D3-registered spec minor in protocol 18, no tombstone, no conversion, the kernel docs batch? section fixed in the same PR), PR #27324 body, its 37-path file list, the net diff vs main at this head (+520 / −1459; git diff b8f4acc26a..609a2715b0 is byte-identical to the fetched net.diff, and the merge-base of the head with origin/main is b8f4acc26a), all seven PR comments (including the lane's rework notes 6485073139 and 6486064326, read as claims), follow-up #27346 (open; carries the three prior should-fixes), and the 50 check-runs on this head: every one completed, 41 success, 9 skipped (matrix parents and opt-in lanes), none failure, none pending. Green on this head: Test Core (8 of 8 shards), TypeScript Type Check (workspace, source, consumer, debt ledger), Lint & Repo Gates (ESLint; CI, release & engine gates; PM dispatch-gates; docs & code guards; repo & tooling gates; three scoped lanes), Check Changeset, PR-body guards, Governed Surface Queue Guard, Spec property liveness, Build Core, Build Docs, Build & E2E UI, Live E2E UI, Type Check UI, Test UI, Dogfood Regression Gate, Check Documentation Links, Check PR Size. Head read with git show prr-27324:...; nothing built, run or re-run.

The delta, commit by commit (1a50dca1e → 609a2715b), with the merge recomputed:

① Derived judgments

Every accept-set and public-surface change the diff implies, each judged against the head tree:

  1. @objectstack/spec/data and the root entry lose 11 value exports and 5 type exports — DataEngineRequestSchema, the nine DataEngine{Find,FindOne,Insert,Update,Delete,Count,Aggregate,Execute,VectorFind}RequestSchema arms, DataEngineContractSchema; types DataEngineRequest, DataEngineRequestParsed, DataEngineExecuteRequest, DataEngineInsertRequest, DataEngineVectorFindRequest. Right. Exactly the set ruling A ([Decision] Retire the unserved "Virtual ObjectQL" wire protocol in data-engine.zod.ts (A), or keep it as a planned contract (B)? (#27028) #27274, 6472013580) retires. api-surface/data.json, export-origins/data.json, declaration-map/data.json shrink by the same names. A head-wide grep for the 16 names and the 5 private helpers (CHANGELOGs and content/docs/releases/ excluded) finds only the retirement kit, the new pin, authorable-surface.base.json (see 6), the changeset, prose notes in data-engine.zod.ts:578,1337,1348, data-engine.test.ts:610, DEVELOPMENT_PLAN.md:313-314 (struck through), ADR-0119:61,63, the 17.data-engine-batch-retired history sentence and the pending .changeset/26954-engine-projection-empty.md (history prose). The 15 commits merged from main since the prior head brought no new reader: ui/ zero hits, skills/ zero hits (Skills-docs: none holds).
  2. The published JSON Schema loses 10 defs (data/DataEngineRequest and the nine arms): the manifest on the head has zero DataEngine*Request lines, and each def is registered in RETIRED_DEFS_BY_MAJOR[18] by one retired-defs/18.data__*.ts whose filename and entry string agree under shardNameFor (all ten read; exactly ten files name 'data/DataEngine…', no duplicate across the major-18 directory, which now also holds spec(field): retire the @deprecated CurrencyValueSchema (still exported at field.zod.ts:581) — ADR-0104 D1 says deleted; prerequisite of the multi-currency epic #8345 #27182's and other entries). Right: the manifest deletion gate (build-schemas.ts, json-schema.manifest.json 的「deliberate removal」删行仍是纪律而非门禁 —— #4650 的同类洞,上移一层(整 schema 级) #4725) requires this declaration and Build Core is green on the head.
  3. The authorable-surface ratchet loses 35 keys over the nine arm defs; authorable-defaults/data.json loses data/DataEngineVectorFindRequest:limit = 5. Right: keys of defs that no longer exist, adjudicated by the retired-def registration, under Metadata-protocol: narrowed, the only kind that may move the row count.
  4. Shrink-only ledgers shrink and never grow: dropped-refinements.baseline.json −8 (252 → 244 schemas, 900 → 892 sites), unemitted-schemas.baseline.json −1 (Data.DataEngineContractSchema), docs-import-surface.baseline.json −6, variant-docs.json −1, test-typecheck-debt.json re-recorded. Right; every move removes a row about a retired def.
  5. No runtime accept set changes. Nothing parsed the retired schemas (no parser or importer outside packages/spec/src/data/ on the head; the QuickJS sandbox speaks ctx.api.object(name), quickjs-runner.ts:17; the wire batch validates with CrossObjectBatchRequestSchema / BatchUpdateRequestSchema, rest/src/batch-routes.ts:243-244,442-444). BaseEngineOptionsSchema:60, DataEngineQueryOptionsSchema:215, RPC_QUERY_ALIAS_SLOTS:629, foldQueryAliasSlots:663, aliasConflictIssue:693, QUERY_TRANSPORT_ALIAS_SLOTS:750, QueryTransportParamsSchema:936, QueryWithTransportSchema:1299 all stay. Right: a declaration leaves, no behaviour does.
  6. authorable-surface.base.json is untouched (git diff b8f4acc26a prr-27324 -- …base.json is empty) and still carries the 35 rows. Right by that file's own contract: it is the deletion gate's pinned anchor at baseRev, written only by gen:schema from a git-resolved baseline.
  7. @objectstack/objectql: one comment moves (engine.ts, RpcQueryOptionsSchema → QueryWithTransportSchema). No surface change. Right.
  8. ADR-0087 chain: one D3 semantic entry in major 18 (PROTOCOL_VERSION = '18.0.0', protocol-version.ts:22), no D2 conversion, no retiredKey() tombstone. Right: route 3 as ruled; no metadata source authors these shapes. Same shape as 17.data-engine-batch-retired and 18.document-schemas-retired.
  9. Generated counts on the moved base: references/index.mdx 1559 → 1549 and the strictness counts 164 → 154 are what regeneration on b8f4acc26a produces (the −10 is this PR's; the −1 under it is spec(field): retire the @deprecated CurrencyValueSchema (still exported at field.zod.ts:581) — ADR-0104 D1 says deleted; prerequisite of the multi-currency epic #8345 #27182's and lives on main). Right; check:generated runs inside the green Lint & Repo Gates / Build Core lanes.

② Semver level

  • Changeset .changeset/27028-data-engine-rpc-protocol-retired.md (unchanged on this head): @objectstack/spec: minor, @objectstack/objectql: patch; Clause-②: no (narrowing); Metadata-protocol: narrowed; marker adr-0087: registered data-engine-rpc-protocol-retired; BREAKING banner; FROM → TO table covering all 16 names; the one-line fix (TS2305 after upgrade). The PR body carries the same two declaration lines.
  • Level matches what the diff publishes. Under ruling A of 2026-10-21 (check-changeset-no-major.mjs), the level follows the Metadata-protocol: kind: narrowed requires a moved package at minor or above (spec minor: met); major is refused in the launch window and ADR-0087 lets the pre-GA break land as a chain step (the D3 entry: present). objectql patch is right for a comment-only edit in a published package. authorable-surface/ and authorable-defaults/ shards moved, which rules out none. Check Changeset, Lint · PM dispatch-gates and Lint · repo & tooling gates are green on this head. Both .changeset/27028-… and main's .changeset/27182-currency-value-schema-retired.md now coexist on the head; distinct ids, distinct markers, no collision.
  • Clause-②: line. no (narrowing): the (narrowing) arm is the ADR-0087 breaking signal the gates read, narrowed beside it is consistent, and the spelling is the repo's established one (packages/spec/CHANGELOG.md; pending .changeset/26954-engine-projection-empty.md). skip-changeset is not involved. The feat(spec)!: title carries the breaking marker. PASS on ②.

③ Boundary flags

Dev flags (report 6475233405, PR body "Acceptance notes"), the lane's rework notes, and the prior record's should-fixes, each answered or escalated:

  1. scripts/def-key-collisions.test.ts NOT MEASURED locally (MODULE_NOT_FOUND in the fixture's tsx shim). Answered by the gate: Test Core, all 8 shards, success on this head; the repo-project suite including this test and the new pin ran green in CI.
  2. IDataEngine doc comments still say "remote/virtual engines" (contracts/data-engine.ts:354,369,404,516). Answered: optional-member TypeScript posture, not the retired wire protocol; may stand.
  3. open_questions: [] — none to answer.
  4. Tier. docs/adr/** is a GOVERNED_TIER_H register row (check-governed-merges.mjs:417), and this PR edits docs/adr/0119-…md, so the PR is Tier H. The lane's ACCEPT 6486064326 names Tier H and does not arm. Escalated, as before: landing is the maintainer's hand or an authorized APPROVED review; this record is the contract-tier review that landing wants and does not substitute for the approval. Governed Surface Queue Guard is green on this head. The PR is no longer a draft (draft: false, mergeable_state: clean).
  5. The moved head itself. The lane says the queue dropped the PR on MERGE_CONFLICT with feat(spec)!: retire the never-consumed CurrencyValueSchema / CurrencyValue export (ADR-0104 D1) #27233 (spec(field): retire the @deprecated CurrencyValueSchema (still exported at field.zod.ts:581) — ADR-0104 D1 says deleted; prerequisite of the multi-currency epic #8345 #27182) and the dev merged main with os-regen-merge.sh, no rebase. Verified in the tree: three commits, one true merge with two parents, recomputed with merge-tree (see the delta section); no hunk of this PR moved except by base-driven counts. The lane's "merge-only exception" reading is confirmed on the evidence, not on the note.
  6. Prior should-fix ④.1 (stale "crosses the RPC / Virtual Data Engine boundary" at contracts/data-engine.ts:172-173): not resolved on this head; the sentence reads verbatim as before. Routed by the lane to follow-up [finding] three prose should-fixes from the Virtual ObjectQL protocol retirement review (PR #27324): a stale "RPC / Virtual Data Engine boundary" docblock, "every arm" in the D3 reason, and the strictness-ledger row note #27346 (open, read via GET; it names all three findings and the reason for not pushing here). Remains should-fix.
  7. Prior should-fix ④.4 ("every arm admitted a caller-supplied context" in the D3 reason and the changeset): not resolved; both texts are verbatim. The deleted code on the diff confirms the imprecision: DataEngineVectorFindRequestSchema carried vector / where / fields / limit / threshold and no context; DataEngineExecuteRequestSchema carried command and an untyped options record. Seven of nine arms (the read and write arms, which extend BaseEngineOptionsSchema with context: ExecutionContextSchema.partial().optional(), :76) did. Routed to [finding] three prose should-fixes from the Virtual ObjectQL protocol retirement review (PR #27324): a stale "RPC / Virtual Data Engine boundary" docblock, "every arm" in the D3 reason, and the strictness-ledger row note #27346. Remains should-fix.
  8. Prior should-fix ③.8 (the hand-written strictness-ledger row 2026-07-unknown-key-strictness-ledger.md:718, "was 14 — DataEngineBatchRequestSchema retired …, chore(spec): retire IDataEngine.batch? per ADR-0119 D3 — declared-but-unimplemented, zero callers #4618", which does not mention the ten more sites that left with spec: the Virtual Data Engine wire protocol block (DataEngineRequestSchema and its arms) has zero readers — decide ADR-0049 enforce-or-remove; its note says "tracked separately" but nothing tracks it #27028): not resolved; the file is not in the diff. The regenerated counts (data-engine.zod.ts 16 → 6) are right and the ratchet test is green. Lane remainder; routed to [finding] three prose should-fixes from the Virtual ObjectQL protocol retirement review (PR #27324): a stale "RPC / Virtual Data Engine boundary" docblock, "every arm" in the D3 reason, and the strictness-ledger row note #27346.
  9. Third-party npm consumers UNMEASURED. Stated in the D3 reason and on the decision card; the maintainer ruled A with that stated. Accepted as declared.
  10. Skills-docs: none. Verified on the head: zero hits for the 16 names under skills/**; no _index.md in the file list.

④ Design judgment

Each hits file is byte-identical to the prior head's version, so the judgments below are re-read against the head tree (which now includes 15 more main commits) rather than re-derived from scratch; every line citation was re-resolved on prr-27324.

  1. packages/spec/src/contracts/data-engine.ts (comment-only, line 61). Holds: WriteObservabilityOptions is a TS-contract-only bag; "a function is unrepresentable in JSON Schema and cannot be serialized, so remote callers (REST, the client SDK) simply never receive these events" is true of the tree. Should-fix (carried): lines 172-173 (strictReadonlyWrites docblock) still say "crosses the RPC / Virtual Data Engine boundary or is reachable from a REST/wire body"; with the protocol retired in this PR there is no RPC / Virtual Data Engine boundary in the spec. One occurrence of the class the PR edited at line 61, missed; no behaviour, export or gate touched. Line 92 ("cross the RPC boundary") is the same class, same weight, and belongs on [finding] three prose should-fixes from the Virtual ObjectQL protocol retirement review (PR #27324): a stale "RPC / Virtual Data Engine boundary" docblock, "every arm" in the D3 reason, and the strictness-ledger row note #27346 beside it. Not a must-fix.
  2. packages/spec/src/data/data-engine.zod.ts. The deletion is exactly the ruled set; every surviving neighbour the arms depended on is still consumed (aliasConflictIssue and foldQueryAliasSlots by QueryWithTransportSchema:1299; transportProjectionArray by DataEngineQueryOptionsSchema.select and the transport dialect; FilterConditionSchema by the filter schemas). The section-8 note (:574-584) holds against the deleted DataEngineContractSchema and the contract: IDataEngine.find:301 and count:322 take a trailing options?: BaseEngineOptions the contract schema lacked; it declared neither vectorFind? (:328) nor execute? (:343); it never emitted (unemitted-schemas.baseline.json, cause function). The section-9 note (:1337-1360) names the doors that exist, each verified on the head: QuickJS sandbox ctx.api.object(name) (quickjs-runner.ts:17); wire batch via CrossObjectBatchRequestSchema / BatchUpdateRequestSchema from ../api/batch.zod.ts (batch-routes.ts:243,442). "every arm admitted a caller-supplied context" here is the same imprecision as ④.4 (seven of nine arms); should-fix, same follow-up. The RPC_QUERY_ALIAS_SLOTS docblock points at QueryWithTransportSchema and QUERY_TRANSPORT_ALIAS_SLOTS (:750): true. Tried to break the route: does anything author these shapes (stack key, registered type, Studio form, CLI)? No; the keys were in the authorable ratchet only because the schema was published. Route 3 (no tombstone) stands. No must-fix.
  3. The ten retired-defs/18.data__DataEngine*Request.ts files. Filename ↔ entry string agree for all ten (listed above); major 18 is the current protocol major; each def is one the manifest on main publishes and this diff removes (ten manifest lines removed, ten entries added, none missing, none extra); no other retired-def file names a data/DataEngine… def. The header note states the ruling, the measurement trees and the route. First consumer (build-schemas.ts manifest deletion gate) accepted them: Build Core green on this head, after the regen commit re-applied the manifest deletion. No finding.
  4. semantic/18.data-engine-rpc-protocol-retired.ts. Conforms to SemanticMigration (id, surface, replacement, reason, acceptanceCriteria; conversionIds and relevantWhen omitted as in the two precedents). surface carries no backticks and no pipe, which build-upgrade-guide.ts:126,135 needs (code span and table cell). replacement names only doors that exist: IDataEngine at @objectstack/spec/contracts; ctx.api.object(name).find(...); REST /data/:object and POST /data/:object/query (protocol.ts:4884); POST {basePath}/batch with the two batch schemas; "DataEngineContractSchema has no replacement schema: the engine contract is the IDataEngine interface" is true. acceptanceCriteria is checkable and is checked by the new pin (TS2305 named; defs absent from the manifest; lit controls survive; tree-scoped absence walk; anti-vacuity case). Should-fix (carried, ③.7): reason says "every arm admitted a caller-supplied context (isSystem included)"; seven of nine did. The judgment the upgrader owes does not change. Not a must-fix.
  5. packages/spec/src/ui/view-grouping-query.ts (comment-only). "in process the same body is IDataEngine.aggregate's EngineAggregateOptions" (:171) holds: aggregate(objectName: string, query: EngineAggregateOptions, options?: BaseEngineOptions) (contracts/data-engine.ts:323). The route it names (client.data.query() → the group-by / aggregation branch) is unchanged by this PR and by the merged main. No finding.
  6. docs/adr/0119-plugin-reachable-transactions-and-honest-atomic-batch.md. Line 61 replaces one path#DataEngineRequest symbol anchor, which this PR makes unresolvable, with a file-level anchor on packages/spec/src/data/data-engine.zod.ts (the [unresolved-symbol] remedy check-adr-symbol-anchors.mjs:51-53,74 itself prescribes), and line 63 adds a dated editorial note in the ADR's own style naming the registering entry by path (a second file-level anchor; the file exists on the head). The decision (D3: batch? retired) is unchanged, and its first consumer agrees: contracts/data-engine.ts:330-338 records batch? as retired under ADR-0119 D3 and names the same three replacements the D3 entry and the kernel docs page (data-engine.mdx:570-573) name (IObjectQLEngine.transaction, objectql-engine.ts:533; batchData with options.atomic; POST {basePath}/batch). The other anchors on the edited paragraph still resolve (contracts/data-engine.ts#IDataEngine, :274; contracts/data-engine.test.ts exists). Lint · docs & code guards (runs check:adr-symbol-anchors) is green on this head. A maintenance edit to a Tier H surface, correct as written; no new rule. No finding.

Must-fix findings: none. Should-fix (all carried from the prior record, none resolved on this head, all on open follow-up #27346): ④.1 (stale "RPC / Virtual Data Engine boundary" at contracts/data-engine.ts:172-173, and the sibling "cross the RPC boundary" at :92), ④.4 ("every arm" → "every read and write arm" in the D3 reason, the changeset and the data-engine.zod.ts:1347 note), ③.8 (the strictness ledger's hand-written row note at :718, lane remainder). The merge brought no new finding.

Implemented-by: claude/project-thread-9f4fjb
Reviewed-by: session_01AavokzJ5DndAwitDXvKy4U

VERDICT: PASS


Generated by Claude Code

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

Projects

None yet

3 participants