A conversational ops engine that resolves teacher absences end-to-end — substitute matching, reschedule, parent notifications.
When a teacher calls out, a small ops team scrambles for 30-60 minutes per incident: find a qualified substitute across timezones, reschedule the affected sessions, message parents and students, and update the source-of-truth roster. The work is mechanical but high-stakes — one missed message is a refund.
A conversational gateway: ops messages a Telegram bot, the bot parses intent with Claude, runs a 5-step matching engine (G1–G5) over the roster, proposes a reassignment plan, and only acts after a `yes` confirmation. Side effects (Slack DMs to the sub, Gmail drafts to parents, sheet writes) are isolated behind connector Protocols so each one can be mocked, dry-run, or swapped without touching the engine.
End-to-end demo handles three scenarios (happy path, sub rejection, unknown teacher) in dry-run mode with every side effect logged. 17 unit tests cover matching, workflow, NLU, and orchestrator. Designed so the live deploy is a config flag, not a rewrite.
The engine talks to DataStore / Notifier / ChatSurface Protocols. Concrete implementations (CSVDataStore, SheetsDataStore, GmailNotifier, SlackNotifier, TelegramChatSurface) plug in at the edge. Mock data and production data are the same code path — you flip a config flag.
Intents are parsed by a `MockIntentParser` (regex, offline, deterministic for tests) or a `ClaudeIntentParser` (Anthropic SDK). Same interface, identical downstream behavior — chosen at boot.
Multi-turn orchestrator goes IDLE → PROPOSING → EXECUTING → IDLE. Crash-safe because state lives on disk, not in memory — bot can restart mid-conversation and pick up.
The bot never writes, sends, or notifies without an explicit `yes`. The proposing step shows exactly what will happen; the executing step is fire-and-forget after confirmation.
Run the free 5-minute diagnostic — I'll tell you whether it's a $0 weekend project or a 2-week build.