ship
Shipワークフロー:ベースブランチを検出・マージし、テストを実行して、差分をレビューし、VERSIONをバンプし、CHANGELOGを更新してから、コミット、プッシュ、PRを作成します。「ship」「deploy」「push to main」「create a PR」「merge and push」といった指示を受けたときに使用します。ユーザーがコードの準備ができたと言及したり、デプロイについて質問したりした場合は、積極的にこのワークフローを提案します。
description の原文を見る
Ship workflow: detect + merge base branch, run tests, review diff, bump VERSION, update CHANGELOG, commit, push, create PR. Use when asked to "ship", "deploy", "push to main", "create a PR", or "merge and push". Proactively suggest when the user says code is ready or asks about deploying.
SKILL.md 本文
序文 (最初に実行)
_UPD=$(~/.codex/skills/gstack/bin/gstack-update-check 2>/dev/null || .agents/skills/gstack/bin/gstack-update-check 2>/dev/null || true)
[ -n "$_UPD" ] && echo "$_UPD" || true
mkdir -p ./.gstack/sessions
touch ./.gstack/sessions/"$PPID"
_SESSIONS=$(find ./.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
find ./.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true
_CONTRIB=$(~/.codex/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true)
_PROACTIVE=$(~/.codex/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
echo "BRANCH: $_BRANCH"
echo "PROACTIVE: $_PROACTIVE"
source <(~/.codex/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
REPO_MODE=${REPO_MODE:-unknown}
echo "REPO_MODE: $REPO_MODE"
_LAKE_SEEN=$([ -f ./.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
echo "LAKE_INTRO: $_LAKE_SEEN"
_TEL=$(~/.codex/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
_TEL_PROMPTED=$([ -f ./.gstack/.telemetry-prompted ] && echo "yes" || echo "no")
_TEL_START=$(date +%s)
_SESSION_ID="$$-$(date +%s)"
echo "TELEMETRY: ${_TEL:-off}"
echo "TEL_PROMPTED: $_TEL_PROMPTED"
mkdir -p ./.gstack/analytics
echo '{"skill":"ship","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ./.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
for _PF in ./.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.codex/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done
PROACTIVEが"false"の場合は、gstackスキルを積極的に提案しないでください。明示的に求められた場合のみ呼び出します。ユーザーが積極的提案をオプトアウトしています。
出力にUPGRADE_AVAILABLE <old> <new>が表示される場合: ~/.codex/skills/gstack/gstack-upgrade/SKILL.mdを読み、「インライン更新フロー」に従ってください(設定されている場合は自動更新、そうでなければ4つのオプションを持つAskUserQuestion を実行、拒否された場合は延期状態を書き込み)。JUST_UPGRADED <from> <to>の場合: ユーザーに「gstack v{to}を実行中(更新完了!)」と伝え、続行してください。
LAKE_INTROがnoの場合: 続行する前に、Completeness Principleを紹介してください。
ユーザーに次のように伝えます: 「gstackはBoil the Lake原則に従います。AIが限界費用をほぼゼロにするとき、常に完全な作業を行います。詳細はこちら: https://garryslist.org/posts/boil-the-ocean」
その後、デフォルトブラウザでエッセイを開くことを提案します:
open https://garryslist.org/posts/boil-the-ocean
touch ./.gstack/.completeness-intro-seen
ユーザーがyesと言った場合のみopenを実行します。常にtouchを実行して確認済みとマークします。これは1回だけ発生します。
TEL_PROMPTEDがnoかつLAKE_INTROがyesの場合: lake introの処理後、テレメトリについてユーザーに尋ねます。AskUserQuestion を使用します:
gstackを改善するのに協力してください!コミュニティモードは、使用データ(どのスキルを使用したか、どのくらい時間がかかったか、クラッシュ情報)を安定したデバイスIDと共有し、トレンドを追跡してバグをより速く修正できるようにします。 コード、ファイルパス、またはリポジトリ名が送信されることはありません。
gstack-config set telemetry offで随時変更できます。
オプション:
- A) gstackを改善するのに協力してください!(推奨)
- B) いいえ、結構です
Aを選択した場合: ~/.codex/skills/gstack/bin/gstack-config set telemetry communityを実行します
Bを選択した場合: フォローアップのAskUserQuestion を実行します:
匿名モードはどうですか?誰かがgstackを使用した事実のみを学びます。ユニークなID、セッションを接続する方法はありません。ただ誰かがそこにいるかどうかを知るのに役立つカウンターです。
オプション:
- A) はい、匿名で問題ありません
- B) いいえ、完全にオフで
B→Aの場合: ~/.codex/skills/gstack/bin/gstack-config set telemetry anonymousを実行
B→Bの場合: ~/.codex/skills/gstack/bin/gstack-config set telemetry offを実行
常に実行:
touch ./.gstack/.telemetry-prompted
これは1回だけ発生します。TEL_PROMPTEDがyesの場合、この部分全体をスキップしてください。
AskUserQuestion 形式
すべてのAskUserQuestion 呼び出しでこの構造に従ってください:
- 再確認: プロジェクト、現在のブランチ(序文で出力された
_BRANCH値を使用します。会話履歴やgitStatusのブランチではなく)、および現在の計画/タスクを述べます。(1~2文) - 単純化: 賢い16歳が理解できるプレーンな英語で問題を説明します。生の関数名、内部用語、実装の詳細は使用しません。具体例とアナロジーを使用します。呼び出される名前ではなく、何をするかを言います。
- 推奨:
RECOMMENDATION: Choose [X] because [one-line reason]。常に完全なオプションをショートカットより優先します(Completeness Principleを参照)。各オプションについてCompleteness: X/10を含めます。キャリブレーション: 10 = 完全な実装(すべてのエッジケース、完全なカバレッジ)、7 = ハッピーパスをカバーしますがいくつかのエッジをスキップ、3 = 重要な作業を先延ばしにするショートカット。両方のオプションが8以上の場合は、より高い方を選択します。1つが5以下の場合はフラグを立てます。 - オプション: 文字付きオプション:
A) ... B) ... C) ...— オプションに労力が必要な場合は、両方のスケールを表示します:(human: ~X / CC: ~Y)
ユーザーがこのウィンドウを20分見ていないと仮定し、コードを開いていません。自分の説明を理解するためにソースを読む必要がある場合は、複雑すぎます。
スキル固有の指示がこのベースラインの上に追加の形式規則を追加する場合があります。
Completeness Principle — Boil the Lake
AI支援コーディングにより、完全性の限界費用がほぼゼロになります。オプションを提示するとき:
- オプションAが完全な実装(完全なパリティ、すべてのエッジケース、100%カバレッジ)でオプションBがわずかな労力を節約するショートカットの場合、常にAを推奨します。CC+gstackで80行と150行の差は意味がありません。「十分に良い」はその他の完全な「完全な」が数分の費用がかかる場合の間違った本能です。
- Lake対ocean: 「lake」は加熱可能です。モジュールの100%テストカバレッジ、完全な機能実装、すべてのエッジケースの処理、完全なエラーパス。「ocean」はできません。システム全体の書き直し、制御できない依存関係への機能追加、複数四半期のプラットフォーム移行。lakeを沸騰させることを推奨します。oceanはスコープ外としてフラグを立てます。
- 労力を見積もるとき、常に両方のスケールを表示します: 人間チーム時間とCC+gstack時間。圧縮比率はタスクタイプによって異なります。このリファレンスを使用します:
| タスクタイプ | 人間チーム | CC+gstack | 圧縮 |
|---|---|---|---|
| ボイラープレート/足場 | 2日 | 15分 | ~100x |
| テスト作成 | 1日 | 15分 | ~50x |
| 機能実装 | 1週間 | 30分 | ~30x |
| バグ修正 + リグレッションテスト | 4時間 | 15分 | ~20x |
| アーキテクチャ/デザイン | 2日 | 4時間 | ~5x |
| 研究/探査 | 1日 | 3時間 | ~3x |
- この原則はテストカバレッジ、エラーハンドリング、ドキュメント、エッジケース、機能完全性に適用されます。時間を「節約」するために最後の10%をスキップしないでください。AIではその10%は秒の費用です。
アンチパターン — これはしないでください:
- 悪い: 「Bを選択します。70%の価値がより少ないコードでカバーされます」(Aが70行だけ多い場合はAを選択します)
- 悪い: 「エッジケースハンドリングをスキップして時間を節約します」(エッジケースハンドリングはCCで分単位の費用です)
- 悪い: 「テストカバレッジを後続のPRに延期しましょう」(テストは沸騰させるのが最も安いlakeです)
- 悪い: 人間チームの労力のみを引用: 「これには2週間かかります」(「2週間人間/~1時間CC」と言います)
リポジトリ所有権モード — 何かを見たら、何かを言う
序文のプリアンブルのREPO_MODEは、このリポのissueの所有者を伝えます:
solo— 1人が80%以上の作業を行っています。彼らはすべてを所有しています。現在のブランチの変更外のissueに気付いたとき(テスト失敗、非推奨警告、セキュリティ勧告、lint エラー、デッドコード、env問題)、調査して積極的に修正を提案します。ソロ開発者は唯一それを修正する人です。デフォルトはアクション。collaborative— 複数のアクティブな寄稿者。ブランチの変更外のissueに気付いたとき、AskUserQuestion でそれらをフラグします — 誰か他の人の責任かもしれません。デフォルトは修正ではなく質問。unknown— 協調としてそれを扱う(より安全なデフォルト — 修正する前に尋ねます)
何かを見たら、何かを言う: ANY ワークフローステップ中に何か間違って見えるものに気付いたとき(テスト失敗だけでなく)、簡潔にそれをフラグします。1文: あなたが気付いたこと。soloモード では、「これを修正したいですか?」と続きます。協調モードでは、それをフラグして先に進むだけです。
気付いたissueを黙って通す必要はありません。全体的なポイントはプロアクティブなコミュニケーションです。
構築前に検索
インフラストラクチャ、不慣れなパターン、またはランタイムがビルトインを持つかもしれないもの構築する前に、最初に検索します。 ~/.codex/skills/gstack/ETHOS.mdで完全な哲学を読みます。
知識の3つのレイヤー:
- レイヤー1 (試行済みで真実 — 配布に含まれています)。車輪を再発明しないでください。しかし、チェックの費用はほぼゼロであり、時々試行済みの質問は素晴らしさが発生する場所です。
- レイヤー2 (新規および人気のある — これらを検索します)。しかし精査します: 人間は熱狂の対象です。検索結果はあなたの考えへの入力であり、答えではありません。
- レイヤー3 (第一原則 — これらすべての上に賞賛)。特定の問題についての推論から導かれた元の観察。すべてのうち最も貴重。
ユーリカの瞬間: 第一原則の推論が従来の知恵が間違っていることを明らかにするとき、それに名前を付けます: 「EUREKA: みんなXをします。なぜなら[仮定]。しかし[証拠]はこれが間違っていることを示しています。Yはより良いです。なぜなら[推論]」
ユーリカの瞬間をログします:
jq -n --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg branch "$(git branch --show-current 2>/dev/null)" --arg insight "ONE_LINE_SUMMARY" '{ts:$ts,skill:$skill,branch:$branch,insight:$insight}' >> ./.gstack/analytics/eureka.jsonl 2>/dev/null || true
SKILL_NAME と ONE_LINE_SUMMARY を置き換えます。インラインで実行します。ワークフローを停止しないでください。
WebSearch フォールバック: WebSearchが利用できない場合は、検索ステップをスキップし、次のように記します: 「検索は利用できません。配布内の知識のみで進めています」
寄稿者モード
_CONTRIBがtrueの場合: あなたは寄稿者モードにいます。あなたはgstackユーザーでもあり、より良くするのに役立ちます。
各主要ワークフロー ステップの終了時 (毎単一のコマンド後ではなく)、使用したgstackツーリングについて考察します。経験を0~10で評価します。10ではなかった場合は、なぜかを考えます。明らかで実行可能なバグ、または興味深い、gstackコードまたはスキル markdown でより良く行われたかもしれないことがあれば、フィールドレポートをファイルします。多分私たちの寄稿者が私たちをより良くするのに役立つでしょう!
キャリブレーション — これはバーです: 例えば、$B js "await fetch(...)"はSyntaxError: await is only valid in async functionsで失敗するのは、gstackがexpressionを非同期コンテキストでラップしなかったためです。小さいですが、入力は合理的でgstackはそれを処理すべきでした。これはファイルする価値のあるもの。これより重要でない事柄は無視してください。
ファイルする価値がない: ユーザーのアプリバグ、ユーザーのURLへのネットワークエラー、ユーザーのサイトでの認証失敗、ユーザー自身のJSロジックバグ。
ファイルするには: ./.gstack/contributor-logs/{slug}.mdを書きます。以下のすべてのセクション (切り詰めないでください。Date/Version フッターを含むすべてのセクションを含めます):
# {Title}
こんにちは gstackチーム — /{skill-name}を使用中にこれを実行しました:
**何をしようとしていたか:** {ユーザー/エージェントが試みていたこと}
**代わりに何が起こったか:** {実際に起こったこと}
**私の評価:** {0-10} — {10ではなかった理由についての1文}
## 再現する手順
1. {ステップ}
## 生の出力
{ここに実際のエラーまたは予期しない出力を貼り付けます}
## これを10にする方法
{1文: gstackが異なるべきだったこと}
**日付:** {YYYY-MM-DD} | **バージョン:** {gstackバージョン} | **スキル:** /{skill}
Slug: 小文字、ハイフン、最大60文字(例:browse-js-no-await)。ファイルが既に存在する場合はスキップします。1セッションあたり最大3レポート。インラインでファイルして続行します。ワークフローを停止しないでください。ユーザーに伝える: 「gstack field report をファイルしました: {title}」
完了状態プロトコル
スキルワークフローを完了するとき、次のいずれかを使用してステータスをレポートします:
- DONE — すべてのステップが正常に完了しました。各請求について証拠が提供されています。
- DONE_WITH_CONCERNS — 完了しましたが、ユーザーが知っておくべき問題があります。各懸念事項をリストアップします。
- BLOCKED — 続行できません。ブロックしているものと試されたことを述べます。
- NEEDS_CONTEXT — 続行するために必要な情報が足りません。正確に何が必要かを述べます。
エスカレーション
「これは私には難しすぎます」と言うか「この結果は確信が持てません」と言って停止することは常に問題ありません。
悪い作業は作業なしより悪いです。エスカレーションのためにペナルティを受けません。
- タスクを3回試みても成功しなかった場合、停止してエスカレーションします。
- セキュリティに敏感な変更について不確実な場合、停止してエスカレーションします。
- 作業のスコープが検証できるものを超える場合、停止してエスカレーションします。
エスカレーション形式:
STATUS: BLOCKED | NEEDS_CONTEXT
REASON: [1-2 sentences]
ATTEMPTED: [you tried what]
RECOMMENDATION: [what the user should do next]
テレメトリ (最後に実行)
スキルワークフローが完了したら(成功、エラー、または中止)、テレメトリイベントをログします。
このファイルのYAML frontmatterのname:フィールドからスキル名を決定します。
ワークフロー結果からアウトカムを決定します(通常に完了した場合は成功、失敗した場合はエラー、ユーザーが中断した場合は中止)。
PLAN MODE EXCEPTION — 常に実行: このコマンドは./.gstack/analytics/(ユーザー設定ディレクトリ、プロジェクトファイルではなく)にテレメトリを書き込みます。スキルプリアンブルは既に同じディレクトリに書き込みます。このパターンと同じです。
このコマンドをスキップするとセッション期間とアウトカムデータが失われます。
このbashを実行します:
_TEL_END=$(date +%s)
_TEL_DUR=$(( _TEL_END - _TEL_START ))
rm -f ./.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true
~/.codex/skills/gstack/bin/gstack-telemetry-log \
--skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \
--used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null &
SKILL_NAME をフロントマターの実際のスキル名に、OUTCOME を success/error/abort に、USED_BROWSE を$Bが使用されたかどうかに基づいてtrue/falseに置き換えます。
アウトカムを判定できない場合は「unknown」を使用してください。これはバックグラウンドで実行され、ユーザーをブロックすることはありません。
ステップ 0: ベースブランチを検出
このPRがターゲットするブランチを決定します。その結果を後続のすべてのステップで「ベースブランチ」として使用します。
-
このブランチのPRが既に存在するかどうかを確認します:
gh pr view --json baseRefName -q .baseRefName成功した場合、出力されたブランチ名をベースブランチとして使用します。 -
PRが存在しない場合(コマンドが失敗する)、リポのデフォルトブランチを検出します:
gh repo view --json defaultBranchRef -q .defaultBranchRef.name -
両方のコマンドが失敗した場合は、
mainにフォールバックします。
検出されたベースブランチ名を出力します。後続のすべてのgit diff、git log、
git fetch、git merge、およびgh pr createコマンドで、指示が「ベースブランチ」と言うところに検出されたブランチ名を置き換えます。
Ship: 完全に自動化されたShip ワークフロー
/shipワークフローを実行しています。これは**非対話的で完全に自動化されたワークフローです。ステップで確認を求めないでください。ユーザーが/shipを言ったということは、それを実行します。まっすぐに実行して、最終的にPR URLを出力します。
停止するのは:
- ベースブランチ上(中止)
- 自動解決できないマージ競合(停止、競合を表示)
- ブランチ内テスト失敗(既存の失敗は分類されプレブロッキングではありません)
- プリランディングレビューでユーザー判断が必要なASK項目を検出
- MINOR またはMAJOR バージョンバンプが必要(質問 — ステップ4を参照)
- ユーザーの判定が必要なGreptile レビューコメント(複雑な修正、偽陽性)
- TODOS.md が見つからず、ユーザーが作成を望む(質問 — ステップ5.5を参照)
- TODOS.md が整理されていない、ユーザーが再編成を望む(質問 — ステップ5.5を参照)
決して停止しないでください:
- コミットされていない変更(常にそれらを含めます)
- バージョンバンプの選択(自動的にMICRO またはPATCH を選択します — ステップ4を参照)
- CHANGELOG コンテンツ(差分から自動生成)
- コミットメッセージの承認(自動コミット)
- 複数ファイル変更セット(自動的にbisectable なコミットに分割)
- TODOS.md 完了項目検出(自動的にマーク)
- 自動修正可能なレビュー結果(デッドコード、N+1、古いコメント — 自動修正)
- テストカバレッジギャップ(自動生成とコミット、または PR本文でフラグ)
ステップ 1: 飛行前チェック
-
現在のブランチを確認します。ベースブランチまたはリポのデフォルトブランチ上の場合、中止します: 「ベースブランチ上です。フィーチャーブランチからshipしてください」
-
git statusを実行します(決して-uallを使用しないでください)。コミットされていない変更は常に含まれます。尋ねる必要はありません。 -
git diff <base>...HEAD --statとgit log <base>..HEAD --onelineを実行して、何がshipされているかを理解します。 -
レビュー準備状況を確認します:
レビュー準備ダッシュボード
レビューの完了後、レビューログと設定を読んでダッシュボードを表示します。
~/.codex/skills/gstack/bin/gstack-review-read
出力を解析します。各スキル (plan-ceo-review, plan-eng-review, plan-design-review, design-review-lite, adversarial-review, codex-review) の最新エントリを検出します。7日以上古いタイムスタンプを持つエントリを無視します。Adversarial行について、adversarial-review(新しい自動スケール)とcodex-review(レガシー)のうち、より新しい方を表示します。Design Review について、plan-design-review(完全な視覚監査)とdesign-review-lite(コードレベルチェック)のうち、より新しい方を表示します。ステータスに「(FULL)」または「(LITE)」を追加して区別します。表示:
+====================================================================+
| REVIEW READINESS DASHBOARD |
+====================================================================+
| Review | Runs | Last Run | Status | Required |
|-----------------|------|---------------------|-----------|----------|
| Eng Review | 1 | 2026-03-16 15:00 | CLEAR | YES |
| CEO Review | 0 | — | — | no |
| Design Review | 0 | — | — | no |
| Adversarial | 0 | — | — | no |
+--------------------------------------------------------------------+
| VERDICT: CLEARED — Eng Review passed |
+====================================================================+
レビュー層:
- Eng Review(デフォルトで必須): Shipをゲートする唯一のレビュー。アーキテクチャ、コード品質、テスト、パフォーマンスをカバーします。
gstack-config set skip_eng_review trueで世界的に無効にできます(「気にしないで」設定)。 - CEO Review(オプション): 判断を使用してください。大規模な製品/ビジネス変更、新しいユーザー向け機能、またはスコープ決定について推奨します。バグ修正、リファクタリング、インフラ、クリーンアップをスキップします。
- Design Review(オプション): 判断を使用してください。UI/UX 変更について推奨します。バックエンドのみ、インフラ、またはプロンプトのみの変更をスキップします。
- Adversarial Review(自動): 差分サイズで自動スケールします。小さい差分(<50行)は敵対的をスキップします。中程度の差分(50~199)はクロスモデル敵対的を取得します。大きい差分(200+)はすべての4パスを取得: Claude構造化、Codex構造化、Claude敵対的サブエージェント、Codex敵対的。設定は必要ありません。
判定ロジック:
- CLEARED: Eng Review は7日以内に1以上のエントリを持ち、ステータスが「clean」(または
skip_eng_reviewがtrue) - NOT CLEARED: Eng Review が見つからない、古い(>7日)、またはオープンissueを持つ
- CEO、Design、Codex レビューはコンテキストのために表示されますが、shipをブロックすることはありません
skip_eng_review設定がtrueの場合、Eng Review は「SKIPPED (global)」を表示し、判定はCLEAREDです
Staleness 検出: ダッシュボード表示後、既存のレビューがStaleである可能性がないか確認します:
- bash出力の
---HEAD---セクションを解析して現在のHEAD コミットハッシュを取得 commitフィールドを持つ各レビューエントリについて: 現在のHEADに対して比較します。異なる場合、経過コミット数をカウントします:git rev-list --count STORED_COMMIT..HEAD。表示: 「注: {skill} レビュー from {date} はstaleである可能性があります。レビュー以降{N}コミット」commitフィールド(レガシーエントリ)がないエントリについて: 「注: {skill} レビュー from {date} はコミット追跡がありません。正確なstalenesss検出のために再実行を検討してください」を表示- すべてのレビューが現在のHEADと一致する場合、stalenesssに関する注記を表示しません
Eng Review が「CLEAR」でない場合:
-
このブランチで以前のオーバーライドをチェック:
source <(~/.codex/skills/gstack/bin/gstack-slug 2>/dev/null) grep '"skill":"ship-review-override"' ./.gstack/projects/$SLUG/$BRANCH-reviews.jsonl 2>/dev/null || echo "NO_OVERRIDE"オーバーライドが存在する場合、ダッシュボードを表示し、「レビューゲートが以前に受け入れられました。続行しています」と記します。もう一度尋ねないでください。
-
オーバーライドが存在しない場合、 AskUserQuestion を使用します:
- Eng Review が見つからないか、オープンissueを持つことを表示
- RECOMMENDATION: 変更が明らかに些細な場合(<20行、タイプ修正、設定のみ)C を選択。より大きい変更の場合はB を選択
- オプション: A) とにかくship B) 中止 — 最初に/plan-eng-review を実行 C) 変更は eng review のにはあまりにも小さい
- CEO Review が見つからない場合は、情報として言及する(「CEO Review は実行されていません — 製品変更に推奨」)が、ブロックしません
- Design Review について:
source <(~/.codex/skills/gstack/bin/gstack-diff-scope <base> 2>/dev/null)を実行します。SCOPE_FRONTEND=trueでダッシュボードに design review (plan-design-review またはdesign-review-lite) が存在しない場合、言及します: 「Design Review は実行されていません。このPRはフロントエンドコードを変更します。ライト design チェックはステップ3.5で自動的に実行されますが、実装後に完全な視覚監査のために/design-review を実行することを検討してください」。ブロックしません。
-
ユーザーがAまたはCを選択する場合、 将来的にこのブランチの
/ship実行がゲートをスキップできるよう、決定を保存します:source <(~/.codex/skills/gstack/bin/gstack-slug 2>/dev/null) echo '{"skill":"ship-review-override","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","decision":"USER_CHOICE"}' >> ./.gstack/projects/$SLUG/$BRANCH-reviews.jsonlUSER_CHOICE を「ship_anyway」または「not_relevant」に置き換えます。
ステップ 2: ベースブランチをマージ(テスト前)
ベースブランチをフェッチしてフィーチャーブランチにマージし、マージされた状態に対してテストが実行されるようにします:
git fetch origin <base> && git merge origin/<base> --no-edit
マージ競合がある場合: 単純な場合(VERSION、schema.rb、CHANGELOG 順序付け)自動解決を試してください。競合が複雑または曖昧な場合、停止して、それらを表示します。
既に最新の場合: 黙かに続行します。
ステップ 2.5: テストフレームワークブートストラップ
テストフレームワークブートストラップ
既存のテストフレームワークとプロジェクトランタイムを検出:
# プロジェクトランタイムを検出
[ -f Gemfile ] && echo "RUNTIME:ruby"
[ -f package.json ] && echo "RUNTIME:node"
[ -f requirements.txt ] || [ -f pyproject.toml ] && echo "RUNTIME:python"
[ -f go.mod ] && echo "RUNTIME:go"
[ -f Cargo.toml ] && echo "RUNTIME:rust"
[ -f composer.json ] && echo "RUNTIME:php"
[ -f mix.exs ] && echo "RUNTIME:elixir"
# サブフレームワークを検出
[ -f Gemfile ] && grep -q "rails" Gemfile 2>/dev/null && echo "FRAMEWORK:rails"
[ -f package.json ] && grep -q '"next"' package.json 2>/dev/null && echo "FRAMEWORK:nextjs"
# 既存のテストインフラストラクチャをチェック
ls jest.config.* vitest.config.* playwright.config.* .rspec pytest.ini pyproject.toml phpunit.xml 2>/dev/null
ls -d test/ tests/ spec/ __tests__/ cypress/ e2e/ 2>/dev/null
# オプトアウトマーカーをチェック
[ -f .gstack/no-test-bootstrap ] && echo "BOOTSTRAP_DECLINED"
テストフレームワークが検出された場合 (設定ファイルまたはテストディレクトリが見つかる): 「テストフレームワークが検出されました: {name} ({N}既存テスト)。ブートストラップをスキップします」と出力します。 既存のテストファイル2~3個を読んで、規約を学びます(命名、インポート、アサーション スタイル、セットアップパターン)。 規約をプロースコンテキストとして保存し、フェーズ8e.5またはステップ3.4で使用するために保存します。ブートストラップの残りをスキップします。
BOOTSTRAP_DECLINED が表示される場合: 「テストブートストラップが以前に拒否されました。スキップしています」と出力します。ブートストラップの残りをスキップします。
ランタイムが検出されない場合 (設定ファイルが見つからない): AskUserQuestion を使用します:
「プロジェクトの言語を検出できませんでした。使用しているランタイムは何ですか?」
オプション: A) Node.js/TypeScript B) Ruby/Rails C) Python D) Go E) Rust F) PHP G) Elixir H) このプロジェクトはテストを必要としません。
ユーザーがHを選択した場合 → .gstack/no-test-bootstrapを書き込み、テストなしで続行します。
ランタイムが検出されたがテストフレームワークがない場合 — ブートストラップ:
B2. ベストプラクティスを研究
WebSearch を使用して、検出されたランタイムの現在のベストプラクティスを見つけます:
"[runtime] best test framework 2025 2026""[framework A] vs [framework B] comparison"
WebSearch が利用できない場合は、この組み込みナレッジテーブルを使用します:
| ランタイム | 主要推奨 | 代替 |
|---|---|---|
| Ruby/Rails | minitest + fixtures + capybara | rspec + factory_bot + shoulda-matchers |
| Node.js | vitest + @testing-library | jest + @testing-library |
| Next.js | vitest + @testing-library/react + playwright | jest + cypress |
| Python | pytest + pytest-cov | unittest |
| Go | stdlib testing + testify | stdlibのみ |
| Rust | cargo test (ビルトイン) + mockall | — |
| PHP | phpunit + mockery | pest |
| Elixir | ExUnit (ビルトイン) + ex_machina | — |
B3. フレームワーク選択
AskUserQuestion を使用します: 「このプロジェクトが[Runtime/Framework]でテストフレームワークがないことを検出しました。現在のベストプラクティスを研究しました。オプションは次のとおりです: A) [主要] — [根拠]。含む: [パッケージ]。サポート: unit、integration、smoke、e2e B) [代替] — [根拠]。含む: [パッケージ] C) スキップ — 今はテストを設定しないでください RECOMMENDATION: Aを選択します。なぜなら[プロジェクトコンテキストに基づいた理由]」
ユーザーがCを選択した場合 → .gstack/no-test-bootstrapを書き込みます。ユーザーに伝える: 「気が変わったら、.gstack/no-test-bootstrapを削除して再実行してください」。テストなしで続行します。
複数のランタイムが検出された場合(モノレポ)→ どのランタイムを最初に設定するかを尋ね、両方を順番に行うオプションを提供します。
B4. インストールと設定
- 選択されたパッケージをインストール(npm/bun/gem/pip/などを使用)
- 最小設定ファイルを作成
- ディレクトリ構造を作成(test/、spec/、など)
- プロジェクトのコードと一致する1つの例テストを作成し、セットアップが機能することを確認
パッケージインストールが失敗した場合 → 1回デバッグします。それでも失敗している場合 → git checkout -- package.json package-lock.json(またはランタイムに相当)で戻します。ユーザーに警告してテストなしで続行します。
B4.5. 最初の実テスト
既存のコードの3~5個の実テストを生成:
- 最近変更されたファイルを検出:
git log --since=30.days --name-only --format="" | sort | uniq -c | sort -rn | head -10 - リスクで優先順位付け: エラーハンドラー > 条件付きビジネスロジック > APIエンドポイント > 純粋関数
- 各ファイルについて: 実の動作をテストする1つのテストを、意味のあるアサーションで書きます。
expect(x).toBeDefined()- テストコードが何をするかテストします。 - 各テストを実行します。パス → 保持。失敗 → 1回修正。まだ失敗 → 黙かに削除。
- 最小1テスト、最大5テストを生成します。
テストファイルでシークレット、APIキー、または認証情報をインポートしないでください。環境変数またはテストフィクスチャを使用します。
B5. 検証
# テスト全体を実行してすべてが機能することを確認
{detected test command}
テストが失敗する場合 → 1回デバッグします。それでも失敗している場合 → すべてのブートストラップ変更を戻して、ユーザーに警告します。
B5.5. CI/CD パイプライン
# CI プロバイダーをチェック
ls -d .github/ 2>/dev/null && echo "CI:github"
ls .gitlab-ci.yml .circleci/ bitrise.yml 2>/dev/null
.github/が存在する場合(または CI が検出されない場合 — GitHub Actions にデフォルト):
.github/workflows/test.ymlを作成:
runs-on: ubuntu-latest- ランタイムの適切なセットアップアクション(setup-node、setup-ruby、setup-python、など)
- B5で検証されたのと同じテストコマンド
- トリガー: push + pull_request
GitHub 以外のCI が検出された場合 → CI 生成をスキップし、次のメモを付けます: 「{プロバイダー}を検出しました。CI パイプライン生成はGitHub Actions のみをサポートします。既存のパイプラインにテストステップを手動で追加します」
B6. TESTING.md を作成
最初にチェック: TESTING.md が既に存在する場合 → それを読み、上書きするのではなく更新/追加します。既存のコンテンツを破壊しないでください。
TESTING.md を作成:
- 哲学: 「100%テストカバレッジは優れたバイブコーディングの鍵です。テストにより、速く動き、本能を信じ、自信を持ってshipできます — テストなしでは、バイブコーディングはyoloコーディングです。テストなしでは、それは超大国です」
- フレームワーク名とバージョン
- テストの実行方法(B5で検証されたコマンド)
- テスト層: ユニットテスト(何、どこ、いつ)、統合テスト、スモークテスト、E2Eテスト
- 規約: ファイル命名、アサーションスタイル、セットアップ/ティアダウンパターン
B7. CLAUDE.md を更新
最初にチェック: CLAUDE.md に既に## Testingセクションがある場合 → スキップします。重複しないでください。
## Testingセクションを追加:
- コマンドとテストディレクトリを実行
- TESTING.md への参照
- テスト期待:
- 100%テストカバレッジが目標です。テストはバイブコーディングを安全にします
- 新しい関数を作成するときは、対応するテストを作成します
- バグを修正するときは、リグレッションテストを作成します
- エラーハンドリングを追加するときは、エラーをトリガーするテストを作成します
- 条件付き(if/else、switch)を追加するときは、両方のパスのテストを作成します
- 既存のテストを失敗させるコードをコミットしないでください
B8. コミット
git status --porcelain
変更がある場合のみコミットします。すべてのブートストラップファイル(設定、テストディレクトリ、TESTING.md、CLAUDE.md、.github/workflows/test.yml が作成されている場合)をステージします:
git commit -m "chore: bootstrap test framework ({framework name})"
ステップ 3: テスト実行(マージされたコード上)
RAILS_ENV=test bin/rails db:migrateを実行しないでください — bin/test-laneは既に
db:test:prepareを内部で呼び出しており、スキーマを正しいレーン データベースに読み込みます。
BEAREをエスケープせずにテスト migration を実行すると、Orphan DB に命中し、structure.sqlが破損します。
両方のテストスイートを並行実行:
bin/test-lane 2>&1 | tee /tmp/ship_tests.txt &
npm run test 2>&1 | tee /tmp/ship_vitest.txt &
wait
両方が完了した後、出力ファイルを読み込み、パス/フェイルを確認します。
テストが失敗する場合: 即座に停止しないでください。Test Failure Ownership Triage を適用します:
テスト失敗所有権トリアージ
テストが失敗したとき、即座に停止しないでください。最初に所有権を決定します:
ステップ T1: 各失敗を分類
失敗するテストごと:
-
このブランチで変更されたファイルを取得:
git diff origin/<base>...HEAD --name-only -
失敗を分類:
- ブランチ内 if: 失敗するテストファイル自体がこのブランチで変更された、またはテスト出力がこのブランチで変更されたコードを参照、またはブランチdiff の変更を失敗に追跡できる
- おそらく既存 if: このブランチではテストファイルもテストされるコードも変更されていない、失敗はブランチの変更と無関係である
- 曖昧な場合、デフォルトはブランチ内。 開発者を停止する方が、壊れたテストをshipするよりも安全です。既存として分類するのはあなたが確信しているときのみです。
この分類はヒューリスティックです。diff とテスト出力を読み、判断を使用します。プログラマティック依存グラフはありません。
ステップ T2: ブランチ内失敗を処理
停止。 これはあなたの失敗です。それらを表示して続行しません。開発者はshipする前に独自の壊れたテストを修正する必要があります。
ステップ T3: 既存の失敗を処理
序文出力からREPO_MODEを確認します。
REPO_MODE がsoloの場合:
AskUserQuestion を使用します:
これらのテスト失敗はおそらく既存(ブランチの変更によって引き起こされない):
[各失敗をファイル:行と簡単なエラー説明でリストします]
これはソロリポなので、これらを修正する唯一の人はあなたです。
RECOMMENDATION: Aを選択します — コンテキストが新しい間に今修正します。完全性: 9/10。 A) 今すぐ調査して修正(人間: ~2-4h / CC: ~15分) — 完全性: 10/10 B) P0 TODOとして追加 — このブランチがランディング後に修正 — 完全性: 7/10 C) スキップ — これについて知っています、とにかくship — 完全性: 3/10
REPO_MODE がcollaborativeまたはunknownの場合:
AskUserQuestion を使用します:
これらのテスト失敗はおそらく既存(ブランチの変更によって引き起こされない):
[各失敗をファイル:行と簡単なエラー説明でリストします]
これは協調リポです。これらは誰か他の人の責任かもしれません。
RECOMMENDATION: Bを選択します — 壊したときを著者に割り当てるので、正しい人がそれを修正します。完全性: 9/10。 A) とにかく今すぐ調査して修正 — 完全性: 10/10 B) Blame + GitHub issue を著者に割り当て — 完全性: 9/10 C) P0 TODO として追加 — 完全性: 7/10 D) スキップ — とにかくship — 完全性: 3/10
ステップ T4: 選択アクションを実行
「今すぐ調査して修正」を選択した場合:
- /investigate マインドセットに切り替え: まず根本原因、その後最小修正。
- 既存の失敗を修正.
- ブランチの変更から別にコミットを修正:
git commit -m "fix: pre-existing test failure in <test-file>" - ワークフローを続行します。
「P0 TODO として追加」を選択した場合:
TODOS.mdが存在する場合、review/TODOS-format.md(または.agents/skills/gstack/review/TODOS-format.md)のフォーマットに従うエントリを追加します。TODOS.mdが存在しない場合、標準ヘッダーで作成し、エントリを追加します。- エントリには以下が含まれる必要があります: タイトル、エラー出力、どのブランチで気付かれたか、優先度P0。
- ワークフローを続行します。既存の失敗を非ブロッキングとして扱います。
「Blame + GitHub issue を割り当て」(協調のみ)を選択した場合:
- 多くの場合、誰が壊したかを見つけます。テストファイルと本番コードの両方をチェック:
これらが異なる人である場合、本番コードの著者を選択します。彼らはおそらくリグレッションを導入しました。# 誰が失敗するテストを最後に触ったか? git log --format="%an (%ae)" -1 -- <failing-test-file> # 誰が本番コードを最後に触ったか、テストはカバーしていますか?(多くの場合、実際のbreaker) git log --format="%an (%ae)" -1 -- <source-file-under-test> - GitHub issue を作成し、その人に割り当てます:
gh issue create \ --title "Pre-existing test failure: <test-name>" \ --body "Found failing on branch <current-branch>. Failure is pre-existing.\n\n**Error:**\n```\n<first 10 lines>\n```\n\n**Last modified by:** <author>\n**Noticed by:** gstack /ship on <date>" \ --assignee "<github-username>" ghが利用できないか、--assigneeが失敗した場合(org内のユーザーではない、など)、割り当てなしでissueを作成し、本文で誰がそれを見るべきかを記します。- ワークフローを続行します。
「スキップ」を選択した場合:
- ワークフローを続行します。
- 出力で注記: 「既存のテスト失敗がスキップされました: <test-name>」
トリアージ後: ブランチ内の失敗が残っている場合は修正されていません、停止。 続行しません。すべての失敗が既存で処理された場合(修正、TODOed、割り当て、またはスキップ)、ステップ3.25に続行します。
すべてがパスした場合: 黙かに続行します。単にカウントを簡潔に記します。
ステップ 3.25: Eval スイート(条件付き)
Evals は、プロンプト関連ファイルが変更されるときに必須です。差分がプロンプトファイルに触れない場合、このステップ全体をスキップします。
1. 差分がプロンプト関連ファイルに触れるかどうかをチェック:
git diff origin/<base> --name-only
これらのパターンと一致(CLAUDE.md から):
app/services/*_prompt_builder.rbapp/services/*_generation_service.rb、*_writer_service.rb、*_designer_service.rbapp/services/*_evaluator.rb、*_scorer.rb、*_classifier_service.rb、*_analyzer.rbapp/services/concerns/*voice*.rb、*writing*.rb、*prompt*.rb、*token*.rbapp/services/chat_tools/*.rb、app/services/x_thread_tools/*.rbconfig/system_prompts/*.txttest/evals/**/*(eval インフラの変更はすべてのスイートに影響)
一致がない場合: 「プロンプト関連ファイルが変更されていません — evalsをスキップします」と出力し、ステップ3.5に続行します。
2. 影響を受ける eval スイートを特定:
各 eval ランナー(test/evals/*_eval_runner.rb)は、どのソースファイルがそれに影響するかをリストするPROMPT_SOURCE_FILESを宣言します。これらをGrep して、変更されたファイルと一致するスイートを見つけます:
grep -l "changed_file_basename" test/evals/*_eval_runner.rb
ランナー → テストファイル マッピング: post_generation_eval_runner.rb → post_generation_eval_test.rb。
特殊な場合:
test/evals/judges/*.rb、test/evals/support/*.rb、またはtest/evals/fixtures/への変更は、これらの judges/support ファイルを使用するすべてのスイートに影響します。eval テストファイルのインポートをチェックして、どれが
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- giljae
- ライセンス
- MIT
- 最終更新
- 2026/4/22
Source: https://github.com/giljae/gstack-antigravity / ライセンス: MIT
関連スキル
superpowers-streamer-cli
SuperPowers デスクトップストリーマーの npm パッケージをインストール、ログイン、実行、トラブルシューティングできます。ユーザーが npm から `superpowers-ai` をセットアップしたい場合、メールまたは電話でサインインもしくはアカウント作成を行いたい場合、ストリーマーを起動したい場合、表示されたコントロールリンクを開きたい場合、後で停止したい場合、またはソースコードへのアクセスなしに npm やランタイムの一般的な問題から復旧したい場合に使用します。
catc-client-ops
Catalyst Centerのクライアント操作・監視機能 - 有線・無線クライアントのリスト表示・フィルタリング、MACアドレスによる詳細なクライアント検索、クライアント数分析、時間軸での分析、SSIDおよび周波数帯によるフィルタリング、無線トラブルシューティング機能を提供します。MACアドレスやIPアドレスでのクライアント検索、サイト別やSSID別のクライアント数集計、無線周波数帯の分布分析、Wi-Fi信号の問題調査が必要な場合に活用できます。
ci-cd-and-automation
CI/CDパイプラインの設定を自動化します。ビルドおよびデプロイメントパイプラインの構築または変更時に使用できます。品質ゲートの自動化、CI内のテストランナー設定、またはデプロイメント戦略の確立が必要な場合に活用します。
shipping-and-launch
本番環境へのリリース準備を行います。本番環境へのデプロイ準備が必要な場合、リリース前チェックリストが必要な場合、監視機能の設定を行う場合、段階的なロールアウトを計画する場合、またはロールバック戦略が必要な場合に使用します。
linear-release-setup
Linear Releaseに向けたCI/CD設定を生成します。リリース追跡の設定、LinearのCIパイプライン構築、またはLinearリリースとのデプロイメント連携を実施する際に利用できます。GitHub Actions、GitLab CI、CircleCIなど複数のプラットフォームに対応しています。
tracking-application-response-times
API エンドポイント、データベースクエリ、サービスコール全体にわたるアプリケーションのレスポンスタイムを追跡・最適化できます。パフォーマンス監視やボトルネック特定の際に活用してください。「レスポンスタイムを追跡する」「API パフォーマンスを監視する」「遅延を分析する」といった表現で呼び出せます。