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. 05PRの作成と対応

活用シーン

  1. 01OpenSpecタスクに基づく機能実装
  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 の各行につき 1 コミット)、レビュー、テスト、PR の作成、フィードバックへの対応、マージまで、ユーザーとのやり取りなしで行います。

フェーズ番号について: フェーズ 1~3(調査、提案、レビュー)は、統合ブランチで /aep-design を使って完了しています。このスキルはフェーズ 0(ワークスペースの初期化)から始まり、フェーズ 4(実装)以降を続けます。

ループの健全性: 各フェーズは統一された --max-turns の暴走防止予算内で実行されます。上限に達しても完了ではありません。「解決できない可能性がある → エスカレーション」として扱ってください(Human-Gate Protocol)。正常終了とは区別されるため、たとえばフェーズ 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. Gitignore に追加します: 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 を読みます。 tasks.md が作業の骨格になります。フェーズ 4 で各行の作業を順番に実装し、各行につき 1 コミットを作成することで、コミット履歴を tasks.md と 1 対 1 で対応させます。事後条件: タスクリストを把握している。

  6. プロジェクトをセットアップします。 .claude/hooks/workspace-setup.sh が存在する場合は bash で実行します(依存関係、開発サーバー、ポート、DB/シード、.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 が存在し、4 つのキーが含まれている。

  7. スプリント契約を生成し、.dev-workflow/contracts.md に保存します。specs/*.md、design.md、tasks.md をもとに、タスクごとにセクションを1つ作成します。形式は references/contract-template.md を参照してください。完了条件: タスクごとにセクションが1つあるファイルが存在すること。

  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 の各タスクを順番に、1タスクずつ=1コミットで実装し、その後コミット SHA を記録します。各タスクでは、実装(ファイルを直接編集)、確認(git status / git diff)、対象を絞ったテストの実行を行い、その後 feat(<scope>): <task description> でコミットします。対応する feature-verification.json のエントリーの commit_sha に、8文字の短縮 SHA を記入します(verification_steps と passes は変更しないでください)。コミットの形式、amend のルール、復旧方法については、正規の タスクごとに1コミットのパターンを参照してください。/aep-build の「The One-Commit-per-Task Pattern (Phase 4 of /aep-build)」を参照してください。

タスクごとのガイダンスを得るため、適用スキルを呼び出します。

/opsx:apply

UI に関わるストーリー — Object Map に従ってください。 ディスパッチされたコンテキストパッケージに Object Map の抜粋(オブジェクト、属性、関係、CTA、画面)が含まれている場合、それを拘束力のある構造として扱います。指定された画面をオブジェクト優先(名詞→動詞、つまりオブジェクトの一覧/詳細と、指定された CTA の配置)で構築し、指定された主要属性を使用してください。また、抜粋に task_oriented と記されている場合を除き、抜粋にないオブジェクトや画面を追加したり、フローを手順型のウィザードにまとめたりしないでください。見た目(calibration/visual-design.yaml)、文体(copy-tone)、およびジャーニー/遷移(ux-flow)は引き続き表現を規定しますが、オブジェクトの構造と CTA の文法は Object Map が規定します。

レッスンの記録(タスクごとに任意): タスクの完了後、特筆すべきこと(自明でない解決策、何度も試行したエラー、ドキュメントの不足など)があれば、.dev-workflow/lessons.md の ## Solutions/## Errors/## Missing の下に ### <title> の小見出しを付けて追記します。後で共有する価値がある場合に限ります。

タスクごとに進捗チェックボックスを更新し、すべてのタスクがコミットされたらフェーズ 4 を完了にします。シグナル: 開始時に status.json の "phase": 4 を設定し、タスクの進行に合わせて task_current、task_index、task_total、completion_pct を最新の状態に保ちます。


フェーズ 5:コードレビューと検証

テストの前にコードを検証します。このフェーズではジェネレーター/評価側のパターンを使用します。詳細な仕組みは /aep-gen-eval の各リファレンスを参照してください。scoring-framework.md(評価項目、しきい値、プリセット)、agent-contracts.md(役割の分離、プロンプトテンプレート)、eval-protocol.md(リクエスト/レスポンス形式、検証 JSON、収束ルール)が含まれます。 Phase 5 の開始 — 評価ラウンドで上限を消費する前に、バインディングティアを導出します。 policy.md の sensitive_paths と審判用アセットのルールに照らして、実際の差分(git diff --name-only "$BASE"...HEAD)から検証ティアを再導出し、.dev-workflow/verification-recipe.json にティア、ディメンションプリセット、最低基準、scope_drift/tier_escalated を出力します。導出ルール、最低基準、レシピのスキーマについては、/aep-gen-eval の references/verification-economics.md → Two-Point Derivation を参照してください(生成された E2E スキルには、実行可能なスクリプトが含まれています)。ここでは、次の 2 つのルールが適用されます。ティアはディスパッチブリーフの暫定ティアから上がる場合のみ変更でき、宣言された files_affected に含まれない差分がある場合は、差分から再計算して scope_drift: true を設定します。レシピファイルがなければ Phase 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>)を追加して Phase 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 が管理します。これは自動操縦の品質ゲートが読み取るシグナルです)。

基準を用意したら、評価者は executor.spawn_evaluator() を介し、モードに応じてディスパッチされ、このワークスペースのファイルと Git の状態に紐付けられた状態で実行されます。モードごとの起動手順は /aep-executor references/backends.md に記載されています。オーケストレーション層がある場合、起動権限はジェネレーターから切り離されます(自動操縦は起動を促し、対話実行ではメインセッションが起動を担います)。オーケストレーターが評価者のコンテキストを組み立てるため、ジェネレーターが評価者の目に触れる情報を選別することはできません。真に単独のビルドの場合に限り、ジェネレーター自身が起動手順を呼び出します。どのモードでも、評価者向けプロンプトでは eval-request.md をジェネレーターによる信頼できない主張と位置づけます。つまり、検証するためのデータであり、採用すべき枠組みではありません(/aep-gen-eval references/agent-contracts.md)。

評価ループ — 各ラウンド N について(1 から開始し、評価者を起動するすべてのティアで最大 2 回:light は 0 回/standard は 2 回/deep は 2 回。レシピでさらに多く指定されていても、ここでは最大 2 回に制限します)。2 回目のラウンドを実施するのは、blocking の指摘があった場合に限ります。

  1. eval-protocol.md(Signal Files)に従って、eval-request .dev-workflow/signals/eval-request.md を作成します。
  2. agent-contracts.md(Evaluator Prompt — Code Quality)から評価者プロンプトを作成し、ワークスペースのパス(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 → Failure Taxonomy)が必ず付与され、それに基づいて振り分けます。environment → Human-Gate Protocol を通じて運用チェックリストへ進み、それ以降のラウンドは行いません。harness-flake → 隔離し、ハーネスに関するストーリーを作成します。scope → ヒューマンゲートを経て /aep-reflect で再分割します。リポジトリ内の未構築の依存関係 → /aep-dispatch で順序を変更します。続行するのは product-defect の指摘のみで、かつ Impact: blocking の場合に限ります。判定はインパクトラベルから導きます(eval-protocol.md)。blocking の指摘がない応答は PASS または PASS with notes として扱います。material の指摘を修正し、修正ごとにその証拠(コミット、テスト、またはプローブ)を eval-request.md の追記に記録します。polish の注記は PR の本文に引き継ぎ、追加ラウンドを一切消費せずに Phase 6 に進みます。ラウンド 1 の後に blocking の指摘がある場合は、再グラウンディング(仕様、設計、コントラクトを最初から読み直す)して修正し、フォローアップのコミットを追加してから、ラウンド 2 としてステップ 1 に戻ります。PR では修正が新しいコミットとして反映されるため、履歴は追記のみとなります。

評価者のみが、eval-protocol.md のフィールド所有権に従って .dev-workflow/feature-verification.json の pass/fail を更新します。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 のままにします)。ゲート記録には 2 ラウンド分の履歴と、人間またはオートパイロットポリシーが選択できる戦略変更の提案を記載します。たとえば、「前のアプローチでは X が解決できなかった。別の設計方針を取ること」と指示した新しいジェネレーター(この作業ツリーを引き継ぎます)を起動する、またはストーリーを実行可能な最小単位に分割し、その分割案を提示する、といった方法があります。

リカバリーラダー(ジェネレーター側、2 段階) — ラウンド 1:同じジェネレーターがその場で blocking の指摘を修正します。ラウンド 2 の前に、再グラウンディングしてから修正します。評価者は採点のみを行うため、再グラウンディングと 2 つのゲート選択肢は、どちらもジェネレーター側で行います。このラダーは product-defect 専用の仕組みです。段階を選ぶ前に、ステップ 6 の分類によって、それ以外のすべてのクラスをラダーの対象外に振り分けます。ハードフェイルまたはセキュリティ上の FAIL(認証モデルの不備、データ露出のリスク)、仕様の矛盾(scope)、外部依存関係の欠如(名前付き拒否タグが必要な environment)の場合は、ラダーをスキップして直ちにエスカレーションします。これらには人間の判断が必要です。根拠と新しいジェネレーターの起動コントラクトについては、/aep-gen-eval references/recovery-ladder.md を参照してください。

品質レビュー — 評価者なし(ライトモード): 正確性、セキュリティ、パフォーマンス、規約を対象に、構造化されたセルフレビューを行い、feature-verification.json のステップを手動で確認します。指摘事項を .dev-workflow/code-review-<feature>.md に記録し、見つかった問題を修正します。

Phase 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 → ヒューマンゲートプロトコルを参照)。回答はメインエージェント経由で戻ってくるため(ハブ&スポーク方式)、人間はすでにいる場所で回答できます。プッシュ通知のないモード(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 — レイヤーのジャーニーを作成する(常に、マージ前)

プロジェクトに journeys/ ディレクトリを持つ e2e-test スキルがあり(dogfood_target != none)、このレイヤーを対象とするジャーニーがない場合、または新しい受け入れ基準にシナリオがない場合は、今すぐ skills/e2e-test/journeys/<NN-slug>.md でジャーニーを作成または拡張します(パスは layer_gates[N].journeys に記載されています。journeys/README.md のテンプレートをコピーし、フロントマターに target:、layer:、covers: を設定します。covers: はこのジャーニーで検証する受け入れ基準の ID です。/aep-e2e-skill-scaffolding references/bdd-journeys.md を参照してください)。

  • stories[].acceptance_criteria の受け入れ基準ごとに 1 つのシナリオを作成します。各 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(実行可能なサーフェスがない場合 — 設定/スキーマ/ドキュメントで、journeys/ ディレクトリがない場合):作成するジャーニーはありません。代わりに、各受け入れ基準を Tier-1 のスクリプトテストケースまたは Tier-3 の API チェックに対応付けてから、ステップ B のカバレッジに関する注記に進みます。

適用する Tier はプロジェクトの種類によって異なります(CLI/ライブラリのレイヤーは [1,2]、本当に none を対象とするレイヤーのみ Tier-1 でジャーニーは不要です)。/aep-e2e-skill-scaffolding references/three-tier-model.md を参照してください。

ステップ B — 作成したジャーニーを実行する(ドッグフードテスト)

ライトモード: ステップ B はスキップします(ステップ A は実行済みです)。ライトモード以外では、利用可能なホスト対応の方法を使ってステップ B を実行します。agent-browser がない場合はスキップせず、次の方法に切り替えます。

環境の事前確認(ジャーニーの実行に費用が発生する前に行います)。 skills/e2e-test/policy.md で宣言されているプローブを実行します(/aep-gen-eval references/verification-economics.md → 環境の事前確認ゲート)。

  • デプロイに依存しないプローブは、journey_timing にかかわらず、すべてのストーリーでここで実行します。CI 設定に必要なシークレットの 名前 が存在すること、想定されるアカウントのフィンガープリントと実際の認証 ID が一致すること、デプロイ設定で環境変数名が設定されていることを確認します。これらに実稼働のターゲットは必要ありません。
  • ターゲットに依存するプローブ(ターゲットに到達可能であること、バインディングが存在すること、フィクスチャをシードできること)は、journey_timing: pre-merge の場合に限り、ここで実行します。post-deploy の場合は /aep-wrap ゲートで実行します。

必須の前提条件が満たされていない場合は、名前を明示して拒否します(REFUSING [dogfood-secret-absent:<NAME>])。Human-Gate Protocol を通じて運用チェックリストとして提示し、ジャーニーを停止します。シナリオの実行数はゼロ、消費ラウンド数もゼロとなり、environment に分類されます。コードのストーリーではなく、運用作業として起票します。任意の機能がない場合(live_policy: milestone_gates_only におけるマイルストーン以外のゲートのライブ部分)は、拒否ではなく SKIP です。これは何も妨げません。

レイヤーのジャーニーを実行します(クリック手順ではなく、意図に沿って実行します)。各 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 → ジャーニーのドッグフードテストをスキップします(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 → 統一レポート形式)で出力し、分類器がホストに依存しない状態を保ちます。チャットではなく .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" を設定します。


フェーズ 7:ジャーニーを仕上げ、レイヤーゲートを記録する

プロジェクトに e2e-test スキルがない場合はスキップしてください。ライトモード: このフェーズをスキップしてください。

ジャーニーはフェーズ 6 のステップ 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 スキルには layer-gate-evidence テンプレートが含まれています)。記録するのは、2 つのカバレッジマトリックス——受け入れ基準のトレーサビリティ(基準 → 証明するテスト → Verify → PASS/FAIL)と スクリプト化カバレッジ(ケース → アサーション → PASS/FAIL)——に加えて、手動チェックリスト、スクリーンショット/API JSON、および WAIVER: 行です。product-context.yaml の layer_gates[N].coverage と evidence.{scripted,journeys,matrix} を更新します。2 段階の切り替え(scripted_passed → passed)は /aep-wrap で行われます(references/layer-advance.md)。


フェーズ 8:結果をレビューする

ライトモード: このフェーズをスキップしてください。

  1. 正しいポートを確認するために .dev-workflow/ports.env を読み込みます。
  2. プロジェクトのフレームワークテスト(Tier 1)、該当する Tier-3 API ドライバー、および影響を受ける過去レイヤーのジャーニーセットを再実行(回帰テスト)します。対象は宣言された files_affected ではなく、マージ済みの差分に基づいて選定します。ジャーニーは、covers: の基準がこのストーリーに属している場合、任意の paths: フロントマターの glob が差分と交差する場合、または paths: が一切宣言されていない場合に影響を受けます(フェイルオープン:未宣言のジャーニーも再実行対象に含めます)。さらに、ウォーキングスケルトンのジャーニーは必ずカナリアとして実行します。これは「アプリが起動しなくなった」種類の問題をすぐに検出するための 1 回の実行です。過去レイヤー全体の再実行は /aep-wrap レイヤーゲートとそのレイヤー途中のチェックポイントで行うものであり、各ストーリーで行うものではありません。ただし、例外として、deep ティアのストーリーではここで過去レイヤー全体を再実行します。このレイヤーの Tier-2 ジャーニーをここで再実行するのは、journey_timing: pre-merge の場合に限ります。post-deploy の場合は、deployed:<url> のターゲットがマージ前に稼働していないため、実行は /aep-wrap ゲートまで保留されます。該当するすべての項目が合格し、coverage.criteria_covered == criteria_total であることを確認します(未達がある場合は WAIVER: を付けます)。
  3. フェーズ 5 のコードレビュー、フェーズ 6 のドッグフードレポート(実施した場合)、フェーズ 7 のジャーニー実行結果+レイヤーゲートの証跡+カバレッジ概要(実施した場合は criteria_covered / criteria_total)を提示します(または進捗ファイルに記載します)。
  4. テストが失敗した場合は、該当するフェーズに戻ります。

シグナル: status.json の "phase": 8, "phase_name": "review-results" を設定します。


フェーズ 9:クリーンアップと公開

ここでは /opsx:archive を実行しないでください。アーカイブはマージ後に統合ブランチで(/aep-wrap 経由で)行います。

  1. 教訓の要約を記述します。 公開前に .dev-workflow/lessons.md に最終的な ## Summary for Next Agent(1~3 文)を記述します。このモジュールで開発を行う次のエージェントに何を伝えますか?ほかに記載がない場合でも必ず記述してください(「実装は単純で、予想外のことはなかった」も有用なシグナルです)。
  2. コミット履歴を確認します。 git log --oneline "$BASE"..HEAD(/aep-git-ref の「Resolving $BASE」に従って $BASE を解決します)。履歴はきれいな直線状であるべきです。tasks.md のタスクごとに 1 つのコミットとし、必要に応じてレビュー修正のコミットが続きます。
  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)。$BASE の解決方法は /aep-git-ref の「$BASE の解決」を参照してください。ホストの自動検出と手順全体は /aep-git-ref の「公開と PR の規約」→「PR を開く」にあります。ホストを識別できない場合は、ベースを指定したうえで手動で開きます。

gh pr create は、明示しないとローカルブランチの状態からベースを推測するため、古いベースや、2 ブランチモードでは本番の main に PR が作成されることがあります。そのため、ベースを明示します。事後条件: 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 の「公開と PR の規約」を参照してください。


フェーズ 11.5:人による評価と反復

PR レビューの修正が解決した後、人間のテスターが機能を評価します(通常はワークスペースからアプリを実行します)。軽微な問題(UX の調整、考慮されていないエッジケース、動作の不一致)が見つかった場合、このフェーズで反復ループを実施します。

問題が見つからなかった場合: フェーズ 12 に進みます。

反復ラウンド:

  1. .dev-workflow/human-eval-round-<N>.md に調査結果を記録します:見つかった内容(説明と再現方法)、重大度(軽微/中程度)、カテゴリ(UX/ロジック/エッジケース/ビジュアル)。
  2. 修正ごとに追加コミットを作成します(fix(<scope>): <human-eval finding>)。
  3. openspec/changes/<name>/ の OpenSpec 変更を整合させます:完了したタスクを tasks.md に追加し、動作が変わった場合は specs/ を更新し、アプローチが変わった場合に限り design.md を更新します。proposal.md のスコープはそのままにします。
  4. 再テスト — 変更した領域についてフェーズ 5(コードレビュー)とフェーズ 6(ドッグフード)を再実行します。
  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 の「$BASE の解決」に従って $BASE を解決します):git fetch origin && git rebase origin/"$BASE" && git push --force-with-lease origin feat/<name> — lease 付きの方法では、最後にフェッチしてからリモートが更新されていない場合にのみプッシュされます(/aep-git-ref の「公開と PR の規約」)。

  2. GitHub 自身の準備状況を確認します:

    gh pr view <number> --json mergeStateStatus,mergeable --jq '{state: .mergeStateStatus, mergeable}'
    
    • CLEAN → 今すぐマージ可能です(必須チェックを満たしているか、必須チェックがありません。必須レビューの不足もありません)→ 続行します(必須チェックが 0 件の CLEAN な PR はマージ可能です。チェックがないことは待つ理由になりません)。
    • それ以外(UNKNOWN、UNSTABLE、BLOCKED、DIRTY、BEHIND)→ 対応する前に、状態ごとの対応方法を記載した references/merge-decision-cases.md を読み込みます。
  3. 未解決のレビューコメントがないこと。

  4. E2E テストに合格していること(該当する場合)。

  5. 評価後にコミットが追加された場合のティア再確認: 最後に評価が PASS となった後(フェーズ 11 のレビュー修正、フェーズ 11.5 の人による評価の修正)にコミットが追加された場合は、更新後の差分に基づいてティアを再判定します。sensitive_paths への変更によりティアが上がった場合は、マージ前に、引き上げ後のティアで新たに評価を 1 回実施する必要があります。これは、最後の評価以降にコードが変更されたための古い評価に関するルールです。

  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" を設定します。そこで作業は終了です。 ラッパーは統合ブランチで /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 は references/signals-spec.md を参照します)。
  • 再開: 進行中のワークフローに戻る場合は、存在すれば .dev-workflow/init.sh を実行し、その後、進捗ファイルを読みます。
  • シグナル: 各フェーズの開始時と終了時に status.json を更新し、フェーズの境目でメインセッションからのフィードバックがないか .dev-workflow/signals/feedback.md を確認します。

次のステップ

マージ後、メインセッションに次を実行するようシグナルを送ります:

/aep-wrap

コメント