15 /goal Examples You Can Copy-Paste (With Exit Conditions)
15 /goal Examples You Can Copy-Paste (With Exit Conditions)
A goal loop is the simplest useful agent loop: state an outcome, give the agent a mechanical way to check it, cap the iterations, and let it run. The whole art is in the exit condition — if the check isn't a command with an exit code, the agent will argue it's done instead of being done.
Every example below follows the same template. Swap in your own commands and paste into your harness, or feed any of them to the [builder](/builder) to get a runnable script.
/goal <outcome> exit: <command that returns 0 when true> budget: <max iterations>, <max wall-clock> scope: <paths the agent may touch>
Browse the full goal-loop collection at [/type/goal](/type/goal).
Testing & CI
### 1. Tests pass and lint is clean
The canonical first loop. Directory: [fix-tests-and-lint](/loops/fix-tests-and-lint).
/goal all tests pass and lint is clean exit: npm test && npm run lint budget: 15 iterations, 60m scope: src/, tests/ — never delete or skip a test to make it pass
### 2. Kill the flaky tests
Note the exit condition: consecutive passes, not one lucky run. Directory: [kill-flaky-tests](/loops/kill-flaky-tests).
/goal the test suite passes 10 consecutive runs with zero flakes exit: for i in $(seq 10); do npm test || exit 1; done budget: 25 iterations, 3h scope: tests/, src/ — fix root causes; quarantining a test requires a TODO comment with the reason
### 3. Get the build green
/goal CI is green on this branch exit: gh run watch --exit-status budget: 10 iterations, 90m scope: anything except .github/workflows/ — fixing the code is allowed, gaming the pipeline is not
Directory: [get-the-build-green](/loops/get-the-build-green).
### 4. Reach a coverage target
/goal line coverage is at or above 80% exit: npm test -- --coverage && node scripts/check-coverage.mjs 80 budget: 20 iterations, 2h scope: tests/ only — write tests for existing behavior, do not modify src/ to be "more testable"
Directory: [reach-coverage-target](/loops/reach-coverage-target).
### 5. Ship the PR until it's green
A goal loop wrapped around CI feedback. Directory: [ship-pr-until-green](/loops/ship-pr-until-green).
/goal PR #482 passes all required checks exit: gh pr checks 482 --required budget: 12 iterations, 2h scope: the PR branch only — respond to CI failures with fixes, push, re-check
Types, lint, and formatting
### 6. TypeScript strict mode, zero errors
/goal the repo compiles under "strict": true exit: npx tsc --noEmit budget: 30 iterations, 4h scope: src/ — no `any`, no `@ts-ignore` without a comment justifying it
### 7. Format until clean
/goal formatter and import sort produce zero diffs exit: npx prettier --check . && npx eslint --max-warnings 0 . budget: 5 iterations, 20m scope: whole repo except generated files listed in .prettierignore
Directory: [format-until-clean](/loops/format-until-clean).
Refactoring & cleanup
### 8. Delete all dead code
/goal knip reports zero unused exports, files, or dependencies exit: npx knip budget: 15 iterations, 90m scope: src/, package.json — every deletion must keep `npm test` passing
Directory: [dead-code-elimination](/loops/dead-code-elimination).
### 9. Burn down the TODOs
/goal zero TODO/FIXME comments older than 90 days remain exit: node scripts/stale-todos.mjs --max-age 90 --fail-on-found budget: 20 iterations, 2h scope: src/ — each TODO is either fixed or converted to a tracked issue with a link
Directory: [todo-burn-down](/loops/todo-burn-down).
### 10. Migrate an API, callsite by callsite
/goal no callers of the deprecated v1 client remain exit: ! grep -rn "from '@lib/api-v1'" src/ && npm test budget: 25 iterations, 3h scope: src/ — migrate one module per iteration, tests pass after each
Directory: [migrate-an-api](/loops/migrate-an-api).
Security & dependencies
### 11. Secrets scan comes back clean
/goal gitleaks finds zero secrets in the working tree exit: gitleaks detect --no-git --exit-code 1 && echo clean budget: 8 iterations, 45m scope: whole repo — move secrets to env vars, add patterns to .gitleaksignore only for confirmed false positives
Directory: [secrets-scan-clean](/loops/secrets-scan-clean).
### 12. Upgrade dependencies, one at a time
/goal zero outdated minor/patch dependencies, tests green after each bump exit: npm outdated --json | node scripts/only-majors-left.mjs budget: 30 iterations, 4h scope: package.json, lockfile — ONE package per iteration, commit per package, revert on test failure
Directory: [dependency-upgrade-one-at-a-time](/loops/dependency-upgrade-one-at-a-time).
Performance & database
### 13. Hunt the N+1 queries
/goal the request-path query count in the perf suite is under budget exit: npm run perf:queries -- --budget 12 budget: 15 iterations, 2h scope: src/db/, src/api/ — add eager loading or batching; schema changes need human review
Directory: [n-plus-one-query-hunt](/loops/n-plus-one-query-hunt).
### 14. Hold the bundle-size line
/goal the client bundle is under 250 kB gzipped exit: npm run build && node scripts/check-bundle-size.mjs 250 budget: 12 iterations, 90m scope: src/, next.config.mjs — code-split and prune; removing user-facing features is out of bounds
Directory: [bundle-size-budget](/loops/bundle-size-budget).
### 15. Apply migrations until the schema matches
/goal migrations apply cleanly to a fresh database and schema matches models exit: dropdb --if-exists loop_test && createdb loop_test && node scripts/migrate.mjs && node scripts/schema-check.mjs budget: 10 iterations, 60m scope: db/migrations/ — additive migrations only; destructive changes stop the loop for human review
Directory: [apply-db-migrations](/loops/apply-db-migrations).
The pattern behind all 15
Three rules, no exceptions:
1. The exit condition is a command. If you can't && it in a shell, it's not an exit condition.
2. The scope names what's forbidden, not just what's allowed. The failure mode of every goal loop is achieving the letter of the goal by violating its spirit — deleting tests, skipping checks, gutting features.
3. The budget is enforced by the harness. The model doesn't count its own iterations; your script does.
Long-running loops also deserve a notification path — a loop that finishes at 3am and tells no one might as well not have run. One ConnectMyEmail hook at the end of the harness fixes that.
Got a goal that isn't on this list? Feed it to the [loop builder](/builder) — it'll pressure-test your exit condition, attach a budget, and hand back a harness you can run today.