> 最危险的工具故障是"静默少做"——技能在、后端不在

Research Tools 入门 2026-09-06 07:21 2026-09-06
#tooling #skills #provenance #audit #failure-modes

自动化工具链的故障按危险程度排序,和直觉相反:

// TABLE_OF_CONTENTS

结论先行

自动化工具链的故障按危险程度排序,和直觉相反

故障 表现 危险度
A 技能/命令在,但它调用的后端没装 静默少做,报告不会说"我没跑" 🔴 最高
B vendored 的上游代码落后 行为陈旧但一致 🟡 中
C 能力真空(工具和技能都没有) 你知道自己没有 🟢 低

C 类最不危险,因为你知道。A 类最危险,因为报告看起来是绿的。

一次实际体检:40 个技能 + 24 个命令 + 43 个工具目录里, 6 个技能声明的后端根本没装

为什么

最典型的一个:一个安全扫描技能声明五层工具链,实际只装了一层。

声明的工具 实际
Python SAST bandit ❌ 未装
多语言 SAST semgrep ❌ 未装
依赖 CVE pip-audit
密钥扫描 detect-secrets ❌ 未装
容器/镜像 trivy ❌ 未装

跑一次,5 层里 4 层出不了结果,而报告不会提这件事。 你会得到一份"没发现问题"的安全报告,并且相信它。

另外三个 LaTeX 工具的后端目录是空的(0 个文件),技能却还挂着。 一个跑不动的技能比没有这个技能更糟——它占着位置,让你以为这块已经覆盖了。

还有一类介于中间的:"内容在,入口不在"—— 代码有 1237 个文件 / 43 MB,但既不在 PATH 也不能 import,只能按绝对路径调用。 这种不算坏,但必须在文档里写明,否则下一个人(或半年后的你)会当成 A 类。

怎么用

定期体检的方法(关键是验后端,不验技能):

  1. 逐个读技能定义,抄出它声明的每一个后端二进制 / Python 模块
  2. 对每一个做实际可用性检查,不是看目录存不存在:
    command -v <bin>                    # 在 PATH 里吗
    python3 -c "import <module>"        # import 得动吗
    find <vendored-dir> -type f | wc -l # 目录是不是空的
    
  3. 对 vendored 的 git 仓库做只读 git ls-remote 比对上游,别盲拉。

给工具本身的两条设计规则(比事后体检更根本):

  • 后端缺失必须是显式失败或显式降级,不能静默跳过。 报告里要有一行"这层没跑,因为 X 没装"。
  • 不要保留跑不动的入口。 要么装上后端,要么删掉技能。二选一。

Provenance 卫生。 43 个目录里只有 2 个有 UPSTREAM-SOURCE.txt。 vendored 的第三方代码必须标出来源,否则会出现两种事故: 把别人的代码当自己的改(升级时冲突),或把自己的代码当 vendored 的删。

标记要区分两种情况: - 整仓 clone —— git pull 可同步。 - 代码片段级摘取(例如摘了某文件的 351–421 行并做了适配)—— git pull 同步不了,必须人工比对上游那几行是否变过。这种尤其要写清楚。

最后:自己的仓库"本地落后于远端"要单独对待。 那通常意味着你在别的机器上推过东西,拉之前先确认本地没有未提交改动。

出处

  • ~/Tools/TOOLING_GAP_AND_PLAN_2026-09-05.md(2026-09-05 体检)
  • ~/Tools/TOOLS.md(工具目录本身)
  • 同类心智:自审的失效模式不是"没发现",是"发现了没执行"(自审也是"看起来跑了"的一类)