前后验证技能Skill before-after

前后验证技能是一种软件开发验证技术,用于通过捕获实施前后的系统状态,证明代码更改实际改变了系统行为。它基于 delta-proof 验证,适用于新功能添加、bug 修复、行为变化等场景,确保变化可追溯和验证。关键词:前后验证、delta-proof、软件开发、系统验证、测试、行为证明、loom 计划、验证对、状态转换。

测试 0 次安装 0 次浏览 更新于 3/24/2026

name: 前后验证 description: 为 loom 计划生成前后验证对。通过捕获实施前后的状态,证明一个阶段实际上改变了系统行为。用于 delta-proof 验证——通过比较系统状态来证明新命令、端点、模块或 bug 修复有效。 allowed-tools: 读取、Grep、Glob、编辑、写入、Bash trigger-keywords: 前 后, 前后, delta 证明, 证明变化, 证明新, 验证 delta, 状态转换, 实施前, 实施后

前后验证技能

概述

前后验证是一种技术,用于证明一个阶段 实际上改变了 系统行为。不仅仅检查最终状态是否有效,而是捕获实施前为真和实施后应为真的事实。这对证明你的阶段导致了变化至关重要。

这很重要,因为如果没有前后思考,你无法区分:

  • “功能已经有效”与“我的阶段使其有效”
  • “bug 已经修复”与“我的修复解决了它”
  • “端点已存在”与“我创建了端点”

Delta-Proof 概念

delta-proof 是证明状态转换发生的验证。

模式

  1. 前状态: 捕获实施前的系统行为

    • 对于新功能:预期失败(功能尚不存在)
    • 对于 bug 修复:预期成功(bug 复现器展示问题)
  2. 后状态: 捕获实施后的系统行为

    • 对于新功能:预期成功(功能现在存在)
    • 对于 bug 修复:预期失败(bug 复现器不再触发 bug)
  3. 配对: 前后结合,证明实施导致了变化

为什么重要

没有 delta-proof 思考,验证可能误导:

坏例子:

# 阶段: 添加用户认证
truths:
  - "cargo test"  # 所有测试通过

问题: 测试可能在此阶段前已通过。这未证明认证被添加。

好例子:

# 阶段: 添加用户认证
description: |
  实现基于 JWT 的用户认证。

  前: curl -f localhost:8080/api/protected 返回 200(无需认证)
  后: curl -f localhost:8080/api/protected 返回 401(现在需要认证)
  后: curl -f -H "Authorization: Bearer <token>" localhost:8080/api/protected 返回 200

truths:
  - "curl -sf localhost:8080/api/protected | grep -q 401"
  - "curl -sf -H 'Authorization: Bearer fake' localhost:8080/api/protected && exit 1 || exit 0"

wiring:
  - source: "src/middleware/auth.rs"
    pattern: "pub fn require_auth"
    description: "认证中间件已注册"

这证明认证被此阶段添加(而非已存在)。

何时使用前后思考

在以下情况使用 delta-proof 验证:

  1. 添加新功能 — 证明功能之前不存在
  2. 修复 bug — 证明 bug 之前存在且之后消失
  3. 改变行为 — 证明旧行为被新行为替换
  4. 创建端点/命令 — 证明它们新可用
  5. 重构伴随行为变化 — 证明行为实际改变

不要在以下情况使用:

  • 验证直接简单(仅检查文件存在)
  • 阶段仅为知识性(无实施)
  • 仅检查代码质量(格式化、linting)

常见场景模板

场景 1: 新 CLI 命令

添加新 CLI 命令时,证明之前不存在。

前状态: 命令不存在(帮助失败或命令未找到) 后状态: 命令存在(帮助成功,基本调用有效)

- id: add-verify-command
  name: "添加 loom verify 命令"
  stage_type: standard
  working_dir: "loom"
  description: |
    实现 `loom verify <stage-id>` CLI 命令。

    DELTA PROOF:
    - 前: `loom verify --help` 失败(命令未注册)
    - 后: `loom verify --help` 成功
    - 后: `loom verify test-stage` 运行验证逻辑

  truths:
    - "loom verify --help"
    - "loom verify nonexistent-stage 2>&1 | grep -q 'Stage not found'"

  wiring:
    - source: "src/main.rs"
      pattern: "verify"
      description: "验证命令在 CLI 中注册"
    - source: "src/commands/verify.rs"
      pattern: "pub fn execute"
      description: "验证命令实施存在"

  artifacts:
    - "src/commands/verify.rs"

场景 2: 新 API 端点

添加 API 端点时,证明之前返回 404 且之后返回数据。

前状态: 端点返回 404(未注册) 后状态: 端点返回预期状态/数据

- id: add-status-endpoint
  name: "添加 /api/status 端点"
  stage_type: standard
  working_dir: "."
  description: |
    实现 GET /api/status 端点返回系统健康状态。

    DELTA PROOF:
    - 前: curl localhost:8080/api/status 返回 404
    - 后: curl localhost:8080/api/status 返回 200 带 JSON 健康数据

  truths:
    - "curl -sf localhost:8080/api/status | jq -e '.healthy'"
    - "curl -sf -o /dev/null -w '%{http_code}' localhost:8080/api/status | grep -q 200"

  wiring:
    - source: "src/routes/mod.rs"
      pattern: "/api/status"
      description: "状态端点在路由器中注册"
    - source: "src/handlers/status.rs"
      pattern: "pub async fn status_handler"
      description: "状态处理程序实施"

  artifacts:
    - "src/handlers/status.rs"

场景 3: 新模块/库

添加新模块时,证明导入之前失败且之后成功。

前状态: 导入/使用失败(模块不存在) 后状态: 导入/使用成功

- id: add-retry-module
  name: "添加重试模块"
  stage_type: standard
  working_dir: "loom"
  description: |
    创建带指数退避的重试模块。

    DELTA PROOF:
    - 前: `use crate::retry::RetryPolicy;` 会失败(模块不存在)
    - 后: 模块编译,导出可用

  truths:
    - "cargo check"
    - "cargo test --lib retry"

  wiring:
    - source: "src/lib.rs"
      pattern: "pub mod retry"
      description: "重试模块从 lib.rs 导出"
    - source: "src/orchestrator/core/orchestrator.rs"
      pattern: "use crate::retry"
      description: "重试模块在协调器中导入"

  artifacts:
    - "src/retry.rs"
    - "tests/retry_tests.rs"

场景 4: Bug 修复(反直觉)

修复 bug 时,证明 bug 复现器之前成功(bug 存在)且之后失败(bug 修复)。

前状态: Bug 复现器成功(展示 bug) 后状态: Bug 复现器失败(bug 不再触发)

这是反直觉但正确:复现器“工作”表示 bug 存在。

- id: fix-crash-on-empty-plan
  name: "修复计划为空时崩溃"
  stage_type: standard
  working_dir: "loom"
  description: |
    修复初始化空计划时的崩溃。

    DELTA PROOF(注意: 对于 bug,前后反转):
    - 前: 空计划导致恐慌(bug 复现器成功找到 bug)
    - 后: 空计划优雅返回错误(bug 复现器失败找到 bug)

    验证方法:
    1. 创建复现崩溃的测试用例
    2. 测试应在修复后通过(优雅捕获崩溃)
    3. 当恐慌不再发生时,证明 bug 修复

  truths:
    - "cargo test test_empty_plan_no_crash"
    - "cargo test --lib plan::parser"

  wiring:
    - source: "src/plan/parser.rs"
      pattern: "if stages.is_empty()"
      description: "添加空阶段列表检查"
    - source: "src/plan/parser.rs"
      pattern: 'Err.*"Plan must contain at least one stage"'
      description: "返回错误而非恐慌"

  artifacts:
    - "tests/empty_plan_tests.rs"

重要: 对于 bug 修复,测试应在修复前失败(复现 bug)且修复后通过。接线验证证明防御代码被添加。

常见陷阱

1. 测试错误内容

坏:

# 添加新用户注册端点
truths:
  - "cargo test"  # 太宽泛 - 未证明端点存在

好:

truths:
  - "curl -sf -X POST localhost:8080/api/register -d '{\"email\":\"test@example.com\"}' | jq -e '.user_id'"

2. 未捕获足够状态

坏:

# 添加命令输出
truths:
  - "loom status"  # 仅检查它运行

好:

truths:
  - "loom status | grep -q 'Active Plan:'"
  - "loom status | grep -q 'Executing:'"

3. 忘记这是关于实施

前后是关于你的阶段改变什么,而非测试设置。

坏思维: “测试运行前,我需要设置数据。测试运行后,我清理。” 好思维: “我的阶段前,功能 X 不存在。我的阶段后,功能 X 工作。”

4. 当简单事实足够时使用前后

过度:

# 仅添加配置文件
description: |
  前: config.toml 不存在
  后: config.toml 存在

truths:
  - "test -f config.toml"

更好:

artifacts:
  - "config.toml"

保留前后思维用于行为变化,非简单文件添加。

5. Bug 修复方向混淆

错误:

# 修复无限循环 bug
description: |
  前: 测试通过
  后: 测试失败展示 bug

正确:

# 修复无限循环 bug
description: |
  前: 代码进入无限循环(bug 存在)
  后: 代码成功完成(bug 修复)

truths:
  - "timeout 5s cargo test test_no_infinite_loop"

YAML 结构参考

Loom 有显式 before_stageafter_stage 字段接受 TruthCheck 定义。这些在阶段生命周期特定点运行:

  • before_stage: 在代理开始工作前运行(验证新工作树中的先决条件)
  • after_stage: 当代理调用 loom stage complete 时运行(验证后置条件)

1. 前后阶段字段(显式 Delta Proof)

before_stage:
  - command: "cargo test test_feature"
    exit_code: 1
    description: "功能测试在实施前失败"

after_stage:
  - command: "cargo test test_feature"
    exit_code: 0
    description: "功能测试在实施后通过"

每个条目是 TruthCheck,字段: command(必需), exit_code(默认 0), description, stdout_contains, stdout_not_contains, stderr_empty

2. Truths(捕获后状态)

truths:
  - "证明功能有效的命令"
  - "验证行为的测试"

Truths 在实施后运行,应成功。

3. Wiring(证明集成点)

wiring:
  - source: "src/main.rs"
    pattern: "register_feature"
    description: "功能在主入口点注册"

4. Artifacts(证明文件存在)

artifacts:
  - "src/feature/implementation.rs"
  - "tests/feature_tests.rs"

5. 阶段描述(记录 Delta)

也在阶段描述中记录 delta-proof 思维供人阅读:

description: |
  实现功能 X。

  DELTA PROOF:
  - 前: <此阶段前为真的事实>
  - 后: <此阶段后应为真的事实>

  [实施详情...]

完整例子

- id: add-metrics-endpoint
  name: "添加 /metrics 端点"
  stage_type: standard
  working_dir: "."
  description: |
    添加 Prometheus 兼容的 /metrics 端点。

    DELTA PROOF:
    - 前: curl localhost:8080/metrics 返回 404
    - 后: curl localhost:8080/metrics 返回 Prometheus 格式
    - 后: 指标包括 request_count, response_time

    实施:
    - 创建指标中间件
    - 注册 /metrics 端点
    - 导出 request_count 和 response_time 测量器

  dependencies: ["add-middleware-support"]

  before_stage:
    - command: "curl -sf localhost:8080/metrics"
      exit_code: 1
      description: "指标端点尚不存在"

  after_stage:
    - command: "curl -sf localhost:8080/metrics | grep -q 'request_count'"
      exit_code: 0
      description: "指标端点返回 request_count"
    - command: "curl -sf localhost:8080/metrics | grep -q 'response_time'"
      exit_code: 0
      description: "指标端点返回 response_time"

  truths:
    - "curl -sf localhost:8080/metrics | grep -q 'request_count'"
    - "curl -sf localhost:8080/metrics | grep -q 'response_time'"
    - "curl -sf localhost:8080/metrics | grep -q 'TYPE request_count counter'"

  wiring:
    - source: "src/routes/mod.rs"
      pattern: "Router.*metrics"
      description: "指标端点已注册"
    - source: "src/middleware/metrics.rs"
      pattern: "pub fn track_metrics"
      description: "指标中间件已实施"

  artifacts:
    - "src/middleware/metrics.rs"
    - "src/routes/metrics.rs"

  acceptance:
    - "cargo test"
    - "cargo clippy -- -D warnings"

与 Loom 计划集成

计划阶段

编写阶段描述时:

  1. 思考: “系统现在能做什么?”
  2. 思考: “系统在此阶段后应做什么?”
  3. 显式记录 delta
  4. 编写捕获后状态的验证

阶段描述模板

description: |
  [此阶段作用的单行摘要]

  DELTA PROOF:
  - 前: [此阶段前的状态 - 预期失败/通过]
  - 后: [此阶段后的状态 - 预期通过/失败]

  [详细实施指导]

  EXECUTION PLAN:
  [如果使用子代理,描述并行工作]

验证策略

对于每个阶段,选择验证机制:

验证类型 使用时机 证明
truths 行为可通过 shell 命令观察 功能在运行时工作
wiring 功能必须与现有代码集成 代码已连接/注册
artifacts 新文件必须存在 文件已创建
acceptance 标准检查(构建、测试、lint) 代码编译且测试通过

结合使用 truthswiring 进行强 delta-proofs。

例子: 带 Delta Proof 的完整阶段

- id: add-stage-complete-command
  name: "添加 loom stage complete 命令"
  stage_type: standard
  working_dir: "loom"

  description: |
    实现 `loom stage complete <stage-id>` 命令以标记阶段为完成。

    DELTA PROOF:
    - 前: `loom stage complete --help` 失败(命令不存在)
    - 后: `loom stage complete --help` 显示用法
    - 后: `loom stage complete test-stage` 将阶段转换为完成状态

    实施:
    - 添加 StageComplete 命令到 CLI
    - 实现状态转换逻辑
    - 添加阶段存在验证
    - 用完成时间戳更新阶段文件

  dependencies: ["knowledge-bootstrap"]

  truths:
    - "loom stage complete --help"
    - "loom stage list | grep -q complete"

  wiring:
    - source: "src/main.rs"
      pattern: "Commands::StageComplete"
      description: "StageComplete 命令在 CLI 中注册"
    - source: "src/commands/stage.rs"
      pattern: "pub fn complete"
      description: "阶段完成实施存在"
    - source: "src/models/stage/transitions.rs"
      pattern: "fn transition_to_completed"
      description: "状态转换逻辑已实施"

  artifacts:
    - "src/commands/stage.rs"

  acceptance:
    - "cargo test"
    - "cargo test stage_complete"
    - "cargo clippy -- -D warnings"

工作目录和路径

所有验证路径相对于 working_dir

working_dir: "loom"  # 命令从 loom/ 目录执行

truths:
  - "cargo test"  # 在 loom/ 中运行(Cargo.toml 所在处)

artifacts:
  - "src/commands/verify.rs"  # 解析为 loom/src/commands/verify.rs

wiring:
  - source: "src/main.rs"  # 解析为 loom/src/main.rs

如果 working_dir: ".",路径相对于工作树根目录。

最佳实践

  1. 记录 delta 在阶段描述中 - 使前后显式
  2. 使用 truths 进行运行时行为 - 证明功能在调用时有效
  3. 使用 wiring 进行集成 - 证明功能已连接
  4. 谨慎使用 artifacts - 优先 truths/wiring 而非文件存在
  5. 测试 delta - 针对实际实施运行 truths
  6. 从用户角度思考 - 用户会尝试什么来证明它有效?

摘要

前后验证证明你的阶段改变了系统:

  • 新功能: 前失败 → 后成功
  • Bug 修复: 前成功(bug 存在) → 后失败(bug 消失)
  • 行为变化: 前显示旧行为 → 后显示新行为

使用 before_stage/after_stage 进行显式自动化 delta-proof,truths 捕获后状态,wiring 证明集成,artifacts 证明文件存在。

始终思考: “我能测量什么来证明此阶段有差异?”