# Heartbeat Checklist

## Overture X Marketing Reminders (Drew)
**Channel:** #overture-x thread (channel id: 1473606178096549911)
**Tag:** <@woplas>

Check date and post reminder if due (9 AM PHT / 01:00 UTC):

| Date | Day | Task | Status |
|------|-----|------|--------|
| 2026-02-19 | Day 2 | Follow B2B SaaS Founders + 15-20 min engagement | ✅ |
| 2026-02-20 | Day 3 | Follow Business Operators & Finance + engagement | ✅ |
| 2026-02-21 | Day 4 | Follow Metrics & Dashboard Space + engagement | ✅ |
| 2026-02-22 | Day 5 | Organic discovery (explore who Day 1-4 follow) | ✅ |

After posting reminder, mark status as ✅ and update `memory/2026-02-18.md` progress tracker.

---

## QA Notification Queue

Check for pending asset QA notifications:
```bash
cat /tmp/qa-notification-queue.jsonl 2>/dev/null
```

For each entry:
- **`qa_pending`** → Post in the entry's `channel`:
  > "🎨 Asset generated for **{productName}** (`{filename}`) — QA review in progress (~15s). I'll post the verdict here once done."
- **`qa_verdict`** type:
  - status `pass` → "QA Verdict for **{productName}**: Pass ✅ — `{filename}` passed QA review. Review it here: <https://symphony.symph.co/marketing>"
  - status `warning` → "QA Verdict for **{productName}**: Needs Review ⚠️ — `{filename}` — Reason: {notes} — Open Content Review: <https://symphony.symph.co/marketing>"
  - status `fail` → "QA Verdict for **{productName}**: Failed ❌ — `{filename}` — Reason: {notes} — Open Content Review: <https://symphony.symph.co/marketing>"

After posting all entries, clear the queue:
```bash
> /tmp/qa-notification-queue.jsonl
```

If queue is empty or missing, skip silently.

---

## Pending Jobs
- Check `agency/jobs/` for pending `.yaml` files with `status: pending`
- If found, read `agency/PIPELINES.md` for processing instructions
- Spawn parallel subagents grouped by product_slug (different products = parallel, same product = sequential)
- If no pending jobs, skip

## Suspicious Process Check
- Run: `ls -la /dev/shm/ && ps aux --sort=-%cpu | head -10`
- Flag if ANY of these patterns match:
  - Processes running from `/dev/shm/` or `/tmp/` with randomized names
  - Any single process using >500% CPU sustained
  - Unknown binaries with short random names (e.g. 8-char alphanumeric)
  - Processes with PPid=1 that aren't recognized system services
- If found: **DM Raven** with details (PID, name, CPU%, path). DO NOT kill — report only.
- DM target: coderaven (Discord user id 470619903855034369)

## End-of-Day Memory Consolidation (Last heartbeat after 22:00 GMT+8)
- Write TIL section to `memory/YYYY-MM-DD.md`
- Review any conversations from today — update people profiles if needed
- Check `agency/Learnings/corrections.md` — any corrections not logged?
- Quick scan: anything worth promoting to `MEMORY.md`?

## Usage Tracking (Every Heartbeat)
- Run `sessions_list` (limit 100)
- Sum total tokens by model and session kind (discord-chat, cron, subagent, etc.)
- Append a JSON line to `agency/usage-logs/usage.jsonl` with:
  - `ts`, `type: "snapshot"`, `totalSessions`, `totalTokens`, `byModel`, `byKind`, `estimatedCostUSD`
- This is **append-only** — never edit or delete previous entries
- Cost rates: Opus 4.6 = $45/MTok blended, Sonnet 4.5 = $9/MTok, Haiku 4.5 = $2.40/MTok

## App Watchdog (Every 2nd heartbeat)
- Run app-watchdog checks on apps in `caddy-ports.json`
- **Only auto-fix apps updated in last ~10 minutes** (check `.next` folder mtime)
- For recently active apps: check process health, HTTP status, stale builds → auto-fix if broken
- For idle apps (>10 min since update): **leave OFF** to conserve resources, report only
- Post issues to #aria if found

## Worktree Copilot Watchdog (Every 2nd heartbeat)
- Run: `bash /home/aria/.openclaw/workspace/agency/infra/worktree-watchdog.sh`
- Checks all active worktree Copilot sessions via `https://symphony.symph.co/api/copilot-worktree/sessions`
- Any session idle >30 minutes → auto-cleanup (kills dev server, removes Caddy entry, frees port)
- If sessions cleaned → post brief summary to #aria: "🌿 Freed N stale worktree session(s): [slug list]"
- If 0 sessions → silent (no noise)

**Logic:**
```bash
# Check if app was recently updated (within 10 min)
MTIME=$(stat -c %Y /path/to/.next 2>/dev/null || echo 0)
NOW=$(date +%s)
AGE_MIN=$(( (NOW - MTIME) / 60 ))
if [ $AGE_MIN -le 10 ]; then
  # Recently active → auto-fix if down
else
  # Idle → report only, don't restart
fi
```

## Correction Detection (Every 2nd heartbeat)
- Run: `python3 skills/corrections-retrieval/scan_conversations.py --days 1`
- Scans today's memory files for correction patterns
- Auto-creates drafts for high-confidence (≥70%) matches in `agency/corrections/drafts/`
- Flags uncertain (40-70%) for manual review
- **New corrections → `agency/corrections/COR-XXX.yaml`** (NOT corrections.md — deprecated)

**Quick inline check for current conversation:**
When receiving user messages, watch for correction signals:
- "That's wrong", "No, you should", "We use X not Y"
- Strong criticism of output quality
- References to violated standards
If detected → run `process_incoming_message()` from semantic classifier

## Fact Extraction (Every 3rd heartbeat)
- Spawn a subagent with task: "Read and follow `memory/FACT_EXTRACTION.md`. Review today's conversations and extract facts."
- Use model: `claude-haiku-4-5` (cheap, fast)
- This keeps the main heartbeat lean — extraction runs in isolation

## Proofreader QA Check (Every 3rd heartbeat)
- Check for pending asset reviews: `curl -s http://localhost:3025/api/pending-reviews`
- If `count > 0`: Spawn the Proofreader to review the pending assets
- After review, clear the queue: `curl -X POST http://localhost:3025/api/clear-pending-reviews`
- Also quick-scan for new unreviewed assets in `/home/aria/products/*/marketing/` and `/home/aria/products/*/assets/`
- Compare against qa-reports.json to find truly new assets
- If new assets found, spawn Proofreader subagent for batch review

**Proofreader spawn task:**
```
Review pending marketing assets at: [list paths]
Update /home/aria/products/social-qa-dashboard/qa-reports.json with findings.
Use `image` tool to visually inspect each asset for:
- Text errors (typos, duplicates)
- Branding issues (wrong name, logo)
- Quality issues (blurry, artifacts)
Mark as pass/warning/fail with notes.
```

## Adulting.Ph Link Checker (Weekly - Mondays only)
- **Only run on Mondays** (check: `date +%u` = 1)
- Run: `bash /home/aria/products/adulting-ph/apps/main/scripts/run-link-check.sh`
- This checks all download/form links in the Adulting.Ph app
- **Only report actual broken links (404s)** — ignore 403s (gov sites blocking bots)
- If broken links found → post to #build-phase adulting-ph thread (channel id: 1473289504495501434)
- Mention @bunsooo if links need updating

## Platform Standards Monitoring (Daily + Weekly)

### Daily Lightweight Check (Every heartbeat)
- Check if official platform spec pages have changed vs last saved standards
- Pages to spot-check (rotate through all 5 each day — don't fetch all at once):
  - Facebook: https://www.facebook.com/business/help/103816146375741
  - Instagram: https://help.instagram.com/1631821640426723
  - LinkedIn: https://www.linkedin.com/help/linkedin/answer/a521928
  - X: https://business.twitter.com/en/help/campaign-setup/advertiser-card-specifications.html
  - TikTok: https://ads.tiktok.com/help/article?aid=9552
- If **no change detected** → log timestamp only to `agency/processes/platform-standards-refresh-log.md`, no rewrite
- If **change detected** → update affected section in `agency/processes/platform-standards-monitoring.md` and log it with: platform, section, old value, new value, source, date, confidence

### Weekly Full Review (Mondays only)
- **Only run on Mondays** (check: `date +%u` = 1)
- Re-validate ALL 5 platforms in full detail
- Update all "last checked" timestamps in `agency/processes/platform-standards-monitoring.md`
- Log any changes to `agency/processes/platform-standards-refresh-log.md`
- Spawn a subagent for this — it's a medium-sized task:
  ```
  Read agency/processes/platform-standards-monitoring.md.
  For each platform (Facebook, Instagram, X, LinkedIn, TikTok):
  - Fetch the official help page
  - Compare specs vs saved standards
  - Update any changed values
  - Update "last checked" date
  - Log changes to agency/processes/platform-standards-refresh-log.md
  Token-efficient: only rewrite sections that changed.
  ```

## Browser Health Check (Every 4th heartbeat)
- Test browser tool: `browser action=status`
- If error (especially "device token mismatch"):
  - **Immediately DM Raven** (user:470619903855034369) with the error
  - Post to #aria: "⚠️ Browser tool down — can't do design research. Flagged to Raven."
- Browser is critical for: design research (Mobbin, Dribbble), competitor analysis, QA screenshots
- Don't silently skip — broken browser = degraded design quality

## Infrastructure Validation (Every 4th heartbeat)
- Run: `bash agency/infra/validate-infra.sh`
- Checks for:
  - Duplicate port allocations
  - Phantom allocations (port but no folder)
  - Phase vs build mismatches
  - Process health summary
- If issues found → post summary to #aria (channel id: 1467744183803580548)
- If all checks pass → silent (no "all good" spam)
- Reference: `agency/infra/slug-mapping.yaml` for caddy_slug ↔ product_folder mappings

## Daily Changelog (Last heartbeat after 22:00 PHT)
- Run: `bash /home/aria/.openclaw/workspace/scripts/daily-changelog.sh`
- Read the generated file
- Post to #aria-changelog (channel ID: 1474268929516900516)
- Simplify any technical jargon to layman's terms
- Include Discord mentions for collaborators
- Group related changes under clear headings

## Brandcast Copilot Jobs

Check for pending Brandcast copilot jobs:
```bash
ls /tmp/brandcast-copilot/pending/ 2>/dev/null
```

For each `*.yaml` job found with `status: pending`:
1. Read the job file — it contains `conversationId`, `messages`, `canvasNodes`
2. Identify the product from the user's request (e.g. "Clocklane", "Worklane")
3. Draft your scene cards (story arc, scene breakdown, aesthetic direction)
4. **Self-review scene cards before writing the response** — run the SceneCardReviewer:

```python
from generator.scene_card_reviewer import SceneCardReviewer
import sys
sys.path.insert(0, '/home/aria/projects/marketing-qa-reviewer')

reviewer = SceneCardReviewer()
review = reviewer.review(
    scene_cards=[...],   # your drafted cards
    product="Clocklane", # product from user request
    platform="tiktok",   # platform from user request or aspectRatio
    total_duration_sec=16,
)

if not review.passes:
    # Fix issues flagged by the reviewer before writing the response
    print(review.format_for_revision())
    # Revise specific scene cards based on issues, then re-review
```

**What to fix before writing the response:**
- CRITICAL issues → MUST fix (color off-brand, arc missing CTA, etc.)
- Warnings → fix if easy; note in response if deferred
- Suggestions → optional

5. Write final reviewed scene cards to the response
6. Write response JSON to `/tmp/brandcast-copilot/responses/<jobId>.json`
7. Mark job done: update `status: done` in the YAML

### ⚡ Auto-Generation (CRITICAL — 2026-02-22)

The Brandcast frontend now **automatically creates nodes AND generates frames + videos** from scene cards. No user action needed — generation starts the moment ARIA responds.

**This means:** Every response MUST include scene cards. The scene cards are the instructions for the canvas. ARIA's job is to write great scene cards — the app does the rest.

### Scene Card Format (REQUIRED per response)

Each scene card triggers: Frame generation (Gemini) → Video generation (Veo 3.1) automatically.

```
\`\`\`scene
{
  "label": "Scene 1 — Hero Shot",
  "framePrompt": "Ultra-close shot of hands opening a sleek dark laptop, cinematic blue light, dramatic shadow, shallow depth of field",
  "videoPrompt": "Slow zoom out from hands on laptop, corporate office at night behind glass, neon city lights in background, smooth camera pull-back, cinematic",
  "aspectRatio": "9:16",
  "product": "Worklane"
}
\`\`\`
```

**Fields:**
- `label` — Short, descriptive scene name (shown in canvas node + copilot chat)
- `framePrompt` — Detailed visual description for the keyframe image (Gemini generates this). Be specific: lighting, angle, composition, mood, subject.
- `videoPrompt` — Motion description for Veo 3.1. Include: camera movement, pacing, atmosphere. No audio references.
- `aspectRatio` — `"9:16"` (TikTok/Reels, default), `"16:9"` (YouTube/landscape), or `"1:1"` (square feed)
- `product` — Optional. Product name context.

**How many scenes?** Match what the user asks for. For a typical "make a video" request: 3–5 scenes covering a story arc (hook → problem → solution → CTA).

**Response file format:**
```json
{
  "jobId": "...",
  "message": "full markdown response including scene cards",
  "status": "done"
}
```

**Job file format (input):**
```yaml
type: brandcast_copilot
id: BC-<timestamp>
status: pending
conversationId: <string>
messages:
  - role: user
    content: "..."
canvasNodes: []
```

If no pending jobs, skip silently.

## That's it
- Keep heartbeats lean — only check for pending work and security spot-check
- Heavy tasks (fact extraction, memory consolidation) run as subagents
- Everything else (email, calendar, weather) handled by cron jobs
