关于 aep-wrap
aep-wrap 是 AEP 流程中合并后的归档与清理技能,在集成分支上归档 OpenSpec 变更、汇总执行记录并移除工作区。它还可同步产品故事状态,并保存工作中的经验记录。
主要功能
- 01归档 OpenSpec 变更
- 02汇总工作区执行记录
- 03合并后同步故事状态
- 04保存经验记录
- 05停止工作进程并移除 worktree
适用场景
- 01PR 合并后归档变更并清理工作区
- 02将执行信号汇总到归档记录
- 03更新已完成故事及其依赖状态
- 04移除工作区前保存经验
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ memorysaver/ agentic-engineering-patterns --skill aep-wrap安装后在 Claude Code 中输入/aep-wrap确认已加载。
附带文件references/convergence.mdreferences/layer-advance.md
详细介绍
收尾
合并后的归档与工作区清理。PR 合并后,在集成分支($BASE)上运行——根据 /aep-git-ref "Integration Branch" 确定 $BASE。此操作会归档 OpenSpec 变更、汇总构建时的运行信号,并移除工作区。
适用场景:
/aep-onboard → /aep-scaffold → [ /aep-design → /aep-launch → /aep-build → /aep-wrap ]
▲ you are here
会话: 主会话,合并后 输入: PR 已合并通知 输出: 已归档的 OpenSpec 变更、已汇总的执行记录、已清理的工作区
阶段 13:在集成分支上归档并清理
硬性防护措施:
/opsx:archive必须在集成分支($BASE)上的主检出目录中运行——绝不能在工作区中运行,因为它会写入openspec/specs/,并与并行工作树发生冲突。
1. 获取已合并状态并快进集成分支
根据 /aep-git-ref "Integration Branch" 确定 $BASE(覆盖值 → 自动检测 develop → main),然后更新本地集成分支,使其包含已合并的 PR:
git fetch origin
git checkout "$BASE"
git pull --ff-only origin "$BASE"
git status
--ff-only 是有意为之——如果 $BASE 存在尚未推送的本地提交而导致失败,请先推送或变基。完成此检出后,你就在集成分支上;后续步骤会通过 BASE=$(git branch --show-current) 获取其名称。
后置条件: HEAD 位于 $BASE,且 git status 干净——收尾期间只有 openspec/ 和 product-context.yaml 可以有差异。如果 apps//packages/ 下的代码已修改,请先调查原因。如果 openspec/changes/<name>/ 缺失(启动前丢失了分派提交),请按照 /aep-git-ref "Recovery" → "OpenSpec files missing after rebase" 恢复(在继续之前运行 git restore --source=<dispatch-sha> -- openspec/)。
2. 停止开发服务器(如果仍在运行,请在工作区中执行)
source .feature-workspaces/<name>/.dev-workflow/ports.env 2>/dev/null
lsof -ti :$SERVER_PORT | xargs kill 2>/dev/null
lsof -ti :$WEB_PORT | xargs kill 2>/dev/null
2.5. 汇总收集——收集执行记录(归档前)
将工作区的构建时运行信号汇总到归档前的变更目录(openspec/changes/<change-name>/convergence/),以便第 3 步中的归档 mv 能在一个提交中将其一并移动。运行收集命令,并按照 references/convergence.md §1 中的生产者约定写入 execution-record.yaml——包括复制列表、清单字段列表和架构。收集操作采用尽力而为原则:源文件缺失时应明确设为 null 或不复制,不得导致收尾失败。
关卡(顺序不变量——先收集,再归档): 在归档前将文件放入
openspec/changes/<change-name>/,可让它们随归档mv一并包含在一个提交中;在第 3 步之后再收集,则需要单独提交,且会与拆除操作发生竞争——存在静默丢失的窗口。
后置条件: 归档前的变更目录中存在 convergence/execution-record.yaml。
3. 运行归档
/opsx:archive <change-name>
4. 提交并推送归档
使用控制平面提交——即第 4、5 和 5.5 步共用的快进提交模式(集成分支已在第 1 步检出):
BASE=$(git branch --show-current) # integration branch, from step 1
git add openspec/ # stages the convergence/ records from step 2.5 — the archive commit carries them, no extra commit
git commit -m "chore: archive <change-name>"
git pull --ff-only origin "$BASE"
git push origin "$BASE"
5. 根据工作区信号同步故事状态(仅限产品周期模式)
独立模式: 如果
product-context.yaml不存在,请跳至步骤 6。
如果这是一个已派发的故事,请读取工作区信号,并对照实际 PR 状态进行核实——信号可能过时(例如,合并后工作区仍可能显示 in_review):
cat .feature-workspaces/<name>/.dev-workflow/signals/status.json
gh pr view <pr-number> --json state,mergedAt
如果 PR 已合并,但信号显示 in_review,则将故事视为 completed。根据(已按 PR 状态修正的)信号,更新 product-context.yaml 中匹配的故事:
status: completed # from signal story_status
completed_at: <timestamp> # from signal completed_at
pr_url: <url> # from signal pr_url
cost_usd: <cost> # from signal cost_usd
如果 story_status 为 failed,则设置 status: failed,并将结构化的 failure_log 记录到 failure_logs: 下。然后,将依赖项现已全部为 completed 的任何 pending 故事转换为 ready。验证 YAML(npx js-yaml product-context.yaml > /dev/null;/aep-validate 提供防护措施和常见修复方法),然后通过控制平面提交(步骤 4)原子化提交所有状态转换——git add product-context.yaml,提交消息为 chore: update story <id> status to completed。
并发协议: 故事完成状态仅在此处写入
product-context.yaml——工作区 Agent 写入信号;/aep-wrap(在集成分支上)读取信号并写入 YAML。
5.5. 归档经验教训
移除工作树之前——这是最后的机会,因为 git worktree remove 会删除 .dev-workflow/lessons.md——复制所有有价值的经验教训:
LESSONS=".feature-workspaces/<name>/.dev-workflow/lessons.md"
if [ -f "$LESSONS" ] && [ "$(wc -l < "$LESSONS")" -gt 12 ]; then # >12 = content beyond the template header
mkdir -p lessons-learned
cp "$LESSONS" "lessons-learned/<change-name>.md"
fi
如果复制了文件,请通过控制平面提交(步骤 4)提交:git add lessons-learned/<change-name>.md,提交消息为 docs: archive lessons from <change-name>。归档的 convergence/ 目录是每项变更的完整记录;lessons-learned/ 则作为快速索引,供 /aep-reflect 步骤 1 读取。
6. 拆除工作进程和工作树(executor.teardown())
移除工作树之前,先停止工作区的工作进程——如果面向操作系统的工作进程仍在已删除的目录中运行,就会变成孤儿进程,并在自动驾驶运行期间不断累积。停止方式取决于启动模式(记录在自动驾驶状态的 backend/agent_id 中,或可从启动方式判断):
# Mode-specific worker stop (each is a no-op for the other modes):
# native-bg-subagent → TaskStop(<bare-hex bg-subagent id>) (session-bound, no team)
# claude-bg → claude stop <agent_id>; claude rm <agent_id>
# codex-subagent → close_agent(<agent_id>) if still running
# codex-exec → nothing to kill (the exec process exited with the build)
# legacy → tmux kill-session -t <name> 2>/dev/null || true
然后,根据 /aep-git-ref「Worktree Lifecycle」→「Remove (/aep-wrap step 6)」移除工作树并删除已合并的功能分支(git worktree remove + git branch -d feat/<name>;仅在 gh pr view <number> --json state 确认状态为 MERGED 后强制删除)。
防护措施
顺序不变量(由实际状态推导的后置条件)。 收尾步骤链是机械化的——每个步骤是否完成都能从实际状态观察到,因此中断后恢复收尾时应检查,而不是重复执行:已收集 =
convergence/execution-record.yaml存在(归档前或归档后的位置)→ 已归档 =openspec/changes/<name>/不存在且存在archive/*<name>*目录 → 已提交 =openspec/下的git status --porcelain状态干净 → 状态已更新 = 故事显示为completed且已设置完成字段 → 经验教训已复制 =lessons-learned/<change-name>.md存在 → 已拆除 = 工作树路径不存在(使用git worktree list交叉核对)。后置条件已满足的步骤应跳过,绝不重复执行。这正是/aep-autopilotreferences/deterministic-orchestration.md 中所概括的模式。
复盘与推进(产品周期模式)
独立模式: 如果
product-context.yaml不存在,请跳过层级门控;你仍可运行/aep-reflect对观察结果进行分类。
层级完成时——当 product-context.yaml 存在且活动层级中的每个故事都为 completed 时——请阅读 references/layer-advance.md,了解两阶段的层级门控检查(运行门控、记录证据,并在覆盖后将 scripted_passed → passed)和层级提炼(隔离执行、仅提出建议的综合整理)。推进到下一层级的设计属于须经人工确认的步骤,必须在下一次 /aep-dispatch 之前记录。
反馈循环
运行 /aep-reflect,对来自此功能的观察进行分类——错误、优化和发现会返回到相应阶段,形成闭环。
下一步
从调度队列中选择下一个故事(/aep-dispatch),或对刚刚交付的内容进行反馈分类(/aep-reflect)。