移除所有测试代码和测试要求
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m33s

**变更说明**:
- 删除所有 *_test.go 文件(单元测试、集成测试、验收测试、流程测试)
- 删除整个 tests/ 目录
- 更新 CLAUDE.md:用"测试禁令"章节替换所有测试要求
- 删除测试生成 Skill (openspec-generate-acceptance-tests)
- 删除测试生成命令 (opsx:gen-tests)
- 更新 tasks.md:删除所有测试相关任务

**新规范**:
-  禁止编写任何形式的自动化测试
-  禁止创建 *_test.go 文件
-  禁止在任务中包含测试相关工作
-  仅当用户明确要求时才编写测试

**原因**:
业务系统的正确性通过人工验证和生产环境监控保证,测试代码维护成本高于价值。

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 17:13:42 +08:00
parent 804145332b
commit 353621d923
218 changed files with 11787 additions and 41983 deletions

View File

@@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.0.2"
generatedBy: "1.1.1"
---
Implement tasks from an OpenSpec change.
@@ -22,7 +22,7 @@ Implement tasks from an OpenSpec change.
- Auto-select if only one active change exists
- If ambiguous, run `openspec list --json` to get available changes and use the **AskUserQuestion tool** to let the user select
Always announce: "Using change: <name>" and how to override (e.g., `/opsx:apply <other>`).
Always announce: "Using change: <name>" and how to override (e.g., `/opsx-apply <other>`).
2. **Check status to understand the schema**
```bash

View File

@@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.0.2"
generatedBy: "1.1.1"
---
Archive a completed change in the experimental workflow.
@@ -63,7 +63,7 @@ Archive a completed change in the experimental workflow.
- If changes needed: "Sync now (recommended)", "Archive without syncing"
- If already synced: "Archive now", "Sync anyway", "Cancel"
If user chooses sync, execute /opsx:sync logic (use the openspec-sync-specs skill). Proceed to archive regardless of choice.
If user chooses sync, execute /opsx-sync logic (use the openspec-sync-specs skill). Proceed to archive regardless of choice.
5. **Perform the archive**

View File

@@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.0.2"
generatedBy: "1.1.1"
---
Archive multiple completed changes in a single operation.
@@ -229,7 +229,7 @@ Failed K changes:
```
## No Changes to Archive
No active changes found. Use `/opsx:new` to create a new change.
No active changes found. Use `/opsx-new` to create a new change.
```
**Guardrails**

View File

@@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.0.2"
generatedBy: "1.1.1"
---
Continue working on a change by creating the next artifact.
@@ -102,35 +102,7 @@ Common artifact patterns:
- The Capabilities section is critical - each capability listed will need a spec file.
- **specs/<capability>/spec.md**: Create one spec per capability listed in the proposal's Capabilities section (use the capability name, not the change name).
- **design.md**: Document technical decisions, architecture, and implementation approach.
- **tasks.md**: Break down implementation into checkboxed tasks, following TDD workflow structure:
**TDD Tasks Structure (MUST follow)**:
```markdown
## 0. 测试准备(实现前执行)
- [ ] 0.1 生成验收测试和流程测试(/opsx:gen-tests
- [ ] 0.2 运行测试确认全部 FAIL证明测试有效
## 1. 基础设施(数据库 + Model
- [ ] 1.x 创建迁移、Model、DTO
- [ ] 1.y 验证:编译通过
## 2. 功能单元 A完整垂直切片
- [ ] 2.1 Store 层
- [ ] 2.2 Service 层
- [ ] 2.3 Handler 层 + 路由
- [ ] 2.4 **验证:功能 A 相关验收测试 PASS**
## N. 最终验证
- [ ] N.1 全部验收测试 PASS
- [ ] N.2 全部流程测试 PASS
- [ ] N.3 完整测试套件无回归
```
**Key principles**:
- Task group 0 MUST be test preparation (generate tests + confirm all FAIL)
- Organize by functional units, NOT by technical layers (Store/Service/Handler)
- Each functional unit MUST end with "verify related tests PASS"
- Final validation MUST include all acceptance + flow tests passing
- **tasks.md**: Break down implementation into checkboxed tasks.
For other schemas, follow the `instruction` field from the CLI output.

View File

@@ -6,12 +6,12 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.0.2"
generatedBy: "1.1.1"
---
Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, and investigate the codebase, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first (e.g., start a change with `/opsx:new` or `/opsx:ff`). You MAY create OpenSpec artifacts (proposals, designs, specs) if the user asks—that's capturing thinking, not implementing.
**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, and investigate the codebase, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first (e.g., start a change with `/opsx-new` or `/opsx-ff`). You MAY create OpenSpec artifacts (proposals, designs, specs) if the user asks—that's capturing thinking, not implementing.
**This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
@@ -96,7 +96,7 @@ This tells you:
Think freely. When insights crystallize, you might offer:
- "This feels solid enough to start a change. Want me to create one?"
→ Can transition to `/opsx:new` or `/opsx:ff`
→ Can transition to `/opsx-new` or `/opsx-ff`
- Or keep exploring - no pressure to formalize
### When a change exists
@@ -202,7 +202,7 @@ You: [reads codebase]
**User is stuck mid-implementation:**
```
User: /opsx:explore add-auth-system
User: /opsx-explore add-auth-system
The OAuth integration is more complex than expected
You: [reads change artifacts]
@@ -252,28 +252,11 @@ You: That changes everything.
There's no required ending. Discovery might:
- **Lock consensus first**: "讨论已经比较清晰了,要锁定共识吗?" → `/opsx:lock <name>`
- **Flow into action**: "Ready to start? /opsx:new or /opsx:ff"
- **Flow into action**: "Ready to start? /opsx-new or /opsx-ff"
- **Result in artifact updates**: "Updated design.md with these decisions"
- **Just provide clarity**: User has what they need, moves on
- **Continue later**: "We can pick this up anytime"
### 推荐流程
当讨论涉及重要决策时,**建议先锁定共识再创建变更**
```
探索讨论 → /opsx:lock → /opsx:new 或 /opsx:ff
```
锁定共识会生成 `consensus.md`,记录:
- 要做什么
- 不做什么
- 关键约束
- 验收标准
后续生成 proposal 时会自动验证是否符合共识。
When it feels like things are crystallizing, you might summarize:
```
@@ -286,9 +269,8 @@ When it feels like things are crystallizing, you might summarize:
**Open questions**: [if any remain]
**Next steps** (if ready):
- Lock consensus: /opsx:lock <name> (推荐先锁定)
- Create a change: /opsx:new <name>
- Fast-forward to tasks: /opsx:ff <name>
- Create a change: /opsx-new <name>
- Fast-forward to tasks: /opsx-ff <name>
- Keep exploring: just keep talking
```

View File

@@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.0.2"
generatedBy: "1.1.1"
---
Fast-forward through artifact creation - generate everything needed to start implementation in one go.
@@ -81,7 +81,7 @@ After completing all artifacts, summarize:
- Change name and location
- List of artifacts created with brief descriptions
- What's ready: "All artifacts created! Ready for implementation."
- Prompt: "Run `/opsx:apply` or ask me to implement to start working on the tasks."
- Prompt: "Run `/opsx-apply` or ask me to implement to start working on the tasks."
**Artifact Creation Guidelines**

View File

@@ -1,442 +0,0 @@
---
name: openspec-generate-acceptance-tests
description: 从 Spec 的 Scenarios 和 Business Flows 自动生成验收测试和流程测试。测试在实现前生成,预期全部 FAIL证明测试有效。
license: MIT
compatibility: Requires openspec CLI.
metadata:
author: junhong
version: "1.0"
---
# 测试生成 Skill
从 Spec 文档自动生成两类测试:
1. **验收测试**Acceptance Tests从 Scenarios 生成,验证单 API 契约
2. **流程测试**Flow Tests从 Business Flows 生成,验证多 API 业务场景
## 触发方式
```
/opsx:gen-tests [change-name]
```
如果不指定 change-name自动检测当前活跃的 change。
---
## 前置条件
1. Change 必须存在且包含 spec 文件
2. Spec 必须包含 `## Scenarios` 部分
3. Spec 建议包含 `## Business Flows` 部分(如果有跨 API 场景)
检查命令:
```bash
openspec list --json
# 确认 change 存在且有 specs
```
---
## 工作流程
### Step 1: 读取 Spec 文件
```bash
# 读取 change 的所有 spec 文件
cat openspec/changes/<change-name>/specs/<capability>/spec.md
```
### Step 2: 解析 Scenarios
从 Spec 中提取所有 Scenario
```markdown
#### Scenario: 成功创建套餐
- **GIVEN** 用户已登录且有创建权限
- **WHEN** POST /api/admin/packages with valid data
- **THEN** 返回 201 和套餐详情
- **AND** 数据库中存在该套餐记录
```
解析为结构:
```json
{
"name": "成功创建套餐",
"given": ["用户已登录且有创建权限"],
"when": {"method": "POST", "path": "/api/admin/packages", "condition": "valid data"},
"then": ["返回 201 和套餐详情"],
"and": ["数据库中存在该套餐记录"]
}
```
### Step 3: 解析 Business Flows
从 Spec 中提取 Business Flow
```markdown
### Flow: 套餐完整生命周期
**参与者**: 平台管理员, 代理商
**流程步骤**:
1. **创建套餐**
- 角色: 平台管理员
- 调用: POST /api/admin/packages
- 预期: 返回套餐 ID
2. **分配给代理商**
- 角色: 平台管理员
- 调用: POST /api/admin/shop-packages
- 输入: 套餐 ID + 店铺 ID
- 预期: 分配成功
3. **代理商查看可售套餐**
- 角色: 代理商
- 调用: GET /api/admin/shop-packages
- 预期: 列表包含刚分配的套餐
```
### Step 4: 生成验收测试
**输出路径**: `tests/acceptance/<capability>_acceptance_test.go`
```go
package acceptance
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"junhong_cmp_fiber/tests/testutils"
)
// ============================================================
// 验收测试:套餐管理
// 来源openspec/changes/package-management/specs/package/spec.md
// ============================================================
func TestPackage_Acceptance(t *testing.T) {
env := testutils.NewIntegrationTestEnv(t)
// ------------------------------------------------------------
// Scenario: 成功创建套餐
// GIVEN: 用户已登录且有创建权限
// WHEN: POST /api/admin/packages with valid data
// THEN: 返回 201 和套餐详情
// AND: 数据库中存在该套餐记录
//
// 破坏点:如果删除 handler.Create 中的 store.Create 调用,此测试将失败
// ------------------------------------------------------------
t.Run("Scenario_成功创建套餐", func(t *testing.T) {
// GIVEN: 用户已登录且有创建权限
client := env.AsSuperAdmin()
// WHEN: POST /api/admin/packages with valid data
body := map[string]interface{}{
"name": "测试套餐",
"description": "测试描述",
"price": 9900,
"duration": 30,
}
resp, err := client.Request("POST", "/api/admin/packages", body)
require.NoError(t, err)
// THEN: 返回 201 和套餐详情
assert.Equal(t, 201, resp.StatusCode)
var result map[string]interface{}
err = resp.JSON(&result)
require.NoError(t, err)
assert.Equal(t, 0, int(result["code"].(float64)))
data := result["data"].(map[string]interface{})
packageID := uint(data["id"].(float64))
assert.NotZero(t, packageID)
// AND: 数据库中存在该套餐记录
// TODO: 实现后取消注释
// pkg, err := env.DB().Package.FindByID(ctx, packageID)
// require.NoError(t, err)
// assert.Equal(t, "测试套餐", pkg.Name)
})
// ------------------------------------------------------------
// Scenario: 创建套餐参数校验失败
// GIVEN: 用户已登录
// WHEN: POST /api/admin/packages with invalid data (name empty)
// THEN: 返回 400 和错误信息
//
// 破坏点:如果删除 handler 中的参数校验,此测试将失败
// ------------------------------------------------------------
t.Run("Scenario_创建套餐参数校验失败", func(t *testing.T) {
// GIVEN: 用户已登录
client := env.AsSuperAdmin()
// WHEN: POST /api/admin/packages with invalid data
body := map[string]interface{}{
"name": "", // 空名称
"price": -1, // 负价格
}
resp, err := client.Request("POST", "/api/admin/packages", body)
require.NoError(t, err)
// THEN: 返回 400 和错误信息
assert.Equal(t, 400, resp.StatusCode)
})
}
```
### Step 5: 生成流程测试
**输出路径**: `tests/flows/<capability>_<flow-name>_flow_test.go`
```go
package flows
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"junhong_cmp_fiber/tests/testutils"
)
// ============================================================
// 流程测试:套餐完整生命周期
// 来源openspec/changes/package-management/specs/package/spec.md
// 参与者:平台管理员, 代理商
// ============================================================
func TestFlow_PackageLifecycle(t *testing.T) {
env := testutils.NewIntegrationTestEnv(t)
// 流程级共享状态
var (
packageID uint
shopID uint = 1 // 测试店铺 ID
)
// ------------------------------------------------------------
// Step 1: 创建套餐
// 角色: 平台管理员
// 调用: POST /api/admin/packages
// 预期: 返回套餐 ID
//
// 破坏点:如果套餐创建 API 不返回 ID后续步骤无法执行
// ------------------------------------------------------------
t.Run("Step1_平台管理员创建套餐", func(t *testing.T) {
client := env.AsSuperAdmin()
body := map[string]interface{}{
"name": "流程测试套餐",
"description": "用于流程测试",
"price": 19900,
"duration": 30,
}
resp, err := client.Request("POST", "/api/admin/packages", body)
require.NoError(t, err)
require.Equal(t, 201, resp.StatusCode)
var result map[string]interface{}
err = resp.JSON(&result)
require.NoError(t, err)
data := result["data"].(map[string]interface{})
packageID = uint(data["id"].(float64))
require.NotZero(t, packageID, "套餐 ID 不能为空")
})
// ------------------------------------------------------------
// Step 2: 分配给代理商
// 角色: 平台管理员
// 调用: POST /api/admin/shop-packages
// 输入: 套餐 ID + 店铺 ID
// 预期: 分配成功
//
// 依赖: Step 1 的 packageID
// 破坏点:如果分配 API 不检查套餐是否存在,可能分配无效套餐
// ------------------------------------------------------------
t.Run("Step2_分配套餐给代理商", func(t *testing.T) {
if packageID == 0 {
t.Skip("依赖 Step 1 创建的 packageID")
}
client := env.AsSuperAdmin()
body := map[string]interface{}{
"package_id": packageID,
"shop_id": shopID,
}
resp, err := client.Request("POST", "/api/admin/shop-packages", body)
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode)
})
// ------------------------------------------------------------
// Step 3: 代理商查看可售套餐
// 角色: 代理商
// 调用: GET /api/admin/shop-packages
// 预期: 列表包含刚分配的套餐
//
// 依赖: Step 2 的分配操作
// 破坏点:如果查询不按店铺过滤,代理商会看到其他店铺的套餐
// ------------------------------------------------------------
t.Run("Step3_代理商查看可售套餐", func(t *testing.T) {
if packageID == 0 {
t.Skip("依赖 Step 1 创建的 packageID")
}
// 以代理商身份请求
client := env.AsShopAgent(shopID)
resp, err := client.Request("GET", "/api/admin/shop-packages", nil)
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode)
var result map[string]interface{}
err = resp.JSON(&result)
require.NoError(t, err)
// 验证列表包含刚分配的套餐
data := result["data"].(map[string]interface{})
list := data["list"].([]interface{})
found := false
for _, item := range list {
pkg := item.(map[string]interface{})
if uint(pkg["package_id"].(float64)) == packageID {
found = true
break
}
}
assert.True(t, found, "代理商应该能看到刚分配的套餐")
})
}
```
### Step 6: 运行测试验证
生成测试后,立即运行验证:
```bash
# 预期全部 FAIL因为功能尚未实现
source .env.local && go test -v ./tests/acceptance/... ./tests/flows/... 2>&1 | head -50
```
**如果测试 PASS**
- 说明测试写得太弱,没有真正验证功能
- 需要加强测试或检查是否功能已存在
---
## 测试模板规范
### 验收测试必须包含
1. **来源注释**:标明从哪个 spec 文件生成
2. **Scenario 注释**:完整的 GIVEN/WHEN/THEN/AND
3. **破坏点注释**:说明什么代码变更会导致测试失败
4. **清晰的结构**GIVEN → WHEN → THEN → AND 分块
### 流程测试必须包含
1. **来源注释**:标明从哪个 spec 文件生成
2. **参与者注释**:涉及哪些角色
3. **共享状态声明**:流程中需要传递的数据
4. **依赖声明**:每个 step 依赖哪些前置 step
5. **破坏点注释**:说明什么代码变更会导致测试失败
### 破坏点注释示例
```go
// 破坏点:如果删除 handler.Create 中的 store.Create 调用,此测试将失败
// 破坏点:如果移除参数校验中的 name 必填检查,此测试将失败
// 破坏点:如果查询不按 shop_id 过滤,此测试将失败(会返回其他店铺数据)
// 破坏点:如果状态机允许 "已使用" → "未分配" 的转换,此测试将失败
```
---
## 输出文件
| 来源 | 输出 |
|------|------|
| Spec Scenarios | `tests/acceptance/<capability>_acceptance_test.go` |
| Spec Business Flows | `tests/flows/<capability>_<flow>_flow_test.go` |
---
## Guardrails
- **不要跳过 Scenario** - 每个 Scenario 必须对应一个测试用例
- **不要省略破坏点** - 每个测试必须有破坏点注释
- **不要硬编码 ID** - 使用共享变量传递流程中的 ID
- **不要忽略依赖** - 流程测试的 step 必须声明依赖
- **不要写永远 PASS 的测试** - 测试必须在功能缺失时 FAIL
---
## 与其他 Skills 的关系
| Skill | 关系 |
|-------|------|
| `openspec-continue-change` | 生成 spec 后可触发 gen-tests |
| `openspec-apply-change` | 实现时参考生成的测试 |
| `openspec-verify-change` | 验证时运行生成的测试 |
---
## 示例交互
```
User: /opsx:gen-tests package-management
AI: 正在分析 change: package-management
找到 spec 文件: openspec/changes/package-management/specs/package/spec.md
解析结果:
- Scenarios: 5 个
- Business Flows: 2 个
生成测试文件:
1. tests/acceptance/package_acceptance_test.go
- Scenario_成功创建套餐
- Scenario_创建套餐参数校验失败
- Scenario_成功更新套餐
- Scenario_成功删除套餐
- Scenario_删除已分配套餐失败
2. tests/flows/package_lifecycle_flow_test.go
- Step1_平台管理员创建套餐
- Step2_分配套餐给代理商
- Step3_代理商查看可售套餐
- Step4_代理商创建订单
- Step5_套餐使用统计更新
3. tests/flows/package_allocation_flow_test.go
- Step1_批量分配套餐
- Step2_验证分配结果
- Step3_撤销部分分配
运行验证:
$ source .env.local && go test -v ./tests/acceptance/package_... ./tests/flows/package_...
--- FAIL: TestPackage_Acceptance (0.00s)
--- FAIL: TestPackage_Acceptance/Scenario_成功创建套餐 (0.00s)
package_acceptance_test.go:45: 404 != 201
--- FAIL: TestFlow_PackageLifecycle (0.00s)
--- FAIL: TestFlow_PackageLifecycle/Step1_平台管理员创建套餐 (0.00s)
package_lifecycle_flow_test.go:38: 404 != 201
✓ 所有测试预期 FAIL功能未实现
✓ 测试生成完成
下一步: /opsx:continue 生成 design 和 tasks
```

View File

@@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.0.2"
generatedBy: "1.1.1"
---
Start a new change using the experimental artifact-driven approach.

View File

@@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.0.2"
generatedBy: "1.1.1"
---
Guide the user through their first complete OpenSpec workflow cycle. This is a teaching experience—you'll do real work in their codebase while explaining each step.
@@ -22,7 +22,7 @@ openspec status --json 2>&1 || echo "NOT_INITIALIZED"
```
**If not initialized:**
> OpenSpec isn't set up in this project yet. Run `openspec init` first, then come back to `/opsx:onboard`.
> OpenSpec isn't set up in this project yet. Run `openspec init` first, then come back to `/opsx-onboard`.
Stop here if not initialized.
@@ -146,7 +146,7 @@ Spend 1-2 minutes investigating the relevant code:
│ [Optional: ASCII diagram if helpful] │
└─────────────────────────────────────────┘
Explore mode (`/opsx:explore`) is for this kind of thinking—investigating before implementing. You can use it anytime you need to think through a problem.
Explore mode (`/opsx-explore`) is for this kind of thinking—investigating before implementing. You can use it anytime you need to think through a problem.
Now let's create a change to hold our work.
```
@@ -459,19 +459,19 @@ This same rhythm works for any size change—a small fix or a major feature.
| Command | What it does |
|---------|--------------|
| `/opsx:explore` | Think through problems before/during work |
| `/opsx:new` | Start a new change, step through artifacts |
| `/opsx:ff` | Fast-forward: create all artifacts at once |
| `/opsx:continue` | Continue working on an existing change |
| `/opsx:apply` | Implement tasks from a change |
| `/opsx:verify` | Verify implementation matches artifacts |
| `/opsx:archive` | Archive a completed change |
| `/opsx-explore` | Think through problems before/during work |
| `/opsx-new` | Start a new change, step through artifacts |
| `/opsx-ff` | Fast-forward: create all artifacts at once |
| `/opsx-continue` | Continue working on an existing change |
| `/opsx-apply` | Implement tasks from a change |
| `/opsx-verify` | Verify implementation matches artifacts |
| `/opsx-archive` | Archive a completed change |
---
## What's Next?
Try `/opsx:new` or `/opsx:ff` on something you actually want to build. You've got the rhythm now!
Try `/opsx-new` or `/opsx-ff` on something you actually want to build. You've got the rhythm now!
```
---
@@ -486,8 +486,8 @@ If the user says they need to stop, want to pause, or seem disengaged:
No problem! Your change is saved at `openspec/changes/<name>/`.
To pick up where we left off later:
- `/opsx:continue <name>` - Resume artifact creation
- `/opsx:apply <name>` - Jump to implementation (if tasks exist)
- `/opsx-continue <name>` - Resume artifact creation
- `/opsx-apply <name>` - Jump to implementation (if tasks exist)
The work won't be lost. Come back whenever you're ready.
```
@@ -503,15 +503,15 @@ If the user says they just want to see the commands or skip the tutorial:
| Command | What it does |
|---------|--------------|
| `/opsx:explore` | Think through problems (no code changes) |
| `/opsx:new <name>` | Start a new change, step by step |
| `/opsx:ff <name>` | Fast-forward: all artifacts at once |
| `/opsx:continue <name>` | Continue an existing change |
| `/opsx:apply <name>` | Implement tasks |
| `/opsx:verify <name>` | Verify implementation |
| `/opsx:archive <name>` | Archive when done |
| `/opsx-explore` | Think through problems (no code changes) |
| `/opsx-new <name>` | Start a new change, step by step |
| `/opsx-ff <name>` | Fast-forward: all artifacts at once |
| `/opsx-continue <name>` | Continue an existing change |
| `/opsx-apply <name>` | Implement tasks |
| `/opsx-verify <name>` | Verify implementation |
| `/opsx-archive <name>` | Archive when done |
Try `/opsx:new` to start your first change, or `/opsx:ff` if you want to move fast.
Try `/opsx-new` to start your first change, or `/opsx-ff` if you want to move fast.
```
Exit gracefully.

View File

@@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.0.2"
generatedBy: "1.1.1"
---
Sync delta specs from a change to main specs.

View File

@@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.0.2"
generatedBy: "1.1.1"
---
Verify that an implementation matches the change artifacts (specs, tasks, design).