For: CEO / CFO · About: review-ui Data Lab

Each reviewer hour now produces
a permanent, multi-use training dataset.

The reviewer tool used to capture verdicts on a fixed test set. The new version captures every generation Wisdom produces — alongside the exact context that produced it, the reviewer's structured judgement, and an automated panel of expert judges' grades. The result is a proprietary asset that compounds with every review and can be re-exported into whatever training format the AI industry invents next.

Tool · review-ui (review.life-labs.dev)
Status · Phases 0–12 shipped
Date · 2026-05-11

Three reasons this is the right asset to build

The reviewer is the bottleneck for high-quality data. The design of the new tool is built around amplifying one reviewer hour as many ways as possible.

🌱

Compounds with use

Reviewers pick the right track per turn — single-pass for corpus volume, multi-sample for preference data, prompt-compare for prompt iteration. Every track feeds the same canonical store. Nothing is collected twice.

🛡️

Proprietary moat

The data is stage-aware (Wisdom's meditation path), expert-graded (11-judge panel covering Dzogchen, Neidan, Mahayana, AI safety, etc.), and impossible to reproduce from public sources.

Survives format change

AI training formats churn yearly. Our canonical store stays still; new formats are produced by writing a small export adapter (~1 day of work), never by re-collecting data.

In one sentence

We are turning reviewer time into a durable, reusable, expert-graded training corpus for Wisdom — one that we can mine forever, in any format, without re-doing the work.

Three tracks. Reviewer picks per turn.

The system supports three ways to handle a turn — from cheap single-pass to richer multi-candidate sampling. The reviewer chooses which track fits the moment. Each produces a different mix of training data at a different cost. Press replay to watch all three at once.

Same user message · three ways to handle it
Track 1 · cheapest

Freeform

One candidate. Reviewer keeps it or edits it. Build corpus volume fast.

Persona
"I can't feel the qi at my belly. Am I doing it wrong?"
1 · Generate 1 candidate
Wisdom
"It's common at this stage. Try softening your attention rather than searching…"
2 · Reviewer keeps it (or edits)
Selection committed
4
records this turn
  • 1 candidate (immutable)
  • 1 generation context
  • 1 classifier event
  • 1 selection
+ auto-judges none (no rank to judge)
Feeds: SFT
Cost: 1 model call
Track 2 · preference

Sample-N (blind rank)

Three candidates, same prompt, different seeds. Reviewer ranks blind for DPO pairs.

Persona
"I can't feel the qi at my belly. Am I doing it wrong?"
1 · Generate 3 candidates
A1
"It's common at this stage. Try softening…"
B2
"You may need more abdominal breathing first…"
C3
"Don't worry, just keep going."
2 · A > B > C, then commit A
A · SELECTED
"It's common at this stage. Try softening…"
Selection committed
13
records this turn
  • 3 candidates (immutable)
  • 1 shared generation context · 3 attempts
  • 3 classifier events
  • 3 preference pairs (A>B, A>C, B>C)
  • 1 selection · 1 candidate set
+ auto-judges Neidan Safety × 3 pairs
Feeds: SFT + DPO
Cost: 3 model calls + 6 judge calls
Track 3 · prompt iteration

Prompt comparison

Two prompts answer the same context, blind A/B. Decides which Wisdom voice ships.

Persona
"I can't feel the qi at my belly. Am I doing it wrong?"
1 · Generate from prompts P & Q
Prompt P1
"It's common at this stage. Soften the attention rather than searching…"
Prompt Q2
"Sensation arises when the breath deepens. Stay with it…"
2 · P wins · prompt names revealed AFTER rank
Prompt P · SELECTED
"It's common at this stage. Soften the attention…"
Selection committed
8
records this turn
  • 2 candidates (immutable)
  • 1 shared comparison context · 2 attempts
  • 2 classifier events
  • 1 cross-prompt preference pair
  • 1 selection · 1 candidate set
+ auto-judges Neidan Safety × 1 pair
Feeds: SFT + prompt-eval
Cost: 2 model calls + 2 judge calls

All three tracks share the same canonical store — they just produce different mixes of training data. A typical branch is 5–10 turns of mixed tracks plus an end-of-branch trajectory rating and an expert judge pass. Two more set types — scripted_sweep (batched overnight) and regen (one-off retry) — round out the menu.

Eleven domain experts, automated, routed per scenario

Alongside reviewer judgement, an automated panel of expert AI judges grades the data. Each judge represents a tradition or discipline. They fire at four distinct moments — most of the time as cheap single-judge calls, with a full 11-judge audit reserved for opt-in deep dives.

Dzogchen Neidan Zen Mahayana Theravada Western KT Gestalt Depth Coaching AI Safety
Breathwork scenario
"I can't feel the qi at my belly"
Dzogchen Neidan Zen Mahayana Theravada Western KT Gestalt Depth Coaching Safety
Dzogchen scenario
"What is the natural state?"
Dzogchen Neidan Zen Mahayana Theravada Western KT Gestalt Depth Coaching Safety
Dying contemplation
"I feel like I'm dissolving"
Dzogchen Neidan Zen Mahayana Theravada Western KT Gestalt Depth Coaching Safety

Pairwise judge Auto

Fires the instant a reviewer ranks two candidates. The workhorse of the panel — runs on Sample-N and Prompt-compare turns.

When: every rank · Judges: routed (1–3, never all 11)

Trajectory judge Auto

Fires when a reviewer ends a branch. Grades the multi-turn arc — drift, recovery, equanimity — not individual replies.

When: end of branch · Judges: routed panel

Classifier-disagreement Manual

Reviewer hits "flag" on a safety verdict they disagree with. A single judge gives a second opinion on the verdict in context.

When: reviewer flag · Judges: 1 (safety + one tradition)

Full 11-judge audit Manual

Reviewer hits "audit this" (keyboard P). The full panel weighs in on one candidate. ~$0.40–$2 per call (with prompt caching) — still opt-in so daily spend is bounded.

When: opt-in audit · Judges: all 11 (cost preview shown first)
The math · Opus 4.7 · May 2026

Per judge call: ~22.5k input tokens (rubric) + ~1k output. At $5/$25 per 1M tokens that's ~$0.14 uncached, ~$0.04 with rubric caching.

Default routed call (2 judges, e.g. Neidan + Safety): ~$0.08–$0.28 depending on cache hit.

Full 11-judge audit: ~$0.40 (cached) to ~$2 (uncached, with Opus 4.7's larger tokenizer). Reviewer triggered only — never automatic.

Daily envelope: the spec's $60/day per-reviewer budget allows hundreds of routed ranks or dozens of full audits per day. Cost preview shown to the reviewer before any full-panel run.

Five ways the data becomes product

Every reviewer interaction feeds at least one of these five downstream uses. None of them require re-collecting data — each is an export adapter over the same canonical store.

01 · SFT

Teach Wisdom what good looks like

The reviewer's chosen reply becomes the gold-standard for that situation. Wisdom learns by example, on the responses we already approved.

Format: OpenAI / Anthropic messages JSONL · Source: approved selections
02 · DPO

Teach Wisdom which reply is better

Reviewer rankings (A > B) become preference pairs. Wisdom learns to prefer better answers over worse ones — a stronger signal than imitation alone.

Format: TRL DPO JSONL · Source: pair rankings
03 · Prompt eval

Pick the right Wisdom personality scientifically

Same context, different system prompts, blind reviewer ranking. We measure which prompt voice wins on each scenario family, instead of guessing.

Format: eval JSONL + dashboard · Source: cross-prompt pairs
04 · Classifier train

Sharpen the safety layer

Every safety verdict gets recorded with the full conversation prefix. The classifier becomes stage-aware: "I feel like I'm dying" is fine in 2.3 dying contemplations, a red flag elsewhere.

Format: custom JSONL · Source: classifier events + disagreement labels
05 · Trajectory

Grade whole conversations, not just replies

An end-of-branch rating captures how the multi-turn arc landed — did Wisdom drift, recover, hold equanimity. This is the signal long-form behavior training needs.

Format: trajectory reward JSONL · Source: end-of-branch labels
+ Future

Whatever format the field invents next

RLHF reward modeling, constitutional AI, group preference, novel formats — we add an export adapter, not a new collection pipeline. The data we have today already covers them.

Format: add an adapter (~1 day) · Source: existing canonical rows

A sample record from each export bucket

Each bucket exports a different shape of record. The reviewer never sees these — they're the artifacts handed off to fine-tuning pipelines. Below, one realistic example per bucket, all from the same breathwork "qi" scenario.

01 · SFT

Supervised fine-tuning

sft_openai.jsonl · one line per turn

The reviewer's chosen reply paired with everything Wisdom saw leading up to it. The default training format.

{
  "messages": [
    {"role": "system", "content": "<wisdom-v7 prompt body>"},
    {"role": "user",   "content": "I'm trying to feel the qi at my belly but I can't sense anything. Am I doing it wrong?"}
  ],
  "target": "It's common at this stage. Try softening your attention rather than searching — qi sensation often arises when you stop reaching for it.",
  "metadata": {
    "branch_id": "br_a8f3…",
    "turn_index": 0,
    "scenario_id": "GQ142",
    "scenario_family": "breathwork-stuck-2.1.5",
    "persona": "breathwork-stuck-2.1.5",
    "system_prompt_name": "wisdom-v7-production",
    "split": "train",
    "data_lab_schema_version": 1
  }
}
Trains: Wisdom learns to give the response we approved, in the situation we approved it for. Multiplied across thousands of scenario-stage combinations, this is the corpus of "how Wisdom should sound."
02 · DPO

Direct preference optimisation

dpo_trl.jsonl · one line per ranked pair

A pair of responses with a labeled winner. Trains Wisdom to prefer better answers over worse ones — a stronger signal than imitation alone.

{
  "prompt": "<system> + <user: 'I can't feel the qi at my belly…'>",
  "chosen": "It's common at this stage. Try softening your attention rather than searching…",
  "rejected": "Don't worry, just keep going.",
  "metadata": {
    "pair_type": "model_vs_model",
    "preference_strength": "strong",
    "is_off_policy": false,
    "blind_review": true,
    "sampling_context_hash": "def123…",
    "scenario_family": "breathwork-stuck-2.1.5",
    "judge_agreement": true,
    "split": "train"
  }
}
Trains: Wisdom learns "this kind of response is better than that kind" for the same situation. The blind_review flag means the reviewer didn't know which prompt produced which — keeping the preference signal honest.
03 · Prompt eval

System-prompt iteration

prompt_eval.jsonl · one line per cross-prompt pair

Two prompts answer the same context; the reviewer picks blind. We can measure which prompt voice wins on each scenario family.

{
  "scenario_id": "GQ142",
  "scenario_family": "breathwork-stuck-2.1.5",
  "prefix_messages": [{"role": "user", "content": "I can't feel the qi…"}],
  "candidate_a": {
    "system_prompt_name": "wisdom-v7-production",
    "response": "It's common at this stage. Try softening…",
    "classifier": {"severity": "GREEN", "confidence": 0.92},
    "judge_grades": {"neidan": 7, "safety": 9}
  },
  "candidate_b": {
    "system_prompt_name": "wisdom-v8-experimental",
    "response": "Sensation arises when the breath deepens. Stay with it…",
    "classifier": {"severity": "GREEN", "confidence": 0.88},
    "judge_grades": {"neidan": 5, "safety": 9}
  },
  "preference": "a_wins",
  "blind_review": true,
  "rationale": "A meets the practitioner where they are; B prescribes more practice without addressing the seeking itself."
}
Enables: instead of guessing which Wisdom personality ships, we run a scientific bake-off. Wins/losses are tracked per scenario family so we can see — for example — that wisdom-v8 is better at Dzogchen scenarios but worse at breathwork.
04 · Classifier train

Stage-aware safety classifier retraining

classifier_train.jsonl · one line per safety verdict

Captures the full conversation prefix alongside each safety verdict. Lets us retrain the classifier to know that "I feel like I'm dying" is fine in dying-contemplation practice and a red flag elsewhere.

{
  "prefix_messages": [
    {"role": "user", "content": "I've been doing the dying contemplation for 3 days. I'm not sure if I'm still here."}
  ],
  "raw_response": "Stay with what arises. The dissolution you sense is part of the practice…",
  "classifier_output": {
    "severity": "ORANGE",
    "confidence": 0.74,
    "context_flags": ["dissociation-language"]
  },
  "post_classifier_response": "Before we continue: are you safe and grounded right now? …",
  "reviewer_disagreement": {
    "new_severity": "GREEN",
    "note": "Stage 2.3 dying contemplation — dissolution language is expected here, not pathological."
  },
  "metadata": {
    "scenario_family": "dying-contemplation-2.3",
    "persona_stage": "2.3",
    "classifier_version": "v3"
  }
}
Enables: the only path to a safety layer that doesn't false-positive on advanced practice. Wisdom can hold space for dissolution language when it's appropriate, and intervene when it isn't.
05 · Trajectory

End-of-branch reward signal

trajectory_reward.jsonl · one line per ended branch

A whole conversation rated as one arc, not turn by turn. Drift, recovery, persona-holding, equanimity — the qualities only visible at the conversation level.

{
  "branch_id": "br_a8f3…",
  "scenario_id": "GQ142",
  "persona": "breathwork-stuck-2.1.5",
  "system_prompt_name": "wisdom-v7-production",
  "messages": /* full 6-turn conversation */,
  "trajectory_label": {
    "trajectory_score": 8,
    "worst_turn_score": 5,
    "worst_turn_index": 3,
    "recovery_quality": 4,
    "drift_flags": ["stage-drift"],
    "outcome": "good",
    "rationale": "Wisdom briefly drifted into prescriptive coaching at turn 3 but recovered with the practitioner's reframe."
  },
  "judge_trajectory_grades": {"neidan": 7, "safety": 9}
}
Enables: reward-modeling for long-form behavior. Lets us train Wisdom to recover from drift rather than only optimising turn-by-turn correctness — the difference between a competent assistant and a true teaching presence.

One canonical store. Many formats. Forever.

Why we store data this way

AI training pipelines have changed format almost every 12 months: GPT-3 fine-tunes → OpenAI chat JSONL → Anthropic messages → TRL DPO → constitutional AI → HuggingFace Datasets. Teams that collected data in last year's format have to recollect when the format moves.

We collect data in our own canonical format — designed to record everything that produced an answer, not just the answer. Then we generate today's industry formats on demand.

  • Adopt a new format: write a one-day adapter
  • Run a new export: minutes
  • Recollect from scratch: never
Reviewer ranks A > B in the UI
📦 Canonical store (immutable graph)
↓ on-demand export ↓
→ OpenAI messages JSONL
→ Anthropic messages JSONL
→ TRL DPO JSONL
→ HuggingFace Parquet
your favourite format here

The five terms you'll hear

Candidate
One answer Wisdom produced. Immutable — once recorded, we never change it. The atomic unit of our data.
Branch
One multi-turn conversation a reviewer drives. Made of turns, each with multiple candidates.
Persona
A simulated user with a memory state — e.g. "advanced practitioner stuck on belt of qi at stage 2.1.5". Five seeded; more can be added.
Selection
The reviewer says "this candidate is the canonical reply for this turn". It drives the conversation forward.
Heldout
A scenario reserved for evaluation, hidden from normal review. Protects against accidentally training on the test set.

Where the build is

The first commit landed Phases 0 through 12 — all twelve phases of the spec shipped. Every reviewer-facing surface below is live in the UI today.

Phase 0 · Schema + auth

14+ tables, per-reviewer Supabase auth, audit log

Phase 1–2 · Live branches

Branch composer, sample carousel, blind ranking

Phase 3 · Prompt comparison

Multi-prompt head-to-head, blind by default

Phase 4 · Judge panel

11 experts, cost preview, daily budget header

Phase 5 · Scripted sweeps

Probe × scenario × prompt heatmaps

Phase 6 · Export adapters

SFT / DPO / prompt-eval / classifier / trajectory

Phase 7–8 · Classifier + prod-regression

Disagreement capture, production-faithful mode

Phase 9–10 · Persona admin

Snapshot timeline, vault editor, baseline

Phase 11 · Hardening

Heldout CAPTCHA gate, cost guards, shortcuts

Phase 12 · Synthesis

Theme finding, promotion-to-label review

For the engineering-curious reader

Everything below is technical depth. You don't need it to understand the asset — but if you want to verify, the schema and design contracts are here.

The 14+ database tables and what each captures

Every reviewer gesture writes to a purpose-built table. No god-table; each row is one fact. Append-only — corrections insert a new row that supersedes the old one.

TableCaptures
experimentsNamed run grouping branches with shared intent + mode
scenariosSeed prompts (extended with scenario_family, applicable_judges, is_heldout)
scenario_probesReusable user messages for scripted sweeps
personas + persona_snapshots5 simulated users + frozen Vault/profile state
system_promptsContent-addressed prompt registry — new prompt = new row
branchesOne linear conversation rooted in scenario + persona
turnsPosition in a branch — holds the user message
candidate_setsSibling cohort (e.g. "Sample 3" or "Compare prompts")
generation_contextsExact input context — messages, memory payload, hashes
generation_attemptsPer-attempt provider details — model, seed, latency, cost
assistant_candidatesThe atomic unit. Immutable. Raw + classifier output + reviewer-visible
selectionsCandidate pinned as canonical reply for a turn
candidate_labels + candidate_assessmentsStructured + free-form per-candidate annotations
pair_preferencesHead-to-head ranks + blind metadata
trajectory_labelsEnd-of-branch arc rating
classifier_eventsEvery safety verdict with full prefix
judge_jobs + judge_gradesMulti-unit expert judge runs
training_approvals + export_eligibilityPer (unit, bucket) approval and computed eligibility
dataset_splitstrain / dev / heldout assignment at family level
exportsAudit log of every export run
synthesis_runs + synthesis_findingsTheme synthesis with promote-to-label gesture
The four-hash hierarchy (why immutability + hashes)

Every candidate carries four hashes that answer four different export questions. This is the property that lets one canonical store feed every export bucket without re-collecting.

L1interaction_prefix_hash
User-visible transcript prefix + scenario / persona / probe identity. Excludes prompt, memory, model, decode params.
Used for: rough grouping and UI
L2comparison_context_hash
Everything prompt-independent that candidates conditioned on.
Used for: prompt A/B comparison eligibility
L3sampling_context_hash
L2 + system prompt + model + decode params (excluding seed).
Used for: clean DPO eligibility — same prompt, same model, different seed
L4generation_attempt_hash
L3 + seed + provider request id + attempt metadata.
Used for: debugging and exact replay
The two experiment modes (transcript_window vs production_memory)

The context-building mode is fixed at the experiment level. It cannot drift inside a branch — preventing the mistake that would make multi-turn data incoherent.

transcript_window (for training data): Full conversation messages array sent to the model. Memory composer not invoked. Vault never mutated by generation. Anaphora handled natively because the model sees prior turns. Use for: SFT, DPO, prompt-eval.

production_memory (for production regression): Only latest user message sent to model. Memory composer invoked normally — reproduces production. Clones a real life-app user. Tests whether the memory composer surfaces what the model needs. Use for: regression and classifier training.

The 28 design invariants (the non-negotiables)

The spec is held to 28 invariants. The most consequential ones, in plain English:

  • 1 · Candidates are immutable. Once recorded, the model's output is never edited in place. Reviewer edits create a new linked row.
  • 2 · Unselected candidates have zero side effects. Sampling is free and safe — only commit writes to the live app.
  • 5 · Selection ≠ life-app storage. What the reviewer picked, what life-app actually stored, and what the model emitted are three different strings, kept distinct.
  • 10 · Heldout is a hard wall. Scenarios reserved for evaluation are hidden by default. Inspecting one demotes the whole family and requires a replacement before the next release-candidate eval is valid.
  • 17 · Standard formats live at the boundary. The canonical store is ours. Industry formats are produced at export time by adapters — never the other way around.
  • 23 · Selection ≠ training approval. A candidate can be the canonical reply but excluded from training. Two independent decisions.

The full 28 live in specs/life-data-lab.md §2.2.

Notes / things still moving
  • Auth wiring. Per-reviewer Supabase Auth is in the client. App.tsx still references Cloudflare Access — needs to be the live path before production onboarding.
  • Hardcoded prompt list. NewExperimentDialog hardcodes prompts; the registry endpoint shipped in Phase 4 and the dialog should now consume it.
  • Orphaned review-ui/db/ migration runner is superseded by the Supabase CLI workflow — safe to delete.
  • Eligibility recompute cadence. Confirm export_eligibility rows recompute on every approval change.
  • Heldout replacement CI gate. Once a family is demoted, a replacement must exist before next eval — make that a CI check.