ADR 0011 — Notion board as a karani-owned mirror, not a second store
Context
Kelyn wants the job hunt visible on a Notion board that stays current without manual updates. Two architectures were possible: (a) an orchestrating agent (ADAM/Claude) syncs conversationally via a Notion MCP connector, or (b) karani talks to the Notion API directly with its own integration token.
Decision
(b) — notionsync/: a thin httpx client (same pattern as the Slack and
OpenRouter clients, no SDK) plus sync logic. Rationale: “constantly
updated” requires updates from cron and from every state change, with no
human or agent in the loop.
Shape of the mirror:
- Postgres remains the system of record; Notion is a projection. Sync is one-way (karani → Notion). Edits made on the board are not read back — the board is for viewing and sharing, verbs go through Slack/CLI/MCP. This avoids two-way conflict resolution entirely.
- Page identity lives on the job row (
notion_page_id): create once, PATCH thereafter, no Notion queries needed. A page deleted on the Notion side 404s on PATCH and is transparently recreated. - Karani owns the database schema.
notion init <parent_page_id>creates the board (status/verdict selects, fit, applied date, outcome, warm-path checkbox, keyword coverage, apply link, job id). - Two sync paths:
maybe_sync_jobfires best-effort after every state change (verdict/status/outcome/draft on Slack and MCP) — it no-ops when unconfigured and never raises, so a Notion outage can’t fail a verdict. The fullsync_jobspass runs in the scheduleddaily-fullchain and reconciles anything missed. - Tracked set = any job with a
user_verdictor anapplication_status— the board shows the hunt, not the firehose of ingested postings.
Consequences
- Positive: the board updates in real time from Slack replies and on schedule from cron; zero manual upkeep.
- Positive: no slack in the dependency budget — httpx only, and the feature is entirely optional (two env vars).
- Negative: one-way sync means board edits are cosmetic. Accepted by design; revisit only if Kelyn actually starts editing there.
- Negative: schema changes require re-running
notion init(new board) or hand-editing properties. Acceptable at one-user scale.
Last updated on