---
name: initializing-context-repo
description: >
  把一个目录初始化成规范的 context-repo（中间产物仓库）：建 prds/ + requirements/ + assets/
  三层骨架、按模板生成 AGENTS.md 导航（真源）与 CLAUDE.md 软链、写根 manifest.yaml（产品名，供
  ws init 校验）、按需建 prds/ 下的功能模块目录。新仓从零建、已有仓缺什么补什么，都用本 skill。
  当用户说「初始化 context-repo」「新建一个中间产物仓库」「给 xxx 产品建 context-repo」
  「这个空仓库要按 context-repo 的规范铺好」「补一下 context-repo 缺的目录和导航文件」
  「把 context-repo 的 AGENTS.md / CLAUDE.md 软链方向翻正」
  「ctx 命令报未找到 context-repo 根」，或给出一个目录要求按中间产物仓规范铺开时使用——
  即使用户没说「初始化」这个词，只要意图是「让一个目录成为合规的 context-repo」就适用。
  建 PRD 骨架走 sdlc-cli ctx scaffold；
  克隆已有 context-repo 建产品工作区走 ws init；知识库初始化走 initializing-knowledge-base。
allowed-tools: Bash(python3:*), Bash(ls:*), Bash(cat:*), Bash(grep:*), Bash(sdlc-cli:*), Read, Write, Edit, Glob, Grep
disable-model-invocation: true
---

# 初始化 context-repo（initializing-context-repo）

## 定位

sdlc-cli 有 `ctx scaffold`（建 PRD 骨架）、`ws init`（克隆已有 context-repo），**但没有命令能从零建一个 context-repo**。本 skill 填这个空：把一个目录铺成 CLI 认得的形状。

职责切得很窄——**只落文件**：

- **做**：判定目录形态、与用户定下产品名与模块划分、跑脚本建三层骨架与固定文件、校验、报告。
- **不做**：`git init`、关联远端、`git commit`、`git push`、写 `~/.sdlc/config.yaml`。这些收尾动作一律交人工或兄弟 skill（见「边界」），本 skill 只在报告里给出命令。

为什么值得单独做：`prds/` 与 `requirements/` 双双存在是 CLI 判「这是 context-repo 根」的唯一判据。缺一个，此后每条 `ctx` 命令都报「未找到 context-repo 根」，而报错信息不会告诉你是初始化时漏了目录。把骨架做成确定性动作，这类问题就不会发生。

## 固定模板硬约束

固定文件由脚本从 `assets/templates/` 复制并替换占位符。**不要把模板正文读进上下文，不要逐段重写模板内容。**

理由：这些文件（`AGENTS.md` 导航、README、gitignore）每次都该长一样。让模型重写会漂——kind 落点表少一行、判根说明改了措辞、软链方向反了，而这些偏差要等到别人踩坑时才暴露。模型该花在判断上的是产品名与模块划分，那才是每个仓不同的部分。

## 主流程

### 1. 确定目标目录与形态

目标目录只有两个来源：用户显式给的路径；没给时用当前工作目录。**不搜索、不推断、不切到别的目录**——铺错目录会在别人的仓里撒一堆文件。

目录必须已存在。不存在时停下来问，别替用户 `mkdir`：路径拼错和「就是要新建」看起来一样，猜错的代价是一个孤儿目录。

脚本会先判形态，四种：

| 形态 | 含义 | 怎么走 |
|---|---|---|
| `empty` | 空目录，或只有 `.git/` | 新建流程，全量生成 |
| `context-repo` | `prds/` 与 `requirements/` 都在 | 补齐流程，缺什么补什么 |
| `partial` | 只有部分层（如只有 `prds/`） | 补齐流程，补上缺的层 |
| `unknown` | 有别的内容、三层一个都没有 | 脚本报错退出 1 |

`unknown` 是刻意的拦：这种目录可能是拿错了（比如指到了代码仓）。脚本会列出发现的文件名，**拿给用户确认再动手**。

### 2. 收齐语义信息

脚本的参数就是要收的信息。已知的直接用，缺的才问：

| 参数 | 必填 | 从哪来 |
|---|---|---|
| `--product` | 是 | `~/.sdlc/config.yaml` 里 `products` 的 key（不是目录名、不是中文名） |
| `--prd-layout` | 否，默认 `standard` | **问用户**，见下 |
| `--module` | 否，可重复 | 用户定的模块划分；说不清就留空 |
| `--description` | 否 | 产品中文说明，写进 manifest 与 README |
| `--repo-id` | 否，可重复 | 该产品的逻辑代码仓 id，仅写进文档供人查阅 |
| `--remote` | 否 | 远端地址，仅写进 README；脚本不碰 git |
| `--alias` | 否，可重复 | 产品别名，写进 `manifest.product_aliases` |

#### 必问：需求产出走不走标准流程

导航文件里 PRD 一节与 kind 落点表随这个答案分两套，**必须问，别默认**：

> 「这个产品的需求产出走标准流程吗——PRD 由 `sdlc-cli ctx scaffold` 建、`prd/` 按四段式分（原始输入 / AI 产出 / 原型 / 迭代）、命名按 `PRD-<日期>-v<版本>-<slug>`？还是需求文档就散放在 `prd/` 里、没这套规矩？」

| 答案 | 传 | 导航文件里写什么 |
|---|---|---|
| 走标准流程 | `--prd-layout standard`（默认） | 四段式 `prd/` 全貌、`PRD-<YYYYMMDD>-v<X.Y>-<slug>` 命名规范、四段式对应的 kind 落点 |
| 不走 / 说不清 / 是历史遗留仓 | `--prd-layout loose` | 只写粗略结构（`manifest.yaml` + `prd/` + 可选 `test-cases/`）、两条硬要求、非四段式的 kind 落点 |

为什么必须问：把不适用的那套写进导航，读的人会照着错的结构放文件——例如仓里 PRD 正文一直放 `prd/` 根，导航却说落 `prd/02_ai_output/`。这类偏差要等到有人找不到文件时才暴露。

判据线索：仓里已有 PRD 时，`ls <某个 PRD>/prd/` 看有没有 `02_ai_output/`（CLI 也是按这个逐个 PRD 判形态的）。全新仓则完全取决于团队打算怎么做。

两种形态可以在同一个仓内共存——CLI 按每个 PRD 各自判别。`loose` 仓后续用 `ctx scaffold` 建的新 PRD 就是四段式，不用回头改导航。

#### 产品名与模块

产品名与模块划分的依据见 [`references/module-and-checks.md`](references/module-and-checks.md)：产品名取哪个串、`product_aliases` 什么时候要写、为什么 manifest 不能多加字段；模块按能力域还是按迭代季度划、问用户哪两句话、什么情况下该建议留空。

模块划分是产品侧决策，**由用户定**。他说不清时建议 `prds/` 留空——首个 PRD 走 `ctx scaffold` 时会触发模块归属对话，届时按真实需求命名比现在凭空造准。

先看 config 里有没有这个产品，能省一轮问话：

```bash
sdlc-cli config get products.<产品名> --json
```

### 3. 跑脚本

先 dry-run 看清会动哪些文件，再实跑：

```bash
python3 <skill>/scripts/init_context_repo.py <目标目录> \
  --product <产品名> --description "<说明>" \
  --prd-layout standard \
  --module 01-xxx --module 02-yyy \
  --repo-id <逻辑仓id> --remote <git地址> \
  --dry-run --json

# 确认无误后去掉 --dry-run 实跑
```

脚本行为：

- **缺失才写，已有文件一律不动**。所以对已有仓可以放心重跑，人手改过的内容不会被冲掉。
- 三层根目录各放一个 `.gitkeep`。空目录 git 不跟踪，没有它 clone 出来判根就失败。目录已有内容时不放。
- **导航真源是 `AGENTS.md`，`CLAUDE.md` 软链指向它。** 方向别反：`AGENTS.md` 是跨 AI 工具的通用约定，`CLAUDE.md` 只是 Claude 侧的入口名。真源放通用的那个，换工具时不用动文件。

存量 context-repo 多是反的（真源在 `.CLAUDE.md` / `CLAUDE.md`，`AGENTS.md` 是软链）。脚本对这种仓**默认不翻**，只在 `skipped` 里报出来——它本身能用，翻方向会产生一次改名 diff，该由用户决定。用户要翻时重跑加 `--normalize-guide`，做法与善后（仓内引用旧文件名的地方要人工改）见 [`references/module-and-checks.md`](references/module-and-checks.md)。

`AGENTS.md` 或 `CLAUDE.md` 已是普通文件（非软链）时一律原样保留并报出来，里面可能有人手写的正文。

### 4. 校验

跑完确认这几条，命令与失败排查见 [`references/module-and-checks.md`](references/module-and-checks.md) 第四节：

- [ ] `cd <repo> && sdlc-cli ctx modules --json` 返回 `ok:true`——**这是「CLI 认得这个仓」最直接的证据**，比逐个 `ls` 目录可靠。
- [ ] `manifest.yaml` 的 `product` 与用户将来 `ws init --product` 要用的名字一致。
- [ ] `ls -la AGENTS.md CLAUDE.md`：`AGENTS.md` 是普通文件（真源），`CLAUDE.md` 是指向它的软链。
- [ ] `grep -r '{{' <repo>` 无输出——有残留占位符说明脚本参数漏了。

`ctx modules` 报「未找到 context-repo 根」时，看 `prds/` 与 `requirements/` 是否都在。

### 5. 报告并交接

报告里说清四件事：

1. 目标目录、判定的形态、新建/保留/跳过各多少（脚本返回里直接有）。
2. 产品名、需求产出形态（`standard` / `loose`）、模块划分，以及为什么这么定（尤其建议 `prds/` 留空时说明理由）。
3. 跳过项与告警——特别是导航文件方向为旧形态（问用户要不要 `--normalize-guide` 翻正）、普通文件冲突、软链降级为副本。
4. **接下来要人做的事**，本 skill 不代做：

```bash
# git 收尾（本 skill 不碰 git）
cd <repo> && git init && git add -A && git commit -m "初始化 context-repo 三层结构"
git remote add origin <远端地址>   # 远端空仓需先在 GitLab 上建好
git push -u origin master

# 注册到全局配置（或交给 configuring-sdlc skill 做）
sdlc-cli config set products.<产品名>.context_repo <远端地址> --json

# 之后就能建产品工作区
sdlc-cli ws init --product <产品名>
```

没提交、没注册的仓也是可用的——`ctx` 命令认本地目录。但**别声称初始化已完成到能 `ws init`**：`ws init` 要克隆远端，远端没建好它跑不起来。如实说到哪一步。

## 边界（OUT）

| 不做 | 归谁 |
|---|---|
| `git init` / 关联远端 / commit / push | 人工（脚本刻意不碰 git，避免在拿错的目录里建仓） |
| 在 GitLab 上创建远端空仓 | 人工 |
| 写 `~/.sdlc/config.yaml`（注册 `products.<name>.context_repo`） | `configuring-sdlc`，或人工 `sdlc-cli config set` |
| 建 PRD 骨架、决定 PRD id | `sdlc-cli ctx scaffold`（会触发模块归属对话） |
| 建 Jira 骨架 | `sdlc-cli ws create --jira` 装配时自动建 |
| 克隆已有 context-repo、建产品/开发工作区 | `assembling-workspace` 的 `ws init` / `ws create` |
| 写任何中间产物正文 | 各 writing-* / generating-* skill |
| 知识库初始化 | `initializing-knowledge-base`（另一套仓，别混） |

## 容易踩的坑

- **产品名用目录名或中文名**。manifest 的 `product` 必须是 config 里 `products` 的 key，否则 `ws init --product <key>` 会报不匹配而中止。
- **往 manifest 加字段**。schema 是 strict 的，只认 `product` / `product_aliases` / `description`。多一个字段整份 manifest 读取失败退化成 null，产品名校验静默失效。
- **不问就按 `standard` 生成导航**。对需求散放在 `prd/` 根的仓，导航会指错落点。拿不到答案时用 `loose`——少说总比说错好。
- **凭空造模块目录**。空模块目录后续没人用，只是噪音。信息不足时留空更好。
- **建二级模块目录**。CLI 只扫一层，二级目录会被误判成 PRD 实体的父目录。
- **手删 `.gitkeep`**。它是空目录能进 git 的唯一办法，删了 clone 出来判根失败。
- **把导航真源放 `CLAUDE.md` 一侧**。真源该是通用的 `AGENTS.md`，否则接入别的 AI 工具时要动文件。
- **擅自给已有仓翻软链方向**。那是一次改名 diff，还会让仓内引用旧文件名的文档失效，先问用户。
- **在已有仓里覆盖文件**。脚本不覆盖，但你自己别用 Write 去改人家的 `.CLAUDE.md`——想改先问。
- **报告里说「已初始化完成」但远端没建**。用户下一步敲 `ws init` 会失败，回来找的是这条含糊的报告。

## 参考子文件

| 子文件 | 何时读 |
|---|---|
| [`references/module-and-checks.md`](references/module-and-checks.md) | 划模块、定产品名、看已有仓缺什么、落盘后校验时 |

## 相关 skill

| 方向 | skill |
|---|---|
| 下游：注册产品与代码仓到全局配置 | `configuring-sdlc` |
| 下游：克隆本仓建工作区 | `assembling-workspace`（`ws init` / `ws create`） |
| 下游：命令面与 ctx 命令族 | `sdlc-cli ctx -h` 与仓库 `README.md` 的命令参考表 |
| 平行：知识库（另一套仓）初始化 | `initializing-knowledge-base` |
