A local-first research operating system for turning curiosity into papers.
You build small projects, declare a primary metric, log runs against hypotheses, and the dashboard nudges you when something is narrative-ready, stalled, or worth a paper. AI critical reviews and skeleton drafts run against your Claude subscription, not API credits.
Single user. Runs on localhost. Data is one SQLite file. Designed to be opened every morning as the first hour of work (/today).
Prereqs: Node ≥ 20.19, Claude Code installed and logged in to your Pro / Max plan.
cd web
npm install
cp .env.example .env # then fill in the four required auth values (below)
npx prisma migrate dev # one-time DB setup
npm run db:seed # optional — sample projects so the dashboard isn't empty
npm run build && npm run startOpen http://localhost:3000.
Required auth. The app refuses to start until four secrets are set in web/.env. web/.env.example ships a copy-paste one-liner that generates all four (SCIENCEDASH_AUTH_TOKEN, SCIENCEDASH_SESSION_SECRET, SCIENCEDASH_PASSWORD_SALT, SCIENCEDASH_AUTH_PASSWORD_HASH) — run it, paste the results, and that's your login password set.
Optional integrations (also in web/.env):
WANDB_API_KEY=... # to ingest run metrics
GITHUB_PAT=... # to track repo freshness
No ANTHROPIC_API_KEY — AI features go through Claude Code (claude login) so they bill against your subscription. Confirm on /settings: Claude Code should show a version, not "missing".
ScienceDash runs entirely on localhost. To reach it from other devices or to connect remote workhorse agents, put it behind a reverse proxy (Tailscale, cloudflared, nginx) and set SCIENCEDASH_BASE_URL. See docs/cluster-integration.md. Auto-deploy (the /settings deploy widget) is author-specific tooling, off unless you set SCIENCEDASH_AUTO_DEPLOY_ENABLED=1.
Web terminal. When you reach the box only through the dashboard (e.g. Tailscale, no SSH) and Claude Code's login times out, every AI feature breaks with no way to re-auth. /terminal is an interactive shell on the machine as the server user — run claude setup-token, open the printed URL, and paste the code back to sign in again. It's on by default; set SCIENCEDASH_TERMINAL_ENABLED=0 to disable it. It's a real shell behind your dashboard login — but an authenticated session can already run commands via the chat's Bash tool, so the terminal is a more direct handle on the same capability, behind the same auth.
The fastest path from "I have an idea" to "I have a paper skeleton":
- Press
n(or click New project). Title + tags + one-line hypothesis. Create. Tag itexploit/explore/systemif you want those groupings on the Portfolio page — there's a row of chips you can click. - On the project page, fill the §16.1 fields (hypothesis, FOM, timeline, next steps). Status
idea → activeis gated until they're set. - Switch to Hypotheses & Runs. Declare a primary metric (
tracking_efficiency, higher better, threshold 0.99). Add a hypothesis with a 10 GPU-h budget. - Log runs as you go — name, GPU-h spent, metric values. The compute meter goes amber when you blow past budget.
- When a hypothesis lands, set its verdict to
supportedand click Spawn paper →. A six-section skeleton appears in/paperslinked to the hypothesis. - Click AI first pass on the paper to fill intro / method / experiments / results from your runs. Edit. Polish per section. Export .tex when ready for arXiv.
Every status change, paper spawn, hypothesis resolution, and accepted AI patch writes a row to the Decision log so you can see whether the random walk is moving forward (§2.4).
| Route | What it's for |
|---|---|
/ |
Today — first-hour ritual. Stalled / narrative-ready / recent runs / pending AI reviews. One card per zone. |
/projects |
List with status / tag / FOM / timeline / next-steps filters. |
/projects/[id] |
Three tabs: Overview (inline-edit fields, AI review), Hypotheses & Runs (cards + Pareto), Activity (decision log). |
/papers |
Kanban: skeleton → draft → internal → arxiv → submitted → published. |
/papers/[id] |
Section-by-section markdown editor, figure attachments, .tex export. |
/runs |
Sortable table across all hypotheses with dynamic metric columns. |
/reading |
Notes; paste an arXiv URL → autofill title / authors / abstract. |
/portfolio |
Outer-loop view: status summary, publication velocity, decision log, AI audit. |
/settings |
Claude Code / W&B / GitHub status, worker heartbeat, job log, prompt editor, per-project AI auto-review toggles. |
Keyboard: ⌘K / Ctrl-K opens the command palette (jump to project, paper, or route). / also opens it when you're not typing. ? opens the in-app help drawer. g T jumps to Today, g P Projects, g A Papers, g R Runs, g N Notes, g O Portfolio, g S Settings. n creates a new project. Esc closes any overlay. Inside the palette: arrow keys + Enter to navigate.
Tags, not fixed categories. Projects aren't categorized by a built-in type or ingredient field — everything is tags. The new-project and project-edit forms surface a row of clickable common-tag chips (exploit, explore, system, tracking, ingredient, hl-lhc, …) so you can classify with one click, but nothing is baked into the schema.
Five surfaces — all explicit-click unless you opt in:
- AI critical review (project Overview). Sends the project state to Claude with the §16.6 contract: critical, not polite, returns actionable patches. Each patch renders with an Accept button on
/today— one click applies the change and writes a Decision. - AI first pass (paper detail). Generates intro / method / experiments / results from the linked hypothesis's runs and metrics. Conclusion + related-work stay empty for you to write (§10.2).
- AI polish (per paper section). Tightens prose without changing claims; preserves
TODO(...)markers and inline math. - Portfolio audit (
/portfolio). Strategic balance review across the whole program — names projects to promote, park, or escalate. - Auto-review on stall (per project, default off). When enabled, the worker invokes critical review automatically once a project goes 14+ days without a run / decision / check-in.
Every call writes a JobRun row visible on /settings with cost in USD. Subscription billing is internal to Claude Code — costUsd is the rate-card estimate, not what you actually pay.
The four prompt templates live at web/src/lib/ai/prompts/*.md and are versioned in git. You can override any of them in the database via the editor at the bottom of /settings; the on-disk version stays as the fallback.
Boots automatically on first request via Next 16's instrumentation.ts. Three ticks:
| Tick | Cadence | What it does |
|---|---|---|
wandb_pull |
30 min | For every project with a wandbEntity/wandbProject, pulls metric values onto existing Run rows matched by wandbRunId. |
github_pull |
60 min | For every project with a githubRepoUrl, fetches last commit SHA + date. |
stall_detect |
60 min | Surfaces projects 14+ days idle on /today. For projects opted into auto-review, fires the AI review automatically. |
A heartbeat row lands every 5 minutes — visible on /settings. If a tick crashes mid-flight or the server is killed (SIGTERM), the in-flight JobRun rows are finalized with error: "shutdown" so the audit log never lies.
For things that should happen now, every tick has a "pull now" button on /settings.
The whole database is web/dev.db. Backing up is cp web/dev.db ~/Backups/sciencedash-$(date +%F).db while the server is stopped. Artifacts (figures, checkpoints) live under web/.data/artifacts/ — back that up too if you upload anything.
There's no migration story for moving between machines — just copy dev.db and the artifacts directory.
ScienceDash exists to keep a single researcher's portfolio honest: it makes you
declare a metric before you run, log runs against hypotheses, and resolve those
hypotheses into papers — so you can see whether the random walk is actually
moving forward. The dashboard enforces a small "research constitution" in code
(status gates, compute budgets, a decision log). The full rationale and the
day-to-day guide live in docs/tutorial.md.
docs/tutorial.md— how it actually works, end to end.docs/setup-tutorial.md— per-project onboarding.docs/cluster-integration.md— connecting remote workhorse agents.docs/workhorse-protocol.md— the sync wire protocol.
See web/README.md.