Skip to content

MetadataManager.get() 丢弃 loadDiagnosed 的 degraded 判定:loader 读不到与「这一项没声明」在 6 个消费点上不可分辨 #5840

Description

@baozhoutao

#5707(getMetaItemLayered 的 overlay 裸 catch)时,测量该方法 code 层那一侧发现的同族点。不在那单范围内(#5707 的文件面限定为 getMetaItemLayered 里 overlay 读的一处 catch),按 Prime Directive #10 单独记在这里,unassigned。严重度不自评,交 PM 分诊。

事实

packages/metadata/src/metadata-manager.ts:

async get(type: string, name: string): Promise<unknown | undefined> {
  const typeStore = this.registry.get(type);
  if (typeStore?.has(name)) return typeStore.get(name);
  const result = await this.load(type, name);   // ← load = (await loadDiagnosed(...)).data
  return result ?? undefined;
}

而同文件的 loadDiagnosed 的 TSDoc 恰恰是为这件事写的(原文):

[ADR-0110 D3] A miss and an outage are different facts with opposite security meanings, and plain load cannot express the difference: a loader that throws is warn-logged and skipped, so a database the metadata plane cannot reach returns the same null as a name that was never declared. Callers that gate on a declaration MUST NOT read that null as "the author declared no gate" — an availability failure would silently widen access (the REST /actions route's fail-open branch, #3935).

loadDiagnosed 算出了 degraded,load() 只取 .data,get() 再把它变成 undefined。也就是说:判定被算出来了,然后在两跳之内被丢掉,get() 的调用方拿不到、也无法拿到这个区别。get() 自己的 TSDoc 只写「先查内存 registry,再回落 loaders」,不含任何关于这一点的告知。

消费方(git grep,排除测试)

位置 读什么
packages/plugins/plugin-security/src/permission-set-projection.ts:398 metadata.get('permission', name) —— 权限集 evaluator 同步
packages/metadata-protocol/src/protocol.ts:3577 / 3583 getMetaItem 的 runtime-item 合并
packages/metadata-protocol/src/protocol.ts:3765 / 3768 getMetaItemLayeredcode 层(读不到 → 报「没有 artifact 基线」)
packages/metadata-protocol/src/protocol.ts:7290 同文件另一处
packages/objectql/src/plugin.ts:695 metadataService.get('object', name)
packages/mcp/src/mcp-server-runtime.ts:443 metadataService.get('agent', agentName)

注意 getMetaItemLayered 的 code 层还额外裹了一个 catch { /* ignore */ },但那处对 loader 失败其实是空转 —— 因为 get() 根本不抛,判定在更上游就没了。修在 catch 上是修不掉的,这也是这条要单独立单、而不是并进 #5707 的原因。

未验证 / 需要开工时先测量

关联

#5707 / #5532(PR #5705)/ #5706 —— 同一条 ADR-0110 D3 规矩在 sys_metadata 直读侧的三次落地;#5108(DatabaseLoader 复数读)、#5089(listForIndex)、#3935(/actions fail-open)。


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions