做 #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 |
getMetaItemLayered 的 code 层(读不到 → 报「没有 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
做 #5707(
getMetaItemLayered的 overlay 裸 catch)时,测量该方法 code 层那一侧发现的同族点。不在那单范围内(#5707 的文件面限定为getMetaItemLayered里 overlay 读的一处 catch),按 Prime Directive #10 单独记在这里,unassigned。严重度不自评,交 PM 分诊。事实
packages/metadata/src/metadata-manager.ts:而同文件的
loadDiagnosed的 TSDoc 恰恰是为这件事写的(原文):loadDiagnosed算出了degraded,load()只取.data,get()再把它变成undefined。也就是说:判定被算出来了,然后在两跳之内被丢掉,get()的调用方拿不到、也无法拿到这个区别。get()自己的 TSDoc 只写「先查内存 registry,再回落 loaders」,不含任何关于这一点的告知。消费方(
git grep,排除测试)packages/plugins/plugin-security/src/permission-set-projection.ts:398metadata.get('permission', name)—— 权限集 evaluator 同步packages/metadata-protocol/src/protocol.ts:3577 / 3583getMetaItem的 runtime-item 合并packages/metadata-protocol/src/protocol.ts:3765 / 3768getMetaItemLayered的 code 层(读不到 → 报「没有 artifact 基线」)packages/metadata-protocol/src/protocol.ts:7290packages/objectql/src/plugin.ts:695metadataService.get('object', name)packages/mcp/src/mcp-server-runtime.ts:443metadataService.get('agent', agentName)注意
getMetaItemLayered的 code 层还额外裹了一个catch { /* ignore */ },但那处对 loader 失败其实是空转 —— 因为get()根本不抛,判定在更上游就没了。修在 catch 上是修不掉的,这也是这条要单独立单、而不是并进 #5707 的原因。未验证 / 需要开工时先测量
undefined读成「没声明 → 放行/退化」)、哪些只是展示。permission-set-projection.ts:398与objectql/plugin.ts:695最值得先测。get()暴露诊断版(如getDiagnosed)、由 gating 调用方改用;(b) 让get()在degraded时抛(与 getMetaItem 的 overlay 读用裸 catch 把「sys_metadata 不可达」吞成「该项不存在」—— GET /meta/:type/:name 在存储故障时回一个无 code 的 400「not found」 #5532 / fix(metadata-protocol): 元数据存储读不到不再被讲成「这一项不存在」 (#5532) #5705 的 503 同语义);(c) 只修被测量证明是 gating 的那几个调用点。(b) 会改公共契约,面更大。关联
#5707 / #5532(PR #5705)/ #5706 —— 同一条 ADR-0110 D3 规矩在
sys_metadata直读侧的三次落地;#5108(DatabaseLoader复数读)、#5089(listForIndex)、#3935(/actionsfail-open)。Generated by Claude Code