# 执行计划：M3 状态机单入口 + git 隐身全套

> 前置：已读 spec §9（外环/例外）/§10（启动序列与状态机）、不变量 8、v7-implementation-plan §1.5、M3 prd/design。
> 落点 `v7/src/state-machine/`、`v7/src/commands/next.js`、`v7/test/`。复用 M1 读接口、M2 finalize/git.js。
> 本机：`cd v7 && PYTHONUTF8=1 node --test`；零依赖延续；命令走 `run(args,options,ctx)` 契约。
> 工作方式：不开子代理；TDD（先红后绿）；诚实分期 commit。

## 分期（D1：单任务分期，git健康 → 路由+检测 → 外环流程 → DTO 缝）

```
P0 git.js 扩展 + git 健康检查（5 异常 + 安全网）+ git 异常样本库
   ↓
P1 状态机路由器 determineNextState + 序0-6 检测 + next CLI
   ↓
P2 外环脚本流程（影响分析 / 回到第N章 / 吃书 retcon）
   ↓
P3 AI 态 DTO 缝 + 落盘函数
   ↓
P4 全量 AC 复核 + 推送验证 CI（git 异常在 Windows 跑）
```

## P0 git 健康检查（D2：激进自动修 + 可恢复安全网）

- [ ] P0.1 扩展 `src/finalize/git.js`：加 `status()`、`stash(msg)`、`mergeAbort()`、`fsck()`、`config(k,v)`、`createBackupRef(name)`（错误转中文）
- [ ] P0.2 `src/state-machine/git-health.js`：`checkGitHealth(ctx) → {ok, fixed, guidance, rescued}`
  - 陈旧 `index.lock` → 自动删（记 rescued）
  - 网盘副本 `xxx (1).md`/`的冲突副本` → 归档到 `工作区/.救援/网盘副本/`（移动非删）
  - 半提交脏工作树 → `git stash`（可恢复）
  - 合并冲突 → 备份 ref + `merge --abort`
  - `.git` 损坏 → **例外**只检测 + 中文指引
  - 每次自动修在 `工作区/.救援/修复日志.md` 追加「修了什么 + 怎么撤」
- [ ] P0.3 `test/state-machine/git-health.test.js`：git 异常样本库逐个（mkdtemp+git init 造各异常），断言修复/归档/指引 + 安全网可恢复 + **零英文堆栈**

**验证 P0**：`node --test test/state-machine/git-health.test.js` 全绿
**提交 P0**：`feat(v7): M3 P0——git 健康检查激进自动修 + 可恢复安全网`

## P1 状态机路由器 + 7 态检测

- [ ] P1.1 `src/state-machine/detectors.js`：序 0-6 各检测函数（解析失败/无书/手改/工作区未完成/卷末/体检周期/其余）
- [ ] P1.2 `src/state-machine/index.js`：`determineNextState(ctx)` —— 先 checkGitHealth，再序 0-6 命中即停，返回 `{序, state, needsAI, dto?, message, gitHealth}`
- [ ] P1.3 序 0 确定性预修复：全角 `：，` 在 YAML 结构位 → 半角替换后只报不问；其余解析失败 needsAI
- [ ] P1.4 `src/commands/next.js`：`run` 契约调 determineNextState，打印中文 message
- [ ] P1.5 `test/state-machine/router.test.js`：构造命中各序的仓库，断言判定正确 + 命中即停顺序

**验证 P1**：`node --test test/state-machine/` 全绿；`webnovel-writer next` 冒烟
**提交 P1**：`feat(v7): M3 P1——状态机单入口路由 + 序0-6 检测 + next CLI`

## P2 外环脚本流程

- [ ] P2.1 `src/state-machine/flows/impact.js`：`analyzeImpact(ctx,{关键词})` grep 正文+履历+时间线，按 `已发布到章` 分两清单
- [ ] P2.2 `src/state-machine/flows/goto-chapter.js`：`gotoChapter(ctx,{chapterNum,confirm})` 定位 ch(N) commit → 展示影响 → confirm 才 reset（先建备份 ref）
- [ ] P2.3 `src/state-machine/flows/retcon.js`：`retcon(ctx,{chapterNum,原因,...})` retcon commit + 设定/条目同步（复用 M2 Writer/finalize 范式）
- [ ] P2.4 CLI：`impact`/`goto-chapter`/`retcon` 命令（run 契约）
- [ ] P2.5 `test/state-machine/flows/`：影响分析分组、回到第N章(reset+备份 ref)、吃书(retcon message+同步)

**验证 P2**：`node --test test/state-machine/flows/` 全绿
**提交 P2**：`feat(v7): M3 P2——外环脚本流程（影响分析/回到第N章/吃书）`

## P3 AI 态 DTO 缝

- [ ] P3.1 `src/state-machine/dto.js`：为序 0/1/4/6 + 分支试写组装 AI 上下文 DTO（不调 AI）
- [ ] P3.2 落盘函数：AI 产物回流由 M3 落盘（M4 不碰文件）的接口占位 + 契约
- [ ] P3.3 `test/state-machine/dto.test.js`：各 AI 态 DTO 字段齐全 + needsAI=true

**验证 P3**：`node --test test/state-machine/` 全绿
**提交 P3**：`feat(v7): M3 P3——AI 态 DTO 缝 + 落盘契约`

## P4 AC 复核 + 推送

- [ ] P4.1 全量 `node --test` 绿；过 prd Acceptance（7 态 e2e / git 异常样本库零英文堆栈 / 外环流程）
- [ ] P4.2 不变量回归（删缓存重建、定稿原子）
- [ ] P4.3 推送验证 CI 双平台（git 异常处理在 Windows 跑）

**提交 P4**：`feat(v7): M3 P4——AC 复核 + CI 双平台`

## 回滚点

- 各 P 独立，未提交前 `git restore v7/` 对应子目录
- P0 git.js 扩展单点；P2 回到第N章/吃书涉及 git reset，务必先备份 ref

## 出口判据（对齐 prd Acceptance）

> 重建后状态（2026-06-27，全量 `node --test` 200 绿）：

- [x] 7 个态各有端到端测试（router.test 命中各序 0-6 + 命中即停）
- [x] git 异常样本库逐个演练（陈旧锁/网盘副本/半提交/合并冲突/.git 损坏），零英文堆栈，安全网可恢复（git-health.test）
- [x] 影响分析/回到第N章/吃书 纯脚本流程有测试（flows/*.test）
- [x] 不破坏 M1/M2 不变量（删缓存重建、定稿原子；M1/M2 测试仍全绿）
- [x] CI 双平台绿（git 异常处理在 Windows 验证）：4 矩阵 job 全绿（run 28289468867，含两个 windows-latest）
