capabilities-sweep
**capabilities-sweep**, Automatically infers and declares capability tags for approximately 174 undeclared skills by pattern-matching their SKILL.md content against a locked taxonomy, then proposes high-confidence declarations in a single pull request while flagging low-confidence rows for human review. Use this after the taxonomy is finalized to eliminate the `(undeclared)` backlog in the capabilities-map without requiring 174 individual edits, supporting optional dry-run, confidence-override, and single-skill iteration modes.
git clone --depth 1 https://github.com/aaronjmars/aeon /tmp/capabilities-sweep && cp -r /tmp/capabilities-sweep/skills/capabilities-sweep ~/.claude/skills/capabilities-sweepSKILL.md
> **${var}** — Optional. Tokens (whitespace-separated):
> - `dry-run` — write the proposal manifest + article, do NOT open a PR, do NOT notify.
> - `propose-only` — write the proposal manifest + article + PR, but mark every row as `proposed: needs-review` regardless of confidence (the PR description asks the operator to confirm each row before merge). Default behaviour: rows that meet the high-confidence threshold (≥2 matching pattern hits OR a single unambiguous on-chain-write signal) are pre-applied to the SKILL.md frontmatter; low-confidence rows are listed in the PR description for operator decision.
> - `slug=<skill-slug>` — restrict the sweep to a single skill (useful for iterating on the inference heuristics without churning ~174 files). The PR is still opened with one file changed.
> - Empty → default execute.
>
> Any unrecognised token → log `CAPABILITIES_SWEEP_BAD_VAR: ${var}` and exit (no writes, no notify).
Today is ${today}. PR #268 landed the locked 6-value capabilities taxonomy in `docs/CAPABILITIES.md` and the matching `capabilities: []` field in `skill-packs.json` (per-pack and per-skill). PR #304 added a CI parity check so the taxonomy can't drift. PR #322 declared `capabilities:` on 22 high-blast-radius skills (the Phase 1 sweep). What remains: **~174 skills shipped before the Phase 1 sweep with no declaration at all** — `capabilities-map` lumps every one of them into a single `(undeclared)` row, drowning the gap signal it was built to surface.
This skill is the Phase 2 closer. It walks every `skills/<slug>/SKILL.md`, skips skills that already have a `capabilities:` line in their frontmatter (idempotent — safe to rerun), and for every undeclared skill runs a body-pattern inference against the locked taxonomy. Inferences that meet a confidence threshold are pre-applied to the SKILL.md frontmatter in a single PR; inferences below the threshold are listed in the PR description for human triage. Goal: empty the `(undeclared)` row in `capabilities-map` in one operator-reviewable PR rather than ~174 micro-edits over months.
Read `memory/MEMORY.md` for context.
Read the last 8 days of `memory/logs/` for prior-run context.
Read `soul/SOUL.md` + `soul/STYLE.md` if populated to match voice in the notification and article.
## Why this exists
`capabilities-map` (PR #313) is supposed to answer "what does my enabled stack actually cover, and where are the gaps?" Today, its output is dominated by one row: "undeclared skills: ~174". Every native skill written before the Phase 1 sweep is in that bucket. The operator can't tell whether a tier is *genuinely* uncovered or whether the coverage is hidden behind an undeclared skill that quietly does `./notify` and `gh api`. The matrix is noise until that backlog is closed.
Closing the backlog by hand is the obvious path and the wrong one. It is ~174 frontmatter edits across files written by ~12 distinct contributors over six months. The edits are mechanically uniform (regex-grade pattern → declaration) but tedious enough that no operator does them on a Tuesday afternoon. The job has been deferred since PR #268 shipped.
This skill makes the job a single PR review. The heuristics are deliberately conservative: a single ambiguous match per skill yields no declaration (the row goes to "needs human"). A skill whose body shows two or more matching signals — say, `./notify` + `gh api repos/.*/issues` — gets a pre-applied `capabilities: [external_api, sends_notifications]` line that the operator can either accept verbatim or override in the PR. Skills with zero matching signals get a pre-applied `capabilities: [read_only]` line — the explicit "this skill does nothing externally visible" declaration the taxonomy already has a value for.
This skill is **a one-shot meta-tool**. It is registered `workflow_dispatch` only — not on a cron — because after one successful merge the backlog is gone and there's nothing left to do until a future contributor lands a new skill without a `capabilities:` line. (When that happens, `capabilities-map` will surface it as a single undeclared row, and the operator dispatches this skill with `slug=<that-skill>` to clear it.)
## Inputs
| Source | Purpose | Auth |
|--------|---------|------|
| `skills/<slug>/SKILL.md` | Each skill's frontmatter + body. Frontmatter is parsed for the existing `capabilities:` line (to skip declared skills). Body is pattern-matched for inference signals. | Local file |
| `docs/CAPABILITIES.md` | The locked 6-value taxonomy — extracted from the `## The taxonomy` section, same parser `capabilities-map` and `scripts/check-capabilities-parity.sh` use. Used to validate every value the skill emits and reject any heuristic that proposes an unknown value. | Local file |
| `skills.json` | Slug → human name, category, schedule. Used in the proposal manifest + PR description for context. | Local file |
| `aeon.yml` | `enabled: true|false` per skill. Surfaces "X of the rows you're about to review are currently enabled" in the PR description so the operator knows the priority order. | Local file |
| `memory/topics/capabilities-sweep-state.json` | Per-skill last_run, last_status, last_proposed_capabilities. Used to skip skills whose proposal hasn't changed since the prior run (no point re-opening a PR that's a no-op). | Local file |
No network calls beyond `gh pr list` (duplicate-PR guard), the `git push` of the sweep branch, and `gh pr create` at the end. No new secrets. `gh` uses `GH_TOKEN` per the standard auth path.
Writes:
- `articles/capabilities-sweep-${today}.md` — full human-readable proposal table (every non-error run, including `NO_CHANGES`)
- `.outputs/capabilities-sweep-proposals.json` — machine-readable proposal manifest (consumed by step 5)
- For each high-confidence proposal: a single line added to `skills/<slug>/SKILL.md` frontmatter — `capabilities: [...]` immediately after the `requires:` line (or after `tags:` when the skill has no `requires:` line), matching the placement PhaMention/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.