The shape of V1.
One page. Every screen, every data shape, every decision that shipped with V1. The decision-capture interface lives separately at SPEC.html in the design folder; this page is the canonical, human-readable reference for what got built.
Stack & infrastructure
· Frontend: Next.js 15 (App Router) · React 19 · TypeScript · Tailwind CSS v3
· Database: Supabase (Postgres + RLS-ready) · schema in supabase/migrations/0001_init.sql
· Auth: none in V1 — single-user demo. RLS policies stubbed for later.
· Deploy: Vercel-ready (Next 15 standalone build)
· Dev server: port 3010 · npm run dev
· Supabase setup: option (c) — schema + migrations + seed only. Create the project, paste keys into .env.local, run supabase db push. App runs on local seed data until then.
Visual identity
· Palette: Cool Paper. Page #fbfaf6 · cards #f6f4ed · sunk surfaces #efece3. Matches handover/fractal-tokens.jsx.
· Type: Inter (sans, body) · Instrument Serif (italic, titles & editorial) · JetBrains Mono (caps, timestamps, tags).
· Accents: indigo #5b5bd6 for AI · amber #b4873a for human attention · forest #3d8a5a for resolve · rose clay #b3452e for destructive · graphite #6b6b6b for deferred.
· Session tints: stone (event) · sage (routine) · sand (crafted).
Information architecture
· /calendar · Calendar / Triage — inbox left (Smart/All/By Project), sessions right with capacity bars + drag targets, AI merge banners, time gaps clickable.
· Ticket Detail · centered modal overlay (880px). Triggered from any ticket. Smart description, history log, linked objects, meta column.
· /spec · this page.
· Deferred for post-V1: Database (read-only system of record) · Agents directory · Ask Agent ⌘J overlay · Object Detail · Ticket Activity full log.
The right pane — Proposal C (vertical timeline)
Selected from three proposals. Whole pane is one chronological feed of writes for the live session. Each ticket is a “dateline” header — struck through if resolved, with the active ticket showing a blinking cursor that hints at what the agent is writing right now.
· Resolved sections collapsed by default · click to expand into the change log
· Active section open and live · core changes highlighted · live cursor at the bottom
· Queued sections show ticket title and goal only
· Deferred sections show line-through title + “moved to” pointer
· Sticky footer · Resolve · Move · Stop-gate (“X unresolved · stop locked”)
Data model
Codified in lib/types.ts · mirrored as Postgres tables in supabase/migrations/0001_init.sql.
· Statuses (5): open · queued · active · resolved · deferred
· Fields: id, title, status, est_min, spent_min, project_id, urgency, source, source_icon, goal, output, session_id, moved_to, shipped_at, created_at
· Urgency: high · medium · low
· Kinds (3): crafted (focused work, amber) · routine (recurring, green) · event (external, grey)
· Fields: id, title, kind, start_min, duration_min, capacity_min, used_min, date, note
· Relationship: 1 session → many tickets via tickets.session_id
· Projects: active · paused · archive · with lead, counts, updated_label.
· Changes (history log): kind ∈ {doc, ticket, link, sheet, file, record} · op ∈ {created, updated, attached, editing, deleted, flagged, started, edited} · core?: boolean · why?: string
· Projects · People · Tickets · Documents · Sessions
· Deferred: Sheets · Records · Files · Links
Agent (⌘J)
· Mode: command palette with stubbed responses for V1. Real LLM wiring deferred.
· Contract: agent is the only mutation surface. UI panes are read-only canvases. ⌘J opens a centered 720px overlay with intent-grouped suggestions (Write · Pull · Plan · Ask).
· Default context: currently selected ticket · currently active session · all linked objects.
· Roster (post-V1): Triage · Drafter · Cohort · Scribe · Publisher · Watcher.
@-link picker
· Trigger: typing @ inside any rich-text field
· Search across: Projects · People · Tickets · Docs
· Ranking: prefix match on title (V1) · upgradeable to FTS / pgvector later
Seed data
· Used as-is from the design files. Source: handover/fractal-calendar.html + fractal-live-session-v6.html.
· People: Pak (you) · Marcus Liang · Ana Park · Dami Chau · Jin Ko · Amir
· Projects: 12 (Fractal V1 Launch · House Move · Fundraise · etc.)
· Sessions: 16 across today, tomorrow, next Monday
· Inbox: 20 unassigned tickets across all projects/urgencies
· Live demo: “Marcus review prep” session at 13:30 with 4 tickets (1 shipped, 1 active, 1 queued, 1 moved). NOW = 14:06.
What's deliberately not in V1
· No real LLM call — agent suggestions are stubbed. The mutation contract works; the model wiring is a switch flip.
· No drag persistence — Calendar drag-drop updates client state only. Wire to Supabase mutations next.
· No auth, no RLS enforcement — schema is RLS-ready (every table has user_id nullable), but policies are commented out for the demo.
· Database/Agents/Ask-Agent screens are designed but not built in V1.
· Subway map — the most ambitious DB visualization — is a post-V1 destination.
· Annotation/comment overlay from live-session-v6 (the design-review tool) is excluded from V1.
Where things live
· app/ — Next.js App Router routes (page.tsx, calendar/, session/, spec/)
· components/ — primitives, NavRail, TopBar, Shell, TicketDetailOverlay
· lib/ — types, seed data, helpers, utils
· supabase/migrations/0001_init.sql — schema
· supabase/seed.sql — seed data, mirrors lib/seed.ts
· .env.local.example — Supabase env vars template
Run it
# from ~/projects/fractal npm install npm run dev # → http://localhost:3010 # Supabase later: cp .env.local.example .env.local # paste your project URL + anon key supabase link --project-ref <your-ref> supabase db push # applies 0001_init.sql + seed.sql
When V1 stops being right, this page changes. It’s the contract; not a museum exhibit.