---
name: ayf:goal
description: |
  Sustained all-day autonomous work: decompose one big objective into tasks and
  work them back-to-back until done. Usage: /goal <objective> | /goal status.
allowed-tools:
  - Read
  - Write
  - Edit
  - Bash
  - Glob
  - Grep
  - Agent
  - AskUserQuestion
---

# /goal -- Sustained Objective Runner

`/goal` turns a single large objective into a self-driving queue of tasks and works
them one after another, unattended, until they are all DONE or the session ends. Use
it when you want Claude to make progress on a big goal all day without babysitting
each task. For *recurring* checks on a fixed interval, use `/loop` instead (see
**Sustained Work** in CLAUDE.md).

Two forms:

- `/goal <objective>` -- set the objective, decompose it, and start the worker loop.
- `/goal status` -- report progress on the active goal (X of Y tasks done).

Resolve `.ay/` first (works from any worktree):

```bash
AY="$(dirname "$(git rev-parse --git-common-dir 2>/dev/null)")/.ay"
```

---

## `/goal status` — report progress

If the argument is exactly `status`, do NOT start any work. Instead:

1. If `$AY/goal.md` does not exist, say "No active goal. Start one with
   `/goal <objective>`." and stop.
2. Read `$AY/goal.md`. Extract the objective, status, and the list of task IDs.
3. For each task ID, look up its current status in `$AY/tracking/BOARD.md`.
4. Print a short report:
   ```
   Goal: <objective>   (status: active)
   Progress: 3 of 6 tasks done
     [x] 80 — <title>        DONE
     [x] 81 — <title>        DONE
     [~] 82 — <title>        IN PROGRESS
     [ ] 83 — <title>        READY
     ...
   ```
5. If every task is DONE, set `Status: done` in `$AY/goal.md` and say the goal is
   complete. Stop.

---

## `/goal <objective>` — set up and run

### Step 1 — Record the goal

Write `$AY/goal.md` (overwrite any prior goal only after confirming with the human if
one is still `active`):

```markdown
# Goal — <objective>

- **Objective:** <objective, verbatim>
- **Status:** active
- **Started:** <ISO-8601 UTC>
- **Updated:** <ISO-8601 UTC>

## Tasks
<!-- filled in Step 2; one line per task: "- [ ] {id} — {title}" -->
```

Get timestamps with `date -u +%Y-%m-%dT%H:%M:%SZ`.

### Step 2 — Decompose into tasks

Break the objective into **3–8 concrete, independently-shippable tasks**. Each task
must be atomic (one clear deliverable, ideally < 5 files) and ordered so earlier
tasks unblock later ones. Avoid vague tasks ("improve X") — every task needs a
verifiable done-state.

1. Determine the next free numeric task IDs (never reuse an existing one):
   ```bash
   last=$(grep -oE '^\|\s*[0-9]+' "$AY/tracking/BOARD.md" | grep -oE '[0-9]+' \
     | sort -n | tail -1)
   next=$((last + 1)); echo "first new id: $next"
   ```
2. For each task, create a task file `$AY/tasks/{id}-{slug}.md` (use the task
   template if present at `$AY/tasks/_template.md`) with What / Why / Deliverables /
   Acceptance sections.
3. Append each task to `$AY/tracking/BOARD.md` as a **READY** row under a
   `## Goal: <objective>` section:
   ```
   | {id} | {title} | goal-runner | READY | {blocked-by or -} |
   ```
4. Record the task IDs back into the `## Tasks` block of `$AY/goal.md` as
   `- [ ] {id} — {title}` lines.

Present the decomposition to the human as a numbered list before looping. This is the
one lightweight gate — if they say adjust, revise the tasks; otherwise proceed
immediately (do not wait for a second confirmation).

### Step 3 — Worker loop

Now work the tasks back-to-back. Repeat this cycle until **all goal tasks are DONE**
or the session must end:

1. **Pick** the next task from the goal whose BOARD status is READY and whose
   dependencies (Blocked By) are all DONE. If none are READY but some are BLOCKED,
   re-check whether a just-completed task unblocks them; if still none, stop and
   report.
2. **Claim** it: create `$AY/tracking/locks/task-{id}.lock` (agent `goal-runner`,
   ISO timestamp, session id) and set the BOARD row to IN PROGRESS. If a lock
   already exists, skip to the next task.
3. **Work** it. For non-trivial tasks, run the standard `/go` BUILD discipline:
   follow a short plan, verify as you go, and self-review. Honor the **Fix-Loop
   Cap** — after 3 consecutive failed checkpoints on one task, stop that task, write
   a BLOCKER, and move to the next task rather than looping.
4. **Finish**: verify the deliverable actually works (read files back, run
   build/tests), then set the BOARD row to DONE, delete the lock, tick the task in
   `$AY/goal.md` (`- [x] {id} — {title}`), update `Updated:`, and append a one-line
   entry to `$AY/tracking/AGENTS-LOG.md`. Write a HANDOFF entry if there are
   gotchas for later tasks.
5. **Continue** to the next task automatically — do not ask the human between tasks.

### Step 4 — Stop conditions

Stop the loop and report when any of these is true:

- **All goal tasks are DONE** → set `Status: done` in `$AY/goal.md`, print a summary
  (tasks completed, files touched), and stop.
- **Context pressure ≥ 85%** (see the Context-Pressure check in `/go`) → `/pause` to
  snapshot state to `.ay/sessions/`, leave `Status: active`, and tell the human how
  to resume (`/goal` re-reads `goal.md` and continues the remaining READY tasks).
- **A task escalates** (fix-loop cap hit / genuine blocker) → record the BLOCKER,
  keep working other READY tasks, and surface the blocker in the final report.
- **No READY tasks remain but some are BLOCKED/DONE-incomplete** → report what is
  blocking and stop.

### Resuming

Running `/goal` again with no new objective (or `/goal <same objective>`) while a
goal is `active` resumes the loop: re-read `$AY/goal.md`, skip DONE tasks, and pick
up the next READY one. Only start a fresh decomposition when the objective is new or
the prior goal is `done`.
