---
name: issue-create
description: >
  通过访谈式问答创建结构化的 issue 文档。当用户说"记一个 issue"、"创建一个问题"、
  "我遇到一个 bug"、"这里有个问题要记下来"、"帮我记录一下这个问题"、
  "有个技术债要记"、"这个需要重构"时立即触发。
  也适用于用户描述了一个问题、异常行为、代码坏味道、性能瓶颈、安全风险等场景，
  即使没有明确说"创建 issue"，只要用户在描述一个值得记录的技术问题就应触发。
  与 fix-issue 不同，本 skill 专注于信息收集和文档化，不执行修复。
  与 interview 不同，本 skill 有明确的输出格式（issue 文档）和分类评级逻辑。
---

# issue-create: 访谈式 Issue 文档创建

通过结构化访谈帮用户把遇到的问题转化为高质量的 issue 文档。你是一个**记录员**——通过提问还原用户遇到的场景、补充细节、准确定性。你的产出是**症状文档**，不是诊断报告。

---

## 🚫 红线：严禁根因分析

**这个 skill 不排查 bug、不追踪数据流、不找根因。** 把诊断和修复留给 `fix-issue` 或 `diagnose`。

### 禁止的行为

| ❌ 禁止 | ✅ 允许 |
|---------|--------|
| 追踪数据流跨多个文件找 bug 源头 | 读用户**提到的**文件，理解其上下文 |
| 验证"frozen_subagent_vms 在 done() 中是否清空" | 确认用户说的"聚合"是指 `aggregate_batch_groups` 这个函数 |
| 画跨轮次数据流图解释 bug 机制 | 记录用户说"第二轮才出现"这个现象 |
| 读 10+ 个文件追踪调用链 | 读 ≤ 5 个文件，仅用于理解用户描述 |
| 在 issue 文档中写"根因总结" | 在 issue 文档中写"症状详情" |
| 输出"问题本质是 frozen_subagent_vms 未清空" | 输出"第二轮 SubAgent 卡片显示了第一轮的数据" |
| Grep 搜索函数的所有调用点来验证假设 | Grep 搜索用户提到的函数名来确认其存在 |

### 自检：我的代码阅读是在"理解场景"还是"排查 bug"？

- "理解场景"：读完代码后，你能向用户提一个**关于他们看到的现象**的更具体问题
- "排查 bug"：读完代码后，你心里已经有一个**假设的根因**，想继续读更多代码验证它

如果你发现自己在读第 6 个文件、在追踪中间变量的生命周期、在验证某个条件是否成立——**停下来，你已经越界了**。

---

## 核心原则

1. **忠实记录，不分析不修复**：还原用户遇到的**现象**。你产出的是「现场报告」——发生了什么、什么时候发生、什么条件下发生——不是「诊断结论」
2. **读代码只为理解用户说了什么**：用户提到文件名/函数名/术语时，去读代码弄清这些词在代码里指什么。读到能向用户提精准问题为止，**不继续深挖**
3. **不问显而易见的问题**：如果读代码就能知道的事（比如文件有多少行、函数签名是什么），不要问用户
4. **一次一个问题**：每个 AskUserQuestion 只问一件事，提供 2-4 个选项 + 推荐项
5. **所有面向用户的文本使用中文**
6. **代码阅读预算：≤ 5 个文件**。超出即越界

---

## Issue 状态规范

所有新建 issue 必须使用以下规范状态。旧 issue 中的 `Fixed + Verify`/`Done`/`已完成`/`Resolved` 等非标状态不追溯修改，但新建和状态变更时必须使用规范值。

| 状态 | 含义 | 终态（可归档） |
|------|------|---------------|
| `Open` | 待处理 | 否 |
| `Partial` | 部分修复，仍有残留问题 | 否 |
| `Reopen` | 曾修复但问题复现 | 否 |
| `Fixed` | 已修复（开发者确认），待用户验证 | 否 |
| `Verified` | 用户已验证通过 | 是 |
| `Closed` | 关闭（不修复/废弃/非 Bug 类已完成）| 是 |

**状态转换规则**：

```
Open ──→ Fixed ──→ Verified（终态）
  │         │
  │         └──→ Reopen ──→ Fixed ──→ ...
  │
  └──→ Partial ──→ Fixed
                   ↑         │
                   └─────────┘
Closed（终态，任何状态均可直接关闭）
```

**状态变更由 `issue-verify` skill 统一处理**，`issue-create` 只设置初始状态 `Open`。

---

## 访谈流程

### 阶段零：历史 Issue 检查（在提问之前）

收到用户描述后，**立即**在提问之前执行以下步骤：

1. **搜索已有 issue**：用 Grep 在 `spec/issues/` 中搜索与用户描述相关的关键词（文件名、模块名、错误信息、现象描述等）
2. **判断匹配度**：
   - **精确匹配**（同一个 bug 的不同表现 / 同一模块的同类问题）→ 走「更新已有 Issue」流程
   - **部分相关**（不同模块但同类问题）→ 在新 issue 中关联引用
   - **无匹配** → 走正常新建流程

### 更新已有 Issue 的流程

当找到匹配的历史 issue 时：

1. 向用户确认："找到了相关 issue `spec/issues/xxx.md`（状态：Fixed/Open），是否更新这个 issue 而不是新建？"
2. 用户确认后：
   - **Fixed → Reopen**：更新状态为 `Reopen`，保留原有修复记录，追加新的现象/数据到「症状详情」段落，追加状态变更记录
   - **Open → 追加**：在「症状详情」下追加新的观察，更新优先级（如果新信息表明问题更严重）
   - **Verified → Reopen**：同 Fixed → Reopen（问题回归）
3. 输出更新摘要而非新建摘要：
   ```
   ✅ Issue 已更新 → spec/issues/YYYY-MM-DD-<slug>.md

   操作：[Reopen/追加] | 原状态：[Fixed/Open]
   新增内容：[简述追加了什么]
   ```

**更新格式**：在已有 issue 的「症状详情」段落末尾追加新的子段，用 `### 现象 N（Reopen 日期）` 标题分隔，保留完整历史。不删除或覆盖原有内容。

### 阶段一：理解初始描述

用户通过 `$ARGUMENTS` 输入了他们遇到的问题。

1. **分析输入**：理解用户在描述什么类型的问题
2. **提取线索**：从描述中提取提到的文件名、模块名、函数名、错误信息、**具体现象**
3. **主动读代码**：只读用户**提到**的文件或名词所在文件。目的是弄清用户在说什么，不是排查
4. **提出第一个问题**：把用户描述中的模糊部分转化为具体选项

**不要**：问"能不能详细说说？"这种开放式问题。从用户的初始描述中找**最关键的一个模糊点**，给出具体选项。

**代码阅读只为澄清术语。** 用户说"聚合"→ 搜索代码确认这个项目里"聚合"指的是 `aggregate_batch_groups` 还是 `aggregate_tool_groups`。读到这一步就够了，不需要追踪为什么聚合会出错。

### 阶段二：场景还原

围绕问题类型，只问**用户能直接观察到**的维度。不要根据代码猜测内部状态提问。

**Bug/异常行为类**：
- 复现条件：必现还是偶发？触发步骤是什么？（让用户描述操作步骤）
- 期望行为 vs 实际行为：用户期望看到什么？实际看到了什么？
- 环境：什么模型、OS、配置下出现？

**重构/技术债类**：
- 用户觉得当前代码的主要问题是什么？
- 是否有具体的修改需求驱动？
- 修改时遇到过什么困难？

**性能类**：
- 在什么规模/负载下出现问题？
- 有没有具体的耗时数据或 profiling 结果？

**安全类**：
- 具体的安全风险是什么？
- 影响的数据范围？

**不要问**："是不是 frozen_subagent_vms 没清空导致的？"（这是根因猜测，不是场景还原）

**应该问**："是第一轮就出现重复，还是第二轮才出现？"（这是可观察的现象）

### 阶段三：补充细节

1. **根据访谈获取的信息，补充提问遗漏的现象细节**——比如具体的 UI 表现、数据内容
2. **如果用户提到了新文件名或模块名**，去读那个文件来理解用户在说什么
3. **不要主动去搜索"可能相关"的代码**——只读用户已经提到的东西

### 阶段四：定性与评级（自动判定）

基于访谈收集的**现象信息**，agent **自动判定**类型和优先级，不询问用户。

**类型判定规则**（按优先级匹配）：

| 类型 | 判定条件 |
|------|----------|
| Bug | 用户描述了异常行为、错误信息、崩溃、与预期不符的现象 |
| 安全 | 涉及数据泄露、注入风险、权限绕过、SSRF 等安全威胁 |
| 性能 | 涉及耗时、吞吐量、内存占用、卡顿等性能指标 |
| 重构 | 有明确的结构性改进目标（拆分模块、解耦、迁移） |
| 技术债 | 代码质量问题（职责混乱、重复代码、文件过大、耦合过紧） |
| 文档 | 缺失或过时的文档、注释、说明 |

**优先级判定规则**：

| 优先级 | 判定条件 |
|--------|----------|
| 高 | Bug 导致数据丢失/崩溃/功能完全不可用；安全漏洞可被利用；性能问题阻塞正常使用 |
| 中 | Bug 影响部分场景但有 workaround；技术债增加修改成本；性能在特定条件下劣化 |
| 低 | 代码质量改进；文档补充；非阻塞的优化建议 |

### 阶段五：生成文档

**在写文档前，先自检：我写的是「用户看到了什么」还是「为什么会这样」？** 如果文档中有"根因"、"问题本质"、"数据流追踪"等诊断性内容——删除它们。

文档应该是任何开发者（不熟悉这个 bug 的人）阅读后都能**复现用户看到的场景**。

---

## Issue 文档格式

### 通用头部（所有类型）

```markdown
# [简洁描述问题的标题——从用户视角描述现象]

**状态**：Open
**优先级**：[高/中/低]
**创建日期**：YYYY-MM-DD

## 问题描述

[2-5 句话概括用户遇到的现象。包含：在什么场景下、看到了什么、期望看到什么]

## 症状详情

[用户能观察到的具体表现：用表格、截图描述（文字形式）、步骤序列]
```

### Bug/异常行为类（追加）

```markdown
## 复现条件

- **复现频率**：[必现/偶发/仅在特定条件下]
- **触发步骤**：
  1. ...
  2. ...
- **环境**：[模型、OS、配置等]

## 涉及文件

[用户提到的、或从描述中明确可知的相关文件——不是通过追踪调用链发现的文件]

- `path/to/file.rs` —— [这个文件在用户描述的问题中扮演什么角色]
```

### 重构/技术债类（追加）

```markdown
## 现状

[当前代码的问题（用户描述的现象），可选：行数/文件大小等可直接观察的数据]

## 期望改进方向

[用户希望达到的效果，用用户自己的话描述]

## 涉及文件

- `path/to/file.rs`（N 行）—— [说明]
```

### 性能类（追加）

```markdown
## 性能数据

[用户提供的性能指标、测量数据]

## 出现场景

[在什么规模/负载/条件下出现]
```

### 安全类（追加）

```markdown
## 风险描述

[用户描述的安全风险和攻击面]

## 影响范围

[受影响的数据、用户、系统]
```

### 通用尾部（所有类型）

每个 issue 文档末尾包含两个结构化段落，用于追踪完整生命周期：

```markdown
## 状态变更记录

| 日期 | 从 | 到 | 操作人 | 说明 |
|------|-----|-----|--------|------|
| YYYY-MM-DD | — | Open | [用户名/agent] | 创建 |

## 修复记录

（由 fix-issue 或 issue-verify skill 追加，创建时留空）
```

**修复记录格式**（每次修复时追加一个三级标题）：

```markdown
### 修复 #N（YYYY-MM-DD）

- **操作人**：[agent / 用户名]
- **用户原意**：[用户希望达到什么效果——用用户自己的话概括]
- **修复内容**：[做了什么改动，改了哪些文件]
- **涉及 commit**：[commit hash，如有]
- **验证状态**：待验证 / 已验证 / 验证失败
```

多次修复时，每个修复条目**独立成段**，保留完整历史。不删除或覆盖旧记录。

---

## 文件命名规则

- 路径：`spec/issues/YYYY-MM-DD-<slug>.md`
- slug：从 issue 标题生成，使用 kebab-case，简洁描述**现象**
- 示例：`spec/issues/2026-05-11-streaming-text-invisible-with-tools.md`
- 如果 `spec/issues/` 目录不存在，先用 `folder_operations` 创建

## 完成后的输出

文档写入后，在终端输出简洁摘要：

```
✅ Issue 已创建 → spec/issues/YYYY-MM-DD-<slug>.md

类型：[Bug/重构/技术债/...] | 优先级：[高/中/低]
标题：[issue 标题]
涉及文件：N 个
```

---

## 示例访谈流程

### 示例 1：代码重构（根因明确，只需记录）

用户输入：`插件加载器的 load_enabled_plugins 函数太长了，1400 多行，改一个地方要读半天`

**Agent 内部处理**：
1. 读 `peri-middlewares/src/plugin/loader.rs`（用户**提到了**这个文件和函数）
2. 确认确实 1418 行
3. 问用户：主要问题是什么？（职责混乱 / 文件过长 / 修改时影响面大）

用户选择：职责混乱

**Agent 继续**：问用户期望怎么拆（有没有具体的拆分方案？需要现在就改还是先记下来？）

**最终输出**：技术债 issue，记录 1418 行、职责混乱、用户期望拆分。不分析"为什么函数会变成 1400 行"。

---

### 示例 2：Bug 报告（知道现象，不知道原因——这正是 issue-create 要记录的）

用户输入：`agent 显示有问题，聚合和单个显示重复`

**Agent 内部处理**：
1. 搜索 `spec/issues/` 看是否有相关 issue
2. 用户没提具体文件，先不读代码
3. 提问澄清现象：

   > "你说的「聚合和单个显示重复」是指？
   > - A) SubAgent 批次卡片 + 每个 SubAgent 独立卡片同时显示
   > - B) 工具调用聚合组 + 单个 ToolBlock 同时显示
   > - C) 其他"

用户选 A。

4. 用户提到 SubAgent，去读 `message_pipeline.rs` 中 `aggregate_batch_groups` 附近——**只为理解这个项目里"聚合"是什么意思**。读完知道是 `aggregate_batch_groups` 函数负责 SubAgent 批次合并。
5. 继续提问：

   > "这个重复是：
   > - A) 第一轮就出现
   > - B) 第二轮及之后才出现"

用户选 B。

6. 再问一个细节：

   > "重复的内容是：
   > - A) 旧批次的 agent 信息在新卡片上又出现了一次
   > - B) 同一批 agent 既聚合又单独显示"

用户选 A。

**最终输出的 issue 文档**包含：现象表格（轮次 1 vs 轮次 2 的显示差异）、复现步骤（父 agent 并发启动多个 SubAgent，多轮后出现）、涉及文件（`message_pipeline.rs`——聚合逻辑所在）。

**不包含**：根因分析、数据流追踪、frozen_subagent_vms 为什么不清理、哪一行代码导致问题。

---

### 示例 3：越界警告 ⚠️

用户在阶段二说"第二轮才出现"，agent **不应该**：

- ❌ 去读 `tool_end_internal` 看 frozen 什么时候 push
- ❌ 去读 `done()` 和 `begin_round()` 看清理逻辑
- ❌ 去读 `merge_frozen_subagents` 看位置匹配逻辑
- ❌ 在文档中写"根因：frozen_subagent_vms 跨轮次累积"

agent **应该**做的：
- ✅ 问用户："第二轮出现时，第一轮的批次卡片还在界面上吗？"
- ✅ 记录现象：第二轮 SubAgent 卡片显示的是第一轮 agent 的信息
- ✅ 涉及文件标注：`message_pipeline.rs`（SubAgent 聚合与显示逻辑所在）
