mcpField
A
aep-build

aep-build

github.com/memorysaver开发1858 次安装6 周前更新
代码仓库

关于 aep-build

aep-build 是在隔离 Git worktree 中自主实现功能的开发技能,依据 OpenSpec 任务逐项编码、提交、审查、测试并处理 PR。它通过进度文件和验证流程跟踪任务,且在人工判断关卡处升级处理。

主要功能

  1. 01在隔离 worktree 中实现
  2. 02按任务逐项提交代码
  3. 03生成进度与验证记录
  4. 04代码审查和测试
  5. 05创建并处理 PR

适用场景

  1. 01按 OpenSpec 任务实施功能
  2. 02在独立分支中执行自动化开发
  3. 03核对任务提交和验收条件
  4. 04测试并跟进 PR 反馈

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/memorysaver/agentic-engineering-patterns --skill aep-build

安装后在 Claude Code 中输入/aep-build确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
contract-template.md
harness-artifacts.md
merge-decision-cases.md
progress-template.md
story-status.md

详细介绍

构建

在隔离的 Git 工作树中的全新 feat/<name> 分支上自主实现功能。初始化工作框架,按顺序实现任务(tasks.md 每行对应一个提交),进行审查和测试、创建 PR、处理反馈并合并——全程无需用户交互。

**阶段编号:**阶段 1–3(探索、提议、审查)已通过 /aep-design 在集成分支上完成。本技能从阶段 0(工作区初始化)开始,并从阶段 4(实现)继续。

循环规范:每个阶段都受统一的 --max-turns 失控预算限制。达到上限不代表完成——应将其视为“可能无法解决 → 升级处理”(人工关卡协议),并与正常结束区分开来,以免卡住的阶段(例如阶段 5 中无法收敛的循环)被误认为已完成。

适用场景:

/aep-onboard → /aep-scaffold → [ /aep-design → /aep-launch → /aep-build → /aep-wrap ]
                                              ▲ you are here

**会话:**工作区会话,自主运行 **输入:**磁盘上的 OpenSpec 工件(由 /aep-design 提交到集成分支) **输出:**已合并的 PR


阶段 0:初始化跟踪

设置跟踪基础设施和环境。分支已存在(/aep-launch 已创建 feat/<name>)。按顺序执行以下步骤;每步结束时都应满足可检查的后置条件。

**步骤 0 — 工作树检查,优先执行。**阶段 4–12 必须在此功能对应的工作树中运行,并在此处验证,而不是假定如此。在 Codex codex-subagent 上,工作树绑定只是软提示契约(spawn_agent 没有 cwd 参数),因此工作进程可能从主检出目录启动,并在那里创建 feat/<name>,导致阶段 12 的自动驾驶检测失效。此检查用于防止这种情况:

WS="<name>"   # your story/change name from the bootstrap prompt — your worktree is
#             .feature-workspaces/<name> on branch feat/<name>, matching the active
#             OpenSpec change (ls openspec/changes/). If WS is still the literal
#             "<name>", resolve it from the prompt/change BEFORE continuing.
TOP=$(git rev-parse --show-toplevel)
BRANCH=$(git branch --show-current)

if [[ "$TOP" != *"/.feature-workspaces/$WS" || "$BRANCH" != "feat/$WS" ]]; then
  echo "GUARD: not in worktree .feature-workspaces/$WS on feat/$WS (top=$TOP branch=$BRANCH)"
  # /aep-launch OWNS worktree creation; the guard only ENTERS the worktree it
  # already made (cd, never `git switch` / `git worktree add -b`).
  ROOT=$(git worktree list --porcelain | sed -n '1s/^worktree //p')   # main worktree root
  if [ -n "$ROOT" ] && [ -d "$ROOT/.feature-workspaces/$WS" ]; then
    cd "$ROOT/.feature-workspaces/$WS"          # launch made it; just enter it
  else
    # No worktree for $WS: escalate (Human-Gate Protocol / needs-human.md)
    # rather than improvising one — "run /aep-launch first, or it misfired."
    echo "ESCALATE: no .feature-workspaces/$WS — run /aep-launch first"; exit 1
  fi
fi
# Re-verify before doing ANY work:
TOP=$(git rev-parse --show-toplevel); BRANCH=$(git branch --show-current)
[[ "$TOP" == *"/.feature-workspaces/$WS" && "$BRANCH" == "feat/$WS" ]] \
  || { echo "STILL NOT IN feat/$WS WORKTREE — STOP and escalate"; exit 1; }

工作树应由 /aep-launch 创建;如果缺失,应升级处理,绝不能在主检出目录中临时创建,因为这会导致无法恢复,而不只是出错。**后置条件:**检查以 0 退出(show-toplevel 以 .feature-workspaces/<name> 结尾,分支为 feat/<name>)。

  1. **发现 OpenSpec 变更。**列出 openspec/changes/ 以查找当前变更;读取 proposal.md、design.md、specs/**/*.md、tasks.md。**后置条件:**已确定变更目录并读取工件。

  2. 创建跟踪文件夹:mkdir -p .dev-workflow。**后置条件:**目录存在。

  3. 将其加入 Git 忽略列表:grep -q '.dev-workflow' .gitignore || echo '\n# Development workflow tracking (per-workspace)\n.dev-workflow/' >> .gitignore。后置条件:grep -q 以 0 退出——.dev-workflow/ 已被 Git 忽略。

  4. **根据此已安装技能的模板创建进度文件。**从工作树根目录解析软件包,优先使用 Codex 的标准安装路径:ROOT=$(git rev-parse --show-toplevel); AEP_BUILD_DIR="$ROOT/.agents/skills/aep-build"; [ -f "$AEP_BUILD_DIR/references/progress-template.md" ] || AEP_BUILD_DIR="$ROOT/.claude/skills/aep-build"; [ -f "$AEP_BUILD_DIR/references/progress-template.md" ] || { echo "aep-build progress template not installed" >&2; exit 1; }; cp "$AEP_BUILD_DIR/references/progress-template.md" ".dev-workflow/progress-$(git rev-parse --short HEAD).md"。填写功能名称、基准 SHA、日期、变更名称和模式;将设计阶段 1–3 标记为预先完成。**后置条件:**文件存在。

  5. **读取 tasks.md。**它_就是_骨架——你将在阶段 4 按顺序实现其中各行,每行对应一个提交,因此提交历史将与其逐项一一对应。**后置条件:**已掌握任务列表。

  6. **运行项目设置。**如果存在 .claude/hooks/workspace-setup.sh,则运行 bash(负责依赖、开发服务器、端口、数据库/种子数据和 .env);否则阅读 README,或询问用户如何设置。该钩子会写入 .dev-workflow/ports.env,至少包含以下四个键:

    WEB_PORT=<port>
    SERVER_PORT=<port>
    BASE_URL=http://localhost:<web-port>
    SERVER_URL=http://localhost:<server-port>
    

    后置条件:.dev-workflow/ports.env 存在并包含这四个键。

  7. 生成冲刺契约到 .dev-workflow/contracts.md,每个任务对应一个章节,依据 specs/*.md + design.md + tasks.md 生成。格式:references/contract-template.md。**完成标志:**文件存在,且每个任务对应一个章节。

  8. 生成特性验证清单 .dev-workflow/feature-verification.json(骨架和生成器所有权规则见 references/harness-artifacts.md)。生成器只写入 commit_sha——verification_steps 和 passes 由评估器负责。**完成标志:**文件存在。

  9. 生成会话恢复脚本 .dev-workflow/init.sh(脚本内容见 references/harness-artifacts.md);为其设置可执行权限:chmod +x。**完成标志:**文件存在且可执行。

  10. **初始化信号:**运行 mkdir -p .dev-workflow/signals,创建 status.json(骨架见 references/harness-artifacts.md),并读取 .dev-workflow/signals/feedback.md 获取主会话输入。完整规范:/aep-launch references/signals-spec.md。完成标志:status.json 存在。

  11. 创建经验文件 .dev-workflow/lessons.md(模板见 references/harness-artifacts.md);根据此次变更填写文件头。第 4 阶段(自选)和第 9 阶段(总结)会填充各个章节。**完成标志:**文件存在。

更新进度文件中的第 0 阶段复选框。**信号:**将 status.json 中的 "phase": 0, "phase_name": "initialized", "completion_pct": 10 设为相应值。

**产品周期模式:**如果此次变更对应 product-context.yaml 中的某个故事(变更名称与该故事的 openspec_change 相匹配),请阅读 references/story-status.md,了解构建时依赖项的重新验证和基于信号的状态协议。独立模式(没有 product-context.yaml):跳过此步骤。


第 4 阶段:应用 OpenSpec

按顺序实现 tasks.md 中的每项任务,一次一项任务,每项任务对应一个提交,然后记录提交 SHA。每项任务都要:实现(直接编辑文件)、检查(git status / git diff)、运行针对性测试,然后提交 feat(<scope>): <task description>,并将 8 位短 SHA 写入 feature-verification.json 对应条目的 commit_sha(绝不修改 verification_steps 或 passes)。提交格式、修正提交规则和恢复方法以规范的每项任务一个提交模式为准——参见 /aep-git-ref 中的 “The One-Commit-per-Task Pattern (Phase 4 of /aep-build)”。

调用应用技能获取逐项任务的指导:

/opsx:apply

**面向 UI 的故事——遵循对象映射。**如果分派的上下文包中包含对象映射切片(对象、属性、关系、CTA、屏幕),则必须将其作为约束结构:以对象为先构建所列屏幕(名词→动词——对象集合/详情,以及指定的 CTA 位置),使用指定的核心属性;不得引入切片之外的对象/屏幕,也不得将流程改为逐步向导,除非切片将其标记为 task_oriented。视觉风格(calibration/visual-design.yaml)、文案语气(copy-tone)和旅程/转场(ux-flow)仍决定设计取向——对象映射决定对象结构和 CTA 语法。

**记录经验(每项任务可选):**完成某项任务后,如果遇到值得记录的内容——例如不明显的解决方案、经过多次尝试才解决的错误、缺失的文档——请使用 ### <title> 子标题,将其追加到 .dev-workflow/lessons.md 中的 ## Solutions / ## Errors / ## Missing 章节下。仅在确实值得传递经验时记录。

逐项任务更新进度复选框;所有任务均已提交后,将第 4 阶段标记为完成。**信号:**开始时将 status.json 的 "phase": 4 设为相应值;随任务进度及时更新 task_current、task_index、task_total、completion_pct。


第 5 阶段:代码审查与验证

测试前先验证代码。本阶段采用生成器/评估器模式——完整机制见 /aep-gen-eval references:scoring-framework.md(维度、阈值、预设)、agent-contracts.md(角色分离、提示词模板)、eval-protocol.md(请求/响应格式、验证 JSON、收敛规则)。 第 5 阶段入口——在任何评估轮次消耗上限之前,确定绑定等级。根据实际差异(git diff --name-only "$BASE"...HEAD)对照 policy.md 的 sensitive_paths 和评审资源规则,重新推导验证等级,并生成 .dev-workflow/verification-recipe.json——包括等级、维度预设、硬性下限、scope_drift/tier_escalated。推导规则、下限和配方架构见:/aep-gen-eval references/verification-economics.md → The Two-Point Derivation(生成的 e2e 技能附带可运行脚本)。这里有两条约束:等级只能在调度简报的暂定等级基础上上调;若差异涉及未列入 files_affected 的文件,则根据差异重新计算,并设置 scope_drift: true。没有配方文件,第 5 阶段不得启动——有调度简报时,现在就推导;独立构建且没有简报时,使用 deep 默认值(失败时放行),并记录相应配方。将 verification_tier 和 tier_escalated 写入 status.json(架构由 /aep-launch references/signals-spec.md 负责)。

完整性检查(始终执行,由生成器负责):

  1. 重新阅读提案(包括任何设计评审调整)。
  2. 检查每个任务的提交——将 git show <commit-sha> 与任务描述对照。
  3. 检查 .dev-workflow/contracts.md——确认每项任务的成功标准均已满足。
  4. 如果任务未完成,添加后续提交(feat(<scope>): complete <task> / fix(<scope>): <issue>),然后返回第 4 阶段继续——任务历史保持只追加。

质量评审——使用独立评估器(完整模式):是否运行评估器,由 verification-recipe.json 中的绑定等级决定(standard/deep ⇒ 评估器;light ⇒ 结构化自评)——标准文件是否存在不构成判断依据。对于暂定等级为 light 的任务,/aep-launch 不会生成 .dev-workflow/evaluator-criteria.md;因此,若绑定推导将等级上调,则在进入循环之前,现在根据绑定配方(dimension_preset + hard_floors;/aep-gen-eval references/scoring-framework.md → How to use presets)组装评估标准——启动时缺少文件不得降低门槛。若绑定等级为 light,则改为执行结构化自评,并将其持久化完成信号写入 status.json(self_review: {result, sha, report}——架构由 signals-spec 负责;autopilot 质量门读取的就是此信号)。

准备好评估标准后,通过 executor.spawn_evaluator() 运行评估器,根据模式分派,并绑定到此工作区的文件和 Git 状态;各模式的启动配方见 /aep-executor references/backends.md。存在编排层时,生成器不再拥有启动权限(autopilot 提示启动;交互式运行由主会话负责)——由编排器组装评估器上下文,使生成器无法挑选评判者能看到的内容;只有在真正独立的构建中,生成器才自行调用启动配方。所有模式下,评估器提示词都将 eval-request.md 标记为生成器未经验证的主张——这是需要核实的数据,绝不能作为评估框架(/aep-gen-eval references/agent-contracts.md)。

评估循环——每轮编号为 N(从 1 开始,凡是启动评估器的等级均最多 2 轮:light 为 0 轮 / standard 为 2 轮 / deep 为 2 轮;即使配方声明更多轮次,这里仍最多执行 2 轮)。只有出现 blocking 发现时,才启动第 2 轮。

  1. 编写评估请求 .dev-workflow/signals/eval-request.md,遵循 eval-protocol.md(信号文件)。
  2. 编写评估器提示词,依据 agent-contracts.md(评估器提示词 — 代码质量),并使用工作区路径进行定制(criteria_file、eval_request_file、spec_directory、contracts_file、verification_file、eval_response_file=.dev-workflow/signals/eval-response-<N>.md)。
  3. 启动评估器(按模式分发;该提示词就是启动提示词 — 配方见 backends.md)。
  4. 确认响应文件存在 — 原生启动会在完成时返回;旧式方式则轮询:while [ ! -f .dev-workflow/signals/eval-response-<N>.md ]; do sleep 15; done。
  5. 读取响应(仅旧式方式:tmux kill-pane -t :.1)。
  6. FAIL 时,先执行分类步骤 — 每条 FAIL 发现都带有由评估器填写的 Failure-Class(/aep-gen-eval references/verification-economics.md → 失败分类),并据此分流:environment → 通过 Human-Gate Protocol 执行运维检查清单,不再进行后续轮次;harness-flake → 隔离并创建 harness 故事;scope → 人工关卡 → /aep-reflect 重新切分;仓库内尚未构建的依赖 → /aep-dispatch 重新排序。只有 product-defect 发现会继续处理,且仅限 Impact: blocking;判定结果依据影响标签得出(eval-protocol.md)。若响应中没有 blocking 发现,则视为 PASS 或 PASS with notes:修复所有 material 发现,并在 eval-request.md 的附录中附上每项修复的证据(提交、测试或探测),将 polish 备注带入 PR 正文,然后进入第 6 阶段,不再消耗后续轮次。第 1 轮后若仍有 blocking 发现:重新梳理依据(从头重读规格说明、设计和契约),修复并追加后续提交,然后回到第 1 步进行第 2 轮 — PR 会将修复视为新提交,因此历史记录保持只追加。

只有评估器会根据 eval-protocol.md 的字段所有权规则更新 .dev-workflow/feature-verification.json 中的通过/失败状态。在 status.json 中跟踪 eval_round 和 recovery_rung;每次 FAIL 时,将响应中按发现统计的类别数量原样抄录到 status.json.failure_classes(值由评估器填写 — 生成器只负责抄录,绝不重新分类;架构由 signals-spec 负责,混合类别分流规则也由其负责)。

明确规定上限耗尽的处理方式,不得静默处理: 第 2 轮后仍未解决的 blocking 发现,无论层级如何,都必须通过 Human-Gate Protocol 提交升级,类型为 eval_not_converging;不得从 standard 升级到 deep(保持 tier_escalated: false)。关卡记录须包含两轮历史,并提出人类或自动驾驶策略可选择的策略变更:告知新的生成器“先前的方法在 X 处失败;请采用不同的设计路径”(继承此工作树),或将故事拆分为最小可行切片,并明确呈现拆分方案。

恢复阶梯(生成器端,两级) — 第 1 轮:同一生成器就地修复 blocking 发现;第 2 轮之前:重新梳理依据,然后修复。评估器只负责评分,因此重新梳理依据和两种关卡选项都由生成器处理。该阶梯仅适用于 product-defect — 在选择任何一级之前,第 6 步的分类流程会将其他所有类别分流出去。遇到严重失败 / 安全 FAIL(授权模型缺口、数据暴露风险)、规格矛盾(scope)或缺少外部依赖(environment — 需要指定拒绝标签)时,跳过阶梯并立即升级:这些情况需要人工判断。理由和新生成器的启动契约:/aep-gen-eval references/recovery-ladder.md。

质量审查 — 不使用评估器(轻量模式): 针对正确性、安全性、性能和约定进行结构化自审,并手动逐项检查 feature-verification.json 中的步骤。将发现记录在 .dev-workflow/code-review-<feature>.md 中,并修复发现的问题。

更新第 5 阶段的复选框。信号: 将 status.json 设置为 "phase": 5, "phase_name": "code-review"。

人工决策关卡协议(适用于任意阶段)

遇到只有人工才能做出的决策时——例如规范未能解决的设计歧义、达到最大轮数后评估仍未收敛,或需要做出产品判断——请设置关卡:

  1. **记录(始终执行):**追加到 .dev-workflow/signals/needs-human.md:

    ## <ISO8601> — Phase <N>
    
    **Question:** <the decision needed, with the options you considered>
    **Context:** <why you can't decide autonomously>
    

    并在 status.json 中设置 "blocked_on": "human"。

  2. 通过启动模式对应的传输方式提出关卡(/aep-executor references/backends.md → The Human-Gate Protocol)。答案会通过主 Agent返回(中心辐射式架构),因此人工可以在原本所在的位置作答。在无推送模式(native-bg-subagent、claude-bg、codex-exec、workflow、headless)下,这意味着设置关卡并暂停:提交 WIP,更新 status.json,然后干净地结束本次运行——状态保存在 worktree 和 .dev-workflow/ 中,协调器会在此处收到答案后恢复一个工作进程。

  3. **仅适用于可原地阻塞的模式:**继续处理不依赖该答案的事项;否则等待,并重新检查 feedback.md。

  4. 收到答案后(通过推送,或暂停后在恢复提示词中收到):在对应条目下追加 resolved: <summary>,清除 blocked_on,然后继续。


阶段 6:浏览器测试(实测)

本阶段以用户旅程为先:步骤 A 根据该层的验收标准编写用户旅程;步骤 B 执行该旅程。步骤 A 始终执行(不受构建模式、dogfood_target、journey_timing 影响)。只有_执行_(步骤 B)会有所不同:在 Light 模式或 dogfood_target == none 时跳过;在 journey_timing: post-deploy 时,延后至 /aep-wrap 关卡执行。

步骤 A — 编写该层的用户旅程(始终执行,合并前)

如果项目有 e2e-test 技能和 journeys/ 目录(dogfood_target != none),且没有用户旅程覆盖此层——或者新增的验收标准缺少对应场景——则现在就在 skills/e2e-test/journeys/<NN-slug>.md 中编写或扩展用户旅程(路径规划见 layer_gates[N].journeys;复制 journeys/README.md 中的模板,设置 front-matter 中的 target:、layer:、covers:——即此用户旅程验证的验收标准 ID;参见 /aep-e2e-skill-scaffolding references/bdd-journeys.md):

  • 每项验收标准对应一个场景(来自 stories[].acceptance_criteria),每个 Then 都对应一项具体的 Verify(API 响应 / DB 记录 / 检查器检查),以意图为准,不绑定具体工具。
  • 用户旅程必须在执行前,将每项验收标准映射到某个场景的 Verify(或者映射到用于验证确定性行为的 Tier-1 脚本测试用例,或用于验证后端 / 异步状态的 Tier-3 API 检查);有意推迟的验收标准须附上 WAIVER: <reason> 行。/aep-wrap 会在将关卡设为 passed 前检查这些覆盖情况。
  • 现在就将用户旅程文件与功能一起提交(合并前)——即使 journey_timing: post-deploy 也是如此,此时仅推迟用户旅程的_执行_(步骤 B)。

dogfood_target == cli(CLI / 库):编写 target: cli 用户旅程——使用 bash 驱动构建好的二进制文件,每个 Then 都对应一项针对退出代码 / stdout / stderr / 文件系统的 Verify。编写规则相同;只有工具路径不同。 dogfood_target == none(没有可运行界面——配置 / schema / 文档,没有 journeys/ 目录):无需编写用户旅程——改为将每项验收标准映射到 Tier-1 脚本测试用例 / Tier-3 API 检查,然后跳到步骤 B 的覆盖说明。

各 Tier 的适用性取决于项目类型(CLI / 库层为 [1,2];只有真正的 none 目标层才全部采用 Tier-1,不编写用户旅程):/aep-e2e-skill-scaffolding references/three-tier-model.md。

步骤 B — 执行编写好的旅程(dogfood 测试)

**轻量模式:**跳过步骤 B(步骤 A 仍会执行)。在轻量模式之外,步骤 B 会使用任何可用的、适配宿主环境的方法运行;如果没有 agent-browser,则降级使用下一种方法,而不是跳过。

**环境预检(在旅程产生任何开销之前)。**运行 skills/e2e-test/policy.md 中声明的探测(/aep-gen-eval references/verification-economics.md → Environment Preflight Gate):

  • 不依赖部署的探测在此处对每个故事都运行,不受 journey_timing 影响——检查 CI 配置中是否存在必需密钥的_名称_、预期账户指纹是否与实际身份验证身份一致,以及部署配置中是否接入环境变量名称。这些探测不需要运行中的目标。
  • 绑定目标的探测(目标可访问、绑定已配置、可以植入测试数据)仅在 journey_timing: pre-merge 时于此处运行;在 post-deploy 时则在 /aep-wrap 门禁处运行。

未满足的必需前置条件属于具名拒绝(REFUSING [dogfood-secret-absent:<NAME>])——通过 Human-Gate Protocol 将其作为运维检查清单列出,并停止旅程:运行 0 个场景,消耗 0 轮,按定义归类为 environment,并作为运维工作提交,而不是代码故事。缺少可选能力(live_policy: milestone_gates_only 下非里程碑门禁的实时部分)应标记为跳过,而非拒绝——它不会阻塞任何内容。

运行该层的旅程(描述意图,而非点击脚本),并根据每一行 Verify 验证状态。旅程的 target:(web/mobile/desktop/cli)以及 skills/e2e-test/tool-selection.md(即 e2e_tool(target_type) 的项目本地映射)共同决定使用哪种自动化工具;适配宿主环境的选择方式及其降级顺序见 /aep-executor references/dogfood-validation.md(e2e_tool(target_type)、web 封装器 dogfood_method())。

根据 skills/e2e-test/policy.md(dogfood_target)解析目标:

  • cli → 通过 bash 在本地运行已构建的二进制文件(不使用 URL);如有需要,使用 bash skills/e2e-test/scripts/seed.sh 植入本地测试数据。
  • none → 跳过旅程 dogfood 测试(Tier-2 不适用);通过 Tier-1 / Tier-3 证明验收标准。
  • local → 运行 source .dev-workflow/ports.env 并使用 $BASE_URL(target_url(local))。
  • deployed:<url> → 使用该 URL(例如 Cloudflare 预览环境/生产环境),并为同一目标植入测试数据(SERVER_URL=<url> bash skills/e2e-test/scripts/seed.sh),而不是本地环境。如果 journey_timing 是 post-deploy,则将执行推迟到 /aep-wrap 门禁处(合并前目标尚未启动)——此处的阶段 6 仅运行 Tier-1/Tier-3,但步骤 A 的旅程文件仍需现在提交。
source .dev-workflow/ports.env   # local target → $BASE_URL  (deployed target: use the URL from policy.md)

无论采用哪种方法,都要输出统一的严重性/类别/复现报告格式(dogfood-validation.md → Unified report format),以便分类器不依赖宿主环境,并将报告写入 .dev-workflow/dogfood-<feature>.md,而不是发到聊天中——/aep-watch 的 dogfood_report 来源会读取该路径,并据此自动创建问题单。

**确认覆盖矩阵。**执行后,重新计算该层的覆盖矩阵:每条验收标准都必须对应一个能证明其满足的场景 Verify / 脚本化用例 / API 检查。由于步骤 A 已为每条验收标准编写了一个场景,此处只需确认——任何未覆盖的验收标准都表示步骤 A 有遗漏:现在补写该场景并重新运行,直至 coverage.criteria_covered == coverage.criteria_total(延期项需附带 WAIVER: <reason> 行)。

**信号:**设置 status.json:"phase": 6, "phase_name": "dogfood-testing"。


Phase 7:完成旅程并记录层级门禁

如果项目没有 e2e-test skill,请跳过。**轻量模式:**跳过此阶段。

该旅程已在 Phase 6 Step A 编写完成。此阶段将执行过程中发现的实际情况纳入该持久化 BDD 回归产物,完成最终定稿。在 skills/e2e-test/journeys/ 中:

  • 完善此层级现有的旅程——纳入选择器/路由偏差、额外的 Verify 行以及修正后的前置条件。在 journey_timing: post-deploy 下,该旅程稍后会在 /aep-wrap 门禁处执行,因此此次合并前定稿只纳入本地/Tier-3 检查发现的内容。
  • 每个 Then 都要保留一行具体的 Verify(API 响应/状态检查)。保持工具无关;API 级断言使用 .dev-workflow/ports.env 中的 $BASE_URL/$SERVER_URL(绝不硬编码端口)。

**记录层级门禁。**将证据写入 docs/layer-gates/<layer>.md(生成的 e2e-test skill 附带 layer-gate-evidence 模板):两份覆盖矩阵——验收可追溯性(标准 → 验证测试 → Verify → PASS/FAIL)和 脚本覆盖(用例 → 断言 → PASS/FAIL)——以及手动检查清单、截图/API JSON 和任何 WAIVER: 行。在 product-context.yaml 中更新 layer_gates[N].coverage 和 evidence.{scripted,journeys,matrix}。两阶段状态翻转(scripted_passed → passed)在 /aep-wrap 进行(参见 references/layer-advance.md)。


Phase 8:审查结果

**轻量模式:**跳过此阶段。

  1. 加载 .dev-workflow/ports.env,获取正确的端口。
  2. 运行项目的框架测试(Tier 1)、适用的 Tier-3 API 驱动程序,以及重放受影响的先前层级旅程集(回归)——根据合并后的差异而非声明的 files_affected 进行选择:当某个旅程的 covers: 标准属于此 story、其可选的 paths: front-matter glob 与差异相交,或者它完全未声明 paths: 时,该旅程就会受到影响(默认放行——未声明的旅程仍保留在重放集中)。此外,始终将 walking-skeleton 旅程作为金丝雀执行——执行一次,立即发现“应用已无法启动”这类问题。完整的先前层级重放应在 /aep-wrap 层级门禁及其中层检查点进行,而不是每个 story 都执行——但有一个例外:deep 层级的 story 要在此处重放完整的先前层级旅程集。仅当 journey_timing: pre-merge 时,才在此处重放此层级的 Tier-2 旅程——在 post-deploy 下,其执行推迟到 /aep-wrap 门禁(deployed:<url> 目标在合并前尚未启动)。验证所有适用项均通过,并且 coverage.criteria_covered == criteria_total(或为缺口添加 WAIVER:)。
  3. 展示(或记录在进度文件中):Phase 5 代码审查、Phase 6 试用报告(若已运行),以及 Phase 7 旅程结果 + 层级门禁证据 + 覆盖率摘要(若已运行,格式为 criteria_covered / criteria_total)。
  4. 如果测试失败,返回相应阶段重新处理。

**状态标记:**将 status.json 设为 "phase": 8, "phase_name": "review-results"。


Phase 9:清理并发布

此处不要运行 /opsx:archive——归档会在合并后通过 /aep-wrap 于集成分支上进行。

  1. **撰写经验总结。**发布前,在 .dev-workflow/lessons.md 中写一段最终的 ## Summary for Next Agent(1–3 句话):你会告诉下一个在此模块中开发的 Agent 什么?即使没有其他条目也要写(“实现过程很顺利,没有意外”也是有用的信息)。
  2. **审查提交历史:**运行 git log --oneline "$BASE"..HEAD(按照 /aep-git-ref 的“Resolving $BASE”说明解析 $BASE)。提交历史应当是干净的线性序列——每个 tasks.md 任务对应一个提交,之后可以有用于修复审查问题的提交。
  3. 变基到最新的集成分支并推送(首次推送时使用 -u):运行 git fetch origin && git rebase origin/"$BASE",解决冲突,然后运行 git push -u origin feat/<name>。完整操作步骤(包括中止流程)请参阅 /aep-git-ref 的“Publishing & PR Conventions”。

阶段 10:创建 PR / MR

创建 PR/MR 时必须显式传入基分支:gh pr create --base "$BASE"(GitHub)/ glab mr create --target-branch "$BASE"(GitLab),并根据 /aep-git-ref 中的“Resolving $BASE”解析 $BASE。主机自动检测和完整流程见 /aep-git-ref 中的“Publishing & PR Conventions” → “Open the PR”。如果主机无法识别,则手动创建 PR/MR,但仍须传入基分支。

显式指定基分支,是因为 gh pr create 否则会根据本地分支状态推断基分支,可能导致 PR 指向过期的基分支,或者在双分支模式下指向生产分支 main。后置条件:gh pr view --json baseRefName 返回 $BASE。

在 PR/MR 正文中包含:变更摘要(根据提案编写)、测试覆盖说明,以及手动测试计划链接(如果已创建)。


阶段 11:PR 审查与 CI 反馈循环

监控 CI 和审查反馈。

对每条评论进行分类: 修复——正确性问题、CI 失败、规范违规、安全问题。确认但跳过——风格偏好、过度设计、外观问题。讨论——会扩大范围的架构建议、相互冲突的评论。

修复循环:(1)对所有评论进行分类;(2)在 .dev-workflow/pr-fix-plan-<round>.md 中编写修复计划;(3)回复已跳过或待讨论的评论;(4)针对每项修复添加后续提交(fix(<scope>): address review feedback on <topic>);(5)重新运行测试;(6)重新推送(git push origin feat/<name>);(7)重复上述步骤,直到 CI 全部通过且审查问题均已解决。提交和推送规范:/aep-git-ref 中的“Publishing & PR Conventions”。


阶段 11.5:人工评估与迭代

PR 审查修复完成后,由人工测试人员评估该功能(通常通过在工作区运行应用来进行)。如果发现小问题(UX 调整、遗漏的边缘情况、行为不匹配),则在此阶段进行迭代。

**如果未发现问题:**跳至阶段 12。

迭代轮次:

  1. 在 .dev-workflow/human-eval-round-<N>.md 中记录发现:发现的问题(描述和复现步骤)、严重程度(轻微/中等)、类别(UX/逻辑/边缘情况/视觉)。
  2. 针对每项修复添加后续提交(fix(<scope>): <human-eval finding>)。
  3. 同步更新 OpenSpec 变更,路径为 openspec/changes/<name>/:在 tasks.md 中将已完成的任务标记为完成;如果行为发生变化,则更新 specs/;仅当方案发生变化时才更新 design.md;保持 proposal.md 中的范围不变。
  4. 重新测试——针对已更改的部分重新执行阶段 5(代码审查)和阶段 6(dogfood)。
  5. 推送(git push origin feat/<name>)。
  6. 如果测试人员发现更多问题,则重复上述步骤。

**信号:**准备好进行人工评估时,创建 .dev-workflow/signals/ready-for-review.flag;将 status.json 设置为 "phase": 11.5, "phase_name": "human-evaluation"。这是一个人工关卡——还应遵循 Human-Gate Protocol,以便协调器将其呈现出来,而不是将你计为卡住。


阶段 12:合并前检查与合并

  1. 确保与集成分支保持同步(按照 /aep-git-ref 中的“Resolving $BASE”解析 $BASE):git fetch origin && git rebase origin/"$BASE" && git push --force-with-lease origin feat/<name> — 带租约的推送仅在远程分支自上次获取后未前进时才会推送(参见 /aep-git-ref 中的“Publishing & PR Conventions”)。

  2. 读取 GitHub 自身的就绪状态:

    gh pr view <number> --json mergeStateStatus,mergeable --jq '{state: .mergeStateStatus, mergeable}'
    
    • CLEAN → 当前可合并(必需检查均已通过或没有必需检查;没有缺少必需审核)→ 继续(没有必需检查的 CLEAN PR 仍可合并 — 缺少检查不是等待的理由)。
    • 其他任何状态(UNKNOWN、UNSTABLE、BLOCKED、DIRTY、BEHIND)→ 操作前加载 references/merge-decision-cases.md,查看各状态的处理方式。
  3. 没有未解决的审核评论。

  4. E2E 测试已通过(如适用)。

  5. 重新检查后续提交的层级:如果上次评估通过后又有提交落地(第 11 阶段的审核修复、第 11.5 阶段的人工评估修复),请基于更新后的差异重新推导层级。如果变更涉及 sensitive_paths,则层级上调,并且合并前需要在上调后的层级重新完成一轮评估 — 这是过期评估规则,因为上次评估后代码已有变更。

  6. 提供最终状态摘要。

  7. 合并决策。mode 标记是检测的唯一依据:第 0 阶段的防护会将所有构建(包括交互式构建)移至工作树,因此无法通过当前工作目录区分自主模式和交互模式。

    MODE=$(cat "$(git rev-parse --show-toplevel)/.dev-workflow/signals/mode" 2>/dev/null)  # anchored — a build phase may have cd'd into a subdir
    
    • mode 的值恰好为 autopilot → 自主模式:满足合并前条件后立即合并(编排器通过信号进行监控;没有人在等待确认)。
    • 其他任何情况(缺失、空值或其他值)→ 交互模式:合并前请求确认。信号含糊时按交互模式处理。

    **“PR 已就绪”不是停止条件。**在自主模式下,只有 6 个合理条件会阻止合并 — 这些条件、完整的各状态处理方式以及示例均以 references/merge-decision-cases.md 为准;其他情况一律合并。**合并后,将 status.json 中的 story_status: "completed" — 到此你的工作结束。**Wrap 会在集成分支上运行 /opsx:archive,因此从此工作树运行 /aep-wrap 会破坏并发协议;由编排器执行收尾。

合并:

  • GitHub:gh pr merge <number> --squash --delete-branch
  • GitLab:glab mr merge <number> --squash --remove-source-branch

防护规则

适用于多个阶段、无法归入单一步骤的规则:

  • 只有主会话可以写入 product-context.yaml — 工作区通过 .dev-workflow/signals/status.json 报告状态(并发协议;/aep-launch 参考 signals-spec.md)。
  • **恢复流程:**如果返回继续执行进行中的工作流,请在 .dev-workflow/init.sh 存在时运行它,然后读取进度文件。
  • **信号:**在每个阶段的开始和结束时更新 status.json,并在阶段边界检查 .dev-workflow/signals/feedback.md 中来自主会话的反馈。

下一步

合并后,通知主会话运行:

/aep-wrap

评论

支持 Markdown