mcpField
S
swain-do

swain-do

github.com/cristoslcエージェントワークフロー2128 回インストール25 週間前に更新
リポジトリ

swain-do について

swain-doは、エージェントの実行状況を追跡するスキルです。抽象的な計画やタスクをtkコマンドに置き換え、タスク分割、依存関係、状態更新に加え、セッション確認、TDD、完了前検証の手順を案内します。

主な機能

  1. 01計画とタスクをtkチケットに変換
  2. 02チケットの依存関係、担当、状態を管理
  3. 03タスクとSPECを関連付け、範囲のずれを解決
  4. 04セッション確認とブックマーク更新
  5. 05TDDと完了前の検証を徹底

活用シーン

  1. 01SPECを実装計画とタスクに分割
  2. 02着手可能な作業を確認してチケットを担当
  3. 03タスクの進捗と関連仕様を追跡
  4. 04作業のずれをエスカレーションして調整

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/cristoslc/swain --skill swain-do

インストール後、Claude Code で/swain-doを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

bin/
ticket-migrate-beads
ticket-query
tk
references/
.gitkeep
configuration.md
escalation.md
execution-strategy.md
plan-ingestion.md
reconciliation.md
tdd-enforcement.md
tk-cheatsheet.md
scripts/
.gitkeep
ingest-plan.py
swain-worktree-overlap.sh
test-worktree-overlap.sh

詳細

実行トラッキング

状態を変更する操作に進む前に、アクティブなセッションがあるか確認します。

REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-session-check.sh" 2>/dev/null

JSON の出力で "status" が "active" 以外の場合は、オペレーターに「アクティブなセッションがありません — /swain-init で開始しますか?」と伝えます。オペレーターがそのメッセージを閉じた場合は続行します。

エージェントの実行トラッキングのための抽象化レイヤーです。他のスキル(例:swain-design)は抽象的な用語で意図を表現し、このスキルがその意図を具体的な CLI コマンドに変換します。

初回使用前: 完全なコマンド構文、フラグ、ID 形式、アンチパターンについて、references/tk-cheatsheet.md を確認してください。

成果物の引き継ぎプロトコル

このスキルは、4 階層のトラッキングモデルに基づき、swain-design から引き継ぎを受けます。

階層成果物このスキルの役割
実装SPECコードを書く前に、トラッキング対象の実装計画とタスクの内訳を作成します
調整EPIC、VISION、JOURNEY直接トラッキングしません — swain-design がこれらを先に子要素へ分解し、その子要素を引き継ぎます
調査SPIKEタスクの内訳が有効なほど複雑な調査の場合、トラッキング対象の計画を作成します
参照ADR、PERSONA、RUNBOOKトラッキングは不要です

調整階層の成果物(EPIC、VISION、JOURNEY)に対して、事前の分解なしで直接呼び出された場合は、まず swain-design に委ねて子 SPEC を作成してもらい、その後、それらの子 SPEC の計画を作成します。

用語の対応関係

他のスキルでは、以下の抽象的な用語を使用します。このスキルは、それらを現在のバックエンド(tk)に対応付けます。

抽象用語意味tk コマンド
実装計画SPEC 成果物に関連するすべてのタスクをまとめる最上位のコンテナーtk create "Title" -t epic --external-ref <SPEC-ID>
タスク計画内の個別の作業単位tk create "Title" -t task --parent <epic-id>
起点参照計画を起点となった SPEC に結び付ける変更不可のリンクepic の作成時に指定する --external-ref <ID> フラグ
spec タグタスクを、そのタスクが影響するすべての SPEC に結び付ける変更可能なタグ作成時の --tags spec:<ID>
依存関係タスク間の順序制約tk dep <child> <parent>(child は parent に依存します)
実行可能な作業着手可能な、ブロックされていないタスクtk ready
割り当てタスクの担当をアトミックに取得することtk claim <id>
完了タスクを完了としてマークすることtk add-note <id> "reason" の後に tk close <id>
放棄完了しないタスクを閉じることtk add-note <id> "Abandoned: <why>" の後に tk close <id>
エスカレーション放棄したうえで swain-design を呼び出し、上流の成果物を更新すること放棄してから swain-design スキルを呼び出します

設定とブートストラップ

設定は .agents/execution-tracking.vars.json に保存されます(初回実行時に作成)。初回セットアップ時の質問、設定キー、6 ステップのブートストラップワークフローについては、references/configuration.md を確認してください。

ステータス

tk で受け付けるステータス値は open、in_progress、closed の 3 つのみです。任意のステータスを設定するには status コマンドを使いますが、依存関係グラフ(ready、blocked)で評価されるのはこの 3 つだけです。

放棄を表すには、tk add-note <id> "Abandoned: ..." の後に tk close <id> を実行します。エスカレーションを参照してください。

チケットのライフサイクル(ADR-015)

チケットは一時的な実行補助情報です。SPEC の実装中に、エージェントが作業を追跡し、中断後に再開するのを支援するために存在します。親 SPEC が終端状態(完了、放棄)に移行した後は、そのチケットを破棄できます。チケットは trunk にコミットせず、振り返りの証拠としても使用せず、worktree のクリーンアップを妨げないようにしてください。発生した内容のアーカイブ記録はセッションログ(.agents/session.json JSONL)であり、チケットは進行中の作業を示すライブダッシュボードです。

運用ルール

  1. イシューを作成するときは、必ず --description(または -d)を指定してください。タイトルだけでは、タスクの背景にある「理由」が伝わりません。この作業を引き継ぐ後続のエージェント(または未来の自分)が、再調査せずに対応できるだけのコンテキストが必要です。
  2. 作業開始時、主要なマイルストーンの達成後、最終回答の前に、タスクを作成・更新してください。これにより、トラッカーを事後記録ではなく、常に最新のダッシュボードとして活用できます。
  3. タスクのタイトルは短く、行動が伝わるものにしてください。タイトルは tk ready の出力、ツリービュー、通知など、表示スペースが限られた場所に表示されます。
  4. 引き継ぎメモは、一時的なチャットのコンテキストではなく、tk add-note <id> "context" を使って保存してください。セッション間でチャット履歴は失われますが、タスクのメモは保持され、すべてのエージェントや閲覧者が確認できます。
  5. 関連するアーティファクト ID への参照をタグに含めてください(例:spec:SPEC-003)。これにより、特定の仕様に関わるすべての作業を検索できます。
  6. 未完了のタスクをクローズする際、放棄理由には**Abandoned: を先頭に付けてください**。このルールにより、放棄された作業を検索でき、何も気づかれないまま消えることを防げます。
  7. 構造化出力には ticket-query を使用してください。プログラムで使う JSON が必要な場合は、人間向けの出力を解析せず、(同梱の bin/ ディレクトリにある)ticket-query にパイプしてください。例:ticket-query '.status == "open"'

TDD の徹底

合理化を防ぐための保護策と完了確認を備えた、厳格な RED-GREEN-REFACTOR を実施します。合理化防止の表、タスクの順序ルール、証拠要件については、references/tdd-enforcement.md をお読みください。

仕様系譜のタグ付け

プランのエピックには --external-ref SPEC-NNN(変更不可の起点)を、子タスクには --tags spec:SPEC-NNN(変更可能)を使用します。検索:ticket-query '.tags and (.tags | contains("spec:SPEC-003"))'。プラン間のリンク:tk link <task-a> <task-b>。

エスカレーション

設計どおりに作業を進められない場合は、タスクを放棄して swain-design にエスカレーションしてください。トリアージ表、放棄コマンド、エスカレーションのワークフロー、仕様をまたぐ場合の対応については、references/escalation.md をお読みください。

「次は何をする?」の手順

ブロックされていないタスクを確認するには tk ready を実行し、進行中の作業を確認するには ticket-query '.status == "in_progress"' を実行します。.tickets/ が空、または存在しない場合は、アーティファクト単位のガイダンスを得るために bash "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents/bin/chart.sh" ready を実行してください。

タスクの引き受け時のコンテキスト

spec:<ID> タグの付いたタスクを引き受ける際は、戦略的なコンテキストを示すため、Vision までの系譜をパンくずリストとして表示してください。親の連鎖を表示するには、bash "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents/bin/chart.sh" scope <SPEC-ID> 2>/dev/null | head -5 を実行してください。これにより、現在のタスクがプロジェクトの戦略とどう結びついているかを、エージェントやオペレーターが把握できます。

アーティファクトと tk の整合性確認

specwatch が不一致(.agents/specwatch.log 内の TK_SYNC、TK_ORPHAN)を検出した場合は、不一致の種類、解決コマンド、整合性確認のワークフローについて references/reconciliation.md をお読みください。

ドリフトの解消(SPEC-307)

チケットを作成、編集、クローズする際、そのチケットに spec: タグが付いている場合は、タグ付けされた SPEC に対してドリフトを解消してください。チケットと SPEC の両方を確認します。チケットのスコープが SPEC の受け入れ条件または問題文からずれている場合は、子チケットを修正する(チケットを編集する)か、親を更新する(SPEC を編集する)ことで修正してください。

修正の方向は、シグナルと内容の判断に基づいて決めます。親に対する過去のドリフト判断の数を数え(多いほど、親が古くなっている可能性が高くなります)、どちらの方向がより良い結果につながるかも評価してください。修正を適用した後、結果をオペレーターに提示して、承認、変更、または差し戻しを受けてください。すべての結果は swain-session-state.sh record-decision でドリフト判断として記録します。

セッションブックマーク

状態を変更する操作の後は、ブックマークを更新してください:bash "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents/bin/swain-bookmark.sh" "<action> <task-description>"

Superpowers スキルの連携

superpowers がインストールされている場合、swain-do は特定のタイミングでこれらのスキルを呼び出します。呼び出しを省略したり、作業をインラインで行ったりすると、スキルが提供する保証が損なわれます。TDD は問題が積み重なる前にリグレッションを検出し、検証は後続の作業を無駄にする誤った完了報告を防ぎます。

  1. あらゆるタスクのコードを書く前: test-driven-development スキルを呼び出します。まず失敗するテスト(RED)を書き、次にテストを通し(GREEN)、その後でリファクタリングします。これは最初のタスクだけでなく、すべてのタスクに適用されます。

  2. 並行作業を割り当てるとき:(サブエージェントが利用可能で、タスクが独立している場合は)subagent-driven-development、そうでなければ(逐次実行の場合は)executing-plans を呼び出します。判断フローについては references/execution-strategy.md を参照してください。

  3. タスクまたは計画の完了を報告する前: verification-before-completion を呼び出します。検証コマンドを実行して出力を読み、その後でのみ成功を報告してください。最新の証拠がない状態で完了を報告してはいけません。

検出: ls .agents/skills/test-driven-development/SKILL.md .claude/skills/test-driven-development/SKILL.md 2>/dev/null — いずれかのパスが存在すれば、superpowers を利用できます。この結果はセッション中キャッシュしてください。

superpowers がインストールされていない場合、swain-do は組み込みの TDD 強制機能(references/tdd-enforcement.md を参照)と逐次実行を使用します。

計画の取り込み(superpowers との連携)

superpowers の計画ファイルがある場合、手動でタスクを分解する代わりに、取り込みスクリプト(scripts/ingest-plan.py)を使用します。使い方、形式要件、および使用しない場合については references/plan-ingestion.md を参照してください。

実行戦略

superpowers の利用可否とタスクの複雑さに基づいて、逐次実行とサブエージェント主導の実行を選択します。判断フロー、検出コマンド、ワークツリー成果物の対応付けについては references/execution-strategy.md を参照してください。

計画前の実装検出

SPEC の計画を作成する前に、すでに実装されている証拠がないかを調べます。これにより、未マージブランチに存在する作業や以前のセッションで完了した作業を再実装せずに済みます。これらのチェックは独立した情報であり、ひとつの判断につながるため、並行して実行します。

シグナルのスキャン
シグナルチェック重要な理由
未マージのブランチgit for-each-ref --format='%(refname:short) %(upstream:trackshort)' refs/heads/ | grep -i "<SPEC-ID>" を実行し、次に git merge-base --is-ancestor <branch> HEAD で未マージであることを確認します。以前のセッションのワークツリーブランチは、トランクに到達していないコミットを含むため、最も強いシグナルです。計画作成の途中でこれを発見すると作業が滞りますが、ここで見つければ手間はかかりません。
Git の履歴git log --oneline --all | grep -i "<SPEC-ID>"SPEC ID を参照するコミットは、リポジトリの履歴内のどこかで実装が行われたことを示します。
成果物ファイルSPEC を読み、記載されている出力(スクリプト、モジュール、設定)を特定します。ls または Glob を使い、それらが HEAD に存在するか確認します。対応するコミットがない状態でディスク上にファイルが存在する場合、不完全な作業または未コミットの作業である可能性があります。
テストの成功SPEC のテストをもう一度実行し、出力を読みます。以前の結果は証拠になりません。証拠となるのは、実行したばかりの結果だけです。これは重要な関門です。エージェントは「以前テストが通った」と合理化して、再実行しない傾向があります。セッション間のコード変更によって、それまで成功していたテストが気づかないうちに失敗することがあるため、これが重要です。
判断
  • シグナルが2つ以上 →(以下の)遡及的クローズの手順に進みます
  • シグナルが1つ → 通常どおり計画を作成し、最初のタスクの説明にそのシグナルを記載します
  • シグナルが0個 → 通常どおり進めます
遡及的なクローズ手順

以前に実装済みであることを示す証拠がある場合は、タスクをすべて分解する手順を省略します。

  1. 追跡用タスクを1つ作成します。tk create "Retroactive verification: <SPEC-ID>" -t task --external-ref <SPEC-ID> -d "Verify prior implementation before closing SPEC."
  2. タスクを担当します。tk claim <id>
  3. verification-before-completionを実行します(superpowersがインストールされている場合)。または、仕様のテストを手動で再実行します。
  4. 検証に合格した場合は、証拠を添えてメモを追加し、タスクを完了した後、swain-designを呼び出して仕様をCompleteに移行します。
  5. 検証に失敗した場合は、通常の計画作成に切り替えます。以前の実装は不完全でした。

Worktree分離の事前手順

swain-doが追跡する変更を伴う作業は、ソースコード、成果物、スキルファイル、データのいずれを変更する場合でも、すべてworktree内で行います。これにより、未完了の変更がtrunkに混入するのを防ぎ、並行するエージェント間の競合を回避できます。ファイルの変更を伴う操作(計画の作成、タスクの担当、コードの記述、成果物の編集、スキルファイルの変更、仕様の移行、実行の引き継ぎ)を行う前に、次の検出手順を実行してください。

読み取り専用の操作では、この事前手順全体を省略します。 現在のコンテキストでそのまま進めてください。読み取り専用として明示的に許可されている操作は次のとおりです。

  • tk ready、tk show、tk status、tk list
  • ticket-query(構造化クエリ)
  • 計画の確認(計画ファイルを変更せずに読み取る)
  • ステータス確認とタスクの照会
Step 0 — 変更のあるファイルをコミットする

この手順は必ず実行します。 worktree内にいるかtrunk上にいるかにかかわらず、セッション中に生じた未コミットの変更(新規作成した成果物、編集した仕様など)は、次に進む前にHEADに反映する必要があります。worktreeはHEADからチェックアウトされ、trunk上でも、未コミットのファイルは上書きされたり失われたりするおそれがあるためです。

REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
UNTRACKED=$(git -C "$REPO_ROOT" ls-files --others --exclude-standard 2>/dev/null)
MODIFIED=$(git -C "$REPO_ROOT" diff --name-only 2>/dev/null)
if [ -n "$UNTRACKED" ] || [ -n "$MODIFIED" ]; then
  [ -n "$UNTRACKED" ] && echo "$UNTRACKED" | xargs -d '\n' git -C "$REPO_ROOT" add --
  [ -n "$MODIFIED" ] && echo "$MODIFIED" | xargs -d '\n' git -C "$REPO_ROOT" add --
  git -C "$REPO_ROOT" commit -m "chore: stage dirty tree before worktree creation" || {
    echo "ERROR: pre-commit step failed — aborting worktree creation"
    exit 1
  }
fi

コミットに失敗した場合(たとえば、pre-commitフックに拒否された場合)は、エラーを報告して停止してください。worktreeの検出や、その他の手順には進まないでください。

Step 1 — 作業ツリーのコンテキストを検出する
# SPEC-250: Check env var first (set by bin/swain), then git plumbing
if [ -n "${SWAIN_WORKTREE_PATH:-}" ]; then
  IN_WORKTREE=yes
else
  GIT_COMMON=$(git rev-parse --git-common-dir 2>/dev/null)
  GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
  [ "$GIT_COMMON" != "$GIT_DIR" ] && IN_WORKTREE=yes || IN_WORKTREE=no
fi

IN_WORKTREE=yes の場合: すでに分離されています。ステップ 5(作業ツリーのブックマーク)に進みます。

IN_WORKTREE=no の場合(メインの作業ツリー)で、操作によってファイルが変更される場合:

  1. 対象の仕様/作業に一致する既存の作業ツリーを確認します。

    REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
    bash "$REPO_ROOT/.agents/bin/swain-worktree-overlap.sh" "<SPEC-ID>"
    

    JSON 出力に "found": true が含まれている場合は、再利用を提案します。「<SPEC-ID> 用の作業ツリーがすでに <path> にあります。再利用しますか?」はいの場合は、swain --resume <name> を使ってセッションを再開するようオペレーターに伝えます。いいえの場合は、目的を説明するテキストを指定して新しいセッションを開始するようオペレーターに伝えます。

  2. 作業ツリーの作成は bin/swain の起動前処理で行われます(SPEC-245、EPIC-056)。ほとんどのランタイム(Gemini CLI、Codex、Copilot、Crush)はセッションの途中で作業ディレクトリを変更できません。EnterWorktree を使って変更できるのは Claude Code だけであり、これはランタイム固有の応急処置であって、普遍的なパターンではありません。あらゆる環境に適用できる正しい方法は、bin/swain による起動前の分離です。

    SWAIN_WORKTREE_PATH が設定されている場合、エージェントはすでに管理対象の作業ツリー内にいます。Git の低レベルコマンドで IN_WORKTREE=yes と判定された場合、エージェントは作業ツリー内にいます(手動で入った可能性もあります)。どちらの場合も、作業を続けます。

    IN_WORKTREE=no で、操作に分離が必要な場合は、オペレーターに次のように伝えます。「作業ツリー内にいません。作業ツリーによる分離を行うには、swain "<purpose>" で新しいセッションを開始してください。」

  3. bin/swain によって作業ツリーが作成された場合は、その後、新しいブランチを反映するようタブ名を付け直します。

    bash "$REPO_ROOT/.agents/bin/swain-tab-name.sh" --path "$(pwd)" --auto
    
  4. 作業ツリーのブックマークを記録します(SPEC-235)。作業ツリーに入った後、swain-bookmark.sh を呼び出して session.json に登録します。

    WT_PATH="$(pwd)"
    WT_BRANCH="$(git branch --show-current 2>/dev/null || echo 'unknown')"
    bash "$REPO_ROOT/.agents/bin/swain-bookmark.sh" worktree add "$WT_PATH" "$WT_BRANCH"
    

オペレーターによる上書き: オペレーターが「trunk で作業する」または「分離しない」と明示した場合は、その指示を尊重して trunk 上で作業します。警告を記録します。「オペレーターの要請により trunk 上で続行します。変更は開発ブランチに直接反映されます。」

注記(SPEC-195): swain-init は起動時に作業ツリーを作成しません。作業ツリーの作成は、swain-do が実際の作業を振り分ける際に実行される、この前文まで延期されます。これにより、作業ツリー名に作業のコンテキストを反映でき、重複の検出も可能になります。

計画内のすべてのタスクが完了した場合、またはオペレーターから要請があった場合は、作業ツリーを退出する前に計画完了時の引き継ぎ(下記参照)を実行します。

計画の完了と引き継ぎ

計画エピック内のすべてのタスクがクローズされた場合(またはオペレーターが作業完了を宣言した場合)は、作業ツリーを退出する前にこの一連の処理を実行します。これにより、振り返り、SPEC の遷移、EPIC の連鎖処理が一貫して実行されます。

Step 1 — 計画の完了を検出する
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
export PATH="$REPO_ROOT/.agents/bin:$PATH"
# Check if any tasks under the plan epic are still open
OPEN_COUNT=$(ticket-query ".parent == \"<epic-id>\" and .status != \"closed\"" 2>/dev/null | wc -l | tr -d ' ')

OPEN_COUNT > 0 の場合、計画は未完了です。作業を続けるか、オペレーターに確認します。OPEN_COUNT == 0 の場合は、次に進みます。

Step 2 — 完了処理のパイプラインを実行する(SPEC-257)

計画の完了を検出した後、SPEC を遷移させる前に品質ゲートのパイプラインを実行します。これにより、BDD テスト、スモークテスト、振り返りがすべて自動的に実行されます。

2a — 完了状態ファイルを作成する

計画エピックの --external-ref から SPEC ID を特定します。

REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
SPEC_ID=$(tk show <epic-id> 2>/dev/null | grep -i 'external_ref' | awk '{print $NF}')
if [ -z "$SPEC_ID" ]; then
  echo "WARNING: No SPEC linked to plan epic — skipping completion pipeline."
fi

SPEC_ID が空の場合は、ステップ 2 全体をスキップしてステップ 3 に進みます。警告を記録します。

DESIGN-018 に従って状態ファイルを作成します。

mkdir -p "$REPO_ROOT/.agents"
jq -n --arg spec "$SPEC_ID" --arg branch "$(git branch --show-current)" \
  '{spec_id: $spec, branch: $branch, pipeline_started: (now | todate), steps: {bdd_tests: {status: "pending", timestamp: null, detail: null}, smoke_test: {status: "pending", timestamp: null, detail: null}, retro: {status: "pending", timestamp: null, detail: null}}}' \
  > "$REPO_ROOT/.agents/completion-state.json.tmp" \
  && mv "$REPO_ROOT/.agents/completion-state.json.tmp" "$REPO_ROOT/.agents/completion-state.json"
2b — BDD テストを実行する

swain-test.sh が利用可能か確認します:

REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
SWAIN_TEST="$REPO_ROOT/.agents/bin/swain-test.sh"

swain-test.sh が存在する場合: 1 回実行し、出力と終了コードを取得します:

BDD_OUTPUT=$(bash "$SWAIN_TEST" --artifacts "$SPEC_ID" 2>&1)
BDD_EXIT=$?
  • 終了コードが 0 の場合 → 状態を passed に更新します:
    BDD_DETAIL=$(echo "$BDD_OUTPUT" | head -5 | tr '\n' ' ')
    jq --arg status "passed" --arg detail "$BDD_DETAIL" \
      '.steps.bdd_tests.status = $status | .steps.bdd_tests.timestamp = (now | todate) | .steps.bdd_tests.detail = $detail' \
      "$REPO_ROOT/.agents/completion-state.json" > "$REPO_ROOT/.agents/completion-state.json.tmp" \
      && mv "$REPO_ROOT/.agents/completion-state.json.tmp" "$REPO_ROOT/.agents/completion-state.json"
    
  • 終了コードが 0 以外の場合 → 状態を failed に更新します:
    BDD_DETAIL=$(echo "$BDD_OUTPUT" | tail -10 | tr '\n' ' ')
    jq --arg status "failed" --arg detail "$BDD_DETAIL" \
      '.steps.bdd_tests.status = $status | .steps.bdd_tests.timestamp = (now | todate) | .steps.bdd_tests.detail = $detail' \
      "$REPO_ROOT/.agents/completion-state.json" > "$REPO_ROOT/.agents/completion-state.json.tmp" \
      && mv "$REPO_ROOT/.agents/completion-state.json.tmp" "$REPO_ROOT/.agents/completion-state.json"
    
    パイプラインを停止します。失敗をオペレーターに報告します:「BDD テストに失敗しました。詳細:{detail}。再実行するには retry、続行するには skip BDD と入力してください。」

swain-test.sh が存在しない場合: 警告を表示し、スキップとして記録します:

jq --arg status "skipped" --arg detail "swain-test.sh not available" \
  '.steps.bdd_tests.status = $status | .steps.bdd_tests.timestamp = (now | todate) | .steps.bdd_tests.detail = $detail' \
  "$REPO_ROOT/.agents/completion-state.json" > "$REPO_ROOT/.agents/completion-state.json.tmp" \
  && mv "$REPO_ROOT/.agents/completion-state.json.tmp" "$REPO_ROOT/.agents/completion-state.json"

次を表示します:「swain-test は利用できません — BDD ゲートをスキップします。」

2c — スモークテストを実行する

bdd_tests が passed または skipped の場合にのみ続行します。bdd_tests が failed の場合、パイプラインは一時停止中です — スモークテストは実行しないでください。

BDD_STATUS=$(jq -r '.steps.bdd_tests.status' "$REPO_ROOT/.agents/completion-state.json")

BDD_STATUS が passed または skipped の場合:

swain-test.sh が存在する場合: swain-test.sh のスモークテスト出力には、手動検証手順を含む ## SMOKE セクションがあります。これを抽出してオペレーターに提示します:

SMOKE_SECTION=$(bash "$SWAIN_TEST" --artifacts "$SPEC_ID" 2>&1 | sed -n '/^## SMOKE/,/^## /p' | head -20)

スモークテストの手順を提示し、確認を求めます:

スモークテストの手順: {smoke section content}

スモークテストに合格しましたか?(yes / no / skip)

  • yes → smoke_test を passed に更新し、詳細を "operator confirmed" にします
  • no → smoke_test を failed に更新し、詳細にはオペレーターからの内容を設定します。パイプラインを停止します:「スモークテストに失敗しました。再確認するには retry、続行するには skip smoke と入力してください。」
  • skip → smoke_test を skipped に更新し、詳細を "operator chose to skip" にします

状態の書き込みには、2b と同じ jq 更新パターンを使用します。

swain-test.sh が存在しない場合: BDD のフォールバックと同様に、詳細を "swain-test.sh not available" としてスキップに記録します。

2d — 振り返りを実行する

bdd_tests と smoke_test の両方が passed または skipped の場合にのみ続行します。振り返りはスキップできません — オペレーターが "skip retro" と入力した場合は拒否します:「振り返りは常に実行されます。不完全な作業からも学びを得るためです。」

エージェントの Skill ツールを使って swain-retro スキルを呼び出します(これはツールの呼び出しであり、bash コマンドではありません):

Skill ツールを使用して、swain-retro を次の引数で呼び出します:"SPEC completion — run retro for before phase transition."

swain-retro の完了後、状態を更新します:

jq --arg status "passed" --arg detail "retro captured" \
  '.steps.retro.status = $status | .steps.retro.timestamp = (now | todate) | .steps.retro.detail = $detail' \
  "$REPO_ROOT/.agents/completion-state.json" > "$REPO_ROOT/.agents/completion-state.json.tmp" \
  && mv "$REPO_ROOT/.agents/completion-state.json.tmp" "$REPO_ROOT/.agents/completion-state.json"

swain-retro が失敗した場合(スキルの呼び出しエラー)、状態を failed に更新して報告します。オペレーターは retry と入力して再実行できます。

2e — スキップと再開の処理

スキップの処理: パイプラインのどの時点でも、オペレーターは次のように入力できます:

  • "skip BDD" → bdd_tests を skipped に設定し、詳細を "operator requested skip" として、2c に進みます
  • "skip smoke" → smoke_test を skipped に設定し、詳細を "operator requested skip" として、2d に進みます
  • "skip retro" → 拒否します。振り返りは常に実行されます。次のように伝えます:「振り返りは不完全な作業からも学びを得るため、スキップできません。」

再開の処理: ステップが失敗し、オペレーターが "retry" または "continue" と入力した場合:

  1. .agents/completion-state.json を読み込みます
  2. ステータスが pending または failed の最初のステップを見つけます
  3. すでに passed または skipped になっているステップは再実行せず、そのステップからパイプラインを再開します

パイプラインゲート: 3 つのステップがすべて完了したら、完了を確認します:

PENDING=$(jq -r '.steps | to_entries[] | select(.value.status == "pending" or .value.status == "failed") | .key' "$REPO_ROOT/.agents/completion-state.json")

PENDING が空(すべてのステップが passed または skipped)の場合、ステップ 3(SPEC の遷移)に進みます。そうでない場合、パイプラインはブロックされています — 残っているステップを報告します。

ステップ 3 — SPEC の移行のために swain-design を呼び出す

パイプラインゲート(SPEC-257): 完了パイプラインが成功した場合にのみ、SPEC の移行に進みます。次のコマンドで確認します:jq -r '.steps | to_entries[] | select(.value.status == "pending" or .value.status == "failed") | .key' "$REPO_ROOT/.agents/completion-state.json"。pending または failed のステップがある場合は、移行せず、ステップ 2 に戻って解決してください。

--external-ref を使って、計画エピックにリンクされた SPEC を特定します:

tk show <epic-id> 2>/dev/null  # external_ref field contains the SPEC ID

SPEC を次のフェーズに移行するために、swain-design を呼び出します。目標フェーズは、SPEC の現在の状態と検証が完了しているかどうかによって異なります。

  • すべての受け入れ基準にエビデンスがある場合 → Complete に移行
  • 受け入れ基準に手動検証が必要な場合 → Needs Manual Test に移行
  • 実装は完了しているがテストされていない場合 → In Progress に移行(すでに移行済みでない場合)

swain-design は、後続の一連の処理を自動的に行います。

  • 親 EPIC も移行すべきか確認します(すべての子 SPEC が完了 → EPIC を Complete に移行)
  • EPIC が終端状態に達した場合 → EPIC レベルの振り返りのために swain-retro を呼び出します(SPEC レベルの振り返りはステップ 2d ですでに実施済みです)
ステップ 4 — マージとクリーンアップを提案する

SPEC の移行が完了した後、マージとクリーンアップを提案します。

すべてのタスクがクローズされました。SPEC-NNN は {phase} に移行しました。このブランチを {base-branch} にマージして、ワークツリーをクリーンアップしますか?

オペレーターが承諾した場合:

  1. すべての変更がコミットされていることを確認します
  2. /swain-sync を実行してマージとプッシュを行います(ロックファイルを ready_for_cleanup に設定します)
  3. ランタイム終了後、bin/swain がワークツリーをクリーンアップします(SPEC-245)

オペレーターが辞退した場合、ブランチは保持されます。次回の起動時に、bin/swain のメニューに表示されます。

注(ADR-015): ワークツリー内の .tickets/ ファイルは一時的な足場であり、クリーンアップの妨げにすべきではありません。SPEC の完了後、チケットにはアーカイブする価値がありません。

一連の処理をスキップする

オペレーターは「just exit」または「skip the handoff」と伝えて、ステップ 2〜4 を省略し、ExitWorktree に直接進めます。計画エピックにメモを記録します:tk add-note <epic-id> "Exited without completion handoff"。ワークツリーは次のセッションのために保持されます。

注: 一連の処理をスキップすると、完了パイプラインは実行されません。.agents/completion-state.json がすでに作成されている場合(ステップ 2a が実行済みの場合)、pending のステップは未完了のまま残ります。swain-teardown はこれを検出し、同期前に未実施のステップを実行します。

ブックマーク管理(ADR-023)

ブックマークは、オペレーターが作業中の内容を記録します。セッション間で保持されるため、次のセッションで前回の続きから作業を再開できます。

ブックマークを設定する

オペレーターが「bookmark this」、「remember where I am」と言った場合、または状態を変更する操作の後:

REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-bookmark.sh" "<context note>"

会話の文脈またはオペレーターが明示したテキストからメモを推定します。文脈が明確な場合、メモを尋ねないでください。

ワークツリーのブックマーク

ワークツリーに入るとき(ワークツリー分離の前置き、ステップ 5 ですでに処理済み)、ワークツリーが登録されます:

bash "$REPO_ROOT/.agents/bin/swain-bookmark.sh" worktree add "$WT_PATH" "$WT_BRANCH"
ブックマークをクリアする

オペレーターが「clear bookmark」または「fresh start」と言った場合:

bash "$REPO_ROOT/.agents/bin/swain-bookmark.sh" --clear

意思決定の記録(ADR-023)

オペレーターまたはエージェントが重要な決定を行ったとき(SPEC の承認、アプローチの選択、方向性の決定)、次のように記録します。

REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-session-state.sh" record-decision --note "Approved SPEC-119 implementation approach"

意思決定は、セッションの意思決定予算に照らして追跡されます。予算に達した場合は、オペレーターに知らせて /swain-teardown の実行を提案します。

進捗ログ(ADR-023)

タスクの完了後、またはマイルストーンに到達した後、進捗ログを更新します。

REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-progress-log.sh" --digest "$REPO_ROOT/.agents/session-log.jsonl"

これにより、変更した各 EPIC/Initiative の progress.md と ## Progress セクションが更新されます。

フォールバック

tk が見つからない、または利用できない場合:

  1. 失敗の理由を記録します。
  2. 作業ディレクトリ内の中立的なテキスト形式のタスク台帳(JSONL または Markdown のチェックリスト)に切り替えます。
  3. 同じステータスモデル(open、in_progress、blocked、closed)を使用し、更新内容を外部から確認できる状態に保ちます。

コメント