Skip to main content
ClaudeWave
Skill510 repo starsupdated today

Goal Tracker

Goal Tracker compares current progress on goals listed in MEMORY.md against quantified metrics including velocity (activity in 14 and 30 day windows), trend data from prior runs, and blocker signals detected in logs, commits, and pull requests. Use it to assess goal momentum, identify stalled efforts, and surface a concrete next action for each incomplete goal.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/aaronjmars/aeon /tmp/goal-tracker && cp -r /tmp/goal-tracker/skills/goal-tracker ~/.claude/skills/goal-tracker
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

<!-- autoresearch: variation B — quantified OKR-style status with velocity, trend vs prior run, and one concrete next action per non-DONE goal -->

> **${var}** — Specific goal title or slug to focus on. If empty, tracks all goals in MEMORY.md.

Read `memory/MEMORY.md` (for the goal list) and `memory/goal-state.json` (prior-run snapshot, if it exists).

## Inputs

**Primary goal source:** `memory/MEMORY.md` section titled `## Goals`. If absent, fall back to `## Next Priorities`. If both are missing or empty, send `./notify "Goal Tracker — NO_GOALS (add a '## Goals' section to memory/MEMORY.md)"` and exit.

**Evidence sources (use every source that responds; record each in the source-status footer):**
- `memory/logs/*.md` — last 30 days. Case-insensitive whole-word match against keywords parsed from each goal title.
- `git log --since="30 days ago" --pretty=format:"%ad|%s" --date=short` — commit subjects.
- `gh pr list --state=all --search "updated:>=$(date -d '30 days ago' +%F)" --json number,title,state,updatedAt,url` — recent PRs.
- `gh issue list --state=all --search "updated:>=$(date -d '30 days ago' +%F)" --json number,title,state,updatedAt,url` — recent issues.
- `memory/cron-state.json` — skill health; relevant when a goal depends on a skill running (e.g., "run first digest").

If `${var}` is set, filter to the matching goal after loading.

## Steps

### 1. Parse goals and prior state

For each goal entry, derive:
- `id` — slugified title (stable across runs)
- `title` — original text
- `keywords` — title minus stopwords (also include obvious aliases, e.g. "digest" ↔ "rss-digest")
- `due` / `target` — parse if present in the bullet, else null

If `memory/goal-state.json` exists, load `{goal_id: {status, activity_count_14d, last_activity_date, run_at}}` for trend comparison.

### 2. Gather evidence per goal

Across all responsive sources, compute:
- `activity_count_14d` — distinct matching entries in last 14 days
- `activity_count_30d` — same, 30-day window
- `last_activity_date` — most recent matching evidence (any source); null if none
- `days_since_last_activity` — today minus `last_activity_date`
- `completion_signal` — true if a log/commit/PR entry pairs the goal's keywords with phrases like "completed", "done", "shipped", "launched", "closed", "merged" (goal-specific PRs only)
- `blocker_signal` — true if a log entry in the last 14 days pairs keywords with "blocked", "waiting on", "stuck on"; capture the blocker phrase

Dedupe evidence by `(source, date, ref)` so a log mentioning a PR doesn't double-count.

### 3. Assign status (apply rules in order — first match wins)

| Status | Rule |
|--------|------|
| DONE | `completion_signal` is true, OR the goal is already marked complete in MEMORY.md |
| BLOCKED | `blocker_signal` is true within the last 14 days |
| ON TRACK | `activity_count_14d >= 2` AND `days_since_last_activity <= 7` |
| NEEDS ATTENTION | `activity_count_14d == 1` OR `days_since_last_activity` between 8 and 14 inclusive |
| AT RISK | `activity_count_14d == 0` AND (`days_since_last_activity > 14` OR no activity ever) |

### 4. Compute trend vs prior snapshot

- `improving` — status moved up the ladder (AT RISK → NEEDS ATTENTION → ON TRACK → DONE) OR `activity_count_14d` rose by ≥50%
- `flat` — same status AND `activity_count_14d` within ±25%
- `degrading` — status moved down OR `activity_count_14d` fell by ≥50%
- `new` — no prior record

### 5. Propose one concrete action per non-DONE goal

Pick the single highest-leverage next step for each goal. Rules:
- **AT RISK** with `days_since_last_activity > 21` → name a specific Aeon skill to enable, a concrete commit, or a file to create (e.g., "Enable `rss-digest` in aeon.yml to produce the weekly digest evidence").
- **BLOCKED** → name the blocker and one unblock step.
- **NEEDS ATTENTION** → name the smallest next deliverable.
- **ON TRACK** → omit action line entirely.

Use one action verb. ≤15 words. No vague "continue monitoring" advice. No action = skip the line, don't fill with filler.

### 6. Format the report

```
*Goal Tracker — ${today}*

Summary: N goals — X at risk, Y needs attention, Z on track, W blocked, V done (overall ↑ improving / → flat / ↓ degrading)

AT RISK (sorted by days_since_last_activity, descending)
• <goal title> — 18d idle, 0 activity/14d (was NEEDS ATTENTION ↓)
  → Action: <one-verb next step>

NEEDS ATTENTION
• <goal title> — 9d idle, 1 activity/14d (new)
  → Action: <one-verb next step>

BLOCKED
• <goal title> — waiting on <blocker> since <date>
  → Action: <unblock step>

ON TRACK
• <goal title> — 3d idle, 5 activity/14d (↑ improving)

DONE
• <goal title> — completed <date>

Sources: logs=ok, git=ok, gh_pr=ok, gh_issue=ok, cron-state=ok
```

Omit any status section that has zero goals.

### 7. Update MEMORY.md safely

- Move DONE goals to a `## Completed Goals` section with completion date. Never delete goals silently.
- Annotate BLOCKED goals inline with the blocker note, but keep them in the active list.
- Do **not** reorder, rephrase, or rewrite the user's goal text.
- Only write MEMORY.md if at least one goal's status changed since the last run. Otherwise leave the file untouched.

### 8. Persist state

Write `memory/goal-state.json` (create if missing):
```json
{
  "run_at": "YYYY-MM-DDTHH:MM:SSZ",
  "goals": {
    "<goal-id>": {
      "status": "AT_RISK",
      "activity_count_14d": 0,
      "last_activity_date": "YYYY-MM-DD"
    }
  }
}
```

### 9. Notify and log

Send the full formatted report via `./notify`.

Append to `memory/logs/${today}.md`:
```
### goal-tracker
- Tracked: N goals (scope: ${var or "all"})
- Status: X at risk, Y needs attention, Z on track, W blocked, V done
- Trend: <notable shifts vs prior run, or "no prior snapshot">
- Actions proposed: <count>
- Sources: logs=ok, git=ok, gh_pr=ok, gh_issue=ok, cron-state=ok
```

## Sandbox note

This skill uses `gh` CLI and local file reads — both work inside the GitHub Actions sandbox. If `gh pr list` or `gh issue li