agentleFS
DanaResearchGroupDanaResearchGroup/agent-skills/autodev/SKILL.md

autodev

Skill1 starsChanged 3 months agoMITView on GitHub

Use when you want to autonomously build a large or long feature end-to-end in one driven session, with automatic adversarial Codex review at every milestone, automatic context handoff/compact/resume past 35%, and Claude Code recovery from usage/session-limit stops (Phoenix). Invoke with the feature description or a path to a spec.

5 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 3 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use subagents heavily: Do the real work in dispatched subagents wherever possible — implementation, searching, reading large files, …

    line 24
  2. Very specific:

    not in herdr/tmux or DRY-RUN/DISABLED → "Auto-handoff is NOT active.

    line 73
  3. Distinctive:

    all true → "Auto-handoff active — I'll keep working through compactions hands-free."

    line 75
  4. Very specific:

    Write $DEV/progress.md (overwrite each update.

    line 83
  5. Very specific:

    Pin the done-check as executable: If the repo is contract-gated (contract status names an active contract), write the feature's "done and …

    line 111
  6. Very specific:

    Implement: Prefer test-first (invoke the tdd skill discipline).

    line 162
  7. Very specific:

    Treat Codex's P1/serious findings as must-fix: fix them before moving on.

    line 167
  8. Distinctive:

    Verify: Run this milestone's tests/build.

    line 169

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

You are an autonomous feature-development driver. You run a long build loop with two always-on behaviors: (1) adversarial Codex review at every milestone via the spar skill, and (2) reliance on the auto-handoff watcher to handle context compaction past 35% so the loop survives across compactions.

Skill syntax is runtime-specific: Claude Code uses /spar and /handoff; Codex uses $spar and $handoff. Where this workflow says to invoke a skill, use the current host's syntax.

Be autonomous. Do not stop for routine choices — use judgment and keep going. Only stop for a genuine blocker, a real user decision, or completion.

Core rule of this mode: the user is asked only when you and Codex agree they must be. Whenever you would normally pause and call AskUserQuestion on a technical/design/architectural decision, you FIRST spar with Codex, and that round ends in an explicit ESCALATE: yes/no vote. A no means you take Codex's option and keep going. See "Decision points" below. This is what makes the loop autonomous instead of bottlenecking on the user.

Use subagents heavily. Do the real work in dispatched subagents wherever possible — implementation, searching, reading large files, running/parsing test output, exploration — so the mother session's context stays small and long runs last far longer between compactions. Dispatch several in parallel when the tasks are independent, keep each subagent's brief tight, and have them return only the distilled result (not raw dumps). Collect every subagent within the phase (foreground) — never leave one running in the background across a checkpoint, or it keeps the pane busy and blocks the auto-handoff watcher. Reserve the mother turn for orchestration and decisions, not bulk work.

Step 0 — Preflight (run once)

SKILLS_ROOT=""
for root in "$HOME/.agents/skills" "$HOME/.claude/skills" "$HOME/.codex/skills"; do
  [ -d "$root/autodev" ] && { SKILLS_ROOT="$root"; break; }
done
AUTODEV_BIN="$SKILLS_ROOT/autodev/bin"
eval "$("$SKILLS_ROOT/bin/skill-slug" 2>/dev/null)" 2>/dev/null || true
[ -z "${SLUG:-}" ] && SLUG=$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)" | tr -cd 'a-zA-Z0-9._-')
SLUG="${SLUG:-unknown}"
DEV="$HOME/agents/autodev/$SLUG"; mkdir -p "$DEV"
S="$HOME/agents/state"
# Prefer the host's authoritative session id, then resolve by pane for older sessions.
MYSID="${CLAUDE_CODE_SESSION_ID:-${CODEX_SESSION_ID:-${CODEX_THREAD_ID:-}}}"
[ -z "$MYSID" ] && MYSID=$(grep -l "^${HERDR_PANE_ID:-__none__}$" "$S"/*.herdr-pane 2>/dev/null | head -1 | xargs -r -n1 basename | sed 's/\.herdr-pane$//')
[ -z "$MYSID" ] && MYSID=$(grep -l "^${TMUX_PANE:-__none__}$" "$S"/*.tmux-pane 2>/dev/null | head -1 | xargs -r -n1 basename | sed 's/\.tmux-pane$//')
CTXFILE="$S/${MYSID:-unknown}.ctx"
# Status-line: mark this session as an autodev run (lights the AUTODEV badge).
[ -n "$MYSID" ] && [ "$MYSID" != "unknown" ] && touch "$S/$MYSID.autodev" 2>/dev/null || true
echo "SLUG=$SLUG"
echo "PROGRESS=$DEV/progress.md"
echo "CTXFILE=$CTXFILE   (read your live context % from here)"
echo -n "MUX: "; if [ "${HERDR_ENV:-}" = "1" ]; then echo "herdr"; elif [ -n "${TMUX:-}" ]; then echo "tmux"; else echo "NONE"; fi
echo -n "AUTO_HANDOFF: "; if [ -f "$S/disable-auto-compact" ]; then echo "DISABLED"; elif [ -f "$S/auto-handoff.armed" ]; then echo "ARMED"; else echo "DRY-RUN"; fi
if [ -n "${CODEX_SESSION_ID:-${CODEX_THREAD_ID:-}}" ]; then
  echo "PHOENIX (limit-resume): CLAUDE-ONLY"
else
  echo -n "PHOENIX (limit-resume): "; if [ -f "$S/disable-auto-compact" ] || [ -f "$S/disable-auto-resume" ]; then echo "DISABLED"; elif [ -f "$S/auto-handoff.armed" ]; then echo "ARMED"; else echo "DRY-RUN"; fi
fi

Remember $CTXFILE — you read your own live context percentage from it at every phase boundary (Phase discipline, below). If MYSID is unknown (not in herdr or tmux, or the statusline hasn't rendered yet), fall back to your own soft estimate of context usage.

Interpret the output and tell the user in one line whether the auto-handoff loop is actually active for this run. It is active ONLY if: running inside herdr or tmux AND state is ARMED AND this is a session started AFTER the hooks were installed (hooks load per session). If any of those is false, say so plainly:

  • not in herdr/tmux or DRY-RUN/DISABLED → "Auto-handoff is NOT active; I'll proactively invoke the handoff skill near 35% and ask you to run /compact." (Codex review still works.)
  • all true → "Auto-handoff active — I'll keep working through compactions hands-free."

Step 1 — Scope and plan

Adopt the feature from the argument (text or a spec file path). If the goal is too vague to execute, ask at most 2-3 sharp clarifying questions via AskUserQuestion, then proceed. Otherwise do not interrogate — start.

Write $DEV/progress.md (overwrite each update; it is the resume anchor):

# autodev: <feature>
status: in-progress
slug: <slug>   updated: <YYYY.MM.DD HH.MM.SS>

## Goal
<one paragraph>

## Milestones
1. [ ] <milestone>
2. [ ] <milestone>
...

## Done
- <what's landed, with commit/file refs>

## Decisions
- <decision — why>

## Next
- <the very next concrete step>

## Blockers
- <none | what + unblock condition>

Pin the done-check as executable. If the repo is contract-gated (contract status names an active contract), write the feature's "done and verified" command into that contract's ## Verifier as a ```verify block, e.g. bash test/ci.sh. A prose Verifier cannot be executed: contract verify refuses with "no ```verify block", and the run falls back to judging its own output. Write the block now, before any code. That way the check is fixed before the work exists to fit it. With no contract, skip this; Step 2's Verify runs the tests directly.

Step 2 — Development loop (repeat per milestone until done)

Prime Codex once (first spar round of the run)

On the first spar invocation of this run only — i.e. when the per-project Codex session is created (~/agents/adversarial/<slug>/.session-id did not yet exist) — prepend a mission brief, so Codex critiques against the actual target instead of inferring it from a diff. A reviewer who never learned the goal reviews the code you wrote, not the feature you owe. The brief has two parts.

1. The mission, quoted from $DEV/progress.md so the goal has one source of truth:

  • the ## Goal paragraph verbatim, and the full ## Milestones list — including the ones not yet built, so Codex can tell a deliberate stub from an omission;
  • which milestone this round covers, and what has already landed (## Done);
  • the constraints fixed for the whole run: stack, interfaces that must not break, standards the repo enforces, anything the user ruled in or out at Step 1;
  • what done and verified means for this feature — the tests/build that must go green.

2. The grounding prime:

Before answering, load and read the actual code in this repository, and review the feature branch we are working on if it is relevant: determine the current branch and its base, run git diff <base>...HEAD (or git log --oneline <base>..HEAD), and read the changed files. Base your critique on what the code actually does, not assumptions.

Codex runs with -C <repo> -s read-only, so it can run git and read any in-repo file. Because the session is persistent (codex exec resume), both parts carry forward to every later round — do not repeat them. Later rounds carry only what changed: the increment and the question.

Codex context is self-managed by the spar skill. The persistent Codex session fills up over a long run; spar handles this on its own — when the session gets too full it has the outgoing session write a successor handoff, rotates to a fresh Codex session reseeded with it (and re-applies the grounding prime), and announces the rotation. Re-attach the mission brief on your first round after a rotation — the predecessor handoff carries Codex's own open threads, not your goal. Otherwise you do nothing extra for this. When you see a spar round announce an auto-handoff, note it in progress.md Decisions ("Codex context rotated to a fresh session at round N — arc carried via predecessor handoff") so a compacted resume knows the Codex memory was rolled over. (This is separate from the host session's auto-handoff, which gates on your context, not the sparring session's.)

For each milestone, in order:

  1. Implement. Prefer test-first (invoke the tdd skill discipline). Make the smallest correct increment.
  2. Adversarial Codex review — ALWAYS. Invoke the spar skill on the increment or the decision behind it (e.g. challenge the design of <thing> I just built). Codex resumes the same persistent session each round, so it sees the whole arc. Treat Codex's P1/serious findings as must-fix: fix them before moving on. Record the round (the spar skill persists Q/A under ~/agents/adversarial/<slug>/).
  3. Verify. Run this milestone's tests/build. Do not advance on red. Fix, re-verify. With a ```verify block in the contract, the last milestone also runs contract verify, and its exit code is the verdict, not your reading of the output. The block is the whole feature's done-check, so an earlier milestone can fail it only because later work is unbuilt; it does not gate those. It runs on a dirty tree, so no commit is needed first.
  4. Record. Update $DEV/progress.md (tick the milestone, update Done/Decisions/Next). If continuous-checkpoint or git is in use, commit the logical unit.
  5. Checkpoint beat, then continue. Before spawning the next phase's work, run the checkpoint beat (see "Phase discipline & checkpoint beats") — quiesce, read $CTXFILE, and yield for auto-handoff if pct > 35. Otherwise continue to the next milestone without waiting for the user.

Spar at EVERY milestone, not just once. The point is continuous adversarial pressure.

Decision points — Codex concurs before the user is asked

This overrides the normal "ask the user" reflex for the duration of the run. The user is asked only when both of you agree the question is theirs — a concurrence gate.

Whenever you reach a point where you would otherwise call AskUserQuestion about a technical / design / architectural / chemistry-modeling decision (which approach, how to resolve a failure, which fix), or you are about to declare a blocker:

  1. Spar first. Invoke the spar skill with the decision and the concrete options + tradeoffs (e.g. Resolve X: option A <...> vs B <...> vs C <...>. Which is correct and why? Favor fixing the real defect over bypassing checks."). Codex resumes the same persistent session, so it has the full arc. Close the question with the vote request:

    End your answer with a line ESCALATE: yes or ESCALATE: no, plus one sentence of reason. Answer yes only if this genuinely requires the human — it stays ambiguous after your own analysis, or it turns on information only they hold. If you can resolve it, answer no and name the option to take.

  2. ESCALATE: no → auto-proceed. Take the option Codex named, record it in progress.md Decisions ("chose A — Codex: <reason>"), and keep working. The user is not asked, and the round file under ~/agents/adversarial/<slug>/ stands as the record of what was decided without them. Still convinced the call is theirs? Fire exactly one tiebreak round saying what Codex's read misses; a second ESCALATE: no binds you — proceed.
  3. ESCALATE: yes → ask. You concur, so call AskUserQuestion with Codex's take folded into the options.
  4. Escalate unilaterally — no vote needed — when the action is irreversible or destructive (deleting data, force-push, dropping a schema, spending money, changing public scope), or the answer is information only the user holds (product intent, priorities, external constraints, what they actually want built). Codex cannot hold the user's intent, so a no there would authorize the very thing that needs their consent. Ask directly and skip the round.
  5. A finding that retires the mission is always the user's call. When something you learn mid-run undercuts the premise the whole feature rests on — the evidence base retires the goal, a probe inverts the load-bearing assumption, the thing being built turns out already to exist — stop and surface it as a decision rather than executing the remaining milestones. This is the carve-out above (only they hold the intent), and it is the failure that autonomous loops make most often: the verdict sits in your own findings while you keep building against it.

    The finding is a premise like any other: corroborate it (probe, re-check, a second look) before acting on it — an uncorroborated retirement claim is not grounds to stop. Once corroborated, run the checkpoint beat's quiesce step (collect every running background agent) and update progress.md and the handoff before you ask, exactly as at any other phase boundary — do not surface the finding mid-phase with agents still in flight and no record of where you stopped.

Honor the user's standing rules when reading Codex: prefer fixing the real defect over "building to pass the check," and treat bypass flags (e.g. asserting a reference state the thermo can't actually support) as a last resort to be flagged, not a default.

Phase discipline & checkpoint beats (gives the watcher its injection window)

The auto-handoff watcher can only invoke the handoff skill and /compact when the host is at a genuine idle prompt — never while a turn is running or background agents are still going (the host queues input while busy, so the keystrokes are lost). A perpetually-busy run therefore never gets checkpointed and blows past 35%. Prevent that:

  • Do not overlap phases. Parallelize within a phase (dispatch several subagents at once is fine), but collect every dispatched agent and finish the phase before starting the next. Never leave a background agent running across a phase boundary.
  • At each phase boundary, before spawning the next batch, run a checkpoint beat:

    1. Confirm quiesced — zero background agents still running. This is mandatory, not cosmetic: while any background agent runs, the pane shows "Waiting for N background agents" and the host queues (loses) injected input, so the auto-handoff watcher CANNOT compact. Never write a handoff / hit a checkpoint with an agent still running on the theory that "the reload will collect it" — it won't, because compaction can't fire on a busy pane. Collect every agent first, then checkpoint.
    2. Read your live context %:
      pct=$(sed -n 's/^pct=\([0-9.]*\).*/\1/p' "$CTXFILE" 2>/dev/null); echo "ctx=${pct:-?}%"
    3. If pct > 35 (or, if MYSID was unknown, your soft estimate says you're past ~a third):
      • Auto-handoff ACTIVE (preflight showed TMUX: yes and AUTO_HANDOFF: ARMED): update progress.md, then end your turn now with one line, e.g. Checkpoint: ctx <pct>%, quiesced at phase boundary — yielding for auto-handoff. Do NOT spawn the next phase. The watcher (idle pane + high %) will run handoff → /compact → inject "continue," and you resume by reading the handoff
        • progress.md and starting the next phase. This is the deliberate idle beat.
      • Auto-handoff NOT active: invoke the handoff skill yourself, update progress.md, tell the user to run /compact then continue, and stop.
    4. Else (pct comfortable): proceed straight into the next phase — no yield, no stall, unless the voluntary-handoff case below applies.

Yielding only when pct > 35 means you never stall the loop for a checkpoint you don't need, and you always hand the watcher a clean idle window exactly when one is required.

Voluntary early handoff (below threshold). The pct > 35 rule is reactive — it fires after you cross the line. But sometimes you are quiesced at a clean phase boundary at, say, 22% and you know the next phase is heavy (a large mechanism review, a wide multi-file refactor, a long spar arc) that will blow well past 35% inside the phase, where there is no idle window for the watcher to use. In that case, hand off before opening the phase rather than partway through it: raise a voluntary request, then end your turn.

bash "$AUTODEV_BIN/request-handoff.sh"   # drops this session's handoff-request marker

This writes ~/agents/state/<sid>.handoff-request, a second trigger path that makes the watcher run the normal handoff → /compact → reload on its next idle Stop even below 35%. It bypasses ONLY the threshold — every other safety gate (idle, pane-live, pane-ownership, cooldown, cycle-lock) still applies. A request never expires by age; it is dropped only once satisfied (a compaction newer than it). After raising it, update progress.md and end the turn — do not open the heavy phase, and do not invoke the handoff skill yourself: the watcher runs its own handoff → /compact → reload on the next idle Stop, so a manual handoff here would just duplicate it. Changed your mind before the watcher acts? request-handoff.sh --cancel removes it. Only the mother session should call this (it resolves its own sid); never from a subagent. This is opt-in — the default remains the reactive pct > 35 beat above.

Already wrote a handoff below threshold? (You invoked the handoff skill did.) Do nothing — the handoff skill files a compact-request, and the watcher runs a compact-only cycle: it skips a second handoff and goes straight to /compact → reload, even below 35%. File it by hand only if needed — request-handoff.sh --compact-only (--cancel withdraws).

Step 3 — Context / compaction (resumable by design)

  • The auto-handoff watcher (when active) will, past 35% at a turn boundary, automatically run handoff → /compact → inject "read the handoff and continue execution." You do not trigger it. Just keep progress.md current so a resumed session continues cleanly.
  • When a handoff is written (auto or manual), ensure it names this autodev loop and points to $DEV/progress.md, stating "resume the /autodev loop for <feature> from Next."
  • On resume after a compaction (you'll receive an injected instruction to read a handoff): read that handoff AND $DEV/progress.md, then CONTINUE the loop from Next. Do not restart from milestone 1; do not re-ask the user what to do.
  • If auto-handoff is NOT active (preflight said so): self-monitor; near ~35% at a clean checkpoint, invoke the handoff skill yourself, update progress.md, and ask the user to run /compact then say "continue".

Step 3b — Usage/session limits (Phoenix auto-resume)

Long autonomous runs eventually hit the usage/session limit — the turn stops with a pane banner like You've hit your session limit · resets 6:20am / /usage-credits to finish what you're working on. This is handled automatically by Phoenix (~/agents/bin/session-resume-watch.sh), a sibling of the auto-handoff watcher launched by the same Stop hook. You do NOT do anything special for it — but know how it behaves so you resume cleanly:

  • On a limit stop, Phoenix first runs /usage-credits (the banner's own suggested action). If that clears the limit, it sends continue and you pick up where you left off.
  • If credits don't clear it (or are disabled via ~/agents/state/no-usage-credits), Phoenix parses the reset time, sleeps until a few minutes past it, then sends continue.
  • While it waits, the status line shows a ⏳ AUTO-RESUME @ <time> badge, it writes ~/agents/state/<sid>.limit-wait, and the auto-handoff watcher defers (no handoff/ compact into a limited session).
  • Phoenix is a no-compaction resume: your context is intact across the limit, so a plain continue resumes the loop directly. When you receive that continue after an ⏳ AUTO-RESUME, just carry on from progress.md Next — do not restart or re-ask.
  • It needs the same conditions as auto-handoff: tmux + ARMED + a post-install session. If Phoenix is not active (preflight shows PHOENIX: DRY-RUN/DISABLED, or not in tmux), a limit stop is on you: wait for the reset and type continue yourself.

Because Phoenix keeps progress.md as the anchor (same as compaction resume), a limit stop mid-run is fully recoverable — keep progress.md current at every checkpoint as you already do.

Step 4 — Stop conditions

  • All milestones done and verification green → set progress.md status: done, write a final handoff, summarize what shipped, and stop. Under a contract, "green" means: commit, then contract verify PASS at that clean HEAD, then contract close. close refuses a stale, dirty or failed run, so a refusal means you are not done.
  • User decision required — Codex voted ESCALATE: yes, or it falls in the unilateral carve-out (irreversible/destructive, or user-only info) per "Decision points" → write handoff, ask via AskUserQuestion, stop.
  • Same step fails 3 times → spar it as a decision point. On ESCALATE: no, take Codex's option and keep going; on yes, stop, write progress.md Blockers, and escalate with what you tried.

When you stop for any of the above, clear the autodev status-line marker: rm -f "$S/$MYSID.autodev" (harmless if $S/$MYSID aren't in scope — it just lingers until the session ends).

Implementation & install (bundled, portable)

The whole automation harness ships inside this skill under bin/, so it is reusable on any machine (copy the skill, run the installer, arm it). See README.md for full operator docs. The scripts are self-locating and store runtime data under AUTODEV_HOME (default ~/agents) — code in the skill, data outside the repo.

  • bin/install.sh — wires the runtime hooks while preserving existing hooks. Claude Code: bash "$AUTODEV_BIN/install.sh"; Codex: bash "$AUTODEV_BIN/install.sh" --codex, then review the new hooks with /hooks in a new Codex session.
  • bin/cc-statusline.sh — writes live context % + tmux pane to $AUTODEV_HOME/state/<sid>.* and renders the automation badge.
  • bin/cc-handoff-gate.sh — PreToolUse hook: while this session's compact/handoff request is pending, denies every tool call except the ones that finish the handoff (writes under handoffs/, request-handoff.sh, reading this session's state files, the handoff skill's verify/pointer commands), telling the model to end its turn. The 3rd denial of one request returns {"continue":false}, which stops Claude even under /goal. Bypass: AUTODEV_NO_HANDOFF_GATE=1, touch $AUTODEV_HOME/state/<sid>.no-handoff-gate (one session) or state/disable-handoff-gate (all). Fails open on any error. Claude Code only — Codex hooks differ and are not gated. The sweeper pages (notify-send, else a PAGE log line) once per request that has been pending 30 min while the watcher only deferred. It also files the handoff-request itself (request-handoff.sh --if-absent, logged REQUEST raised (threshold, busy Nm)) when a session is over the threshold and its pane has worked continuously for 20 min (AUTODEV_BUSY_MINUTES), so a session stuck in one long turn is stopped without having to file its own. The sweep keeps <sid>.busy-since for this; an idle pane, an open menu/prompt, a recorded Stop, or a >10 min observation gap resets it.
  • bin/cc-stop-hook.sh — at each turn end, marks idle and launches both watchers ($HERE/…).
  • bin/codex-stop-hook.sh — records Codex's effective active-context percentage and launches the handoff watcher at each turn end.
  • bin/sessionstart-compact.sh — shared post-compaction reload-instruction backup.
  • bin/auto-handoff-watch.sh — context-threshold → handoff//compact/reload engine; emits /handoff on Claude Code and $handoff on Codex.
  • bin/session-resume-watch.sh — Phoenix usage/session-limit → /usage-credits/wait → continue.

Control switches live in $AUTODEV_HOME/state/ (auto-handoff.armed, disable-auto-compact, disable-auto-resume, no-usage-credits); logs in $AUTODEV_HOME/logs/. Hooks load per session, so install/relocation takes effect for new sessions only.

Rules

  • Autonomous by default. Routine choices are yours; the user is asked on ESCALATE: yes or the carve-out, and nowhere else.
  • spar every milestone. Fix P1 findings before advancing.
  • Never advance on failing tests.
  • Keep progress.md and handoffs resumable across compaction — that is what makes the long run survive context limits.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.