Viewing files at commit 62758990fe31Commit detailsView latest

Browse files
cloudflare/schema_v2.sql 144 lines · 5.4 KB · sql
1
-- Oak benchmark dashboard schema v2 (ADDITIVE migration over schema.sql).
2
--
3
-- Apply after schema.sql. Only ALTER TABLE ... ADD COLUMN and new tables /
4
-- indexes: nothing existing is renamed, retyped, or dropped, so replaying R2
5
-- raw objects against either schema version stays valid.
6
7
PRAGMA foreign_keys = ON;
8
9
-- Runner identity (ADR-0007) and lane context on measurements. Null means
10
-- the producing lane did not record the signal (ADR-0002), never 0/''.
11
ALTER TABLE measurements ADD COLUMN runner_id TEXT;
12
ALTER TABLE measurements ADD COLUMN runner_class TEXT;
13
ALTER TABLE measurements ADD COLUMN load_tier TEXT;
14
ALTER TABLE measurements ADD COLUMN netshape_profile TEXT;
15
16
-- p95 sits between the existing p90/p99 columns; nearest-rank like the rest.
17
ALTER TABLE aggregates ADD COLUMN p95_ms REAL;
18
19
-- Subject identity (review fix): identity is the deterministic subject_id,
20
-- a stable hash of (run_key, effective subject, subject_kind, binary_sha256)
21
-- computed at ingest. Two different binary_sha256 values for the same subject
22
-- name in one run are two distinct subject records; `name` stays the plain
23
-- subject string and is no longer an identity. The ingest upsert keys
24
-- ON CONFLICT(subject_id), so this explicit unique index names the conflict
25
-- target (it mirrors the PRIMARY KEY; redundant on disk, additive and
26
-- self-documenting).
27
--
28
-- Supersession note: schema.sql originally declared an inline
29
-- UNIQUE (run_key, name) on subjects. SQLite cannot drop an inline table
30
-- constraint via ALTER TABLE, so no additive migration statement can remove
31
-- it from already-created databases. Resolution, additive-only:
32
--   * schema.sql's CREATE TABLE (which only runs on fresh databases, via
33
--     IF NOT EXISTS) no longer carries the inline UNIQUE — fresh/rebuilt
34
--     databases accept multiple shas per name;
35
--   * databases created before this revision still carry the old inline
36
--     constraint and will reject a second sha for one name; they are
37
--     rebuildable by replaying R2 raw objects (the schema.sql header
38
--     documents R2 as the source of truth), which sheds the constraint;
39
--   * measurements, aggregates, and comparisons all reference subjects by
40
--     subject_id (foreign keys + dashboard_comparisons view joins), so
41
--     nothing else changes.
42
CREATE UNIQUE INDEX IF NOT EXISTS idx_subjects_subject_id
43
  ON subjects (subject_id);
44
45
-- Non-unique lookup index replacing the implicit index the old inline
46
-- UNIQUE (run_key, name) provided on fresh databases.
47
CREATE INDEX IF NOT EXISTS idx_subjects_run_name
48
  ON subjects (run_key, name);
49
50
-- Committed Git Baseline Books (ADR-0006): compact JSON summaries served by
51
-- GET /api/baseline-book/:id. book_json is oakbench.baseline_book.book_json
52
-- output; manifest_json is the provenance manifest.
53
CREATE TABLE IF NOT EXISTS baseline_books (
54
  book_id TEXT PRIMARY KEY,
55
  runner_class TEXT,
56
  manifest_json TEXT,
57
  book_json TEXT NOT NULL,
58
  created_utc TEXT NOT NULL
59
);
60
61
CREATE INDEX IF NOT EXISTS idx_baseline_books_runner_class
62
  ON baseline_books (runner_class, created_utc DESC);
63
64
-- Repro-bundle verification results served by GET /api/verifications.
65
CREATE TABLE IF NOT EXISTS verifications (
66
  id INTEGER PRIMARY KEY AUTOINCREMENT,
67
  bundle_sha256 TEXT NOT NULL,
68
  verdict TEXT NOT NULL,
69
  detail_json TEXT,
70
  created_utc TEXT NOT NULL
71
);
72
73
CREATE INDEX IF NOT EXISTS idx_verifications_bundle
74
  ON verifications (bundle_sha256, created_utc DESC);
75
76
-- Stored target scorecards (oakbench.scorecard.evaluate_targets output);
77
-- GET /api/scorecard returns the most recent row.
78
CREATE TABLE IF NOT EXISTS scorecards (
79
  id INTEGER PRIMARY KEY AUTOINCREMENT,
80
  bench_id TEXT,
81
  profile TEXT,
82
  scorecard_json TEXT NOT NULL,
83
  created_utc TEXT NOT NULL
84
);
85
86
CREATE INDEX IF NOT EXISTS idx_scorecards_created
87
  ON scorecards (created_utc DESC);
88
89
-- HMAC-verified GitHub webhook deliveries (POST /webhook/github).
90
CREATE TABLE IF NOT EXISTS webhook_events (
91
  id INTEGER PRIMARY KEY AUTOINCREMENT,
92
  event TEXT,
93
  delivery_id TEXT,
94
  payload_json TEXT,
95
  signature_valid INTEGER NOT NULL DEFAULT 0,
96
  created_utc TEXT NOT NULL
97
);
98
99
CREATE INDEX IF NOT EXISTS idx_webhook_events_created
100
  ON webhook_events (created_utc DESC);
101
102
-- Which dimensions breached for a regression verdict (review fix): JSON
103
-- array string like '["p90"]'; null/'[]' when no breach. Without this the
104
-- computed regression_dimensions field died at ingest and readers could not
105
-- tell a p50 breach from a p90 breach.
106
ALTER TABLE comparisons ADD COLUMN regression_dimensions TEXT;
107
108
-- Refresh the readback view to expose the new column (views carry no data;
109
-- drop+recreate is a definition refresh, not a destructive migration).
110
DROP VIEW IF EXISTS dashboard_comparisons;
111
CREATE VIEW dashboard_comparisons AS
112
SELECT
113
  c.comparison_id,
114
  c.run_key,
115
  r.bench_id,
116
  r.timestamp_utc,
117
  r.profile,
118
  r.host_id,
119
  target.name AS target_subject,
120
  baseline.name AS baseline_subject,
121
  c.baseline_kind,
122
  c.scenario,
123
  c.operation,
124
  c.p50_delta_ms,
125
  c.p50_slower_pct,
126
  c.p90_delta_ms,
127
  c.p90_slower_pct,
128
  c.p99_delta_ms,
129
  c.p99_slower_pct,
130
  c.avg_token_delta,
131
  c.token_higher_pct,
132
  c.avg_output_byte_delta,
133
  c.output_byte_higher_pct,
134
  c.avg_tool_call_delta,
135
  c.tool_call_higher_pct,
136
  c.failure_rate_delta_pp,
137
  c.state,
138
  c.is_regression,
139
  c.regression_dimensions,
140
  c.severity_score
141
FROM comparisons c
142
JOIN benchmark_runs r ON r.run_key = c.run_key
143
JOIN subjects target ON target.subject_id = c.target_subject_id
144
JOIN subjects baseline ON baseline.subject_id = c.baseline_subject_id;