Delegate an implementation task to a headless Antigravity (`agy`) session in write mode, inside an isolated git worktree, then verify the result with a cross-family review pass before it merges. Use when the user wants a second model family's implementation attempt, wants to offload a well-scoped coding task, or explicitly asks to let agy implement something.
Installs into .claude/skills of the current project.
Are you the author of Agy Implement?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/aarontzeng-agy-implement)
---
name: agy-implement
description: Delegate an implementation task to a headless Antigravity (`agy`) session in write mode, inside an isolated git worktree, then verify the result with a cross-family review pass before it merges. Use when the user wants a second model family's implementation attempt, wants to offload a well-scoped coding task, or explicitly asks to let agy implement something.
---
# Delegate implementation to agy, then verify
Complements `agy-adversarial-review` (review-only intent via `--mode plan`).
This skill goes the other direction: agy **writes code**, so the safety comes
from three stacked boundaries — worktree isolation, the sandbox with a
targeted allow-list, and mandatory review before anything reaches the main
branch.
## Before the first run of a session
Read **[`../agy-adversarial-review/references/agy-runtime.md`](../agy-adversarial-review/references/agy-runtime.md)**.
It holds the
family-level mechanics shared by both agy roles — the permission allow-list,
the `--add-dir` workspace trap, the silent-death mode, auth diagnosis, and
the model catalogue. This file assumes you know them and covers only what
makes a run an *implementation*.
Three runtime facts this role depends on directly:
- **This role needs TOOL permissions, not just the `unsandboxed(...)` shell
rules — and it is the role that finds out.** An empty `permissions.allow`
loads as `permissions=<nil>` and falls back to asking a human who is not
there, so the first tool call is auto-denied and the run dies having read
nothing. The review role survives that (its prompt hands it a pre-written
diff), this one does not. Add `read_file(<worktree>/**)` and
`write_file(<worktree>/**)` scoped to the worktree, never the home
directory. Full diagnosis, and why the error message's own suggested fix is
the wrong one, in the runtime file's permission section.
- The **write set** is the read-only git rules plus `unsandboxed(git add)`,
`unsandboxed(git commit)`, and the pinned test-runner spellings (a ruled
exception — the runtime file carries the ruling and what it costs).
`push`, `reset`, `checkout`, `clean` and `worktree` are deliberately
absent, which keeps no-push machine-enforced everywhere except inside the
test-runner process. Never reach for `--dangerously-skip-permissions` to
unblock something.
- **A run that returns nothing did not necessarily do nothing** — an
auto-denied permission kills the run with zero output while edits made
before the denial are already on disk. The forensic commands are in the
runtime file; run them after every failed, empty, or timed-out run.
## Why a worktree, always
`agy` runs with `--mode accept-edits` — it can create, edit, and delete
files. Two agents editing the same tree at once is a documented failure
class. There is no version of this skill that skips the worktree.
```bash
RUN_DIR=$(mktemp -d "${TMPDIR:-/tmp}/agy-implement.XXXXXX") # FIRST — the snapshot below lands here
BASE=$(git rev-parse HEAD) # from a clean checkout, recorded before anything
WORKTREE=../<repo>-agy-<short-task-slug>
git worktree add -b agy/<short-task-slug> "$WORKTREE" "$BASE"
# The helper lives in the SUITE's tree, cwd is the TARGET repo — a bare
# `scripts/…` resolves against the target and exits 127.
DEV_LEAD=${DEV_LEAD_ROOT:-$(ls -d "$HOME"/.claude/plugins/cache/dev-lead/dev-lead/* 2>/dev/null | sort -V | tail -1)}
[ -x "$DEV_LEAD/scripts/snapshot-refs.sh" ] || { echo "dev-lead root unresolved — set DEV_LEAD_ROOT to your checkout"; exit 1; }
"$DEV_LEAD/scripts/snapshot-refs.sh" save "$WORKTREE" "$RUN_DIR/remote-refs.before" # push-detection baseline
```
Verify against that exact SHA later — never against the moving branch name.
The remote-refs snapshot exists because of the test-runner ruling: inside
that process the no-push rule is instruction-level only (runtime file), and
this baseline is what the handoff check diffs against to make the residual
risk observable instead of assumed away.
## Run it
```bash
# RUN_DIR was created in the worktree step above.
# Write the task prompt to "$RUN_DIR/task.md" in its own step.
# Confirm this Gemini model is in the account catalogue; if not, pick an
# available suffix variant.
AGY_MODEL=gemini-3.8-flash-high
agy -p "$(cat "$RUN_DIR/task.md")" \
--model "$AGY_MODEL" \
--mode accept-edits \
--sandbox \
--add-dir "$WORKTREE" \
--disable-slash-commands \
--print-timeout 20m0s
```
Unlike the review role, this one keeps `--disable-slash-commands`: measured,
it does not cancel `--mode accept-edits` (it cancels `--mode plan` only — see
the [runtime file](../agy-adversarial-review/references/agy-runtime.md)), so
there is no no-write layer here to lose.
Role-specific choices:
- **`--mode accept-edits`** is the write mode and the whole point.
- **`--add-dir "$WORKTREE"`** — the worktree, never the main checkout.
- **`--print-timeout 20m0s`** — implementations run longer than reviews.
- **Gemini model tier** — the default is `gemini-3.8-flash-high` (the
roster's), with the `-high` suffix; the suffix IS the effort, so change only
`AGY_MODEL` to `-medium` or `-low` if the task calls for it, nothing else.
Verify from the log which model actually served (runtime file); a model
with no calibration rows on your account is calibration, not a gate.
- **Model family** — if the CLI exposes a second family's pool on separate
quota, that pool's strong model is a legitimate implementer too (diversity
constrains the reviewer, not the implementer). `--effort` stays absent for
Claude models too — there it is rejected outright (see runtime: the model-id
suffix is the effort control in both pools, so the flag is never needed).
## Writing the task prompt
- **Premise preflight** (this exact clause would have prevented a measured
failure): instruct agy to first compare every factual claim in the task
against the current code, tests, and ADRs, and to STOP and report the
contradiction instead of editing if any premise is wrong. The incident: a
task said "remove the duplicate query" when the second query was a
deliberate last-moment safety re-check; the delegate faithfully removed
it, and only the next review round caught the regression. The task
author's description of the code is a hypothesis, not a fact.
- **State the task precisely**: acceptance criteria, exact files/directories
in scope, and the absolute worktree path as the working root.
- **Git rules to state verbatim**: MAY `git add`/`git commit` on the
worktree branch; NEVER push, reset, checkout/clean, or touch another
branch (the allow-list enforces this; saying it avoids wasted denied
attempts). Plain-English commit messages, no AI-authorship trailers.
- **Point it at the repo's own standards** — the governing
`CLAUDE.md`/`AGENTS.md` for the touched area, not conventions it invents.
- **Say the finishing steps are ACCEPTANCE CRITERIA, not closing etiquette.**
Two measured failures, same shape: a run that edited nothing because "run
the whole suite before finishing" was read as a FIRST step — it backgrounded
the suite, had nothing left to do while waiting, and ended its turn with a
clean worktree and a one-line report; and a run that produced good work and
never committed it, with `git add`/`git commit` allow-listed and the prompt
explicitly permitting them. Permission to do something is not an instruction
to do it. Write both as numbered criteria the delegate must satisfy, and for
the suite say WHERE it runs: "run it in the FOREGROUND and wait for it; do
not background it and end your turn."
- **Every shell command the brief itself mentions must be allow-listed — the
delegate runs exactly what you wrote.** Measured 2026-09-06, twice in one
hour: a brief said "find the file with `ls tests | grep adjusted`", the next
revision listed `npx vitest run` as the test spelling; neither was
allow-listed and each killed the run at that step with zero output and
nothing on disk. The fix is not a bigger allow-list: list in the brief the
ONLY spellings that exist (the git reads, `git add`/`commit`, the pinned
runners, `grep`/`rg`/`head`/`tail`/`wc`), say anything else — `ls`, `cat`,
`sed`, `find`, `npx`, pipes — kills the run, and put file names in the brief
instead of telling the delegate how to discover them.
- **Tests: PIN the exact command, because only the allow-listed spellings
exist.** Any other spelling (`.venv/bin/pytest`, `uv run pytest`,
`make test`) is auto-denied and **kills the whole run with zero output** —
the model never gets to "handle" the denial. The task prompt states: "run
tests ONLY as `python3 -m pytest <paths>`; no other test/build command
exists for you." Non-pytest repos stay on the old division of labor —
delegate writes, lead runs — until their runner earns its own deliberate
allow-list ruling. The lead re-runs the suite after handoff regardless:
self-testing is the delegate's feedback loop, not the verification.
- **List the existing tests and mock seams the change is expected to
break.** The single largest measured failure class — 18 broken existing
tests across two rounds — was the delegate changing a queried behavior
without seeing which existing tests mock that seam. Before dispatch, grep
the touched functions for their test-side mocks and patches, and name them
in the prompt: "these N tests mock `X.y`; your change moves that seam, so
update them as part of the task."
- **Anchor every NEW test to a position, not just a file**: "add it to class
`TestX`, immediately after `test_y`". The measured incident: a
class-method-shaped test landed outside its class, parsed as a nested
function, and was NEVER COLLECTED — green suite, zero protection, caught
only by the lead's mutation check.
- **Say the test run must be in the FOREGROUND, in the same step.** This
delegate backgrounds its own `pytest` and then ends its turn waiting for a
completion notification that will never arrive — the same leaf failure the
suite documents for subagents, except here the delegate does it to itself.
Measured twice on `gemini-3.8-flash-high`: once with zero edits after 20
minutes, and once (2026-09-05) with the whole implementation finished and
correct but never verified, shipping two red guardrail tests the delegate
would have seen in one run. The second time the task prompt did not carry
this clause, which is the control: the trap is the model's DEFAULT, not a
regression. Put it in verbatim — "run the test command in the foreground and
read its output in the same step; nothing will notify you; a turn that ends
in 'waiting for the test suite' has abandoned the task" — and treat a run
whose log ends on that sentence as complete-but-unverified: take the work,
do not re-dispatch it.
- **No recursive delegation**: "do not invoke agy, other CLIs, or any review
script."
## After it finishes: verify before anything is trusted
1. In the worktree: `git log "$BASE"..HEAD --oneline`,
`git diff "$BASE"...HEAD`, `git status --short`. Scope discipline is
verified, not assumed. Check commit messages for AI-authorship trailers —
an amend is free while the branch is local. Then the push check the
test-runner ruling depends on — a later step is a NEW shell and `$DEV_LEAD`
does not survive into it, so re-resolve before using it:
```bash
DEV_LEAD=${DEV_LEAD_ROOT:-$(ls -d "$HOME"/.claude/plugins/cache/dev-lead/dev-lead/* 2>/dev/null | sort -V | tail -1)}
"$DEV_LEAD/scripts/snapshot-refs.sh" check "$WORKTREE" "$RUN_DIR/remote-refs.before" || exit 1
```
Any delta means something pushed during the run: a stop-and-report
incident, never a shrug. (A successful `git push` updates the
remote-tracking ref, which this catches; a review-system push
(`refs/for/*`) does not create one, so the check is a tripwire for the
common case, not an alibi — which is why the allow-list still excludes
`git push` itself.)
2. **Run the test suite yourself**, in the worktree, regardless of what agy
self-reported.
3. **Mutation-check every new regression test**: run it against the pre-fix
code and confirm it FAILS; restore, confirm it passes. A test that passes
against the code it claims to guard is a mirror, not a test — the
measured case was a test whose own harness re-patched the mock it
depended on, so it exercised nothing. If mutation-checking is
impractical, say so and do not call the test a regression proof.
4. Review — see "The loop" below.
5. Merge (fast-forward from the worktree branch) and tear down the worktree
**only after the diff and the verified findings are approved** — by the user, or, where the
roster sets `merge_gate.mode = lead`, by a fully green verdict itself;
anything not green, and any stricter project contract, still goes to the person — then the lead pushes to the ref the project's contract names
and reports it. The delegate never pushes.
## The loop (implement → review → fix → re-verify)
1. **R1**: agy implements in the worktree (this skill).
2. **Review gate**: a reviewer from a *different model family* than the
implementer. Two contexts of the same family are a fresh look, not model
diversity. When quota is tight, spend the scarce model on review.
3. **Verify findings yourself** before acting — measured hit rates run well
below 100%, and acting on a wrong finding writes a wrong fix. Hold your
own rejections to the same evidence standard.
4. **R2**: a new task in the SAME worktree, new commit on top. Quote each
verified finding verbatim, with why it is real and what fix is required.
R2 tasks written this way have fixed all findings on the first try; vague
"address the review" tasks have no track record.
5. **Re-verify** (steps 1–3, including mutation checks on R2's new tests).
Small, precisely diagnosed defects you find yourself are yours to fix
directly — a third delegation round for a one-line fix costs more than it
protects.
6. Merge gate as above.
## What this skill is not
Not a way to skip review — it moves *who types the code*, not *who is
accountable for it being correct*. For a tiny change, writing and
supervising the task costs more than implementing directly; do that instead.