做 #5532(getMetaItem overlay 读把 outage 吞成 miss)时,在同一个文件里发现的第三处同族点。不在那单范围内(#5532 / PR #5705 的文件面限定为 getMetaItems / getMetaItem 的四处 overlay 读 + getMetaItemCached 终末错误),按 Prime Directive #10 单独记在这里,unassigned。
标 finding:这条今天不会让用户拿到错误的判定,只会让 Studio 的三层对比视图少画一层 —— 属于展示失真而非安全或数据后果。分级请以 PM 的分诊为准,我不自评严重度。
位置
packages/metadata-protocol/src/protocol.ts,getMetaItemLayered(以内容定位:注释 // ── overlay layer: sys_metadata row (org-scoped wins, then env-wide) ── 之后的 try):
} catch {
// DB unavailable — overlay stays null
}
const effective: unknown | null = overlay ?? code;
现象
getMetaItemLayered 是 Phase 3a 的分层读:分别返回 code(artifact 基线)、overlay(per-org / env 的 sys_metadata 行)与 effective。sys_metadata 读失败时 overlay 保持 null,于是:
overlay 报告为「这一项没有任何定制」——实际是「定制读不到」;
overlayScope 保持 null;
effective 退化成 code,即把 artifact 基线当成生效值呈现。
Studio 的「code / overlay / effective」对比正是给作者看「我改过什么」的。故障期它会告诉作者「你什么都没改过,当前生效的就是打包件原样」——和 #5532 同一个错误结论(可用性故障被讲成「你没声明」),只是落在 diff 视图而不是 404 上。
#5532(PR #5705)修的是 getMetaItems / getMetaItem 的四处 overlay 读;getMetaItemLayered 是另一个方法、另一条读,PR #5705 刻意没有扩到它(scope = the issue)。ADR-0110 D3 的规矩相同。
建议修法(与 PR #5705 对齐,不代裁决)
PR #5705 已在同文件引入 rethrowUnlessMetadataStoreUnprovisioned:isMissingTableError(表还没建 → 确实没有 overlay 行 → null 是真相)良性放行,其余抛 status: 503 / code: SERVICE_UNAVAILABLE,驱动错误挂 cause。这里复用同一个私有方法即可,一处 catch。
另一种可能更贴合这个方法契约的方向:分层读返回的是诊断形状,所以也可以给 overlay 增加一个「未知 / 读失败」的第三态,而不是让整个请求 503 —— 但那是新的返回形状,需要维护者拍板,别在实现时自行选。
未验证:调用方(Studio 的哪个面板、有没有别的消费者)对 overlay: null 的具体渲染,以及 503 化会不会让某个面板整体空白。开工时应先测量再决定上面两条哪一条。
关联
#5532 / PR #5705(同文件同家族)、#5706(getEffectiveLock 的 fail-open,同家族的写侧)、ADR-0110 D3、#5108。
Generated by Claude Code
做 #5532(getMetaItem overlay 读把 outage 吞成 miss)时,在同一个文件里发现的第三处同族点。不在那单范围内(#5532 / PR #5705 的文件面限定为
getMetaItems/getMetaItem的四处 overlay 读 +getMetaItemCached终末错误),按 Prime Directive #10 单独记在这里,unassigned。标
finding:这条今天不会让用户拿到错误的判定,只会让 Studio 的三层对比视图少画一层 —— 属于展示失真而非安全或数据后果。分级请以 PM 的分诊为准,我不自评严重度。位置
packages/metadata-protocol/src/protocol.ts,getMetaItemLayered(以内容定位:注释// ── overlay layer: sys_metadata row (org-scoped wins, then env-wide) ──之后的try):现象
getMetaItemLayered是 Phase 3a 的分层读:分别返回code(artifact 基线)、overlay(per-org / env 的 sys_metadata 行)与effective。sys_metadata读失败时overlay保持null,于是:overlay报告为「这一项没有任何定制」——实际是「定制读不到」;overlayScope保持null;effective退化成code,即把 artifact 基线当成生效值呈现。Studio 的「code / overlay / effective」对比正是给作者看「我改过什么」的。故障期它会告诉作者「你什么都没改过,当前生效的就是打包件原样」——和 #5532 同一个错误结论(可用性故障被讲成「你没声明」),只是落在 diff 视图而不是 404 上。
与 #5532 的区别
#5532(PR #5705)修的是
getMetaItems/getMetaItem的四处 overlay 读;getMetaItemLayered是另一个方法、另一条读,PR #5705 刻意没有扩到它(scope = the issue)。ADR-0110 D3 的规矩相同。建议修法(与 PR #5705 对齐,不代裁决)
PR #5705 已在同文件引入
rethrowUnlessMetadataStoreUnprovisioned:isMissingTableError(表还没建 → 确实没有 overlay 行 →null是真相)良性放行,其余抛status: 503/code: SERVICE_UNAVAILABLE,驱动错误挂cause。这里复用同一个私有方法即可,一处 catch。另一种可能更贴合这个方法契约的方向:分层读返回的是诊断形状,所以也可以给
overlay增加一个「未知 / 读失败」的第三态,而不是让整个请求 503 —— 但那是新的返回形状,需要维护者拍板,别在实现时自行选。未验证:调用方(Studio 的哪个面板、有没有别的消费者)对
overlay: null的具体渲染,以及 503 化会不会让某个面板整体空白。开工时应先测量再决定上面两条哪一条。关联
#5532 / PR #5705(同文件同家族)、#5706(
getEffectiveLock的 fail-open,同家族的写侧)、ADR-0110 D3、#5108。Generated by Claude Code