Why split from scheduler.py
scheduler.pyis 2000+ lines and growing. Small interval and cron jobs ship inline there because they're one function and one trigger. Heavy multi-step jobs (dreaming, graph rebuild, FAQ compilation) get their own file under app/cron/ so the implementation has room to breathe, and the scheduler file stays scannable.
The jobs
dreaming.py — Light + deep dreaming
Schedule: Light: 02:00 WITA daily · Deep: Mon 04:00 WITA
Reflection passes over recent interactions that produce memory summaries, taste updates, and agent insights. Light is fast and incremental; deep is slower and produces new long-term memory chunks.
Outputs: Updated UserMemory rows, new ProjectMemory entries, LLM-written summaries fed back into the soul prompt.
graph_builder.py — Entity graph rebuild
Schedule: Every 1 hour
Rebuilds the derived edges of the knowledge graph from raw interactions, user memory, venue chunks, and A2A envelope history. Writes EntityNode and EntityEdge rows with typed relations.
Outputs: Fresh graph ready for venue recommendations, taste similarity queries, and network-level insights.
wiki_reconcile.py — Fleet wiki reconciliation
Schedule: Every 4 hours
Syncs the authoritative agent wiki (agnt-wiki/) back against the project memory store so fleet agents share the same view of the platform, people, and ongoing work.
Outputs: Updated ProjectMemory entries, delta log appended with reconciliation diffs.
faq_compile.py — FAQ compilation
Schedule: Extraction: Sun 23:59 WITA · Compilation: Sun 03:00 WITA
Two-stage weekly pipeline. Extraction clusters the week's support conversations into FAQ candidates. Compilation reads the candidates and emits a compiled FAQ index the public /faq page consumes.
Outputs: Updated FAQ index, delta log entry, optional PR to agnt-wiki.
Leader election
Every cron job ends up running inside a scheduled APScheduler trigger, which means it's already protected by the scheduler's Redis-backed leader lock. Only the leader worker actually runs the function. Jobs that touch money or produce durable data also take a PostgreSQL advisory lock as a belt-and-braces second layer.
Runbooks
Jobs that matter in ops have their own skill docs in the fleet skill directory (agnt-fleet/skills/). For example:
agnt-faq-extract— weekly FAQ compiler runbookagnt-hypothesis— deep dreaming hypothesis formatagnt-cron— full APScheduler reference