Skip to content

fix(metadata-protocol): 保存的 overlay 立即可派发 —— 写路径直写 SchemaRegistry(#4521) - #4622

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-4521-meta-overlay-cache-window
Aug 2, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-4521-meta-overlay-cache-window

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #4521

问题

#4432 F1 验证发现:PUT /api/v1/meta/action/{name} 成功后的一小段窗口内,GET /api/v1/meta/action 已经能列出该 overlay,但 POST /api/v1/actions/{object}/{name} 却返回 ADR-0110 的 "has no declaration" 404,稍后再调用又成功。期间没有任何东西过期——是那次列表读取修好了派发路径。

根因

滞后的"缓存"就是引擎的 SchemaRegistry。运行时派发路径(resolveRouteActionDeclaration)把 registry 当作元数据的实时视图来读(来源 2),但 saveMetaItem 只对 object 类型做写后同步(applyObjectRegistryMutation 对其它类型直接返回);其余 overlay 类型进入 registry 的唯一途径是 getMetaItems 的读侧水合。于是"这个类型有没有人列过"悄悄决定了刚保存的 action 能不能被调用——写后读一致性取决于读取顺序。

修复(生产者侧,符合 Prime Directive #12)

没有在派发点加任何重试、休眠或容错回退,而是让写入本身把 registry 写透:

  • 新增 applyRegistryWriteThrough,在三个"写入已生效"的时点调用:saveMetaItem(仅 mode === 'publish')、runPublishSideEffects(草稿晋升发布)、rollbackMetaItem(回滚后的正文即为线上正文)。对所有 overlay 类型生效,object 分支行为不变。
  • 把读侧水合规则抽取为共享的 hydrateOverlayIntoRegistry(含 ADR-0010 §3.3 保护信封嫁接、ADR-0048 按行所属包做 artifact 查找),getMetaItems 与写透共用一份实现——读和写不可能再把 registry 留在两种不同状态。
  • 写透与读侧携带相同的 environmentId === undefined 门:环境作用域的行不会泄漏进控制面共享的 registry。写不会比读更宽松。
  • 写透是 best-effort(与原 object 分支一致):行已持久化,registry 打嗝只会退化为修复前的行为(下次列表水合),绝不会丢写。

边界(测试钉住)

  • 草稿保存仍然不进入实时 registry(暂存区语义不变);
  • 从未声明过的名字仍然解析为空——ADR-0110 的 404 原样保留;
  • DELETE("恢复 artifact 默认值")仍能还原打包 artifact:overlay 是明键 shadow,不是就地覆盖(这正是旧测试 "saveMetaItem 不得改 registry" 曾守护的风险,现已由 restoreArtifactRegistryView 结构性保证,该测试已反转并注明缘由)。

测试

  • 新增 packages/runtime/src/meta-overlay-read-your-writes.test.ts(7 例):用真实的 ObjectStackProtocolImplementation.saveMetaItem + 真实 SchemaRegistry + 真实 resolveRouteActionDeclaration 复现 PUT→POST 原始场景(中间无任何列表调用),并钉住上述三条边界;去掉写透即失败。
  • 反转 packages/objectql/src/protocol-meta.test.ts 中的旧断言并注明历史缘由。
  • pnpm --filter @objectstack/metadata-protocol test:25 文件 206 例通过;--filter @objectstack/objectql test:98 文件 1596 例通过;--filter @objectstack/runtime test:77 文件 1063 例通过。
  • @objectstack/objectql typecheck 通过;check:type-check-coverage 棘轮 OK(metadata-protocol / runtime 在 DEBT 账本内,未新增超额)。

备注

🤖 Generated with Claude Code

https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5


Generated by Claude Code

…ry so they are dispatchable immediately (#4521)

A just-saved overlay was listed but not dispatchable for a short window:
saveMetaItem only wrote the registry through for `object`, so every other
overlay type reached it solely via the READ-side hydration in getMetaItems —
the listing call is what repaired the dispatch path. resolveRouteActionDeclaration
reads the registry, so `PUT /meta/action/x` followed by `POST /actions/<obj>/x`
answered the ADR-0110 "has no declaration" 404 until someone listed the type.

- Extract the read-side hydration rule (ADR-0010 §3.3 protection graft,
  ADR-0048 package-scoped artifact lookup) into hydrateOverlayIntoRegistry and
  share it between getMetaItems and the new applyRegistryWriteThrough.
- Call the write-through from saveMetaItem (publish mode), runPublishSideEffects
  (draft promotion), and rollbackMetaItem — for EVERY overlay type, with the
  same environmentId scoping gate the read carries.
- Boundaries pinned by tests: drafts never leak into the live registry,
  ADR-0110's 404 for a genuinely absent declaration stands, and DELETE still
  restores the packaged artifact (the overlay is a plain-key shadow).

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

vercel Bot commented Aug 2, 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 2, 2026 11:46am

Request Review

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/metadata-protocol.

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

  • content/docs/concepts/metadata-lifecycle.mdx (via @objectstack/metadata-protocol)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/metadata-protocol)
  • content/docs/releases/v9.mdx (via @objectstack/metadata-protocol)

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.

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

2 participants