Agent Skillsaaronjmars/aeon › Fleet Control

Fleet Control

GitHub

管理Aeon实例集群,提供健康检查、技能分发及状态快照控制视图。生成包含成本、可靠性及同比变化的每日评分卡视图。自动验证GitHub认证与速率限制,动态发现实例并记录日志,确保决策就绪的运维操作。

skills/fleet-control/SKILL.md aaronjmars/aeon

Trigger Scenarios

执行健康检查或获取实例状态 向指定或全部实例分发技能 查看集群运行成本与可靠性评分卡

Install

npx skills add aaronjmars/aeon --skill Fleet Control -g -y
More Options

Use without installing

npx skills use aaronjmars/aeon@Fleet Control

指定 Agent (Claude Code)

npx skills add aaronjmars/aeon --skill Fleet Control -a claude-code -g -y

安装 repo 全部 skill

npx skills add aaronjmars/aeon --all -g -y

预览 repo 内 skill

npx skills add aaronjmars/aeon --list

SKILL.md

Frontmatter
{
    "var": "",
    "cron": "0 9,15 * * *",
    "name": "Fleet Control",
    "tags": [
        "dev",
        "meta",
        "fleet",
        "report",
        "cost"
    ],
    "type": "Skill",
    "category": "core",
    "description": "Operate managed Aeon instances registered in memory\/instances.json — health-check, dispatch skills, and full status snapshots (control view), plus a fleet-wide scorecard of runs, tokens (OpenRouter shape), est. cost and reliability with day-over-day deltas and alerts (scorecard view)"
}

${var} — Command / view selector. Empty (or unrecognized) → Health Check (default control view). status → full Status Mode (control view). dispatch <instance|*> <skill> [var=<value>]Dispatch Mode: trigger a skill on one child or all healthy/degraded children (control view). scorecardScorecard Mode: fleet-wide runs/tokens/cost/reliability scorecard with day-over-day deltas + alerts (scorecard view).

Today is ${today}. Operate the fleet of Aeon instances registered in memory/instances.json. The control view (health/status/dispatch) is decision-ready: every run leads with a verdict, then a delta vs prior check, then per-instance lines that name the next concrete action. The scorecard view publishes the daily fleet-wide cost/reliability scorecard.

The fleet is discovered at runtime, never hardcoded: it is this repo ("self") plus every non-archived entry in memory/instances.json (the registry fleet-control and spawn-instance maintain). With zero managed instances the scorecard simply covers the single self repo — still useful.

Shared preamble (every run)

  1. Read memory — read memory/MEMORY.md for high-level context and scan the last ~3 days of memory/logs/ for recent activity; don't re-report a signal already logged there.

  2. Voice — if soul/SOUL.md and soul/STYLE.md exist and are populated, read them and match the operator's voice in every notification. If they are empty templates or absent, use a clear, direct, neutral tone — terse, lowercase, no fluff.

  3. Parse ${var} → mode:

    • empty / unrecognized → Health Check Mode (control view; default)
    • exactly statusStatus Mode (control view)
    • starts with dispatch Dispatch Mode (control view)
    • exactly scorecardScorecard Mode (scorecard view)
  4. Route:

    • Health Check / Status / Dispatch → run the Control-view pre-flight below, then the matching mode section. These modes make live gh calls.
    • Scorecard → skip the control-view pre-flight entirely (it needs no gh and no live network — it reads prefetched files) and jump straight to Scorecard Mode.

Control-view pre-flight (health / status / dispatch only)

  1. Verify gh authgh auth status must succeed. If not, log FLEET_NO_AUTH to memory/logs/${today}.md and notify Fleet Control: gh auth missing — check GITHUB_TOKEN secret. Stop.

  2. Check rate limitREMAINING=$(gh api rate_limit --jq '.resources.core.remaining'). If REMAINING < 50, log FLEET_RATE_LIMITED:remaining=${REMAINING} and notify a one-line warning, then stop.

  3. Load the registry — read memory/instances.json. If the file is missing, write {"instances": []} to bootstrap. If .instances is absent or []:

    • Log FLEET_EMPTY: no managed instances to memory/logs/${today}.md.
    • Stop. Do NOT notify.
  4. Load prior state — read memory/state/fleet-control-state.json (create the directory and file with {"instances": {}, "last_full_summary_date": ""} if missing). Shape:

    {
      "instances": {
        "<name>": { "health": "<status>", "last_checked": "<ISO>", "consecutive_unreachable": 0 }
      },
      "last_full_summary_date": "YYYY-MM-DD"
    }
    

Health Check Mode (default — control view)

For each registered instance, skip rows with archived: true from per-instance work (count them separately). Run the three calls per instance in parallel using & + wait and write each to /tmp/fleet/${SAFE}.{repo,runs,cron}.json:

a. Repo metadata:

gh api "repos/${REPO}" \
  --jq '{full_name, pushed_at, archived, default_branch, open_issues_count}' \
  > "/tmp/fleet/${SAFE}.repo.json" 2>"/tmp/fleet/${SAFE}.repo.err" &

b. Workflow runs in last 24h (precise window, not "last 5"):

SINCE=$(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ)
gh api "repos/${REPO}/actions/runs?created=>${SINCE}&per_page=100&exclude_pull_requests=true" \
  --jq '{total_count, runs:[.workflow_runs[]|{name,status,conclusion,created_at,html_url}]}' \
  > "/tmp/fleet/${SAFE}.runs.json" 2>"/tmp/fleet/${SAFE}.runs.err" &

c. Cron-state from child:

gh api "repos/${REPO}/contents/memory/cron-state.json" --jq '.content' 2>"/tmp/fleet/${SAFE}.cron.err" \
  | base64 -d > "/tmp/fleet/${SAFE}.cron.json" &

wait after launching all three for an instance (or batch across all instances if you trust your parallelism — keep ≤16 concurrent calls to stay under rate limit).

Classify each instance with precise thresholds:

  • unreachable — repo metadata call returned non-zero (404/403/etc.)
  • archived — repo metadata returns archived: true
  • pending_secretsruns.total_count == 0 for the 24h window AND repo pushed_at ≥ 7 days old (newly-spawned instances under 7 days stay unclassified-but-tracked)
  • staleruns.total_count == 0 AND pushed_at > 7 days old AND not archived
  • degraded — ≥1 cron-state skill with consecutive_failures ≥ 3 OR (24h failure_count / total_count) ≥ 0.5 with total_count ≥ 2
  • warning — 24h failure_count ≥ 1 but ratio < 0.5
  • healthy — has runs in last 24h, all conclusions success or in_progress/queued, no degraded cron-state skills

For each instance compute a next_action (one short imperative phrase):

  • pending_secretsadd ANTHROPIC_API_KEY at https://github.com/${REPO}/settings/secrets/actions
  • degradedinvestigate <skill_name> (<consecutive_failures>× in a row, last_error: <signature, ≤60 chars>)
  • warningmonitor — <N>/<Total> runs failed in 24h
  • staleconfirm intent: no runs in 24h, last push <relative_date>; archive or re-enable
  • unreachableverify access: <reason from repo.err>
  • healthynone
  • archivednone (archived)

Compute delta vs prior state (per-instance prior.health vs current.health):

  • NEW — instance not in prior state
  • DEGRADED — was healthy/warning, now degraded/unreachable/stale/pending_secrets
  • RECOVERED — was degraded/unreachable/stale/pending_secrets, now healthy/warning
  • DROPPED — was in prior state, no longer in registry
  • (no change → no delta line)

Update the registry — write back health, last_checked (ISO UTC), and next_action per instance to memory/instances.json. Preserve all other fields (purpose, parent, created, skills_enabled, etc.).

Update the state file — write the current per-instance health snapshot to memory/state/fleet-control-state.json. Update last_full_summary_date to today only when this run notifies. Increment consecutive_unreachable for unreachable instances; reset to 0 otherwise.

Log to memory/logs/${today}.md (under the consolidated heading — see Log section):

### fleet-control
- Mode: health check
- Verdict: [FLEET_OK | NEEDS_ATTENTION:N]
- Sizes: total=N, healthy=N, warning=N, degraded=N, stale=N, pending=N, unreachable=N, archived=N
- Deltas: [list NEW/DEGRADED/RECOVERED/DROPPED, or "none"]
- Sources: gh=ok, rate_remaining=N

Notification gate — send the notification if any of:

  • len(deltas) > 0
  • today != prior last_full_summary_date (first check of UTC day → daily rollup)
  • any current instance is degraded or unreachable

Otherwise skip notify (silent no-op when nothing changed mid-day — operator isn't trained to ignore).

Notification body (when sent):

*Fleet Control — ${today}*
Verdict: <FLEET_OK | NEEDS_ATTENTION:N>

[If deltas exist]:
What changed:
- NEW: <name> (<repo>) — <health>
- DEGRADED: <name> — was <prior>, now <current>: <reason>
- RECOVERED: <name> — was <prior>, now <current>
- DROPPED: <name> — no longer in registry

Fleet (N total):
- <name> [<HEALTH>]: <repo> — <next_action>
- ...

[If first-of-day rollup]:
Counts: healthy <H> · warning <W> · degraded <D> · stale <S> · pending <P> · unreachable <U> · archived <A>

Sources: gh=ok · rate_remaining=N

Cap the per-instance list at 12 lines; if more, append ...and N more — see memory/instances.json. Always include archived in counts; never list archived rows in the per-instance section.


Dispatch Mode (control view)

Parse var: dispatch <instance|*> <skill> [var=<value>].

Resolve targets:

  • If <instance> is *, target = every registry entry whose current health is healthy, warning, or degraded (skip unreachable, stale, pending, archived).
  • Otherwise, exact name match against the registry. Not found → notify Fleet Dispatch: instance '<name>' not in registry and stop.

For each target instance:

  1. Validate skill exists in child:

    gh api "repos/${REPO}/contents/skills/${SKILL}/SKILL.md" >/dev/null 2>&1 \
      || { OUTCOME="missing_skill"; continue; }
    
  2. Check skill is enabled in child's aeon.yml (best-effort warning, not a block — workflow_dispatch can override enabled: false):

    gh api "repos/${REPO}/contents/aeon.yml" --jq '.content' 2>/dev/null | base64 -d \
      | grep -E "^[[:space:]]*${SKILL}:.*enabled:[[:space:]]*true" >/dev/null \
      || NOT_ENABLED_WARN=1
    
  3. Trigger the skill:

    if [ -n "$DISPATCH_VAR" ]; then
      gh workflow run aeon.yml --repo "${REPO}" -f skill="${SKILL}" -f var="${DISPATCH_VAR}" \
        && OUTCOME="dispatched" || OUTCOME="api_failed:$?"
    else
      gh workflow run aeon.yml --repo "${REPO}" -f skill="${SKILL}" \
        && OUTCOME="dispatched" || OUTCOME="api_failed:$?"
    fi
    

Collect per-target outcomes: dispatched | missing_skill | api_failed:<code> (with optional not_enabled_warn flag).

Log:

### fleet-control
- Mode: dispatch
- Command: dispatch <inst|*> <skill> [var=...]
- Targets: N
- Dispatched: N | missing_skill: N | api_failed: N
- Per-target: [<name>: <outcome>, ...]

Notify (always, in dispatch mode):

*Fleet Dispatch*
Command: dispatch <inst|*> <skill>
Targets: <N> — Dispatched: <N>
Successful: <comma-sep names>
[If failures]:
Failed: <name>: <reason>, ...
[If not_enabled_warn]:
Warning: <name> has skill disabled in aeon.yml — dispatched anyway

If 0 dispatched out of N targets, the verdict line reads Fleet Dispatch: 0/${N} — see failures below and exit code logged is FLEET_DISPATCH_FAILED:no_targets_succeeded.


Status Mode (control view)

Generate the comprehensive snapshot, but make it scannable.

For each registered instance (skip archived from detail blocks but count them in the summary), gather in parallel:

  • Repo meta: stargazers_count, pushed_at, open_issues_count, default_branch
  • Last 10 workflow runs:
    gh api "repos/${REPO}/actions/runs?per_page=10&exclude_pull_requests=true" \
      --jq '[.workflow_runs[]|{name,status,conclusion,created_at,html_url}]'
    
  • Full cron-state.json
  • aeon.yml (parse enabled skills)
  • Last 5 commits (one-line gh api repos/${REPO}/commits?per_page=5 --jq ...)

Compute the same delta block, but compare against the most recent prior output/articles/fleet-status-*.md (parse the per-instance health rows; if none exists, mark the section "no prior status to diff against").

Write to output/articles/fleet-status-${today}.md:

# Fleet Status — ${today}

## Verdict
<one line: FLEET_OK | NEEDS_ATTENTION:N | DEGRADED:N — top issue first>

## Top Issue
<one paragraph: the single highest-priority instance and what it needs, OR "none">

## Fleet Health
| Instance | Repo | Health | Last Active | Skills | Open Action |
|----------|------|--------|-------------|--------|-------------|

## What Changed Since Last Status
<list of NEW/DEGRADED/RECOVERED/WENT_STALE/DROPPED instances since prior fleet-status article, or "no changes">

## Per-Instance Detail

### <name> — <repo>
- Purpose: <from registry>
- Health: <status>, last checked <ISO>
- Last 10 runs:
  | Skill | Status | Conclusion | When |
  |-------|--------|-----------|------|
- Skills enabled: <comma list>
- Recent commits:
  - <sha> <message>
- Action: <next_action>

## Counts
| Metric | Value |
|--------|-------|

## Sources
gh=ok · rate_remaining=N · registry=N instances · prior_status=<filename or "none">

Log:

### fleet-control
- Mode: status
- Article: output/articles/fleet-status-${today}.md
- Verdict: <line>
- Sizes: total=N, healthy=N, ...

Notify (always, in status mode):

*Fleet Status — ${today}*
<verdict>
Top issue: <one line, or "none">
Counts: healthy <H> · warning <W> · degraded <D> · stale <S> · pending <P> · unreachable <U>
Article: output/articles/fleet-status-${today}.md

Scorecard Mode (scorecard view)

Publish the daily fleet scorecard to memory/scorecard.md and append a trend row to memory/scorecard-history.csv. (Ran daily at 13:00 UTC as its own dispatch when this skill is scheduled with var: scorecard.)

All data has already been gathered by scripts/prefetch-fleet-scorecard.sh (which ran outside the sandbox with network/gh access). This mode needs no network or gh — work only from the prefetched files below.

Inputs (prefetched — read these)

  • /tmp/fleet-scorecard/scorecard-body.md — the computed markdown tables (Fleet totals, Per-repo, Top skills by cost, Least reliable skills). These numbers are authoritative — do not recompute or alter them.
  • /tmp/fleet-scorecard/metrics.json — today's key totals: total_runs, total_failures, generations, prompt_tokens, cached_tokens, completion_tokens, total_tokens, est_cost_usd, cache_discount_usd.

If /tmp/fleet-scorecard/scorecard-body.md is missing or empty, the prefetch failed or resolved an empty fleet — write a one-line note to /tmp/skill-result.txt saying so and stop (do not overwrite the existing scorecard, do not notify).

Steps

1. Load today's metrics and yesterday's baseline

  • Read /tmp/fleet-scorecard/metrics.json (today).
  • Read the last row of memory/scorecard-history.csv if it exists (the previous run's metrics) to compute deltas. If the file doesn't exist yet, this is the first run — deltas are "—".

2. Compute day-over-day deltas

For total_runs, total_failures, generations, total_tokens, est_cost_usd, cache_discount_usd, compute today − previous. Format as signed (e.g. +312 runs, +$148, +5 failures). These are cumulative all-time figures, so deltas show the last ~24h of activity.

3. Build the Alerts block

Scan the computed tables in scorecard-body.md and flag:

  • Any skill in "Least reliable skills (last 14d)" with fail rate ≥ 25% (call it out by name + repo + rate). That table is already windowed to 14 days, so long-resolved incidents won't trigger false alarms — anything listed there is a current problem worth surfacing.
  • Any cost spike: est_cost_usd delta > 1.5× the median daily delta from history (if ≥7 history rows exist), or just note the day's cost increase otherwise.
  • If total_failures rose by more than 10 since yesterday, flag it.
  • If no issues, write ✅ No anomalies — fleet healthy.

4. Write memory/scorecard.md

Structure (overwrite the file):

# 🛰️ Aeon Fleet Scorecard — as of ${today}

_Auto-generated daily by skills/fleet-control (scorecard view). Tokens reported OpenRouter-style (cached_tokens ⊆ prompt_tokens)._

## Since last update (~24h)
| Metric | Δ |
|---|---:|
| Runs | <signed> |
| Failures | <signed> |
| Generations | <signed> |
| Total tokens | <signed, humanized> |
| Est. cost | <signed $> |
| Cache discount | <signed $> |

## Alerts
<the alerts block from step 3>

<PASTE the full contents of /tmp/fleet-scorecard/scorecard-body.md verbatim here>

---
_Sources: GitHub Actions run history + each repo's `memory/token-usage.csv`. Fleet resolved from memory/instances.json + self. Cost = Anthropic list price (estimate)._

5. Append the trend row

Append one line to memory/scorecard-history.csv (create with a header if it doesn't exist):

date,total_runs,total_failures,generations,prompt_tokens,cached_tokens,completion_tokens,total_tokens,est_cost_usd,cache_discount_usd

Use ${today} for the date and the values straight from metrics.json. Append, never rewrite prior rows.

6. Notify

Write a terse daily pulse to /tmp/scorecard-notify.md and send it with ./notify -f /tmp/scorecard-notify.md. One short paragraph — today's totals (runs, est. cost, total tokens), the headline deltas, and any alert. Example shape: "fleet at 12.5k runs, ~$7.8k notional. +312 runs / +$148 since yesterday. cost-report still failing (88% fail). caching saved ~$43k." Also copy this text to /tmp/skill-result.txt so the framework captures it.

7. Memory log

Append the scorecard entry under the consolidated ### fleet-control heading in memory/logs/${today}.md (see Log section), noting the headline numbers (so future skills like self-improve/reflect see it).

Scorecard notes

  • Numbers come only from the prefetched files — never invent or estimate figures yourself.
  • The scorecard is cumulative/all-time; the deltas are what make the daily run useful.
  • GitHub Actions retains runs ~90 days, so the run history is a rolling window; the token CSVs are the durable record committed in each repo.

Log

All modes append under one ### fleet-control heading in memory/logs/${today}.md, with a - Mode: discriminator line (the health loop parses this shape). Use the per-mode block shown in each mode section above. For Scorecard Mode use:

### fleet-control
- Mode: scorecard
- Scorecard: memory/scorecard.md updated — <total_runs> runs, ~$<est_cost_usd> notional, <total_tokens humanized>
- Deltas: <+runs> / <+$cost> since yesterday
- Alerts: <alert summary or "none">

Exit taxonomy

Every run logs exactly one of these to memory:

  • FLEET_CONTROL_OK — health/status/dispatch/scorecard completed normally
  • FLEET_EMPTY — no instances in registry (silent stop; control view)
  • FLEET_NO_AUTH — gh auth missing (control view)
  • FLEET_RATE_LIMITED:remaining=N — abandoned to preserve quota (control view)
  • FLEET_DISPATCH_OK:N/M — dispatched N of M targets
  • FLEET_DISPATCH_FAILED:<reason> — dispatch produced 0 dispatches
  • FLEET_SCORECARD_EMPTY — prefetch missing/empty; scorecard skipped without overwriting or notifying

Sandbox note

Control view (health / status / dispatch): always use gh api over raw curl (handles auth and the sandbox env-var-in-headers issue). All cross-repo calls go through gh api or gh workflow run. No outbound HTTP needed beyond what gh does internally.

Scorecard view: needs no network inside the sandbox — all gh/API work happens in scripts/prefetch-fleet-scorecard.sh, which runs in the workflow's prefetch phase with gh auth and stages its output under /tmp/fleet-scorecard/. If the prefetch's cross-repo reads fail for a managed instance, it's almost always the GitHub token scope (the token needs read access to that instance's repo; self is always readable). The prefetch degrades gracefully — a repo it can't read is simply absent from the tables rather than crashing the run.

Required env vars

None for the skill itself. scripts/prefetch-fleet-scorecard.sh uses GH_TOKEN/GITHUB_TOKEN (provided by the workflow) and reads GITHUB_REPOSITORY to resolve "self". The control view relies on the workflow-provided GITHUB_TOKEN for its live gh calls.

Constraints

  • Never delete an instance from memory/instances.json automatically — only update fields. Even unreachable instances stay in the registry until the operator removes them by hand.
  • Preserve all registry fields not explicitly written by this skill (purpose, parent, created, skills_enabled, etc.).
  • Never write secrets to logs or notifications.
  • Cap notification length at ~30 lines; truncate the per-instance list with ...and N more when needed.
  • Health Check stays silent when nothing changed mid-day — the daily-rollup path handles the recurring "is everything fine?" question without spam.
  • Scorecard Mode never overwrites memory/scorecard.md when the prefetch is missing/empty, and appends (never rewrites) prior rows in memory/scorecard-history.csv.
  • Do not change the skill's tags, var semantics, or schedule without strong justification.

Write complete, working code. No TODOs or placeholders.

Output

After completing any task, end with a ## Summary listing what you did, files created/modified, and any follow-up actions needed.

Version History

  • fb16753 Current 2026-07-05 12:06

Same Skill Collection

skills/action-converter/SKILL.md
skills/article/SKILL.md
skills/auto-merge/SKILL.md
skills/auto-workflow/SKILL.md
skills/autoresearch/SKILL.md
skills/bd-radar/SKILL.md
skills/changelog/SKILL.md
skills/code-health/SKILL.md
skills/cost-report/SKILL.md
skills/create-skill/SKILL.md
skills/ctrl/SKILL.md
skills/defi-overview/SKILL.md
skills/deploy-prototype/SKILL.md
skills/digest/SKILL.md
skills/distribute-tokens/SKILL.md
skills/ecosystem-pulse/SKILL.md
skills/fear-divergence/SKILL.md
skills/feature/SKILL.md
skills/fetch-tweets/SKILL.md
skills/fork-fleet/SKILL.md
skills/github-monitor/SKILL.md
skills/github-trending/SKILL.md
skills/heartbeat/SKILL.md
skills/idea-forge/SKILL.md
skills/idea-pipeline/SKILL.md
skills/inbox-triage/SKILL.md
skills/install-skill/SKILL.md
skills/investigation-report/SKILL.md
skills/issue-triage/SKILL.md
skills/last30/SKILL.md
skills/memory-flush/SKILL.md
skills/mention-radar/SKILL.md
skills/monitor-polymarket/SKILL.md
skills/narrative-convergence/SKILL.md
skills/narrative-tracker/SKILL.md
skills/okf-export/SKILL.md
skills/okf-ingest/SKILL.md
skills/onchain-monitor/SKILL.md
skills/operator-scorecard/SKILL.md
skills/picks-tracker/SKILL.md
skills/pm-manipulation/SKILL.md
skills/pm-pulse/SKILL.md
skills/pr-review/SKILL.md
skills/pr-triage/SKILL.md
skills/price-alert/SKILL.md
skills/reply-maker/SKILL.md
skills/repo-scanner/SKILL.md
skills/schedule-ads/SKILL.md
skills/search-skill/SKILL.md
skills/self-improve/SKILL.md
skills/send-email/SKILL.md
skills/skill-health/SKILL.md
skills/skill-repair/SKILL.md
skills/soul-builder/SKILL.md
skills/spawn-instance/SKILL.md
skills/strategy-builder/SKILL.md
skills/token-movers/SKILL.md
skills/token-pick/SKILL.md
skills/treasury-info/SKILL.md
skills/tx-explain/SKILL.md
skills/unlock-monitor/SKILL.md
skills/verdikta-hunter/SKILL.md
skills/vuln-scanner/SKILL.md
skills/vuln-tracker/SKILL.md
skills/workflow-audit/SKILL.md
skills/write-tweet/SKILL.md
skills/x402-monitor/SKILL.md
skills/base-mcp/SKILL.md
skills/star-milestone/SKILL.md

Metadata

Files
0
Version
fb16753
Hash
4550c410
Indexed
2026-07-05 12:06

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-09 00:59
浙ICP备14020137号-1 $Carte des visiteurs$