Repository navigation
chore(spec): retire IDataEngine.batch? per ADR-0119 D3 — declared-but-unimplemented, zero callers #4618
Description
ADR-0119 D3 rules IDataEngine.batch? retired. This issue is the mechanical removal.
ADR renumbered. This issue originally cited ADR-0118. That record is now ADR-0119 (
docs/adr/0119-plugin-reachable-transactions-and-honest-atomic-batch.md) — it merged the same day as an unrelated ADR-0118 (非用户 actor 的平台契约), and the earlier merge holds the number.
The finding
packages/spec/src/contracts/data-engine.ts:97-100:
/**
* Batch Operations (Transactional)
*/
batch?(requests: DataEngineRequest[], options?: { transaction?: boolean }): Promise;- No engine implements it.
ObjectQLhas nobatchmethod; there is no other engine in the tree. - No caller invokes it.
DataEngineRequestis imported by exactly one non-spec file — the contract declaring it. - The doc comment is three words, specifying nothing about partial failure, ordering, cross-object refs, rollback scope, or what
transaction: falsemeans. Contrast the deliberate, evidenced optionality of its neighboursgetDefaultDriverName?/getDriverByName?(:107-118), which name their implementer and their probing caller. - Its
DataEngineRequestSchemaunion (packages/spec/src/data/data-engine.zod.ts:706-717) even nests batch requests recursively — a shape nobody designed against because nobody built it. - The only "test" is
packages/spec/src/contracts/data-engine.test.ts:162-177, which builds an ad-hoc object literal with abatchproperty and asserts it is defined. It pins the type, not an implementation.
A declared capability that cannot be exercised is precisely ADR-0049's enforce-or-remove target. ADR-0119 D1 (transaction on IObjectQLEngine) and D4 (real atomic batchData) now cover its stated purpose in-process, and POST {basePath}/batch covers it on the wire.
Work
Follow the spec-property-retirement playbook, contract-member route — this is a TypeScript contract member, not an authorable Zod metadata key, so there is no retiredKey tombstone to add (nothing can "author" it; the removal is invisible to metadata authors and visible only to TS consumers).
- Delete the member at
data-engine.ts:97-100; drop the type-only test case atdata-engine.test.ts:162-177. - Decide
DataEngineRequest/DataEngineBatchRequestSchema's fate (data-engine.zod.ts:694-717, 764) — if the union has no other live reader after the member goes, it retires with it; if the wire-side batch still uses part of it, keep exactly that part and say so. - Rebuild spec before running the generated-artifact check (
pnpm --filter @objectstack/spec build && pnpm --filter @objectstack/spec check:generated) —check:api-surfacereadsdist, and a staledistproduces a phantom-removal diff. - Changeset carrying the FROM → TO migration text, since it ships to consumers as the package CHANGELOG: "
IDataEngine.batch?is removed. It was never implemented by any engine and had no callers. For in-process multi-write atomicity useIObjectQLEngine.transaction(cb); for a batch over one object use the metadata protocol'sbatchDatawithoptions.atomic: true; on the wire usePOST {basePath}/batch." - Upgrade-guide entry per ADR-0087's removal discipline.
Refs: ADR-0119 D3, ADR-0049, #4612.
Activity
[-]chore(spec): retire IDataEngine.batch? per ADR-0118 D3 — declared-but-unimplemented, zero callers[/-][+]chore(spec): retire IDataEngine.batch? per ADR-0119 D3 — declared-but-unimplemented, zero callers[/+]fix(spec): true up the variant-docs and strictness ledgers the batch …
os-zhuang commentedon Aug 2, 2026
已落地(#4687)
按 issue 的 work 清单逐条:
data-engine.ts:97-100的成员;删除data-engine.test.ts的类型钉测试DataEngineRequestSchema保留,去掉batch分支;DataEngineBatchRequestSchema整体删除check:generated(见下面那条教训)data-engine-batch-retired进入升级指南与spec-changes.json第 2 条的判断
DataEngineRequestSchema剩下的九个分支现在也全都没有读者——树里没有 Virtual Data Engine 实现,只有这个描述它的 schema。已在文件内标注,值得单开一单;但退休一个已发布的线协议与退休batch?是两个不同的决定,不该塞进一个标题只承诺了后者的改动里。线上的 batch 未受影响:它用
api/batch.zod.ts的CrossObjectBatchRequestSchema/BatchUpdateRequestSchema校验,是另一套 schema,与被删的那个从无关系。刻意不加
retiredKey()墓碑墓碑是靠一次 parse 把处方送达的,而从来没有任何东西 parse 过
DataEngineBatchRequestSchema——落在 playbook 的第三条路径「没人能收到的处方就是噪音」。它的三行authorable-surface.json基线、json-schema.manifest.json条目,以及那条已经陈旧的docs-import-surface.baseline.json豁免,都在同一改动里显式删除。执行渠道是tsc。一条教训,值得下次 spec removal 前知道
第 3 步的顺序不是形式主义。中途有一次我在不完整的
dist上跑了gen:api-surface,它静默抹掉了一个与本次改动无关的./studio的ActivationEvent (type)导出,并顺手往docs-import-surface.baseline.json里为这个缺口加了一条棘轮豁免——正是那个工具自己警告过的「棘轮悄悄停止棘轮」。没有任何报错,是把生成物与main逐文件对比才发现的。这条已经变成机制:#4675 / #4702 让
check:generated --fix在dist比src旧时拒绝运行gen:api-surface,不再只是警告。Generated by Claude Code
feat(spec,metadata-protocol): ADR-0118 — transactions reach plugin sp…
feat(runtime,cli,core): ADR-0119 D2 boot reconciliation + `os migrate…