Files
.pouch/skills/declarative-openspec-loop/SKILL.md
T
2026-07-02 23:57:59 +08:00

8.3 KiB
Raw Blame History

name, description
name description
declarative-openspec-loop 声明式编程循环 - 用户提供校验方式,Agent 自动 propose/apply/校验并迭代直到通过。Use when the user provides expectations or a verification method and wants the agent to implement, verify, and iterate until expectations pass. Triggers on 声明式编程、按预期循环、做到校验通过、declarative loop.

声明式 OpenSpec 循环

用户提供判断结果是否符合预期的方式Agent 按 OpenSpec 流程 propose → apply → 校验,不通过则分析原因并迭代,直到通过。通过后输出变更点与思路。

前置:需要 openspec CLI 及三个子 skill。预期/校验写法的详细说明和端到端示例见 reference.md


何时使用

  • 用户说「按我给的预期/校验方式做,做到通过为止」
  • 用户提供了校验命令、预期文档、校验清单或自由描述,并希望自动迭代
  • 用户提到「声明式编程」「按预期循环」「做到校验通过」

输入:预期与校验方式

用户必须提供如何判断结果符合预期(可组合):

形式 示例
校验命令 make test-one2,退出码 0 即通过
预期文档 docs/tmp/expect_desc.md 中的校验项表格
校验清单 日志须含 阶段2 圆弧起点阶段3 右边竖边
自由描述 「拟合轮廓与 PLY 逆时针顺序一致」

若用户未给清,必须先问。详细格式说明见 reference.md § 预期/校验方式


如何调用子 skill(关键)

本 skill 编排三个子 skill,每次调用子 skill 时必须先读取对应 SKILL.md 并遵循其中的完整步骤

步骤 子 skill 读取路径
探索 openspec-explore .cursor/skills/openspec-explore/SKILL.md
提案 openspec-propose .cursor/skills/openspec-propose/SKILL.md
实现 openspec-apply-change .cursor/skills/openspec-apply-change/SKILL.md

不要凭记忆执行子 skill 的流程,每次都读取最新的 SKILL.md 再做。


主流程

用户输入:目标 + 校验方式
        │
        ▼
  1. 初始化:change 名称 + docs/tmp/<name>/ + expectation.md
        │
        ▼
  2. [可选] explore:目标复杂/模糊时先探索
        │
        ▼
  3. propose:生成 proposal / design / tasks(任务带验收标准)
        │
        ▼
  4. apply:按 tasks 实现
        │
        ▼
  5. 校验 ──通过──▶ 6a. 完成:输出变更与思路
        │
      不通过
        │
        ▼
  6b. 分级处理(见下)──▶ 回到 4 或 3

迭代分级:失败后怎么做

校验不通过时,根据失败根因选择不同路径,避免小 bug 也走完整提案流程:

Level 1:代码小修复(最常见)

触发:编译错误、运行时 bug、坐标写反、off-by-one、日志格式不对等实现层面问题。

动作

  1. 定位出错代码,直接修复
  2. 重新编译(若适用)
  3. 回到步骤 5 校验

不需要 explore,不需要修改 proposal/design/tasks。

Level 2:任务遗漏或不完整

触发:某个校验项没有对应的 task、task 描述模糊导致实现偏差。

动作

  1. 分析缺失的校验项对应什么工作
  2. tasks.md补充或修正 task
  3. 回到步骤 4 apply 执行新增/修正的 task → 步骤 5 校验

Level 3:设计级问题(最少见)

触发:整体方向错误、架构不合适、预期理解有偏差、多个校验项系统性失败。

动作

  1. 读取子 skill openspec-explore 并执行:基于校验结果 + 当前 proposal/design 分析根因
  2. 将分析写入 docs/tmp/<change-name>/iteration_<N>.md
  3. 修订 proposal.md / design.md / tasks.md(在原有 change 上修改,不新建)
  4. 回到步骤 4 apply步骤 5 校验

判断依据

信号 Level
编译报错 1
运行崩溃 / 段错误 1
单个校验项不通过,其余都通过 1 或 2
多个校验项不通过,但原因各异 2
多个校验项不通过,原因相同(方向性错误) 3
校验项全部不通过 3

最大迭代次数

  • 默认上限:5 轮(一轮 = 一次 apply + 一次校验)。
  • 到达上限后暂停并询问用户:展示当前进度、未通过的校验项、已尝试的修复方向,让用户决定是否继续。
  • 用户可在初始化时指定不同的上限(如「最多跑 3 轮」「不限轮次」)。
  • Level 1 的小修复(如编译错误修复后重新编译)不计入轮次,仅 apply+校验 计一轮。

编译失败处理

对于需要编译的项目(C/C++、Rust、Go 等):

  1. apply 完成后、运行校验命令前,先编译(或校验命令本身触发编译)。
  2. 若编译失败:属于 Level 1,直接修复编译错误,重新编译,不计入迭代轮次。
  3. 若编译成功但校验不通过:按正常分级处理。
  4. 编译错误的修复不需要 explore 或修订 proposal。

重复失败检测

若连续 2 轮校验结果中,同一个校验项以相同原因失败

  1. 停止自动迭代
  2. 向用户报告:哪个校验项、什么错误、已尝试的两次修复各做了什么
  3. 请用户给出新方向或手动介入

避免 Agent 在同一个坑里反复打转。


恢复 / 续接

对话中断后重新进入时:

  1. 检查 docs/tmp/<change-name>/ 下已有的 iteration_*.md → 确定当前轮次
  2. 检查 openspec/changes/<name>/tasks.md[x] / [ ] → 确定 task 进度
  3. 读取最近一轮的 iteration_<N>.mdcheck_result_<N>.txt → 了解上次失败原因
  4. 从上次中断的步骤继续,不从头开始

TodoWrite 跟踪

整个循环过程中用 TodoWrite 跟踪进度:

示例 todo 列表:
- [x] 初始化 change + expectation.md
- [x] propose: 生成 proposal/design/tasks
- [in_progress] 第 1 轮 apply + 校验
- [ ] 校验通过 → 输出变更摘要

每轮 apply + 校验 为一个 todo;校验不通过时更新 todo 内容(如「第 1 轮:3/8 校验项通过,Level 2 修复中」)。


过程数据存储

根目录:docs/tmp/<change-name>/

文件 内容
expectation.md 校验方式摘要(或引用路径)
iteration_<NNN>.md 每轮:apply 要点、校验结果、失败项、分级、修复动作
check_result_<NNN>.txt 校验命令原始输出
iteration_final.md 通过后的最终摘要(可选)

docs/tmp 不存在,先创建。


输出模板(校验通过时)

## 声明式循环完成

**Change:** <change-name>
**校验方式:** <摘要>
**迭代轮次:** N

### 变更摘要

- <文件 1><改动>
- <文件 2><改动>

### 思路

<设计取舍、与预期的对应、关键实现要点>

### 过程数据

`docs/tmp/<change-name>/`

Guardrails

  • 未提供校验方式时:不进入循环,先问用户。
  • 每轮校验结果必须落盘:至少记录通过/不通过与未满足项。
  • 优先复用同一 change:修订 proposal/design/tasks,不盲目新建。
  • 任务带验收标准propose 时每个 task 尽量带可执行的验证步骤。
  • explore 只分析不改代码:改代码通过 apply 或 Level 1 直接修复。
  • 最大轮次到达时停下问用户:不自动放弃也不无限跑。
  • 重复失败时升级:同一错误连续 2 轮 → 停下问用户。
  • 用户可随时中断:暂停并汇报当前状态。