--- 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 ""` 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/ -maxdepth 1 -type f -name 'TC*.ts' | sort # 或源码插件: find apps/lina-plugins//hack/tests/e2e/ -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//spec.md` 2. 执行增量操作: ```markdown ### Requirement: 父级选择器循环引用防护 系统应在父级选择器中禁用当前菜单及其所有子菜单, 以防止循环引用。 #### Scenario: 编辑包含子菜单的菜单 WHEN 用户编辑一个包含子菜单的菜单 THEN 父级选择器应禁用当前菜单及所有子菜单 ### Requirement: 导入错误处理 系统应在导入失败时显示错误信息。 **MODIFIED:** 错误信息应包含行号、字段名和校验失败原因。 ### 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//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 记录:** 已写入 /tasks.md / 已新建 / 未记录(原因:<原因>) **报告问题数:** 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 路径在验证后立即标记完成 - **匹配文件语言** — 使用目标文件中已有内容的相同语言