# 端到端演练:HR 招聘后台(4 场景全跑通)

> 这是给学员看的完整演练 demo。
> 角色:小王,某互联网公司 HR 专员,Excel 管候选人管到崩溃,想做个内部工具。
> 目标:跟业务助手智能体(本 Skill)从 0 到 1 把招聘后台做出来,并经历 4 种典型往返。
> 读这份 demo 之前,请先看 `examples/README.md` 入门。

## 0. 这次演练的「剧本」

| 阶段 | 动作 | 触发场景 |
| --- | --- | --- |
| 阶段一 | 3 轮对话搞清楚业务 | — |
| 阶段二 | 写出 PRD v0.1 | — |
| 阶段三 | 第一次生成 demo | — |
| 场景 A | 加一个「面试官评分 1-5」字段 | 改 PRD 后再生成 |
| 场景 B | 把对话里补充的「业务规则」合并到 PRD | 对话并入 PRD |
| 场景 C | 流程大改:加「笔试」环节 | 重大改动重生成 |
| 场景 D | 首页仪表盘数字调大、换公司蓝 | 视觉微调 |

下面所有「学员说」都是小王原话,所有「Skill 说」都是 Skill 应该输出的话(学员看到的)。

---

## 阶段一:需求发现(3 轮对话)

### 第 1 轮:角色 + 痛点

> 学员说:
> 我是 HR 专员,平时用 Excel 管候选人,候选人多了根本管不过来,经常漏掉简历、漏约面试,想搞个工具。

> Skill 说:
> 收到。听起来你现在的痛点是「候选人多、流程乱、容易漏」。我接着问两个问题,问完就给你出产品文档。
> 1. 这个工具主要给你自己用,还是 HR 团队几个人一起用?
> 2. 一个候选人从你收到简历到入职,中间大致要走几步?每一步你大概做什么?

### 第 2 轮:核心功能 + 字段

> 学员说:
> 主要是给我自己用,偶尔组长会看。流程是这样的:业务部门先发「招聘需求」(岗位、人数、要求),我在招聘网站收简历,把候选人录入,然后 HR 面试 → 业务面试 → 管理层终面 → 发 offer → 入职。每轮面试要记评价。

> Skill 说:
> 明白了。最后一个问题,我想确认下:
> 1. 除了「候选人主表」,你还需要单独维护「招聘需求」和「面试评价」吗?(我建议分开,更清晰)
> 2. 候选人要记录哪些字段?我先猜几个你看够不够:姓名、应聘岗位、来源渠道、当前阶段、最近联系时间、备注。

### 第 3 轮:风格 + 字段确认

> 学员说:
> 字段差不多,再加一个「期望薪资」吧。需求和面试评价分开放,这样我能从需求看进度。
> 风格不用太花哨,简洁能用就行,像 Vercel 那种。

> Skill 说:
> 好的,我现在去写产品文档,会写到 `outputs/prd-hr-recruitment-v0.1.md`,写完我告诉你。

**阶段一执行清单(对照 `SKILL.md` 第 3 节)**

- [x] 第一轮:问角色 + 痛点
- [x] 第二轮:问核心功能 + 流程
- [x] 第三轮:问字段 + 风格
- [x] 告诉用户接下来要出 PRD
- [x] 没有一次问 10 个问题把用户淹没

---

## 阶段二:PRD 自动生成 v0.1

Skill 写出 `outputs/prd-hr-recruitment-v0.1.md`,关键内容(节选):

```markdown
---
产品名: HR 招聘后台
版本: v0.1
最后更新: 2026-06-09
---

## 1. 产品定位

为 HR 专员提供一个集中管理招聘需求、候选人、面试评价的内部工具,
替代当前用 Excel 管理候选人时容易漏掉简历、漏约面试的痛点。

## 2. 目标用户

- 主要:HR 专员(自己用)
- 次要:HR 组长(只看统计和进度)

## 3. 使用场景

- 每天:查看候选人进度、安排面试、记录面试评价
- 每周:汇总招聘需求完成情况、统计漏掉的简历

## 4. 核心功能列表

- [x] P0 招聘需求管理(发布、编辑、关闭)
- [x] P0 候选人管理(录入、编辑、状态推进、删除)
- [x] P0 面试评价记录(HR 面试 / 业务面试 / 管理层终面)
- [x] P0 仪表盘(招聘需求完成度、漏掉的简历提醒)
- [ ] P1 候选人搜索、按岗位筛选
- [ ] P1 导出候选人 Excel

## 5. 字段定义

### 5.1 招聘需求

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| 标题 | 文本 | 是 | 例如「高级前端工程师」 |
| 部门 | 文本 | 是 | 业务部门 |
| 人数 | 数字 | 是 | 招聘人数 |
| 状态 | 枚举 | 是 | 开放/已满/已关闭 |

### 5.2 候选人

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| 姓名 | 文本 | 是 |  |
| 应聘岗位 | 关联 | 是 | 关联到招聘需求 |
| 来源渠道 | 枚举 | 否 | BOSS/拉勾/猎聘/内推 |
| 当前阶段 | 枚举 | 是 | 简历筛选/HR 面试/业务面试/管理层终面/已发 offer/已入职/已淘汰 |
| 最近联系时间 | 日期 | 否 |  |
| 期望薪资 | 数字 | 否 | 单位:千元 |
| 备注 | 文本 | 否 |  |

### 5.3 面试评价

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| 候选人 | 关联 | 是 | 关联到候选人 |
| 面试轮次 | 枚举 | 是 | HR 面试/业务面试/管理层终面 |
| 面试官 | 文本 | 是 |  |
| 评价 | 文本 | 是 |  |
| 日期 | 日期 | 是 |  |

## 6. 视觉风格

- 风格:Vercel / shadcn UI 风格,简洁清晰
- 左侧主导航,顶部 16px 固定栏
- 浅色 + 深色双主题
- 5 种状态色(绿/黄/红/蓝/灰)

## 7. 业务规则

- 候选人必须依次经过 HR 面试 → 业务面试 → 管理层终面 → offer
- 同一候选人同一轮次可以有多次面试评价(允许二面)
```

> Skill 说:
> PRD 已经写到 `outputs/prd-hr-recruitment-v0.1.md`。
> 请逐项审阅:产品定位、目标用户、核心功能、字段定义、视觉风格、业务规则。
> 有问题直接说「修改 XX 部分」,没问题就说「OK 开始生成 Demo」。

**阶段二执行清单(对照 `SKILL.md` 第 4 节)**

- [x] PRD 写到文件,不写到对话
- [x] 包含产品定位/目标用户/使用场景
- [x] 包含核心功能列表(按优先级)
- [x] 包含字段定义
- [x] 包含视觉风格
- [x] 等用户确认,没闷头生成 Demo

> 学员说:OK

---

## 阶段三:网页应用自动生成

Skill 基于 PRD 生成 `outputs/demo-hr-recruitment/index.html`(单文件 HTML,55KB 左右),完成后告诉学员:

> Skill 说:
> Demo 已经写到 `outputs/demo-hr-recruitment/index.html`。
> 双击在浏览器打开就能用,数据存在 localStorage,刷新不丢。
> 包含 6 个视图:仪表盘 / 招聘需求 / 候选人列表 / 候选人看板 / 面试评价 / 设置。

学员打开 demo,看到左侧导航、浅色主题、能新建招聘需求、能录入候选人、能切换候选人阶段。点击保存按钮后刷新页面,数据还在。

**阶段三执行清单(对照 `SKILL.md` 第 5 节)**

- [x] 单文件 HTML,所有 CSS/JS 内联或 CDN
- [x] 主导航在左侧(`lg:pl-60` + `<aside>` 固定左侧)
- [x] 顶部 16px 固定栏
- [x] 浅色/深色双主题
- [x] 5 种状态色配对
- [x] Tailwind safelist 包含动态状态色类
- [x] lucide 图标(零 emoji)
- [x] 每个图标按钮带 aria-label
- [x] Modal 含 ESC 关闭 + click.outside 关闭
- [x] localStorage 持久化(`hr-recruitment__data_v1`)
- [x] 移动端适配 + 抽屉式左侧导航
- [x] CRUD 全部真的能用(对照 `references/crud-pattern.md`)

---

## 场景 A:加一个字段

学员用了一周 Demo,业务部门反馈「面试官有没有认真面试我们也不知道」,想给每个面试评价加个「面试官评分 1-5」。

> 学员说:再加一个「面试官评分」字段,1-5 分,放在面试评价里。

### A.1 Skill 内部判断(30 秒)

这是一次典型的「改字段」反馈 → 路由到**场景 A:用户完善 PRD 后再次生成**。

### A.2 Skill 准备改动

1. PRD 5.3 节「面试评价」字段表追加一行
2. PRD 顶部版本 v0.1 → v0.2
3. 演示代码的面试评价 Modal 加这个字段 + 列表里展示
4. CHANGELOG.md 顶部加一段
5. localStorage 读取处加 `score ?? null` 兜底(老数据没有这个字段不崩)

### A.3 Skill 先告诉用户要改什么

> Skill 说:
> 我准备做 3 处改动:
> 1. PRD `5.3 面试评价` 加一行「面试官评分(数字 1-5,选填)」,版本升到 v0.2
> 2. Demo 的「面试评价」弹窗加这个字段,列表里展示出来
> 3. CHANGELOG.md 加一条 v0.2 记录
> 老数据兼容:没有这个字段的旧评价会显示为「—」。
> 确认后我改。

### A.4 学员确认后,Skill 实际写入

PRD 5.3 节插入:

```markdown
| 面试官评分 | 数字 | 否 | 1-5 分,业务部门可见 |
```

代码关键片段(Alpine.js data + 模板):

```javascript
// data 里加字段
const defaultEval = { id: ..., 候选人, 面试轮次, 面试官, 评价, 日期, 面试官评分: null };

// 保存时兜底
saveAll(items.map(x => ({ ...x, 面试官评分: x.面试官评分 ?? null })));

// 模板展示(用中文「/5」避免引号转义问题)
<td>
  <span x-text="item.面试官评分 ? item.面试官评分 + String.fromCharCode(47) + String(5) : String.fromCharCode(0x2014)"></span>
</td>
```

更直观的写法(单引号转义用 \):

```javascript
// 或者用反引号包字符串,避开单引号转义
<td>
  <span x-text="item.面试官评分 ? item.面试官评分 + `/5` : `—`"></span>
</td>
```

CHANGELOG.md 顶部新增:

```markdown
## v0.2 - 2026-06-15 - 新增面试官评分字段

业务反馈:业务部门希望看到面试官对候选人的打分。

### 变更

- 字段:`面试评价.面试官评分`(数字 1-5,选填)
- PRD:5.3 节,版本 v0.1 → v0.2
- Demo:面试评价 Modal 加输入框,列表加展示列

### 数据兼容

- 老评价无此字段,读取时显示「—」,不报错
```

### A.5 改完后告诉学员

> Skill 说:
> 改完了,这次改了 3 处:
> 1. PRD 5.3 加了一行 + 升到 v0.2
> 2. Demo 面试评价 Modal 加了输入框,列表里会展示「X/5」
> 3. CHANGELOG.md 顶部加了一段 v0.2 记录
> 老数据兼容,没有评分的评价显示「—」。
> 验证方法:打开 Demo → 面试评价 → 新建一个评价 → 输入 4 → 保存 → 列表里看到「4/5」。

**场景 A 自检(对照 `references/iteration-patterns.md` 第 2 节)**

- [x] 30 秒判断属于场景 A
- [x] PRD/代码/CHANGELOG 三件套一起改
- [x] 数据兼容(老字段 `?? null`)
- [x] 改完告诉用户「改了什么 / 数据兼容 / 怎么验证」

---

## 场景 B:把对话内容合并到 PRD

学员继续用了两周,中间跟 Skill 提过一些零碎业务规则,现在想让 Skill 把这些都正式写进 PRD。

> 学员说:把咱们之前聊天里说的那些业务规则也写到 PRD 里

### B.1 Skill 抽取对话事实

Skill 回看过去几周的对话,挑出 4 条事实陈述(过滤掉寒暄、确认、疑问):

1. 「我们的业务部门希望,候选人通过 HR 面试后,24 小时内必须安排业务面试,否则系统要提醒 HR」
2. 「已淘汰的候选人保留 90 天,90 天后系统自动删除」
3. 「管理层终面必须有 HR 组长参与,业务部门自己不能跳过 HR」
4. 「招聘需求发布超过 60 天没招满,自动标记为暂停」

### B.2 Skill 去重 + 定位

和当前 PRD 比对:

- 事实 1 → 新增,合并到 PRD 第 7 节「业务规则」
- 事实 2 → 新增,合并到 PRD 第 7 节「业务规则」
- 事实 3 → 和现有规则「业务部门不能跳过 HR 终面」部分重复,需要补全
- 事实 4 → 新增,合并到 PRD 第 7 节「业务规则」

### B.3 Skill 在对话里展示合并草案(不打文件)

> Skill 说:
> 我准备把以下 4 条对话内容合并到 PRD 第 7 节「业务规则」,版本 v0.2 → v0.3:
>
> 1. **(新)** 候选人通过 HR 面试后 24 小时内必须安排业务面试,系统超期提醒
> 2. **(新)** 已淘汰候选人保留 90 天,到期自动清理
> 3. **(补全)** 管理层终面必须有 HR 组长参与,业务部门不可跳过
> 4. **(新)** 招聘需求发布超过 60 天未招满,自动标记为「暂停」
>
> 确认后我写入 PRD。

### B.4 学员确认

> 学员说:第 3 条改成「必须有 HR 组长在场」,不是「参与」。其他 OK。

### B.5 Skill 写入(打文件)

PRD 第 7 节追加 4 条 + 版本升到 v0.3:

```markdown
## 7. 业务规则

- 候选人必须依次经过 HR 面试 → 业务面试 → 管理层终面 → offer
- 同一候选人同一轮次可以有多次面试评价(允许二面)
- **(v0.3 新增)** 候选人通过 HR 面试后 24 小时内必须安排业务面试,系统超期提醒
- **(v0.3 新增)** 已淘汰候选人保留 90 天,到期自动清理
- **(v0.3 补全)** 管理层终面必须有 HR 组长在场,业务部门不可跳过
- **(v0.3 新增)** 招聘需求发布超过 60 天未招满,自动标记为「暂停」
```

CHANGELOG.md 顶部加:

```markdown
## v0.3 - 2026-06-22 - 业务规则补充

### 变更

- 合并对话中的 4 条业务规则到 PRD 第 7 节
- 版本 v0.2 → v0.3

### 下一步

PRD 改完了。要重新生成应用吗?这些规则会落到 Demo 的提醒和自动任务里。
```

### B.6 Skill 主动询问要不要重生成

> Skill 说:
> PRD 改完了,版本升到 v0.3。
> 这 4 条规则里有 3 条涉及 Demo 的逻辑改动(超期提醒、90 天清理、60 天暂停),需要重新生成应用才会生效。
> 要我现在重新生成吗?

**场景 B 自检(对照 `references/iteration-patterns.md` 第 3 节)**

- [x] 显式触发「把刚才的也写进 PRD」
- [x] 抽对话事实(过滤寒暄/确认/疑问)
- [x] 去重 + 定位到对应章节
- [x] 给用户看合并草案(不直接打文件)
- [x] 用户可以微调草案(第 3 条措辞)
- [x] 写入文件 + 升版本 + 写 CHANGELOG
- [x] 主动询问要不要重新生成应用

---

## 场景 C:PRD 重大改动重生成

一个月后,公司换了招聘流程:HR 面试 → **笔试** → 业务面试 → 终面。

> 学员说:流程大改一下,HR 面试和业务面试中间加一个笔试环节,笔试不通过直接淘汰。

### C.1 Skill 判断(30 秒)

- 影响字段:候选人「当前阶段」枚举 + 面试评价「面试轮次」枚举
- 影响视图:候选人看板新增一列
- 影响业务规则:流程变更
- 影响 localStorage 数据结构:`当前阶段` 枚举值变化

→ 影响 > 30% 代码 → 路由到**场景 C:重大改动重生成**。

### C.2 Skill 先冻结老版本

> Skill 说:
> 这次是大改,影响 5 个地方。我建议冻结当前 v0.3 作为 snapshot,然后开 v1.0 整页重写。
>
> 冻结操作:
> - `outputs/demo-hr-recruitment/` → `outputs/demo-hr-recruitment-v0.3-snapshot-20260708/`
> - `outputs/prd-hr-recruitment-v0.3.md` → `outputs/_archive/prd-hr-recruitment-v0.3.md`
>
> 你的老数据(`hr-recruitment__data_v1`)会通过迁移函数升级,不会丢。
> 确认后我开始?

### C.3 学员确认

> 学员说:OK

### C.4 Skill 冻结 + 新 PRD + 整页重写

**新 PRD v1.0** 关键差异:

```markdown
---
产品名: HR 招聘后台
版本: v1.0 (基于 v0.3 重大重构)
最后更新: 2026-07-08
---

## 5.2 候选人(变更)

| 当前阶段 | 枚举 | 是 | 简历筛选/HR 面试/**笔试**/业务面试/管理层终面/已发 offer/已入职/已淘汰 |

## 5.3 面试评价(变更)

| 面试轮次 | 枚举 | 是 | HR 面试/**笔试**/业务面试/管理层终面 |

## 7. 业务规则(变更)

- **(v1.0 新增)** 笔试环节,HR 面试通过后必须先笔试,通过后才能进入业务面试
- **(v1.0 新增)** 笔试不通过直接淘汰,不进入业务面试
- 其他规则沿用 v0.3
```

**数据迁移函数**(在 Demo 启动时执行):

```javascript
function migrateData_v0_v1(oldData) {
  // 候选人阶段:原「HR 面试」之后,如果是已经过 HR 面试没安排业务面试的,保持原样不动
  // 新流程只在 v1.0 之后生效,老候选人保留阶段
  return {
    ...oldData,
    version: 2,
    招聘需求: oldData.招聘需求 || [],
    候选人: (oldData.候选人 || []).map(c => ({
      ...c,
      // 阶段值不变,看板新列「笔试」先显示为空
    })),
    面试评价: oldData.面试评价 || [],
  };
}

// 启动时检测版本
const stored = JSON.parse(localStorage.getItem(HR_KEY) || "null");
if (stored && stored.version !== 2) {
  const migrated = migrateData_v0_v1(stored);
  // 备份老数据
  localStorage.setItem("hr-recruitment__backup_v0", JSON.stringify(stored));
  localStorage.setItem(HR_KEY, JSON.stringify(migrated));
}
```

**CHANGELOG.md 顶部大事记**:

```markdown
## v1.0 - 2026-07-08 - 重大重构:加入笔试环节

⚠️ **Breaking**:候选人阶段枚举扩展,数据模型版本 v1 → v2
自动迁移函数 `migrateData_v0_v1` 启动时执行,老数据自动备份到 `hr-recruitment__backup_v0`

### 主要变化

- [业务] 新增笔试环节,HR 面试 → 笔试 → 业务面试 → 终面
- [业务] 笔试不通过直接淘汰
- [技术] 候选人看板新增「笔试」列
- [数据] `当前阶段` 枚举扩展,新增「笔试」
- [数据] `面试轮次` 枚举扩展,新增「笔试」
- [数据] 老数据自动迁移,老阶段值不变

### 回滚方法

如果 v1.0 有问题,把 `outputs/demo-hr-recruitment-v0.3-snapshot-20260708/` 复制回来即可。
```

### C.5 Skill 写完告诉学员

> Skill 说:
> v1.0 已经写完,整页重写,数据自动迁移。
>
> 这次改了:
> 1. 候选人阶段枚举加了「笔试」
> 2. 面试评价枚举加了「笔试」
> 3. 候选人看板新增「笔试」列
> 4. 业务规则加了「笔试不通过直接淘汰」
> 5. 启动时自动迁移老数据,老候选人阶段值保持不变
>
> 验证方法:
> 1. 打开 Demo(刷新一次,触发迁移)
> 2. 找一个 v0.3 时代的候选人,确认他还在,阶段没变
> 3. 在控制台输入 `localStorage.getItem("hr-recruitment__backup_v0")`,能看到老数据备份
> 4. 找一个新候选人推到「笔试」阶段,看板新列应该有他

**场景 C 自检(对照 `references/iteration-patterns.md` 第 4 节)**

- [x] 30 秒判断影响 > 30%,属于场景 C
- [x] **冻结老版本** snapshot 复制到带日期目录
- [x] PRD 老版本归档到 _archive
- [x] 主版本 +1(v0.3 → v1.0)
- [x] 整页重写,不继承老代码
- [x] 写迁移函数,老数据自动升级
- [x] 迁移失败的数据备份到 `__backup_v0`
- [x] CHANGELOG 顶部大事记 + 标 ⚠️ Breaking
- [x] 给回滚方法

---

## 场景 D:小改直接动代码

v1.0 上线第二天,学员觉得首页仪表盘数字太小,想用公司主色。

> 学员说:首页仪表盘那几个大数字(在招岗位数、面试安排数、入职人数)调大一点,颜色用我们公司蓝 #1E40AF,字号大两号。

### D.1 Skill 判断(30 秒)

- 纯视觉调整(字号、颜色)
- 不改业务字段、不改流程、不改视图结构
- → 路由到**场景 D:小改直接动代码,跳过 PRD**

### D.2 Skill 直接动代码

找 demo-hr-recruitment/index.html 里仪表盘大数字的 class,把:

```html
<div class="text-3xl font-semibold text-slate-900 dark:text-slate-100">
  <span x-text="stats.openJobs"></span>
</div>
```

改成:

```html
<div class="text-5xl font-bold text-[#1E40AF] dark:text-blue-400">
  <span x-text="stats.openJobs"></span>
</div>
```

其他几个数字同样处理。

CHANGELOG.md 顶部加补丁记录(不升版本号):

```markdown
## patch - 2026-07-09 - 仪表盘数字字号调大 + 公司蓝

### 变更

- 仪表盘 4 个大数字:text-3xl → text-5xl
- 颜色:slate-900 → #1E40AF(亮)/ blue-400(暗)
- 不改 PRD(纯视觉微调)
```

### D.3 Skill 改完告诉学员

> Skill 说:
> 仪表盘改完了,刷新浏览器看看。
>
> 改了:
> - 4 个大数字字号 text-3xl → text-5xl
> - 颜色换成 #1E40AF(你们公司蓝),深色模式下用 blue-400
>
> PRD 没改(纯视觉),CHANGELOG 加了一条 patch 记录。
>
> 验证方法:打开 Demo 首页 → 看到仪表盘 4 个大数字变大变蓝 → 切到深色模式 → 数字变成浅蓝。

**场景 D 自检(对照 `references/iteration-patterns.md` 第 5 节)**

- [x] 30 秒判断属于场景 D
- [x] 直接改代码,不改 PRD
- [x] CHANGELOG 加 patch 记录(不升版本)
- [x] 告诉用户「刷新浏览器」

---

## 演练收尾

### 最终交付物

```
outputs/
├── prd-hr-recruitment-v1.0.md             (当前 PRD)
├── _archive/
│   └── prd-hr-recruitment-v0.3.md         (老版本)
├── demo-hr-recruitment/
│   ├── index.html                         (v1.0 应用)
│   ├── CHANGELOG.md                       (v0.2 / v0.3 / v1.0 / patch 全记录)
│   └── README.md                          (用户手册)
└── demo-hr-recruitment-v0.3-snapshot-20260708/   (冻结的老版本)
    └── index.html                         (出问题可回滚)
```

### 4 场景对照表

| 场景 | 触发 | 改 PRD | 改代码 | 改 CHANGELOG | 升版本 | 冻结老版 | 数据迁移 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| A 改字段 | 业务反馈 | ✓ | ✓ | ✓ | 次版本 | — | 兼容映射 |
| B 对话合并 | 「把刚才聊的也写进 PRD」 | ✓ | — (待用户确认再改) | ✓ | 次版本 | — | — |
| C 重大改动 | 流程推翻 | ✓ | ✓ (整页重写) | ✓ | 主版本 | ✓ | 迁移函数 |
| D 视觉微调 | 「字号调大点」 | — | ✓ | ✓ (patch) | — | — | — |

### 学员学到的关键点

1. **PRD 永远领先于代码**:任何改字段、改流程、改业务规则的请求,都先动 PRD 再动代码
2. **CHANGELOG 是审计追踪**:出问题能查「哪天改了什么」
3. **场景路由决定工作流**:30 秒判断属于 4 种场景中的哪一种,流程就清晰了
4. **数据兼容是底线**:字段重命名加映射,字段删除要容错,字段新增给默认值,大改写迁移函数
5. **「冻结老版 + 主版本号 +1」是场景 C 的安全网**:出问题了能回滚

### 学员可以拿这份 demo 练什么

- 自己扮演小王,选一个真实业务(不是 HR 也行),跟 Skill 跑一遍 4 场景
- 看每个场景的「30 秒判断」怎么做的(回看本 demo 第 A.1 / B.1 / C.1 / D.1 节)
- 看每个场景的「反模式」(回看 `references/iteration-patterns.md` 各场景末尾)
- 比对最终交付物结构,跟自己的实际项目交付物对照

## 下一步

- 想了解场景路由的判定细节,读 `references/iteration-patterns.md`
- 想看实际可用的 demo 长什么样,打开 `outputs/demo-hr-recruitment/index.html`
- 想了解 CRUD 实现规范,读 `references/crud-pattern.md`
- 想了解 PRD 模板结构,读 `references/prd-template.md` 和 `assets/prd-template.md`
