Heartbeat

$npx mdskill add aaronjmars/aeon/Heartbeat

> **${var}** — Area to focus on. If empty, runs all checks.

SKILL.md

.github/skills/HeartbeatView on GitHub ↗
---
name: Heartbeat
description: Proactive ambient check — surface anything worth attention
var: ""
tags: [meta]
---
> **${var}** — Area to focus on. If empty, runs all checks.

If `${var}` is set, focus checks on that specific area.

Read memory/MEMORY.md and the last 2 days of memory/logs/ for context.

## Checks (in priority order)

### P0 — Failed & stuck skills (check first)

Read `memory/cron-state.json`. This file tracks every scheduled skill's state and quality metrics:
```json
{
  "skill-name": {
    "last_dispatch": "2026-04-06T12:00:00Z",
    "last_status": "dispatched|success|failed",
    "last_success": "2026-04-06T12:05:00Z",
    "last_failed": "2026-04-05T12:03:00Z",
    "total_runs": 10,
    "total_successes": 8,
    "total_failures": 2,
    "consecutive_failures": 0,
    "success_rate": 0.80,
    "last_quality_score": 4,
    "last_error": "error signature text"
  }
}
```

Flag these conditions:
- **Failed skills**: any entry with `last_status: "failed"`. Report the skill name and when it failed.
- **Stuck skills**: any entry with `last_status: "dispatched"` where `last_dispatch` is **>45 minutes ago**. The skill was dispatched but never reported back — likely hung or crashed before the state update step ran.
- **API degradation**: any skill with `consecutive_failures >= 3`. This likely indicates an external API is down or rate-limiting. Report the skill, failure count, and `last_error`. If multiple skills share similar error signatures, flag the shared dependency.
- **Chronic failures**: any skill with `success_rate < 0.5` (and `total_runs >= 5`). The skill is failing more than it succeeds.
- **Self-check**: if heartbeat's own entry shows `last_success` is **>36 hours ago** (or missing), note that heartbeat itself may be unreliable.

### P1 — Stalled PRs & urgent issues

- [ ] Any open PRs stalled > 24h? (use `gh pr list`)
- [ ] Any GitHub issues labeled urgent? (use `gh issue list`)

### P2 — Flagged memory items

- [ ] Anything flagged in memory/MEMORY.md that needs follow-up?

### P3 — Missing scheduled skills

Read `aeon.yml` for enabled skills with schedules. Cross-reference with `memory/cron-state.json`:
- If an enabled skill has **no entry at all** in the state file, it has never been dispatched by the scheduler.
- If a skill's `last_success` is **>2x its schedule interval** old (e.g., a daily skill hasn't succeeded in >48h), flag it.

Do NOT use `gh run list` for this — the state file is authoritative.

## Dedup & notification

Before sending any notification, grep memory/logs/ for the same item. If it appears in the last 48h of logs, skip it. Never notify about the same item twice.

Batch all findings into a **single notification**, grouped by priority tier:
```
🔴 FAILED: skill-a (failed 2h ago), skill-b (stuck 1h ago)
🟡 STALLED: PR #42 open 3 days
🔵 MEMORY: follow-up on X flagged 2 days ago
```

## Public status page

After the priority checks (even when everything is green — this step **always** runs), regenerate `docs/status.md` so the public GitHub Pages site reflects current fleet health.

### Data sources
- `memory/cron-state.json` — per-skill run state (authoritative)
- `memory/issues/INDEX.md` — open issue table
- `aeon.yml` — enabled skill list with schedules
- Latest `articles/token-report-*.md` (most recent by filename date) — optional; powers the Token Pulse section. Skipped silently when no file exists.

### Overall status
Compute one of three overall states from the same signals used above:
- `🔴 DEGRADED` — any P0 flag fired (failed skill, stuck skill, consecutive_failures ≥ 3, chronic failures with success_rate < 0.5, heartbeat self-check >36h stale)
- `🟡 WATCH` — any P1/P2/P3 flag fired (stalled PRs, urgent issues, flagged memory items, skills >2x their schedule interval old) or any open issue with severity `critical` or `high`
- `🟢 OK` — no flags at all

### Format

Write `docs/status.md` with Jekyll frontmatter so it renders as a gallery page:

```markdown
---
layout: default
title: "Status"
permalink: /status/
---

# Agent Status

**Overall:** 🟢 OK
**Updated:** 2026-04-24 19:06 UTC
**Open issues:** 0
**Next scheduled run:** heartbeat at 20:00 UTC

Auto-generated by the `heartbeat` skill on every run (3× daily at 08:00 / 14:00 / 20:00 UTC). If the Updated timestamp is more than ~8h stale, the agent is not running.

## Token pulse

| Token | Price | 24h | Liquidity | Volume (24h) | FDV |
|-------|-------|-----|-----------|--------------|-----|
| AEON | $0.0000032626 | -11.16% | $223.4K | $41.3K | $326.3K |

_Source: `articles/token-report-2026-04-28.md` · verdict: SLIDING_

## Skill health (last 7 days)

| Skill | Last run | Status | Success rate | Consecutive failures |
|-------|----------|--------|-------------:|---------------------:|
| token-report | 2026-04-24 12:30 UTC | ✅ success | 100% | 0 |
| fetch-tweets | 2026-04-24 06:53 UTC | ✅ success | 95% | 0 |
| …           | …                    | …         | …    | … |

## Open issues

_(if INDEX.md has any open rows, render them here; otherwise: "No open issues.")_

| ID | Title | Severity | Category | Detected |
|----|-------|----------|----------|----------|
| ISS-001 | … | medium | rate-limit | 2026-04-22 |

---
*Fork this repo and your copy inherits this page automatically — [how it works](/memory/).*
```

### Rules
- Include **all** enabled skills from `aeon.yml` (not only those with recent runs). For skills with no entry in cron-state.json, show `—` for timestamp and `not yet run` in status.
- Sort the skill table by last-run timestamp descending (most recent first); skills that have never run sink to the bottom.
- Format timestamps as `YYYY-MM-DD HH:MM UTC` (strip seconds and the `Z`).
- Success rate shows `total_successes / total_runs × 100` rounded to whole percent; display `—` when `total_runs == 0`.
- Status column icons: `✅ success`, `❌ failed`, `⏳ dispatched` (if last_dispatch within 45min), `🕸 stuck` (if last_dispatch > 45min and last_status still dispatched), `—` (never run).
- For the `Next scheduled run:` line, pick the enabled skill with the soonest upcoming cron time relative to now.
- Dedup state: re-running heartbeat overwrites `docs/status.md` wholesale each time — do not append.
- Never expose values from `.env`, secrets, or anything outside cron-state.json + issues/INDEX.md + aeon.yml + articles/token-report-*.md. This file is public.

### Token pulse rules
- Pick the **latest** `articles/token-report-*.md` by filename date (sort descending, take the first match).
- **Staleness:** if the picked file's date is older than 24h relative to the heartbeat run timestamp, render `_No recent token data (latest report YYYY-MM-DD)._` in place of the table — do not lift stale figures into the table.
- **No file at all:** omit the `## Token pulse` section entirely. The status page must still render cleanly with no token row.
- **Token symbol:** read from `memory/MEMORY.md` "Tracked Token" table (first row, `Token` column). If the table is missing, render the heading as `## Token pulse` with the symbol column blank.
- **Field extraction (regex, tolerant of both old `Value | 24h Change` and new `Now | 24h Δ` table layouts):**
  - **Price:** first `| Price |` row → first `$` value in the row → strip whitespace.
  - **24h:** same Price row → first `±?\d+(\.\d+)?%` token in the row (typically the second cell). Render as written, preserving sign. If absent, render `—`.
  - **Liquidity:** first `| Liquidity |` row → first `$` value.
  - **Volume (24h):** first row whose first cell matches `Volume\b.*24h` or `24h Volume` → first `$` value.
  - **FDV:** first `| FDV |` row → first `$` value.
  - For any field whose row or `$` value cannot be located, render `—` for that cell only — do not skip the section.
- **Verdict line:** if the source article contains a `**Verdict:** LABEL` line, append `· verdict: LABEL` to the source line. If no Verdict line is present (older format), omit the suffix.
- **Source link:** the trailing `_Source: ..._` line names the exact article file used so a reader can verify the numbers.

The file lands on `main` through the workflow's auto-commit step — no explicit `git` commands needed in this skill.

## Output

If nothing needs attention, log "HEARTBEAT_OK" (plus the overall status page verdict, e.g. `HEARTBEAT_OK · STATUS_PAGE=OK`) and end your response.

If something needs attention:
1. Send a single concise notification via `./notify` (grouped by priority as above)
2. Log the findings and actions taken to memory/logs/${today}.md
3. Log one line with the status-page verdict, e.g. `STATUS_PAGE=DEGRADED — wrote docs/status.md`

More from aaronjmars/aeon

SkillDescription
[REPLACE: SKILL_NAME]Watch Vercel deploys for [REPLACE: VERCEL_PROJECT] — alert on [REPLACE: ALERT_ON] in the last [REPLACE: LOOKBACK_HOURS] hours
Action Converter5 concrete real-life actions for today, leverage-scored against open loops with specificity and anti-fluff gates
Agent BuzzCurated AI-agent tweets, clustered into narratives with insight summaries
agent-displacementWeekly tracker of AI agent substitution signals — which roles, companies, and industries show real headcount displacement. Named roles + real deployments only.
AI Framework WatchWeekly competitive-intelligence digest on the AI agent framework space — momentum, releases, breaking changes across a curated watchlist
AIXBT PulseCross-domain market pulse from AIXBT's free grounding endpoint — crypto, macro, tradfi, geopolitics. Refreshes taxonomy references (clusters, chains) as a bonus.
api-health-probeDaily pre-batch API provider health check — detects credit exhaustion or auth failure for every configured provider key before the morning batch runs, giving the operator a window to act before skills degrade
Approval AuditList 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.
article-queueWeekly article idea synthesizer — ranks signals from topic-momentum, beat-tracker, and narrative-tracker into a prioritized queue the article skill reads on next run
atrium-catalog-watcherWeekly diff of the Atrium marketplace catalog at https://atriumhermes.tech/.well-known/skills/index.json against the prior snapshot — surfaces newly-published skills, removed skills, and updated descriptions. Supply-side complement to sparkleware-catalog (curated skill-packs.json registry) and skill-update-check (version drift of installed skills).