Skip to content

fix(objectql): 运行时注册的汇总字段不该等重启才会算 - #4427

Merged
os-zhuang merged 1 commit into
mainfrom
fix/summary-index-registry-revision
Aug 1, 2026
Merged

fix(objectql): 运行时注册的汇总字段不该等重启才会算#4427
os-zhuang merged 1 commit into
mainfrom
fix/summary-index-registry-revision

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

问题

引擎的 roll-up summary 索引只有一个失效点 —— engine.registerApp。而运行时发布路径根本不走它:它直接往 registry 里注册(protocol.saveMetaItemregistry.registerObject)。

于是:任何已经写过一次数据的 kernel(发布动作自己就会往 sys_metadata 写行)都握着一份在新对象出现之前构建的索引。此后每一次子记录写入都查不到 descriptor,静默跳过重算,父记录上的汇总字段一直是 null,直到进程重启。

这正是 AI 搭出来的应用里「已完成任务数」在元数据完全正确的情况下依然永远为空的原因:汇总配置对、子行的外键也解析好了,就是没有任何东西去算它(objectstack-ai/cloud#970 的收尾环节)。

改动

  • SchemaRegistry 增加单调递增的 objectRevision,在对象集合发生变化时自增(registerObject / invalidate / invalidateAll / unregisterObjectsByPackage / reset)。
  • 引擎的 getSummaryDescriptors 记住索引构建时的 revision,一旦对方前进就重建。

这样「从 registry 派生的缓存」不会再因为某条路径忘了调用失效函数而变陈旧。invalidateSummaryIndex() 保留,作为兜底。

测试

新增回归用例 summary-rollup.test.ts > a roll-up registered at RUNTIME still computes:先写一行把索引焐热,再按运行时发布的方式注册 parent + child,插入子行后断言父行的 task_count / completed_task_count(带 filter)算对。去掉本 PR 的引擎改动后该用例会失败(已验证)。

packages/objectql 全量 91 files / 1501 tests 通过。

🤖 Generated with Claude Code

…t to compute

The engine's roll-up summary index had exactly one invalidation site —
`engine.registerApp` — and the runtime publish path does not go through it: it
registers straight into the registry (`protocol.saveMetaItem` →
`registry.registerObject`). So a kernel that had already performed a single
write — publishing itself writes `sys_metadata` rows — held a summary index
built before the new object existed. Every child write of a freshly published
roll-up then found no descriptor and silently skipped the recompute, and the
parent field read null until the process restarted.

That is how an AI-built app's "已完成任务数" shipped permanently empty over
completely correct metadata: the roll-up was configured, the child rows were
seeded with resolved foreign keys, and nothing recomputed (cloud#970).

`SchemaRegistry` now carries a monotonic `objectRevision`, bumped on every
change to the registered object set (register, invalidate, unregister, reset),
and the engine rebuilds its index whenever that number has moved — so a
registry-derived cache can no longer go stale through a path that forgot to call
the invalidator. `invalidateSummaryIndex` stays as a belt-and-braces hook.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 1, 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 1, 2026 4:56am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m labels Aug 1, 2026
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/objectql.

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

  • content/docs/concepts/metadata-lifecycle.mdx (via @objectstack/objectql)
  • content/docs/data-modeling/formulas.mdx (via packages/objectql)
  • content/docs/deployment/migration-from-objectql.mdx (via @objectstack/objectql)
  • content/docs/deployment/vercel.mdx (via @objectstack/objectql)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/objectql)
  • content/docs/kernel/services.mdx (via @objectstack/objectql)
  • content/docs/permissions/authentication.mdx (via @objectstack/objectql)
  • content/docs/plugins/index.mdx (via @objectstack/objectql)
  • content/docs/plugins/packages.mdx (via @objectstack/objectql)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/objectql)
  • content/docs/protocol/objectql/query-syntax.mdx (via packages/objectql)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/objectql)
  • content/docs/releases/implementation-status.mdx (via @objectstack/objectql)

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.

@os-zhuang
os-zhuang merged commit 26bb053 into main Aug 1, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the fix/summary-index-registry-revision branch August 1, 2026 05:04
xuyushun441-sys pushed a commit that referenced this pull request Aug 1, 2026
…ll-up fix

#4427 made the summary index follow `registry.objectRevision` and pinned the
headline path: an object registered after the index was already built. The
same counter is responsible for three neighbouring behaviours it does not
exercise, and each was independently broken before that fix:

- re-registering an EXISTING object with a new summary field (the
  `update_metadata` incremental-authoring path — the object is already live,
  so this replaces a contributor rather than adding an object)
- unregistering the parent, after which its roll-up must STOP being recomputed
  (the mirror of the bug: a stale index keeps writing to a parent that is gone)
- the child's own insert already being correct, rather than a later write
  quietly repairing it — the property that made the original defect so
  slippery, since the no-op PATCH workaround always produced right answers

Verified they earn their place: reverting #4427's `getSummaryDescriptors`
change fails all three (roll-up `undefined`), alongside its own case.

objectql 1504 tests pass; tsc clean. Test-only change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant