oneshot について
oneshot は、小規模で範囲の明確な変更向けの軽量ワークフロースキルです。簡潔な計画、実装、検証を行い、既定では直接コミットし、ポリシーや要求に応じて PR に進みます。
主な機能
- 014 フェーズの軽量ワークフロー
- 021 ページの計画とセッション内実装
- 03変更リスクに応じた検証
- 04直接コミットが既定、PR も選択可能
- 05イベント記録による再現可能な経路決定
活用シーン
- 01ドキュメントの誤記や局所的な null チェックの修正
- 02依存関係のバージョンや設定キーの更新
- 03サブエージェントを使わない小規模変更
MCP 対応
Exarchos MCP のワークフローおよびオーケストレーションアクションで進行を管理します。PR 経路では MCP アクションが PR を作成し、検出した VCS プロバイダーに振り分けます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ lvlup-sw/ exarchos --skill oneshotインストール後、Claude Code で/oneshotを入力して読み込まれたか確認します。
同梱ファイルreferences/choice-state.md
詳細
ワンショットワークフロースキル
VCS プロバイダー
synthesize パスを選択した場合、このスキルでは Exarchos MCP アクション(create_pr、merge_pr など)を使って VCS 操作を行います。
これらのアクションは、適切な VCS プロバイダー(GitHub、GitLab、Azure DevOps)を自動で検出し、処理を振り分けます。
gh/glab/az コマンドは不要です。MCP サーバーがプロバイダーへの振り分けを処理します。
feature フロー全体(plan → plan-review → delegate → review → synthesize → completed)を使うほどではないものの、イベントソーシングによる監査可能性と計画ステップを必要とする、小規模な変更に適した4フェーズの軽量なワークフロータイプです。ワークフローはデフォルトで直接コミットし、必要に応じて PR パスを選べます。この2つの選択は、ヒューリスティックではなく、純粋なイベントソーシングガードによって implementing の終了時に決定されます。
**ワンショットを初めて実行する場合は、まずこちらをお読みください。**ワークフローの
implementing終了時には 選択状態があります。completed(直接コミット)に進むか、synthesizeを経由するか(PR)は、2つの入力によって決まります。初期化時に設定されたsynthesisPolicyと、 ユーザーが implementing 中にsynthesize.requestedイベントを発行したかどうかです。どちらの入力も永続化されるため、決定はリプレイセーフです。
ワンショットを使う場面
以下の条件をすべて満たす場合にワンショットを使います。
- 変更範囲が限定されている。通常は単一ファイル、または密接に関連する2〜3ファイルのまとまりです。
- サブエージェントへの委任が不要で、1回のセッション内で実装と検証を無理なく完了できます。
- 設計ドキュメントが不要です。タスクの説明から目標が明らかで、1ページの計画で十分です。
- 2段階のレビューが不要です。直接コミットで問題ないほど変更が単純であるか、PR レビュー1回で十分です。
ワンショットに適した具体例:
- README の誤字を修正する
- 依存関係のバージョンを上げる
- 関数1つに不足している null チェックを追加する
- CI ワークフローの YAML を調整する
- 設定キーの名前を、参照されているすべての箇所で変更する
- 単発のヘルパースクリプトを追加する
- 採用するかどうか未定の探索的なスパイクを行う
ワンショットを使わない場面
以下のいずれかに該当する場合はワンショットを使わず、代わりに完全な feature ワークフロー(ideate)を使ってください。
- 多くのファイルやモジュールに及ぶ横断的なリファクタリング
- サブエージェントに分解すると効果的な複数ファイルにわたる機能
- 設計の検討や、複数のアプローチの比較が必要な作業
- spec-review と quality-review の2段階レビューが必要な作業
- 別のエージェントチームとの調整が必要な作業
- 段階的に取り込むべき変更(スタックされた PR)
- 後から参照できる設計ドキュメントを残したい作業
ワンショットを始めた後で、変更が想定より大きいとわかった場合は、cancel して ideate でやり直すのが適切です。
ワンショットの途中で feature ワークフローに拡張しようとしないでください。プレイブックの構成が異なるため、ステートマシンとの調整に手間がかかります。
Synthesis ポリシー — 3 つの選択肢
oneshot ワークフローの synthesisPolicy フィールドでは、変更を PR にするかどうかについて、ユーザーの意図をあらかじめ宣言します。次の 3 つの値のいずれかを取り、state.oneshot.synthesisPolicy に保存されます。
| ポリシー | 動作 | 使用する場面 |
|---|---|---|
always | イベントに関係なく、finalize 時に常に implementing → synthesize に遷移します。必ず PR が作成されます。 | このワークフローでの変更は、たとえ小さなものでも、すべて記録に残したりレビューしたりしたい場合です。 |
never | イベントに関係なく、finalize 時に常に implementing → completed に遷移します。PR は作成されず、コミットは現在のブランチに直接追加されます。 | 個人的な作業や試験的な作業を反復しており、PR を明示的に作成しない場合です。 |
on-request (デフォルト) | デフォルトでは直接コミットします。ユーザーは request_synthesize を呼び出すことで、implementing の途中から PR を選択できます。finalize 時に synthesize.requested イベントがストリームに 1 つでもあれば、ワークフローは completed ではなく synthesize に遷移します。 | 最も一般的なケースです。まずは直接コミットする前提で始めつつ、差分を確認したユーザーが考えを変えられるようにします。 |
デフォルトが on-request なのは、最も意外性が少ないためです。ユーザーが明示的に手間のかかる方法を求めるまでは、簡単な方法で進められます。
ポリシーはイベントより優先されます。 synthesisPolicy: 'never' が設定されており、何らかの理由で synthesize.requested イベントがストリームに存在する場合(たとえば、ユーザーがワークフローを on-request だと思ってアクションを呼び出した場合)でも、ガードは completed に遷移させます。ポリシーはユーザーが宣言した意図であり、実行時のシグナルより優先されます。
ライフサイクル
plan ──────► implementing ──┬── [synthesisOptedOut] ──► completed
│
└── [synthesisOptedIn] ──► synthesize ──► completed
4 つのフェーズがあります。implementing の後の分岐は UML の 選択状態 であり、state.oneshot.synthesisPolicy と synthesize.requested イベントの数を純粋関数で評価する、相互排他的な 2 つの HSM 遷移によって実装されています。
| フェーズ | 処理内容 | 終了条件 |
|---|---|---|
plan | 目標、アプローチ、変更するファイル、追加するテストを記載した簡潔な 1 ページの計画を作成します。設計ドキュメントは作成しません。サブエージェントへのディスパッチもありません。 | artifacts.plan が設定される → implementing に遷移 |
implementing | セッション内でループし、リスクに応じて検証の範囲を調整します。デフォルトは低いティア(静的解析で十分)です。影響範囲の大きい変更では、check_test_adequacy のキルプローブのもと、変更後の動作を網羅するテストを追加します(test-after)。作業を進めながらコミットします。 | テスト合格 + 型チェック正常 + finalize_oneshot の呼び出し |
synthesize | synthesisOptedIn が true の場合のみ到達します。既存のシンセシスフローに引き継ぎます。詳細は @skills/synthesize/SKILL.md を参照してください。exarchos_orchestrate({ action: "create_pr" }) で PR を作成し、自動マージを有効にします。CI ゲートが適用されます。 | PR がマージされる → completed |
completed | 終端状態です。直接コミットする経路では、コミットはすでにブランチに追加されているため、これ以上の作業はありません。synthesize の経路では、PR のマージイベントによってワークフローが終了します。 | — |
他のすべてのワークフロータイプと同様に、共通のキャンセル遷移を通じて、どのフェーズからでも cancelled に遷移できます。
手順
ステップ 1 — 初期化
action: 'init'、workflowType: 'oneshot'、および任意の synthesisPolicy を指定して exarchos_workflow を呼び出します。
exarchos:exarchos_workflow({
action: "init",
featureId: "fix-readme-typo",
workflowType: "oneshot",
synthesisPolicy: "on-request" // optional — defaults to 'on-request'
})
ユーザーの意図が最初から明確な場合(「これの PR がほしい」など)は、synthesisPolicy: "always" を渡します。「PR は作らず、そのままコミットして」など、PR を作成しない意図が明確な場合は、synthesisPolicy: "never" を渡します。それ以外の場合は、このフィールドを省略してデフォルトの on-request を使用します。implementing フェーズで、いつでも後から PR に切り替えられます。
初期化によって新しいワークフロー状態が返され、ワークフローは plan で開始します。
ステップ 2 — 計画フェーズ
1ページの計画を作成します。意図的に簡潔な内容にします。設計書や並列化の分析、N 個のタスクへの分割は不要です。計画では、次の4つの質問にそれぞれ5~10行で答えます。
- 目標 — ユーザーは何を達成しようとしていますか?
- アプローチ — 実装戦略を一文で表すとどうなりますか?
- ファイル — 変更するファイルはどれですか?(通常は1~5個)
- テスト — 追加するテストケースはどれですか?(説明ではなく名前)
計画を保存してから、implementing に移行します。フィールドの変更とフェーズの変更は別々のアクションです。update は計画の成果物を書き込みます(phase は予約済みフィールドのため、update では変更できません)。その後、transition でフェーズを進めます。ガードは最新の状態を参照するため、oneshot-plan-set ガードの評価前に計画が反映されます。
exarchos:exarchos_workflow({
action: "update",
featureId: "fix-readme-typo",
updates: {
"artifacts.plan": "<plan text>",
"oneshot.planSummary": "<one-line summary>"
}
})
exarchos:exarchos_workflow({
action: "transition",
featureId: "fix-readme-typo",
target: "implementing"
})
計画は feature ワークフローとの整合性を保つため、artifacts.plan に保存します。パイプラインビューに表示する、人が読みやすい一文の要約は oneshot.planSummary に保存します。oneshot-plan-set ガードが必須とするのは artifacts.plan だけです。planSummary はパイプラインビュー用の任意のラベルであり、実際の計画成果物の代わりにはなりません。
ステップ 3 — 実装フェーズ
セッション内でループを実行し、変更のリスクに応じて検証の範囲を調整します(@skills/_shared/references/verification.md の段階を参照)。oneshot はデフォルトで低ティアです。単純な修正であれば、静的解析で十分です。変更がより大きな影響を及ぼす領域(スキーマ、型、API、共有契約)に触れる場合、または I/O 境界をまたぐ場合は、より高いティアのタスクです。新規または変更された動作をテストでカバーしてください(テストを後から追加してもかまいません)。また、実際には失敗しないテストは check_test_adequacy のキルプローブによって拒否されることを想定してください。
計画に含まれる、より高いティアの動作ごとに次を行います。
- 動作を実装します。
- そのティアで必要なテストを追加します(変更範囲に絞ったテスト。高ティアでは境界をまたぐ統合テストも追加)。テスト名は
Method_Scenario_Outcomeとします。 - テストが成功した状態を保ちながらリファクタリングします。
動作ごとに細かくレッド・グリーンを繰り返す方法も明示的に選択できますが、必須ではありません。
論理的な変更ごとに、単一のアトミックなコミットを作成します。複数の無関係な変更を1つのコミットにまとめないでください。oneshot では変更をまとめて検出する独立したレビュー段階がないため、コミットをアトミックに保つことが特に重要です。
oneshot ではサブエージェントのディスパッチはありません。メインエージェントが直接作業します。また、独立したレビュー段階もありません。ティアに応じた検証(静的解析に加え、低ティアを超える場合は check_test_adequacy のキルプローブ)によって品質を維持します。また、ユーザーが希望した場合は、PR レビューを合成します。
ワークフロー途中でPRを選択する
plan または implementing の途中で、やはりPRを作成したいとユーザーが判断した場合(デフォルトのポリシーは on-request)、request_synthesize オーケストレーションアクションを呼び出して選択できます。
exarchos:exarchos_orchestrate({
action: "request_synthesize",
featureId: "fix-readme-typo",
reason: "user requested review of the parser changes"
})
このアクションのトリガーは会話の内容であり、特定のキーワードではありません。 次のような表現に注意してください。
- 「やっぱり、これのPRを作成しましょう」
- 「取り込む前にレビューしてほしい」
- 「これをPRにして」
- 「誰かに確認してもらおう」
- 「これをsynthesizeして」
こうした表現があれば、すぐに request_synthesize を呼び出してください。ハンドラーはワークフローのイベントストリームに synthesize.requested イベントを追加します。synthesisOptedIn ガードは finalize 時にイベントストリームを読み取り、適切な遷移先を決定します。
request_synthesize は plan フェーズと implementing フェーズの両方で受け付けられます。PRの経路を選ぶと決めた時点で、implementing の開始前であっても呼び出してください。終端フェーズ(synthesize、completed、cancelled)では受け付けられません。
重複した呼び出しはルーティングに関しては冪等ですが、イベントに関しては冪等ではありません。呼び出すたびに新しい synthesize.requested イベントが追加されますが、ガードは1件以上あれば「オプトイン済み」と見なすため、1回呼び出しても5回呼び出してもルーティングの判断は同じです。監査のため、イベントストリームには重複分もすべて記録されます。
request_synthesize を呼び出しても、フェーズは遷移しません。ワークフローは現在のフェーズにとどまります。この判断が反映されるのは、手順4で finalize_oneshot を呼び出したときだけです。
Step 4 — Finalize(選択ポイント)
implementing ループが完了したら(テストに合格し、型チェックに問題がなく、すべてのコミットが完了したら)、finalize_oneshot を呼び出して選択状態を解決します。
exarchos:exarchos_orchestrate({
action: "finalize_oneshot",
featureId: "fix-readme-typo"
})
ハンドラーは次の処理を行います。
- 現在の状態を読み取り、
workflowType === 'oneshot'およびphase === 'implementing'であることを確認します。 - イベントストアから
_eventsを読み込み、ガードがHSMによる実際の遷移時と同じ情報を参照できるようにします。 - 状態に対して
guards.synthesisOptedInを評価します。ガードはstate.oneshot.synthesisPolicyと_events配列を確認します。 - 解決された遷移先フェーズ(
synthesizeまたはcompleted)を指定してhandleSetを呼び出します。HSMは遷移境界でもガードを再評価するため、読み取りと遷移の間に競合が発生しても安全に検出されます。
考えられる結果は次のとおりです。
synthesisPolicy | synthesize.requested イベントの有無 | 解決された遷移先 | 経路 |
|---|---|---|---|
always | (任意) | synthesize | PR経路 |
never | (任意) | completed | 直接コミットする経路 |
on-request(デフォルト) | あり | synthesize | PR経路 |
on-request(デフォルト) | なし | completed | 直接コミットする経路 |
Step 5a — 直接コミットする経路(終端)
finalize の結果が completed なら、これで完了です。implementing 中に行ったコミットはすでに現在のブランチにあります。まだプッシュされていない場合はプッシュしてください。
git push
ワークフローは completed になり、デフォルトのパイプラインビューには表示されなくなります。完了を報告してください。
## Oneshot Complete (direct-commit)
Workflow: <featureId>
Plan: <one-line summary>
Tests added: N
Commits: <hash list>
Path: direct-commit
Step 5b — Synthesize 経路
finalize の結果が synthesize なら、標準のsynthesisフローに引き継ぎます。@skills/synthesize/SKILL.md を参照してください。feature ワークフローで使われるものと同じ prepare_synthesis/validate_pr_body/create_pr の仕組みが適用されます。prepare_synthesis で必須の repoRoot も含まれます。コミット先のリポジトリの絶対パスを渡してください。すべての準備状況チェックはサーバー自身の作業ディレクトリではなく、そのリポジトリ内で実行されます。PRのマージ後、ほかのすべてのワークフロータイプと同様に、既存の mergeVerified ガードを介してワークフローは synthesize → completed に遷移します。
オプトインしたoneshotのsynthesizeでは、delegate や review を実行する必要はありません。これらのフェーズはoneshotプレイブックには存在しません。PRレビューが唯一のレビューです。完了を報告してください。
## Oneshot Complete (synthesize)
Workflow: <featureId>
PR: <url>
Tests: X pass | Build: 0 errors
Path: synthesize → PR review → merge
呼び出し例
例A — 直接コミット(デフォルトの on-request ポリシー、オプトインなし)
User: "Quick fix — there's a typo in the README, 'recieve' should be 'receive'.
Use oneshot."
Agent:
1. exarchos_workflow init { featureId: "fix-readme-typo", workflowType: "oneshot" }
→ workflow created in 'plan' phase, synthesisPolicy defaults to 'on-request'
2. Produces a 4-line plan: goal=fix typo, approach=sed, files=[README.md],
tests=[readme has no occurrence of 'recieve']
3. exarchos_workflow update {
featureId: "fix-readme-typo",
phase: "implementing", // top-level
updates: {
"artifacts.plan": "...",
"oneshot.planSummary": "..."
}
}
4. edits README, fixes typo (low tier — a docs one-liner; static analysis
suffices, no test-first ceremony)
5. verifies: greps README for 'recieve' → 0 matches
6. git commit -m "docs: fix 'recieve' typo in README"
7. exarchos_orchestrate finalize_oneshot { featureId: "fix-readme-typo" }
→ guard sees policy='on-request' + no synthesize.requested event
→ resolves to 'completed'
8. git push
"Done. Workflow completed via direct-commit path."
例B — implementingの途中でオプトイン(on-request → ユーザーが判断を変更)
User: "Add input validation to the parseConfig helper. Oneshot."
Agent:
1. exarchos_workflow init { workflowType: "oneshot" }
→ 'plan' phase, default 'on-request'
2. plans (goal: validate input, files: [parser.ts, parser.test.ts])
3. transitions to 'implementing'
4. adds the null-input validation to parseConfig
5. adds a test for the null-input case (test-after)
6. refactors: extracts validateInput helper (tests stay green)
7. commits
User: "Actually, this is touching the parser — I want a review on it before
it lands."
Agent:
8. exarchos_orchestrate request_synthesize {
featureId, reason: "user requested review of parser changes"
}
→ appends synthesize.requested event
9. exarchos_orchestrate finalize_oneshot { featureId }
→ guard sees policy='on-request' + 1 synthesize.requested event
→ resolves to 'synthesize'
10. hands off to @skills/synthesize/SKILL.md → prepare_synthesis →
validate_pr_body → create_pr → merge
例C — synthesisPolicy: 'always'(PR必須)
User: "I want a PR for any change to the auth module, even small ones.
Use oneshot but always make a PR."
Agent:
1. exarchos_workflow init {
workflowType: "oneshot",
synthesisPolicy: "always"
}
2-7. plan + implement + verify + commits, identical to Example A
8. exarchos_orchestrate finalize_oneshot { featureId }
→ guard sees policy='always' (short-circuits — no event check needed)
→ resolves to 'synthesize'
9. synthesis flow → PR
状態管理
ワークフロー状態の oneshot キーの下で、oneshot 固有の状態を追跡します。
exarchos:exarchos_workflow({
action: "update",
featureId: "<id>",
updates: {
"oneshot": {
"synthesisPolicy": "on-request",
"planSummary": "Fix off-by-one in pagination helper"
}
}
})
servers/exarchos-mcp/src/workflow/schemas.ts のスキーマに従い、synthesisPolicy フィールドは省略可能で、デフォルトは 'on-request' です。ユーザーが希望を示している場合は、明示的に設定することをおすすめします。
フェーズ遷移とガード
oneshot の遷移表全体については、@skills/checkpoint/references/phase-transitions.md を参照してください。
注: エンジンの
exarchos_workflow describe playbook="oneshot"の出力と、hsm-definitions.tsの HSM 定義が、遷移動作の正規の情報源です。phase-transitions.mdは文章による参考資料であり、内容が実態からずれる可能性があります。不一致がある場合は、エンジンのdescribe出力を優先してください。
oneshot のクイックリファレンス:
| From | To | Guard |
|---|---|---|
plan | implementing | oneshotPlanSet(artifacts.plan が空でないことが必要) |
implementing | synthesize | synthesisOptedIn |
implementing | completed | synthesisOptedOut |
synthesize | completed | mergeVerified |
| (任意) | cancelled | 汎用 — 常に許可 |
synthesisOptedIn と synthesisOptedOut は、state.oneshot.synthesisPolicy と state._events の純粋関数です。これらは、意味のある 4 つの組み合わせすべてで相互排他的です。always と never は、それぞれイベントフラグを無視して 1 つの結果に対応し、on-request は synthesize.requested イベントの有無に応じて分岐します。常に、いずれか一方のガードだけが true を返します。
スキーマの確認
パラメータスキーマ(synthesisPolicy の列挙値を含む)を確認するには exarchos_workflow({ action: "describe", actions: ["init", "update"] }) を使用し、フェーズ遷移、ガード名、プレイブックの説明を確認するには exarchos_workflow({ action: "describe", playbook: "oneshot" }) を使用してください。オーケストレーションアクションのスキーマを確認するには exarchos_orchestrate({ action: "describe", actions: ["request_synthesize", "finalize_oneshot"] }) を使用してください。
リスクに応じた検証
@skills/_shared/references/verification.md の検証段階は oneshot にも適用されます。oneshot は低コスト(低リスク)の段階がデフォルトです。1 行の修正や設定の微調整では、通常は静的解析(型チェック+リンター)に頼り、テストファーストの手順は踏みません。ただし、リスクを示す要因がある場合は別です。具体的には、次のとおりです。
- 低リスクの変更(ドキュメント/設定/名前変更のみで、影響範囲がほぼないもの)は、静的解析に合格すれば十分です。動作が自明でない場合に限り、対象を絞ったテストを追加してください。
- 変更がより広い範囲に影響する箇所(スキーマ/型/API/共有コントラクト)に触れる場合、または I/O 境界をまたぐ場合は、低リスク段階のタスクではありません。新規または変更した動作をテストでカバーしてください(テスト後でもかまいません)。また、実際には失敗しないテストは
check_test_adequacyのキルプローブに検出されることを想定してください。 - どの段階でも、コミットはアトミックに保ちます。コミット 1 つにつき、論理的な変更は 1 つです。
oneshot では、すべて「1 行だけ」の変更だと考えて、検証をまったく省きたくなるかもしれません。低リスク段階を超える変更では、その誘惑に負けないでください。oneshot の目的は、適切なコストで監査可能性を確保することであり、検証をゼロにすることでも、些細な編集に機能開発向けの手順をすべて適用することでもありません。
アンチパターン
| しないこと | 代わりにすること |
|---|---|
| 計画フェーズを省略する(「明白だから」) | それでも4行の計画を書きます。将来の自分が読む成果物になります |
| 些細な1行変更に、完全なレッド・グリーン・リファクタリングの手順を適用する | リスクに応じて検証します。低リスクでは静的解析を中心にし、影響範囲の大きい変更では変更した動作を網羅するテストを追加します |
| 「ワンショットだから」と検証をすべて省略する | 低リスクでも静的解析には合格する必要があります。影響範囲の大きい変更では、変更した動作を網羅するテストも引き続き必要です |
| 複数ファイルのリファクタリングにワンショットを使う | ideate と完全な機能ワークフローを使います |
| ワンショットの途中で機能ワークフローに拡張しようとする | キャンセルして、ideate からやり直します |
ユーザーの意図を確認せずに request_synthesize を呼び出す | ユーザーからPRの依頼があるまで待ってから呼び出します |
| 「ワンショットだから」と無関係な変更を1つのコミットにまとめる | コミットはアトミックに保ちます。まとめすぎを見つけるレビュー段階がないためです |
最後に finalize_oneshot を呼び出し忘れる | そうしないとワークフローが永久に implementing のままになります。明示的に呼び出します |
完了条件
-
exarchos_workflow initをworkflowType: "oneshot"で呼び出した - 1ページの計画を
artifacts.planに保存した - フェーズを
implementingに移行した - 計画したすべての動作を、リスク階層に応じて実装・検証し、アトミックなコミットにした
-
finalize_oneshotを呼び出し、completedまたはsynthesizeに到達した - 直接コミットする場合:コミットをプッシュした
- 合成する場合:
@skills/synthesize/SKILL.mdを使ってPRを作成し、マージした