Skip to content

os doctor?? 兜底 DEFAULT_INSTALLED_PACKAGES_DIR —— 同一函数里两行之隔,一行明令禁止这个写法 #5996

Description

@baozhoutao

实施 #5429(ledger 可读性提为 posture 无关的独立检查,PR #5988)时核验发现。观察类,今日无人踩到,记录以免下次有人照抄。

事实

packages/cli/src/commands/doctor.ts,readInstalledPackageEntries() 里:

const dir = path.join(cwd, mod.DEFAULT_INSTALLED_PACKAGES_DIR ?? '.objectstack/installed-packages');

DEFAULT_INSTALLED_PACKAGES_DIR@objectstack/cloud-connection 的导出,也就是「ledger 目录叫什么」这件事的唯一权威。这里对它做了一次消费端 ?? 兜底。

同一个函数往下两行,读 list() 的返回时写着(#5413 留下的注释,原文):

// #5413 — read BOTH halves of the listing. Destructured with no `??`
// fallback on purpose: `list()` declares this shape, and a tolerant read
// here would be the exact consumer-side accommodation that let the silence
// live in the first place.
const { entries, skipped } = new mod.LocalManifestSource(dir).list();

同一个文件、同一个函数、同一个被读的模块,一处禁止 ?? 兜底并写明了理由,另一处正在用。

为什么这可能是个缺陷(以及为什么判为观察类)

Prime Directive #12:producer 是契约,consumer 不得用 ?? 容忍。这个 ?? 的语义是「模块加载成功了但没有这个导出」—— 真发生时,doctor 会安静地去读一个硬编码路径,而不是报告「我读 ledger 的那个包不认得 ledger 目录了」。运行时(rehydrate() 侧)读的仍是权威常量,于是两侧看的是两个目录、都不作声。#5644 刚刚才把「包在但加载不了」从静默里拆出来,这是同一条边界上剩下的最后一格。

判轻的原因,也是不建议现在动它的原因:

  1. 该导出当前存在,没有任何版本里不存在过 —— 这是一段死代码,不是活缺陷;
  2. @objectstack/cloud-connection 是可选依赖、动态 import() 载入,没有静态类型能在编译期钉住这个导出,所以「删掉 ?? 直接读」需要顺带决定「读不到时报哪一行」—— 大概率是 installedPackageLedgerReaderFailureCheck 的近亲(包在、但不是我认得的那个包),属报告面的小扩展,不是删两个字符;
  3. 真删掉时应连带考虑:installedPackageLedgerSkippedEntriesCheckfix 里也硬编码了 Under \.objectstack/installed-packages/`:这句字面路径,而那一刻 doctor 手里是有真实dir` 的。

建议处置

finding,不排期。若哪天 packages/cloud-connection 的导出面要动,或有人再来碰 readInstalledPackageEntries(),顺手一并做掉:去掉 ??,把「导出缺失」变成一条具名的报告行,并让 fix 引用真实解析出的目录而不是字面量。


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