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.
git clone --depth 1 https://github.com/aaronjmars/aeon /tmp/goal-tracker && cp -r /tmp/goal-tracker/skills/goal-tracker ~/.claude/skills/goal-trackerSKILL.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 liMention/keyword sweep on social platforms for [REPLACE: KEYWORDS] — trends, sentiment, top posts
5 concrete real-life actions, leverage-scored against open loops with specificity and anti-fluff gates
Curated AI-agent tweets, clustered into narratives with insight summaries
Tracker of AI agent substitution signals — which roles, companies, and industries show real headcount displacement. Named roles + real deployments only.
Competitive-intelligence digest on the AI agent framework space — momentum, releases, breaking changes across a curated watchlist
Cross-domain market pulse from AIXBT's free grounding endpoint — crypto, macro, tradfi, geopolitics. Refreshes taxonomy references (clusters, chains) as a bonus.
Pre-batch API provider health check — detects credit exhaustion or auth failure for every configured provider key before the scheduled batch runs, giving the operator a window to act before skills degrade
List a wallet's live ERC-20 token approvals on Base and flag unlimited / risky spender grants. Keyless via Base RPC (eth_getLogs + eth_call) — no explorer key needed.