The tick
backend/services/heartbeat.py has an async _tick() that runs on a schedule. Each tick:
- Skip if Dad is currently chatting (streaming guard, lesson 4).
- Run vault auto-indexing (incremental ChromaDB update for changed files).
- Read all task files in
vault/todos/. - Pass them to an LLM with the current time and recent context.
- If the LLM decides to act, execute (could be: send a Telegram message, post to cwk-site, fetch market data, anything).
- Update task files based on what was done.
Why an LLM is the right scheduler here
'Every Monday morning unless it's a holiday' is hard to express in cron. 'When the market closes red 3 days in a row' is hard to express in any DSL. An LLM reads the todo + the world state + the recent context and decides. The scheduler isn't the cron — it's the judgment.