---
name: lina-feedback
description: >-
  用于处理用户对已有实现的反馈分诊与执行闭环：先判断是否需要纳入 OpenSpec
  活跃变更或新建变更，再完成根因分析、实现、验证和必要测试。凡是用户针对已有实现反馈
  Bug、缺陷、改进点、建议或实现遗漏，即使没有明确提到“反馈”或 OpenSpec，也必须使用本技能。
compatibility: 依赖 openspec CLI、lina-e2e 技能、lina-review 技能。
---

# Lina 反馈：结构化的修复、验证与测试覆盖循环

当用户在实现后发现 Bug、改进点或提出建议时，此技能先判断反馈是否值得沉淀为 OpenSpec 记录，再选择追加活跃变更、新建变更、直接修复或仅答复说明。进入 OpenSpec 路径的问题需要组织到`tasks.md`中的可追踪任务列表；未达到 OpenSpec 记录门槛的问题也必须完成清晰的根因分析、实现取舍、验证和结果说明。

**核心原则：**
1. **先分诊再处理** — 不因存在活跃变更就自动写入 OpenSpec，先判断反馈价值、影响范围和可追踪性需求
2. **规范是唯一事实来源** — 达到 OpenSpec 门槛且属于规范级别的变更需先更新规范再记录任务
3. **验证方式匹配问题性质** — 功能行为修复需要单元测试或 E2E 测试覆盖；项目治理类反馈使用`openspec validate`、静态扫描、文件检查、格式检查或审查结论等治理验证方式

**交互语言**：与用户交互的内容语言以用户上下文使用的语言为准，用户使用英文则使用英文，用户使用中文则使用中文。

## 工作流

### 1. 反馈分诊与 OpenSpec 门槛

**关键规则：**
1. 先判断反馈是否需要 OpenSpec 记录，再决定目标变更；活跃变更只是候选上下文，不是自动追加条件。
2. OpenSpec 记录门槛由 AI 自主判断。除非归属存在真实歧义或方案风险需要用户取舍，不要把门槛判断交还给用户。
3. **活跃变更**是指仍直接存在于`openspec/changes/`下、且**未被移入**`openspec/changes/archive/`的变更目录。不要将`status: complete`、所有任务已勾选或其他完成信号视为"非活跃"，除非实际已归档。

```bash
openspec list --json
# 或：ls openspec/changes/ | grep -v archive
```

当两个信号不一致时，优先遵循文件系统规则：

- 如果变更目录仍存在于`openspec/changes/`下且不在`archive/`中，则为活跃变更。
- `openspec list --json`可能仍将此类变更报告为`status: complete`；这仅表示实现任务已完成，**不**表示变更已归档。
- 只有位于`openspec/changes/archive/`下的已归档变更才是非活跃的。

**处理路径：**

| 路径 | 判定标准 | 操作 |
|------|----------|------|
| `openspec-existing` | 反馈直接修正或补全某个活跃变更的目标、验收、实现缺口、回归问题或治理门禁 | 追加到该活跃变更的`tasks.md`，必要时更新`specs/` |
| `openspec-new` | 反馈形成新的可持续产品能力、模块/API/数据/权限契约、跨模块设计、架构决策或需要长期追踪的治理规则 | 新建变更，再写入最小必要 OpenSpec 文档 |
| `direct-fix` | 反馈是局部实现问题、文案/技能说明微调、轻量治理修正、低风险测试补充，或不具备长期规范沉淀价值 | 不创建或追加 OpenSpec；直接做根因分析、修复和验证，并在结果中说明跳过 OpenSpec 的理由 |
| `no-change` | 反馈只是讨论、已被现有实现覆盖、暂不采纳的建议，或需要先澄清而不能安全落地 | 不修改文件；输出判断依据、已检查证据和下一步条件 |

**应进入 OpenSpec 的常见信号：**
- 改变用户可观察的功能语义、接口契约、数据模型、权限边界、模块边界或插件宿主能力。
- 修复暴露出原规范缺失、验收标准不完整、任务拆分遗漏或活跃变更实现范围不完整。
- 影响多个模块、插件、端到端工作流、发布治理或后续归档审查。
- 需要在未来审查、归档、回归验证或团队协作中保留明确追踪记录。

**通常不进入 OpenSpec 的信号：**
- 不改变产品或框架契约的技能文档措辞、注释、格式、局部脚本提示或轻量治理说明。
- 单文件、低风险、无长期设计价值的实现修正，且通过测试或静态检查即可闭环。
- 探索性建议、偏好表达或暂不采纳的方向，尚未形成可执行需求。

分诊后必须先告知：
```
### 反馈分诊
- 处理路径：direct-fix / openspec-existing / openspec-new / no-change
- 判断依据：<反馈是否达到 OpenSpec 记录门槛的原因>
- 活跃变更：<无 / 已考虑的变更及相关性>
- 后续动作：<直接修复 / 写入目标变更 / 新建变更 / 仅说明>
```

**存在多个活跃变更时：**
只有在处理路径为`openspec-existing`且多个活跃变更都高度相关、无法可靠自主选择时，才向用户确认目标变更。

```
检测到多个活跃变更。此反馈应追加到哪个变更？

1. config-management — 系统配置 CRUD 管理
2. user-auth — 用户认证增强

请选择 1 或 2：
```

如果只有一个活跃变更与反馈强相关，则自动选择并告知；如果存在活跃变更但均不相关，不要强行追加。

**需要新建变更时：**
1. 从反馈内容派生 kebab-case 名称（如 "fix-menu-circular-ref"）
2. 如果名称已存在，添加后缀 ("-2")
3. 执行：`openspec new change "<name>"`
4. 生成最小化的`proposal.md`（一段话概述上下文）
5. 纯 Bug 修复可跳过`design.md`，除非涉及架构变更

OpenSpec 路径告知："将反馈修复应用到变更：**<名称>**"

### 2. 读取当前上下文

如果处理路径为`openspec-existing`或`openspec-new`，读取目标变更上下文：

| 文件 | 用途 |
|------|------|
| `tasks.md` | 任务结构、命名规范、编号 |
| `design.md` | 架构上下文 |
| `proposal.md` | 功能范围和意图 |
| `specs/` | 增量规范定义 |

```bash
# 查找目标模块目录内的 TC ID，用于按模块本地递增规划测试编号
find hack/tests/e2e/<module> -maxdepth 1 -type f -name 'TC*.ts' | sort
# 或源码插件：
find apps/lina-plugins/<plugin-id>/hack/tests/e2e/<module> -maxdepth 1 -type f -name 'TC*.ts' | sort
```

如果处理路径为`direct-fix`或`no-change`，只读取判断和验证所需的源码、文档、测试、规则文件或运行证据；不要为了形式化流程创建 OpenSpec 文档。

**外部规则文件：**
- 读取`AGENTS.md`作为顶层规范入口。
- 必须按`AGENTS.md`的强制规则加载矩阵识别反馈命中的规则域，并在分诊、记录任务、修改规范、修复代码或输出审查结论前读取所有对应的`.agents/rules/*.md`。
- 禁止仅凭记忆、历史上下文、摘要或此前读取记录替代本次读取。
- 若触发场景命中但对应规则文件不存在、无法读取或存在无法调和的规则冲突，不得继续反馈修复；必须先修复规则入口或向用户说明阻断原因。
- 每个反馈都必须评估并记录`i18n`、缓存一致性、数据权限、开发工具跨平台和测试影响。若存在影响，必须读取对应规则文件并按其中的设计、实现、验证和审查要求执行；若确认无影响，也必须在该反馈的影响分析或审查结论中明确记录。
- 常见规则域包括但不限于：后端 Go 读取`.agents/rules/backend-go.md`；API 契约读取`.agents/rules/api-contract.md`；SQL 和 DAO 读取`.agents/rules/database.md`；缓存读取`.agents/rules/cache-consistency.md`；数据权限读取`.agents/rules/data-permission.md`；源码插件、动态插件、插件同构开发目录和插件生命周期资源读取`.agents/rules/plugin.md`；前端 UI 读取`.agents/rules/frontend-ui.md`；测试读取`.agents/rules/testing.md`；开发工具读取`.agents/rules/dev-tooling.md`；文档治理读取`.agents/rules/documentation.md`；OpenSpec 流程读取`.agents/rules/openspec.md`；`i18n`读取`.agents/rules/i18n.md`。

### 3. 分析和组织问题

对每个报告的问题：

**按类型分类：**
- **bug** — 行为不正确，代码与规范不匹配
- **missing** — 功能不完整，实现存在缺口
- **ux** — 用户体验改进，无需修改规范
- **test-gap** — 仅缺少测试覆盖

**按规范影响分类：**

| 级别 | 定义 | 操作 |
|------|------|------|
| **implementation** | 规范正确，代码有误 | 仅修复代码 |
| **spec-level** | 需求缺失/不完整/已变更 | 先更新规范，再修复 |
| **internal** | 无用户可观察变更但涉及可执行行为 | 修复代码，优先单元测试 |
| **governance** | 文档命名、规范文本、OpenSpec 记录、审查规则说明等项目治理问题 | 修复文档/规范，使用治理验证 |

**关联问题分组** — 同一根因 → 合并为单个任务，包含多个验证点。

同时记录 OpenSpec 门槛判断：
- `openspec-existing`：说明关联的活跃变更、关联原因和需要更新的`tasks.md`/`specs/`范围。
- `openspec-new`：说明为什么不能放入现有活跃变更，以及新变更的最小范围。
- `direct-fix`：说明为什么不值得沉淀为 OpenSpec，以及采用的验证方式。
- `no-change`：说明不修改的原因和未来触发条件。

### 4. 更新增量规范（仅限 OpenSpec 路径的规范级别问题）

对于规范级别的问题，在记录任务前先更新规范：

1. 确定受影响的能力：`specs/<capability>/spec.md`
2. 执行增量操作：

```markdown
<!-- ADDED: 新增需求 -->
### Requirement: 父级选择器循环引用防护
系统应在父级选择器中禁用当前菜单及其所有子菜单，
以防止循环引用。

#### Scenario: 编辑包含子菜单的菜单
WHEN 用户编辑一个包含子菜单的菜单
THEN 父级选择器应禁用当前菜单及所有子菜单

<!-- MODIFIED: 变更需求（包含完整原始块） -->
### Requirement: 导入错误处理
系统应在导入失败时显示错误信息。
**MODIFIED:** 错误信息应包含行号、字段名和校验失败原因。

<!-- REMOVED: 废弃需求 -->
### Requirement: 旧版导入格式
系统应支持旧版 CSV 格式。
**REMOVED:** 此格式不再支持。
**迁移方案：** 使用带表头行的新版 CSV 格式。
```

### 5. 将任务列表写入 tasks.md（仅限 OpenSpec 路径）

在`tasks.md`中追加**反馈章节**：

```markdown
## Feedback

- [ ] **FB-1**: 父级选择器在菜单编辑中允许循环引用
- [ ] **FB-2**: 导入错误信息缺少行号和字段详情
- [ ] **FB-3**: 重置密码功能缺少测试覆盖
```

**编号：** 顺序使用`FB-1`、`FB-2`等。如果章节已存在，从最后编号继续。

**每个任务一行** — 不使用子字段。分析在修复阶段进行。

写入前说明分诊结论和拟写入任务；只有在多个目标变更归属不清、任务范围存在高风险取舍或用户明确要求确认时，才暂停等待用户选择。

如果处理路径为`direct-fix`或`no-change`，跳过本步骤，并在最终结果中记录未更新`tasks.md`的原因。

**验证覆盖规划（内部）：**
- 用户可观察的行为变更 → 需要 E2E 测试
- 源码插件专属的用户可观察行为变更 → E2E 放在`apps/lina-plugins/<plugin-id>/hack/tests/e2e/`，专属 POM/helper 放在插件同级`hack/tests/pages/`、`hack/tests/support/`
- 后端逻辑、服务层、工具函数、缓存、权限、数据权限、插件桥接等内部可执行行为变更 → 需要单元测试或更低成本的自动化测试
- 纯项目治理类反馈 → 不为兜底新增单元测试或 E2E 测试，改用`openspec validate`、静态扫描、文件存在性检查、格式检查或审查结论
- 场景合适时优先在现有 TC 或现有测试中添加子断言

### 6. 执行修复（循环）

对每个 OpenSpec 反馈任务或直接修复项：

**a. 告知：** `## 修复 FB-X: <问题标题>`或`## 直接修复: <问题标题>`

**b. 调查** — 读取源文件，确认根因

**c. 实现** — 最小化、聚焦的修复，遵循现有模式

**d. 编写/更新测试或治理验证** — 行为修复按`AGENTS.md`选择单元测试或`lina-e2e`测试；项目治理类反馈使用规范校验、静态扫描或文件检查

**e. 评估影响范围（必须）**

实现后，识别回归风险：

| 变更类型 | 关联验证 |
|---------|---------|
| 后端 API 端点 | 所有调用该端点的前端页面 |
| 共享组件/工具函数 | 所有使用该组件的页面 |
| 数据库 Schema/DAO | 所有读写受影响表的功能 |
| 认证/权限 | 所有认证测试 + 权限相关测试 |
| 页面特定 | 该模块目录下的所有测试 |
| 项目治理文档/规范 | `openspec validate`、静态扫描、文件存在性检查或格式检查 |

```bash
# 示例：查找用户 API 变更的相关测试，包含宿主和源码插件自有 E2E
git grep -l "api/user" -- 'hack/tests/e2e/**/TC*.ts' 'apps/lina-plugins/**/TC*.ts'
```

告知：
```
### FB-X 影响分析
- 修改文件：apps/lina-core/internal/controller/menu.go
- 受影响模块：菜单管理
- 回归测试：hack/tests/e2e/iam/menu/TC001-menu-crud.ts, hack/tests/e2e/iam/menu/TC002-auth-menu.ts
```

同时必须记录：
- `i18n`影响：涉及时列出资源归属、目标语言、验证命令；不涉及时写明无运行时行为、前端 UI、API 文档源文本、插件清单或语言包资源影响。
- 缓存一致性影响：涉及时说明权威数据源、失效机制和分布式策略；不涉及时写明无缓存影响。
- 数据权限影响：涉及时说明读写边界和验证；不涉及时写明无数据操作影响。
- 开发工具跨平台影响：涉及时说明验证；不涉及时写明无开发工具或脚本影响。
- 外部规则加载影响：列出已按`AGENTS.md`命中的`.agents/rules/*.md`；若某规则域确认无影响，写明无影响判断。命中规则但未读取对应规则文件时，不得标记该反馈完成。

**f. 验证（标记完成前必须执行）**

1. 运行此任务新增/更新的测试或治理验证 → **必须通过**
2. 运行所有已识别的回归测试或回归验证 → **必须通过**
3. OpenSpec 路径仅在以上都通过后，才能在`tasks.md`中将任务标记为`[x]`；直接修复路径不修改`tasks.md`

如果回归测试失败：
- 如果与当前变更相关，直接修复
- 如果是独立问题，重新执行反馈分诊；达到 OpenSpec 门槛才作为新的 FB 任务添加，否则按直接修复或后续风险报告处理

**g. 运行审查** — 完成后必须调用`lina-review`技能

### 7. 综合验证

所有修复完成后：

1. 汇总所有任务的回归测试
2. 一次性运行全部测试
3. 报告：
```
### 综合验证结果
- 总测试数：N
- 通过：N
- 失败：N（列出详情）
- 回归测试：全部通过 ✓ / X 个失败
```

如果存在失败 → 重新执行反馈分诊，必要时添加新的 FB 任务，回到步骤 6。

### 8. 报告完成

```markdown
## 反馈完成

**处理路径：** direct-fix / openspec-existing / openspec-new / no-change
**变更：** <名称>
**OpenSpec 记录：** 已写入 <change>/tasks.md / 已新建 <change> / 未记录（原因：<原因>）
**报告问题数：** X
**已修复问题数：** Y/X
**新增测试：** Z 个测试用例 / 子断言
**回归测试：** 跨 N 个模块运行 R 个测试
**验证结果：** 全部通过 / 剩余 N 个问题

### 本次已修复
- [x] FB-1: <标题> ✓（测试：TC001a | 回归：iam/menu TC001, TC002 ✓）
- [x] FB-2: <标题> ✓（测试：已有覆盖 | 回归：auth TC003 ✓）

### 剩余（如有）
- [ ] FB-3: <标题> — 被 <原因> 阻塞
```

## 边界情况

| 场景 | 处理方式 |
|------|---------|
| 单个问题 | 先分诊；达到 OpenSpec 门槛才写入变更 |
| 仅缺少测试用例 | 分类为 test-gap；若只是局部覆盖缺口可直接补测试，不强制写入 OpenSpec |
| 修复后发现更多问题 | 重新分诊；达到门槛才添加 FB 任务 |
| "Bug"实为功能请求 | 重新分类为 spec-level；达到 OpenSpec 门槛时先更新规范 |
| 存在活跃变更但反馈不相关 | 不强行追加；按`direct-fix`、`openspec-new`或`no-change`处理 |
| 轻量文档、技能或治理措辞改进 | 通常走`direct-fix`；若会改变 OpenSpec 工作流或团队治理门禁，必须同步规则文件并重新判断记录门槛 |
| 测试不可行（时序、基础设施） | 通过完整测试套件验证，在摘要中说明原因 |
| 多轮反馈 | 每轮先分诊；同一目标变更中的任务在单个 Feedback 章节中顺序编号 |

## 护栏规则

- **先判断 OpenSpec 门槛** — 不因存在活跃变更就自动追加，也不为低价值反馈新建变更
- **达到门槛才记录** — `openspec-existing`和`openspec-new`路径需要先记录再修复，`direct-fix`路径需要先说明分诊和根因再修复
- **规范级别问题先更新规范** — OpenSpec 路径中先更新增量规范
- **减少不必要确认** — AI 自主决定记录门槛；仅在归属或方案取舍确实不清时询问用户
- **最小化修复** — 不进行问题范围之外的重构
- **用户可见的修复需要测试** — 除非技术上不可行，否则无例外
- **测试未通过不得标记完成** — 仅在测试通过后标记`[x]`
- **必须进行影响分析** — 每个修复都需要识别回归测试
- **回归失败阻塞完成** — 必须在标记完成前解决
- **实时更新 tasks.md** — 仅 OpenSpec 路径在验证后立即标记完成
- **匹配文件语言** — 使用目标文件中已有内容的相同语言
