Stack: Python 3.11+ FastAPI + uvicorn (backend), Vite + React 19 + TypeScript + Tailwind v4 (frontend in dashboard/frontend/).
Build served by FastAPI from dashboard/frontend/dist/ via catch-all SPA handler (main.py:560).
See specs/workflow.md for the full pipeline and specs/workflow.yaml for the machine-readable definition.
Issue → Plan (CTO) → Dev (branch + PR)
→ Tech Lead Code Review (mandatory gate)
→ CTO approves → CTO merges to dev
→ QA → [Pass → CTO PR to main | Fail → loop]
→ Close
The development pipeline is defined in machine-readable YAML (specs/workflow.yaml) with a JSON Schema (specs/workflow.schema.json). Every agent MUST:
- Load
specs/workflow.yamlat session start - Follow the defined stages in order
- Verify preconditions before proceeding to a stage
- Verify postconditions before marking a stage complete
- Use the defined handoff protocol (
specs/protocol.md) for agent-to-agent communication - Run
bash scripts/validate-workflow.shbefore pushing any code
Enforcement mechanisms:
- Pre-push hook (
.githooks/pre-push): runs validation on every push. Install:git config core.hooksPath .githooks - PR template (
.github/PULL_REQUEST_TEMPLATE.md): mandatory checklist in every PR
| Role | File | Scope | Gate |
|---|---|---|---|
| CTO | specs/roles/cto.md |
Architecture, launch agents, verify workflows, approve PRs, sole PR-to-main authority | Mandatory |
| Tech Lead | specs/roles/tech-lead.md |
Automated Code Review (mandatory gate), Security/UI-UX triage, delegation to Dev | Mandatory |
| Full Stack Developer | specs/roles/fullstack-developer.md |
Feature/bug implementation | Mandatory |
| QA/Tester | specs/roles/qa-tester.md |
Validation against test plan, QA loop with escalation | Mandatory |
| Security Specialist | specs/roles/security-specialist.md |
Pentesting, black box, SAST/DAST → creates Issue | On demand |
| UI/UX Specialist | specs/roles/ui-ux-specialist.md |
Design/UX review, accessibility audit → creates Issue | On demand |
| Advisory | — (see CTO) | Deep architecture review on CTO request (loop exhaustion, complex design) | On demand (CTO-activated) |
CTO ── launches agents, verifies workflows, approves PRs, sole PR-to-main authority
├── Tech Lead ── Code Review (gate), Security/UI-UX triage, delegate to Dev
├── Full Stack Developer ── implementation
├── QA/Tester ── validation, QA loop
├── Security Specialist ── pentesting → Issue
└── UI/UX Specialist ── design/UX review → Issue
↑
Advisory ── deep review on CTO request
See specs/sandbox.md for conventions.
See sandbox/README.md for implementation details.
# Backend
uvicorn dashboard.main:app --port 8765 --reload # dev server
python3 -m py_compile dashboard/main.py # syntax check
ruff check dashboard/ # lint (install: pip install ruff)
# Frontend (dashboard/frontend/)
pnpm run dev # Vite dev server, proxies /api and /auth to :8765
pnpm run build # tsc -b + vite build → dist/
pnpm run test # vitest
pnpm run test:coverage # vitest --coverage
pnpm run lint # eslint
# Deployment (production VM)
bash dashboard/start.sh # idempotent: builds frontend, creates venv, configures nginx+systemddashboard/main.py— FastAPI app. All API/auth routes before the catch-all at line 560 (@app.get("/{full_path:path}")). Never add routes after it.dashboard/runner.py— generic async subprocess runner (create_job(tool, command, cwd)+ SSE streaming).toolis a free string, add new tools without modifying this file.dashboard/chat_store.py— SQLite persistence for/chat(projects, chats, messages). DB atdashboard/data/chat.db, WAL mode, auto-created on startup@app.on_event("startup").dashboard/nginx.conf— reverse proxy, HTTP→HTTPS redirect, VPN-only (allow 10.0.0.0/24; deny all;), SSE buffering off, client_max_body_size 55M (uploads).dashboard/start.sh— production deploy: builds frontend, replaces venv atomically, generates self-signed TLS cert, installs nginx config + systemd service.
| Directory | Purpose |
|---|---|
dashboard/ |
FastAPI backend + React SPA |
sandbox/ |
Docker sandbox infrastructure for parallel agents |
specs/ |
Agent role definitions and development workflow |
tests/ |
Rate-limit / edge-case tests (Python scripts, not a formal suite) |
docs/ |
Architecture, API, DB schema, ops documentation |
/ → Landing, /notes → Notes, /chat → Chat, /chat/:chatId → Chat
GET /api/jobs/GET /api/jobs/{job_id}— list and inspect jobs (via runner.py)GET /api/jobs/{job_id}/stream— SSE log streamingGET /api/jobs/{job_id}/logs— past job logsPOST /api/jobs/{job_id}/cancel— cancel a running jobGET /api/notes/tree/GET /api/notes/content— Obsidian vault browsing (production only; returns[]gracefully when vault missing)GET /api/projects/POST /api/projects/PATCH /api/projects/{id}/DELETE /api/projects/{id}— project CRUDPOST /api/projects/{id}/folders/DELETE /api/projects/folders/{id}— project folder managementGET /api/chats/POST /api/chats/GET /api/chats/{id}/PATCH /api/chats/{id}/DELETE /api/chats/{id}— chat CRUDPOST /api/chat/send— spawnsclaude -psubprocess per message (production only; uses--resumefor continuity)POST /api/files/upload— file upload for chat (validated: 10 MB/file, 50 MB total, 10 files)GET /api/health— health check (no auth required)GET /api/diagnostics— deployment health details (frontend built, DB exists, vault exists, Python/FastAPI/uvicorn versions)
-
Temporary files: ALWAYS use
tmp/(project root) — never/tmp/,/dev/shm/, or any system temp. This is non-negotiable: system temp dirs are outside the project, invisible to git, don't get cleaned up by project scripts, and create reproducibility issues.tmp/is gitignored, project-scoped, and cleaned bygit clean. If you used/tmp/for anything, it's a bug — move it. -
Tailwind v4: CSS-first config via
@themeinindex.css(notailwind.config.ts). Dark theme:--color-bg: #0d1117,--color-surface: #161b22,--color-accent: #7C3AED. -
Secrets:
dashboard/.credentials.jsonand.envfiles (all gitignored, chmod 0600). Never hardcode, log, or commit real credentials. -
Secrets masking: API secrets sent back from
/api/credentialsare masked as••••••••; the POST endpoint preserves existing values when masked is submitted. -
HTTP Basic Auth in middleware (
AuthMiddlewareclass) vs nginx: enforced at the app layer fromDASH_USER/DASH_PASSenv vars. Exceptions:/api/health. -
Rate limiting:
slowapimiddleware —@limiter.limit("N/minute")on every API endpoint. -
Job retention: finished jobs evicted after 1 hour, max 200 finished jobs in memory.
-
Frontend testing: vitest + @testing-library/react in
dashboard/frontend/. -
No CI/CD in repo: no
.github/directory. Deployment is manual viadashboard/start.shon the production VM, triggered by a self-hosted GitHub Actions runner (configured outside this repo on the VM). -
GitHub issue labels (team convention, enforced via
specs/workflow.md): every issue gets exactly one ofbug,feature,security,documentation.
claudeCLI (authenticated subscription) — needed by/chat/home/ubuntu/vault/— Obsidian vault, needed by/notesnginx+uvicornon ports 80/443/8765- iptables firewall (persisted via
netfilter-persistent): adding a newlisten <port>in nginx.conf also needs a matching iptables rule before the traffic flows.
Static verification in sandbox: python3 -m py_compile, pnpm run build, instantiate FastAPI app and check app.routes, test API endpoints with TestClient. Never try to simulate Claude CLI, vault, or nginx here.
Role-based port ranges (fullstack: 8800-8849, QA: 8850-8899, UI: 8900-8949).
Critical cleanup order: stop container FIRST (sandbox-down.sh), then remove worktree.
See sandbox/README.md and sandbox/VALIDATION.md.