# Full Chain Testing

> 完整功能链路测试执行器（stack-agnostic / project-agnostic）。当多个 feature 已陆续收尾、 某条**跨多 feature 的端到端旅程（A→B→C）首次贯通**、需要为这条关键旅程织一张端到端安全网时使用： 与前三格根本不同——本格的被测对象**不是给定的，要先从系统结构里【挖掘】出来**。先从三源 （静态代码图 + 运行时 trace + spec 契约）挖出一份**跨多 feature 的通路清单（path inventory）**， 挑 P0 关键旅程，再端到端验证、固化成安全网。覆盖跨多 feature 且含非 UI 跳步（定时任务 / 异步 / 跨通道）的 完整链路；单 feature 内单切片归"局部前后端"第三格，不在这里。两个最独特点：① 被测对象要先被挖掘出来； ② 它是**安全网层**——少而精只盖 P0；**若 bug 首次在这层被发现，说明下层（单后端/单前端/局部前后端）漏测了， 应回补下层**。六步闭环：挖通路+选 P0 → 全系统编排+只 stub 外部边界 → 条件命中 → 两层落地 → RED→GREEN（禁 sleep， fake clock/手动触发定时任务/poll-retry 等最终态）→ 归档+拆栈+PR 人审。触发词：完整功能链路 / 端到端旅程 / 跨 feature 测试 / 通路挖掘 / path inventory / 关键旅程 / 安全网 / journey 测试 / full chain testing / e2e journey / 链路贯通测试。天然要最多代码才能跑、是最后才能执行的一格；代码未落地时只能"挖候选通路 + 写 RED E2E"不能跑。遵循 testing-system-blueprint 蓝本（风险分级 / 可追溯 / 发布门 / 三层节奏），受自愈护栏约束 （只写测试不改产品码、断言不可弱化、禁伪造修复、有界重试、产 PR 人审，发现真 bug 回交 superpowers TDD）。 被 test-routing-advisor 判定"完整功能链路"时调用，也可直接触发。兄弟：backend-testing（单后端）/ frontend-testing（单前端）/ fullstack-slice-testing（局部前后端）。

- Skill: `fufankeji/full-chain-testing` (Agent Skill, multi-file: 24 files)
- Install (CLI): `npx skillmds@latest add fufankeji/full-chain-testing`
- Raw SKILL.md: https://api.skillmd.com/api/skills/fufankeji/full-chain-testing/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: fufankeji (https://skillmd.com/u/fufankeji)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/fufankeji/full-chain-testing

---


# full-chain-testing · 完整功能链路测试执行器

## 这个 skill 解决什么

前三格各自盯一个**给定的、范围明确的**被测对象：`backend-testing` 验单后端的真实、`frontend-testing`
验单前端的渲染与交互契约、`fullstack-slice-testing` 在**单个 feature 内**把一条消费者↔提供者切片拉活对账。
它们的共同前提是——**被测对象是已知的，边界由那个 feature 划好了**。

**完整功能链路是第四格，它解决的是另一类问题：当多个 feature 陆续完成后，一条"用户从 A feature 走到
B feature 再到 C feature"的端到端旅程会【首次贯通】。这条旅程跨多个 feature、常常含非 UI 的跳步
（定时任务触发、异步消息、跨通道投递），从来没有任何一格盯过它整条是否真的连得起来。**
本格就是给这类**跨多 feature 的关键旅程**织一张端到端安全网。

> **本质一句话**：完整功能链路 = **先从系统结构里挖出一条条跨多 feature 的端到端通路（path inventory）
> → 挑出 P0 关键旅程 → 端到端验证，作为安全网。** 覆盖**跨多 feature**、且**含非 UI 跳步**
> （定时任务 / 异步 / 跨通道）的完整链路。**单 feature 内的单条切片归第三格"局部前后端"，不在这里。**

遵循 `testing-system-blueprint` 蓝本（按名引用即可）：风险分级排序、可追溯 ID、发布门、三层节奏（本格落 L3）。

---

## 两个最独特点（务必先读懂——它们决定了本格与前三格的根本不同）

### 独特点 ①：被测对象要先被【挖掘】出来

前三格的被测对象是**给定的**（"测这个后端""测这个前端""测这条切片"）。本格不是——**没有人会
直接告诉你"完整链路有哪几条"**。一条跨多 feature 的旅程散落在多个 feature 的代码、配置、契约里，
**它作为一个整体从未在任何一处被显式声明过**。所以本格的第一项、也是最核心的工作，是**把通路从
系统结构里挖出来**（path inventory）。挖通路的方法论见下方 ⭐ 三源模型——这是本 skill 最核心、已实证的部分。

### 独特点 ②：它是"安全网层"，少而精只盖 P0

链路 E2E 慢且脆（蓝本 §三 L3）。本格**不追覆盖率**，只对**挖出来的通路里风险最高的 P0 关键旅程**
织网——"整条链路确实贯通"这件 L1/L2/前三格无法覆盖的事，才是它存在的唯一理由。由此引出一条铁律：

> **若某个 bug 是【首次】在本层（链路 E2E）被发现的，那是下层漏测的信号——说明它本该在单后端 /
> 单前端 / 局部前后端被更便宜地抓住，却漏了。此时除了让链路转绿，更要【回补下层】，把这个缺陷
> 在它本该被抓住的那一格补成回归。** 链路层是"补网"，不是"首次发现 bug 的垃圾桶"（蓝本 §三 L3 心态）。

---

## 两条绝对约束（先读，贯穿全程）

1. **stack-agnostic（栈无关）**：所有能力一律用"**能力描述 + 按栈/场景实例化 lookup**"表达，绝不把某一
   工具写死成依赖或唯一答案。本文与 `references/gaps.md` 里出现的 **glia / OpenLore / Pathfinder /
   Tracetest / docker-compose / OpenTelemetry / AppMap / eBPF / gstack `/qa`** 等，**全部只是"某栈/某场景的
   实例示例"，绝不是唯一解，更不是硬依赖**。环境里没有某个工具，就回退到该能力的通用等价物。
   - **特别提醒（glia）**：glia 是**非商业 license**——可作"静态代码图"能力的示例提及，但**商业产品不可用**；
     更重要的是**本 skill 不绑定任何单一工具**，静态图能力可由任意等价物实例化（OpenLore 式或该栈自带的
     调用图 / 依赖分析）。
   - **gstack `/qa` 不是硬依赖**——它只是"diff-aware E2E"在某环境下的一个实例；没有它就回退通用 E2E。
     本 skill 不写任何 gstack 安装步骤。
2. **project-agnostic（项目无关）**：不出现任何业务名词，也不绑定任何具体框架或协议。所有**项目专有**的东西
   ——具体有哪些 cron / 定时任务、某跳步是不是流式（SSE / WebSocket / 长轮询）、具体接口形状、token / 鉴权
   / 一次性登录机制、跨通道用什么、项目里到底有没有 gstack——**一律运行时现读、绝不写进 skill，也绝不预设**。
   一律写成**条件式**："**若旅程含定时触发，则用 fake clock / 手动触发**……"、"**若某跳步是流式，则**……"。

---

## ⭐ 通路挖掘 = 三源模型（本 skill 最核心、已实证的部分）

挖通路不能靠单一信息源——**没有任何一个源能挖出整张图**。本格的核心方法论是**三源互补**：每个源
**只可靠地挖得动一类边**，合起来才拼得出一条完整的跨 feature 通路。这是被两个真实项目 + 控制实验坐实的结论。

```
静态代码图（glia / OpenLore 式，按栈实例化）   → 可靠挖出：后端路由 / 资源 / 调用图 / 共享依赖
                                                  （语法指纹清晰的边）
运行时 trace（分布式追踪 / AppMap 式）          → 现代前端栈下【唯一可靠地】补：
                                                  FE↔BE 桥边 + 解耦边（HTTP / cron / 异步 / 跨通道）
spec 契约（项目自己的跨 feature 契约表 / AC）   → 兜语义 + 代码未落地时的【唯一真理源】
```

**三源各自的边界、能力、与已知失败模式（写进 skill 当"已知失败模式"，下次别再踩）：**

### 源 A · 静态代码图（按栈实例化，glia / OpenLore 为示例，非依赖）

**能挖**：后端路由、资源、调用图、共享依赖——凡是**语法指纹清晰的边**（一个函数显式调另一个、一个
路由显式挂某 handler、多 feature 显式 import 同一个共享模块），静态图都挖得很准。

**已知失败模式（两个真实项目 + 控制实验坐实，务必当成已知事实写入认知）**：
- **静态图只挖得动"半张图"**——只覆盖语法清晰的边。
- **挖不动"框架封装的跨服务请求边"**：现代前端**基本不写裸 `fetch`**，只要请求经过**框架封装**
  （AI-SDK / 自建 client / 模板 URL 拼接 等），**FE↔BE 桥边就在静态图里断掉**。这已在**两个独立项目
  各自复现**，且**控制实验证明 resolver 本身没坏**（把同样的调用还原成裸 fetch 就能被挖到）——
  即这不是工具 bug，而是"框架封装吃掉了语法指纹"的**结构性边界**。
  → **结论：FE↔BE 桥边必须靠源 B（运行时 trace）或源 C（spec 契约）补，不能指望静态图。**
- **cron / queue 这类解耦边**：静态 resolver 的 corpus 稀疏（corpus-sparse）、命中不乐观。
  → **优先靠源 B（trace）/ 源 C（spec）补，别死磕静态图。**

### 源 B · 运行时 trace（分布式追踪 / AppMap 为示例，非依赖）

**唯一可靠地补静态图挖不动的两类边**：① **FE↔BE 桥边**（框架封装吃掉语法指纹后，只有真跑一遍、
看 trace 才知道前端那次交互到底打了哪个后端端点）；② **解耦边**（HTTP / cron / 异步消息 / 跨通道
投递——这些边在代码里是"发了就走、另一头另起炉灶"，静态连不起来，trace 能把同一条 trace-id /
correlation-id 串起来）。

**实例化 lookup（非唯一解）**：分布式追踪（OpenTelemetry 式）/ 执行轨迹录制（AppMap 式）/
内核级观测（eBPF 式）——按栈与可观测设施现读现选；环境没有就退到"加临时日志埋点 + 手动跑一遍串边"。

### 源 C · spec 契约（项目自己的跨 feature 契约表 / AC，不依赖任何工具）

**兜两件事**：① **语义**——trace 能告诉你"A 之后真的调了 B"，但**为什么调、这条边属于哪条业务旅程、
这条旅程的 P0 验收点是什么**，要回到项目自己的 spec / 跨 feature 契约表 / AC 里读。② **代码未落地时的
唯一真理源**——见下方时机说明。

**已知失败模式**：**代码未落地时（链路只存在于 spec 里），静态工具与 trace 全瞎**（没有代码可分析、
没有运行时可追）。→ **此时 spec 契约是唯一真理源**，仍可据它"挖候选通路 + 写 RED E2E"（写好但还不能跑绿）。

> **三源合用的纪律**：先用源 A 挖出后端骨架（半张图），再用源 B 把 FE↔BE 桥边和解耦边补齐成整张图，
> 全程用源 C 兜语义、定 P0、并在代码未落地时充当唯一真理源。**任何一源缺位都拼不出完整跨 feature 通路。**

---

## 工作流（六步闭环）

> 骨架与前三格同构，**差异集中在步骤 0"挖通路"（独特点 ①）与"安全网层"心态（独特点 ②）**。

### 步骤 0 · 挖通路（三源）+ 选 P0

1. **三源挖通路**（见上方 ⭐ 三源模型）：源 A 挖后端骨架 → 源 B 补 FE↔BE 桥边 + 解耦边 → 源 C 兜语义。
   产出一份**跨多 feature 的通路清单（path inventory）**：每条通路记录它**穿过哪些 feature、含哪些跳步**
   （UI 可走段 / 定时 / 异步 / 跨通道）。
2. **选 P0 关键旅程**（P0 = 风险/优先级四档 P0–P3 里**最高档**，P0 最高→P3 最低；完整判据见蓝本
   `risk-tiers.md`）：按蓝本 §一 风险分级，从通路清单里**只挑 P0**（数据损坏 / 越权 / 资金额度错算 /
   核心主流程不可用 / 不可撤销的对外投递 等"出事即不可逆 + 高频"的旅程）。**安全网少而精——不要把通路清单里每条都织成 E2E。**
3. **确认"跨多 feature"**：每条入选旅程必须**真的跨多个 feature**。若某条其实只在单 feature 内（哪怕含
   前后端），它属第三格"局部前后端"，**剔出本格**，回交 `fullstack-slice-testing`。

> 挖不出明确的跨 feature 通路、或拿不到任何一源（栈不可分析 + 无可观测 + 无 spec）就停下来问，别假设。

### 步骤 1 · 全系统编排 + 外部边界 stub（本格"立地基"）

链路 E2E 要把**整条旅程穿过的所有 feature + 它们依赖的中间件**一起、可复现地拉活——比第三格"起两侧"
范围更大。这一步只做一件事：**让整条 P0 旅程能一键、可复现地以真实形态起来，健康检查通过**。

- **内部全真**：旅程穿过的所有内部 feature / 服务 / 中间件（DB / 缓存 / 队列 / 调度器…，**具体有哪些
  运行时现读**）一律以真实形态参与——这正是链路测试的价值，**禁止把被测的内部 feature stub 掉**
  （stub 掉就退化、失去意义，见护栏）。
- **只 stub 外部第三方边界**：仅对**系统边界之外、不可控、贵或慢**的第三方依赖打桩——**典型如 LLM /
  推送通道 / 支付**。具体哪些是"外部边界"运行时现读，别预设。
- 复用项目里**现成的编排定义**（compose / 启动脚本 / CI service 段，运行时现读）；没有才按栈实例化最小编排。
- **冒烟验证地基可用**：起栈后先打通一条最简单的真实旅程，证明整条链能动，再进入分层断言。
  **这一步绿之前，不写任何链路断言。**

### 步骤 2 · 条件命中（每条 P0 旅程含哪些跳步）

对每条入选旅程，**运行时确认它实际含哪些跳步类型**，决定后面怎么驱动、怎么断言：

| 跳步类型 | 含义 | 落地方式（步骤 3/4 据此选） |
|---|---|---|
| **UI 可走段** | 旅程里有用户在界面上真的点 / 输入的段 | 可选 diff-aware E2E（gstack `/qa` 为其一）或通用 E2E 驱动；**非依赖，无则回退** |
| **定时触发** | 旅程靠 cron / scheduler 推进（非 UI 跳步） | **编排驱动**：fake clock 控时 / 手动触发该定时任务，**绝不真等到那个钟点** |
| **异步** | 旅程靠消息 / 队列 / 后台任务推进 | **编排驱动** + poll-retry 等最终态（有界重试，不固定 sleep） |
| **跨通道** | 旅程跨入站 / 出站通道（如经第三方通道再回） | **编排驱动** + 在外部边界 stub 处观测投递、断真实落点 |

> **"含非 UI 跳步"是本格区别于纯前端 E2E 的关键**：一条完整链路常常是"用户点一下 → 定时任务半夜
> 生成 → 异步推送到某通道 → 用户在另一端收到"。**非 UI 跳步用编排驱动**（手动触发 / fake clock /
> 观测异步最终态），**不能靠在 UI 上干等**。

### 步骤 3 · 两层落地

对每条 P0 旅程，按"先黑盒贯通、再结构化断言"两层落地：

1. **第一层 · 黑盒贯通**：在已起好的全系统真栈上，把整条旅程**端到端跑一遍**，确认"A→B→C 整条确实通"。
   - **UI 可走段**：若环境**已有** diff-aware E2E 工具（gstack `/qa` 为其一）优先用（聚焦改动相关的旅程、省时）；
     **没有就回退通用 E2E**（Playwright / Cypress 或该栈等价物）。本 skill 不写其安装步骤。
   - **非 UI 跳步**：用**编排驱动**把旅程推过去（手动触发定时任务 / fake clock 推进 / 发一条真实消息 /
     在 stub 边界观测投递）。
   - 再次强调：E2E 工具**只探测已跑的 localhost、不起栈**——所以**步骤 1 起栈必须已完成**。
2. **第二层 · 结构化链路断言**：沿旅程的**关键交接点**逐点断言（A 的输出真的成了 B 的输入、B 的产物真的
   触发了 C、跨通道投递真的落到正确终点、最终态真的达成且一致）。黑盒贯通只证"通了"，结构化断言才证
   "**每个交接点逐项对得上**"——这才是把安全网固化成回归的部分。

> 具体工具与断言模式见 `references/gaps.md`，按步骤 0 挖通路时识别的栈 / 跳步类型取对应行。

### 步骤 4 · RED→GREEN（禁 sleep）+ 数据隔离

1. **数据隔离先行**：链路 E2E 跑在全系统真栈上、穿过多个 feature 的数据，**必须有 seed / teardown
   fixture** 保证整条旅程的数据可控、互不污染、可重复（起一份已知数据 → 跑整条旅程 → 清掉）。
2. **控时与等待的铁律（最易踩、护栏级）**：
   - **禁 `sleep` / `waitForTimeout` 假装就绪或假装到点**——链路含定时 / 异步跳步时，固定睡眠既慢又脆且骗人。
   - **定时跳步**：用 **fake clock 控时** 或**手动触发该定时任务**，把旅程"快进"到目标时点。
   - **异步 / 跨通道跳步**：用 **poll-retry 等最终态**（有界重试轮询到目标状态），而非固定睡固定秒数。
3. **RED**：先写会失败的链路断言，确认它**因真实链路缺陷而红**（某交接点对不上、解耦边没接上、最终态没达成），
   而不是因为栈没起好 / 测试写错 / 睡眠不够而红。**真红有理**，才往下走。
4. **GREEN**：让断言转绿。
   - 若红暴露的是**真实链路 bug**——**HALT，不要自己改产品码**（见护栏），回交
     `superpowers:test-driven-development` / `superpowers:systematic-debugging` 修，修完再回本 skill 固化回归。
   - **并且**（独特点 ②）：**判断这个 bug 是不是"首次在链路层才被发现"**——若是，说明下层漏测了，
     **同时提示回补下层**（把它在单后端 / 单前端 / 局部前后端那一格补成回归，让它下次在更便宜的层被抓住）。
5. **断言不可弱化**：禁止为转绿放松断言（把交接点断言删掉、把最终态校验改宽、把时序断言注释掉、
   把禁掉的 sleep 偷偷加回来）。

### 步骤 5 · 归档（进发布门、journey 级可追溯）+ 拆栈 + PR 人审

每条新增的链路安全网测试：

- 按 `testing-system-blueprint` **风险分级**进发布门——**P0 关键旅程进发布门硬阻断**（链路断 = 核心
  业务旅程不可用）。安全网只盖 P0，所以入选的基本都是发布门硬项。
- 挂 **journey 级可追溯 ID**——关联这条旅程**穿过的多个 feature / 多个 AC / 含哪些跳步**（比单 feature
  的可追溯粒度更粗，但要能机械回答"这条跨 feature 旅程测了没"）。
- 对齐**三层节奏**：链路 E2E 属蓝本 **L3**（最慢、最脆），只放"验证整条链确实通"这一件 L1/L2/前三格
  覆盖不了的事；**不要把单元级 / 单 feature 级断言塞进链路 E2E**。
- **拆栈（teardown）**：CI 与本地节奏都是 **起全系统栈 → 跑旅程 → 拆栈**；测完把真栈与数据一并清理。
- 补测以 **PR 形式交付，由人审核合并**；PR 说明列出：挖出的通路清单摘要、入选的 P0 旅程及理由、
  每条旅程含哪些跳步、用了哪三源挖到它、外部边界 stub 了哪些、以及——若发现 bug——**它是否首次在链路层
  被发现 + 已回补到下层哪一格**。

---

## 时机说明（诚实写进 skill，别假装能提前跑）

full-chain 天然要**最多代码才能跑**——它要把整条跨多 feature 旅程穿过的所有 feature 都拉活。
因此它是**最后才能真正执行的一格**：必须等旅程穿过的那些 feature 都已落地。

- **代码未落地时**（链路只存在于 spec 里）：源 A / 源 B 全瞎（无代码可析、无运行时可追），**源 C（spec 契约）
  是唯一真理源**。此时**仍能做、且应该做**：用 spec 挖**候选通路** + 写 **RED E2E**（断言写好、挂上可追溯，
  但因代码没到而红 / 挂起，不能跑绿）。
- **方法论可先于代码建好**：本 skill 是**可复用资产**——挖通路的三源模型、安全网选 P0 的判据、编排与控时
  纪律，都可以在代码齐全之前先想清楚、先把候选通路与 RED E2E 落好。**真验证（跑绿）跟着代码走。**

---

## 关键区别于前三格（务必讲清）

| | 前三格（后端 / 前端 / 局部前后端） | 本格（完整功能链路） |
|---|---|---|
| 被测对象 | **给定的**（边界由那个 feature 划好） | **要先从三源挖出来**（独特点 ①） |
| 范围 | 单 feature（前两格单侧，第三格单 feature 内单切片） | **跨多 feature + 含非 UI 跳步**（定时 / 异步 / 跨通道） |
| 层级心态 | 各自盖各自的真实 / 接缝 | **安全网层**，少而精只盖 P0；**bug 首现于此 = 下层漏测，回补下层**（独特点 ②） |
| 起栈范围 | 一侧 / 单 feature 两侧 | **整条旅程穿过的所有 feature + 中间件**，只 stub 外部边界 |
| 执行时机 | feature 收尾即可 | **最后**才能跑；代码未落地时只能挖候选通路 + 写 RED E2E |

---

## 自愈护栏（不可越过）

补测过程允许有界自动迭代（挖通路 → 起栈 → RED → GREEN → 拆栈），但受以下护栏约束（沿用 blueprint 的护栏）：

- **只写测试 / 编排配置，不改产品码**——这是默认动作。本 skill 负责挖通路、起全系统栈、配编排、写链路断言，**不修业务实现**。
- **断言不可弱化**——禁止为转绿放松断言（删交接点断言、放宽最终态校验、注释时序断言、缩小契约比对字段集）。
- **禁伪造修复**——不得用 `skip`、**固定 `sleep` / `waitForTimeout` 假装就绪或假装到点**、把被测的**内部
  feature 偷偷 stub 掉**、起假服务冒充真栈等手段伪装通过。**本格一旦把被测的内部 feature stub 掉，
  就退化成下层、失去全部意义**（stub 只允许打在外部第三方边界上）。
- **有界重试升级**——链路 E2E 天然脆（端口竞争、健康检查抖动、异步最终态未达、跨通道延迟）；自动迭代有
  上限，连续失败达上限即停止并升级给人，**绝不靠"再跑一次就好"或"再多睡几秒"掩盖真实的链路不稳定**。
- **产 PR 人审**——所有产物（通路清单 + 编排配置 + 链路安全网测试）以 PR 交付，人工审核后合并。
- **发现真 bug 要 HALT，回交 superpowers 修**——本 skill **不自行改产品代码**。RED 暴露真实链路缺陷时
  **停下来**，回交 `superpowers:test-driven-development` / `superpowers:systematic-debugging` 走修复闭环，
  修完再回本 skill 固化回归。**并且：若该 bug 首次在链路层被发现，同时提示回补下层**（独特点 ②）——
  让它在本该被抓住的更便宜的那一格也补成回归。

护栏的目的：让链路安全网可以自动织，但任何"把被测内部 feature stub 回去""栈没真起就假装通过""靠 sleep
掩盖时序""越界改产品码"的捷径都被堵死。

---

## 与上下游的关系

- 上游：`test-routing-advisor` 判定"完整功能链路"时调用本 skill（也可被用户直接触发）。**杀手锏对接**：
  路由器从依赖图推导出"完成某 feature 后某条跨 feature 旅程 A→B→C 首次贯通"并提示"这条链路现在可以端到端
  测了"——本 skill 正是接住这个提示、把那条旅程挖实并织成安全网的执行器。
- 蓝本：所有挖通路后的分级 / 可追溯 / 发布门 / 节奏遵循 `testing-system-blueprint`（按名引用，不复制其内容）；本格落 **L3**。
- 兄弟：`backend-testing`（单后端）/ `frontend-testing`（单前端）/ `fullstack-slice-testing`（局部前后端，
  单 feature 内单切片）——三者是"下层"；**本格 bug 首现时回补的就是它们**。
- 可参考（**非依赖**）：**Pathfinder** 的 journey→E2E 骨架生成思路、**Tracetest** 的 trace→断言思路——
  作为"挖到通路后如何生成 E2E / 如何把 trace 转成链路断言"的实例参考，**不绑定、环境没有就用通用等价物**。
- 方法论复用：发现真链路缺陷的修复与调试复用 `superpowers:test-driven-development` 和
  `superpowers:systematic-debugging`（本 skill HALT 后回交它们）。
- 边界：**单 feature 内单切片**属第三格 `fullstack-slice-testing`，不在本格。

---

## 配套实现：`scripts/` 通路挖掘 + 可视化工具

本 skill 附带一套 **clean-room 自研**的参考实现（MIT，归用户所有），把"挖通路 → 合并三源 →
派生 journey → 生成 RED E2E → 可视化"这条流程做成可真跑的工具。stack-agnostic / project-agnostic：
按栈识别（读 pyproject/package.json）后处理，不写死任何业务名。**反瞎编铁律**：每条边都带 provenance
（`文件:行号` 或 `trace span`），指不出证据的边只标 `candidate`，绝不假装坐实。

中心产物 `path-inventory.json`（`scripts/pathinv.py` 定义 schema + 校验门）：
features / nodes / edges(每条带 source+status+provenance) / journeys。

| 文件 | 刀 | 语言 | 用途 |
|------|----|------|------|
| `scripts/pathinv.py` | 共享 | Python | path-inventory schema + status 升级 + `validate()` 反瞎编门 |
| `scripts/knife1_spec.py` | 刀1 源C | Python | 解析 spec-kit `tasks.md` 的 `[依赖] Fn` / `[BE/FE/INT]` / `[FR 来源]` → 跨 feature 候选边（candidate，证据=文件:行号） |
| `scripts/knife2_static.py` | 刀2 源A | Python | AST(Python FastAPI 装饰器/import/redis key/scheduler) + 正则(Next route/import/fetch/redis) → code-confirmed；**框架封装的 FE→BE（useObject/useChat）老实标 candidate** |
| `scripts/knife3_trace.py` | 刀3 源B | Python | 读 correlation-id 结构化事件日志 → trace-confirmed 边（证据=span/event） |
| `scripts/knife4_merge.py` | 刀4 | Python | 三源合并去重、status 升级、标 spec-only 缺口、派生 journey、按风险启发式标 P0（注"需人确认"） |
| `scripts/knife5_e2e.py` | 刀5 | Python | 选一条 journey → 生成 pytest/Playwright RED E2E 骨架（condition-based wait，禁 sleep） |
| `scripts/knife6_viewer.html` | 刀6 | HTML/JS | 单文件自包含（纯 DOM+CSS，无重依赖）；**给人看的"用户旅程清单"**——每条 journey 一句话 summary + 步骤流芯片，按 status 着色（candidate=虚线灰 / code=蓝 / trace=绿），点步骤看 provenance 详情；技术散点图降级为"查看技术细节"折叠 |
| `scripts/view.sh` | 一键开图 | bash | `bash view.sh demo` / `bash view.sh alpha` / `bash view.sh out/xxx.json` → 自动起本地服务 + 打开浏览器 + 数据已加载，**无需拖拽** |
| `scripts/run_pipeline.sh` | 编排 | bash | 起 demo → 注入 cid 跑旅程 → 刀2+刀3 → 刀4 合并 → 刀5 骨架，输出到 `scripts/out/` |
| `demo-app/` | 验证靶 | Python(stdlib)+HTML | 小而全多 feature demo（A 前端按钮→B 接口写 kv+异步→C cron 读 kv+推送），含全部边类型，真能跑 |

### 使用流程（触发时机 + 自动产出 + 看图）

1. **触发时机** —— **不是"全部 feature 开发完"才触发**。是**某条跨多 feature 的端到端旅程首次贯通**时
   触发(逐 journey,不是项目结尾)。`test-routing-advisor` 的"杀手锏"就是从依赖图主动发现这种"首次贯通"
   并提示——人最容易忘的就是这个。
2. **自动产出** —— 触发后,按本 skill 步骤跑 spec 解析 → 静态扫码 → trace 采集 → 三源合并,**自动产出
   `path-inventory.json`**。对 demo,`bash scripts/run_pipeline.sh` 一键真跑通;对真实项目,Claude 按 skill
   读栈、按栈实例化、跑出等价产物到 `scripts/out/`。
3. **一键看图** —— `bash scripts/view.sh demo`(或 `alpha` / 任意 inventory 路径)→ 自动起本地服务 + 打开
   浏览器 + **数据已加载**,直接进酷炫"用户旅程清单"页面,**无需拖拽**。
   (双击 `knife6_viewer.html` 后把 json 拖入页面投放区是 file:// 兜底用法,推荐用 `view.sh`。)

单点用法:对 spec 树跑 `knife1_spec.py <specs/>`、对真代码跑 `knife2_static.py <repo/>`,再
`knife4_merge.py` 合并、`knife4b_narrate.py` 补叙事——这一串其实就是步骤 2 的拆解。

