Files
momentum-system/storage/experiments_schema.sql
T
momentum devandClaude Fable 5 e624352328 experiment-os: schema DDL (experiments/runs/verdicts tables)
Plan 006 step 1. Idempotent, applied by the harness on first run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 23:37:27 -04:00

47 lines
2.6 KiB
SQL

-- Experiment OS schema (plan 006) — pre-registered, auto-adjudicated
-- counterfactual experiments over logged fires.
--
-- Applied by research/experiments/registry.apply_schema on first run (same
-- idiom as pg_schema.sql; also handed to the owner to run manually if preferred).
-- Idempotent: safe to run repeatedly (CREATE ... IF NOT EXISTS throughout).
-- An experiment is a pre-registered, immutable contract. Rows are never
-- updated after registration except status/verdict fields.
CREATE TABLE IF NOT EXISTS experiments (
id TEXT PRIMARY KEY, -- slug, e.g. 'time_stop_10m_v1'
registered_at TIMESTAMP NOT NULL,
hypothesis TEXT NOT NULL, -- one sentence, human-readable
population JSONB NOT NULL, -- PopulationConfig dump + extra filters
intervention JSONB NOT NULL, -- typed params, e.g. {"kind":"time_stop","minutes":10,"confirm":"new_high_or_0.5R"}
bars JSONB NOT NULL, -- pre-registered pass/fail criteria, e.g. {"expR_delta_min":0.05,"min_n":300,"p_max":0.05}
futility JSONB, -- early-kill rule, e.g. {"min_n":500,"expR_delta_max":-0.02}
fidelity JSONB NOT NULL, -- slippage floors: {"atr_frac":0.25,"spread_mult":3,"adverse_ticks":1}
status TEXT NOT NULL DEFAULT 'running', -- running|passed|failed|inconclusive|killed
verdict_at TIMESTAMP,
verdict_note TEXT
);
-- One row per (experiment, replayed fire): the counterfactual outcome.
CREATE TABLE IF NOT EXISTS experiment_runs (
experiment_id TEXT NOT NULL REFERENCES experiments(id),
fire_id TEXT NOT NULL, -- order_id / receipt correlation id
symbol TEXT NOT NULL,
session_date DATE NOT NULL,
baseline_r DOUBLE PRECISION, -- what actually happened (R units)
variant_r DOUBLE PRECISION, -- counterfactual outcome (R units)
detail JSONB, -- entry/exit stamps, fills, floor hits
computed_at TIMESTAMP NOT NULL,
PRIMARY KEY (experiment_id, fire_id)
);
CREATE INDEX IF NOT EXISTS idx_exp_runs_exp_date ON experiment_runs (experiment_id, session_date);
-- Verdict history (append-only; the dashboard ledger reads this).
CREATE TABLE IF NOT EXISTS experiment_verdicts (
experiment_id TEXT NOT NULL REFERENCES experiments(id),
as_of TIMESTAMP NOT NULL,
n INTEGER NOT NULL,
metrics JSONB NOT NULL, -- observed values vs each bar
verdict TEXT NOT NULL, -- PASS|FAIL|INCONCLUSIVE|KILLED
PRIMARY KEY (experiment_id, as_of)
);