[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71J5B7R7ZDACB1FH3KCQ6BJ":3,"skill-same:01M71J5B7R7ZDACB1FH3KCQ6BJ":85},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":42,"linkOnly":43,"markdownContent":44,"markdownBody":45,"frontMatter":46,"refName":50,"commitSha":51,"skillDirectory":52,"forksCount":13,"repositoryHtmlUrl":53,"repositoryHomepageUrl":6,"ownerHtmlUrl":54,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":55,"install":56,"resources":68},"01M71J5B7R7ZDACB1FH3KCQ6BJ","drive",null,"Automatically cycles through implementation, PR creation, self-review, and fixes from an Issue or an instruction to produce a merge-ready PR. Supports single\u002Fmultiple Issues\u002FPRs and explicit dependency notation. Can optionally run through to merge. In orchestration, detects and self-resolves cross-cutting concerns before merge, leaving no follow-up within a single run.","ozzy-labs\u002Fskills","ozzy-labs","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F246109093?v=4","01M6H0M2K2PZXHWNHJJTWY20FY","01M71J2B6FZ5KPEXPR5VS1TX7Z",0,"MIT","https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdrive\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[5,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41],"self","follow-up","issue","pr creation","edit","write","read","merge","run","dependency","review","websearch","Bash","workflow","orchestration","issues","up","creation","ready","2026-11-10 10:12:30",false,"---\ndescription: Automatically cycles through implementation, PR creation, self-review, and fixes from an Issue or an instruction to produce a merge-ready PR. Supports single\u002Fmultiple Issues\u002FPRs and explicit dependency notation. Can optionally run through to merge. In orchestration, detects and self-resolves cross-cutting concerns before merge, leaving no follow-up within a single run.\nargument-hint: \u003C#N | #N,#N | #N-N | instruction> [--merge] [--concurrency N] [--review=quick|final-deep|deep] [--no-usage-guard]\ndisable-model-invocation: true\nallowed-tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, AskUserQuestion, Agent, Workflow\n---\n\n# drive\n\nRead `.agents\u002Fskills\u002Fdrive\u002FSKILL.md` and follow its workflow steps.\n\n**Important:** for each phase, Read the corresponding skill's SKILL.md and execute **only the workflow steps**. **Ignore entirely** the \"next action suggestions\" section and the \"completion report\" section within the SKILL.md you read. Transitions between phases are controlled by this skill.\n\n## Claude Code-specific additions\n\n### Input parsing\n\nParse `$ARGUMENTS` and identify the target list (Issue\u002FPR\u002Finstruction), dependency notation, and options (`--merge`, `--concurrency N`, `--review=\u003Cmode>`, `--no-usage-guard`). Deterministic expansion, DAG\u002Fwave construction, and mode branching are delegated to `drive-plan.mjs` (`~\u002F.claude\u002Fskills\u002Fdrive\u002Fdrive-plan.mjs`; for dogfooding, `\u003Crepo>\u002F.claude\u002Fskills\u002Fdrive\u002Fdrive-plan.mjs`), the same as the canonical, and aggregate-report formatting is delegated to `drive-report.mjs`.\n\n- 1 target with no dependency notation (`->`) → single mode\n- 2 or more targets, or dependency notation present → orchestration mode\n\nHandling of `--review`:\n\n- Default is `quick`\n- Single mode: accepts all of `quick` \u002F `final-deep` \u002F `deep`\n- Orchestration mode: forces `--review=quick`; if `final-deep` \u002F `deep` is specified, shows a warning and falls back to `quick` (cost management)\n\nHandling of usage-guard:\n\n- **Enabled by default (opt-out)**. A plain drive with no checkpoints inserted runs only when `--no-usage-guard` is explicitly added.\n- If `--no-usage-guard` is not specified, the usage-guard engine is called at the checkpoints described later in \"usage-guard wiring (default ON, disabled via `--no-usage-guard`)\"; on Usage Limit overage, it waits until the budget recovers before re-entering itself.\n- `--usage-guard` is accepted as a backward-compatible **deprecated no-op alias** (it doesn't need to be explicit since it's ON by default; behavior is identical to the default). It is never force-added to the continuation command.\n- **The original argument list is saved** at parse time (used to assemble the continuation command `\u002Fdrive \u003C元の引数>` and the resume line in the failure-time report `再開: \u002Fdrive \u003C元の引数>` — canonical's Phase 5 \u002F Phase Final-6, only when there's a leftover `failed` \u002F `merge-ready` \u002F `skipped` —). `--no-usage-guard` is included in what's saved, and carried over to the continuation command, only if the user specified it. `--usage-guard` is a no-op alias, so it's neither saved nor added.\n\n### Autonomous execution\n\nAskUserQuestion is not used at all — including for plan approval — up through the merge step (or merge confirmation) (fully autonomous execution).\n\n### usage-guard wiring (default ON, disabled via `--no-usage-guard`)\n\n**Enabled by default.** Pauses work before the Claude Code Usage Limit (5-hour = Current \u002F weekly = Weekly) reaches 100%, and automatically resumes once the budget recovers. **Only when `--no-usage-guard` is specified does this section's processing not run at all, leaving drive's core behavior unchanged** (since pause\u002Fresume is Claude-specific, the wiring is confined to this overlay; precedent: `review --deep`). `--usage-guard` is accepted as a deprecated no-op alias, but since it's enabled by default, behavior doesn't change.\n\n> **Claude-only**: the usage-guard engine depends on the OAuth usage-rate endpoint and `ScheduleWakeup`, so it only works on Claude Code (the `usage-guard` skill gated by `adapters: claude-code` = #121). The base SKILL.md is ON by default, but since this overlay isn't included in the build output for other adapters (codex\u002Fgemini\u002Fcopilot), it effectively remains a no-op there.\n\n#### Graceful degrade (skill absent)\n\nSince it's ON by default, drive is **not stopped with an error** even in an environment where the usage-guard skill \u002F `usage-check.mjs` **doesn't exist** (e.g., `~\u002F.claude\u002Fskills\u002Fusage-guard\u002F` not installed). At the start of each checkpoint, check for the existence of the `usage-guard` skill (`.claude\u002Fskills\u002Fusage-guard\u002FSKILL.md`; in user-scope, `~\u002F.claude\u002Fskills\u002Fusage-guard\u002FSKILL.md`), and **if its absence is detected, emit a one-line warning** (e.g., \"⚠️ usage-guard degraded: skill not installed, proceeding normally without monitoring\") **and proceed normally as-is** (treated as fail-open — subsequent checkpoints are also skipped). This is a mandatory requirement of being ON by default: the guard's own absence must never hard-stop drive.\n\n#### checkpoint trigger points\n\nWhen `--no-usage-guard` is not specified (= default ON), usage-guard is called only at the following **entry points to a resumable unit**:\n\n| Mode | checkpoint |\n|---|---|\n| Single mode | **before each target's Phase 1 (implement) begins** |\n| Single mode | **before each review-loop iteration** (before each pass in Phase 3 begins) |\n| Orchestration | **before each wave begins** (at the start of the wave loop in Phase 1..N) |\n| Orchestration | **before each worker dispatch** (immediately before launching a worker within the same wave) |\n\n**Checkpoints are always placed at boundaries where re-entry can happen cleanly.** It **does not pause** mid-implement (partway through implementation, before a PR exists), partway through a review pass, or partway through a commit\u002Fpush — pausing there risks losing track of progress on re-entry. Since drive has idempotent resume (detecting an existing PR and resuming from Phase 3), any of the boundaries above can safely resume from where they left off on re-run.\n\n#### Steps at a checkpoint\n\nAt each checkpoint, run the following:\n\n1. Read the `usage-guard` engine (`.claude\u002Fskills\u002Fusage-guard\u002FSKILL.md`; in user-scope, `~\u002F.claude\u002Fskills\u002Fusage-guard\u002FSKILL.md`) and run its \"lightweight wait-loop\" (= run `usage-check.mjs` in the same directory via Bash to get JSON).\n   - **At the wave \u002F worker-dispatch checkpoint (orchestration), gate headroom-aware (#141)**: wave dispatch definitively launches **N uninterruptible workers**, and they consume budget while running. Judging by the current value alone can't account for the projected consumption of a whole wave, and the threshold can be overshot mid-wave (observed in practice: `five_hour` 86% → 98% after 1 wave, with 3-worker concurrency). To prevent this, the dispatch checkpoint passes `usage-check.mjs --headroom \u003Cpct>` and gates on the **projected post-dispatch value** (`util + reserve(N) >= threshold`). `reserve(N)` is a reservation proportional to the concurrency level `N` (`--concurrency`, default `min(4, tasks in wave)`). **A rough guideline is `reserve = N × per_worker_pct`** (`per_worker_pct` is the projected consumption per heavy worker; take the observed `86→98 \u002F 3-worker ≈ 4pt\u002Fworker` as the initial value, overridable via the `USAGE_GUARD_DISPATCH_HEADROOM` env var). Example: `concurrency=3`, `per_worker≈4pt` → `--headroom 12` → pause before dispatch if `threshold(95) − 12 = 83%` is exceeded. The larger `--concurrency` is, the larger the reserve grows.\n   - **The single-mode Phase 1 \u002F review-loop checkpoint doesn't pass headroom** (= default 0, gating on the current value, as before). Since the consumption of 1 unit can be absorbed at an interruptible boundary, no reserve is needed.\n2. `ok: true` (both budgets are below threshold; at the dispatch checkpoint, `util + reserve` is below threshold) → **proceed normally**. Move straight on to the next phase \u002F wave \u002F worker dispatch.\n3. `ok: false` (either budget exceeds the threshold) → defer to usage-guard's wait-loop. A post-reset buffer (`resume_buffer_seconds`, default +300 seconds) is folded into `wait_seconds`, and the wait extends to `resets_at + buffer` (avoiding a re-bounce from re-entering right at the reset boundary). **Execute the engine's `resume_plan` (#212) rather than re-deriving the trigger by hand**: `usage-check.mjs` emits `resume_plan { trigger, wait_seconds, fire_at }`, and orchestration checkpoints pass `--context orchestration` so the plan prefers a durable one-shot (mapping in usage-guard SKILL.md §\"Resume plan\"). The `trigger` cases:\n   - `schedule-wakeup` (in-session, wait ≤1h) → set up a heartbeat with `ScheduleWakeup(min(wait_seconds, 3600))` and **wait** (no re-entry and no budget consumption while waiting). If `wait_seconds` exceeds 3600, re-check in multiple installments.\n   - `cron-oneshot` (non-`\u002Floop` orchestration, wait >1h, needing restart resilience) → set a `CronCreate` (`recurring: false`, durable) to **`fire_at`** (`= resets_at + resume_buffer_seconds`), and re-submit the continuation command when it fires (a single wall-clock shot, restart-resilient; the one-shot auto-deletes after firing). Since this being ON by default makes this path (>1h, non-`\u002Floop`) easy to hit, this is preferred over `ScheduleWakeup`. See usage-guard SKILL.md §Lightweight wait-loop, \"Choosing the resume trigger\", for details.\n   - `cron-routine` (durable, survives a 100% hard-interrupt — #213) → arm a **cloud Routine** at `fire_at`. See \"Durable pre-arm\" below; validate `firesAfterReset(plan, resets_at)` first, and fall back to `cron-oneshot` + a warning where `\u002Fschedule` is unavailable.\n   - **When a reflection lag is suspected (`suspected_reflection_lag: true`), don't set a long-duration CronCreate at the boundary — instead re-check with `ScheduleWakeup` at a short interval (`wait_seconds` ≈ 180 seconds)** (this catches a false 100% caused by the residual image of the prior window right after the boundary, once recovery is confirmed, avoiding a false negative from a ~5h stall; see usage-guard SKILL.md §Behavior: reflection-lag detection).\n   - On waking, self-re-enter via the continuation command **`\u002Fdrive \u003C元の引数>`** (since it's ON by default, `--usage-guard` is never force-added; `--no-usage-guard` is carried over only if the user specified it — though since this section doesn't run at all when `--no-usage-guard` is set, the actual continuation command can simply pass the original arguments as-is). drive's idempotent resume detects the existing PR \u002F branch \u002F completed workers and **resumes from where it left off** (no duplicate side effects, even across a wait).\n   - Repeat steps 3–4 until `usage-check.mjs` returns `ok: true`.\n\n> Pass the **original argument list** as-is to the continuation command (since it's ON by default, adding `--usage-guard` is unnecessary — the guard keeps taking effect by default after resume too).\n\n#### Durable pre-arm (hard-interrupt resilience, #213\u002F#217)\n\nA reactive pause (steps above) keeps the session alive so an **in-session** trigger (`ScheduleWakeup` \u002F a session-scoped `CronCreate`) can fire. But if the boundary checkpoint is bypassed and a worker burns all the way to **100%**, the session **hard-interrupts** and those in-session triggers die with it — the exact \"stopped and never resumed\" failure. Only a **cloud Routine** (scheduled deployment) survives a hard-interrupt.\n\nFor orchestration \u002F long runs with hard-interrupt risk, **pre-arm a durable resume at run start** (not reactively):\n\n1. Before launching the first wave, run `usage-check.mjs --context durable` to obtain a `resume_plan` with `trigger: \"cron-routine\"` and `fire_at`.\n2. **Assert `firesAfterReset(plan, resets_at)`** (a Routine firing at\u002Fbefore the reset is rejected with `session_rate_limited_error`; `fire_at = resets_at + buffer` already satisfies this — the guard catches a `resume_buffer=0` \u002F clock-skew edge).\n3. Arm a **cloud Routine** at `fire_at` whose prompt is the continuation command `\u002Fdrive \u003C元の引数>` (idempotent — drive resumes from the existing PR\u002Fbranch\u002Fcached workers, so a spurious fire is a harmless no-op).\n4. On a clean finish (limit never hit), the one-shot Routine either no-ops on its idempotent continuation or is cancelled.\n5. **Fallback**: where the host `\u002Fschedule` (Routines) is unavailable, fall back to the in-session `cron-oneshot` path + a degradation warning — a durable path that cannot be armed must not silently drop the resume.\n\nThis composes with the two existing layers (headroom-aware boundary pause + the `#123` PreToolUse ceiling): the pre-armed Routine is the **last-resort net** that recovers even a genuine hard-interrupt.\n\n#### Granularity and duplication (two-layer defense against in-wave overshoot, #141)\n\nOrchestration pauses at the granularity of **wave boundaries \u002F worker-dispatch boundaries**. There's a structural failure mode here:\n\n- **Failure mode (in-wave overshoot)**: even if the boundary checkpoint dispatches with `ok:true`, the N launched workers **consume budget while running**. Since the boundary checkpoint has no effect while things are running, the threshold can be crossed and 100% reached mid-wave. `ok:false` is only **detected after the fact** at the next boundary, and can't prevent overshoot within that wave (observed in practice: 86% pre-dispatch, threshold 95 → 3-worker concurrency → 98% while running). **Lowering the threshold is a stopgap that can't account for concurrency and is not a substitute.**\n\nThis is closed off with a **two-layer defense**:\n\n1. **A resumable pause at the boundary (headroom-aware, preventive)**: at the wave \u002F worker-dispatch checkpoint, pass `usage-check.mjs --headroom \u003Cpct>` (with `reserve(N)` computed from `--concurrency`) and gate on the **projected post-dispatch value**, stopping the dispatch itself preemptively (step 1 of \"Steps at a checkpoint\" above). On a headroom trip, the wait is until the budget edge + buffer (headroom recovers when the budget resets).\n2. **The mid-unit ceiling (#123 PreToolUse hook, a reliable ceiling)**: a mid-unit overage in an already-launched, running worker can't be stopped at a boundary. The #123 hook — which **takes effect before every tool call and also reaches inside subagents** — is the only reliable ceiling. In environments running `\u002Fdrive`'s wave parallelism, it's **recommended to wire up the `matcher:\"*\"` hook by default** (#141). Previously, due to the risk of the **pre-#139** hook hard-stopping on a transient outlier, it remained only a \"recommended addition,\" but since **#139 (file kill-switch \u002F reflection-lag ALLOW \u002F debounce \u002F spike rejection) resolved the hard-stop risk**, wiring it by default has become safe. In the unlikely case of a false deny, it can be released immediately with **`touch ~\u002F.claude\u002Fusage-guard\u002FDISABLE`** (usage-guard SKILL.md §Disabling). See usage-guard SKILL.md §Enabling the PreToolUse hook for wiring steps.\n\n> The boundary pause (headroom-aware) and the mid-unit hook are **each insufficient on their own**. headroom is the \"stop dispatch preemptively\" prevention; the hook is the \"reliable ceiling during execution.\" Only when both are in place is overshoot practically closed off.\n\n- The prompt itself passed to the worker (subagent) can remain unchanged. Since the worker runs single mode, **the parent inserting a headroom-aware checkpoint before worker dispatch (ON by default)** is what provides wave-granularity budget handling.\n\n#### fail-open (surfacing degradation)\n\nIf usage-check's signal acquisition fails completely (both the endpoint → JSONL fallback fail), usage-guard returns `ok: true` (fail-open). drive proceeds normally as-is — **a bug in the guard itself must never hard-stop drive**.\n\nHowever, fail-open means the **guard is effectively OFF**. When the `source` of the JSON obtained at a checkpoint is anything other than `endpoint` \u002F `cache` (especially `fail-open`), the drive caller **leaves the degradation explicitly in the report** (e.g., \"⚠️ usage-guard degraded: source=fail-open, not actually monitoring\"). See usage-guard SKILL.md §Environment requirements for the causes of the endpoint path being unusable (api.anthropic.com egress \u002F permission to read `~\u002F.claude\u002F.credentials.json`) and how to recover. The PreToolUse hook on a running worker likewise emits a degradation warning to stderr.\n\n### Choosing the orchestration execution mechanism\n\nFor orchestration worker parallel execution, **the Workflow method is canonical (default)**. It rides natively on the harness via Claude Code's Dynamic Workflows (a deterministic script + journal resume + parallel `agent()` launches), delegating wave execution, worker distribution, progress observation, and interrupt\u002Fresume to the runtime ([ADR-0028](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fhandbook\u002Fblob\u002Fmain\u002Fadr\u002F0028-skills-architecture-engine-judgment-policy-catalog.md) R2). It falls back to the conventional Agent tool method (the \"subagent dispatch\" section) **only in environments where the Workflow tool is unavailable** (Dynamic Workflows disabled — `disableWorkflows` — \u002F an older version).\n\n| | Workflow method (canonical) | Agent tool method (fallback) |\n|---|---|---|\n| Concurrency control | runtime manages the cap (max 16) and queueing | manual semaphore |\n| worktree isolation | `agent({ isolation: 'worktree' })` | `Agent({ isolation: \"worktree\" })` |\n| Return-value validation | structured validation via `schema` (mismatches auto-retry) | parent parses free-form JSON |\n| Progress monitoring | `\u002Fworkflows` UI + `log()` | `gh pr list` 30-second polling |\n| Interrupt\u002Fresume | journal resume (`resumeFromRunId`; completed workers restored from cache) | manual re-run (PR detection via drive's idempotent resume) |\n\n### Orchestration via the Workflow method (canonical)\n\nPhase 0 (DAG \u002F wave construction) and the plan display are done **on the conversation side, before launching the Workflow** (since a workflow can't accept mid-run user input, all approval-related steps are placed before\u002Fafter launch). Pass the wave configuration via `args` and assemble a script of the following form:\n\n```js\nexport const meta = {\n  name: 'drive-orchestration',\n  description: 'drive: wave 単位で worker を並列実行し merge-ready PR 群を作る',\n  \u002F\u002F pure literal（args を参照できない）。起動時に drive-plan.mjs の wave 数へ合わせて書く\n  phases: [{ title: 'Wave 1' }, { title: 'Wave 2' }],\n}\n\n\u002F\u002F worker 戻り値 contract。canonical（.agents\u002Fskills\u002Fdrive\u002FSKILL.md）の戻り値 JSON を Schema 化した\n\u002F\u002F もので、フィールドは canonical と 1:1。runtime が schema 不一致を検出して自動リトライする。\n\u002F\u002F status は worker では最大 merge-ready（self-merge しないため merged は現れない）。\nconst WORKER_SCHEMA = {\n  type: 'object',\n  required: ['target', 'status', 'final_head_state'],\n  properties: {\n    target: { type: 'string' },                    \u002F\u002F \"#N\"\n    title: { type: 'string' },\n    branch: { type: 'string' },\n    pr_url: { type: 'string' },\n    pr_number: { type: 'number' },\n    status: { enum: ['merge-ready', 'failed'] },    \u002F\u002F worker は self-merge しない\n    review: { type: 'object' },                     \u002F\u002F { mode, axes_applied, by_axis, total, iterations }\n    cross_cutting_gaps: { type: 'array', items: { type: 'string' } },\n    final_head_state: { type: 'object' },           \u002F\u002F { symbolic_ref, rev_parse_HEAD, status_short }\n    error: { type: 'string' },\n  },\n}\n\n\u002F\u002F worker prompt。Agent tool 方式「subagent dispatch」節の制約と同一(runtime の worktree 隔離は\n\u002F\u002F cleanup を肩代わりするが worker の git 操作自体は防がないため制約は省略不可)。\nconst workerPrompt = (target) => [\n  `.agents\u002Fskills\u002Fdrive\u002FSKILL.md を Read し、target ${target} について単一モード Phase 1-3 を実行せよ。`,\n  '- Phase 4（マージ）は実行しない。merge-ready で停止し gh pr merge を一切呼ばない（self-merge 禁止）。',\n  '- main \u002F 親 ref への書き込み禁止: git checkout main \u002F switch main \u002F symbolic-ref HEAD refs\u002Fheads\u002Fmain \u002F',\n  '  update-ref refs\u002Fheads\u002Fmain \u002F reset --hard origin\u002Fmain（main を指す状態で）\u002F branch -m \u002F push origin main。',\n  '- Edit\u002FWrite の file_path は自 worktree path（.claude\u002Fworktrees\u002Fagent-\u003Cid>\u002F）配下の絶対パス限定。まず pwd で確認。',\n  '- 依存元 wave がある target は依存元 PR の headRefName をベースに stacked PR を作る。',\n  '- 戻り値は WORKER_SCHEMA の JSON（status は最大 merge-ready、final_head_state \u002F cross_cutting_gaps 含む）。',\n].join('\\n')\n\n\u002F\u002F args は drive-plan.mjs --json の出力そのもの（会話側で Phase 0 に実行して渡す）:\n\u002F\u002F   { waves: string[][], deps: { \"#N\": string[] }, concurrency, review, options: { merge }, ... }\n\u002F\u002F waves は target 文字列の二次元配列、deps は target → 依存 target[] の map（canonical と同形）。\nconst results = []\nconst failed = new Set()\n\nfor (const [i, wave] of args.waves.entries()) {\n  \u002F\u002F 依存元が failed の target は dispatch せず skipped（canonical の失敗 semantics）。deps は\n  \u002F\u002F drive-plan.mjs の deps map をそのまま参照する（wave 要素に依存情報を再掲しない）。\n  const runnable = wave.filter((t) => !(args.deps[t] ?? []).some((d) => failed.has(d)))\n  for (const t of wave) {\n    if (runnable.includes(t)) continue\n    const upstream = (args.deps[t] ?? []).filter((d) => failed.has(d))\n    results.push({ target: t, status: 'skipped', error: `upstream failed: ${upstream.join(',')}` })\n    log(`${t} skipped (upstream failed: ${upstream.join(',')})`)\n  }\n\n  \u002F\u002F 同一 wave 内の独立 worker は parallel() で並列（バリア = wave 完了）。wave 列の for-await が\n  \u002F\u002F 依存バリア。pipeline() は stage 間バリアがないため依存 wave には使わない（意図的に parallel）。\n  \u002F\u002F runtime が concurrent cap（最大 16）を管理。--concurrency がそれより小さければ、会話側で\n  \u002F\u002F runnable を args.concurrency 件ずつのスライスに整形して直列に流す。\n  const waveResults = await parallel(\n    runnable.map((t) => () =>\n      agent(workerPrompt(t), {\n        label: t,\n        phase: `Wave ${i + 1}`,\n        isolation: 'worktree',\n        schema: WORKER_SCHEMA,\n      }),\n    ),\n  )\n\n  for (const r of waveResults) {\n    if (!r) continue\n    results.push(r)\n    if (r.status === 'failed') failed.add(r.target)\n    log(`${r.target} → ${r.pr_url ?? '-'} (${r.status})`)\n  }\n}\nreturn { results }\n```\n\nThe `workerPrompt(target)` in the script must always include the following (the skeleton is already embedded in the script above; identical constraints to the Agent tool method's \"subagent dispatch\". The runtime's worktree isolation takes care of cleanup, but doesn't prevent the worker's git operations themselves, so the prompt constraints can't be omitted):\n\n- Instructions to Read the canonical SKILL.md and run single-mode Phase 1-3 (**do not run Phase 4 merge; stop at `merge-ready`**)\n- A list of commands prohibited for writing to main \u002F the parent-side ref\n- The Edit \u002F Write tool's `file_path` constraint (limited to its own worktree path)\n- Merge prohibition (never call `gh pr merge`)\n- Base-branch rule (a target with an upstream wave dependency is stacked on headRefName; since it doesn't self-merge, it's stacked regardless of `--merge`)\n- The return-value JSON contract (`status` capped at `merge-ready` \u002F includes `final_head_state` \u002F `cross_cutting_gaps`; matches the `WORKER_SCHEMA` above)\n\nNotes specific to the Workflow method:\n\n- **`Date.now()` \u002F `Math.random()` \u002F argument-less `new Date()` cannot be used within the script** (the runtime throws, for resume determinism). If a timestamp is needed, pass it via `args`\n- **Observability is handled by the `\u002Fworkflows` UI and `log()`** (`p` to pause \u002F `x` to stop \u002F per-agent token monitoring). The Agent tool method's `gh pr list` 30-second polling is **unnecessary** (the Workflow method doesn't poll for PR detection)\n- The `await` between waves is an **intentional barrier** from the dependency relationship (don't turn it into a pipeline)\n- Workers within the workflow are fixed to `acceptEdits` and inherit the session's allowlist. To avoid permission prompts during a long-running run, confirm before launch that the necessary commands are on the allowlist\n- **Interrupt\u002Fresume is the Workflow's journal resume**: re-entering via `Workflow({scriptPath, resumeFromRunId})` restores unchanged `agent()` calls (completed workers) from the journal\u002Fcache and continues from the incomplete wave. This is the primary mechanism replacing the conventional \"detect a PR via 30-second `gh pr list` polling and re-run manually.\" drive's idempotent resume (detecting an existing PR) remains as a secondary safety net (it also takes effect inside workers)\n- **Phase Final-1 through Final-6 are run on the conversation side after the workflow ends.** Since a worker's worktree contains changes, it's not subject to the runtime's automatic deletion; Final-2 audit \u002F Final-3 reconciliation are performed within this surviving worktree, and cleanup (the Final-5 section) is done last. The worktree path convention (`.claude\u002Fworktrees\u002Fagent-\u003Cid>\u002F`) is the same\n- **The folding for Final-3 reconciliation is also done on the conversation side after the workflow returns** (group the gaps by `source_pr`, and fold them in parallel per PR with `parallel()`; within the same PR it's sequential). Alternatively, a separate small workflow dedicated to reconciliation may be launched\n- The Final-4 merge (parent-centralized, dependency-order merge when `--merge` is specified) and the bulk-merge confirmation when `--merge` is not specified (the AskUserQuestion in the \"After completion\" section) are performed after the workflow returns\n- **The wave checkpoint is inserted on the conversation side** (default ON; omitted when `--no-usage-guard` is specified). Since the workflow script runs deterministically and can't call either Read on the SKILL.md or `ScheduleWakeup`, launch the workflow per wave, and **before** each wave's launch, run the \"usage-guard wiring\" section's checkpoint on the conversation side **headroom-aware** (deriving `--headroom` from `--concurrency`; #141) (if `ok`, launch the next wave's workflow; if over, wait → re-enter via `\u002Fdrive \u003C元の引数>`, restoring completed workers from cache via `resumeFromRunId` and continuing). While the workflow is running (a mid-unit overage in an already-dispatched worker), the #123 PreToolUse hook serves as the ceiling (§Granularity and duplication)\n\n### subagent dispatch (orchestration mode, Agent tool method fallback)\n\nIn orchestration mode, each target is run in parallel with the `Agent` tool:\n\n- **isolation:** `\"worktree\"` (mandatory)\n- **subagent_type:** `general-purpose`\n- **prompt:** since a subagent can't call a slash command, have it Read `.agents\u002Fskills\u002Fdrive\u002FSKILL.md` and instruct it to run the single-mode workflow (Phase 1-3) for target #N. **The worker does not run Phase 4 (merge)** — after review passes, it stops at `merge-ready` and returns JSON without ever calling `gh pr merge` (the same even when `--merge` is specified; the parent centrally manages the merge in Phase Final-4). Have it return the final result as JSON\n- **Prohibition on writing to main \u002F the parent-side ref (must be stated explicitly in the prompt):** the subagent is self-contained within its own worktree branch. The following commands are all **prohibited** — they pollute the parent worktree's `HEAD` \u002F `index` \u002F `refs\u002Fheads\u002Fmain` via the shared git directory ([Issue #66](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F66) \u002F [Issue #89](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F89)). Since the worktree is deleted on the parent side, there's no need to switch back to main:\n  - `git checkout main` \u002F `git switch main` \u002F `git checkout HEAD~` (moving HEAD)\n  - `git symbolic-ref HEAD refs\u002Fheads\u002Fmain` (symbolically switching HEAD to main)\n  - `git update-ref refs\u002Fheads\u002Fmain \u003Csha>` (directly rewriting the main ref)\n  - `git reset --hard origin\u002Fmain` (if run while its own branch points to main, this propagates indirectly to the parent)\n  - `git branch -m \u003Cnew-name>` (breaks the worktree-branch binding)\n  - `git push origin main` \u002F `git push origin HEAD:main`\n- **Require `final_head_state` in the return-value JSON (must be stated explicitly in the prompt):** on completion, the subagent must include the output of its own worktree's `git symbolic-ref HEAD` \u002F `git rev-parse HEAD` \u002F `git status --short` in the `final_head_state` field of the return-value JSON. If `symbolic_ref` is `refs\u002Fheads\u002Fmain` or empty (detached), the parent-side Phase Final-1 raises a warning. This is a countermeasure against the observed discrepancy between the self-reported \"no main checkout\" and reality ([Issue #89](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F89)), making the self-attestation verifiable\n- **The Edit \u002F Write tool's `file_path` constraint (must be stated explicitly in the prompt):** the `file_path` passed to a subagent's Edit \u002F Write tool must always be limited to an absolute path starting with its own worktree path (`.claude\u002Fworktrees\u002Fagent-\u003Cid>\u002F`). A parent worktree path (a path directly under the repo root that doesn't include `.claude\u002Fworktrees\u002F`) must never be passed. The pollution observed in Phase 20 (opshub) occurred **via the absolute path argument of Edit\u002FWrite, not via `cd`**, which is why this constraint is decisive. It's safe to check its own worktree path with `pwd` before execution and then pass it to the tool ([Issue #77](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F77))\n- **Merge prohibition (must be stated explicitly in the prompt):** the subagent never calls `gh pr merge` at all (neither `--auto` nor `--delete-branch`). If it were to self-merge, it would already be merged, cross-cutting couldn't be folded in, and follow-up would remain. In addition, `--delete-branch` fails to delete a branch held by its own worktree (`fatal: '\u003Cbranch>' is already used by worktree at ...`). All merging and cleanup of local branches \u002F worktrees is handled on the parent side in Phase Final (Final-4 merge \u002F Final-5 cleanup) ([Issue #69](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F69) \u002F [#166](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F166))\n- **Out-of-scope impact check (must be stated explicitly in the prompt):** if the subagent adds an enum \u002F field \u002F CLI flag, it greps the whole repo for the corresponding help strings \u002F error messages \u002F samples\u002Fdocs and checks whether they're in sync. If not in sync, it includes the fix in its own PR if feasible. If it clearly exceeds its own scope, it records it in the return-value JSON's `cross_cutting_gaps: string[]` field in the form `\u003Cfile>:\u003Cline> — \u003Csymbol> not synced`, to be aggregated into the parent's Phase Final-2 audit ([Issue #70](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F70))\n- **The base branch when there's an upstream wave dependency:** since the worker doesn't self-merge, the upstream also remains unmerged during the run. So regardless of `--merge`, **it creates a stacked PR based on the upstream PR's headRefName** (the parent reassigns the downstream's base to main when merging in dependency order in Phase Final-4)\n- **Parallel launch:** independent subagents within the same wave are launched in parallel via **multiple tool calls in a single message**\n- **Concurrency:** `min(4, tasks in wave)`, overridable with `--concurrency N`; exceeding 8 only warns\n- **When the number of tasks in a wave exceeds the concurrency level:** wait for a free slot via a semaphore approach (wait for a previously launched subagent to complete before launching the next)\n\n### Observability and interrupt\u002Fresume\n\nWhen Phase 0 completes (before launching the Workflow, on the conversation side), display the wave configuration and target list. Output the aggregate report in Phase Final. The mechanisms for progress observation and interrupt\u002Fresume differ by method:\n\n**Workflow method (canonical):**\n\n- Progress is handled by each worker's single-line `log()` output and the `\u002Fworkflows` UI (`p` to pause \u002F `x` to stop \u002F per-agent token monitoring). **No `gh pr list` polling is done**\n- Interrupt\u002Fresume is the **Workflow's journal resume**: re-entering via `Workflow({scriptPath, resumeFromRunId})` restores completed workers (unchanged `agent()` calls) from the journal\u002Fcache and continues from the incomplete wave. This replaces the conventional \"poll `gh pr list` every 30 seconds from the wave-launch time and resume via PR detection\"\n- State finalization has the worker return-value JSON (`schema`-validated) as the SSOT\n\n**Agent tool method (fallback):**\n\n- Since the `Agent` tool returns only the final result, streaming intermediate reports aren't possible. The parent records the wave-launch time `\u003CT>` in ISO 8601 and polls `gh pr list --author @me --state open --search \"created:>=\u003CT>\" --json number,url,headRefName,title` at 30-second intervals. It detects new PRs from the diff against known PRs and displays the URL immediately\n- Interrupt\u002Fresume is manual re-run (drive's idempotent resume detects the existing PR \u002F branch and continues from Phase 3)\n\n### Phase Final-1: parent worktree consistency check\n\nA fail-safe for the case where a subagent pollutes the parent's `HEAD` \u002F `index` \u002F `refs\u002Fheads\u002Fmain` via the shared git directory (originating from [Issue #66](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F66) \u002F [Issue #77](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F77) \u002F [Issue #89](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F89)). **For the execution details of the 7 detection axes (+ cross-checking the return value's `final_head_state`) and the recovery sequence, see the \"7 contamination-detection axes\" and \"Recovery sequence\" sections of [`worktree-safety.claude-code.md`](worktree-safety.claude-code.md).** If any of them don't match, output a warning + recovery steps at the end of the aggregate report.\n\n### Phase Final-2: cross-cutting audit (pre-merge, parallel within worker worktrees)\n\nFollows the detection content of the canonical's (`.agents\u002Fskills\u002Fdrive\u002FSKILL.md`) Phase Final-2 (worker-report aggregation \u002F enum-flag sync \u002F stale wording \u002F lockfile drift \u002F docs-code). Claude Code-specific execution:\n\n- Run grep within each worker's worktree (`.claude\u002Fworktrees\u002Fagent-\u003Cid>\u002F`, which persists until Final-5). Fetch the PR-specific diff with `gh pr diff \u003CN>` and `rg` the extracted symbols within that worktree\n- Run **in parallel per PR** (with the Agent tool method, multiple tool calls in a single message; with the Workflow method, `parallel()` on the conversation side after return). Attribute each gap to `source_pr` and pass it to Final-3\n\n### Phase Final-3: reconciliation (folding into the originating PR, parallel per PR)\n\nFollowing the canonical's Phase Final-3, group the gaps by `source_pr` and fix\u002Fpush in the originating PR's worktree. Claude Code-specific execution:\n\n- In the worker worktree (`.claude\u002Fworktrees\u002Fagent-\u003Cid>\u002F`) corresponding to each gap's `source_pr`, Edit the target file (`file_path` limited to its own worktree path) → lint → commit (`fix(sync): ...`) → `git push`\n- **Parallel per PR** (no collision, since each uses a separate worktree; multiple tool calls for the Agent tool method, `parallel(gaps.groupBy(pr))` for the Workflow method). **Multiple gaps within the same PR are sequential** (they share the same worktree)\n- No full review loop is run (lint pass only). A gap where folding conflicts \u002F that spans multiple PRs falls back to a dedicated reconciliation PR, which is merged at the tail of Phase Final-4 with main as the base after all content PRs have merged (see canonical Final-3). A folding failure is left as a warning via fail-soft\n\n### Phase Final-4: dependency-order merge (centralized by the parent)\n\nFollowing the canonical's Phase Final-4, the parent merges in topological order when `--merge` is specified. Claude Code-specific notes:\n\n- **`POLICY_GUARD_PROCEED=merge gh pr merge --squash` does not add `--delete-branch`** (since the worker worktree still holds that branch and remains, deleting the local branch would fail due to the worktree lock. Deletion of the branch \u002F worktree is consolidated into Final-5 cleanup). `POLICY_GUARD_PROCEED=merge` conveys `--merge`'s proceed override to the PreToolUse `policy-hook.mjs` (wired via `hooks add policy`), avoiding a deny stemming from gate=`ask` (canonical's \"Merge and the autonomy policy\" \u002F [#195](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F195))\n- If a phantom conflict appears after reassigning the downstream PR's base (`gh pr edit \u003C下流> --base main`), run `git rebase origin\u002Fmain` → `git push --force-with-lease` within the downstream's worktree (limited to its own worktree branch; the parent ref is left untouched) before merging the next one\n- The parent worktree's HEAD \u002F main ref is not touched. Since the merge goes through the `gh` API (a remote operation), the parent's local git state proceeds unchanged\n\n### Phase Final-5: subagent worktree cleanup\n\nRuns after Final-4's merge. The per-status cleanup policy (`merged` is deleted \u002F `merge-ready` and `failed` are left in place) follows the canonical's Phase Final-5. **For the Claude Code worktree-mechanism-specific execution steps (avoiding cwd loss via a subshell, releasing the `-f -f` lock, checking for leftover `worktree-agent-*` synthetic branches), see the \"Cleanup execution steps\" section of [`worktree-safety.claude-code.md`](worktree-safety.claude-code.md)** (originating from [Issue #69](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F69) \u002F [Issue #90](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F90)). If anything other than `merged` is left over, or cleanup itself fails, output a list of leftovers and manual cleanup steps as a warning at the end of the aggregate report.\n\n### On interruption\n\nIf interrupted at any phase, confirm the next action with AskUserQuestion:\n\n- **「エラーを修正して再開する」** → resume from the interrupted phase\n- **「中断する」** → end\n\nIn orchestration mode, if only some tasks fail, after outputting the Phase Final report, confirm the resume targets with AskUserQuestion.\n\n### After completion\n\n#### Single mode\n\n1. **When `--merge` is specified:** run the merge following the Phase 4 procedure, report the result, and end\n2. **When `--merge` is not specified:** call AskUserQuestion (don't set the `answers` parameter)\n   - **「PR をマージする」** → run the merge with `POLICY_GUARD_PROCEED=merge gh pr merge --squash --delete-branch` and report the result (since AskUserQuestion's explicit approval satisfies the `ask` gate, `POLICY_GUARD_PROCEED=merge` is prefixed so it passes through the PreToolUse `policy-hook.mjs`; see the canonical's \"Merge and the autonomy policy\")\n   - **「追加の変更を行う」** → end\n\n#### Orchestration mode\n\nPhase Final runs Final-1 (consistency) → Final-2 (audit) → Final-3 (reconciliation), regardless of whether `--merge` is present (to finalize the PRs gap-free). The only branch point is the Final-4 merge:\n\n1. **When `--merge` is specified:** the parent merges in dependency order in Phase Final-4, followed by Final-5 cleanup (cleaning up merged workers) → outputting the Final-6 aggregate report, and ending\n2. **When `--merge` is not specified:** after completing through Final-3, call AskUserQuestion (don't set the `answers` parameter)\n   - **「全 PR を一括マージする」** → run Phase Final-4's dependency-order merge, followed by Final-5 cleanup → output the Final-6 report\n   - **「個別に対応する」** → output the Final-6 report and end. `merge-ready` worktrees remain left in place. The user cleans them up after merging, either via `\u002Fhealth` area #7 or manually\n","# drive\n\nRead `.agents\u002Fskills\u002Fdrive\u002FSKILL.md` and follow its workflow steps.\n\n**Important:** for each phase, Read the corresponding skill's SKILL.md and execute **only the workflow steps**. **Ignore entirely** the \"next action suggestions\" section and the \"completion report\" section within the SKILL.md you read. Transitions between phases are controlled by this skill.\n\n## Claude Code-specific additions\n\n### Input parsing\n\nParse `$ARGUMENTS` and identify the target list (Issue\u002FPR\u002Finstruction), dependency notation, and options (`--merge`, `--concurrency N`, `--review=\u003Cmode>`, `--no-usage-guard`). Deterministic expansion, DAG\u002Fwave construction, and mode branching are delegated to `drive-plan.mjs` (`~\u002F.claude\u002Fskills\u002Fdrive\u002Fdrive-plan.mjs`; for dogfooding, `\u003Crepo>\u002F.claude\u002Fskills\u002Fdrive\u002Fdrive-plan.mjs`), the same as the canonical, and aggregate-report formatting is delegated to `drive-report.mjs`.\n\n- 1 target with no dependency notation (`->`) → single mode\n- 2 or more targets, or dependency notation present → orchestration mode\n\nHandling of `--review`:\n\n- Default is `quick`\n- Single mode: accepts all of `quick` \u002F `final-deep` \u002F `deep`\n- Orchestration mode: forces `--review=quick`; if `final-deep` \u002F `deep` is specified, shows a warning and falls back to `quick` (cost management)\n\nHandling of usage-guard:\n\n- **Enabled by default (opt-out)**. A plain drive with no checkpoints inserted runs only when `--no-usage-guard` is explicitly added.\n- If `--no-usage-guard` is not specified, the usage-guard engine is called at the checkpoints described later in \"usage-guard wiring (default ON, disabled via `--no-usage-guard`)\"; on Usage Limit overage, it waits until the budget recovers before re-entering itself.\n- `--usage-guard` is accepted as a backward-compatible **deprecated no-op alias** (it doesn't need to be explicit since it's ON by default; behavior is identical to the default). It is never force-added to the continuation command.\n- **The original argument list is saved** at parse time (used to assemble the continuation command `\u002Fdrive \u003C元の引数>` and the resume line in the failure-time report `再開: \u002Fdrive \u003C元の引数>` — canonical's Phase 5 \u002F Phase Final-6, only when there's a leftover `failed` \u002F `merge-ready` \u002F `skipped` —). `--no-usage-guard` is included in what's saved, and carried over to the continuation command, only if the user specified it. `--usage-guard` is a no-op alias, so it's neither saved nor added.\n\n### Autonomous execution\n\nAskUserQuestion is not used at all — including for plan approval — up through the merge step (or merge confirmation) (fully autonomous execution).\n\n### usage-guard wiring (default ON, disabled via `--no-usage-guard`)\n\n**Enabled by default.** Pauses work before the Claude Code Usage Limit (5-hour = Current \u002F weekly = Weekly) reaches 100%, and automatically resumes once the budget recovers. **Only when `--no-usage-guard` is specified does this section's processing not run at all, leaving drive's core behavior unchanged** (since pause\u002Fresume is Claude-specific, the wiring is confined to this overlay; precedent: `review --deep`). `--usage-guard` is accepted as a deprecated no-op alias, but since it's enabled by default, behavior doesn't change.\n\n> **Claude-only**: the usage-guard engine depends on the OAuth usage-rate endpoint and `ScheduleWakeup`, so it only works on Claude Code (the `usage-guard` skill gated by `adapters: claude-code` = #121). The base SKILL.md is ON by default, but since this overlay isn't included in the build output for other adapters (codex\u002Fgemini\u002Fcopilot), it effectively remains a no-op there.\n\n#### Graceful degrade (skill absent)\n\nSince it's ON by default, drive is **not stopped with an error** even in an environment where the usage-guard skill \u002F `usage-check.mjs` **doesn't exist** (e.g., `~\u002F.claude\u002Fskills\u002Fusage-guard\u002F` not installed). At the start of each checkpoint, check for the existence of the `usage-guard` skill (`.claude\u002Fskills\u002Fusage-guard\u002FSKILL.md`; in user-scope, `~\u002F.claude\u002Fskills\u002Fusage-guard\u002FSKILL.md`), and **if its absence is detected, emit a one-line warning** (e.g., \"⚠️ usage-guard degraded: skill not installed, proceeding normally without monitoring\") **and proceed normally as-is** (treated as fail-open — subsequent checkpoints are also skipped). This is a mandatory requirement of being ON by default: the guard's own absence must never hard-stop drive.\n\n#### checkpoint trigger points\n\nWhen `--no-usage-guard` is not specified (= default ON), usage-guard is called only at the following **entry points to a resumable unit**:\n\n| Mode | checkpoint |\n|---|---|\n| Single mode | **before each target's Phase 1 (implement) begins** |\n| Single mode | **before each review-loop iteration** (before each pass in Phase 3 begins) |\n| Orchestration | **before each wave begins** (at the start of the wave loop in Phase 1..N) |\n| Orchestration | **before each worker dispatch** (immediately before launching a worker within the same wave) |\n\n**Checkpoints are always placed at boundaries where re-entry can happen cleanly.** It **does not pause** mid-implement (partway through implementation, before a PR exists), partway through a review pass, or partway through a commit\u002Fpush — pausing there risks losing track of progress on re-entry. Since drive has idempotent resume (detecting an existing PR and resuming from Phase 3), any of the boundaries above can safely resume from where they left off on re-run.\n\n#### Steps at a checkpoint\n\nAt each checkpoint, run the following:\n\n1. Read the `usage-guard` engine (`.claude\u002Fskills\u002Fusage-guard\u002FSKILL.md`; in user-scope, `~\u002F.claude\u002Fskills\u002Fusage-guard\u002FSKILL.md`) and run its \"lightweight wait-loop\" (= run `usage-check.mjs` in the same directory via Bash to get JSON).\n   - **At the wave \u002F worker-dispatch checkpoint (orchestration), gate headroom-aware (#141)**: wave dispatch definitively launches **N uninterruptible workers**, and they consume budget while running. Judging by the current value alone can't account for the projected consumption of a whole wave, and the threshold can be overshot mid-wave (observed in practice: `five_hour` 86% → 98% after 1 wave, with 3-worker concurrency). To prevent this, the dispatch checkpoint passes `usage-check.mjs --headroom \u003Cpct>` and gates on the **projected post-dispatch value** (`util + reserve(N) >= threshold`). `reserve(N)` is a reservation proportional to the concurrency level `N` (`--concurrency`, default `min(4, tasks in wave)`). **A rough guideline is `reserve = N × per_worker_pct`** (`per_worker_pct` is the projected consumption per heavy worker; take the observed `86→98 \u002F 3-worker ≈ 4pt\u002Fworker` as the initial value, overridable via the `USAGE_GUARD_DISPATCH_HEADROOM` env var). Example: `concurrency=3`, `per_worker≈4pt` → `--headroom 12` → pause before dispatch if `threshold(95) − 12 = 83%` is exceeded. The larger `--concurrency` is, the larger the reserve grows.\n   - **The single-mode Phase 1 \u002F review-loop checkpoint doesn't pass headroom** (= default 0, gating on the current value, as before). Since the consumption of 1 unit can be absorbed at an interruptible boundary, no reserve is needed.\n2. `ok: true` (both budgets are below threshold; at the dispatch checkpoint, `util + reserve` is below threshold) → **proceed normally**. Move straight on to the next phase \u002F wave \u002F worker dispatch.\n3. `ok: false` (either budget exceeds the threshold) → defer to usage-guard's wait-loop. A post-reset buffer (`resume_buffer_seconds`, default +300 seconds) is folded into `wait_seconds`, and the wait extends to `resets_at + buffer` (avoiding a re-bounce from re-entering right at the reset boundary). **Execute the engine's `resume_plan` (#212) rather than re-deriving the trigger by hand**: `usage-check.mjs` emits `resume_plan { trigger, wait_seconds, fire_at }`, and orchestration checkpoints pass `--context orchestration` so the plan prefers a durable one-shot (mapping in usage-guard SKILL.md §\"Resume plan\"). The `trigger` cases:\n   - `schedule-wakeup` (in-session, wait ≤1h) → set up a heartbeat with `ScheduleWakeup(min(wait_seconds, 3600))` and **wait** (no re-entry and no budget consumption while waiting). If `wait_seconds` exceeds 3600, re-check in multiple installments.\n   - `cron-oneshot` (non-`\u002Floop` orchestration, wait >1h, needing restart resilience) → set a `CronCreate` (`recurring: false`, durable) to **`fire_at`** (`= resets_at + resume_buffer_seconds`), and re-submit the continuation command when it fires (a single wall-clock shot, restart-resilient; the one-shot auto-deletes after firing). Since this being ON by default makes this path (>1h, non-`\u002Floop`) easy to hit, this is preferred over `ScheduleWakeup`. See usage-guard SKILL.md §Lightweight wait-loop, \"Choosing the resume trigger\", for details.\n   - `cron-routine` (durable, survives a 100% hard-interrupt — #213) → arm a **cloud Routine** at `fire_at`. See \"Durable pre-arm\" below; validate `firesAfterReset(plan, resets_at)` first, and fall back to `cron-oneshot` + a warning where `\u002Fschedule` is unavailable.\n   - **When a reflection lag is suspected (`suspected_reflection_lag: true`), don't set a long-duration CronCreate at the boundary — instead re-check with `ScheduleWakeup` at a short interval (`wait_seconds` ≈ 180 seconds)** (this catches a false 100% caused by the residual image of the prior window right after the boundary, once recovery is confirmed, avoiding a false negative from a ~5h stall; see usage-guard SKILL.md §Behavior: reflection-lag detection).\n   - On waking, self-re-enter via the continuation command **`\u002Fdrive \u003C元の引数>`** (since it's ON by default, `--usage-guard` is never force-added; `--no-usage-guard` is carried over only if the user specified it — though since this section doesn't run at all when `--no-usage-guard` is set, the actual continuation command can simply pass the original arguments as-is). drive's idempotent resume detects the existing PR \u002F branch \u002F completed workers and **resumes from where it left off** (no duplicate side effects, even across a wait).\n   - Repeat steps 3–4 until `usage-check.mjs` returns `ok: true`.\n\n> Pass the **original argument list** as-is to the continuation command (since it's ON by default, adding `--usage-guard` is unnecessary — the guard keeps taking effect by default after resume too).\n\n#### Durable pre-arm (hard-interrupt resilience, #213\u002F#217)\n\nA reactive pause (steps above) keeps the session alive so an **in-session** trigger (`ScheduleWakeup` \u002F a session-scoped `CronCreate`) can fire. But if the boundary checkpoint is bypassed and a worker burns all the way to **100%**, the session **hard-interrupts** and those in-session triggers die with it — the exact \"stopped and never resumed\" failure. Only a **cloud Routine** (scheduled deployment) survives a hard-interrupt.\n\nFor orchestration \u002F long runs with hard-interrupt risk, **pre-arm a durable resume at run start** (not reactively):\n\n1. Before launching the first wave, run `usage-check.mjs --context durable` to obtain a `resume_plan` with `trigger: \"cron-routine\"` and `fire_at`.\n2. **Assert `firesAfterReset(plan, resets_at)`** (a Routine firing at\u002Fbefore the reset is rejected with `session_rate_limited_error`; `fire_at = resets_at + buffer` already satisfies this — the guard catches a `resume_buffer=0` \u002F clock-skew edge).\n3. Arm a **cloud Routine** at `fire_at` whose prompt is the continuation command `\u002Fdrive \u003C元の引数>` (idempotent — drive resumes from the existing PR\u002Fbranch\u002Fcached workers, so a spurious fire is a harmless no-op).\n4. On a clean finish (limit never hit), the one-shot Routine either no-ops on its idempotent continuation or is cancelled.\n5. **Fallback**: where the host `\u002Fschedule` (Routines) is unavailable, fall back to the in-session `cron-oneshot` path + a degradation warning — a durable path that cannot be armed must not silently drop the resume.\n\nThis composes with the two existing layers (headroom-aware boundary pause + the `#123` PreToolUse ceiling): the pre-armed Routine is the **last-resort net** that recovers even a genuine hard-interrupt.\n\n#### Granularity and duplication (two-layer defense against in-wave overshoot, #141)\n\nOrchestration pauses at the granularity of **wave boundaries \u002F worker-dispatch boundaries**. There's a structural failure mode here:\n\n- **Failure mode (in-wave overshoot)**: even if the boundary checkpoint dispatches with `ok:true`, the N launched workers **consume budget while running**. Since the boundary checkpoint has no effect while things are running, the threshold can be crossed and 100% reached mid-wave. `ok:false` is only **detected after the fact** at the next boundary, and can't prevent overshoot within that wave (observed in practice: 86% pre-dispatch, threshold 95 → 3-worker concurrency → 98% while running). **Lowering the threshold is a stopgap that can't account for concurrency and is not a substitute.**\n\nThis is closed off with a **two-layer defense**:\n\n1. **A resumable pause at the boundary (headroom-aware, preventive)**: at the wave \u002F worker-dispatch checkpoint, pass `usage-check.mjs --headroom \u003Cpct>` (with `reserve(N)` computed from `--concurrency`) and gate on the **projected post-dispatch value**, stopping the dispatch itself preemptively (step 1 of \"Steps at a checkpoint\" above). On a headroom trip, the wait is until the budget edge + buffer (headroom recovers when the budget resets).\n2. **The mid-unit ceiling (#123 PreToolUse hook, a reliable ceiling)**: a mid-unit overage in an already-launched, running worker can't be stopped at a boundary. The #123 hook — which **takes effect before every tool call and also reaches inside subagents** — is the only reliable ceiling. In environments running `\u002Fdrive`'s wave parallelism, it's **recommended to wire up the `matcher:\"*\"` hook by default** (#141). Previously, due to the risk of the **pre-#139** hook hard-stopping on a transient outlier, it remained only a \"recommended addition,\" but since **#139 (file kill-switch \u002F reflection-lag ALLOW \u002F debounce \u002F spike rejection) resolved the hard-stop risk**, wiring it by default has become safe. In the unlikely case of a false deny, it can be released immediately with **`touch ~\u002F.claude\u002Fusage-guard\u002FDISABLE`** (usage-guard SKILL.md §Disabling). See usage-guard SKILL.md §Enabling the PreToolUse hook for wiring steps.\n\n> The boundary pause (headroom-aware) and the mid-unit hook are **each insufficient on their own**. headroom is the \"stop dispatch preemptively\" prevention; the hook is the \"reliable ceiling during execution.\" Only when both are in place is overshoot practically closed off.\n\n- The prompt itself passed to the worker (subagent) can remain unchanged. Since the worker runs single mode, **the parent inserting a headroom-aware checkpoint before worker dispatch (ON by default)** is what provides wave-granularity budget handling.\n\n#### fail-open (surfacing degradation)\n\nIf usage-check's signal acquisition fails completely (both the endpoint → JSONL fallback fail), usage-guard returns `ok: true` (fail-open). drive proceeds normally as-is — **a bug in the guard itself must never hard-stop drive**.\n\nHowever, fail-open means the **guard is effectively OFF**. When the `source` of the JSON obtained at a checkpoint is anything other than `endpoint` \u002F `cache` (especially `fail-open`), the drive caller **leaves the degradation explicitly in the report** (e.g., \"⚠️ usage-guard degraded: source=fail-open, not actually monitoring\"). See usage-guard SKILL.md §Environment requirements for the causes of the endpoint path being unusable (api.anthropic.com egress \u002F permission to read `~\u002F.claude\u002F.credentials.json`) and how to recover. The PreToolUse hook on a running worker likewise emits a degradation warning to stderr.\n\n### Choosing the orchestration execution mechanism\n\nFor orchestration worker parallel execution, **the Workflow method is canonical (default)**. It rides natively on the harness via Claude Code's Dynamic Workflows (a deterministic script + journal resume + parallel `agent()` launches), delegating wave execution, worker distribution, progress observation, and interrupt\u002Fresume to the runtime ([ADR-0028](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fhandbook\u002Fblob\u002Fmain\u002Fadr\u002F0028-skills-architecture-engine-judgment-policy-catalog.md) R2). It falls back to the conventional Agent tool method (the \"subagent dispatch\" section) **only in environments where the Workflow tool is unavailable** (Dynamic Workflows disabled — `disableWorkflows` — \u002F an older version).\n\n| | Workflow method (canonical) | Agent tool method (fallback) |\n|---|---|---|\n| Concurrency control | runtime manages the cap (max 16) and queueing | manual semaphore |\n| worktree isolation | `agent({ isolation: 'worktree' })` | `Agent({ isolation: \"worktree\" })` |\n| Return-value validation | structured validation via `schema` (mismatches auto-retry) | parent parses free-form JSON |\n| Progress monitoring | `\u002Fworkflows` UI + `log()` | `gh pr list` 30-second polling |\n| Interrupt\u002Fresume | journal resume (`resumeFromRunId`; completed workers restored from cache) | manual re-run (PR detection via drive's idempotent resume) |\n\n### Orchestration via the Workflow method (canonical)\n\nPhase 0 (DAG \u002F wave construction) and the plan display are done **on the conversation side, before launching the Workflow** (since a workflow can't accept mid-run user input, all approval-related steps are placed before\u002Fafter launch). Pass the wave configuration via `args` and assemble a script of the following form:\n\n```js\nexport const meta = {\n  name: 'drive-orchestration',\n  description: 'drive: wave 単位で worker を並列実行し merge-ready PR 群を作る',\n  \u002F\u002F pure literal（args を参照できない）。起動時に drive-plan.mjs の wave 数へ合わせて書く\n  phases: [{ title: 'Wave 1' }, { title: 'Wave 2' }],\n}\n\n\u002F\u002F worker 戻り値 contract。canonical（.agents\u002Fskills\u002Fdrive\u002FSKILL.md）の戻り値 JSON を Schema 化した\n\u002F\u002F もので、フィールドは canonical と 1:1。runtime が schema 不一致を検出して自動リトライする。\n\u002F\u002F status は worker では最大 merge-ready（self-merge しないため merged は現れない）。\nconst WORKER_SCHEMA = {\n  type: 'object',\n  required: ['target', 'status', 'final_head_state'],\n  properties: {\n    target: { type: 'string' },                    \u002F\u002F \"#N\"\n    title: { type: 'string' },\n    branch: { type: 'string' },\n    pr_url: { type: 'string' },\n    pr_number: { type: 'number' },\n    status: { enum: ['merge-ready', 'failed'] },    \u002F\u002F worker は self-merge しない\n    review: { type: 'object' },                     \u002F\u002F { mode, axes_applied, by_axis, total, iterations }\n    cross_cutting_gaps: { type: 'array', items: { type: 'string' } },\n    final_head_state: { type: 'object' },           \u002F\u002F { symbolic_ref, rev_parse_HEAD, status_short }\n    error: { type: 'string' },\n  },\n}\n\n\u002F\u002F worker prompt。Agent tool 方式「subagent dispatch」節の制約と同一(runtime の worktree 隔離は\n\u002F\u002F cleanup を肩代わりするが worker の git 操作自体は防がないため制約は省略不可)。\nconst workerPrompt = (target) => [\n  `.agents\u002Fskills\u002Fdrive\u002FSKILL.md を Read し、target ${target} について単一モード Phase 1-3 を実行せよ。`,\n  '- Phase 4（マージ）は実行しない。merge-ready で停止し gh pr merge を一切呼ばない（self-merge 禁止）。',\n  '- main \u002F 親 ref への書き込み禁止: git checkout main \u002F switch main \u002F symbolic-ref HEAD refs\u002Fheads\u002Fmain \u002F',\n  '  update-ref refs\u002Fheads\u002Fmain \u002F reset --hard origin\u002Fmain（main を指す状態で）\u002F branch -m \u002F push origin main。',\n  '- Edit\u002FWrite の file_path は自 worktree path（.claude\u002Fworktrees\u002Fagent-\u003Cid>\u002F）配下の絶対パス限定。まず pwd で確認。',\n  '- 依存元 wave がある target は依存元 PR の headRefName をベースに stacked PR を作る。',\n  '- 戻り値は WORKER_SCHEMA の JSON（status は最大 merge-ready、final_head_state \u002F cross_cutting_gaps 含む）。',\n].join('\\n')\n\n\u002F\u002F args は drive-plan.mjs --json の出力そのもの（会話側で Phase 0 に実行して渡す）:\n\u002F\u002F   { waves: string[][], deps: { \"#N\": string[] }, concurrency, review, options: { merge }, ... }\n\u002F\u002F waves は target 文字列の二次元配列、deps は target → 依存 target[] の map（canonical と同形）。\nconst results = []\nconst failed = new Set()\n\nfor (const [i, wave] of args.waves.entries()) {\n  \u002F\u002F 依存元が failed の target は dispatch せず skipped（canonical の失敗 semantics）。deps は\n  \u002F\u002F drive-plan.mjs の deps map をそのまま参照する（wave 要素に依存情報を再掲しない）。\n  const runnable = wave.filter((t) => !(args.deps[t] ?? []).some((d) => failed.has(d)))\n  for (const t of wave) {\n    if (runnable.includes(t)) continue\n    const upstream = (args.deps[t] ?? []).filter((d) => failed.has(d))\n    results.push({ target: t, status: 'skipped', error: `upstream failed: ${upstream.join(',')}` })\n    log(`${t} skipped (upstream failed: ${upstream.join(',')})`)\n  }\n\n  \u002F\u002F 同一 wave 内の独立 worker は parallel() で並列（バリア = wave 完了）。wave 列の for-await が\n  \u002F\u002F 依存バリア。pipeline() は stage 間バリアがないため依存 wave には使わない（意図的に parallel）。\n  \u002F\u002F runtime が concurrent cap（最大 16）を管理。--concurrency がそれより小さければ、会話側で\n  \u002F\u002F runnable を args.concurrency 件ずつのスライスに整形して直列に流す。\n  const waveResults = await parallel(\n    runnable.map((t) => () =>\n      agent(workerPrompt(t), {\n        label: t,\n        phase: `Wave ${i + 1}`,\n        isolation: 'worktree',\n        schema: WORKER_SCHEMA,\n      }),\n    ),\n  )\n\n  for (const r of waveResults) {\n    if (!r) continue\n    results.push(r)\n    if (r.status === 'failed') failed.add(r.target)\n    log(`${r.target} → ${r.pr_url ?? '-'} (${r.status})`)\n  }\n}\nreturn { results }\n```\n\nThe `workerPrompt(target)` in the script must always include the following (the skeleton is already embedded in the script above; identical constraints to the Agent tool method's \"subagent dispatch\". The runtime's worktree isolation takes care of cleanup, but doesn't prevent the worker's git operations themselves, so the prompt constraints can't be omitted):\n\n- Instructions to Read the canonical SKILL.md and run single-mode Phase 1-3 (**do not run Phase 4 merge; stop at `merge-ready`**)\n- A list of commands prohibited for writing to main \u002F the parent-side ref\n- The Edit \u002F Write tool's `file_path` constraint (limited to its own worktree path)\n- Merge prohibition (never call `gh pr merge`)\n- Base-branch rule (a target with an upstream wave dependency is stacked on headRefName; since it doesn't self-merge, it's stacked regardless of `--merge`)\n- The return-value JSON contract (`status` capped at `merge-ready` \u002F includes `final_head_state` \u002F `cross_cutting_gaps`; matches the `WORKER_SCHEMA` above)\n\nNotes specific to the Workflow method:\n\n- **`Date.now()` \u002F `Math.random()` \u002F argument-less `new Date()` cannot be used within the script** (the runtime throws, for resume determinism). If a timestamp is needed, pass it via `args`\n- **Observability is handled by the `\u002Fworkflows` UI and `log()`** (`p` to pause \u002F `x` to stop \u002F per-agent token monitoring). The Agent tool method's `gh pr list` 30-second polling is **unnecessary** (the Workflow method doesn't poll for PR detection)\n- The `await` between waves is an **intentional barrier** from the dependency relationship (don't turn it into a pipeline)\n- Workers within the workflow are fixed to `acceptEdits` and inherit the session's allowlist. To avoid permission prompts during a long-running run, confirm before launch that the necessary commands are on the allowlist\n- **Interrupt\u002Fresume is the Workflow's journal resume**: re-entering via `Workflow({scriptPath, resumeFromRunId})` restores unchanged `agent()` calls (completed workers) from the journal\u002Fcache and continues from the incomplete wave. This is the primary mechanism replacing the conventional \"detect a PR via 30-second `gh pr list` polling and re-run manually.\" drive's idempotent resume (detecting an existing PR) remains as a secondary safety net (it also takes effect inside workers)\n- **Phase Final-1 through Final-6 are run on the conversation side after the workflow ends.** Since a worker's worktree contains changes, it's not subject to the runtime's automatic deletion; Final-2 audit \u002F Final-3 reconciliation are performed within this surviving worktree, and cleanup (the Final-5 section) is done last. The worktree path convention (`.claude\u002Fworktrees\u002Fagent-\u003Cid>\u002F`) is the same\n- **The folding for Final-3 reconciliation is also done on the conversation side after the workflow returns** (group the gaps by `source_pr`, and fold them in parallel per PR with `parallel()`; within the same PR it's sequential). Alternatively, a separate small workflow dedicated to reconciliation may be launched\n- The Final-4 merge (parent-centralized, dependency-order merge when `--merge` is specified) and the bulk-merge confirmation when `--merge` is not specified (the AskUserQuestion in the \"After completion\" section) are performed after the workflow returns\n- **The wave checkpoint is inserted on the conversation side** (default ON; omitted when `--no-usage-guard` is specified). Since the workflow script runs deterministically and can't call either Read on the SKILL.md or `ScheduleWakeup`, launch the workflow per wave, and **before** each wave's launch, run the \"usage-guard wiring\" section's checkpoint on the conversation side **headroom-aware** (deriving `--headroom` from `--concurrency`; #141) (if `ok`, launch the next wave's workflow; if over, wait → re-enter via `\u002Fdrive \u003C元の引数>`, restoring completed workers from cache via `resumeFromRunId` and continuing). While the workflow is running (a mid-unit overage in an already-dispatched worker), the #123 PreToolUse hook serves as the ceiling (§Granularity and duplication)\n\n### subagent dispatch (orchestration mode, Agent tool method fallback)\n\nIn orchestration mode, each target is run in parallel with the `Agent` tool:\n\n- **isolation:** `\"worktree\"` (mandatory)\n- **subagent_type:** `general-purpose`\n- **prompt:** since a subagent can't call a slash command, have it Read `.agents\u002Fskills\u002Fdrive\u002FSKILL.md` and instruct it to run the single-mode workflow (Phase 1-3) for target #N. **The worker does not run Phase 4 (merge)** — after review passes, it stops at `merge-ready` and returns JSON without ever calling `gh pr merge` (the same even when `--merge` is specified; the parent centrally manages the merge in Phase Final-4). Have it return the final result as JSON\n- **Prohibition on writing to main \u002F the parent-side ref (must be stated explicitly in the prompt):** the subagent is self-contained within its own worktree branch. The following commands are all **prohibited** — they pollute the parent worktree's `HEAD` \u002F `index` \u002F `refs\u002Fheads\u002Fmain` via the shared git directory ([Issue #66](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F66) \u002F [Issue #89](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F89)). Since the worktree is deleted on the parent side, there's no need to switch back to main:\n  - `git checkout main` \u002F `git switch main` \u002F `git checkout HEAD~` (moving HEAD)\n  - `git symbolic-ref HEAD refs\u002Fheads\u002Fmain` (symbolically switching HEAD to main)\n  - `git update-ref refs\u002Fheads\u002Fmain \u003Csha>` (directly rewriting the main ref)\n  - `git reset --hard origin\u002Fmain` (if run while its own branch points to main, this propagates indirectly to the parent)\n  - `git branch -m \u003Cnew-name>` (breaks the worktree-branch binding)\n  - `git push origin main` \u002F `git push origin HEAD:main`\n- **Require `final_head_state` in the return-value JSON (must be stated explicitly in the prompt):** on completion, the subagent must include the output of its own worktree's `git symbolic-ref HEAD` \u002F `git rev-parse HEAD` \u002F `git status --short` in the `final_head_state` field of the return-value JSON. If `symbolic_ref` is `refs\u002Fheads\u002Fmain` or empty (detached), the parent-side Phase Final-1 raises a warning. This is a countermeasure against the observed discrepancy between the self-reported \"no main checkout\" and reality ([Issue #89](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F89)), making the self-attestation verifiable\n- **The Edit \u002F Write tool's `file_path` constraint (must be stated explicitly in the prompt):** the `file_path` passed to a subagent's Edit \u002F Write tool must always be limited to an absolute path starting with its own worktree path (`.claude\u002Fworktrees\u002Fagent-\u003Cid>\u002F`). A parent worktree path (a path directly under the repo root that doesn't include `.claude\u002Fworktrees\u002F`) must never be passed. The pollution observed in Phase 20 (opshub) occurred **via the absolute path argument of Edit\u002FWrite, not via `cd`**, which is why this constraint is decisive. It's safe to check its own worktree path with `pwd` before execution and then pass it to the tool ([Issue #77](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F77))\n- **Merge prohibition (must be stated explicitly in the prompt):** the subagent never calls `gh pr merge` at all (neither `--auto` nor `--delete-branch`). If it were to self-merge, it would already be merged, cross-cutting couldn't be folded in, and follow-up would remain. In addition, `--delete-branch` fails to delete a branch held by its own worktree (`fatal: '\u003Cbranch>' is already used by worktree at ...`). All merging and cleanup of local branches \u002F worktrees is handled on the parent side in Phase Final (Final-4 merge \u002F Final-5 cleanup) ([Issue #69](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F69) \u002F [#166](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F166))\n- **Out-of-scope impact check (must be stated explicitly in the prompt):** if the subagent adds an enum \u002F field \u002F CLI flag, it greps the whole repo for the corresponding help strings \u002F error messages \u002F samples\u002Fdocs and checks whether they're in sync. If not in sync, it includes the fix in its own PR if feasible. If it clearly exceeds its own scope, it records it in the return-value JSON's `cross_cutting_gaps: string[]` field in the form `\u003Cfile>:\u003Cline> — \u003Csymbol> not synced`, to be aggregated into the parent's Phase Final-2 audit ([Issue #70](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F70))\n- **The base branch when there's an upstream wave dependency:** since the worker doesn't self-merge, the upstream also remains unmerged during the run. So regardless of `--merge`, **it creates a stacked PR based on the upstream PR's headRefName** (the parent reassigns the downstream's base to main when merging in dependency order in Phase Final-4)\n- **Parallel launch:** independent subagents within the same wave are launched in parallel via **multiple tool calls in a single message**\n- **Concurrency:** `min(4, tasks in wave)`, overridable with `--concurrency N`; exceeding 8 only warns\n- **When the number of tasks in a wave exceeds the concurrency level:** wait for a free slot via a semaphore approach (wait for a previously launched subagent to complete before launching the next)\n\n### Observability and interrupt\u002Fresume\n\nWhen Phase 0 completes (before launching the Workflow, on the conversation side), display the wave configuration and target list. Output the aggregate report in Phase Final. The mechanisms for progress observation and interrupt\u002Fresume differ by method:\n\n**Workflow method (canonical):**\n\n- Progress is handled by each worker's single-line `log()` output and the `\u002Fworkflows` UI (`p` to pause \u002F `x` to stop \u002F per-agent token monitoring). **No `gh pr list` polling is done**\n- Interrupt\u002Fresume is the **Workflow's journal resume**: re-entering via `Workflow({scriptPath, resumeFromRunId})` restores completed workers (unchanged `agent()` calls) from the journal\u002Fcache and continues from the incomplete wave. This replaces the conventional \"poll `gh pr list` every 30 seconds from the wave-launch time and resume via PR detection\"\n- State finalization has the worker return-value JSON (`schema`-validated) as the SSOT\n\n**Agent tool method (fallback):**\n\n- Since the `Agent` tool returns only the final result, streaming intermediate reports aren't possible. The parent records the wave-launch time `\u003CT>` in ISO 8601 and polls `gh pr list --author @me --state open --search \"created:>=\u003CT>\" --json number,url,headRefName,title` at 30-second intervals. It detects new PRs from the diff against known PRs and displays the URL immediately\n- Interrupt\u002Fresume is manual re-run (drive's idempotent resume detects the existing PR \u002F branch and continues from Phase 3)\n\n### Phase Final-1: parent worktree consistency check\n\nA fail-safe for the case where a subagent pollutes the parent's `HEAD` \u002F `index` \u002F `refs\u002Fheads\u002Fmain` via the shared git directory (originating from [Issue #66](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F66) \u002F [Issue #77](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F77) \u002F [Issue #89](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F89)). **For the execution details of the 7 detection axes (+ cross-checking the return value's `final_head_state`) and the recovery sequence, see the \"7 contamination-detection axes\" and \"Recovery sequence\" sections of [`worktree-safety.claude-code.md`](worktree-safety.claude-code.md).** If any of them don't match, output a warning + recovery steps at the end of the aggregate report.\n\n### Phase Final-2: cross-cutting audit (pre-merge, parallel within worker worktrees)\n\nFollows the detection content of the canonical's (`.agents\u002Fskills\u002Fdrive\u002FSKILL.md`) Phase Final-2 (worker-report aggregation \u002F enum-flag sync \u002F stale wording \u002F lockfile drift \u002F docs-code). Claude Code-specific execution:\n\n- Run grep within each worker's worktree (`.claude\u002Fworktrees\u002Fagent-\u003Cid>\u002F`, which persists until Final-5). Fetch the PR-specific diff with `gh pr diff \u003CN>` and `rg` the extracted symbols within that worktree\n- Run **in parallel per PR** (with the Agent tool method, multiple tool calls in a single message; with the Workflow method, `parallel()` on the conversation side after return). Attribute each gap to `source_pr` and pass it to Final-3\n\n### Phase Final-3: reconciliation (folding into the originating PR, parallel per PR)\n\nFollowing the canonical's Phase Final-3, group the gaps by `source_pr` and fix\u002Fpush in the originating PR's worktree. Claude Code-specific execution:\n\n- In the worker worktree (`.claude\u002Fworktrees\u002Fagent-\u003Cid>\u002F`) corresponding to each gap's `source_pr`, Edit the target file (`file_path` limited to its own worktree path) → lint → commit (`fix(sync): ...`) → `git push`\n- **Parallel per PR** (no collision, since each uses a separate worktree; multiple tool calls for the Agent tool method, `parallel(gaps.groupBy(pr))` for the Workflow method). **Multiple gaps within the same PR are sequential** (they share the same worktree)\n- No full review loop is run (lint pass only). A gap where folding conflicts \u002F that spans multiple PRs falls back to a dedicated reconciliation PR, which is merged at the tail of Phase Final-4 with main as the base after all content PRs have merged (see canonical Final-3). A folding failure is left as a warning via fail-soft\n\n### Phase Final-4: dependency-order merge (centralized by the parent)\n\nFollowing the canonical's Phase Final-4, the parent merges in topological order when `--merge` is specified. Claude Code-specific notes:\n\n- **`POLICY_GUARD_PROCEED=merge gh pr merge --squash` does not add `--delete-branch`** (since the worker worktree still holds that branch and remains, deleting the local branch would fail due to the worktree lock. Deletion of the branch \u002F worktree is consolidated into Final-5 cleanup). `POLICY_GUARD_PROCEED=merge` conveys `--merge`'s proceed override to the PreToolUse `policy-hook.mjs` (wired via `hooks add policy`), avoiding a deny stemming from gate=`ask` (canonical's \"Merge and the autonomy policy\" \u002F [#195](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F195))\n- If a phantom conflict appears after reassigning the downstream PR's base (`gh pr edit \u003C下流> --base main`), run `git rebase origin\u002Fmain` → `git push --force-with-lease` within the downstream's worktree (limited to its own worktree branch; the parent ref is left untouched) before merging the next one\n- The parent worktree's HEAD \u002F main ref is not touched. Since the merge goes through the `gh` API (a remote operation), the parent's local git state proceeds unchanged\n\n### Phase Final-5: subagent worktree cleanup\n\nRuns after Final-4's merge. The per-status cleanup policy (`merged` is deleted \u002F `merge-ready` and `failed` are left in place) follows the canonical's Phase Final-5. **For the Claude Code worktree-mechanism-specific execution steps (avoiding cwd loss via a subshell, releasing the `-f -f` lock, checking for leftover `worktree-agent-*` synthetic branches), see the \"Cleanup execution steps\" section of [`worktree-safety.claude-code.md`](worktree-safety.claude-code.md)** (originating from [Issue #69](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F69) \u002F [Issue #90](https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fissues\u002F90)). If anything other than `merged` is left over, or cleanup itself fails, output a list of leftovers and manual cleanup steps as a warning at the end of the aggregate report.\n\n### On interruption\n\nIf interrupted at any phase, confirm the next action with AskUserQuestion:\n\n- **「エラーを修正して再開する」** → resume from the interrupted phase\n- **「中断する」** → end\n\nIn orchestration mode, if only some tasks fail, after outputting the Phase Final report, confirm the resume targets with AskUserQuestion.\n\n### After completion\n\n#### Single mode\n\n1. **When `--merge` is specified:** run the merge following the Phase 4 procedure, report the result, and end\n2. **When `--merge` is not specified:** call AskUserQuestion (don't set the `answers` parameter)\n   - **「PR をマージする」** → run the merge with `POLICY_GUARD_PROCEED=merge gh pr merge --squash --delete-branch` and report the result (since AskUserQuestion's explicit approval satisfies the `ask` gate, `POLICY_GUARD_PROCEED=merge` is prefixed so it passes through the PreToolUse `policy-hook.mjs`; see the canonical's \"Merge and the autonomy policy\")\n   - **「追加の変更を行う」** → end\n\n#### Orchestration mode\n\nPhase Final runs Final-1 (consistency) → Final-2 (audit) → Final-3 (reconciliation), regardless of whether `--merge` is present (to finalize the PRs gap-free). The only branch point is the Final-4 merge:\n\n1. **When `--merge` is specified:** the parent merges in dependency order in Phase Final-4, followed by Final-5 cleanup (cleaning up merged workers) → outputting the Final-6 aggregate report, and ending\n2. **When `--merge` is not specified:** after completing through Final-3, call AskUserQuestion (don't set the `answers` parameter)\n   - **「全 PR を一括マージする」** → run Phase Final-4's dependency-order merge, followed by Final-5 cleanup → output the Final-6 report\n   - **「個別に対応する」** → output the Final-6 report and end. `merge-ready` worktrees remain left in place. The user cleans them up after merging, either via `\u002Fhealth` area #7 or manually\n",{"description":7,"allowed-tools":47,"argument-hint":48,"disable-model-invocation":49},"Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, AskUserQuestion, Agent, Workflow","\u003C#N |",true,"main","db212a47efe751fa1c42bd76e61dbfd8328e5b10",".claude\u002Fskills\u002Fdrive","https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills","https:\u002F\u002Fgithub.com\u002Fozzy-labs","2026-07-13 06:49:42",{"source":8,"skillName":5,"commands":57,"prompt":67,"zipAvailable":49},[58,61,64],{"tool":59,"command":60},"npx","npx skills add ozzy-labs\u002Fskills --skill drive",{"tool":62,"command":63},"bunx","bunx skills add ozzy-labs\u002Fskills --skill drive",{"tool":65,"command":66},"pnpm","pnpm dlx skills add ozzy-labs\u002Fskills --skill drive","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdrive\u002FSKILL.md",[69,75,79],{"path":70,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":73,"sourceHtmlUrl":74},"drive-plan.mjs","SCRIPT","脚本",19539,"https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdrive\u002Fdrive-plan.mjs",{"path":76,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":77,"sourceHtmlUrl":78},"drive-report.mjs",12307,"https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdrive\u002Fdrive-report.mjs",{"path":80,"resourceType":81,"resourceTypeDesc":82,"sizeBytes":83,"sourceHtmlUrl":84},"worktree-safety.claude-code.md","REFERENCE","参考文档",9418,"https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdrive\u002Fworktree-safety.claude-code.md",[86,111,137,159,187,209],{"skillNo":87,"name":88,"nameZh":6,"description":89,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":92,"publishedAt":42},"01M71J6R63H4E6ZE6KMDM4CT85","verify","An integrated skill that runs the combined validation of build \u002F typecheck \u002F test \u002F lint in one shot. The `verify.mjs` engine auto-discovers validation commands via a discovery chain (AGENTS.md's 「検証」 section → package.json scripts → justfile\u002FMakefile\u002Flefthook → language heuristics), executes them serially with their source attached, and returns a result summary. If a higher-priority stage produces a hit, only that stage is executed (no crossing stages).","https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fverify\u002FSKILL.md",[],[88,93,94,95,96,97,98,99,100,101,102,103,35,104,105,106,107,108,109,110],"combined","heuristics","chain","repo","discovery","section","lefthook","only","auto","package","stage","one","lint","dry","engine","with","test","typecheck",{"skillNo":112,"name":113,"nameZh":6,"description":114,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":115,"categories":116,"keywords":117,"publishedAt":42},"01M71J6JW7SAY9PDKAWHG3SJCR","usage-guard","Monitors Claude Code's Usage Limit (5-hour = Current \u002F weekly = Weekly), pauses work when it exceeds 95%, and automatically resumes once the reset restores headroom. Bundles an engine form that a caller such as drive Reads at a checkpoint, and a standalone form, `\u002Fusage-guard \"\u003Ccontinuation command>\"`, that guards arbitrary work. Claude-only (depends on the OAuth usage-rate endpoint + ScheduleWakeup).","https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fusage-guard\u002FSKILL.md",[],[118,119,120,121,122,100,123,124,125,126,127,128,129,130,131,132,133,134,135,136],"usage","usage guard","guard","weekly","standalone","guards","when","code","reset","work","command","at","rate","status","endpoint","as","continuation","form","limit",{"skillNo":138,"name":139,"nameZh":6,"description":140,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":141,"categories":142,"keywords":143,"publishedAt":42},"01M71J6FRG119REA1G0S99Q4GZ","topics","Selects GitHub topic candidates by having the `topics.mjs` engine perform constraint validation, popularity measurement, broad+narrow \u002F singular-plural comparison, and hardcoded ozzy-labs conventions, then applies them via `gh repo edit --add-topic` following the policy's `externally-visible` gate (default batch-confirm). Scope is limited to use within ozzy-labs.","https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftopics\u002FSKILL.md",[],[139,144,145,96,146,147,148,149,150,151,152,35,153,154,155,106,107,156,157,158],"measurement","scope","policy","default","true","gh","plural","use","comparison","apply","candidate","batch","candidates","github","via",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":171,"publishedAt":42},"01M71J6DC27P4FDSP10SDT2PSN","skill-observability","Defines the skill observability event contract (event.schema.json) and emit substrate (obs-emit.mjs). The SSOT for the measurement layer of the skill improvement loop. Referenced by other skills and hooks.","https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fskill-observability\u002FSKILL.md",[165,166],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":167,"categoryName":168,"taxonomyType":169,"taxonomyTypeDesc":170},"01JBSEEDCAT000000000000037","律师与法务","PROFESSION","适用职业",[172,173,144,174,175,176,177,178,179,180,181,182,183,184,185,186],"observability","skill observability","improvement","skill improvement","for","event","hooks","contract","schema","loop","false","substrate","json","improvement loop","layer",{"skillNo":188,"name":189,"nameZh":6,"description":190,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":191,"categories":192,"keywords":194,"publishedAt":42},"01M71J6AYECH1J94RAZ49QZ19Y","skill-metrics","Aggregates the local observability event log (~\u002F.agents\u002Fobservability\u002Fevents.jsonl) and presents, read-only, per-skill invocation counts and notable events (fallback \u002F HITL rejection \u002F loop cap reached \u002F abort). Fires on \"show me the skill metrics,\" \"aggregate the observability results,\" \"which skills get used the most?\" Does not send anything.","https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fskill-metrics\u002FSKILL.md",[193],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},[195,196,172,197,198,199,200,201,177,202,203,204,205,148,100,181,206,35,207,208],"skill metrics","metrics","event log","which","show","get","read-only","iso","aggregates","send","local","show me","log","jsonl",{"skillNo":210,"name":211,"nameZh":6,"description":212,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":213,"categories":214,"keywords":215,"publishedAt":42},"01M71J68TD0QFATGW3BBZVCWA2","ship","Runs verification, commit, and PR creation all at once. An integrated pipeline that runs verify (build + type + test + lint) → commit → PR creation in sequence against the changes.","https:\u002F\u002Fgithub.com\u002Fozzy-labs\u002Fskills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fship\u002FSKILL.md",[],[211,216,217,109,218,219,88,40,220,221,129,29,222,223,148,26,35,224,105],"type","verification","changes","pr","build","pipeline","sequence","grep","commit"]