# `docs/superpowers/` — specs 与 plans 的保留规则

> 立于 2026-08-03（[[INFRA-F96]]）。判据的完整设计与实测依据 = [`specs/2026-08-03-infra-f96-plan-spec-lifecycle-design.md`](./specs/2026-08-03-infra-f96-plan-spec-lifecycle-design.md)。
> **本文件是规则真源，机械执行由 `pnpm audit:plan-lifecycle` 负责**（L4 pre-commit + L5 prepublishOnly）。

---

## 两个目录，两条不同的规则

| 目录 | 是什么 | 寿命 | 谁在管 |
|---|---|---|---|
| [`specs/`](./specs/) | **设计推理** —— 为什么选这条路、否掉了什么、前提是什么 | **无限期保留。不归档、不瘦身。** | 无闸（刻意）|
| [`plans/`](./plans/) | **执行脚手架** —— 做哪些步、写哪些代码、怎么验 | **到「仓库里没有任何东西再指向它」为止** | `audit:plan-lifecycle` |

### 为什么两条规则不同（一句话版）

实测：`specs/` 95.8% 是散文，18/29 份被引用，其中 6 处引用来自**代码、测试、闸、skill**；
`plans/` 42% 是代码块，28 份里 22 份只有 1 个 commit（写完就没人再碰），18 份全仓零引用。

**失效模式不对称**：
- 丢一份 plan = 少一份已完成工作的执行记录 —— 而它留着反而会**继续提供指令**（`STATUS.md` §三 18 此刻就写着某份 live plan 的 Task 6 Step 2③「那句是错的，别照抄」）。
- 丢一份 spec = **一个已经拍过的决策被重新拍一遍，或者被"已经否决过的理由"推翻**。

---

## `plans/` 的规则

### 判据：**可达性**，不是「做完没」

一份 plan 留在 `plans/` 的唯一条件是 **仓库里有东西指向它**（`STATUS.md` / `backlog.md` / pickup / 代码注释 / 另一份 live plan，都算）。

**为什么不按「做完没」判**：checkbox 勾选率实测 **3.9%**，且三个确认已发布的 plan **一个都没勾** → 勾选状态与真实完成度已证无关，机械判不了。
**为什么不按「目录别超过 N KB」判**：那个判据被规避的方式是「把内容挤进别的目录」，总量不降。
**可达性判据被规避的方式**是「从 `STATUS`/`backlog` 指向它」—— 那正是 owner「唯一真源、别处一律引用」裁定要的动作，所以逃逸方向是对的。

### 到期怎么办

```bash
git mv docs/superpowers/plans/<file>.md docs/_archive/superpowers/plans/
```

**归档，不删除。** git 历史完整，需要时 `git log --follow` / `git show` 取回。

> ⚠️ 归档是**迭代收敛**的：移走一批后，只被它们引用的另一批会掉到零引用 —— 闸下次会自己点名。这是正确行为，不是缺陷。

### ⛔ 归档前必做：抢救扫描

已完成的 plan 里**可能夹着只写在那里的、仍然生效的约束**。
[[INFRA-F84]] 删档时就撞上过一条：`build:wc` 必须排在 `build:playground` 之前 —— 当时把它搬进了 [`scripts/check-dist-wc-freshness.mjs`](../../scripts/check-dist-wc-freshness.mjs) 的头注释才保住。

移动之前，对每份待归档 plan 过一遍：

1. 找出「未来改动仍须遵守」的规矩（`X 必须在 Y 之前` / `不能用 Z 因为会 W` / `这个值只能取 N`）。
2. 对每条 `grep -rn` 实证它在仓库别处**有没有第二家**（配套 spec / 源码头注释 / 机械闸 / 测试断言 / divergence entry / conventions 文档）。
3. **只活在 plan 里的**，先搬到**它约束的那个对象旁边**（那个脚本的头注释、那条闸的判据注释、那个测试的 why 注释），再移动。

> 判据是「有没有第二家」，不是「看起来重不重要」—— 后者是判断题，会漂。

### 写新 plan 时

同一个 commit 里从 `STATUS.md` / `backlog.md` / pickup 指它一次。
这**不是新增负担** —— 实测既有 9 个样本里 8 个本来就是同日落地指针，最大滞后 1 天（闸的 grace 期就是照这个推的）。

---

## `specs/` 的规则

**无限期保留，不归档。** 它 404 KB、不在 [L-core onboarding 路径](../STATUS.md#起手必读链路)上，不吃 onboarding 预算。

### ⛔ 明确不做：不建 spec 索引

看起来很顺的一个补充是「建一份表列出每份 spec 设计了什么」。**不做** —— 手工维护的清单 = 会漂的第二副本，正是 [[INFRA-F58]] 全部工作、`audit:rule-inventory` 的存在理由、以及 owner「唯一真源、别处一律引用」裁定在治的病。

**零引用 spec 的正解**是在**它所设计的那件东西旁边留一个指针**（像 [`scripts/audit-sort-tokens.mjs`](../../scripts/audit-sort-tokens.mjs) 头部指回自己的 spec 那样），而不是给它们建目录。

---

## 与 `docs/internal/_plans/README.md` 的关系

那一份管 **session pickup**，本文件管 **实施计划**。两者的活跃判据字面相同（全仓 0 引用），归档落点不同（`_archive/_plans/` vs `_archive/superpowers/plans/`）。

**刻意没有合并**：`_plans/` 的判据里还多一条「被 `STATUS` 固定指针引用的留原位」，与本判据的交互没测过。
闸的实现按可扩展写 —— 将来要把 `_plans/` 纳入同一条闸，改 `scripts/audit-plan-lifecycle.mjs` 里的 `MANAGED_DIRS` 一处即可。
