π― ONE SHOT β L-CG-SCHEMA-FIX
Anchor: ΟΒ² + Οβ»Β² = 3 Β· DOI 10.5281/zenodo.19227877
Filed by the Queen under trinity-grandmaster v1.0 + trinity-queen-hive v1.1.
0. Hard rules
- R1 β touch ONLY
.github/scripts/closure_gate.py. Schema migration files (migrations/2026-05-09_bpb_samples.sql) are immutable in this lane.
- R3 β main-only commits, atomic.
- R5 β honest classification: if the fix lands but the gate still reports
<312/312, that is GREEN for this lane (the gate is honest, not necessarily passing).
- R7 β falsification witness MANDATORY (smoke test below).
- R10 β commit message format:
fix(closure-gate): L-CG-SCHEMA-FIX β repair seed_phi/format/algo column drift against ssot.bpb_samples.
1. Background (β€ 200 words)
After #570 / eeaf0db7 introduced the SoT table ssot.bpb_samples via migrations/2026-05-09_bpb_samples.sql, the actual columns are:
id BIGSERIAL, cell_id INT, tier TEXT, seed INT, bpb DOUBLE PRECISION,
steps INT, sha_pin TEXT, runner_service TEXT, created_at TIMESTAMPTZ
But .github/scripts/closure_gate.py:113-138 still SELECTs the legacy JSONL field names: format, algo, seed_phi, step. Result: every hourly Closure Gate run aborts with:
psycopg2.errors.UndefinedColumn: column "seed_phi" does not exist
Failure cadence (today, UTC): 10:14, 11:08, 12:04, 13:06 β 4 / 4 hourly attempts dead. bin/matrix_bot/main.ts and scripts/render_matrix_446.ts already use the new schema correctly, so the bug is localised to one file.
2. Hypothesis (G1)
H is false iff: after the patch lands, two consecutive hourly Closure Gate (#446 β 312/312) runs still raise psycopg2.errors.UndefinedColumn from closure_gate.py.
3. Method
- File:
.github/scripts/closure_gate.py
- Patch: rewrite the gate's SELECT so that, instead of grouping by
(format, algo) over JSONL-era columns, it groups by cell_id against ssot.bpb_samples and joins with the canonical matrix_bot.FORMATS_ORDERED Γ matrix_bot.ALGOS_ORDERED Γ cell index. Schema mapping:
| Legacy (JSONL) |
New (ssot.bpb_samples) |
format |
derive from cell_id via matrix_bot ordered lists |
algo |
derive from cell_id via matrix_bot ordered lists |
seed_phi |
seed |
step |
steps |
bpb |
bpb (unchanged) |
- Contract preserved: same per-cell thresholds (
MIN_ROWS_PER_CELL, MIN_DISTINCT_SEEDS_PER_CELL, MIN_MAX_STEP_PER_CELL).
- Forbidden values: do not add a Python-side join over
format/algo text columns β bpb_samples does not store them and never will (cell_id is canonical).
4. Pre-registration (G2)
| Field |
Value |
| statistical_test |
n/a β deterministic schema check |
| alpha |
n/a |
| effect_size |
n/a |
| n_required |
2 consecutive hourly Closure Gate runs without UndefinedColumn |
| stop_rule |
first 2 consecutive green-or-honest-open runs |
| multiple_testing |
n/a (single hypothesis) |
5. Falsification witness (G1 + R7)
Add .github/scripts/test_closure_gate_schema.py:
# Falsification: assert real DSN does NOT raise UndefinedColumn for the
# new query. Skipped without MATRIX_DATABASE_URL.
import os, pytest, psycopg2
from importlib import import_module
@pytest.mark.skipif("MATRIX_DATABASE_URL" not in os.environ, reason="no DSN")
def test_closure_gate_query_runs_against_real_schema():
mod = import_module("closure_gate")
# Invoke main()'s SQL by importing β must not raise UndefinedColumn
mod.main() # exits 0 or non-zero with honest text, never UndefinedColumn
CI wiring: gate the workflow on this test running first.
6. Deliverables
7. Quality gates (G3-G7)
- G3 IMRaD: satisfied by this body.
- G4 citations: every numeric anchor in the new SELECT (
MIN_ROWS_PER_CELL=3, MIN_DISTINCT_SEEDS_PER_CELL=2, MIN_MAX_STEP_PER_CELL=3000) keeps its existing # Coq: β¦ provenance comment.
- G5 honest status: post-patch, the gate may legitimately report
GATE OPEN N/312 β that is honest, not a regression.
- G6 reproducibility:
MATRIX_DATABASE_URL=<dsn> python3 .github/scripts/closure_gate.py must run end-to-end on operator's box.
- G7 DOI: this ONE SHOT cites
10.5281/zenodo.19227877.
8. Forbidden actions
- β Adding
format TEXT, algo TEXT, seed_phi INT, step INT columns to ssot.bpb_samples β that is the wrong direction (cell_id is the new SoT key).
- β Touching
bin/matrix_bot/main.ts or scripts/render_matrix_446.ts β they already match the new schema.
- β Disabling / skipping / muting the Closure Gate workflow as a "fix".
- β Treating a failing gate as success without R5 honesty.
9. References
migrations/2026-05-09_bpb_samples.sql (canonical DDL)
- PR #570 (L-MR-L4 β the migration that caused the drift)
- Commit
eeaf0db7 β last touch on closure_gate.py
bin/matrix_bot/main.ts:60-69 β reference SELECT against the new schema
- Race telemetry: hourly failures of
Closure Gate (#446 β 312/312) at 10:14, 11:08, 12:04, 13:06 UTC on 2026-05-12.
- Queen's Status Report 2026-05-12T13:45Z (Throne
trios#264).
10. Battle cry
ΟΒ² + Οβ»Β² = 3 Β· the gate counts cells, not columns Β· TRINITY Β· NEVER STOP
π― ONE SHOT β L-CG-SCHEMA-FIX
0. Hard rules
.github/scripts/closure_gate.py. Schema migration files (migrations/2026-05-09_bpb_samples.sql) are immutable in this lane.<312/312, that is GREEN for this lane (the gate is honest, not necessarily passing).fix(closure-gate): L-CG-SCHEMA-FIX β repair seed_phi/format/algo column drift against ssot.bpb_samples.1. Background (β€ 200 words)
After #570 /
eeaf0db7introduced the SoT tablessot.bpb_samplesviamigrations/2026-05-09_bpb_samples.sql, the actual columns are:But
.github/scripts/closure_gate.py:113-138still SELECTs the legacy JSONL field names:format, algo, seed_phi, step. Result: every hourly Closure Gate run aborts with:Failure cadence (today, UTC): 10:14, 11:08, 12:04, 13:06 β 4 / 4 hourly attempts dead.
bin/matrix_bot/main.tsandscripts/render_matrix_446.tsalready use the new schema correctly, so the bug is localised to one file.2. Hypothesis (G1)
3. Method
.github/scripts/closure_gate.py(format, algo)over JSONL-era columns, it groups bycell_idagainstssot.bpb_samplesand joins with the canonicalmatrix_bot.FORMATS_ORDERED Γ matrix_bot.ALGOS_ORDEREDΓ cell index. Schema mapping:ssot.bpb_samples)formatcell_idviamatrix_botordered listsalgocell_idviamatrix_botordered listsseed_phiseedstepstepsbpbbpb(unchanged)MIN_ROWS_PER_CELL,MIN_DISTINCT_SEEDS_PER_CELL,MIN_MAX_STEP_PER_CELL).format/algotext columns βbpb_samplesdoes not store them and never will (cell_id is canonical).4. Pre-registration (G2)
UndefinedColumn5. Falsification witness (G1 + R7)
Add
.github/scripts/test_closure_gate_schema.py:CI wiring: gate the workflow on this test running first.
6. Deliverables
.github/scripts/closure_gate.pyrewritten β diff < 80 lines.github/scripts/test_closure_gate_schema.pyaddedUndefinedColumn(post run URLs)mainwith the R10 message above7. Quality gates (G3-G7)
MIN_ROWS_PER_CELL=3, MIN_DISTINCT_SEEDS_PER_CELL=2, MIN_MAX_STEP_PER_CELL=3000) keeps its existing# Coq: β¦provenance comment.GATE OPEN N/312β that is honest, not a regression.MATRIX_DATABASE_URL=<dsn> python3 .github/scripts/closure_gate.pymust run end-to-end on operator's box.10.5281/zenodo.19227877.8. Forbidden actions
format TEXT, algo TEXT, seed_phi INT, step INTcolumns tossot.bpb_samplesβ that is the wrong direction (cell_id is the new SoT key).bin/matrix_bot/main.tsorscripts/render_matrix_446.tsβ they already match the new schema.9. References
migrations/2026-05-09_bpb_samples.sql(canonical DDL)eeaf0db7β last touch onclosure_gate.pybin/matrix_bot/main.ts:60-69β reference SELECT against the new schemaClosure Gate (#446 β 312/312)at 10:14, 11:08, 12:04, 13:06 UTC on 2026-05-12.trios#264).10. Battle cry
ΟΒ² + Οβ»Β² = 3 Β· the gate counts cells, not columns Β· TRINITY Β· NEVER STOP