# Next Session: Fix Annie Startup Spam

## What
Every time annie-voice restarts, scheduled agents (especially proactive-triage, every 15 min) fire immediately with stale context, sending nonsensical Telegram messages to Rajesh. Fix by adding eager `_compute_first_run` in `start()` (prevents instant-fire) plus a short grace period sleep (gives context sources time to refresh with fresh data).

## Plan
`~/.claude/plans/synchronous-questing-dragon.md`

Read the plan first — it has the full implementation, all 13 adversarial review findings, and design decisions.

## Key Design Decisions (from adversarial review)

1. **Hybrid approach, not sleep-only.** Architecture review showed a bare `asyncio.sleep(300)` was a blunt instrument with no observable state. The fix is: (a) eager `_compute_first_run(boot_now)` in `start()` to anchor grid math to boot time, (b) short 120s grace period as defense-in-depth for stale context.
2. **Safe env var parsing.** Module-level `int(os.getenv())` crashes the entire import on bad input. Use `_parse_grace_period()` helper with warning + fallback to 120.
3. **Observable grace state.** `_grace_until` timestamp exposed in `list_jobs()` so dashboard shows `grace_remaining` during suppression. Review found "no observable state surface" was a critical flaw.
4. **Explicit CancelledError handling.** Grace sleep wrapped in try/except — logs "grace period interrupted by shutdown" and returns cleanly.
5. **Tests use object-form monkeypatch** (`monkeypatch.setattr(agent_scheduler, "...", N)`) and all have `@pytest.mark.asyncio` (code review found string-form and missing decorator would cause silent pass in strict mode).
6. **120s not 300s.** Reduced from 5 min to 2 min after review showed 300s suppresses legitimate network anomaly alerts on 3am crash restarts.

## Files to Modify

1. `services/annie-voice/agent_scheduler.py` — Add `import os`, safe parser, `_grace_until`, eager init in `start()`, grace sleep in `_scheduler_loop()`, grace state in `list_jobs()`
2. `services/annie-voice/server.py` — One log line after scheduler start
3. `services/annie-voice/tests/test_agent_scheduler.py` — 6 new tests

## Start Command

```
cat ~/.claude/plans/synchronous-questing-dragon.md
```

Then implement the plan. All adversarial findings are already addressed in it.

## Verification

1. `cd services/annie-voice && python -m pytest tests/test_agent_scheduler.py -v` — all 6 new + existing tests pass
2. `cd services/annie-voice && python -m pytest tests/ -x --timeout=60` — full suite, no regressions
3. On Titan: `git pull && find services/annie-voice -name '*.pyc' -delete`
4. `./start.sh annie` (from laptop)
5. Check logs for "Startup grace period: 120s" and 2 min later "scheduler active"
6. Check dashboard agent status: `grace_remaining` field visible during grace
7. Confirm no Telegram spam for 2 minutes after restart
8. Confirm proactive-triage fires normally at next 15-min grid slot after grace
