| name | Followup Patrol |
| category | productivity |
| description | Escalation audit โ parses the follow-up / open-loop section of MEMORY.md plus the issue tracker, computes item ages, and alerts on items hitting urgency thresholds so nothing rots unattended |
| var | |
| tags | ["meta","ops","memory"] |
| schedule | 0 11 * * 2 |
${var} โ Optional filter (e.g. "security", "release", "disclosure"). If empty, audits everything.
Today is ${today}. This skill watches the follow-up backlog so nothing falls through the cracks between self-reviews.
Voice
If soul/SOUL.md and soul/STYLE.md exist and are populated, read them and match the operator's voice in the notification. Otherwise use a clear, direct, neutral tone โ state what needs to happen, no hedging.
Why this skill exists
Open loops accumulate in MEMORY.md between reviews. Items requiring a human action can sit for weeks without anything escalating them by age. Other skills cover specific lanes (e.g. pr-tracker for bot PRs, disclosure-tracker for pending disclosures, pvr-watchlist for enablement probes). This skill is the catch-all โ the general follow-up backlog plus the issue tracker, escalated by age.
Steps
1. Read the follow-up section
Read memory/MEMORY.md. Find the follow-up section using this resolution order:
- A
## Known Follow-ups section, if present (the canonical home).
- Otherwise
## Next Priorities (the default section a fresh Aeon ships with).
- Otherwise
## Open Loops or any heading containing "follow" / "todo" / "pending".
Extract every bullet point under the matched section. If none of these sections exist, skip follow-up parsing and proceed with the issue tracker only (step 3).
For each bullet, parse:
- Label โ the name/identifier before the em dash or first
โ
- Date mentioned โ look for dates like
5/12, 5/25, since 4/30, 24d+, 12d, an ISO date, etc.
- Status type โ classify as one of:
operator โ requires manual human action (e.g. "operator: open PR", "rotate key X")
auto โ being handled by another skill on a schedule (e.g. "pvr-watchlist probing 6/1")
deferred โ explicitly deferred pending a decision
deadline โ has a hard date (e.g. "2026-06-12")
- Description โ the full bullet text, one line
2. Compute age for each item
Today = ${today}. For each item:
- If it contains a date like
5/12 or since 5/12 โ age = days since that date
- If it says
24d+ โ age = 24 (or more)
- If it says
12d โ age = 12
- If no date is detectable โ age = unknown (treat as WATCH)
Apply urgency tiers:
| Tier | Condition | Action |
|---|
| CRITICAL | age > 21d AND type = operator | Must escalate immediately |
| HIGH | age > 14d AND type = operator | Escalate this cycle |
| MEDIUM | age > 7d (any type) | Note and monitor |
| WATCH | age โค 7d OR type = auto/deferred/deadline | Informational only |
If ${var} is set, only process items whose text contains ${var} (case-insensitive).
3. Read open issues
Read memory/issues/INDEX.md if it exists. Find the ## Open table. Extract each open issue row:
- ID, title, severity, detected date
- Compute age from detected date
Add them to the escalation picture (separate section in output). If memory/issues/INDEX.md doesn't exist, skip this section.
4. Write memory/topics/follow-up-status.md
Overwrite the file:
# Follow-up Status โ ${today}
*Generated by followup-patrol. Next run: next Tuesday 11:00 UTC.*
## CRITICAL (operator action required, >21d)
| Item | Age | Type | Action Needed |
|------|-----|------|---------------|
## HIGH (operator action required, >14d)
| Item | Age | Type | Action Needed |
|------|-----|------|---------------|
## MEDIUM (>7d)
| Item | Age | Type | Notes |
|------|-----|------|-------|
## WATCH (<7d or auto-tracked)
| Item | Age | Type | Notes |
|------|-----|------|-------|
## Open Issues
| ID | Title | Severity | Age |
|----|-------|----------|-----|
---
*Items in CRITICAL/HIGH tiers require operator attention. AUTO items are handled by scheduled skills.*
5. Decide whether to notify
- If zero CRITICAL and zero HIGH items: skip notification. Log
FOLLOW_UP_PATROL_SKIP: no escalation-tier items found.
- Otherwise: always notify.
6. Send notification
Write to .pending-notify-temp/followup-patrol-${today}.md (create the dir if needed):
follow-up patrol โ ${today}
open issues: N (severities)
CRITICAL (>21d, operator): N items
- [label] โ Nd โ [one-line action]
HIGH (>14d, operator): N items
- [label] โ Nd โ [one-line action]
MEDIUM (>7d): N items
[brief list]
WATCH: N items (auto-tracked)
full breakdown: memory/topics/follow-up-status.md
Keep under 800 chars. State what needs to happen.
Then run:
./notify -f .pending-notify-temp/followup-patrol-${today}.md
7. Log to memory/logs/${today}.md
Append:
## Follow-up Patrol
- **Items parsed:** N
- **CRITICAL:** N
- **HIGH:** N
- **MEDIUM:** N
- **WATCH:** N
- **Open issues:** N
- **Notification:** sent / skipped
- FOLLOW_UP_PATROL_OK
If skipped: FOLLOW_UP_PATROL_SKIP: <reason>.
Required Env Vars
None. All reads from local memory/ files.
Sandbox Note
No network calls required. All data comes from local memory/MEMORY.md and memory/issues/INDEX.md โ both committed to the repo and available in every run after checkout. The only outbound call is ./notify, which is already sandbox-safe.