Skip to content

fix(metadata-protocol)!: batch 逐行结果迁移到 BatchOperationResultSchema 形状 —— 方案 B 硬切 (#4793) - #4841

Merged
os-zhuang merged 6 commits into
mainfrom
claude/issue-4793-batch-row-result-schema
Aug 3, 2026
Merged

fix(metadata-protocol)!: batch 逐行结果迁移到 BatchOperationResultSchema 形状 —— 方案 B 硬切 (#4793)#4841
os-zhuang merged 6 commits into
mainfrom
claude/issue-4793-batch-row-result-schema

Conversation

@os-zhuang

@os-zhuang os-zhuang commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Fixes #4793

按维护者拍板的方案 B 实施:实现迁到 schema 形状,搭 v17 major 窗口硬切,不做双发过渡,changelog 诚实写明升级路径。

分歧对照(迁移前 → 迁移后)

三个端点(POST /data/:object/batch / /updateMany / /deleteMany)的逐行 results 条目:

旧 wire(实现私有形状) 新 wire(= BatchOperationResultSchema 声明) 消费方迁移
错误 error: string errors: ApiError[] row.errors?.[0]?.message,按 row.errors?.[0]?.code 分支
记录 record data 改名读取
下标 ❌ 从不发 index: number(请求数组下标) 新增 —— 无 id 失败行的关联依据
droppedFields ✅ 已对齐 不变 无需改动

实现侧行类型直接别名 spec 类型(type BatchDataRowResult = BatchOperationResult),tsc 双向钉死;protocol.ts 原 814-820 的「刻意分歧」注释已删(存在理由已消灭)。

batch.zod.ts 只动 describe 文案,schema 形状一字未变 —— 本 PR 是「实现追上已发布契约」,不是改契约迁就实现。

ROLLED_BACK / NOT_ATTEMPTED 结构化

#4798 引入的两个 message 字符串前缀提升为 ApiError.code 一级结构化信息,注册进 ERROR_CODE_LEDGER(@objectstack/metadata-protocol 名下,含语义注释;#4805 的 ledger 现状不动,只做本单最小扩充):

  • errors[0].code === 'ROLLED_BACK' —— 已写入、被回滚撤销;message 保留致因行下标与原始错误
  • errors[0].code === 'NOT_ATTEMPTED' —— 从未执行;更早的行失败中止了批次
  • 致因行保留自己的语义码(RECORD_NOT_FOUND / VALIDATION_FAILED 等;无码的引擎抛错按 status 映射,兜底 INTERNAL_ERROR,httpStatus 有则镜像)

未复用 BATCH_ABORTED(metadata publish 面)与标准目录的 TRANSACTION_FAILED(描述整个事务,非逐行判定)——「已尝试被撤销 vs 从未执行」的区分正是本单要求成为 code 一级的信息,合并进任一既有码都会把它抹回 message。

Conformance 钉子(结构性收益)

新增 packages/metadata-protocol/src/protocol.batch-row-conformance.test.ts:三端点真实响应行(成功行、失败行、ROLLED_BACK 行、NOT_ATTEMPTED 行、returnRecords:false 行)逐行过 BatchOperationResultSchema.parse

⚠️ 单靠 .parse() 的钉子不足以发现回退:zod z.object 对未知键是静默剥离而非报错,且 errors 是 optional —— 实现改回发 error/record 时,.parse() 照样绿。故钉子额外断言旧键缺席(error/record not present)与新键在场(失败行必有非空 errors,每行 index 等于请求下标)。

Sabotage 实跑(临时把三处 emitter 改回发 error/record,跑钉子):

× non-atomic create — success rows (data present) and the failure row (errors, code, index)
× returnRecords: false — rows stay conformant, `data` is dropped, `errors`/`index` are kept
× a row that names no id fails with VALIDATION_FAILED, not an unclassified 500
× atomic rollback — ROLLED_BACK, the causal row, and NOT_ATTEMPTED all parse, as CODES
× non-atomic — mixed success and failure
× atomic rollback — all three row classes, as codes (updateMany)
× non-atomic — a missing id is RECORD_NOT_FOUND with its HTTP status mirrored
× atomic rollback — all three row classes, as codes (deleteMany)
AssertionError: expected { id: 'new-1', success: true, …(1) } to not have property "record"
AssertionError: expected { id: 'b', success: false, …(1) } to not have property "error"
 Test Files  1 failed (1)
      Tests  8 failed (8)

钉子必红,确认后已还原实现。

仓内消费方清扫读数(裸名扫描)

  • packages/client/src/client.batch-transaction.test.ts:135 的双形状对冲 ?? (x as any).record?.project —— 清除,收敛到 GetDataResponseSchema 声明的单一形状并升级为等值断言
  • fix(metadata-protocol): deleteMany/updateMany 的 atomic 要么为真、要么拒绝 (#4620) #4798 的三个测试套件(protocol.batch-atomic / protocol.many-data-atomic / objectql protocol-batch-atomic)—— 断言从前缀正则迁到 code 判定
  • 首跑暴露的另外三处旧形状读点(protocol.delete-many / protocol.dropped-fields.bulk / protocol.record-not-found 测试)—— 一并迁移
  • packages/rest ingress:三条路由均 res.json(result) 直传,无行级重映射,零改动;packages/client SDK:纯 spec 类型直传,零改动
  • docs:data-api.mdx / wire-format.mdx(响应示例整体换新形状)/ client-sdk.mdx 更新;references/api/* 为 describe/ledger 变更的再生成物。顺带修正 data-api.mdxfix(metadata-protocol): deleteMany/updateMany 的 atomic 要么为真、要么拒绝 (#4620) #4798 遗留的失实陈述(「deleteMany 无包裹事务」)—— 与本次同段落文档直接矛盾,留着会自相矛盾,故在同 PR 修正并在此声明
  • skills / examples:零 batch 行结果消费点
  • 剩余 .error/.record 命中均属其它契约(import 行 { row, ok, action, error }、notification/job service outcome、security explain layer、core bulk-write 内部 util、单记录 GetDataResult.record)—— 不在本单范围

objectui 影子排查(PM 于 785b8a5d432cf009389a1a9180fdac2a8297543f 实测 + 本实施 agent 独立浅克隆 971302e22e8e8c49d73d16ef3c3f56b8d2510ebe 复测,两次读数一致):

git grep -rnE "batchData|updateManyData|deleteManyData|BatchOperationResult" -- 'packages' ':!*CHANGELOG*'  → 0 命中
git grep -rnE "\.(record|error)\b" -- 'packages/*/src' | grep -iE "batch|many|rowresult|results\["          → 0 命中

objectui 仅使用跨对象 /api/v1/batch(batchTransaction,不同契约,本 PR 未动)——零旧键消费方,无需跨仓 linkage issue

ADR-0087 conversion 评估

对照 D3 semantic[] 先例(enhanced-api-error-field-errors-renamed,同为 RESPONSE 面):已登记。step17 新增 semantic 条目 batch-row-result-schema-shape(响应面、无存量元数据可重写,故为 semantic TODO 而非 D2 conversion),gen:spec-changes + gen:upgrade-guide 再生成,docs/protocol-upgrade-guide.md 迁移条目即升级指引通道(#4535 §5 先例)。ADR-0119 追加 addendum 记录 D4 行标记编码从前缀演进为结构化 code(D4 不变量本身不变)。

Changesets

与 main 的同步(2026-08-03 10:2xZ,已含 #4831/#4657)

更正:本 PR body 早前一版写「merge origin/main(含 #4616 / #4657 线上先行合入)」—— 当时 #4657 并未合并(其 PR #4831 尚在 CI),该表述不成立,现更正。首次合并仅含 #4616 等;#4831 于 10:18Z 落地后已再次同步。

registry.tsspec-changes.json / protocol-upgrade-guide.md#4831 正面重叠,且后两者在 .gitattributes 中是 merge=os-regen。实测复现了该驱动的静默吞并:

合并后(零冲突标记):
  origin/main 的 spec-changes.json 含 activationEvents 条目: 4
  合并结果    的 spec-changes.json 含 activationEvents 条目: 0   ← 被静默吞掉

按协议修复:git checkout origin/main -- <生成物> 后从合并后的源整体重新生成,不做文本合并。核对断言(全部通过):

断言 读数
step17 同时含两条 id plugin-activation-events-retired 1 / batch-row-result-schema-shape 1
spec-changes.json 同时含两单条目 activationEvents 4 / batch-row 2
protocol-upgrade-guide.md 同时含两条 各 1
#4657 删除未复活 "kernel/ActivationEvent" / "studio/ActivationEvent" / ActivationEventSchema / activationEvents 在 manifest 与 api-surface 中均 0
#4616 删除未复活 "system/EmailTemplate" / "system/SMSTemplate" / "system/PushNotification" / "system/InAppNotification"0(manifest 中 3 处 EmailTemplateDefinition* 是另一条live 家族,与 origin/main 一致)
四张 ratchet 与 origin/main 逐字节相同 是 —— 本单导出增删为 0(check:dual-source-exports 名数 4286→4276 的下降全部来自 #4657/#4616 的删除,已正确保留)

commit 2a58532f1 单独记录该重生成,pre-commit 的 os-regen 守卫亦独立确认「2 artifacts merged WITHOUT a text merge … marker cleared」。

验证读数(同步 #4831 后全量重跑)

  • @objectstack/metadata-protocol test:32 files / 268 passed(含新钉子 10 条)
  • @objectstack/spec test:295 files / 7358 passed
  • check:generated:✓ All 8 generated artifacts are up to date
  • check:dual-source-exports:0 accepted dual-source(4276 names / 16 entry points,171 re-exported)
  • check:exported-any:0(1864 types + 1607 schemas);check:liveness / check:empty-state / check:strictness-ledger / check:adr-anchors:全绿
  • @objectstack/client test:17 files / 222 passed;@objectstack/rest test:38 files / 573 passed;objectql protocol-batch-atomic:6 passed
  • 全仓 pnpm typecheck:122/122;全仓 pnpm build:71/71

过程记录:同步后首跑 client/rest 出现整文件加载失败(Failed to resolve entry for package "@objectstack/objectql",0 断言执行)—— 是 AGENTS.md §9 的合并后陈旧构建态,非本改动;按其处方 pnpm install --frozen-lockfile && pnpm build && rm -rf packages/runtime/.objectstack 刷新后全绿(上表读数即刷新后)。

已知 CI 状况(非本 PR 引入)

Test Core (1/2) 对每个 spec PR 均红(签名:DTS Build start 后零 tsc 输出直接 ELIFECYCLE),已由 PM 立案 #4845 并在排查根因;本 PR 未为此改任何代码,亦未尝试绕过。

影响面(诚实声明)

被 break 的只有绕开类型(as any / 裸 JS)读 error/record 的 off-contract 用法;照 SDK 类型/schema/文档写的消费方是从本 PR 起第一次在运行时拿到已发布契约。content/docs/releases/ 未触碰。

🤖 Generated with Claude Code

https://claude.ai/code/session_0176qgxgCXTJCUv4YFLtusP9

claude added 2 commits August 3, 2026 09:18
…4793)

- protocol.ts 三个 bulk-write 端点(batchData/updateManyData/deleteManyData)的
  逐行结果迁到 spec 声明形状:error:string → errors:ApiError[],record → data,
  补发 index(请求数组下标);行类型直接别名 BatchOperationResult,tsc 双向钉死
- ROLLED_BACK / NOT_ATTEMPTED 从 message 前缀提升为 ApiError.code 一级结构化信息
  (ERROR_CODE_LEDGER 注册),message 保留人类可读致因;删除 ADR-0119 D4 留下的
  「刻意分歧」注释(存在理由已消灭)
- 新增 conformance 钉子 protocol.batch-row-conformance.test.ts:三端点真实响应行
  逐行过 BatchOperationResultSchema.parse + 旧键缺席 + errors/index 在场断言
  (sabotage 实证:改回 error/record 时 8/10 红)
- spec:ledger 注册两码;migrations/registry step17 增 semantic 条目
  batch-row-result-schema-shape;atomic/errors describe 更新;衍生物再生成
- 仓内消费方清扫:#4798 三个测试套件 + delete-many/dropped-fields/record-not-found
  测试迁移断言;client.batch-transaction.test.ts:135 双形状对冲清除;
  docs(data-api/wire-format/client-sdk)示例与文字更新,data-api 中 #4798 遗留的
  「deleteMany 无事务」陈述一并修正;ADR-0119 追加 addendum 记录编码演进
- changesets:@objectstack/metadata-protocol major(升级指引 + 与 #4798 changeset
  的叠加关系),@objectstack/spec minor

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176qgxgCXTJCUv4YFLtusP9
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 3, 2026 11:28am

Request Review

@github-actions github-actions Bot added the size/l label Aug 3, 2026
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/metadata-protocol, @objectstack/spec.

106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via @objectstack/metadata-protocol, packages/spec)
  • content/docs/concepts/north-star.mdx (via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/metadata-protocol, @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/metadata-protocol, @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Copy link
Copy Markdown
Contributor Author

CI:Test Core 红 —— 已立案的 #4845(spec DTS 内存天花板),不重跑,理由如下

聚合门禁是分片 Test Core (1/2) 失败的连带。分片那条已诊断:DTS Build start零 tsc 输出直接 ELIFECYCLE(SIGKILL 签名),同 job 内 vitest 7362 用例全绿且无遗漏

已立 #4845,现已三例复现且指向同一结论:

PR 内容性质 首跑
#4831 纯删除 OOM(重跑转绿)
#4841(本 PR) wire 形状迁移 OOM
#4846 patch,零运行时代码改动 OOM

第三例决定性:#4846 只改散文与注释,spec 类型图与 v17 前逐字节等价,照样在同一步被杀 —— 说明命中取决于「是否真跑 DTS 这一趟」,与改了什么无关。根因分析见 #4845(--max-old-space-size=12288 对 16 GB runner 而言是「允许涨到 12 GB」,V8 因此不积极 GC,越过物理内存被内核杀掉)。

本 PR 现在不重跑,因为它必须先做一次强制的 main 同步再推:本 PR 与 #4831(#4657,合并队列中)、#4846(#4709)共用 packages/spec/spec-changes.json,而该文件在 .gitattributes 里是 merge=os-regen —— merge 零冲突标记却会静默吞掉一侧改动,只有重新生成才暴露(#4616 今日实证)。等 #4831 落地后本 PR 会 git merge origin/main + 取 main 版重新生成再 push,那次推送会触发全新 CI。现在重跑等于烧一轮必然作废的 CI。

实施侧本地读数(合并基上)供参考:metadata-protocol 268/268(含新钉子 10 条)、spec 7380、client 222、rest 573、全仓 typecheck 122/122、全仓 build 71/71。


Generated by Claude Code

os-regen 合并驱动对 spec-changes.json / protocol-upgrade-guide.md 不做文本合并,
本次合并零冲突标记地只保留了本分支一侧,静默吞掉 #4657 的条目(实测:
origin/main 的 spec-changes.json 含 4 条 activationEvents 条目,合并后为 0)。

按协议 git checkout origin/main -- <生成物> 后从合并后的源整体重新生成:
- spec-changes.json:现同时含 #4657 的 activationEvents 4 条与本单
  batch-row-result-schema-shape 2 条
- protocol-upgrade-guide.md:同时含 plugin-activation-events-retired 与
  batch-row-result-schema-shape
- 四张 ratchet(api-surface / api-surface-signatures / authorable-surface /
  json-schema.manifest)与 origin/main 逐字节相同 —— 本单不增删任何导出

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176qgxgCXTJCUv4YFLtusP9

Copy link
Copy Markdown
Contributor Author

已同步 #4831(#4657 activationEvents),重生成 + 全量复验完成

推送 2a58532f1(fast-forward,未 rebase / 未 force-push)。

1. os-regen 静默吞并 —— 实测复现

registry.ts#4831 在 step17 的不同 hunk,git 零冲突干净合并;而 spec-changes.json / protocol-upgrade-guide.mdmerge=os-regen,合并结果只保留了本分支一侧:

origin/main 的 spec-changes.json 含 activationEvents 条目: 4
合并结果    的 spec-changes.json 含 activationEvents 条目: 0   ← 无冲突标记,静默丢失

按协议修复:git checkout origin/main -- <六个生成物> 后从合并后的源整体重新生成(未做任何文本合并)。commit 2a58532f1 单独记录;pre-commit 的 os-regen 守卫独立确认 2 generated artifact(s) were merged WITHOUT a text merge … marker cleared

2. 核对断言(全部通过)

断言 读数
step17 同时含两条 id plugin-activation-events-retired 1 / batch-row-result-schema-shape 1
spec-changes.json 同时含两单 activationEvents 4 / batch-row 2
protocol-upgrade-guide.md 同时含两条 1
#4657 删除未复活 "kernel/ActivationEvent" / "studio/ActivationEvent" / ActivationEventSchema / activationEvents → manifest 与 api-surface 中均 0
#4616 删除未复活 "system/EmailTemplate" / "system/SMSTemplate" / "system/PushNotification" / "system/InAppNotification" → 均 0
四张 ratchet vs origin/main 逐字节相同 → 本单导出增删 0

关于 #4616 的一个澄清:manifest 中 system/EmailTemplate 子串有 3 处命中,逐条查为 EmailTemplateDefinition / …Category / …Variable —— 另一条 live 家族,且与 origin/main 完全一致,不是复活。精确名(带引号)命中为 0。

check:dual-source-exports 的名数由 4286 → 4276、re-exported 173 → 171,全部来自 #4657/#4616 的删除被正确保留,与我方 api-surface 零 delta 一致。

3. 验证读数(同步后全量重跑)

  • metadata-protocol test:32 files / 268 passed(含 conformance 钉子 10 条)
  • spec test:295 files / 7358 passed
  • check:generated:✓ All 8 up to date
  • check:dual-source-exports:0 accepted dual-source(4276 names / 16 entry points)
  • check:exported-any:0(1864 types + 1607 schemas);check:liveness / check:empty-state / check:strictness-ledger / check:adr-anchors:全绿
  • client test:17 files / 222 passed;rest test:38 files / 573 passed;objectql protocol-batch-atomic:6 passed
  • 全仓 pnpm typecheck:122/122;全仓 pnpm build:71/71

过程记录:同步后首跑 client/rest 曾整文件加载失败(Failed to resolve entry for package "@objectstack/objectql",0 断言执行)—— AGENTS.md §9 的合并后陈旧构建态,非本改动;按其处方刷新后全绿,上表即刷新后读数。

4. PR body 更正

早前 body 里「merge origin/main(含 #4616 / #4657 线上先行合入)」一句当时不成立(#4831 尚在 CI),已在 body 中更正并保留更正说明,避免留下将来误导人的断言。

5. CI

Test Core (1/2)DTS Build start → 零 tsc 输出 → ELIFECYCLE#4845,已知非本 PR 引入;未为此改任何代码,未尝试绕过

保持 draft,un-draft 与入队归 PM。若 #4846(#4709)先入队,我可再同步一次 —— 届时 registry.ts / spec-changes.json 会是同一类重叠,按同一协议处理。


Generated by Claude Code

claude added 2 commits August 3, 2026 11:02
os-regen 第三轮实测:#4846 对 app-dead-authoring-keys-removed summary 的散文修正
('WAS read by objectui')在合并中被静默吞掉(origin/main 2 处命中,合并后 0)。
按协议 checkout origin/main 后从合并源整体重生成;spec-changes.json 现三方并存:
#4657 activationEvents 4 条、#4846 散文 2 处、#4793 batch-row 2 条。
四张 ratchet 与 origin/main 逐字节相同(本单导出增删 0)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176qgxgCXTJCUv4YFLtusP9

Copy link
Copy Markdown
Contributor Author

末次同步完成:已含 #4846(main 61cc079ec),推送 7e8858a46(fast-forward)

os-regen 第三轮,如预告般复现

#4846app-dead-authoring-keys-removed summary 的散文修正在合并中被静默吞掉:

origin/main 的 spec-changes.json 含 'WAS read by objectui': 2
合并结果(零冲突标记):                                   0   ← 静默丢失

按协议 git checkout origin/main -- <六个生成物> 后从合并源整体重生成;pre-commit os-regen 守卫再次独立确认(2 artifacts merged WITHOUT a text merge … marker cleared)。

核对断言(全部通过)

断言 读数
spec-changes.json 三方并存 #4657 activationEvents 4 / #4846 WAS read by objectui 2 / #4793 batch-row 2
registry.ts step17 两条 id plugin-activation-events-retired 1 / batch-row-result-schema-shape 1
protocol-upgrade-guide.md 三方 1(#4846 散文 1 处)
#4657/#4616 删除未复活(带引号精确名) manifest 6 个名 + api-surface 6 个名 → 全 0
四张 ratchet vs origin/main 逐字节相同(本单导出增删 0)

验证读数

按 AGENTS.md §10 判断:本轮增量提交(#4856/#4842/#4847/#4822/#4838/#4836/#4857/#4858/#4846)与本 PR 改动面唯一交叠是 spec(#4846 registry 散文 + #4856 vitest 配置),故重跑 spec 全量 + metadata-protocol 全量 + 全仓 build/typecheck;client/rest 与增量零交叠,未重跑(上一轮读数 222/573 仍有效),合并队列会验证合并提交本身。

过程记录(自纠):本轮 pnpm install 误跑在 merge 之前,导致 @objectstack/verify#4857 新增的 @objectstack/types/node 子路径解析失败(TS2307)——又是 §9 陈旧态,补 pnpm install --frozen-lockfile 后全绿。已核实 packages/types / packages/verify 树与 origin/main 逐字节相同,非本 PR 引入。

CI 首跑预期能绿(#4856 已带上)。可以 un-draft + 入队。


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 3, 2026 11:28
@os-zhuang
os-zhuang enabled auto-merge August 3, 2026 11:29
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 3, 2026
Merged via the queue into main with commit ac37fc6 Aug 3, 2026
22 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-4793-batch-row-result-schema branch August 3, 2026 11:50
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/l tests tooling

Projects

None yet

2 participants