Skip to content

s3ak6i-dev/Signal

Repository files navigation

Signal

A project management tool for AI research teams where the unit of work is the experiment, not the task.

Signal treats research sprints the way engineering teams treat development sprints — with structured hypothesis tracking, confidence scoring, version-controlled prompt bundles, and a formal handoff pipeline from research to engineering.


What is Signal

Most research teams manage their work in Notion docs, shared spreadsheets, or Jira boards that were built for engineers. Signal is purpose-built for AI research workflows:

  • Each experiment begins with a structured hypothesis (If / Then / Measured By)
  • Confidence is tracked as a 0–100 score across the sprint, not as binary done/not-done
  • When an experiment converges, it produces a Handoff Bundle — a structured artifact that an engineer can implement without needing to read the research notes
  • Prompt and model configurations are version-controlled via AVC (AI Version Control), capturing diffs between prompt versions alongside eval results
  • Dead ends are treated as first-class knowledge: every archived experiment has an epitaph and is indexed for future search so the team never repeats failed approaches
  • The Branch Graph visualizes how experiments fork from each other over time

Tech Stack

Layer Technology
Framework Next.js 16 (App Router)
Language TypeScript 5
Styling Tailwind CSS 4 + CSS custom properties (design tokens)
Database PostgreSQL via Neon (serverless)
ORM Drizzle ORM
Auth Auth.js v5 (next-auth@beta) with Google + GitHub OAuth
Charts Recharts 3
Graph @xyflow/react (React Flow v12)
Rich text Tiptap 3
Drag & drop @dnd-kit
Icons Lucide React
Deployment Vercel

Project Structure

src/
├── app/
│   ├── (auth)/
│   │   └── login/              # OAuth login page
│   ├── (dashboard)/
│   │   ├── layout.tsx          # Sidebar + topbar shell
│   │   ├── board/              # Kanban experiment board
│   │   ├── experiments/[id]/   # Experiment detail (7 tabs)
│   │   ├── handoffs/           # Handoff queue + detail
│   │   ├── handoffs/[id]/
│   │   ├── avc/                # AVC bundle list
│   │   ├── avc/[bundleId]/     # Bundle detail
│   │   ├── avc/diff/           # Side-by-side prompt diff
│   │   ├── registry/           # Dead ends registry
│   │   ├── registry/[id]/      # Dead end detail
│   │   ├── graph/              # Branch graph (React Flow)
│   │   ├── reports/            # Sprint report
│   │   ├── lead/               # Lead dashboard
│   │   ├── sprints/            # Sprint management
│   │   ├── team/               # Team members
│   │   ├── integrations/       # Integrations
│   │   └── settings/           # Workspace settings
│   ├── api/auth/               # Auth.js route handler
│   └── layout.tsx              # Root layout
├── components/
│   ├── board/                  # Kanban board components
│   ├── experiments/detail/     # Per-tab experiment components
│   ├── shell/                  # Sidebar + topbar
│   ├── shared/                 # ConfidenceBar, StatusBadge
│   └── ui/                     # Shadcn/base UI primitives
├── lib/
│   ├── auth.ts                 # Auth.js config
│   ├── db/
│   │   ├── index.ts            # Drizzle + Neon client
│   │   └── schema.ts           # Full Drizzle schema (25+ tables)
│   ├── actions/                # Server actions (experiments, handoffs)
│   ├── queries/                # DB query functions
│   ├── session.ts              # Auth helpers (getCurrentUser, requireAuth)
│   ├── mock-*.ts               # Mock data (used as fallback when no DB)
│   └── utils.ts
├── middleware.ts                # Auth.js route protection
scripts/
└── seed.ts                     # Database seed script (Sprint 14 sample data)

Pages

Work

Route Description
/lead Lead dashboard — KPIs, sprint countdown, handoff funnel, team pulse, alerts
/board Kanban board — experiments organized by status (Draft / Running / Converged / Branched / Stale)
/sprints Sprint management — three-panel layout with sprint list, sprint detail, and planning backlog
/handoffs Handoff queue — ready, blocked, in-progress, and shipped handoffs
/handoffs/[id] Handoff detail — implementation brief, failed paths, AVC bundle, confidence history
/graph Branch graph — interactive React Flow canvas showing experiment lineage in Temporal, Tree, or Cluster layout
/avc AVC bundle list — all prompt/model snapshots grouped by experiment
/avc/[bundleId] Bundle detail — prompt version, eval suite, model config, tool definitions
/avc/diff Prompt diff — side-by-side diff between two AVC bundle versions with eval delta panel

Knowledge

Route Description
/registry Dead ends registry — searchable archive of failed experiments with Keyword, Semantic, and Variable search modes
/registry/[id] Dead end detail — epitaph, hypothesis, result summary, confidence arc, related entries
/reports Sprint report — AI summary, stat cards, confidence snapshot chart, learnings, handoffs, in-flight experiments, scorecard

Workspace

Route Description
/team Team members — roles, invite panel, per-member experiment stats
/integrations Integrations — GitHub, Slack, W&B, Notion, Linear, MLflow connections
/settings Settings — General, Notifications, Appearance, Data & Export tabs

Database Schema

Signal uses 25+ PostgreSQL tables across 7 domains:

Authusers, accounts, sessions, verification_tokens (Auth.js managed)

Workspaceworkspaces, workspace_members (roles: researcher / engineer / lead)

Sprintssprints (active/closed, configurable decay/stale thresholds)

Experimentsexperiments, confidence_snapshots, team_votes, result_entries, learnings, open_questions

Handoffshandoffs, failed_paths, handoff_dependencies

AVCavc_bundles, prompt_versions, few_shot_examples, model_configs, eval_suites, eval_cases, tool_definitions, annotations

Registrydead_end_entries, dead_end_relations

Miscsprint_reports, activity_log, notifications, integrations, api_keys


Getting Started

Prerequisites

  • Node.js 20+
  • A Neon database (free tier works)
  • Google OAuth app or GitHub OAuth app (or both)

1. Clone and install

git clone https://github.com/s3ak6i-dev/Signal.git
cd Signal
npm install

2. Environment variables

Create .env.local in the project root:

# Database (Neon)
DATABASE_URL=postgresql://user:password@host/dbname?sslmode=require

# Auth.js
AUTH_SECRET=your-random-32-char-secret

# Google OAuth (optional)
AUTH_GOOGLE_ID=your-google-client-id
AUTH_GOOGLE_SECRET=your-google-client-secret

# GitHub OAuth (optional)
AUTH_GITHUB_ID=your-github-client-id
AUTH_GITHUB_SECRET=your-github-client-secret

Generate AUTH_SECRET with:

npx auth secret

3. Push the database schema

npm run db:push

This runs drizzle-kit push which creates all tables in your Neon database without generating migration files.

4. Seed sample data (optional)

npx tsx scripts/seed.ts

Seeds Sprint 14 with:

  • 4 team members (Surya, James, Mia, Priya)
  • 1 workspace
  • 11 experiments with confidence snapshots, results, and learnings
  • Parent-child experiment relationships
  • 2 handoffs (1 ready, 1 blocked)

5. Run locally

npm run dev

Open http://localhost:3000. The app redirects to /login. Sign in with Google or GitHub.

Without a database: The board page falls back to mock data automatically. Most pages work off mock data so you can explore the UI without credentials.


Available Scripts

npm run dev          # Start dev server with Turbopack
npm run build        # Production build
npm run start        # Start production server
npm run lint         # Run ESLint
npm run db:push      # Push schema to database (no migrations)
npm run db:generate  # Generate Drizzle migration files
npm run db:migrate   # Apply migration files
npm run db:studio    # Open Drizzle Studio (local DB GUI)
npx tsx scripts/seed.ts   # Seed sample data

Design System

Signal uses a dark design system with CSS custom properties. All tokens are defined in src/app/globals.css.

Color tokens

--bg: #080a0e               /* Page background */
--surface-1: #0d1117        /* Card background */
--surface-2: #161b22        /* Elevated surface */
--surface-3: #1c2128        /* Highest surface */
--signal-accent: #3b8eea    /* Primary accent (blue) */
--border-default: rgba(255,255,255,0.08)
--text-primary: #e6edf3
--text-secondary: #8b949e
--text-muted: #656d76

Status colors

--status-converged: #22c55e
--status-running:   #3b8eea
--status-branched:  #f59e0b
--status-stale:     #ef4444
--status-draft:     #656d76

Typography

  • Body: Inter (--font-inter)
  • Metrics and refs: JetBrains Mono (--font-jetbrains-mono)

Hard constraints — no gradients, no drop shadows (accent glow only), no blur, no emoji.


OAuth Setup

Google

  1. Go to Google Cloud Console → APIs & Services → Credentials
  2. Create an OAuth 2.0 Client ID (Web application)
  3. Authorized redirect URI: http://localhost:3000/api/auth/callback/google
  4. Copy Client ID and Secret to .env.local

GitHub

  1. Go to GitHub Settings → Developer settings → OAuth Apps → New OAuth App
  2. Homepage URL: http://localhost:3000
  3. Callback URL: http://localhost:3000/api/auth/callback/github
  4. Copy Client ID and Secret to .env.local

Deployment

The project is configured for Vercel deployment.

  1. Push to GitHub
  2. Import the repo in Vercel
  3. Add all environment variables from .env.local to the Vercel project settings
  4. Deploy — Vercel detects Next.js automatically

For production OAuth, update redirect URIs in your Google/GitHub apps to use your production domain (e.g., https://yourdomain.vercel.app/api/auth/callback/google).


Key Architectural Decisions

Mock data fallback — Every page that hits the database wraps the query in a try/catch and falls back to mock data. This means the UI is explorable without credentials, and the app degrades gracefully during database outages.

No Drizzle relations defined — Queries use Drizzle's select().from().leftJoin() API rather than the relational db.query.xxx.findMany({ with: {...} }) API. This avoids needing to define relations() while keeping queries explicit and composable.

Server actions for mutations — All writes go through "use server" functions in src/lib/actions/. Each action calls requireAuth(), performs the write, logs to activityLog, and calls revalidatePath to invalidate the Next.js cache.

Auth.js v5 middlewaresrc/middleware.ts protects all routes under /(dashboard) and redirects unauthenticated users to /login with a callbackUrl parameter.

Confidence as a time series — Experiment confidence is stored as a confidence_snapshots table rather than a single column on the experiment. This enables trend charts, decay detection, and sprint-over-sprint comparison.

About

Project management for AI research teams. Track experiments with hypothesis-driven workflows, confidence scoring, AVC prompt versioning, structured handoffs to engineering, and a dead ends registry — built on Next.js, Neon, and Auth.js.

Topics

Resources

Stars

Watchers

Forks

Contributors