name: feature description: Start a new feature in an isolated git worktree with TDD workflow when_to_use: when the user says "start a feature", "new feature", invokes "$agent-dashboard:feature", or describes work that needs an isolated branch + worktree + TDD loop. NOT for hotfixes, single-file edits, pure exploration, or non-code changes (use $agent-dashboard:chore, $agent-dashboard:fix, $agent-dashboard:investigate instead). version: 1.0.0 disable-model-invocation: true effort: max
Start a new feature in an isolated git worktree.
Feature description: $ARGUMENTS
Instructions
Follow these phases in order. Each phase has a gate — do not proceed until the gate is satisfied.
Before every action, identify the current phase and check its gate. If a gate is not satisfied, stop instead of falling back. If you violate phase order, halt and report the violated gate.
If the feature touches browser UI, Playwright, dev-server ports, screenshots, or interactive Browser/Chrome inspection, apply ../_shared/ui-automation.md at planning, environment setup, verification, delegation, and cleanup points.
Phase 1: Setup
Derive a short kebab-case name from the description
Derive the app name from the git repo:
basename $(git rev-parse --show-toplevel)Switch to main:
git checkout mainPull latest:
git pull origin mainCreate branch
feat/<name>and worktree../worktrees/<app>/<name>from main. Run two separateexec_commandtool calls — do not chain them with&&. The dashboard's PostToolUse hook only stampsworktree_cwd+branchwhen the command starts withgit worktree add; a compoundmkdir … && git worktree add …slips past the regex and leaves the dashboard unable to detect dir or branch.First, ensure the parent directory exists:
mkdir -p ../worktrees/<app>Then run
git worktree add -b feat/<name> ../worktrees/<app>/<name> mainas its ownexec_commandtool call:git worktree add -b feat/<name> ../worktrees/<app>/<name> main- If the branch already exists, ask the user whether to resume it or choose a new name.
From the source repo root (before cd'ing), copy environment files into the worktree preserving their exact relative path from the project root:
- Find all env files recursively:
find . -name '.env*' -not -path './.git/*' -not -path './node_modules/*' - For each file found, recreate its directory structure in the worktree and copy it. For example:
./. env→../worktrees/<app>/<name>/.env./services/api/.env.local→../worktrees/<app>/<name>/services/api/.env.local./infra/.env.production→../worktrees/<app>/<name>/infra/.env.production
- Use:
for f in $(find . -name '.env*' -not -path './.git/*' -not -path './node_modules/*'); do mkdir -p "../worktrees/<app>/<name>/$(dirname "$f")" && cp "$f" "../worktrees/<app>/<name>/$f"; done - If
.claude/settings.local.jsonexists:mkdir -p ../worktrees/<app>/<name>/.claude && cp .claude/settings.local.json ../worktrees/<app>/<name>/.claude/ - Important: Commands in this step write outside the project root. Use Codex escalation (
sandbox_permissions: "require_escalated") with a concise justification; do not try to route around approvals.
- Find all env files recursively:
cd into the worktree, run
node "$HOME/.codex/hooks/agent-dashboard/claim-worktree.js", and confirm withpwdandgit branch --show-currentVerify: compare env files between source and worktree. Run the same
findcommand in both directories and diff the file lists. If any files are missing in the worktree, halt and report failure. If the source repo had no.env*files, note that explicitly.
Gate: Working directory is the new worktree on the correct branch, based on latest main. If .env* files existed in the source repo, they are all present in the worktree.
Phase 2: Plan
Plan-first guarantee. Phase 2 is planning only. No dependency installs, no
sentinel writes, no environment setup runs until the plan is approved. The
only writes allowed in this phase are read-only research (Codex explorer)
and the <proposed_plan> submission itself. Environment setup kicks off in
the post-approval actions below.
Phase order: Plan Mode first, then research, then interview, then submit. Plan Mode is the entry gate to Phase 2 — nothing else in this phase happens outside it. Each step has a HARD-GATE you cannot rationalize past.
Enter Codex Plan Mode via
/planbefore continuing. Dashboard-created Codex feature sessions should auto-enter Plan Mode before the skill prompt is submitted. Ifpermission_modeis notplan, stop immediately and ask the user to run/plan; do not research, interview, draft, callspawn_agent, callupdate_plan, edit files, write tests, run setup, or create sentinels.No spawn_agent,request_user_input, or plan drafting untilpermission_mode='plan'.Research with
spawn_agentexplorer. Use a Codexexplorersubagent for non-trivial codebase or library lookups. Always pairspawn_agentwith await_agentto retrieve the explorer's findings — never spawn-and-forget. Do not delegate planning — composing the plan is your job. Synthesize what you found inline as your own assistant text so it lands in the visible plan artifact (not in a tool result the user can't approve).explorerfor research is fine; never dispatch another role to compose the plan. Everyspawn_agentmust be followed bywait_agent.Interview the user via
request_user_input. Identify every gating decision the implementation depends on — URLs, IDs, scope boundaries, copy text, what to delete vs keep, version pins, credentials. Ask them as a singlerequest_user_inputcall with multi-choiceoptions, not as freeform numbered text. Ifrequest_user_inputis unavailable during Phase 2, stop and ask the user to run/plan.Schema: 1–3 questions per call, each with a
header(≤12 chars), 2–3 mutually exclusiveoptions. Recommended option goes first with(Recommended)suffix. The client adds an "Other" escape hatch automatically.Worked example:
request_user_input({ questions: [{ id: "focus_path", question: "Where should focus.json live?", header: "Focus path", options: [ {label: "~/.agent-dashboard/focus.json (Recommended)", description: "Co-located with agents/ state dir already watched."}, {label: "$XDG_RUNTIME_DIR/agent-dashboard/focus.json", description: "Tmpfs-backed, cleared on reboot."}, ], }] })The plan you submit in step 4 must be implementable as written. No "Decisions needed", "Phase 0", "TBD", "?", or "to be confirmed" sections. If a user answer changes scope, re-interview before submitting.
If you find yourself typing "1." "2." "3." questions in assistant text — STOP. Use request_user_input.Draft inline, then submit via
<proposed_plan>. Wait for user approval. Plan Mode is already active (step 1); draft the plan as your own assistant text and then wrap the full plan markdown in<proposed_plan>...</proposed_plan>. This renders the plan through Codex's native plan-review flow for accept/reject. After submitting<proposed_plan>, stop until the plan-review approval arrives; ordinary chat approval is not implementation approval.Caveat:
update_planis a progress checklist tool, not a planning-mode substitute. Use it after approval to track implementation progress; do not use it to bypass Plan Mode.Phase format for multi-phase plans. If the plan has 3+ distinct work units, structure it with a
## Phaseschecklist and matching### Phase X:headings. The post-approval probe reads this format to offer dispatch;$agent-dashboard:implementparses it to drive the dispatch loop. Plans without it can't be dispatched.## Phases - [ ] **Phase A: <short name>** — files: <globs>, deps: - - [ ] **Phase B: <short name>** — files: <globs>, deps: A - [ ] **Phase C: <short name>** — files: <globs>, deps: B ### Phase A: <short name> <10–50 lines: what files, what tests, what invariants, what to leave alone.> ### Phase B: <short name> <...>Rules:
- The
## Phasesblock is the dispatch index. Phase names MUST match between checklist and### Phase X:headings (case-sensitive). deps:defaults to "depends on previous phase". Use-for "no dependencies".- [ ]= pending.- [x]= done.$agent-dashboard:implementflips these as it dispatches.- Fewer than 3 work units? Skip this format. Inline paragraphs are fine; the probe won't fire below the threshold.
<proposed_plan>is the only acceptable submission. Pasting the plan as ordinary assistant text is a violation, even if you also update a checklist afterwards. The user reviews and approves through the plan-review UI — nowhere else.No exceptions:
- Don't start a "small" preparatory edit while waiting.
- Don't write the test file "to save time".
- Don't ask "should I proceed?" in assistant text — the plan-review UI's accept action is the approval.
Post-approval actions (immediately after the user accepts the plan, before Phase 3):
Write the plan-path sentinel (always). Save the approved plan markdown to a worktree-local file and record that absolute path so
$agent-dashboard:implementcan find it:echo "<absolute-plan-path>" > .feature-plan-pathKick off environment setup as a background
exec_command(always). The setup task runs in parallel with the dispatch probe and any pre-Phase-3 work so its install time is amortised. It must:Auto-detect project type from project files (highest match wins):
Priority Signal Type 1 react-nativein package.json dependenciesMobile 2 next,vite, orwebpackin package.jsonWeb 3 requirements.txt,pyproject.toml, orsetup.pyPython 4 go.modGo 5 Dockerfileordocker-compose.ymlContainerized Ask the user only if no signal matches.
Install dependencies appropriate for the project type (e.g.
pip install,npm install,go mod download). Configure ports, create emulators/simulators as needed. For browser UI work, allocate worktree-local Playwright/server/profile/output resources per../_shared/ui-automation.md.Symlink large source-content directories (
data/,datasets/,evals/,models/,artifacts/) from the source repo rather than copying. NEVER symlink build outputs or per-project caches (.next/,dist/,build/,out/,target/,.turbo/,.cache/,.parcel-cache/,.vite/,__pycache__/,.pytest_cache/,.gradle/,.venv/,node_modules/) — they bake absolute paths and corrupt across worktrees, and must be regenerated per-worktree.On success, write a sentinel file:
touch .env-setup-doneOn failure, write the error:echo "<error message>" > .env-setup-failed
Count the phases. Read the plan; count
- [ ]/- [x]lines under## Phases. If there's no## Phasesblock or the count is< 3, skip step 4 below and start Phase 3 (inline TDD).Probe for dispatch handoff (only when phase count ≥ 3). Call
request_user_inputexactly once when available; otherwise ask one concise direct question and wait for the user's answer. Never choose the recommended option yourself.- Question:
"Plan has {N} phases. Continue inline here, or hand off to $agent-dashboard:implement for context isolation?" - Header:
"Dispatch" - Options (recommended first):
"Continue inline (Recommended for ≤4 phases)"— Stay in this session; run RED → GREEN → REFACTOR per phase in order."Hand off to $agent-dashboard:implement"— Exit $agent-dashboard:feature. The user invokes$agent-dashboard:implementin a fresh session; each phase dispatches to its own subagent.
If
Continue inline: start Phase 3. The## Phasesstructure becomes documentation — inline TDD ignores the index.If
Hand off to $agent-dashboard:implement: print the message below and exit cleanly. Do not start Phase 3.Plan saved to <plan-path>. Worktree ready at <worktree-path>. To continue, run: $agent-dashboard:implement (Recommended: open a fresh terminal session for max context isolation.)- Question:
- The
Gate: Plan approved with no open decisions. .feature-plan-path written. Either Phase 3 begins (inline) or the skill exited with the handoff message (dispatch).
Phase 3: Implement
Pre-gate: Check for .env-setup-done in the worktree root.
- If present: verify dependencies are installed (e.g.
node_modules/exists,pip listsucceeds,go env GOPATHworks) and data symlinks resolve correctly. - If
.env-setup-failedexists: surface the error and halt. - If neither file exists: the background agent is still running — wait for it to finish before proceeding.
Effort note: When launched via the agent-dashboard's New Agent flow, this skill starts at implementation effort. Codex Plan Mode is the high-reasoning planning surface; once the approved plan is accepted, use update_plan for progress tracking and keep implementation effort proportional to the work.
Delegation gate: Use Codex spawn_agent only if the user explicitly requested subagents OR the plan touches 10+ files / ~3,000+ lines of implementation. Below that threshold, the orchestration overhead (skill loading, prompt construction, subagent context, result parsing, review) costs more tokens than implementing directly. If delegating, use $agent-dashboard:implement with the approved plan (Phase 2) as implementation context, then skip to the phase gate. Otherwise, proceed below.
Build the feature following strict RED → GREEN → REFACTOR:
RED. Write the failing test. Run
make test. Paste the failing output into the conversation. Wrote implementation before test? Delete it. Start over. No exceptions:- Don't keep it as "reference"
- Don't write tests for the implementation you already wrote
- Don't claim "the test would obviously fail" — show it failing
GREEN. Write the minimum implementation to make the failing test pass. Run
make test. Paste the passing output. Wrote more than the test demanded? Revert and re-do. No "while I'm here" additions, no premature abstractions.REFACTOR. Clean up. Run
make testafter each meaningful edit. Tests broke during refactor? Revert that edit and try a smaller step. Refactor is structure-only — if behavior changed, you're back in RED.
For UI verification, prefer headless Playwright with worktree-local resources. Use interactive Browser/Chrome inspection only when the shared policy says it is warranted.
Gate: Environment ready. All tests pass via make test. Implementation matches the approved plan.
Phase 4: Review
Review all changes for correctness, security, and convention adherence. Apply all project rules and conventions that are in your context.
Gate: No critical or high-severity issues remain.
Phase 5: Deliver
- Commit the feature changes with a
feat:conventional commit message. - Open the PR by invoking
$agent-dashboard:pr. That skill owns the cleanup pass (Codexworkerwith an inline cleanup brief),make fmt,make test, push, andgh pr create. Do not callgh pr createdirectly — apr-skill-gatehook will block it.
Gate: Clean commit history with conventional commit messages. PR opened via $agent-dashboard:pr.
Phase 6: Cleanup (on merge)
Triggered when the user indicates the feature has been merged upstream.
- Verify the branch is merged (warn if unmerged commits remain)
- Tear down environment resources: remove symlinks, stop dev servers or emulators, release any browser lease, remove worktree-local UI scratch state, delete
.env-setup-done/.env-setup-failed/.feature-plan-pathsentinel files - Remove worktree and delete branch
- Confirm cleanup is complete
Red Flags — STOP
Failure modes the MUST block doesn't already cover. If you catch yourself saying any of these, pause:
- "I'll just sketch the implementation first" → Phase 3 RED violation. Delete and restart.
- "The plan is obvious, let me start" → Phase 2 gate violation. Wait for
<proposed_plan>approval. - "Tests pass on my reading of the code" → didn't run
make test. Run it. - "I'll just call
gh pr createdirectly" → Phase 5 violation. Thepr-skill-gatehook will block it; use$agent-dashboard:pr. - "I'll bundle this unrelated cleanup into the feature commit" → split it into a separate PR.
- "User picked hand-off, but I'm already here — I'll just do Phase 3 myself" → exit cleanly. They opted out of inline TDD for a reason; don't second-guess.