Three terminals, ten minutes.
The local stack is the marketing site, the inbox app, the FastAPI sidecar, and SQLite. No external services, no API keys. The full Phase 3 MVP runs on your laptop.
Prerequisites
- Node 20+ — for the Next.js app.
node --versionto check. - Python 3.12+ — for the FastAPI sidecar.
python3 --version. - Three terminals. Or three tmux panes. Or three iTerm tabs.
1 · Web app on :3000
cd accountability-interface npm install # first time only npm run dev
Open http://localhost:3000 in your browser. The marketing site loads. Click Open the demo in the hero — you'll land on the inbox at /app. It will be empty until you start the sidecar in terminal 2.
2 · FastAPI sidecar on :8000
cd accountability-interface/python_app python3.12 -m venv .venv # first time only .venv/bin/pip install -r requirements.txt .venv/bin/uvicorn main:app --port 8000 --reload
The sidecar writes its SQLite database to python_app/data/accountability.db. That file is the source of truth across restarts. Health check at http://localhost:8000/ should return JSON. OpenAPI docs at /docs.
3 · TX-1 submitter — seed the inbox
cd accountability-interface/python_app .venv/bin/python tx1_submit.py
This stands in for the real TX-1 agent system. It POSTs the Chicago Bottleneck and Apex Industrial scenarios to the sidecar. Re-run it whenever you want fresh proposals — the script is idempotent (already-present proposals return 409 and are skipped).
Refresh the inbox at /app. Two proposals should appear. You're ready to walk the flow — see How to use for the step-by-step.
Reset the demo
Once you've decided both proposals, the queue empties. To replay:
# Via the UI Open /app, click 'Reset demo' in the empty state. # Via curl curl -X POST http://localhost:8000/api/admin/reset
Project layout
The codebase is small enough to read end to end in an hour. The TypeScript types in lib/types.ts mirror the spec in CLAUDE.md word for word — when they diverge, the markdown wins.
accountability-interface/
├── app/
│ ├── (marketing)/ ← this site
│ ├── (app)/app/ ← inbox, /app/proposals/[id], /app/records/[id]
│ ├── layout.tsx ← Plex Sans/Mono fonts
│ └── globals.css ← Carbon import + token overrides
├── components/
│ ├── proposal/ ← ProposalCard, OverridePanel, DismissPanel, …
│ ├── queue/ ← QueueRow, EmptyQueue
│ ├── record/ ← DecisionRecordView
│ ├── marketing/ ← SiteNav, SiteFooter, MarketingShell, blocks
│ └── shared/ ← SectionLabel
├── lib/
│ ├── types.ts ← Proposal + DecisionRecord (source of truth)
│ ├── api.ts ← sidecar client
│ ├── format.ts ← expiry formatter
│ └── seedData.ts ← in-memory fallback
└── python_app/
├── main.py ← /api/proposals, /api/decisions, /api/records
├── schema.sql ← SQLite tables
├── tx1_submit.py ← stand-in for TX-1's /submit-proposal
├── requirements.txt
└── data/ ← SQLite db (gitignored)Wiring a new agent system
SS-1 and Swarm Lite hook in the same way TX-1 does — POST a Proposal to /api/proposals, register a callback URL for decisions. The schema is in lib/types.ts; an end-to-end example is python_app/tx1_submit.py.