name: pinpoint-agy-execute description: End-to-end runbook for Antigravity to pick an agy-ready bead, implement it, and bring it to ready-for-review. Follow every step in order. Do not skip steps.
pinpoint-agy-execute
When to invoke: Tim says "find an agy-ready bead and take it to review", "work on PP-xxx (it's agy-ready)", or any equivalent instruction to start executing a tagged bead independently.
Step 0 — Verify environment
Confirm you are in a properly-configured worktree before touching any code:
git rev-parse --show-toplevel— the path must be under.claude/worktrees/or another non-primary worktree path (not the main repo clone).git branch --show-current— must be a feature branch, NOTmain.- Confirm
.env.localexists in the worktree root (generated by the Huskypost-checkouthook viascripts/worktree_setup.py). - Confirm
supabase/config.tomlexists and is not the template (the file is chmod 444 when generated).
The Antigravity GUI creates the worktree at session launch; the post-checkout hook allocates the slot, generates .env.local, writes supabase/config.toml, and records the port assignment. If any of those artifacts are missing, stop and tell Tim — do not attempt to repair the worktree yourself.
Step 1 — Pick the bead
Dispatched via pinpoint-agy-dispatch: The initial prompt names the bead explicitly (first line is a specific imperative, e.g. "Implement PP-xxx: …"). Use that bead ID. Still verify the agy-ready label per the rule below before proceeding.
With no bead specified: Run bd query "label=agy-ready AND status=open" --priority-max=2. Pick the top result by priority, then by ID (lexicographic tiebreak). If the list is empty, tell Tim there are no tagged candidates and stop.
With a bead ID specified: Skip the query. Verify the bead has the agy-ready label by running bd show <id> and checking the LABELS line. If the label is absent, refuse to proceed and ask Tim to confirm the bead is groomed.
Detect agy-ui: Also check whether the bead carries the agy-ui label. If it does, browser verification is required at Steps 5 and 11 — note this now so you don't miss it later.
Step 2 — Claim
bd update <id> --status=in_progress
bd comment <id> 'Antigravity starting. Branch: <current-branch>. Picking up this bead now.'
Step 3 — Read the bead
Run bd show <id> (again, in full). Read:
- Description
- Acceptance criteria
- All comments (especially Tim's notes and any grooming decisions)
If at any point the bead reveals an open decision that the gates should have caught — an unresolved Option A / Option B fork, a "discuss with user" marker, a missing file path — stop immediately. Post:
bd comment <id> 'Stopped at Step 3. Open decision found: <describe the gap>. Re-groom before resuming.'
Do not proceed. Tim or Claude will re-groom.
Step 4 — Implement
Follow the acceptance criteria literally. Do not interpret, extrapolate, or improve beyond what is stated.
- Re-use existing utilities — don't invent helpers when something equivalent exists.
- Never
git add -Aorgit add .— always add specific files by name. - If a design ambiguity surfaces mid-implementation despite gating, stop and post a
bd commentdescribing the ambiguity. Do not make a judgment call and continue. - Drizzle migrations only:
pnpm run db:generatethenpnpm run db:migrate. Neverdrizzle-kit push. Neverdb:resetagainst any non-local DB.
Step 5 — Verify
Run the exact verification command named in the bead description. Default fallback if none is named:
pnpm run check
If the bead requires integration tests or a migration:
pnpm run preflight
The preflight command is capped at 2 host-wide concurrent runs via sem --jobs 2. Accept the wait — do not use preflight:unlocked unless Tim explicitly says to.
Fix any failures. If a failure is unrelated to your change and was pre-existing, note it in the PR description but do not abandon — fix your change so the pre-existing failure is the only one remaining, and call it out explicitly.
agy-ui branch: If the bead carries the agy-ui label, do the following after the automated verification passes and before opening the PR (Step 8):
- Start Supabase:
supabase start - Start the dev server:
pnpm dev- The assigned port is in
.env.local(keyPORT; the full URL isNEXT_PUBLIC_SITE_URL) and.claude/launch.json.
- The assigned port is in
- Use
/browserto open the app at the worktree's port. - Confirm the acceptance criteria render/behave correctly as stated in the bead.
/browser grants Chrome access only — it does not start the stack. You must run steps 1–2 yourself before using it. If you cannot start Supabase (port collision, stuck container), stop and ask Tim.
Step 6 — Commit
git add <specific files only>
git commit -m "$(cat <<'EOF'
<type>(<scope>): <subject> (<bead-id>)
<body if needed>
Co-Authored-By: Antigravity <noreply@google.com>
EOF
)"
Hard rules:
- Never
--no-verify. - If the pre-commit hook fails, fix the issue and create a new commit. Do not
--amend— amending after a hook failure modifies the previous commit, losing the fix trail. - Commit message format:
feat(scope): description (PP-xxx)— lowercase type, parens around scope, bead ID in parens at end.
Step 7 — Push
First push (new branch):
git push -u origin <current-branch>
Subsequent pushes:
git push
Verify tracking: git branch -vv must show [origin/<branch>], not [origin/main]. If tracking shows [origin/main], you are about to push to the wrong remote ref — stop and correct with git branch --set-upstream-to=origin/<current-branch>.
Step 8 — Open PR
Use GitHub MCP (preferred — runs inside Antigravity's MCP context):
mcp__github__create_pull_request(
owner: "timothyfroehlich",
repo: "PinPoint",
title: "<type>(<scope>): <subject> (<bead-id>)",
body: <see template below>,
head: "<current-branch>",
base: "main",
draft: false
)
Fall back to gh pr create --title "..." --body "..." only if MCP is unavailable.
PR body template:
## Summary
<1-3 bullet points describing what changed>
## Bead
<bead-id>: <bead title>
## Verification
Commands run:
- `<exact command(s) from Step 5>`
Result: all passing.
## Notes
<any pre-existing failures, deliberate omissions from the bead's "out of scope", or noteworthy decisions>
Open as non-draft (i.e., draft: false) — the ready-for-review label is applied later in Step 10 after CI is green.
Step 9 — Watch CI
./scripts/workflow/pr-watch.py <PR-number>
If pr-watch.py is not usable in Antigravity's harness, poll via MCP:
mcp__github__pull_request_read(
method: "get_status",
owner: "timothyfroehlich",
repo: "PinPoint",
pullNumber: <PR-number>
)
Wait for the CI Gate check to complete. Only CI Gate is required (Vercel is not required). BLOCKED while E2E is running is normal — wait it out.
If CI fails: diagnose, fix, commit (Step 6), push (Step 7), repeat from Step 9. Do not open a new PR.
Step 10 — Label ready-for-review
Once CI is green:
agy-ui branch: Before applying the label, re-verify the UI. Late fixes may introduce regressions. Use /browser to open the app at the worktree's port and confirm the acceptance criteria still hold. If the stack is no longer running, restart it (supabase start + pnpm dev) first — /browser grants Chrome access only.
Once UI verification passes (or the bead has no agy-ui label):
mcp__github__update_pull_request(
owner: "timothyfroehlich",
repo: "PinPoint",
pullNumber: <PR-number>,
labels: ["ready-for-review"]
)
Or via gh:
gh pr edit <PR-number> --add-label ready-for-review
Step 11 — Hand off
bd comment <id> 'PR #<number> open and labeled ready-for-review: <PR-URL>
Summary: <2-3 sentence description of what changed>
Verification: <commands run + outcome>
Do not merge — Tim reviews and merges.'
Do not merge. The block-direct-merge.cjs hook refuses mcp__github__merge_pull_request and gh pr merge — do not attempt either.
Hard Rules
These apply throughout every step. No exceptions without explicit Tim approval.
- Never
--no-verifyon any git command. - Never
gh pr mergeormcp__github__merge_pull_request— Tim merges. - Sync via merge, never rebase:
git fetch origin && git merge origin/main. Rebase rewrites SHAs, forces push, breaks guardrails. bd show <id>andbd readyare the source of truth for scope. If reality diverges from the bead, stop and update the bead first.- If sandboxed / cannot run
chmod: ask Tim to runchmod +x <path>andgit update-index --chmod=+x <path>manually (per~/.claude/CLAUDE.md). - Drizzle migrations only:
db:generate+db:migrate. Neverdrizzle-kit push. Neverdb:resetagainst any non-local DB. localhost, not127.0.0.1: cookie host isolation breaks Supabase SSR auth across the two.git add <specific files>: nevergit add -Aorgit add ..