# Preflight

> 动手写代码前做一次对称决策预研 / Symmetric pre-flight research before writing code。钉死一句话需求 → 按「标准/协议 → 标准库 → OS 原生 → 项目已有代码 → SDK → 框架 → 第三方库 → 开源项目 → 自研」由便宜到贵的层级找现成方案并外部核实维护状态 → 实测基线并把「做」与「不做」两侧同口径摆出来 → 输出 复用/组合/改造/自研/不做/暂缓 六选一结论。当用户开新项目或新模块、问「有没有现成的库」「要不要自己造轮子」「这个功能值不值得加」「现在改还是先跑一段看」、做方案选型或可行性判断时使用；also use for build-vs-buy, tech stack selection, feasibility, "should I write this myself", dependency-adoption decisions；实现中途冒出技术风险（要引新依赖/改架构/动认证或网络）时也触发。纯改 bug、修报错、纯重构、用户已指定依赖或已定好实现方式时不要用。

- Skill: `ainxin-1/preflight` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add ainxin-1/preflight`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ainxin-1/preflight/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Research & Search
- Author: Ainxin-1 (https://skillmd.com/u/ainxin-1)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/ainxin-1/preflight

---


# Preflight

## Overview

两件事合一次做完：调研回答「有没有现成的」，对称举证回答「该不该做」。产出是一个可被推翻的决策，不是一份报告。

改字、调色、明确的小 bug、用户已定方案的执行——**不要走这套流程**。但反过来：实现过程中撞上了没预料到的技术风险（要引新依赖、要改架构、要动认证/加密/网络），**当场停下来进入本流程**，而不是硬着头写完。

## 可调参数

想换口味只动这五个数，正文其他部分不依赖它们：

| 参数 | 默认 | 作用 |
|---|---|---|
| 检索轮次上限 | 4 | 到顶仍未定论就交给人，不许自动下一轮 |
| 可信候选数 | 2 | 达到即可停手 |
| 候选上限 | Light 3 / Deep 4 | 到顶就停；发现明显更好的可替换旧的，不许无限收集 |
| 报告长度 | 每项 ≤2 行；Light ≤8 行、Deep ≤20 行 | 限长压在**每一项**上，不靠砍必填项凑行数——11 项 × 2 句装不进 12 行，硬塞就会牺牲证据 |
| 过期天数 | 30 | 状态类内容超期默认标「可能过期」 |

## 硬规则

只保留五条，都属于「证据类」与「不可逆类」。

- **决策成立前不写实现代码。** 允许读代码、跑探针、建空骨架；预研期间不改动既有文件。
- **候选方案必须来自本轮实际检索并读取过的来源**，且候选的关键事实要能由该来源直接核验——写明是哪个字段（如 `pushed_at`、License 标签、页面某段），不是"我搜过了"。每个候选附可点开的 URL、最近一次提交时间、许可证。**搜一次给旧知识套一层证据外壳不算核验**；查不到出处就不许列进候选——宁缺毋滥。
- **引入第三方代码必须有明确授权**：授权可以来自用户本次确认，也可以来自宿主 agent 已声明的有效权限（能装依赖的模式、预先批准的规则）。但**预研本身不得自行扩大授权范围**——"用户说过上次可以装"不等于"这次可以装"，也不许推断"这个环境应该会批准"。涉及 clone、包管理器安装、下载 release、改 workspace 之外的文件、对外发布，无授权就停下来问。
- **硬约束否决的是「最终方案」，不是单个组件**：组件本身不满足硬约束时，必须写明**由什么补齐**（适配层、原生层、条件编译、换组合里的另一件），补不齐才否决——否则会和"组合/改造"这两种结论自相矛盾。不许用 star 高、功能多、AI 熟悉来补分（硬约束指：必须离线、无服务器、指定平台、禁 GPL、指定语言或版本、免费、低内存等）。其余淘汰项：许可证不兼容（GPL/AGPL 对闭源产品有传染风险）、停更且说不出可承担的后果（见 playbook——**光"很久没提交"不构成淘汰**）、职责与现有模块重叠（会造出两套真相）。命中即淘汰，别把判断留给用户猜。
- **高时间敏感的断言不许用现在时陈述，冲突必须留痕。** 高敏感（必须外部核实）：版本号、API 签名、默认值、维护状态、许可证、兼容性、「某功能/某工具是否存在」、安全公告、官方支持状态。低敏感（别为「求新」而查）：数据结构、算法原理、语言基础语法、通用工程原则。高敏感若无本轮抓到的来源，写成「据我知识（约 ____ 年前后），需核实」并给出验证方式或验证成本；只标不动算违规。一旦外部证据与内部知识打架，显式写出「内部知识：__ ／ 当前外部证据：__ ／ 采用后者，依据 __」——不许悄悄换结论而不留痕，也不许因为"模型记得"就坚持旧的。模型对旧知识和新知识给出同样的置信感，所以这靠格式逼停，不靠它自觉。

## 模式：Light 还是 Deep

**默认 Light。** 只有命中下面任一条才升 Deep——不写"视复杂度而定"，那种判断必然倒向省事：

- 要引入新的第三方依赖
- 动认证、加密、支付、权限
- 换存储、换网络方案、换框架、改架构
- **改动跨越多个调用方，或触及对外协议 / 数据格式 / 持久化结构**（哪怕不引新依赖）
- 有两个以上成熟方案在竞争
- 改动会带来长期维护面（新服务、新守护进程、新配置体系）

**不给"命中但其实风险已被覆盖"的降级口**——那句无法核查，会把判定重新交回模型自觉，而它必然往轻的那边判。误升 Deep 的代价是多几行输出；漏升的代价是错决策。

Light 走：项目内搜 → 快速外部侦察 → 核硬约束与维护状态 → 直接给结论。只填模板第 1–4 与 10–11 项，≤8 行。
Deep 走下面完整流程，11 项全填，≤20 行。

## 判定输出

**顺序固定，不许调换。** 第一位放什么，决定后面所有文字在为谁辩护。

```
1. 需求一句话 + 硬约束（语言 / 平台 / 体积 / 离线 / 许可证）｜ 外部验证：已验证 / 部分 / 未验证（附检索日期与通道）
2. 不做会怎样：最坏情况 + 严重度
3. 最强反对理由（≥2 句，写给「主张做」的那一方读；**必须指向本案的具体代价、风险或失败条件**——换个需求就能照抄的句子算空转）
4. 支持理由（≥2 句，长度不许超过反对段）
5. 基线实测：产物体积 / 启动或首屏耗时 / 内存或包大小 / 依赖数（口径按项目类型取等价项，见 references）—— 附命令与测量日期；测不了写「未测量」
6. 预估变化：与第 5 行同口径
7. 新增概念数，以及是否与现有模块职责重叠
8. 删除成本：反悔时要改哪几个文件、几处调用
9. （仅当候选停更时）停更检查：原项目状态 → 是否找到继任/接管版 → 继任关系有无确认
10. 结论：复用 / 组合 / 改造 / 自研 / 不做 / 暂缓（六选一，不许「都可以」）
11. 翻转条件：出现什么证据就改口 + 本次明确不做的事
```

收益与成本不对称是这套流程要治的病：**只报收益不报成本的结论视为未成立。**

**「暂缓」是给真信息不足的出口，不是逃避出口**：只有当缺的那条事实会直接改变结论、且当场确实无法验证时才用，必须同时写「缺什么 ／ 怎么补 ／ 补的成本」。一轮预研最多暂缓一次；用户说"就在不确定里定"，就写明假设然后给结论。承认不确定优于编造确定，但**滥用不确定同样是失信**。

**每个候选只写两行**，多一行就是调研腔：

```
A ｜ 来源 URL ｜ 状态词表值 · 最新活动日期 ｜ 许可证 ｜ 覆盖需求第 1、3 条
   主要问题与成本：__
```

追的是"当前约束下足够可靠、可验证、可回退"的方案，不是互联网里最完美的那个。找不到更好的就停，别把预研做成无限优化。

缺能力就标出来，别假装有：没有检索能力 → **未验证**；没有终端或构建能力 → **未测量**；读不到项目代码 → **无法检查项目现状**。三项各自如实填，然后基于已有信息给有限结论并说明它为什么是有限结论。

## 流程

1. **钉需求。** 一句话复述用户真正要的结果（不是他想到的解法），外加硬约束。术语有歧义问一个问题，别猜着往下走。
2. **侦察。** 按 `references/search-playbook.md` 执行。**先查家里，再出门搜库**——现成方案不等于第三方库，按由便宜到贵的层级排查：标准/协议 → 语言标准库 → 操作系统原生能力 → **当前项目已有代码与已有依赖** → 官方 SDK → 成熟框架 → 第三方库 → 完整开源项目 → 自研。搜外部时**先探测再选通道**：`command -v gh`（Windows 用 `where gh`）有结果就用 `gh search repos`，没有就走可用的网络检索工具；shell 无外网时别浪费轮次试 `curl` / `git clone`，直接降级为「未外部验证」。探测结果按机器有效，不要沿用记忆里的旧结论。
3. **核查留下的候选。** 先回答一个问题：**这个功能万一做错，在本项目里会以什么形式变坏？** 答案决定要量什么——可执行文件或安装包体积、首屏与交互延迟、常驻内存、启动时间、依赖数量、构建时长、线上延迟与配额、磁盘或电量占用，任一即可，不许凑齐全表。答不出具体形式，就写「无可见代价」并给出为什么——那句话本身就是一条反对意见。通用五项无论什么栈都要查：最近提交时间、issue 有没有人回、依赖规模、是否需要网络或 native 权限、有无安全事故记录。
4. **对称判定。** 按 `references/metrics-baseline.md` 量基线，填输出模板，定分档。
5. **落地。** 拿到批准后再 clone 或加依赖；把社区挖到的坑固化成代码注释或一条回归测试，而不是留在聊天记录里。

## 分档

用契合分档，不用百分比——数字只会诱导模型编数字：

- **A 几乎就是它** → 复用（默认倾向）
- **B 能改改用** → 改造或 fork；必须显式估算那 20% 不契合部分的长期胶水成本
- **C 只能参考** → 自研，把 C 的接口设计和踩过的坑抄进自己的设计
- **D 空白区**（连续两轮检索零有效结果）→ 自研，且把「找不到」本身当结论写下来

平台绑定、体积与冷启动敏感、需要长期演进的产品代码：自研容忍度提高一档，B 档常常也不值得背。

## 软默认

可以越界，但越界要用一句话说清为什么：

- 默认检索 2 轮；已有可信候选达到上限数即可停，跑到轮次上限仍无定论就交给人。
- 报告按参数表限长，且限的是**每项**不是总数；宁可少填一项也不要把它压成空话。
- 状态类内容标注抓取日期，超期默认加「可能过期」，而不是删掉或照旧引用。

## 用户输入不可靠时

用户的表述常常是「他想到的解法」，不是「他要的结果」。分三种情形，不要混：

- **前提可证伪且已证伪**（他说库还在维护，实际已归档）：必须先纠正再动手，一句话给来源。顺着错误前提执行等于撒谎。
- **目标对、路径明显更差**：给**一个**替代方案 + 一句代价对比，然后按用户的决定执行。给完就闭嘴，不追加第二第三个。
- **怀疑是 XY 问题**：问**一个**问题点破，他没确认之前不许替换目标。

三个闸门：被他否掉的替代方案不在同一会话重提；建议只做减法或换路，不许借机加功能；不确定值不值得提就不提，直接照做。

## 报告纪律

写结论进 `.md` 或对外汇报时，`references/reporting-rules.md` 那三条必须遵守。**建议把它们复制进你的 `AGENTS.md`**——skill 只在被触发时加载，常设义务放这儿会半数会话失效。

## Resources

- `references/search-playbook.md` — 检索通道优先级、种子词构造、排序偏差修正、社区信源、停手条件与红线
- `references/metrics-baseline.md` — 各项成本的实测口径与命令示例（示例，非清单）
- `references/reporting-rules.md` — 状态三态、三种语气、不主动造文档

