Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
196 commits
Select commit Hold shift + click to select a range
78f7cca
docs: experimental Ask chat — design spec
audriB May 12, 2026
54972e5
docs: experimental Ask chat — implementation plan
audriB May 12, 2026
e1373b0
feat(ask): scaffold deps + env + feature flag
audriB May 12, 2026
5895b93
feat(ask): per-IP rate limiter for /api/ask
audriB May 12, 2026
b9a1ea0
feat(ask): system prompt for the experimental chat
audriB May 12, 2026
9c64dee
feat(ask): tool handlers for 5 catalog endpoints
audriB May 12, 2026
c7183f6
feat(ask): edge route handler /api/ask + Anthropic client
audriB May 12, 2026
7b8c9f4
feat(ask): chat UI primitives (Markdown, Message, Input, Chips, Threa…
audriB May 12, 2026
9f16701
feat(ask): top-level chat shell with v5 useChat hook
audriB May 12, 2026
3508806
feat(ask): /ask page + scoped not-found
audriB May 12, 2026
2582bff
feat(ask): add 'Ask' tab to marketing nav (env-gated)
audriB May 12, 2026
858a762
test(ask): playwright smoke for /ask
audriB May 12, 2026
382f073
fix(ask): coerce empty-string env vars to undefined in zod schema
audriB May 12, 2026
01fc12e
fix(marketing): footer mobile-viewport overflow (min-w-0 + break-words)
audriB May 12, 2026
310563e
feat(ask): voyage AI dep + VOYAGE_API_KEY env (RAG layer scaffold)
audriB May 12, 2026
5803816
feat(ask): dataset metadata sidecar + build-time index generator
audriB May 12, 2026
080b66b
feat(ask): RAG retrieval — index loader + Voyage client + tool + prompt
audriB May 12, 2026
2b71dfa
docs(ask): RAG layer addendum (design + refresh workflow)
audriB May 12, 2026
ffb2e40
fix(ask): tighten test typing on top-K index loader results
audriB May 12, 2026
ae20dd7
feat(ask): full vh-lab/shrek-lab RAG pipeline (pgvector + hybrid + re…
audriB May 13, 2026
90f39be
chore(ask): drop voyageai SDK from build script, use REST directly
audriB May 13, 2026
fc97fc4
feat(ask): Day 1 — citation foundation (refs + chips + sources panel)
audriB May 13, 2026
fabc44d
feat(ask): Day 2 — query_documents + walk_provenance tools
audriB May 13, 2026
53732c5
feat(ask): Day 4 — fetch_signal tool + SignalChart inline-rendering
audriB May 13, 2026
7da28dc
fix(ask): system prompt — force semantic_search for PI/lab name queries
audriB May 13, 2026
f4e1359
fix(ask): bump stopWhen step cap from 5 → 8 to fit multi-tool queries
audriB May 13, 2026
7e7659e
fix(ask): cap query_documents at 30 rows (was 100) — context blowup
audriB May 13, 2026
5fb80b2
fix(ask): slice query_documents rows client-side — backend ignores pa…
audriB May 13, 2026
4298ad9
fix(ask): bump step cap 8 → 12 — chart prompts need more exploration …
audriB May 13, 2026
eb3015c
chore: trigger preview redeploy for step-cap 12
audriB May 13, 2026
ee45c08
fix(ask): replace stale suggested prompts with smoke-tested scientifi…
audriB May 13, 2026
4aab582
feat(ask): binarySignalExample sidecar + file-aware fetch_signal
audriB May 13, 2026
1abfc6b
docs(ask): pre-compact checkpoint capturing state + NDI-python next step
audriB May 13, 2026
b0564a5
docs(ask): append NDI-python integration strategy to pre-compact chec…
audriB May 13, 2026
90afd8b
test(audit): byte-for-byte audit harness for NDI-python integration
audriB May 13, 2026
9d8b325
audit(layer2/3): route feat/experimental-ask-chat preview at experime…
audriB May 13, 2026
66cbe58
audit(layer2/3): flip priority — branch override before UPSTREAM_API_URL
audriB May 13, 2026
d32bf55
feat(chat): violin chart end-to-end — Plotly + PlotlyMount + ViolinCh…
audriB May 14, 2026
e321bfb
fix(chat): route server-side tool calls to experimental Railway on br…
audriB May 14, 2026
65826d2
docs(ask): pre-compact checkpoint #2 — Plan C pivot + Sprint 1 roadmap
audriB May 14, 2026
bf9de75
feat(chat): ndi_query tool — structured Query DSL cross-dataset
audriB May 14, 2026
4e15bc4
feat(chat): aggregate_documents tool — server-side numeric stats
audriB May 14, 2026
a922724
docs(ask): post-compact checkpoint update — Sprint 1 collapsed
audriB May 14, 2026
a075f16
feat(chat): lookup_ontology tool — CURIE resolution with NDI-python f…
audriB May 14, 2026
7f07848
fix(chat): surface tabular_query column-hint on empty result
audriB May 14, 2026
6f1d831
feat(labchat): wave-1 scope-up — 4 new chart types + tools + UX + ops
audriB May 14, 2026
80d1d19
feat(labchat): Sprint 1.5 — cloud-backed ndi.dataset.Dataset binding
audriB May 14, 2026
6841a12
fix(chat): tabular_query citation points to TABLE view, not one row
audriB May 14, 2026
0e6e1d2
feat(chat): per-group sample-row citations + ndi_query coverage trans…
audriB May 14, 2026
fcfdce4
feat(chat): granular completeness sweep — aggregate / treatment / spike
audriB May 14, 2026
99524d1
fix(chat): Sources panel shows ALL tool references, not just LLM-cite…
audriB May 14, 2026
30f43e2
fix(chat): aggregated audit findings — P0 + P1 fixes (frontend)
audriB May 14, 2026
07295eb
docs(audit): comprehensive audit report — 5 of 9 agent findings + fixes
audriB May 14, 2026
7897037
perf+docs: disable /ask Link prefetch + correct cost analysis
audriB May 14, 2026
f3603d0
docs(handoff): pre-compact handoff document for next session
audriB May 14, 2026
c9ca508
fix(chat): POST tools 403 + chart fences truncated — two systemic cha…
audriB May 14, 2026
b336c54
docs(handoff): final pre-compact update — all 9 audit agents done
audriB May 14, 2026
f471cff
fix(chat,auth): four navigation P0s + anonymous reset-password gate
audriB May 14, 2026
bc5e7e3
fix(a11y,docs,chat): P1 polish — chart aria-labels, JsonTree CURIE, d…
audriB May 14, 2026
9760a7c
docs: post-compact nav-P0 batch session notes
audriB May 14, 2026
14609c0
perf(chat): enable Anthropic prompt caching on system prompt
audriB May 14, 2026
9ab0aaa
perf(chat): cap streamText maxRetries to 1 — fast-fail on rate limits
audriB May 14, 2026
21fbc86
fix(docs): treat name="Document" as placeholder for H1 fallback
audriB May 14, 2026
1fe27f7
docs: update session notes with full commit chain + smoke-test PASSes
audriB May 14, 2026
dd8c92b
fix(chat,ontology): bump Sonnet to 4.6 + use NCBI Datasets taxonomy b…
audriB May 14, 2026
e9c36d6
chore(env): consolidate process.env reads through lib/env.ts
audriB May 14, 2026
252a296
fix(chat): probe→element alias hint + typed binding-failure surfacing
audriB May 14, 2026
4a98b8e
feat(observability): structured logging in /api/ask + tool handlers
audriB May 14, 2026
61f5026
perf(chat): trim duplicated guidance from system prompt (~23% shorter)
audriB May 14, 2026
e145ce6
docs: session notes for the second batch ("finish the remainders")
audriB May 14, 2026
c7f0a2a
feat(workspace): /my/workspace/[id] — Task-2 viewer GUI with 5 panels
audriB May 14, 2026
369d92a
refactor(arch): rename lib/ai shared parts → lib/ndi (Phase 1A)
audriB May 14, 2026
c6a2e3d
refactor(arch): consolidate charts + media into components/ndi/ (Phas…
audriB May 14, 2026
41a8715
feat(arch): auth-aware ToolContext — workspace works on private data …
audriB May 14, 2026
0a48a32
docs: Task 2/3 remaining gaps — follow-up spec
audriB May 14, 2026
8cee037
feat(catalog): WorkspaceCTA on /datasets/[id]/overview (Task-3 gap #4)
audriB May 14, 2026
0da372f
docs: enumerate upstream-repo asks (ndi-python, ndi-matlab, ndi-cloud…
audriB May 14, 2026
a34b448
feat(workspace): ElectrodePositionPanel — Task-2 follow-up gap #2
audriB May 14, 2026
d0f0755
refactor(chat): slim spike-summary + treatment-timeline to Railway pr…
audriB May 14, 2026
fc1c8b0
feat(workspace): PSTH panel — Task-2 follow-up gap #1
audriB May 14, 2026
f52c5b6
docs: pre-compact handoff v2 — workspace + Phase 1/2/3 architecture s…
audriB May 14, 2026
ac1285b
fix(workspace): pre-smoke bug sweep + tutorial-parity matrix
audriB May 14, 2026
c12fd7a
fix(ask): bump function maxDuration 60s → 180s
audriB May 14, 2026
abe486c
chore(docs): scrub Vercel share-bypass token from spec + parity matrix
audriB May 14, 2026
9a13de8
fix(workspace): soften Electrode Position panel error copy
audriB May 15, 2026
cc2414e
docs(specs): tutorial-parity smoke final report + ground-truth ref
audriB May 15, 2026
7d92e42
chore(security): annotate test-stub Voyage keys + add .gitleaksignore…
audriB May 15, 2026
1a3794a
docs(security): archive resolved 2026-05-14 credential-leak incident
audriB May 15, 2026
24b9590
docs(audit): comprehensive multi-angle audit + cross-dataset smoke
audriB May 15, 2026
619febf
docs(arch): comprehensive architecture audit at macro level
audriB May 15, 2026
1663a46
docs(plan): pre-compact handoff + triaged execution plan
audriB May 15, 2026
34f252e
docs(plan): consolidated master execution plan post-audit + HIPAA + /…
audriB May 15, 2026
729907d
docs(plan): add explicit orientation section for post-compact bot
audriB May 15, 2026
c474248
feat(ask): Stream 1 Tier-1 quick wins — psth registration, prompt fix…
audriB May 15, 2026
aca4428
docs(compliance): Stream 2.1 + 2.6 — HIPAA Technical Safeguards audit…
audriB May 15, 2026
9320b4b
docs(operations+architecture): Stream 2.2 + 2.3 + 2.4 design + 2.5 ADRs
audriB May 15, 2026
af24614
refactor(ask): Stream 4 — catalog handlers to lib/ndi/tools/, X-Reque…
audriB May 15, 2026
6931282
feat(workspace+chat): Stream 4 panel canonicalization + 4.11 prompt d…
audriB May 15, 2026
3b7cf54
feat(workspace+infra): S6.10 catalog badge + S6.2 workspace-client te…
audriB May 15, 2026
8660501
feat: finish remaining plan — AI SDK v6 + Stream 3 (auth-gated /ask, …
audriB May 15, 2026
a285a0b
docs: pre-compact handoff + CLAUDE.md sync + master-plan status marke…
audriB May 15, 2026
567ff0f
docs(CLAUDE.md): promote orientation to the TOP — survives compaction…
audriB May 15, 2026
a872d4b
feat(chat+tables): Stream 3.5 ToolContext retrofit + Voyage cost accu…
audriB May 15, 2026
d9c8c3f
feat(aggregate-documents): Stream 4.9 — thin client over /api/aggrega…
audriB May 15, 2026
38c3b28
docs: post-compact remainders — Stream 3.5 + 3.2 + 4.9 + 5.8 status u…
audriB May 15, 2026
1333fd3
design(workspace): lock decisions on /my/workspace redesign
audriB May 15, 2026
7efa9b1
feat(workspace): Phase A — split /my/workspace into tabbed layout
audriB May 16, 2026
a921427
feat(workspace): Phase B — Overview + Structure tabs
audriB May 16, 2026
1d88fa9
feat(workspace): Phase D — AskPanel (drawer/sidebar/fullscreen) + ret…
audriB May 16, 2026
0bfafd0
feat(workspace): Phase C — Subjects + Sessions tabs (filter + virtual…
audriB May 16, 2026
1808bee
feat(workspace): Phase E — panel anchor ids + design doc update
audriB May 16, 2026
8664f64
feat(workspace): Phase F — one-canvas redesign (rip 5-tab IA)
audriB May 17, 2026
78d9aa8
docs(workspace): Phase F implementation log + audit dispositions
audriB May 17, 2026
b3b4305
feat(workspace): Phase G — interactive data grid with multi-select + …
audriB May 17, 2026
95cdeba
feat(workspace): Phase H — fill the gaps (group-by, multi-sort, colum…
audriB May 17, 2026
61562ff
fix(build): commit pnpm-lock.yaml updates (Phase G + H Radix deps)
audriB May 17, 2026
4b2d22d
fix(workspace): StimuliPicker pageSize 500 → 200 (backend cap)
audriB May 17, 2026
ca19a61
docs(workspace): carryability + architecture review + small fixes
audriB May 17, 2026
777da84
fix(use-this-data): simpler default snippets per Steve's feedback
audriB May 17, 2026
8917ffa
docs(audit): post-compaction audit plan + CLAUDE.md pointer
audriB May 17, 2026
bd58e07
Fix 20 bugs from 2026-05-18 comprehensive audit
audriB May 17, 2026
c90cb59
Dynamic-column auto-discovery for workspace pickers
audriB May 17, 2026
eeb3dd1
Workspace pickers: full dynamic column construction, no hardcoding
audriB May 17, 2026
9bf13fa
Critical: route handlers were being bypassed by Vercel rewrite; +UI s…
audriB May 17, 2026
750b759
UI sweep wave 2: chat panel Safari fix, table H-scroll, tutorial doc
audriB May 17, 2026
f3e5529
docs(backend-followups): add F-1c (snapshot probes) + F-1d (epoch alias)
audriB May 17, 2026
e200f97
G-verify followup: chat header truncate chain + F-1e backend ticket
audriB May 17, 2026
17b785b
Session handoff: 2026-05-18 audit + UI sweep arc
audriB May 17, 2026
5030c76
SignalViewer: time-coloring of traces
audriB May 17, 2026
d77b7f4
Video playback panel (Bhar B10, Haley H12)
audriB May 17, 2026
222fe92
BehavioralTrack panel (Haley XY trajectory)
audriB May 17, 2026
6ad978c
Merge feat/signal-time-coloring: SignalViewer time-coloring of traces
audriB May 17, 2026
2f83456
Merge feat/video-playback-panel: Video playback panel (Bhar B10, Hale…
audriB May 17, 2026
511b705
Merge feat/behavioral-track-panel: BehavioralTrack panel (XY trajecto…
audriB May 17, 2026
fc1b8a8
UI polish: header H-scroll sync + mobile minmax
audriB May 17, 2026
7a7aafc
Patch-clamp step-family panel (Francesconi D8)
audriB May 17, 2026
caa93a7
Derived/computed columns on tabular_query views
audriB May 17, 2026
b0a2835
Session handoff: 2026-05-19 evening post-handoff execution
audriB May 17, 2026
66667ef
Fix: VideoPlaybackPanel rejecting valid video docs
audriB May 18, 2026
83ea47e
Doc: live panel-exercise pass + B1 RCA
audriB May 18, 2026
035d152
feat(BehavioralTrack): pair-mode for Haley-style X+Y split docs
audriB May 18, 2026
8a92e24
docs(adr): ADR-009 — Railway list endpoints return per-doc data
audriB May 18, 2026
61d3fb9
Doc: code-out-everything phase + Bhar Gantt live-verified
audriB May 18, 2026
d8546ae
Doc: pre-compaction handoff polish — deferred-items TL;DR + CLAUDE.md…
audriB May 18, 2026
f89af4b
fix(counts): wrapper-class filter parity (Bhar 12 → 11)
audriB May 18, 2026
fd44603
fix(css): mobile <375px sweep + loading skeleton harmonization
audriB May 18, 2026
870e215
refactor(F-1b): remove JS treatment-broadcast pivot — backend now shi…
audriB May 18, 2026
fe6a26f
Doc: post-compaction session shipped F-1b end-to-end + CSS sweep
audriB May 18, 2026
e14cdab
docs: add 10-minute team tutorial handout
audriB May 18, 2026
73c71df
docs(handout): swap Bhar demo for Francesconi patch-clamp (better vis…
audriB May 18, 2026
67d6999
fix(F-4): useQuery for workspace panel runs — stable query keys + dedup
audriB May 18, 2026
28a02eb
fix(F-1b-UI): don't auto-hide server-discovered columns on sparsity
audriB May 18, 2026
f473d61
Doc: handoff updated with F-1b-UI fix, F-4 merge, 4 new bugs surfaced
audriB May 18, 2026
73d2c4d
docs(B6): spec for parent/aggregate session filter
audriB May 18, 2026
05487ec
fix(B4): fallback Document name in pickers when base.name is empty
audriB May 18, 2026
1af8b41
fix(B1/B7): accept NDI-format AND Mongo ids in panel Document ID inputs
audriB May 18, 2026
bed4c72
Doc: handoff updated post-bug-blast arc + exhaustive test matrix design
audriB May 18, 2026
a3f6855
Doc: B6 fully closed (8-commit composition + live-verified sessions=2)
audriB May 18, 2026
ecb084e
docs(S5.3): write cross-table joins design spec
audriB May 18, 2026
a7bce45
feat(S5.3): cross_table_query tool handler + proxy route + tests
audriB May 18, 2026
5d9ae7e
fix: H-scroll alignment between table header and body for wide tables
audriB May 18, 2026
ecc2d8a
feat(S5.3): ScatterChart component + cross_table_query chat tool
audriB May 18, 2026
de8cd0b
feat(S5.3): wire scatter-chart fence into Markdown chat renderer
audriB May 18, 2026
29f9aa9
feat(S5.3): system-prompt + chat-tools description for cross_table_query
audriB May 18, 2026
b4cd502
feat(S5.3): BehavioralComparePanel cross-table mode toggle
audriB May 18, 2026
163a729
docs(handoff): post-crash recovery handoff for completion run
audriB May 19, 2026
a324ff9
docs(handoff): correct F-1 status + lock in F-6, B6 audit, ?className…
audriB May 19, 2026
8ff0749
docs(handoff): add pre-flight checklist at top of post-crash block
audriB May 19, 2026
d7c90d2
docs(handoff): S5.3 backend shipped + verified; checklist now empty
audriB May 19, 2026
b7b6f78
docs(handoff): completion run fully done — all deferred items resolved
audriB May 19, 2026
3e0c28d
fix(overview): session-count override no longer undoes B6 filter
audriB May 19, 2026
c59eaf4
docs(test-matrix): synthesize 3-agent results + 8 new bugs surfaced
audriB May 19, 2026
1583a33
fix(hero): suppress precomputed Subjects when documentCount is 0
audriB May 19, 2026
15af094
docs(test-matrix): update synthesis + handoff with 3 fixes shipped
audriB May 19, 2026
5559e53
docs(test-matrix): root-cause NEW-5 as Vercel SSO + reclassify NEW-2
audriB May 19, 2026
d06e9e2
fix(workspace): friendly fallback when dataset metadata fails to load
audriB May 19, 2026
41dd6d4
docs(ops): Vercel Automation Bypass Token setup guide
audriB May 19, 2026
57bab7e
docs(test-matrix): retract Vercel SSO root-cause claim
audriB May 19, 2026
cc25719
feat(workspace): media panel handles images + Documents picker auto-f…
audriB May 19, 2026
4a0ddd7
feat(code-export): complete fetch_signal + add get_document + cross_t…
audriB May 19, 2026
e659488
docs(handoff): Show-Code deep-dive scope for post-compaction agent
audriB May 19, 2026
e68af00
fix(code-export): apply NDI-python + NDI-matlab audit findings
audriB May 19, 2026
ef4d11a
feat(code-export): co-versioning safety check (Topic #9, static layer)
audriB May 19, 2026
4f54f5c
fix(code-export): live-verified file shape pattern (Topic #6 partial)
audriB May 19, 2026
ee21d5b
docs(handoff): GitHub Template arc — Phase 1 scaffold landed
audriB May 19, 2026
4e85ef8
feat(github-template): Open in GitHub + Download ZIP buttons (ADR-010)
audriB May 19, 2026
e2fd90a
docs(handoff): GitHub Template arc — all 3 pillars landed
audriB May 19, 2026
9955c21
docs: consolidate handoff into HANDOFF.md + supersede old dated docs
audriB May 20, 2026
6178aa2
fix(security): GitHub Template + proxy.ts hardening (audit 2026-05-20)
audriB May 22, 2026
77d6db1
fix(data-isolation): env discriminator + cron gating (audit 2026-05-20)
audriB May 22, 2026
fa70e07
fix(ask): hardening — fail-closed gate + KV daily refund + telemetry …
audriB May 22, 2026
2a7e7c2
fix(tools): scope=private unlock + sanitize + HNSW ef_search (audit 2…
audriB May 22, 2026
41f66ad
fix(workspace): NEW-2 root cause + panel canonicalization (audit 2026…
audriB May 22, 2026
e819be4
docs: HANDOFF + HIPAA + DR drift (audit 2026-05-20)
audriB May 22, 2026
1ada2d0
test(ask): regression coverage for P0 #5 fail-closed gate
audriB May 22, 2026
b2925b9
chore: gitignore .env*.local
audriB May 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ test-results/
/[0-9][0-9]-*.jpg
/[0-9][0-9]-*.yml

# Audit subdirectory at repo root — agents bucket their per-session
# screenshots under `audit/<YYYY-MM-DD-topic>/` so the root-level
# `/audit-*.png` patterns above don't catch them. Anchor the dir
# itself so the whole tree is ignored.
/audit/

# macOS Finder duplicate files + directories (caught by hygiene CI; should
# never reach repo). Cover both extension-bearing files (`Foo 2.tsx`) and
# extension-less files (`pre-push 2`, `.npmrc 2`) and dup-named dirs
Expand All @@ -81,3 +87,8 @@ test-results/
" 2".*
" 3".*
.vercel

# Local Playwright snapshot artifacts (never commit)
workspace-snapshot.md
.playwright-mcp/
.env*.local
26 changes: 26 additions & 0 deletions .gitleaksignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# gitleaks per-commit allowlist
# https://github.com/gitleaks/gitleaks#gitleaksignore
#
# All entries below are findings in HISTORICAL commits that are no
# longer reachable from any branch HEAD after the 2026-05-15 BFG
# history scrub (see SECURITY-INCIDENT-2026-05-14.md for the
# incident write-up). They remain reachable only via the
# `gitleaks-pre-scrub-2026-05-15-rollback` tag, which is the
# emergency-rollback safety belt and will be deleted ~7 days after
# the scrub once production has burned in cleanly.
#
# The findings are test stubs — fake keys shaped like the Voyage AI
# `pa-` prefix but with literal fixture values like
# `pa-test-key-1234567890`. Inline `// gitleaks:allow` annotations
# have been added to the live versions of those test files, so the
# fingerprints below stop being findings once the rollback tag is
# deleted.

# voyage-client.test.ts (line 18 of commit 080b66b0) — test stub
080b66b0262dd6ef68775547873747bf3653b913:apps/web/tests/unit/ai/voyage-client.test.ts:generic-api-key:18

# semantic-search-tool.test.ts (line 40 of commit 080b66b0) — test stub
080b66b0262dd6ef68775547873747bf3653b913:apps/web/tests/unit/ai/semantic-search-tool.test.ts:generic-api-key:40

# semantic-search-tool.test.ts (line 96 of commit ae20dd72) — test stub
ae20dd7245310a1a4694db9f2657a70e4f2b1353:apps/web/tests/unit/ai/semantic-search-tool.test.ts:generic-api-key:96
197 changes: 187 additions & 10 deletions CLAUDE.md

Large diffs are not rendered by default.

78 changes: 73 additions & 5 deletions apps/web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,83 @@
#
# Phase 4 wires UPSTREAM_API_URL into next.config.ts rewrites.
# Phase 3a wires INTERNAL_API_URL into RSC server-side prefetches.
# Phase 5 wires EDGE_CONFIG into lib/flags.ts.
# The /ask experimental chat reads ANTHROPIC_API_KEY, VOYAGE_API_KEY,
# DATABASE_URL, and NEXT_PUBLIC_ASK_ENABLED.
# The cron warm-cache route reads CRON_SECRET.

# FastAPI proxy base (Railway) — required for /api/* rewrite (Phase 4)
# ──────────────────────────────────────────────────────────────────
# Backend (FastAPI proxy on Railway) — required for /api/* rewrite
# ──────────────────────────────────────────────────────────────────

# Public/edge rewrite target — Vercel proxies `/api/*` here.
UPSTREAM_API_URL=https://ndb-v2-production.up.railway.app

# Same as UPSTREAM_API_URL in production. Used by RSC server-side fetches
# to bypass the Vercel rewrite layer (avoids double-hop). Phase 3a.
INTERNAL_API_URL=https://ndb-v2-production.up.railway.app

# Vercel Edge Config connection string (Phase 5).
# Get from Vercel dashboard → Edge Config → Connection String.
# EDGE_CONFIG=https://edge-config.vercel.com/...
# ──────────────────────────────────────────────────────────────────
# Cron — /api/cron/warm-cache shared secret
# ──────────────────────────────────────────────────────────────────

# Bearer secret that external cron callers must echo as
# `Authorization: Bearer ${CRON_SECRET}`. Vercel's own cron (set in
# vercel.json) sets `x-vercel-cron: 1` and bypasses this — so the
# variable can be unset for Vercel-managed cron only.
# CRON_SECRET=<random 32+ char hex>

# ──────────────────────────────────────────────────────────────────
# /ask experimental chat (anonymous-public on feat/experimental-ask-chat)
# ──────────────────────────────────────────────────────────────────

# Anthropic API key (Sonnet 4.x). When unset OR empty, /api/ask returns
# 503 and /ask renders a "coming soon" notice. Min length 20 chars.
# ANTHROPIC_API_KEY=sk-ant-api03-...

# Public flag toggling the "Ask" link in the marketing header. Set
# to '1' to surface the tab; '0' or unset hides it. Decoupled from
# ANTHROPIC_API_KEY so the key can be deployed without the tab
# visible to general visitors.
# NEXT_PUBLIC_ASK_ENABLED=0

# Voyage AI key for query-time embedding + reranking (voyage-4-large +
# voyage rerank-2.5). Same key shape as vh-lab + shrek-lab chatbots.
# When unset, semantic_search_datasets returns an error and Claude
# falls back to structured catalog tools. Min length 10 chars.
# VOYAGE_API_KEY=pa-...

# Postgres + pgvector connection string for the /ask RAG store.
# Each chatbot owns its own Railway-hosted pgvector instance.
# Required at runtime when semantic_search_datasets is exercised, and
# at build time when running `pnpm build-ask-index`.
# DATABASE_URL=postgresql://user:pass@host:port/dbname?sslmode=require

# ──────────────────────────────────────────────────────────────────
# GitHub Template workflow (ADR-010)
# ──────────────────────────────────────────────────────────────────
# Powers the "Open in GitHub" + "Download as ZIP" buttons on every
# workspace panel + chat tool message. The buttons let users derive
# their own private repo from `Waltham-Data-Science/ndi-analysis-template`
# pre-populated with `current_analysis.py` matching the panel they
# were inspecting. See apps/web/docs/architecture/decisions/010-...
#
# GITHUB_CLIENT_ID + GITHUB_CLIENT_SECRET come from a GitHub OAuth App
# (Settings → Developer settings → OAuth Apps). Authorization callback
# URL must include `/api/github/oauth/callback` on every deploy. When
# either is unset, the "Open in GitHub" button renders disabled with
# a tooltip; the "Download as ZIP" button still works if GITHUB_APP_TOKEN
# is set. Min length 10 chars (GitHub IDs are ~20 chars).
# GITHUB_CLIENT_ID=Iv1.deadbeefdeadbeef
# GITHUB_CLIENT_SECRET=<github-oauth-app-secret>

# Server-side PAT used to read the PRIVATE template repo for the
# "Download as ZIP" flow (no user OAuth). Scopes: `repo` (read).
# When unset, the /api/github/download-analysis-zip route returns
# 503 with a typed envelope. Min length 20 chars.
# GITHUB_APP_TOKEN=ghp_<token>

# Public flag that the OpenInGitHubButton reads to decide whether to
# render enabled or disabled. Mirrors GITHUB_CLIENT_ID presence on the
# server. Decoupled so staging can set the secrets server-side while
# still hiding the button from end users. Set to '1' to enable.
# NEXT_PUBLIC_GITHUB_INTEGRATION_ENABLED=0
1 change: 1 addition & 0 deletions apps/web/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.vercel
25 changes: 23 additions & 2 deletions apps/web/COMPLIANCE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
# Compliance posture — `ndi-cloud-app` (2026-04-26)
# Compliance posture — `ndi-cloud-app` (internal, 2026-04-26)

> **2026-05-15 update — this document is now SUPPLEMENTARY.**
> The authoritative externally-distributable compliance posture is
> **`apps/web/docs/compliance/posture.md`** (Stream 2.6 deliverable).
> The control-by-control mapping of how each §164.312 requirement is
> realized in code lives in
> **`apps/web/docs/operations/hipaa-technical-safeguards.md`**
> (Stream 2.1 deliverable).
>
> This file is preserved for the data-residency / encryption / audit-trail
> reference tables which the externalized doc summarizes but does not
> reproduce in full. Internal contributors should use this file; external
> reviewers (IRB, CISO, prospective enterprise partners) should be sent
> the doc under `docs/compliance/`.

This document records the data-handling, encryption, access-control,
audit-trail, and regulatory-fit posture of the unified
Expand Down Expand Up @@ -254,8 +268,15 @@ scratch.
audit, O5 origin enforcement, O6 IDOR investigation.
(`Waltham-Data-Science/ndi-data-browser-v2/docs/plans/cross-repo-unification-2026-04-24.md`)

## 8. Update history
## 8. External services

| Service | Purpose | Data shared | Direction |
|---|---|---|---|
| **GitHub (OAuth + REST)** | "Open in GitHub" + "Download as ZIP" — ADR-010 | The user's own OAuth token (HttpOnly cookie, encrypted at rest with `GITHUB_TOKEN_ENCRYPTION_KEY`); the panel args + datasetName when the user clicks. No PHI; the dataset args are pointer references the user just saw in the workspace. | Outbound only; GitHub never reads cloud-app data. |

## 9. Update history

| Date | Change | Reason |
|---|---|---|
| 2026-04-26 | First draft. | Phase 6.7 Sequence 5 audit follow-up A10. |
| 2026-05-19 | Added §8 External services for GitHub OAuth + PAT. | ADR-010 — GitHub Template workflow. |
Loading
Loading