Commit5f245bfunknown_key
Merge pull request #100 from ccantynz-alt/worktree-agent-a3377aad30d55da26
Merge pull request #100 from ccantynz-alt/worktree-agent-a3377aad30d55da26 fix: rename duplicate migration 0065_auto_generate_tests → 0077, move…
1 file changed+49−495f245bfbad2a5a593c15680d43aee51e5978b7a7
1 changed file+49−49
ModifiedTODO.md+49−49View fileUnifiedSplit
@@ -25,61 +25,61 @@ These are NOT build tasks — the code is complete. They need ops/config action.
2525
2626These are confirmed missing by direct code inspection.
2727
28- [x] 2026-06-06 **Container registry (Docker/OCI)** — `src/routes/oci-registry.ts` implements full OCI Distribution Spec v1.0: GET/HEAD/PUT/DELETE blobs, chunked PATCH uploads, GET/PUT/DELETE manifests, tags list, catalog. Blobs stored at `${OCI_STORE_PATH}/blobs/sha256/<digest>`. `drizzle/0084_oci_registry.sql` adds `oci_repositories` + `oci_tags`. Basic auth via `api_tokens` table.
29- [x] 2026-06-06 **Redis SSE fan-out** — `src/lib/sse.ts` rewritten. When `REDIS_URL` or `VALKEY_URL` is set, uses two `Bun.RedisClient` instances (pub + sub) with `autoReconnect`. Topic-scoped SUBSCRIBE/UNSUBSCRIBE. On disconnect, re-subscribes all channels. Falls back to local delivery if Redis unreachable. In-memory path unchanged when no URL set. Zero API changes to callers.
30- [x] 2026-06-06 **Workflow cache SAVE** — `saveCacheEntry()` implemented in `src/lib/actions/cache-action.ts`. DB-backed via `workflow_run_cache` Postgres table; tarballs paths, SHA-256 hashes, 100MB cap, upserts content. Wired in `src/lib/workflow-runner.ts` post-job. LOAD unchanged.
31- [x] 2026-06-06 **Pack-content ruleset enforcement** — `commit_message_pattern`, `blocked_file_paths`, `max_file_size` now blocking at push time via pre-receive hook (`GIT_CONFIG_COUNT` env injection). Git commands: `git log --format="%H %s"`, `git diff --name-only`, `git cat-file -s`. Wired in `src/routes/git.ts` (HTTP) and `src/lib/ssh-server.ts` (SSH). All 10 push-policy + 23 ruleset tests pass.
32- [x] 2026-06-06 commit:44ed968 **Branch preview expiry cleanup** — `expireOldPreviews()` wired as `preview-expiry` autopilot task in `src/lib/autopilot.ts`. Admin UI updated to show 10 tasks including `auto-merge-sweep`, `ai-build-from-issues`, and `preview-expiry`.
33- [x] 2026-06-06 **Server targets → customer-facing** — `src/routes/deploy-targets.tsx` (414 lines). `GET/POST /settings/deploy-targets`, `POST /settings/deploy-targets/:id/delete`, `POST /settings/deploy-targets/:id/test`. AES-256-GCM encryption via `SERVER_TARGETS_KEY`. Ownership-gated. Added to settings subnav and registered in `src/app.tsx`.
34- [x] 2026-06-06 **Claude Web Sessions → customer-facing** — `/:owner/:repo/claude` now open to all authenticated users with repo access. `listSessionsForUser()` scopes sessions to owner. Session list: colour-coded status badges, reverse-chron order. SSE stream via `GET /:owner/:repo/claude/:sessionId/stream?prompt=`. Spawns `claude --print --output-format stream-json`. "✨ Claude AI" sidebar card added to repo home (`src/routes/web.tsx`).
35- [x] 2026-06-06 **AI budget hard enforcement** — `assertAiQuota(userId)` added to `src/lib/billing.ts` with 60s in-memory cache. Wired into `ai-review.ts` (posts skip comment), `ai-review-trio.ts` (fail-closed trio result), `ai-ci-healer.ts` (returns skipped), `spec-to-pr.ts` (returns error to UI). Warn at 90%, throw `AiQuotaExceededError` at 100%. Fails open on DB error.
36- [x] 2026-06-06 **Spec-to-Live real-time progress UI** — `src/routes/specs.tsx` (+593 lines). POST redirects to `/:owner/:repo/spec/:jobId/progress`. Polling (2s, <20 lines JS) as primary; SSE endpoint as secondary. 8-stage timeline: analyzing→writing→opening_pr→ai_reviewing→gates_running→merging→deploying→done. In-memory `SpecJob` Map with 10-min eviction. No-JS server-render fallback.
28- [ ] **Container registry (Docker/OCI)** — No files exist for this anywhere in the codebase. npm package registry is complete (`src/lib/packages.ts`). The OCI push/pull protocol needs implementing: `GET /v2/`, `HEAD /v2/:name/blobs/:digest`, `POST /v2/:name/blobs/uploads/`, `PUT /v2/:name/manifests/:ref`. Without Docker support, teams with containerised apps can't fully leave GitHub.
29- [ ] **Redis SSE fan-out** — `src/lib/sse.ts` is a single-process in-memory broadcaster. The TODO(scale) is right in the code. Multi-instance deploys mean live comment updates, PR live view, and push watch only reach subscribers on the same process. Replace the internal broadcaster with Redis pub/sub behind the same interface.
30- [ ] **Workflow cache SAVE** — `src/lib/actions/cache-action.ts` has an explicit TODO(v2) for the SAVE half. Only LOAD is implemented. Every CI run after the first runs cold. Wire save-on-job-success.
31- [ ] **Pack-content ruleset enforcement** — `commit_message_pattern`, `blocked_file_paths`, `max_file_size` in `src/lib/rulesets.ts` need actual git pack inspection to enforce at push time. Currently those rule types are advisory only. Implement in `src/lib/push-policy.ts`.
32- [ ] **Branch preview expiry cleanup** — `src/lib/branch-previews.ts` exports `expireOldPreviews()` but it's never called anywhere (not wired into autopilot). Branch preview rows have a 24h TTL in the DB schema (`expires_at`) but nothing enforces it. Add as an autopilot task.
33- [ ] **Server targets → customer-facing** — `src/routes/admin-server-targets.tsx` and migration `0073_server_targets.sql` exist but the routes are under `/admin/servers` — site-admin only. Build a customer-facing `/settings/deploy-targets` that lets any user add SSH deploy targets for their own repos. This is the push-to-your-own-server story.
34- [ ] **Claude Web Sessions → customer-facing** — Migration `0074_claude_web_sessions.sql` exists with `claude_web_sessions` + `claude_web_messages` tables. Admin-only in v1 per migration notes. Build the customer UI at `/:owner/:repo/claude` — browser-based Claude Code sessions with persistent transcript. This is a massive differentiator.
35- [ ] **AI budget hard enforcement** — `src/routes/billing-usage.tsx` confirms: the budget cap is advisory only ("Advisory cap; we warn when projected EOM exceeds it"). When a user's projected AI spend exceeds their cap, features should degrade gracefully. Wire `checkQuota()` from `src/lib/billing.ts` as a hard gate before AI feature calls.
36- [ ] **Spec-to-Live real-time progress UI** — Spec→PR exists. The remaining loop is PR→AI review→auto-merge→deploy→notification. More importantly, the user submits a spec and sees a blank page or redirect. Wire a live progress view (SSE-backed) showing each stage as it happens: "Writing code... Opening PR... AI reviewing... Gates passing... Merged in 1m 52s." This is the "wow" moment.
3737- [ ] **Agent marketplace — real listings** — Migration `0070_agent_marketplace.sql` is complete with full schema (listings, installs, reviews, 30% revenue cut built in). The route `src/routes/marketplace-agents.tsx` exists. But there are only seed listings. Write a "Publish an agent" guide, reach out to 10 developers, get 20+ real listings.
3838
3939---
4040
4141## 🟡 PRIORITY 3 — Messaging (Every Page Needs This)
4242
43- [x] 2026-06-06 **Landing hero** (`src/views/landing.tsx`) — H1: "Write the spec. Gluecron ships it." Subhead: "Spec to PR in 90 seconds. Push to live in 25. AI review, auto-merge, deploy — automatic." Sleep Mode demoted to single closing clause. Rail label: "deploys shipped".
44- [x] 2026-06-06 **Landing "what's happening now" rail** — Rail label updated; "Three reasons" card 1 rewritten to lead with timing numbers. Sleep Mode demoted to one line.
45- [x] 2026-06-06 **vs-github AI rows** (`src/routes/vs-github.tsx`) — All 10 AI-native rows now have latency numbers: "AI review fires the moment PR opens (~8s)", "auto-merge triggers the instant gates pass", "ai:build → draft PR in 90 seconds", etc. Sleep Mode renamed to "async batch digest" — framed as opt-in, not the headline.
46- [x] 2026-06-06 **Demo page** (`src/routes/demo.tsx`) — Tile headings: "being built right now" / "merged the instant gates passed". Steps updated with real-time language. Live feed subtitle: "Happening right now". Empty states rewritten.
47- [x] 2026-06-06 **Sleep Mode demoted** — Demoted across landing (one closing clause) and vs-github (async opt-in framing). Never leads anywhere.
48- [x] 2026-06-06 **OG/meta descriptions** — All pages audited. Landing title/desc: "AI-native git host. Spec to PR in 90 seconds." Pricing, vs-github, demo, explore, help: descriptions added. Per-repo pages: dynamic description. "wake up to", "overnight", "while you sleep" stripped everywhere including landing-2030.tsx body copy. Tests updated.
49- [x] 2026-06-06 **Pricing page** — Speed-first hero: monospace "Spec to PR in 90 seconds." accent stat, sub-copy with timing numbers. "Included in every plan" pill strip. All 4 plan card taglines mention AI review + auto-merge. OG/meta description added.
43- [ ] **Landing hero** (`src/views/landing.tsx`) — Kill "wake up to a merged PR." New headline: "Write the spec. Gluecron ships it." Subhead leads with numbers: "Spec to PR in 90 seconds. Push to live in 25. AI review, auto-merge, deploy — all automatic."
44- [ ] **Landing "what's happening now" rail** — Replace async copy with real-time events: "PR #47 auto-merged 8 seconds ago", "AI flagged a secret in last push", "Spec shipped to draft PR in 1m 43s". Live-feeling, instant.
45- [ ] **vs-github AI rows** (`src/routes/vs-github.tsx`) — Reframe 10 AI-native comparison rows around latency not just capability. Add real timing numbers. GitHub Copilot waits for you to type; Gluecron acts the moment you open a PR.
46- [ ] **Demo page** (`src/routes/demo.tsx`) — Replace "watch autopilot work" with a live ticker of things happening right now. Stock-ticker feel, not a status report.
47- [ ] **Sleep Mode demoted** (`src/routes/sleep-mode.tsx`) — Move to secondary feature only. Never headline. Primary pitch everywhere = instant results.
48- [ ] **OG/meta descriptions** — Audit every page's `<meta description>` and OG tags. Strip "wake up to" and replace with speed language.
49- [ ] **Pricing page** (`src/routes/pricing.tsx`) — CTAs currently link to `/settings/billing?plan=X` not directly to checkout. Fine functionally but lead copy needs to hit the speed angle. Add the "spec to PR in 90 seconds" stat to the hero.
5050
5151---
5252
5353## 🔵 PRIORITY 4 — Polish & Customer Experience
5454
5555### Onboarding
56- [x] 2026-06-06 **Empty state for new repos** — 3-option panel in `src/routes/web.tsx`: git commands to push first commit, link to /import, link to /:owner/:repo/specs. Done in wave 1.
57- [x] 2026-06-06 **Onboarding email sequence** — `drizzle/0081_onboarding_emails.sql` adds `onboarding_emails_sent jsonb`. `src/lib/onboarding-drip.ts`: T+0 welcome (fire-and-forget in `auth.tsx` POST /register), T+1d "Try Spec-to-PR", T+3d "Your AI is watching" via `onboarding-drip` autopilot task. Idempotent via jsonb key tracking. Skips when RESEND_API_KEY unset.
58- [x] 2026-06-06 **Dashboard "AI just did this" widget** — `AiActivityWidget` added to `src/routes/dashboard.tsx`. Queries `audit_log` (auto_merge.merged, ai_build.dispatched) and `gate_runs` (status=repaired) for last 60 minutes. Shows per-category counts, item list with links, "All quiet — AI is watching." empty state.
59- [x] 2026-06-06 **Push Watch → make it discoverable** — Pulsing "● Live" badge in `RepoHeader` (red + `pushWatchPulse` animation when <5min, muted "○ Watch" when <24hr). Query on `activity_feed` WHERE action='push'. Eye-icon watch link on every commit row. `src/views/components.tsx`, `src/views/layout.tsx`, `src/routes/web.tsx`.
60- [x] 2026-06-06 **Repo overview AI stats strip** — `getRepoAiStats(repoId)` in `src/routes/web.tsx`. Shows "⚡ AI merged N PRs this week · Saved ~X hrs · N open security alerts" below file tree. Queries `activity_feed` (auto_merge), `pr_comments` (is_ai_review), `gate_runs` (security). Hidden when all zeros.
56- [ ] **Empty state for new repos** — Push your first commit / Import from GitHub / Try Spec-to-PR. Not a blank page.
57- [ ] **Onboarding email sequence** — T+0 welcome, T+1 day "try spec-to-PR", T+3 days "here's what AI did for similar repos". Resend sequences.
58- [ ] **Dashboard "AI just did this" widget** — What autopilot did in the last hour (not 7 days). PRs auto-merged, specs shipped, CI healed, secrets repaired. Real-time feel.
59- [ ] **Push Watch → make it discoverable** — The page (`/:owner/:repo/push/:sha`) exists and is polished. Add a "Live" pulsing link on the repo header that activates after every push. This is the first "wow" moment new users need to see.
60- [ ] **Repo overview AI stats strip** — Below the file tree: "AI merged 3 PRs this week · Saved ~4.5 hrs · 0 open security alerts." Makes AI value visible at a glance.
6161
6262### Admin
63- [x] 2026-06-06 **Admin > AI cost breakdown** — `/admin/ai-costs`: monthly total, breakdown by `category`, top 10 spenders with CSS bar chart. `ai_cost_events` JOIN `users`. Added to admin dashboard nav.
64- [x] 2026-06-06 **Admin > Stripe sync** — `src/routes/admin-stripe.tsx` at `/admin/stripe`. Fetches non-free users from `user_quotas`, calls live Stripe API per user, flags plan mismatches. `POST /admin/stripe/:userId/sync` corrects local plan to match Stripe. Degrades gracefully without STRIPE_SECRET_KEY.
65- [x] 2026-06-06 **Admin > Autopilot health** — `/admin/autopilot/health`: 10 tasks with last-tick status, duration, 24h success/error counts from `audit_log`. In-process `getLastTick()`/`getTickCount()` from autopilot.ts.
66- [x] 2026-06-06 **Admin > User growth chart** — `/admin/growth`: daily signups last 30 days (`date_trunc('day', created_at)`), activation rate (users with ≥1 repo), CSS bar chart table.
67- [x] 2026-06-06 commit:44ed968 **K3 tasks on `/admin/autopilot`** — `auto-merge-sweep` and `ai-build-from-issues` were already present; `preview-expiry` added. Badge updated to "10 tasks".
63- [ ] **Admin > AI cost breakdown** — Total AI spend this month, per feature (review/triage/CI healer/spec-to-PR/chat), top spenders. `aiCostEvents` table has everything needed. Unit economics.
64- [ ] **Admin > Stripe sync** — Stripe subscription status per user vs local plan. Flag mismatches. Link to Stripe dashboard.
65- [ ] **Admin > Autopilot health** — Last tick time, per-task success/error counts, average tick duration. Expose the CI healer, proactive monitor, stale sweep, and preview expiry tasks alongside existing tasks.
66- [ ] **Admin > User growth chart** — Signups over time, activation rate (created a repo), conversion rate (free→paid).
67- [ ] **K3 tasks on `/admin/autopilot`** — `auto-merge-sweep` and `ai-build-from-issues` run every tick but aren't listed in the admin UI. Add them with stats.
6868
6969### Developer Experience
70- [x] 2026-06-06 **System/autopilot user** — `drizzle/0078_bot_user.sql` seeds `gluecron[bot]` (empty password_hash, non-loginable). `src/lib/bot-user.ts` lazy-caches the UUID. 10 comment call sites updated across `stale-sweep.ts`, `ai-review.ts`, `ai-review-trio.ts`, `autopilot.ts`. 🤖 bot pill shown in PR/issue comment headers.
71- [x] 2026-06-06 **Notification preferences** — Restructured into 4 categories in `src/routes/settings.tsx`: AI activity, CI/CD, Code review, Mentions. All existing `name=` attrs preserved — POST handler unchanged. Email pill count updated to 5 events.
72- [x] 2026-06-06 **Repo health badge on repo overview** — Health score badge added to `RepoHeader` in `src/routes/web.tsx`. Grade colours: Elite=green, Strong=blue, Improving=yellow, Needs Attention=red. Links to /:owner/:repo/insights/health. Done in wave 1.
73- [x] 2026-06-06 **AI Trio Review UI indicator** — `TrioVerdictPills` component added to `src/routes/pulls.tsx`. Three pills (Security/Correctness/Style) in the PR header meta div. Feature-flagged on `AI_TRIO_REVIEW_ENABLED=1`. Pills link to `#trio-review-section`. No extra DB query — reads from already-fetched `prComments`.
74- [x] 2026-06-06 **L1 sleep-mode column split** — `drizzle/0079_sleep_digest_column.sql` adds `last_sleep_digest_sent_at`. Schema updated. `sleep-mode.ts` and `autopilot.ts` now write/read the dedicated column. Tests updated. (Renamed from 0077 to avoid collision with `0077_auto_generate_tests.sql`.)
75- [x] 2026-06-06 **GitHub unlink route** — `POST /settings/github/unlink` deletes `sso_user_links` rows with `subject` starting `"github:"`. "Disconnect GitHub" button shown on settings page when GitHub is linked. Audited via `auth.github.unlink`.
76- [x] 2026-06-06 **Branch preview expiry UX** — `src/routes/previews.tsx`: expired cards get `.preview-card.is-expired`, strikethrough muted URL, "↺ Rebuild" button linking to `/previews/rebuild?branch=`. `expireOldPreviews()` confirmed to set `status='expired'` correctly.
70- [ ] **System/autopilot user** — K3 posts marker comments credited to the PR/issue author. Create `gluecron[bot]` synthetic user row. Autopilot actions should show a bot avatar.
71- [ ] **Notification preferences** — Flat checkbox list currently. Restructure into categories: AI activity, CI/CD, code review, mentions. Per-category toggle.
72- [ ] **Repo health badge on repo overview** — `computeHealthScore` exists, health page exists. Add a small badge to `RepoHeader`.
73- [ ] **AI Trio Review UI indicator** — When trio review is enabled, show three separate verdict pills on the PR (Security ✓, Correctness ✓, Style ✓) not one combined comment. The data is already structured that way.
74- [ ] **L1 sleep-mode column split** — `sleep_mode_digest` and weekly digest share `last_digest_sent_at`. Add `last_sleep_digest_sent_at` column.
75- [ ] **GitHub unlink route** — `/settings/sso/unlink` removes any SSO link. Add dedicated `/settings/github/unlink`.
76- [ ] **Branch preview expiry UX** — previews.tsx shows status pills (building/ready/failed/expired). Once expiry cleanup is wired, test the "expired" state renders correctly.
7777
7878### Documentation & Help
79- [x] 2026-06-06 **Docs site** — `src/routes/docs.tsx` (1600 lines). Routes: /docs, /docs/getting-started, /docs/workflow-yaml, /docs/mcp-server, /docs/api, /docs/agents. All 15 MCP tool names from mcp-tools.ts, real rate limits, real workflow YAML examples, agent.json manifest format. Footer "Docs" link updated.
80- [x] 2026-06-06 **Changelog page** — `src/routes/changelog.tsx` at `/changelog`. June + May 2026 releases listed. "Subscribe to updates" CTA → `/settings/notifications`. Changelog link added to footer in `layout.tsx`.
79- [ ] **Docs site** — `/help` exists as a migration cheatsheet. Need: Getting Started, API reference, MCP server setup, Workflow YAML syntax, Agent publishing guide. Could be `/docs` served from the self-hosted repo.
80- [ ] **Changelog page** — `/changelog` with recent releases + AI-generated notes. Users have no way to know what shipped.
8181- [ ] **Legal pages attorney review** — All four legal pages (`terms`, `privacy`, `dmca`, `acceptable-use`) are substantive drafts marked "DRAFT — requires attorney review." Get legal sign-off before any paid launch.
82- [x] 2026-06-06 **Status page — polish** — `drizzle/0080_incidents_and_status_subscribers.sql` adds `incidents` + `status_subscribers` tables. `src/routes/status.tsx` rewritten: overall status banner, 6 service uptime rows, last-10 incident history table, subscribe form with confirm/unsubscribe token flow.
82- [ ] **Status page — polish** — `/status` and `/status.svg` exist. Add incident history, subscribe-to-alerts, make it look production-grade.
8383
8484---
8585
@@ -89,27 +89,27 @@ These are confirmed missing by direct code inspection.
8989- [ ] **VS Code extension → publish** — `vscode-extension/` is built. Run `vsce package`, publish to VS Code Marketplace. Free discovery.
9090- [ ] **CLI → publish to npm** — `cli/gluecron.ts` is built. Publish as `gluecron` npm package. `npx gluecron login` as zero-install entry.
9191- [ ] **CLI → Homebrew formula** — `brew install gluecron`. Mac developer standard.
92- [x] 2026-06-06 **JetBrains plugin** — `jetbrains-plugin/` skeleton (14 files). Gradle + IntelliJ Platform Plugin 1.16.1, targets 2023.1+. 4 actions: Open PRs, Create Issue, Merge PR (API call), View Health. `GluecronUtil.kt` detects owner/repo from git remote. `./gradlew buildPlugin` → zip. Publish to JetBrains Marketplace manually.
93- [x] 2026-06-06 **GitHub migration as primary CTA** — "Migrate from GitHub →" button added to landing hero and logged-out nav (accent pill). "Coming from GitHub?" callout card on explore page. Import page headline: "Migrate your GitHub org in 60 seconds."
94- [x] 2026-06-06 **Developer program page** — `src/routes/developer-program.tsx` at `/developer-program`. Hero: "Build on Gluecron. Earn revenue." Publish agent / 70% revenue share / partner badge sections. Partner application form (POST logs + redirects). Footer link added.
95- [x] 2026-06-06 **Shareable AI hours saved card** — `src/routes/share.tsx`: SVG OG image at `/share/hours-saved?user=:username` (1200×630, dark bg, green glow number). HTML share page at `/share/:username` with og:image, Twitter pre-fill, copy-link button. "Share your AI stats" link added to billing usage page. Hours: PRs×1.5 + reviews×0.5 + heals×0.3.
96- [x] 2026-06-06 **Blog / devlog** — `src/routes/blog.tsx` at `/blog` + `/blog/:slug`. 3 posts: "30 features in one session", "Why we killed the overnight pitch", "Spec to PR in 90 seconds". Footer "Blog" link added. No DB dependency.
92- [ ] **JetBrains plugin** — Same four commands as VS Code. Kotlin plugin. Covers IntelliJ, WebStorm, GoLand.
93- [ ] **GitHub migration as primary CTA** — Bulk import is built (`src/routes/import-bulk.tsx`). Make "Migrate your GitHub org in 60 seconds" the hero CTA for GitHub users, not buried in the nav.
94- [ ] **Developer program page** — `/developer-program`: publish an agent, revenue share (30% platform cut is already in the schema), `gluecron-partner` badge, docs.
95- [ ] **Shareable AI hours saved card** — OG-image endpoint for Twitter/LinkedIn: "I saved 14 hours this week with Gluecron". Viral growth lever.
96- [ ] **Blog / devlog** — Monthly shipping updates. Developers follow platforms that ship visibly.
9797
9898---
9999
100100## ⚫ PRIORITY 6 — Strategic / Long-Term
101101
102102- [ ] **SOC 2 Type II** — Engage auditor, scope controls. 6–9 months. No enterprise deals without it.
103- [x] 2026-06-06 **EU data residency** — `drizzle/0083_data_region.sql` adds `data_region` to `repositories`. Dropdown on repo creation (US/EU Frankfurt). Read-only pill in repo settings. "EU data residency" added to Pro tier on pricing page + FAQ.
104- [x] 2026-06-06 **GDPR account deletion verification** — Two gaps fixed in `src/lib/account-deletion.ts`: disk repo cleanup (rm each `repositories.diskPath` + user dir) and Stripe subscription cancellation. DB CASCADE already handled sessions/ssh_keys/api_tokens etc. `audit_log.user_id` ON DELETE SET NULL anonymises rows. New `/admin/deletions` page + force-purge button.
105- [x] 2026-06-06 **Audit log SIEM export** — `GET /api/v2/audit` in `src/routes/api-v2.ts`. Admin Bearer auth, params: since/until/limit/cursor/actor/action/resource_type. Returns `{events, nextCursor, hasMore}` + `X-Total-Count` header. Each event: id, action, actor_username, resource_type, metadata, created_at, ip_address.
106- [x] 2026-06-06 **Enterprise sales page** — `src/routes/enterprise.tsx` at `/enterprise`. Sections: custom pricing, SSO (SAML/OIDC), SLA, data residency, SOC 2, SIEM. Contact form `POST /enterprise/contact` → `enterprise_leads` table (migration 0082). Footer "Enterprise" link added.
103- [ ] **EU data residency** — Neon postgres EU region + Fly.io EU region. "Data region" selector at org creation.
104- [ ] **GDPR account deletion verification** — Migration `0049_account_deletion.sql` adds `deleted_at` and `deletion_scheduled_for`. Verify the full cascade is implemented: bare git repo deletion, related rows purged, audit log anonymised.
105- [ ] **Audit log SIEM export** — `GET /api/v2/audit?since=&format=json`. Required by enterprise security teams (Splunk, Datadog, Elastic).
106- [ ] **Enterprise sales page** — `/enterprise`: custom pricing, SSO, dedicated support SLA, data residency. Contact form → Calendly.
107107- [ ] **Native iOS app** — Minimum viable: repo browser, notifications, PR approve/reject, AI chat. React Native.
108108- [ ] **Native Android app** — Share React Native codebase with iOS.
109- [x] 2026-06-06 **Multi-agent pipeline UI** — `src/routes/agent-pipelines.tsx` (1100 lines). Routes: `/:owner/:repo/agents` (list), `/agents/new` (builder, JS-free ?stages=N pattern), `POST /agents` (creates session + lease rows), `/:sessionId` (live view, 5s meta-refresh), `/:sessionId/cancel`. "Agents" tab added to RepoNav.
110- [x] 2026-06-06 **AI pair programmer (browser)** — Covered by "Claude Web Sessions → customer-facing" above. `/:owner/:repo/claude` open to all authenticated users. SSE streaming via `claude --print --output-format stream-json`. "✨ Claude AI" sidebar card on repo home.
111- [x] 2026-06-06 **End-to-end test suite** — 38 Playwright tests across `e2e/`: auth (7), repo (9), pulls (6), issues (8), settings (8). `e2e/fixtures.ts` shared helpers with real git push via `Bun.spawn`. `bun run e2e` script added. `@playwright/test ^1.49.0` in devDependencies.
112- [x] 2026-06-06 **Load testing** — `scripts/load-test.js` (100 VUs, p95<500ms threshold, tests landing/explore/blog/pricing). `scripts/load-test-git.js` (150 VUs + spike, tests Smart HTTP info/refs and git-upload-pack). Run with `k6 run scripts/load-test.js`.
109- [ ] **Multi-agent pipeline UI** — `agent-multiplayer.ts` and `agent_sessions`/`agent_leases` tables are complete. Wire a UI to define pipelines: Agent A writes, Agent B reviews, Agent C deploys.
110- [ ] **AI pair programmer (browser)** — Claude Code session embedded in a browser tab alongside the file editor. `claude_web_sessions` schema is ready (migration 0074), `src/routes/claude-web.tsx` exists — make it customer-facing.
111- [ ] **End-to-end test suite** — Playwright covering register → push → PR → AI review → merge. Catches flow regressions that unit tests miss.
112- [ ] **Load testing** — k6 or Artillery before any growth push. What happens at 1000 concurrent git pushes?
113113- [ ] **Database connection pooling verification** — Confirm PgBouncer or Neon pooling is correctly configured for multi-instance load.
114114
115115---
116116