WIKI/SYS PING HUB

SYS PING HUB

Updated 3 weeks ago
╔══════════════════════════════════════════════════════════════════════════════╗
║                                                                              ║
║   P I N G   H U B   +   W A K E U P   S Y S T E M                           ║
║   ⚙ M A N A G E D   H E A L T H   C H E C K S   &   S C H E D U L E R      ║
║                                                                              ║
╠══════════════════════════════════════════════════════════════════════════════╣
║  STATUS: LIVE                    VERIFIED: 2026-03-06                        ║
╚══════════════════════════════════════════════════════════════════════════════╝
⫷✦🜛❂⛬🜞Ω🜚⛬❂🜛✦⫸───────────────────────────────────────────⫷✦🜛❂⛬🜞Ω🜚⛬❂🜛✦⫸
 WHAT IT DOES: Managed periodic health-check pings + scheduled agent wakeup
               injections into Claude and Aeris mailboxes.
────────────────────────────────────────────────────────────────────────────────

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  SYSTEM GLYPH
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  GLYPH:        ⚙
  UNICODE:      U+2699 · GEAR
  MEANING:      Mechanism — automated ping coordination daemon; the gear
                represents the scheduled, mechanical heartbeat of health checks
  WHEN TO USE:  SYS docs, Ping Hub / wakeup system references, KID tags for
                launchd ping plists and health-check artifacts
  TAGGING:      KID:FORGE:MECHANISMS:PINGHUB|V:STATUS:DATE:OWNER


▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
[ ⚡ ] A R C H I T E C T U R E
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

┌── Ping Hub ─────────────────────────────────────────────────────────────────┐
│                                                                              │
│ config.yaml (human-editable)                                                 │
│     → ping-watcher.sh (triggered on file change or every 5 min)             │
│         → Python: parses YAML, upserts pings table in overmind.db           │
│         → generates/loads launchd plists: com.forge.ping.<id>               │
│             → each plist fires: ping_hub.sh run <id>                        │
│                 → executes command, writes ping_runs row, updates            │
│                   consecutive_failures                                       │
└────────────────────────────────────────────────────────────────────────────┘

┌── Wakeup System ────────────────────────────────────────────────────────────┐
│                                                                              │
│ Drop JSON to ~/.forge-wakeups/pending/WAKEUP_*.json                         │
│     → wakeup-daemon.sh (every 60s via com.forge.wakeup)                     │
│         → Phase 1: ingest pending/ → validates JSON → upserts wakeups table │
│         → Phase 2: queries wakeups table for due records                    │
│             → injects prompt text as .md file into target mailbox           │
│             → logs to wakeup_log table                                      │
└────────────────────────────────────────────────────────────────────────────┘


░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
[ ❖ ] K E Y   P A T H S
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

| Component | Path |
|-----------|------|
| Ping config | `~/.forge-ping/config.yaml` |
| ping_hub.sh | `~/Desktop/THE_FORGE/FORGE_CLAUDE/04_⚙_MECHANISMS/core/ping_hub.sh` |
| wakeup.sh | `~/Desktop/THE_FORGE/FORGE_CLAUDE/04_⚙_MECHANISMS/core/wakeup.sh` |
| wakeup-daemon.sh | `~/Desktop/THE_FORGE/FORGE_CLAUDE/04_⚙_MECHANISMS/core/wakeup-daemon.sh` |
| ping-watcher.sh | `~/Desktop/THE_FORGE/FORGE_CLAUDE/04_⚙_MECHANISMS/core/ping-watcher.sh` |
| Browser UI server | `~/.forge-ping/server.py` |
| Ping logs | `~/.forge-ping/logs/` |
| Watcher log | `~/.forge-ping/logs/watcher.log` |
| Wakeup daemon log | `~/.forge-ping/logs/wakeup-daemon.log` |
| Wakeup pending drop | `~/.forge-wakeups/pending/` |
| Wakeup scheduled | `~/.forge-wakeups/scheduled/` |
| Wakeup fired | `~/.forge-wakeups/fired/` |
| Wakeup failed | `~/.forge-wakeups/failed/` |
| Claude mailbox | `~/Desktop/THE_FORGE/@FORGE_CLAUDE_MAILBOX` |
| Aeris mailbox | `~/Desktop/THE_FORGE/AExGO/03_📋_QUEUE/@AERIS_FORGE_MAILBOX` |
| Overmind DB | `~/Desktop/THE_FORGE/FORGE_CLAUDE/04_⚙_MECHANISMS/db/overmind.db` |
| Ping scripts dir | `~/Desktop/THE_FORGE/FORGE_CLAUDE/04_⚙_MECHANISMS/pings/` |


▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
[ 📶 ] C O N F I G U R E D   P I N G S
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

| ID | Label | Schedule | Enabled | Consecutive Failures |
|----|-------|----------|---------|---------------------|
| `browser-export` | Browser history export | `0 3 * * *` | YES | 0 |
| `cleanup-loop` | Weekly cleanup — archives old logs | `0 3 * * 0` | YES | 0 |
| `gitwatch` | Git auto-commit | `keepalive` | YES | 0 |
| `goldfish` | Screen capture every 5 min | `*/5 * * * *` | YES | 0 |
| `goldfish-digest` | 3-hour narrative digest | `0 9,12,15,18,21 * * *` | YES | 0 |
| `memory-index` | Nightly Aeris memory → grimoire sync | `0 3 * * *` | **NO** | 0 |
| `panel-updater` | Gemini Flash panel health pulse | `*/15 * * * *` | YES | 0 |
| `pulse-heartbeat` | Confirms pulse.sh has run within 15 min | `*/15 * * * *` | YES | 0 |
| `scraps-patrol` | Categorizes SCRAPS folder | `0 0,4,8,12,16,20 * * *` | YES | 1 |
| `scryer-health` | Confirms scryer watcher logs within 10 min | `*/10 * * * *` | YES | 0 |

⫷ `memory-index` disabled — activate when `aeris-memory-index.sh` is confirmed. ⫸
⫷ `scraps-patrol` had 8 failures (2026-02-22); resolved to 1 as of 2026-02-25 audit. ⫸


▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
[ ⚙ ] S C R I P T S   &   C O M P O N E N T S
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄

| Script | Purpose |
|--------|---------|
| `ping_hub.sh` | CLI for all ping operations: list/status/health/run/propose/approve/reject/pending |
| `ping-watcher.sh` | Reads config.yaml, upserts DB, generates/loads/unloads individual ping plists |
| `wakeup.sh` | CLI for wakeup management: schedule/list/cancel/status/test/process-pending |
| `wakeup-daemon.sh` | 60s daemon: ingests pending JSON, fires due wakeups via mailbox injection |
| `server.py` | Python stdlib HTTP server for browser UI on port 7776 |


▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
[ ⛬ ] L A U N C H D   D A E M O N S
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

| Label | Trigger | Script | Purpose |
|-------|---------|--------|---------|
| `com.forge.ping-watcher` | WatchPaths(config.yaml) + StartInterval=300 | `ping-watcher.sh` | Config sync + plist management |
| `com.forge.ping.<id>` | Per-ping cron (or KeepAlive for gitwatch) | `ping_hub.sh run <id>` | Individual ping execution |
| `com.forge.wakeup` | StartInterval=60 | `wakeup-daemon.sh` | Wakeup injection daemon |
| `com.forge.ping-ui` | KeepAlive + RunAtLoad | `server.py` | Browser dashboard on :7776 |

All plists in `~/Library/LaunchAgents/`. `com.forge.wakeup` RunAtLoad=false.


░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
[ 🜄 ] D B   T A B L E S   U S E D
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

| Table | Purpose |
|-------|---------|
| `pings` | Canonical ping registry. Upserted by ping-watcher on every tick. |
| `ping_runs` | Execution log. One row per firing. 631 rows as of 2026-02-22. |
| `pending_pings` | Proposed new pings awaiting approval. Status: PENDING/APPROVED/REJECTED. |
| `wakeups` | Scheduled wakeup definitions. Columns: id, label, target, prompt, schedule_type, cron, fire_at, interval_sec, priority, status, next_fire, fire_count. |
| `wakeup_log` | Fire history. Used by `wakeup.sh status` and double-fire guard. |

All SQLite access uses `.timeout 10000`.


▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
[ 🜂 ] C O M M O N   C O M M A N D S
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

```bash
PING="~/Desktop/THE_FORGE/FORGE_CLAUDE/04_⚙_MECHANISMS/core/ping_hub.sh"
WAKEUP="~/Desktop/THE_FORGE/FORGE_CLAUDE/04_⚙_MECHANISMS/core/wakeup.sh"

# Ping Hub
bash "$PING" list                    # all pings with schedule + status
bash "$PING" health                  # overdue check + launchctl load status
bash "$PING" status goldfish         # details + last 5 runs for one ping
bash "$PING" run goldfish            # manual trigger (records to ping_runs)
bash "$PING" propose                 # interactive: propose new ping
bash "$PING" pending                 # list pings awaiting approval
bash "$PING" approve scraps-patrol   # approve proposed ping
bash "$PING" reject <id>             # reject proposed ping

# Wakeup System
bash "$WAKEUP" list                  # all scheduled wakeups
bash "$WAKEUP" schedule \
  --id my-id --target claude \
  --label "Label" --cron "0 9 * * *" \
  --prompt "Prompt text"
bash "$WAKEUP" status <id>           # details + last 5 fire logs
bash "$WAKEUP" cancel <id>           # stop future fires
bash "$WAKEUP" test <id>             # test-fire immediately

# Browser UI
open http://localhost:7776

# Direct DB check
sqlite3 ~/Desktop/THE_FORGE/FORGE_CLAUDE/04_⚙_MECHANISMS/db/overmind.db \
  "SELECT id, enabled, consecutive_failures, last_run FROM pings ORDER BY id;"
```


════════════════════════════════════════════════════════════════════════════════
[ 🝓 ] G O T C H A S
════════════════════════════════════════════════════════════════════════════════

- **Python path in launchd:** All plists use `/opt/homebrew/bin/python3` (TCC fix S155). Do not swap to `/usr/bin/python3` — launchd strips PATH.
- **Browser UI bound to 127.0.0.1:** `server.py` fixed to `127.0.0.1:7776` (patched 2026-02-24) — was previously binding to all interfaces, causing port conflicts.
- **No `timeout` on macOS:** Use done-flag polling pattern for time-limited scripts.
- **Wakeup double-fire guard:** 30-second guard (`DOUBLE_FIRE_SECONDS`) prevents re-fire on same daemon tick.
- **Wakeup JSON naming:** Files must be `WAKEUP_<something>.json` in `~/.forge-wakeups/pending/`. Other filenames ignored.
- **config.yaml: absolute paths only.** No `~` shorthand — launchd does not expand tildes.
- **Disabling a ping:** Set `enabled: false` in config.yaml. Next watcher tick unloads and deletes the plist.
- **scraps-patrol: intermittent failures.** Was 8 failures (2026-02-22), resolved to 1 by 2026-02-25 audit. Investigate `scraps-patrol.sh` if failures climb again.
- **Wakeup injection format:** Prompt written as `.md` file directly into mailbox buffer. mailbox-trigger.sh picks up on next poll.
- **com.forge.ping-watcher dual trigger:** Fires on WatchPaths write to config.yaml AND 300s heartbeat.

▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
🜚 SYS_PING_HUB // THE FORGE // ⛬⚚⛬ THE LAW STANDS.
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀