Source-backed investment state for private-market deal teams.
DealState is an archival state register for investment teams. It turns scattered files, emails, CRM updates, notes and generated work into a single, source-backed view of what the team knows, believes, questions and still needs.
It is deliberately not a document repository and not a generic chat-over-files demo. Documents are inputs. DealState is the investment state derived from those inputs.
Live paths
| Surface | Link | What to look at |
|---|---|---|
| Landing page | dealstate-zeta.vercel.app | Product positioning, Humanist Compute Atelier visual system and core state loop |
| Demo deal | /opportunities/project-nova | Fully populated synthetic deal room |
| Pipeline | /opportunities | State list with Project Nova plus thin synthetic deal shells |
| Methodology | /methodology | Rules behind source-backed state derivation |
The current app uses a Humanist Compute Atelier direction: paper canvas, editorial serif type, sparse institutional navigation, source slips, provenance lines, marginalia and state-register cards. The previous dusk aesthetic is archived under docs/archive/dark-dealstate-aesthetic/.
DealState keeps the operating state of a deal visible:
| Product question | DealState answer |
|---|---|
| What is currently true? | A current state card with recommendation, confidence, source coverage and key metrics |
| What changed since the last review? | A timestamped change rail with evidence references |
| Which claims are supported? | A claims ledger that separates sourced facts, inferences, conflicts and unsupported assertions |
| What is missing before IC? | A document checklist and suggested request list |
| Where are the risks? | Open issue tables with severity, evidence and owner-style next actions |
| Can I ask the deal a question? | Deterministic opportunity-manager answers over the synthetic state |
| What can I reuse? | Generated outputs for onboarding, market mapping and theme work |
Project Nova is the populated demo opportunity. All figures, people, files and companies are synthetic.
| Metric | Current demo state |
|---|---|
| Source artefacts | 14 |
| Received artefacts | 7 |
| Missing or requested artefacts | 5 |
| Superseded artefacts | 2 |
| Open diligence issues | 5 |
| Derived key metrics | 5 |
| Firm scoring dimensions | 9 |
| Overall deal score | 61 |
| Source coverage | 46% |
| Generated outputs | 3 |
pie title Project Nova source artefacts
"Received" : 7
"Requested" : 3
"Missing" : 2
"Superseded" : 2
The intentionally useful bit is the tension in the state: ARR is reported at EUR18.4m in the May model and EUR17.8m in the IC memo draft, NRR is asserted without cohort evidence, EBITDA add-backs are unsupported, and customer concentration is not yet supplied. DealState keeps those issues visible rather than smoothing them into a confident paragraph.
flowchart LR
A[Files, emails, CRM and notes] --> B[Source ledger]
B --> C[Typed facts and inferences]
C --> D[Current investment state]
D --> E[Conflicts, gaps and review actions]
E --> F[Outputs and team questions]
F --> D
+-------------------+ +-------------------+ +-------------------+
| Source material | ---> | State engine | ---> | Deal room UI |
| decks, models, | | facts, conflicts, | | metrics, issues, |
| notes, CRM | | coverage, scores | | outputs, chat |
+-------------------+ +-------------------+ +-------------------+
| | |
v v v
data/*.yaml lib/state-engine.ts app/opportunities/*
content/demo/* lib/scoring.ts components/*
The product model is simple: make the durable object the state of the deal, not the latest uploaded file and not the latest chat answer.
Project Nova is arranged as a three-column workspace.
+----------------------+ +--------------------------------------+ +----------------------+
| Workspace rail | | Current investment state | | Review rail |
| | | | | |
| Overview | | Recommendation and confidence | | Latest changes |
| Metrics | | Key metrics with provenance | | Manager chat |
| Claims | | Claims ledger | | Document checklist |
| Materials | | Open issues | | Missing requests |
| Issues | | Nine-dimension scorecard | | Generated outputs |
| Questions | | Suggested next actions | | Contacts |
| Outputs | | | | |
+----------------------+ +--------------------------------------+ +----------------------+
That structure is meant for the repeated, slightly messy workflow of private-market diligence: catch up, inspect what changed, check evidence, decide what to ask for next, and reuse the current state in a memo or briefing.
Scores are directional, not decorative. Higher is more favourable. Risk dimensions therefore score mitigation, not exposure.
ICP fit 84 | #################...
Market attractiveness 72 | ##############......
Competition risk 63 | #############.......
Leadership risk 60 | ############........
Revenue quality 58 | ############........
Retention quality 55 | ###########.........
Diligence confidence 50 | ##########..........
AI disruption risk 46 | #########...........
Data completeness 40 | ########............
The overall Project Nova score is 61, computed from weighted firm dimensions in data/scores.yaml by lib/scoring.ts.
DealState is built around a few non-negotiables:
| Rule | How the app shows it |
|---|---|
| Sources are preserved | Every material metric carries a citation, inference marker or unsupported state |
| Conflicts stay visible | Conflicting values are shown as conflicts until reconciled |
| Missing material is state | Absent artefacts become open requests, not private analyst memory |
| Chat is not the source of truth | Chat answers are deterministic in pass 1 and cite the same state ledger |
| Synthetic means synthetic | The demo makes no claim about a real company, market or transaction |
The visual system uses an archival paper tone: calm, source-backed and closer to an investment casebook than a generic SaaS dashboard.
flowchart TB
subgraph UI[Next.js App Router]
Home[Landing page]
Pipeline[Opportunities list]
DealRoom[Project Nova deal room]
Method[Methodology]
end
subgraph Domain[Domain logic]
Repo[Opportunity repository]
State[State engine]
Score[Scoring engine]
Chat[Deterministic chat responses]
end
subgraph Data[Data layer]
Seed[YAML seed files]
Content[Markdown demo outputs]
SQL[Supabase schema]
end
Seed --> Repo
Content --> Repo
Repo --> State
Repo --> Score
Repo --> Chat
State --> DealRoom
Score --> DealRoom
Chat --> DealRoom
SQL -. optional next step .-> Repo
Current default: USE_SUPABASE=false, which serves validated YAML through SeedRepository.
Optional path: Supabase tables and RLS are scaffolded in supabase/migrations/20260621190524_init.sql, but full aggregate hydration in SupabaseRepository remains a pass-1 next step.
Pass 2 adds the real data-plane foundations behind the same UI contract. The dashboard still reads through OpportunityRepository, so seed mode and the public Project Nova demo remain stable.
| Stage | Current implementation |
|---|---|
| Tenancy | Firm, fund, deal and membership schemas plus a deny-by-default RLS migration in supabase/migrations/20260630090000_pass2_foundations.sql |
| Ingestion | SourceAdapter, in-memory ingestion runner, content-hash dedupe, supersession marking and Gmail OAuth stub in lib/ingest/ |
| Parsing | Deterministic segment parser with stable email, CSV and spreadsheet-text locators in lib/parse/ |
| Extraction | Citation verification and candidate materialisation into existing Fact records in lib/citations.ts and lib/extract/ |
| Retrieval | RLS-aware hybrid retrieval fusion helper in lib/retrieve/ |
| Grounding | Grounded answer validation with abstention on missing evidence in lib/generate/ |
| Evals | Offline Project Nova fixtures, gold labels and npm run eval under evals/ and scripts/eval.ts |
The live Gmail connector, hosted Supabase branch database, live model transport and preview deployment require account credentials. Until those exist, the public demo stays on the synthetic tenant and the live-only code paths fail closed with TODO(pass2): markers.
| Path | Purpose |
|---|---|
app/ |
Next.js routes, metadata, sitemap and robots |
components/ |
Landing, navigation, deal room, chart and shared UI components |
data/ |
Synthetic Project Nova state, documents, facts, issues, scores, events and contacts |
content/demo/project-nova/ |
Generated Markdown outputs shown in the product |
lib/state-engine.ts |
Current state, source coverage and change derivation |
lib/scoring.ts |
Weighted deal score calculation |
lib/repo/ |
Seed and optional Supabase repository boundary |
scripts/ |
YAML validation and copy linting |
docs/archive/dark-dealstate-aesthetic/ |
Archived pre-overhaul dusk aesthetic, screenshots and restoration notes |
public/graphics/ |
Source-to-state SVG graphics used by the Humanist Compute Atelier surface |
BUILD-REPORT.md |
Last full implementation and deployment report |
Prerequisites:
- Node.js 22 or later
- npm
gitleaksif you are using the repo hooks
npm cicp .env.example .env.localnpm run devOpen:
http://localhost:3000/opportunities/project-nova
Seed mode needs no external service. To point the app at Supabase later, apply the migration, seed equivalent rows, set the public Supabase URL and publishable key, and set USE_SUPABASE=true.
The normal quality gate is:
npm run validateThat runs:
validate-data -> lint:copy -> typecheck -> lint -> test
For a production build:
npm run buildFor the deterministic pass-2 eval:
npm run evalThe last recorded full release check is in BUILD-REPORT.md. It covers validation, tests, static generation, route smoke checks, desktop and mobile browser QA, Lighthouse checks, Vercel deployment, remote HTTP smoke checks and log inspection.
The public demo currently runs on Vercel:
https://dealstate-zeta.vercel.app
Useful production routes:
/
/opportunities
/opportunities/project-nova
/methodology
/opportunities/project-nova/outputs/onboarding-brief
Everything in Project Nova is synthetic and centralised under data/ and content/demo/. The repo currently demonstrates product shape, state discipline and UI integrity. It does not yet run live ingestion, retrieval, model calls or real customer data.
The next high-value steps are:
- Implement full Supabase aggregate hydration.
- Add real ingestion adapters for files, email and CRM records.
- Replace deterministic chat with structured, cited model outputs.
- Add evaluation fixtures for extraction, conflict detection and answer grounding.
- Add row-level permission boundaries for firm, fund, deal and user scopes.
Most deal tools make teams choose between static files, fragile trackers and chat answers that are hard to audit. DealState takes the other route: keep the source ledger, derive the investment state, expose the gaps, and make the current view easy to inspect.
That is the wedge: one live state for every deal.