# 需求: CTF 题目落盘命令 (create-challenge-doc)

## §1 背景与目标

**来源痛点**: 2026-06-27 落盘 SekaiCTF Web 题 `&lt;\w+` 时，花了 10+ 轮对话修正，全部根因是"落盘"与"解题"边界未固化。具体越界：

| # | 越界行为 | 根因 |
|---|---------|------|
| 1 | 把源码分析/架构/bot 行为/API 枚举写进文档 | 没区分"落盘"vs"解题" |
| 2 | 解压了附件 | 没区分"下载材料"vs"开始干活" |
| 3 | 写未验证断言（team_token 轮换、初始 500 分） | 把推断当事实 |
| 4 | 用未解释黑话（tarball、slug、URL 编码） | 没考虑读者 |
| 5 | 凭证过度披露（3 个 token + 长 README） | 过度工程 |
| 6 | 加自行注解（"可打印 ASCII"） | 把解释混进转录 |
| 7 | 文件名踩 Windows 禁用字符 `<` | 没考虑跨平台 |
| 8 | 标题曲解（解码成 `<\w+`） | 自行解读而非如实记录 |

**根因总结**: 缺乏一个固化的"落盘该做什么、不该做什么"规则集，导致每次落盘都重新摸索、反复越界。

**预期收益**:
- 落盘轮次从 10+ 降到 1-2（规则前置，避免反复修正）
- 跨类别（web/binary/mobile/ai）一致的行为约束
- 凭证安全（不泄漏）、跨平台安全（文件名）默认保证

## §2 技术方案

### 改动文件

| 文件 | 改动类型 | 说明 |
|------|---------|------|
| `.opencode/commands/create-challenge-doc.md` | 新增 | 单文件 opencode 命令 |

### 命令定位

- **类型**: opencode 命令（`.opencode/commands/` 下，frontmatter `description` + markdown 规则体）
- **适用范围**: 通用——任何来自 CTF 平台网站的题目（web/binary/mobile/ai 均可）
- **结构**: 单文件，自包含（不引用外部 knowledge-base，规则精炼可控）

### 命令内容设计

**Frontmatter**:
```
---
description: CTF 题目落盘 — 从网站读取题目、下载原始附件（不解压）、生成忠实转录的本地分析文档。绝不分析/解读/发散
---
```

**主体章节**:

1. **角色与目标**: 一句话——把网站上的题目忠实落盘到本地（文档 + 原始附件），为后续解题做准备。明确边界：**只落盘，不解题**。

2. **输入（$ARGUMENTS）**: 网站题目页 URL +（如需登录）登录方式/凭证 + 用户指定的解题要求。

3. **输出**:
   - 文档: `docs/分析/<分类>/<短名>.md`
   - 附件: `docs/分析/<分类>/Attachments/<短名>/`（原始文件，不解压）
   - 凭证（若有）: `.privacy-data/<比赛>/`（gitignored）

4. **核心原则（8 条防越界清单）**——命令主体，来自 §1 痛点：

   | # | 原则 |
   |---|------|
   | 1 | **只转录页面原文，不分析**：不写源码分析/架构/bot 行为/API 枚举，那是解题阶段的事 |
   | 2 | **不解读、不加注解**：原文照录，不擅自解释术语/正则/编码 |
   | 3 | **不写未验证断言**：没观察到的数值/没验证的机制不写，不把推断当事实 |
   | 4 | **附件只下载原始文件，不解压**：解压/阅读是解题阶段 |
   | 5 | **不用未解释黑话**：用文件全名或通俗说法 |
   | 6 | **凭证不进 docs/ 且从简**：token/密码绝不写进 `docs/`（进 git）；存 `.privacy-data/`（gitignored）；文档只写位置和登录方式。凭证文件**从简**——一个登录凭证即可，不做冗余快照/多份副本/长说明文件 |
   | 7 | **跨平台命名**：文件/目录名避开 Windows 禁用字符 `< > : " / \ \| ? *`；题目名含特殊字符时用安全短名，文档内记真实标题 |
   | 8 | **解题要求只记用户指定的**：不自行添加 |

5. **执行流程（步骤）**:
   1. （需登录时）用凭证登录，凭证存 `.privacy-data/<比赛>/`
   2. 读取题目页面
   3. 转录元信息（标题/分类/作者/分值/解题数/Flag 格式，如实不臆断）
   4. 转录描述原文（Description/Note 等）
   5. 转录连接信息（靶机/提交平台 URL）
   6. 下载原始附件（含 Attachments 区和 Download config 等所有页面可下载材料），**不解压**
   7. 记录提交入口（页面可见的 admin bot/flag 框等）
   8. 写解题要求节（仅用户指定）
   9. 写登录与凭证节（方式+位置，不含值）
   10. 执行落盘后自检清单

6. **落盘后自检清单**（对照 8 条原则）:
   - [ ] 文档无分析/解读内容？
   - [ ] 无自行加注解？
   - [ ] 无未验证断言/臆断数值？
   - [ ] 附件未被解压？
   - [ ] 无未解释黑话？
   - [ ] 凭证未写进 docs/（只在 .privacy-data/）且从简（无冗余快照/长说明）？
   - [ ] 文件名无 Windows 禁用字符？
   - [ ] 解题要求无自行添加？

7. **输出文档结构模板**（保证一致性；各节按需，题目无对应内容则省略）:
   ```
   # 分析-<短名>（题目 <真实标题>）
   > 来源 / 平台
   ## 题目元信息（table）
   ## 题目描述（官网原文）
   ## 连接信息
   ## 附件（仅下载，未解压未分析）
   ## 提交入口（页面可见，无则省略）
   ## 解题要求（用户指定）
   ## 登录与凭证（方式+位置，不含值；无需登录则省略）
   ```

## §3 实现规范

### 改动范围表

| 项目 | 内容 |
|------|------|
| 改动文件数 | 1（新增） |
| 新增代码 | ~120 行 markdown |
| 修改代码 | 0 |
| 删除代码 | 0 |
| 编码规则 | opencode 命令格式（frontmatter `description` + markdown）；与现有命令（write-writeup.md 等）风格一致 |

### §3.1 实施步骤拆分

```
步骤 1. 创建命令文件
  - 文件: .opencode/commands/create-challenge-doc.md
  - 预估行数: ~120 行（< 200）
  - 验证点:
    1. frontmatter 格式正确（含 description，无多余字段）
    2. 8 条核心原则齐全且与 §1 痛点一一对应
    3. 执行流程 10 步齐全
    4. 自检清单 8 条齐全
    5. 输出文档结构模板齐全
    6. 无未解释黑话、无越界内容（命令自身符合它定的规则）
  - 依赖: 无

步骤 2. 端到端验证
  - 文件: 无新增（验证步骤 1 的产物）
  - 预估行数: 0
  - 验证点:
    1. 命令文件能被 opencode 识别（frontmatter 可解析、出现在命令列表）
    2. 回归对照：用本次 SekaiCTF 题（已落盘的 docs/分析/web/分析-ltw.md）逐条核对——命令的 8 条原则能覆盖本次所有 8 个修正点，无遗漏
  - 依赖: 步骤 1
```

## §4 验收标准

### 功能验收
- [ ] 命令 frontmatter 含 `description`
- [ ] 含 8 条核心原则（与 §1 痛点一一对应）
- [ ] 含执行流程（含"不解压""凭证存 .privacy-data"等关键约束）
- [ ] 含落盘后自检清单
- [ ] 含输出文档结构模板

### 回归验收
- [ ] 不修改任何现有命令/agent/plugin 文件
- [ ] 与现有命令（write-writeup.md/gui-interact-pc.md）风格一致

### 架构验收
- [ ] 命令位于正确位置 `.opencode/commands/`
- [ ] 单文件自包含（不引用外部 knowledge-base）
- [ ] 通用范围（不硬编码 web-only 假设）

## §5 与现有需求文档的关系

独立需求，不依赖其他需求文档。来源于 2026-06-27 SekaiCTF 题目落盘实战复盘。
