recommender
The core of oO. Takes a user + a context, returns one tip.
Contract
POST /recommend
{ user_id, context?: { time, timezone, client, ... } }
→ { tip: { id, kind: "todo"|"advice", title, body, source, deep_link, meta } }
POST /feedback
{ user_id, tip_id, reaction: "done"|"snooze"|"dismiss", at }
Internals (stable seams)
- Candidate sources — pluggable async generators. v0: Todoist tasks via
integrations. Later: advice library, calendar nudges, health prompts. - Context assembler — merges request context with features (inline now, feature-store later).
- Policy —
Policy.pick(candidates, context) → tip. Registered by name:random— v0 (Phase 0).bandit.linucb— v1 (Phase 1).remote— delegates toml/servingFastAPI scorer (Phase 1+).
Phase 0 goal
RandomPolicy only. The service, contract, and seams exist; the brain does not yet.