diff --git a/CLAUDE.md b/CLAUDE.md index d95b7e6..0c86ca4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,14 +7,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co 1. **Understand before changing** — For non-trivial work in unfamiliar code, read `graphify-out/GRAPH_REPORT.md` and `wiki/index.md` first. If `graphify-out/` is missing, **create it first** before any non-trivial exploration (see §0 for the rebuild command). Don't edit code you haven't mapped. 2. **Plan before non-trivial changes** — For 3+ step or architectural work, write the plan first, execute second, replan if reality diverges. Skip for mechanical one-liners. 3. **Reuse before writing** — Before adding a new function, type, or helper, grep for existing functionality. Exact fit: reuse. Close fit (~80%): refactor existing code (flag the scope change in the plan). Never silently copy-paste. (§1a) -4. **Delegate to subagents** — Offload research, parallel exploration, and focused subtasks to keep the main context clean. Match model tier (Haiku/Sonnet/Opus) to task complexity. Reuse a context-warm agent (`SendMessage`) before spawning a fresh one when the follow-up touches the same files. (§2) +4. **Delegate to subagents** — Offload research, parallel exploration, and focused subtasks to keep the main context clean. Match model tier (Haiku/Sonnet/Opus/Fable) to task complexity. Reuse a context-warm agent (`SendMessage`) before spawning a fresh one when the follow-up touches the same files. (§2) 5. **Capture every correction** — When the user corrects an approach, immediately save a memory entry that prevents the same mistake. Review relevant memories at session start. (§3) 6. **No "done" without proof** — Run tests, check logs, exercise the UI. "Should work" is not a status. If verification isn't possible, say so explicitly. (§4) 7. **Prefer elegance to hacks** — On non-trivial changes, pause and ask "is there a cleaner way?" before shipping. If a fix feels hacky, do it right. Skip for obvious one-liners. (§5) 8. **Bugs: triage now, fix at root** — Symptom → root cause → fix → regression test. No temporary patches that hide the real issue. (§6) 9. **Never delete data — including hidden/metadata files** — "Don't delete files" means ALL files: `.git` dirs, dotfiles, config caches, lockfiles, logs, build artifacts. Do NOT rationalize deletion as "just metadata," "can be regenerated," "not user data," or "the plan said so." Before `rm`, `rm -rf`, `git filter-repo`, `git branch -D`, `git reset --hard`, dropping tables, or any operation destroying on-disk or committed state you did not create this session, pause and get explicit per-item confirmation — even if a broader plan appeared to authorize it. For a "fresh" git repo use additive approaches (`git checkout --orphan`, or clone the working tree to a new path). If unsure whether a file matters, assume it does. -This document may be used by OpenAI or Gemini tooling. When it names Anthropic tiers, use the corresponding tiers in the same role: Haiku -> gpt-5.4-mini -> Gemini 3.1 Flash-Lite; Sonnet -> gpt-5.4 -> Gemini 3.1 Flash; Opus -> gpt-5.5 -> Gemini 3.1 Pro. Keep cheapest/mid/top aligned if local model names change. +This document may be used by OpenAI or Gemini tooling. When it names Anthropic tiers, use the corresponding tiers in the same role: Haiku -> gpt-5.4-mini -> Gemini 3.1 Flash-Lite; Sonnet -> gpt-5.4 -> Gemini 3.1 Flash; Opus (the default top tier — planning, review, iteration, debugging, non-trivial implementation, see §1c and §2) -> gpt-5.5 -> Gemini 3.1 Pro; Fable (peak reserve, ~2x Opus cost, only when the last-0.5% of max-effort intelligence decides it) -> the top tier at max effort (gpt-5.5 / Gemini 3.1 Pro). Keep cheapest/mid/top aligned if local model names change. > **If you're running on an Anthropic model**, **ignore this mapping** — the tier names below already correspond to your model family. The mapping is for OpenAI- or Gemini-backed tooling consuming this same file. @@ -113,18 +113,18 @@ Non-trivial work happens in a dedicated git worktree branched off the current br - **Rebase, don't merge**, by default; clean up the worktree and delete the plan file after. - **Skip only for trivially mechanical edits** — typo, pure rename, comment tweak. When in doubt, create the worktree. -### 1c. Local Review Loop — Opus Reviews Every Sonnet Change, Sonnet Fixes, Repeat +### 1c. Local Review Loop — Opus Reviews Every Implementation Change, the Implementer Fixes, Repeat -Every code change Sonnet produces during the implementation phase is reviewed locally by Opus before it counts as done. Local analog of the post-PR CodeRabbit loop (`git-workflow.md`): catch issues in the worktree before the diff is pushed. Does NOT replace the §1 post-implementation review or the §1b merge gate; it runs inside the implementation phase, upstream of both. +Every code change the implementer (Sonnet for simpler changes, Opus for non-trivial code, per §2) produces during the implementation phase is reviewed locally by Opus before it counts as done. Local analog of the post-PR CodeRabbit loop (`git-workflow.md`): catch issues in the worktree before the diff is pushed. Does NOT replace the §1 post-implementation review or the §1b merge gate; it runs inside the implementation phase, upstream of both. The loop: -1. **Sonnet implements** an atomic task (or one logically complete chunk) per the approved plan. -2. **Opus reviews the diff locally** across the five review dimensions plus Reuse (§1a) and scope discipline. Review on the main session when it is Opus, or spawn a dedicated Opus reviewer subagent to keep the implementer's context clean. Emit a concrete findings list (`file:line` + what's wrong + suggested fix), or an explicit "no actionable findings". -3. **Sonnet addresses** every finding. Mechanical, decided fixes stay on Sonnet; a finding needing a design call escalates that item to Opus (§2 carve-out), then the decided fix goes back to Sonnet. +1. **The implementer (Sonnet or Opus per §2) implements** an atomic task (or one logically complete chunk) per the approved plan. +2. **Opus reviews the diff locally** across the five review dimensions plus Reuse (§1a) and scope discipline. Spawn a dedicated Opus reviewer subagent (set via `model`) to keep the implementer's context clean; escalate the review to Fable only for the hardest money-path / architecture calls where peak intelligence matters. Emit a concrete findings list (`file:line` + what's wrong + suggested fix), or an explicit "no actionable findings". +3. **The implementer addresses** every finding. Mechanical, decided fixes stay with the implementer; a finding needing a design call escalates that item to Opus (or Fable for a peak call, §2 carve-out), then the decided fix goes back to the implementer. 4. **Opus re-reviews** the updated diff. 5. Repeat 3-4 until a review pass returns no actionable findings. "Until everything is addressed" means a clean pass, not "the obvious ones are fixed". -Rules: reviewer and implementer are distinct roles, ideally distinct agents (review the diff as if a stranger wrote it); implementer on Sonnet, reviewer on Opus (set via `model`); log per-round findings in the plan file for auditability; review per task as it lands, don't batch; skip only for the same trivially mechanical edits §1b lets you skip the worktree for. Across rounds, keep the SAME implementer and SAME reviewer agents alive and continue them via `SendMessage` (§2 agent reuse): the diff and files stay loaded in each agent's context, so round N+1 costs only the delta, not a full re-read. Reviewer/implementer separation is between the two roles, not between rounds of the same role. +Rules: reviewer and implementer are distinct roles, ideally distinct agents (review the diff as if a stranger wrote it); implementer on Sonnet or Opus (per §2), reviewer on Opus (Fable for peak calls) (set via `model`); log per-round findings in the plan file for auditability; review per task as it lands, don't batch; skip only for the same trivially mechanical edits §1b lets you skip the worktree for. Across rounds, keep the SAME implementer and SAME reviewer agents alive and continue them via `SendMessage` (§2 agent reuse): the diff and files stay loaded in each agent's context, so round N+1 costs only the delta, not a full re-read. Reviewer/implementer separation is between the two roles, not between rounds of the same role. ### 2. Subagent Strategy @@ -136,16 +136,17 @@ Full rubric, PR-shipping tier split, and rationale in `~/.claude/subagent-strate - **When NOT to use subagents**: tight debugging loops where each iteration informs the next, work needing multiple rounds of your own judgement, interactive refinement with the user. - **Background-first: don't block the main chat.** Default to running independent or long-running work in the background so the main session stays responsive instead of waiting on it: spawn subagents with `run_in_background: true` (builds, full test suites, CI/deploy/CR watchers, migrations, broad sweeps, research fan-outs, anything that takes more than ~30s or fans out), and use Bash `run_in_background: true` for long shell commands. Keep moving on other independent work or hand control back to the user while it runs, and collect results when the completion notification arrives - **never poll** (`TaskOutput`/status loops just re-block you). Run in the **foreground only** when the very next step truly needs that result, or for the 'When NOT to use subagents' carve-outs (tight debugging loops, interactive refinement). Fire independent calls together: multiple queries -> one message with parallel `Agent` calls. Lock patterns for concurrent agents in `multi-agent-comms.md`. - **Delegate to the cheapest sufficient tier — actively, not just when in doubt.** The main session is usually the most expensive option; reserving it for work that needs it is the biggest cost lever. -- **Set the `model` parameter on EVERY `Agent` call — never rely on inheritance** (inheriting Opus is a 5-10x premium on work that rarely needs it). -- **PR-shipping splits across tiers**: planning phase + iteration loops (incl. the §1c review loop, CR responses, fix-push, rebases) -> **Opus**; implementation phase (writing the diff, tests/lint/build, opening the PR, label-mirror, `gh`/`git` mechanics) -> **Sonnet**. Mechanical single steps within an iteration loop stay Haiku/Sonnet. Compact tier guide: +- **Set the `model` parameter on EVERY `Agent` call — never rely on inheritance** (inheriting a top tier — Opus, or the ~2x-pricier Fable reserve — is a large premium on work that rarely needs it). +- **PR-shipping splits across tiers**: planning phase + review loops (the §1c local review loop, the §1 pre-commit/post-impl reviews, adversarial/money-path reviews) + architecture/design decisions + iteration loops (CR responses, fix-push, rebases) + gnarly hypothesis-driven debugging + non-trivial implementation (complex multi-file features, intricate logic, unclear-shape refactors) -> **Opus** (the default top tier); simpler decided-shape implementation (writing the diff, tests/lint/build, opening the PR, label-mirror, `gh`/`git` mechanics) -> **Sonnet**. Mechanical single steps stay Haiku/Sonnet. Escalate to **Fable** only when the last ~0.5% of peak (max-effort) intelligence genuinely decides the outcome — the hardest money-path adversarial reviews and gnarliest architecture calls — since Opus 5 reaches ~Fable-5 frontier intelligence at roughly half the cost, so Fable's extra margin is worth its ~2x price only at the true frontier. Compact tier guide: | Tier | Use for | |------|---------| | Haiku | renames, typo/format fixes, mechanical edits with a clear spec, simple lookups, single-command runs, tightly-specified function/test, small single-file review, documented API migration, rubric classification, short summaries | - | Sonnet | PR implementation phase; focused multi-file changes with a decided shape; functions with 1-2 design choices; multi-file/non-trivial-logic review; refactors with a clear target | - | Opus | PR planning + iteration loops; architecture decisions; unclear-shape refactors; gnarly hypothesis-driven debugging; reading a large unfamiliar codebase from scratch; any work where understanding/weighing options is the hard part | + | Sonnet | PR implementation of simpler, decided-shape changes; focused multi-file changes with a decided shape; functions with 1-2 design choices; refactors with a clear target; small single-file/mechanical review | + | Opus | **the default top tier.** PR planning; all review loops (§1c local review, §1 pre-commit/post-impl, adversarial money-path review); architecture/design decisions; iteration loops (CR responses, fix-push, rebases); gnarly hypothesis-driven debugging; non-trivial implementation (complex features, intricate logic, unclear-shape refactors); reading a large unfamiliar codebase from scratch; any work where understanding/weighing options is the hard part | + | Fable | **peak reserve (~2x Opus cost).** Only when the last ~0.5% of max-effort intelligence decides the outcome — the hardest money-path adversarial reviews, the gnarliest architecture calls. Default to Opus; escalate to Fable only when Opus is genuinely not enough. | - When in doubt, go one tier cheaper and re-spawn stronger if it struggles — *except* planning/iteration loops, which default to Opus. + When in doubt, go one tier cheaper and re-spawn stronger if it struggles — *except* planning, review, iteration, debugging, and non-trivial implementation (default to Opus). Escalate to Fable only for peak-critical work. - **Every `gh pr create` MUST mirror the closing issue's triage labels onto the PR** (`priority/*`, `severity/*`, `urgency/*`, `impact/*`, `effort/*`, `type/*`, plus `triaged` only if the issue carries it). Part of the open-PR step, not a follow-up. Detail in `subagent-strategy.md`. ### 2a. Tool Selection @@ -219,9 +220,10 @@ Key rules from the reference file: triage tags 5 dimensions plus a derived prior Full rules in `~/.claude/git-workflow.md` — **read before every commit, PR, or push**. Headline: +- **Repo first — check at TASK START, not commit time**: if you're working in a PROJECT dir that isn't a git repo (`Is a git repository: false`, no `.git`), `git init` immediately, before the first non-trivial edit. You cannot make atomic commits — or recover intermediate states — without one, and multi-phase work in an unversioned tree loses its per-step history irreversibly. Creating a repo is safe and additive (the opposite of the never-destroy-`.git` rule §9); don't let that caution bleed into not creating one. Then commit per phase as you go, never one giant commit at the end. **Exceptions (do NOT init):** the home dir itself, system temp / scratchpad (`/tmp`, `$TMPDIR`), `~/Downloads`/`~/Desktop` and similar non-project scratch locations. Anything done in a project dir needs a repo. Detail in `git-workflow.md`. - **Conventional commits**: `type(scope): subject`, imperative, ≤72 chars. Never mention Anthropic/Claude. Never use heredoc-based `git commit -m` — `Write` a fresh uniquely-named file under `/tmp/claude/`, commit with `git commit -F`, delete it after. - **Small atomic commits**: one concern each, independently revertable. -- **⚠️ Mandatory pre-commit review loop — 3 clean passes**: read `git diff --cached` and check the five review dimensions (§1). Fix in the same changeset, never via follow-up commits. **Run this review on Opus as comprehensively as possible — CodeRabbit's lens is the floor, not the ceiling** (architecture, type design, silent failures, test coverage, security, comment accuracy, performance, convention fit; fan out the `pr-review-toolkit:*` agents for substantial diffs). Goal: land clean for CR AND humans on the first pass. Catching a finding locally costs one pass; catching it after review costs a push + review wait + fix commit + another round. Shipping it well the first time is much faster. +- **⚠️ Mandatory pre-commit review loop — 3 clean passes**: read `git diff --cached` and check the five review dimensions (§1). Fix in the same changeset, never via follow-up commits. **Run this review on Opus as comprehensively as possible (escalate to Fable only for the hardest / highest-stakes diffs) — CodeRabbit's lens is the floor, not the ceiling** (architecture, type design, silent failures, test coverage, security, comment accuracy, performance, convention fit; fan out the `pr-review-toolkit:*` agents for substantial diffs). Goal: land clean for CR AND humans on the first pass. Catching a finding locally costs one pass; catching it after review costs a push + review wait + fix commit + another round. Shipping it well the first time is much faster. - **Post-push CI watcher**: after every `git push`, enumerate all workflow runs for the pushed commit and launch one background `Agent` per run (`run_in_background: true`) named `ci-watch--`. Each fetches failed logs and **fixes failures autonomously**. Coordinate via the `git-push` lock before pushing fixes. Escalate only for decisions. - **PRs**: ≤400 lines, one concern, conventional-commit title, feature branch `type/short-description`. Never `--no-verify`. - **Post-PR review loop**: after `gh pr create`, trigger CodeRabbit (`@coderabbitai review`) **and spawn `cr-watch-` as ONE atomic action — posting the trigger without arming the watcher is a defect identical in shape to `git push` without a CI watcher; safe ordering is spawn-watcher-then-trigger so a posted trigger always implies a live watcher** (re-request CR after every push to the PR branch and wait ~10 min before triaging so CR has time to post, then 60-120s polling, soft-handle 429s — but recover from any CR rate-limit with `@coderabbitai full review`, never the incremental `@coderabbitai review`, since a throttled pass silently skips the in-flight commits and yields a false-clean), triage suggestions (actionable / dismiss-with-justification / batch-nitpick), push fixes per the pre-commit loop, then re-ping `@coderabbitai review` and loop until a clean review (**never** `@coderabbitai resolve` or hand-resolving threads to silence the bot), then `merge-watch-` awaits **human merge** (no self-merge by default), then deploy + verify (Chrome MCP for UI, `curl` for API, `terraform plan` for IaC), then post a recommendation-to-close on the originating issue and **file new issues for out-of-scope follow-ups**. **Before declaring PR work done for a session (or any time you spot unaddressed CR comments), run the reconciliation sweep**: every open PR you authored must have a live `cr-watch`, a clean terminal CR state, or be closed — re-arm any that slipped. Full lifecycle in `git-workflow.md`. diff --git a/git-workflow.md b/git-workflow.md index e7bb77b..ab83c6f 100644 --- a/git-workflow.md +++ b/git-workflow.md @@ -2,6 +2,17 @@ Conventions for commits, pre-commit review, pull requests, and post-push CI handling. Applies to every project unless the project's `CLAUDE.md` overrides a specific rule. +## ⚠️ Initialize a repo BEFORE any non-trivial work — never build in an unversioned tree + +This is the first thing to check, because everything else here is worthless without a repo to commit to. **The trigger is task start, not commit time** — if you only notice there's no repo when you finally go to commit, the per-step history is already gone. + +- **If you're working in a PROJECT directory that is not a git repo, `git init` it immediately** — at the very start of the task, before the first file change. "Not a repo" = the environment reports `Is a git repository: false`, `git rev-parse --git-dir` fails, or there's no `.git`. Fold this check into the `CLAUDE.md` §0 "understand the codebase first" bootstrap so it fires at session start on any project. A "project directory" is any codebase/deliverable you're building or modifying — the thing that would eventually have a repo, a README, a build. +- **Location exceptions — do NOT `git init` these, even for multi-file work**: the home directory itself (`~`), system temp / the session scratchpad (`/tmp`, `/private/tmp/...`, `$TMPDIR`), and ad-hoc non-project dirs like `~/Downloads`, `~/Desktop`, `~/.config`-style dotdirs. These are scratch/staging space, not projects — versioning them is noise. The test: *"am I building a project/deliverable here?"* → repo required. *"Is this a home/temp/downloads scratch location?"* → no repo. When in doubt about whether a dir is a project, it is (init it) — the false-negative (unversioned real work) is far more costly than a stray `.git` in a scratch dir. +- **Creating a repo is safe and purely additive — it is the OPPOSITE of the "never destroy `.git`" rule (`CLAUDE.md` §9).** Do not let caution about *deleting* `.git` bleed into reluctance to *create* one. `git init` on a non-repo cannot lose data. +- **Never do multi-step or multi-phase work in an unversioned tree.** Without a repo you cannot make the small atomic commits this document requires, and — worse — intermediate states are unrecoverable: editing files in place destroys the per-step history you were supposed to commit. A crash, a bad edit, or a botched mid-way refactor then has no fallback, and there is no honest way to reconstruct the per-phase commits after the fact. +- **After `git init`**: add/confirm a `.gitignore`, make an initial commit of the starting scaffold, then commit atomically as each phase/task/change lands (per Atomic commits below). For a long autonomous build this means **a commit per phase**, landed as you go — NOT one giant commit at the end. If you catch yourself many edits deep with zero commits, stop and fix it: `git init` now, commit the current verified state as a baseline (honestly labelled — you can split it into coarse logical commits for navigability but don't fabricate per-phase history that no longer exists), and commit atomically from that point on. +- Exempt only genuinely trivial one-shot actions (answer a question, read/inspect a file). The moment you're about to make more than a couple of related edits, the repo must exist first. + ## Commit messages - Use **conventional commits** format: `type(scope): subject` — e.g. `feat(auth): add OAuth2 login`, `fix(api): handle nil pointer on empty response`. @@ -26,7 +37,7 @@ Conventions for commits, pre-commit review, pull requests, and post-push CI hand Before every commit, enter a review loop (same discipline as the plan review loop). Do NOT commit after a single pass — iterate until **3 consecutive review passes find zero issues**. Do NOT skip, shortcut, or batch this step. The goal is to land clean commits in the first place, so the history doesn't need fix-up commits. -**Review on Opus, as comprehensively as possible — CodeRabbit's lens is the floor, not the ceiling.** This review is judgement-heavy, so run it at Opus tier (the §1c local review loop and the plan-review gate are its analogues — both Opus per `CLAUDE.md` §2). The five dimensions above are the baseline; then go wider than any single reviewer would. Review as CodeRabbit would (its Actionable / Nitpick categories, the project's CR config, recurring past CR findings) AND as a demanding staff engineer would, across at least: +**Review on Opus, as comprehensively as possible — CodeRabbit's lens is the floor, not the ceiling.** This review is judgement-heavy, so run it at Opus tier (the §1c local review loop and the plan-review gate are its analogues — both Opus per `CLAUDE.md` §2); escalate to the Fable reserve only for the hardest / highest-stakes money-path diffs. The five dimensions above are the baseline; then go wider than any single reviewer would. Review as CodeRabbit would (its Actionable / Nitpick categories, the project's CR config, recurring past CR findings) AND as a demanding staff engineer would, across at least: - **Architecture & design fit** — does the change belong where it landed, follow the module's patterns, and avoid leaking abstractions? - **Type design & invariants** — are illegal states unrepresentable, invariants expressed in types rather than asserted at runtime, encapsulation intact? @@ -71,7 +82,7 @@ For staged changes touching multiple concerns (Go + TS + Terraform) or any subst - `pr-review-toolkit:comment-analyzer` — comment accuracy and rot, especially after large doc/comment edits. - `pr-review-toolkit:code-simplifier` — clarity, dead code, and duplication that can be collapsed. -Spawn each on the appropriate tier (the review judgement itself is Opus-class; mechanical single-file diffs can drop to Sonnet), aggregate the findings, dedupe overlaps, and resolve every actionable item before the commit lands. +Spawn each on the appropriate tier (the review judgement itself is Opus-class, with Fable held in reserve for the hardest money-path diffs; mechanical single-file diffs can drop to Sonnet), aggregate the findings, dedupe overlaps, and resolve every actionable item before the commit lands. ### Fix before committing, never after @@ -222,6 +233,8 @@ Once merged, the `merge-watch-` agent waits for the deploy pipeline (`gh r When verification can't be done remotely (sandboxed env, gated credentials, change requires a real customer scenario): say so explicitly in the comment in §6 — never silently skip and claim done. +**Reclaim the worktree once merged.** The `merge-watch-` agent is the one that observes the merge, so it owns cleanup: after the §5 verification, run the worktree sweep from `~/.claude/worktrees.md` ("Reclaiming worktrees after the PR merges or closes") for this PR's branch: safety-gate it (clean tree, nothing unpushed; recover stranded work per `feedback_recover_stranded_fix_work` if not), then `git worktree remove` it, delete **both** the local branch (`git branch -D`) **and the remote branch** (`git push origin --delete ` — a merged/wontfix head branch is dead; leaving it accumulates hundreds of stale remote refs), and archive/delete the plan file. If this PR was closed as wontfix instead of merged, the same sweep applies. This is what keeps `git worktree list` and `git branch -r` from silently accumulating dozens of merged-branch worktrees and refs; pair it with the periodic no-worktree **branch sweep** in `~/.claude/worktrees.md` ("Sweep merged/closed branches that have NO worktree") for branch refs left behind after their worktree is already gone. + ### 6. Comment on the originating issue with the verification outcome Post a structured comment to the GitHub issue that the PR was solving: diff --git a/issue-pr-autopilot.md b/issue-pr-autopilot.md index 7128d53..2d36b92 100644 --- a/issue-pr-autopilot.md +++ b/issue-pr-autopilot.md @@ -94,6 +94,31 @@ Both are currently **disabled** (pending validation). > the **current latest Sonnet model id** at routine-creation time. Refresh both > together when a newer generation ships so they stay on the same generation. +> **Server-pinned minute (observed 2026-07-27):** the `RemoteTrigger` API pins the +> cron **minute** server-side for load-spreading, so a submitted `0 */4 * * *` is +> rewritten to a stable server-chosen minute (the planner has landed at `:44` and +> `:55` on successive writes, not `:00`; resubmitting `0` does not stick). The `:00`/`:30` values below are +> therefore **nominal**. This is a latency detail only: correctness comes from the +> `plan-ready`/`pr-created` labels, not the clock (see "Correctness is from labels, +> not the clock"), so an inverted plan/worker order within a slot just defers the +> pickup to the next worker fire. At enable-time, read the actual `next_run_at` / +> `cron_expression` of both routines; if you want strict plan-before-work ordering, +> set the worker's nominal minute later than the planner's server-assigned minute +> (accepting the server may re-pin it too). + +> **Frontier-judgement escalation is manual.** The planner runs on Opus (the default +> top tier, ~Opus-5-class): it cannot escalate to the Fable peak reserve mid-run, +> because a routine is pinned to a single model for the whole fire and has no +> Agent/Task tool. Opus 5 lands within ~0.5% of Fable 5's peak at roughly half the +> cost, so Opus is the right default here and Fable is not worth a permanent second +> routine. If a specific issue genuinely needs frontier judgement (a gnarly +> architecture call or a high-stakes money-path plan), a **human** re-plans it +> out-of-band on Fable — e.g. do one manual `run` of the planner with its model +> temporarily set to the latest Fable id, or draft the plan branch by hand — then +> let the normal worker fire pick it up via the `plan-ready` label. Do NOT add a +> standing Fable planner routine for this; it would burn run-budget (see +> "Run-budget") for the rare case. + > **Earlier exploration routines:** `cudly-autopilot-plan-30` and > `cudly-autopilot-worker-45` were created during design exploration and are no > longer part of the active design. Delete them via the routines UI at diff --git a/subagent-strategy.md b/subagent-strategy.md index 4439a49..754e31b 100644 --- a/subagent-strategy.md +++ b/subagent-strategy.md @@ -6,15 +6,15 @@ Detail extracted from `CLAUDE.md` §2. The headline triggers stay in `CLAUDE.md` Before doing a piece of work in the main session (or spawning a subagent at the parent's tier), ask: *can a cheaper Claude, OpenAI, or Gemini subagent handle this per the rubric below?* If yes, spawn it with the `Agent` tool's `model` parameter. The main session's tier is typically the most expensive option available, so reserving it for work that genuinely needs it is the single biggest cost lever. Treat the rubric as a positive obligation to delegate down, not just a tie-breaker. This applies recursively: a subagent that needs to spawn further subagents also defaults to the cheapest sufficient tier. -**Set the `model` parameter on EVERY `Agent` call — never rely on inheritance.** Omitting it makes the subagent inherit the parent's model, which when the parent is Opus silently makes every subagent Opus too: a 5-10x cost premium for work that almost always doesn't need it. Even when you want the parent's tier, pass it explicitly so the choice is visible at the call site. +**Set the `model` parameter on EVERY `Agent` call — never rely on inheritance.** Omitting it makes the subagent inherit the parent's model, which when the parent is a top tier (Opus, or the pricier Fable reserve) silently makes every subagent that tier too: a large cost premium for work that almost always doesn't need it. Even when you want the parent's tier, pass it explicitly so the choice is visible at the call site. ## Routine PR-shipping splits across tiers The standard pattern (plan + 3-pass review + worktree + implement + test + push + open-PR + ping-CR + arm-CI-watcher) is NOT a single-tier workload: -- **Planning phase -> Opus.** Drafting the §1b plan file, the three-pass plan review gate, the §1 post-implementation review, the §1a reuse analysis, and the §5 elegance check all require holding multiple competing constraints in working memory at once: invariants from the issue body, lessons from prior commits, cross-cutting test impact, edge cases the acceptance criteria didn't enumerate. Sonnet plan reviews miss enough subtleties on real PR work that the rework cost exceeds the up-front Opus delta. -- **Iteration loops -> Opus.** Responding to CodeRabbit pass-N findings, fix-push cycles after a failed CI run, worktree-recovery after a watchdog stall, the §1c local review loop, and conflict-resolution rebases all share one shape: react to feedback that didn't fit the original plan without breaking what already worked. Sonnet stalls here; the triage surface grows each round and a Sonnet-tier triage either dismisses real findings as "out of scope" without filing a follow-up or produces fixes that don't exercise the contract under review. -- **Implementation phase -> Sonnet.** Writing the diff per the plan's task breakdown, running tests/lint/build, opening the PR, mirroring labels, routine `gh`/`git` mechanics. With a clean plan in hand and design questions answered upstream, Sonnet ships diffs cleanly across multi-file changes. +- **Planning + review phase -> Opus (the default top tier).** Drafting the §1b plan file, the three-pass plan review gate, the §1 post-implementation review, the §1c local review loop, the §1a reuse analysis, the §5 elegance check, and adversarial money-path reviews all require holding multiple competing constraints in working memory at once: invariants from the issue body, lessons from prior commits, cross-cutting test impact, edge cases the acceptance criteria didn't enumerate. Sonnet plan reviews miss enough subtleties on real PR work that the rework cost exceeds the up-front Opus delta. Opus 5 reaches ~Fable-5 frontier intelligence at roughly half the cost, so it is the right default here; escalate to **Fable** only for the hardest money-path adversarial reviews or gnarliest architecture calls, where the last ~0.5% of max-effort intelligence is worth Fable's ~2x price. +- **Iteration loops -> Opus.** Responding to CodeRabbit pass-N findings, fix-push cycles after a failed CI run, worktree-recovery after a watchdog stall, and conflict-resolution rebases all share one shape: react to feedback that didn't fit the original plan without breaking what already worked. Sonnet stalls here; the triage surface grows each round and a Sonnet-tier triage either dismisses real findings as "out of scope" without filing a follow-up or produces fixes that don't exercise the contract under review. +- **Implementation phase -> Sonnet for simpler changes, Opus for non-trivial code.** Writing the diff per the plan's task breakdown, running tests/lint/build, opening the PR, mirroring labels, routine `gh`/`git` mechanics. With a clean plan in hand and design questions answered upstream, Sonnet ships simpler, decided-shape diffs cleanly across multi-file changes; escalate the implementation to **Opus** when the code itself is non-trivial: complex multi-file features, intricate/hard logic, or a refactor whose shape only becomes clear while implementing. Both the upstream planning/design and the non-trivial coding sit on Opus now (Opus 5 covers both at ~half Fable-5's cost); on the implementation phase the only split is Sonnet for simpler, decided-shape diffs vs Opus once the code turns non-trivial. - **Carve-out boundary.** A single mechanical step within an iteration loop (apply a one-line CR-suggested diff verbatim, push) is still Haiku/Sonnet-able. Escalate to Opus when the loop step requires judgement about *what* to do, not just executing a decided fix. (Same rule of thumb as §1b's "skip the worktree only for trivially mechanical edits".) - **Scope.** This split applies to PR-shipping. Other workflows have their own rubrics: backlog triage uses `triage.md`; routine watchers (`ci-watch-*`, `cr-watch-*`, `merge-watch-*`) use polling-on-Haiku, escalate-on-Opus per `git-workflow.md`. @@ -43,7 +43,7 @@ In all of these, send the agent the new instruction with just the delta ("review **When NOT to reuse** (spawn fresh instead): - **Independence is the point.** Adversarial verification (CLAUDE.md §4), fresh-eyes review, refute-style judging: a verifier that shares the implementer's context inherits its blind spots. Reviewer and implementer stay distinct agents; but the same reviewer SHOULD persist across rounds of its own loop. -- **Wrong tier.** An agent's model is fixed at spawn. If the follow-up needs Opus judgement and the warm agent is Haiku/Sonnet (or the follow-up is mechanical and the warm agent is Opus, where each continued turn re-reads its whole accumulated context at Opus prices), a fresh right-tier spawn is cheaper than a wrong-tier continuation. +- **Wrong tier.** An agent's model is fixed at spawn. If the follow-up needs Opus judgement and the warm agent is Haiku/Sonnet (or the follow-up is mechanical and the warm agent is a top tier, where each continued turn re-reads its whole accumulated context at top-tier prices), a fresh right-tier spawn is cheaper than a wrong-tier continuation. - **Polluted or bloated context.** The agent went down failed paths, accumulated huge tool output, or is near its context limit. A fresh agent with a tight briefing beats a confused warm one. - **Unrelated task.** Overlap in time is not overlap in context; don't funnel misc work through one long-lived agent. @@ -58,10 +58,11 @@ In all of these, send the agent the new instruction with just the delta ("review ## Model rubric — match tier to task complexity - **Haiku / gpt-5.4-mini / Gemini 3.1 Flash-Lite** (default for most delegations): file renames, typo fixes, mechanical edits with a clear spec, simple lookups (grep for a symbol, find where X is called), reading one file to answer a factual question, formatting/style fixes, running a single command (or routine `gh`/`git` op) and reporting output, implementing a tightly-specified function, writing a test from a tight spec, code review of a small single-file diff, mechanical API/SDK migration with a documented mapping, classifying/labelling against a clear rubric (e.g. triage chunks), summarising one file or short diff. Cheap, fast, good enough when the answer is mostly mechanical or rubric-driven. -- **Sonnet / gpt-5.4 / Gemini 3.1 Flash**: the implementation phase of PR-shipping; focused multi-file changes where coordination needs judgement but the target shape is decided; implementing a function whose spec is mostly clear but has 1-2 design choices; code review of a multi-file or non-trivial-logic diff; refactors with a clear target shape. Use when design questions are answered upstream and the work is "execute the plan", not "decide the plan" or "react to a reviewer". -- **Opus / gpt-5.5 / Gemini 3.1 Pro** (or stay on the top-level model): the planning phase and the iteration loops of PR-shipping (per the split above); architecture decisions; multi-file refactors where the shape is unclear; debugging gnarly bugs needing hypothesis iteration; reading a large unfamiliar codebase from scratch (no `graphify-out/`) to synthesise a mental model; any work where "understanding" or "weighing options" is the hard part. +- **Sonnet / gpt-5.4 / Gemini 3.1 Flash**: the implementation phase of PR-shipping for simpler, decided-shape changes; focused multi-file changes where coordination needs judgement but the target shape is decided; implementing a function whose spec is mostly clear but has 1-2 design choices; code review of a small single-file or mechanical diff; refactors with a clear target shape. Use when design questions are answered upstream and the work is "execute the plan", not "decide the plan" or "react to a reviewer". +- **Opus / gpt-5.5 / Gemini 3.1 Pro** (the default top tier): the planning phase of PR-shipping (per the split above); all review loops (the §1c local review loop, the §1 pre-commit/post-impl reviews, adversarial money-path reviews); architecture/design decisions; the iteration loops of PR-shipping (CR pass-N responses, fix-push after a failed CI run, worktree-recovery, conflict-resolution rebases); debugging gnarly bugs needing hypothesis iteration; the implementation phase when the code is non-trivial (complex multi-file features, intricate or hard logic, refactors whose shape only becomes clear while implementing); reading a large unfamiliar codebase from scratch (no `graphify-out/`) to synthesise a mental model; any work where "understanding" or "weighing options" is the hard part. Opus 5 reaches ~Fable-5 frontier intelligence at roughly half the cost, so it is the everyday top-tier workhorse for both reasoning and heavy coding. +- **Fable / gpt-5.5 / Gemini 3.1 Pro at max effort** (the peak reserve, ~2x Opus cost): only when the last ~0.5% of max-effort intelligence decides the outcome — the hardest money-path adversarial reviews and the gnarliest architecture calls, where a wrong call is very expensive and Opus is genuinely not enough. Default to Opus and escalate to Fable deliberately, not by habit. -**When in doubt, go one tier cheaper and see if it's good enough** — for implementation, research, and mechanical work; re-spawn stronger if it struggles. *Exception*: planning phases and iteration loops default to Opus and step down only when the specific step is clearly mechanical. The cost of a stalled iteration agent that needs main-session takeover exceeds the up-front Opus delta. The main conversation's model is user-set and fixed mid-session; this rule only governs `Agent` spawns. +**When in doubt, go one tier cheaper and see if it's good enough** — for implementation, research, and mechanical work; re-spawn stronger if it struggles. *Exception*: planning, review, iteration, debugging, and non-trivial implementation default to Opus; step down only when the specific step is clearly mechanical, and step up to Fable only for peak-critical work. The cost of a stalled agent that needs main-session takeover exceeds the up-front Opus delta. The main conversation's model is user-set and fixed mid-session; this rule only governs `Agent` spawns. ## Label-mirroring on PR creation