Skip to content

fix(objectql): artifact lock envelope survives overlay hydration and reset (ADR-0010 §3.3)#1775

Merged
os-zhuang merged 2 commits into
mainfrom
fix-metadata-registry-shadow-lock
Jun 12, 2026
Merged

fix(objectql): artifact lock envelope survives overlay hydration and reset (ADR-0010 §3.3)#1775
os-zhuang merged 2 commits into
mainfrom
fix-metadata-registry-shadow-lock

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Problem

在无 environmentId 的本地栈(control-plane kernel)复现的元数据状态污染:

  1. 对带 _lock: full 的 artifact-backed app 执行 PUT /api/v1/meta/app/setup(锁门禁在 control-plane 被设计性跳过,写入成功);
  2. overlay 行存在期间的任意 GET /api/v1/meta/app 会把 overlay body 以无 packageIdregisterItem 水合进 SchemaRegistry 的 plain key,shadow 掉 composite key(<packageId>:<name>)下的 artifact;
  3. lookupArtifactItem / getEffectiveLock / isArtifactBacked 都经 registry.getItem(plain key 优先命中)拿到被剥光 envelope 的 overlay body → GET 返回 _lock: undefined,违反 ADR-0010 §3.3(overlay 不得放松 packaged lock);
  4. DELETE(reset)只删 DB 行,恢复块查 metadataService.get 落空 → 污染的 shadow 残留到服务重启。

Fix(三层)

  • SchemaRegistry.getArtifactItem() — 穿透 shadow 的 artifact 专用查找:优先扫 composite key、要求真实 _packageId(排除 'sys_metadata' 哨兵)。protocol 的全部 envelope 读取点(lookupArtifactItem / getEffectiveLock / isArtifactBacked / getMetaItemLayered code 层)改用,锁解析从此对 shadow 免疫。
  • 水合保留 envelopegetMetaItems / loadMetaFromDb 注册 shadow 前先 mergeArtifactProtection 把 artifact 的 _lock/_packageId/_provenance 嫁接到 overlay body:内容字段 overlay win,保护信封 artifact win。
  • SchemaRegistry.removeRuntimeShadow() + restoreArtifactRegistryView() — reset 删除 plain-key shadow,artifact 视图立即恢复(无需重启);no-op 二次 DELETE 可自愈历史污染;draft 丢弃不清 shadow(active overlay 可能仍在)。

Verification

  • 新增 protocol-registry-shadow.test.ts(8 用例):PUT→GET→DELETE 全链路 envelope 保持、reset 自愈、scoped kernel 在 registry 已被污染时 403 item_locked 仍生效、两个新 registry 方法的单元行为。
  • objectql 全套 569 测试通过,tsc --noEmit 干净。
  • showcase 实机端到端(OS_PORT=3700):PUT → GET(overlay 存在)→ DELETE → GET,_lock: full / _packageId / _provenance 全程保持;单条 GET 信封 editable/deletable: false 正确。

🤖 Generated with Claude Code

…reset (ADR-0010 §3.3)

On a control-plane kernel, GET /meta/:type hydrates sys_metadata overlay
rows into the SchemaRegistry under the PLAIN key — shadowing the packaged
artifact registered under `<packageId>:<name>`. Every envelope reader
(lookupArtifactItem / getEffectiveLock / isArtifactBacked) resolved the
shadow instead of the artifact, so a `_lock: full` app read back as
unlocked after PUT+GET, and DELETE (reset) only removed the DB row —
the polluted shadow survived until restart.

Fix, three layers:
- SchemaRegistry.getArtifactItem(): shadow-immune artifact lookup
  (composite keys first, requires a real `_packageId`, excludes the
  'sys_metadata' rehydration sentinel). All protocol envelope readers
  and getMetaItemLayered's code layer now use it.
- Hydration (getMetaItems / loadMetaFromDb) grafts the artifact's
  `_lock`/`_packageId`/`_provenance` onto the overlay body before
  registering, so registry-direct readers keep the envelope: overlay
  content wins, artifact protection wins.
- SchemaRegistry.removeRuntimeShadow() + restoreArtifactRegistryView():
  reset drops the plain-key shadow so the artifact view is restored
  without a restart; a no-op DELETE self-heals pre-existing pollution.
  Draft discards keep the shadow (the active overlay may still exist).

Regression suite: protocol-registry-shadow.test.ts pins the
PUT→GET→DELETE envelope round-trip, reset healing, and shadow-immune
403 item_locked enforcement on scoped kernels.

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

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 12, 2026 9:06am

Request Review

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling labels Jun 12, 2026
@os-zhuang
os-zhuang merged commit 2796a1f into main Jun 12, 2026
12 checks passed
@os-zhuang
os-zhuang deleted the fix-metadata-registry-shadow-lock branch June 12, 2026 09:07
baozhoutao added a commit that referenced this pull request Jun 17, 2026
* chore: bump objectui to e6fd254e8797

feat(metadata-admin): book metadata display UI (ADR-0046 §6) (#1775)

objectui@e6fd254e879708ca6395777a5d5517c60a555e19

* chore(console): changeset for objectui refresh to e6fd254
os-zhuang added a commit that referenced this pull request Jun 17, 2026
feat(metadata-admin): book metadata display UI (ADR-0046 §6) (#1775)

objectui@e6fd254e879708ca6395777a5d5517c60a555e19
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

Development

Successfully merging this pull request may close these issues.

1 participant