Skip to main content

ADR-004 — Plans become a DB-backed graph engine (editable + actionable in-app)

reference · tech-lead · updated 2026-06-21 · source

  • Status: Accepted (2026-06-20; built by effort #560)
  • Date: 2026-06-16
  • Owner: Tech Lead
  • Related issue: #560 (Plan Engine effort)
  • Supersedes: decision #221 (2026-06-10, file-based MDX plans)

Context

  • Today plans are MDX in apps/admin/src/plans/, read from disk (src/lib/plans.ts); editing them requires an IDE + PR.
  • José wants to edit and act on plans from admin/desktop (or via Claude), not through an IDE.
  • They aren't flat plans: it's plan → subplans (parent+dependsOn+timeline) — product-development-flow.md already calls for a "product Timeline" with meetings/approvals.
  • The roadmap must always stay aligned — today that's manual sync work.
  • Git-as-CMS rejected by José (no editing via IDE/commit).

Decision

  • Move plans from files to a Plan Engine with a single graph in Postgres (existing Drizzle/Fastify). Headline: one graph, three views, actionable.
  • Model — 5 tables (@tedos/db, Drizzle/Postgres): plan_node (parent_id → tree), plan_dependency (DAG dependsOn/blocks), plan_version (append-only = versioning), plan_link (issue/PR/deploy/branch = live Deliverables, the issue#↔node map), and sync_event (idempotency / loop-prevention for the bidirectional GitHub↔graph + Vercel sync: source · external_id · payload_hash · processed_at · unique(source, payload_hash)). The fifth table was added when ADR-005 made the graph a bidirectionally synced mirror of GitHub — without it the sync echoes loop.
  • The roadmap is NOT a doc: it's the timeline projection of the same graph → aligned by construction, nothing to sync.
  • In-app editing + actions (create/link issue, start, status); Claude and the admin hit the same backend (Fastify endpoints exposed as MCP) — one engine, two clients.
  • Body = markdown + structured blocks (Callout/Timeline/Deliverables as data), no JSX at runtime.
  • Scope: plans only. knowledge/ stays file-based (governed by knowledge-base.md).

Consequences

Positive

  • Edit/act without IDE or PR; roadmap always aligned; version history with diff/restore.
  • The subplan-graph is the navigation (tree), not a flat list.

Negative / trade-offs

  • Loses git-native review of plans (rebuilt with a human gate + plan_version).
  • New write surface to GitHub + a render runtime (markdown+blocks instead of build-time MDX).

Follow-ups required (done under effort #560)

  • Build: effort #560 stands up @tedos/db (5 tables), the /plan/* API, MCP tools, the GitHub↔graph + Vercel sync, the admin /plan + /roadmap views, and the one-shot issue ingest. The plan IS the parent issue (ADR-006) — no MDX plan file.
  • One-shot ingest of the existing GitHub issues → plan_node/plan_version (guarded, idempotent).
  • Reconciled plan-output-format.md, workflow-vs-product.md, kit-engine-boundary.md, CLAUDE.md; retired packages/engine/src/tickets.ts (#570).

Alternatives considered

OptionWhy not
Git-as-CMS (editor → commit/PR)José: no editing via IDE/commit; not "live"
TinaCMS (git-backed MDX)Still anchored to git/PR; same rejection
Hybrid DB + git snapshot on publishMore complex; the snapshot is added later as a "publish" action if needed

References

  • Build effort: #560 (parent issue = the plan, ADR-006)
  • knowledge/product-development-flow.md · .claude/rules/plan-output-format.md · .claude/rules/workflow-vs-product.md · .claude/rules/kit-engine-boundary.md
  • Related: ADR-005 (tasks→graph, adds sync_event) · ADR-006 (effort workflow)
  • Prior decision: #221 (2026-06-10) in decisions/log.md