diff --git a/db/README.md b/db/README.md new file mode 100644 index 00000000..0ecf20fb --- /dev/null +++ b/db/README.md @@ -0,0 +1,77 @@ +# db/ — Neon PostgreSQL Migrations & Seeds + +## Structure + +``` +db/ + migrations/ + 001_create_experiment_queue.sql — DDL: experiment_queue table + indexes + 002_experiment_queue_trigger.sql — auto-update updated_at trigger + seeds/ + wave_gf001_phase0_baseline.sql — Phase 0: fp32 IEEE baseline (1 row) + wave_gf001_phase1_phi_lr.sql — Phase 1: phi-LR ladder Quick-3 (18 rows) +``` + +## Apply to Neon + +```bash +# 1. Set connection string +export DATABASE_URL="postgres://..." + +# 2. Run migrations (order matters) +psql $DATABASE_URL -f db/migrations/001_create_experiment_queue.sql +psql $DATABASE_URL -f db/migrations/002_experiment_queue_trigger.sql + +# 3. Seed +psql $DATABASE_URL -f db/seeds/wave_gf001_phase0_baseline.sql +psql $DATABASE_URL -f db/seeds/wave_gf001_phase1_phi_lr.sql +``` + +## experiment_queue schema + +| Column | Type | Notes | +|-------------|-----------------|------------------------------------------------| +| id | SERIAL PK | Auto-increment | +| canon_name | TEXT UNIQUE | e.g. `WAVE-GF-001-P1-k0-s34` | +| phase | SMALLINT | 0=Baseline 1=phi-LR 2=Opt 3=Arch 4=Dtype 5=Hybrid | +| status | TEXT | pending / running / done / failed / skip | +| priority | SMALLINT | 1=highest … 9=lowest | +| seed | INTEGER | phi-series: 34, 55, 89, 144, 233… | +| lr | DOUBLE PRECISION| Learning rate (phi-ladder: alpha_phi·φ^(-k/2)) | +| optimizer | TEXT | adamw / lion / sgdm | +| d_model | INTEGER | 128 / 192 / 256 / 384 / 512 / 618 | +| dtype | TEXT | fp32 / gf16 / bf16 / fp16 / gf32 | +| config_json | JSONB | Full run config | +| result_json | JSONB | Populated after run completes | +| error_msg | TEXT | Populated on failure | +| created_at | TIMESTAMPTZ | Auto | +| updated_at | TIMESTAMPTZ | Auto via trigger (002) | + +## Useful queries + +```sql +-- Dequeue next pending job (worker-safe) +SELECT * FROM experiment_queue +WHERE status = 'pending' +ORDER BY priority, id +LIMIT 1 +FOR UPDATE SKIP LOCKED; + +-- Mark as running +UPDATE experiment_queue SET status='running' WHERE canon_name='WAVE-GF-001-P1-k0-s34'; + +-- Save result +UPDATE experiment_queue +SET status='done', result_json='{"val_loss":2.341,"step":27000}' +WHERE canon_name='WAVE-GF-001-P1-k0-s34'; + +-- Phase 1 leaderboard +SELECT canon_name, seed, lr, status, + result_json->>'val_loss' AS val_loss +FROM experiment_queue +WHERE phase = 1 +ORDER BY (result_json->>'val_loss')::float NULLS LAST; +``` + +--- +*Generated: 2026-05-02 | WAVE-GF-001 | phi² + phi⁻² = 3 · TRINITY* diff --git a/db/migrations/001_create_experiment_queue.sql b/db/migrations/001_create_experiment_queue.sql new file mode 100644 index 00000000..06a6f3ec --- /dev/null +++ b/db/migrations/001_create_experiment_queue.sql @@ -0,0 +1,34 @@ +-- ============================================================ +-- Migration 001: experiment_queue table +-- Project : t27 / GoldenFloat Family — WAVE-GF-001 +-- Date : 2026-05-02 +-- Engine : Neon (PostgreSQL) +-- ============================================================ + +CREATE TABLE IF NOT EXISTS experiment_queue ( + id SERIAL PRIMARY KEY, + canon_name TEXT NOT NULL UNIQUE, -- e.g. "WAVE-GF-001-P1-k0-s34" + phase SMALLINT NOT NULL, -- 0=Baseline 1=phi-LR 2=Opt 3=Arch 4=Dtype 5=Hybrid + status TEXT NOT NULL DEFAULT 'pending' + CHECK (status IN ('pending','running','done','failed','skip')), + priority SMALLINT NOT NULL DEFAULT 5, -- 1=highest … 9=lowest + seed INTEGER, + lr DOUBLE PRECISION, + optimizer TEXT, + d_model INTEGER, + dtype TEXT, + config_json JSONB, + result_json JSONB, + error_msg TEXT, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE INDEX IF NOT EXISTS idx_eq_status_priority + ON experiment_queue (status, priority); + +CREATE INDEX IF NOT EXISTS idx_eq_phase + ON experiment_queue (phase); + +COMMENT ON TABLE experiment_queue IS + 'GoldenFloat WAVE-GF-001 experiment queue — phi-seeded training runs'; diff --git a/db/migrations/002_experiment_queue_trigger.sql b/db/migrations/002_experiment_queue_trigger.sql new file mode 100644 index 00000000..2e99c85c --- /dev/null +++ b/db/migrations/002_experiment_queue_trigger.sql @@ -0,0 +1,18 @@ +-- ============================================================ +-- Migration 002: auto-update updated_at on experiment_queue +-- ============================================================ + +CREATE OR REPLACE FUNCTION set_updated_at() +RETURNS TRIGGER AS $$ +BEGIN + NEW.updated_at = NOW(); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS trg_experiment_queue_updated_at + ON experiment_queue; + +CREATE TRIGGER trg_experiment_queue_updated_at + BEFORE UPDATE ON experiment_queue + FOR EACH ROW EXECUTE FUNCTION set_updated_at(); diff --git a/db/seeds/wave_gf001_phase0_baseline.sql b/db/seeds/wave_gf001_phase0_baseline.sql new file mode 100644 index 00000000..1c36e24d --- /dev/null +++ b/db/seeds/wave_gf001_phase0_baseline.sql @@ -0,0 +1,9 @@ +-- ============================================================ +-- Seed: Phase 0 — Baseline (fp32 IEEE, seed=42, AdamW lr=1e-3) +-- ============================================================ +INSERT INTO experiment_queue + (canon_name, phase, priority, seed, lr, optimizer, d_model, dtype, config_json) +VALUES + ('WAVE-GF-001-P0-baseline-fp32', + 0, 1, 42, 1e-3, 'adamw', 256, 'fp32', + '{"desc":"IEEE fp32 baseline, AdamW lr=1e-3, seed=42, d=256","batch":64,"steps":27000}'); diff --git a/db/seeds/wave_gf001_phase1_phi_lr.sql b/db/seeds/wave_gf001_phase1_phi_lr.sql new file mode 100644 index 00000000..8f78cf04 --- /dev/null +++ b/db/seeds/wave_gf001_phase1_phi_lr.sql @@ -0,0 +1,60 @@ +-- ============================================================ +-- Seed: Phase 1 — phi-LR ladder (Quick-3 seeds × k=0..5) +-- alpha_phi = 6.18e-4, lr(k) = alpha_phi * phi^(-k/2) +-- phi = 1.6180339887 +-- seeds Quick-3: {34, 55, 89} (Fibonacci) +-- ============================================================ + +-- k=0 lr ≈ 6.180e-4 +INSERT INTO experiment_queue (canon_name, phase, priority, seed, lr, optimizer, d_model, dtype, config_json) VALUES + ('WAVE-GF-001-P1-k0-s34', 1, 2, 34, 6.180e-4, 'adamw', 256, 'gf16', + '{"k":0,"phi_lr_k":0,"seed":34,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=0"}'), + ('WAVE-GF-001-P1-k0-s55', 1, 2, 55, 6.180e-4, 'adamw', 256, 'gf16', + '{"k":0,"phi_lr_k":0,"seed":55,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=0"}'), + ('WAVE-GF-001-P1-k0-s89', 1, 2, 89, 6.180e-4, 'adamw', 256, 'gf16', + '{"k":0,"phi_lr_k":0,"seed":89,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=0"}'); + +-- k=1 lr ≈ 4.854e-4 +INSERT INTO experiment_queue (canon_name, phase, priority, seed, lr, optimizer, d_model, dtype, config_json) VALUES + ('WAVE-GF-001-P1-k1-s34', 1, 2, 34, 4.854e-4, 'adamw', 256, 'gf16', + '{"k":1,"phi_lr_k":1,"seed":34,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=1"}'), + ('WAVE-GF-001-P1-k1-s55', 1, 2, 55, 4.854e-4, 'adamw', 256, 'gf16', + '{"k":1,"phi_lr_k":1,"seed":55,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=1"}'), + ('WAVE-GF-001-P1-k1-s89', 1, 2, 89, 4.854e-4, 'adamw', 256, 'gf16', + '{"k":1,"phi_lr_k":1,"seed":89,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=1"}'); + +-- k=2 lr ≈ 3.814e-4 +INSERT INTO experiment_queue (canon_name, phase, priority, seed, lr, optimizer, d_model, dtype, config_json) VALUES + ('WAVE-GF-001-P1-k2-s34', 1, 3, 34, 3.814e-4, 'adamw', 256, 'gf16', + '{"k":2,"phi_lr_k":2,"seed":34,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=2"}'), + ('WAVE-GF-001-P1-k2-s55', 1, 3, 55, 3.814e-4, 'adamw', 256, 'gf16', + '{"k":2,"phi_lr_k":2,"seed":55,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=2"}'), + ('WAVE-GF-001-P1-k2-s89', 1, 3, 89, 3.814e-4, 'adamw', 256, 'gf16', + '{"k":2,"phi_lr_k":2,"seed":89,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=2"}'); + +-- k=3 lr ≈ 2.998e-4 +INSERT INTO experiment_queue (canon_name, phase, priority, seed, lr, optimizer, d_model, dtype, config_json) VALUES + ('WAVE-GF-001-P1-k3-s34', 1, 3, 34, 2.998e-4, 'adamw', 256, 'gf16', + '{"k":3,"phi_lr_k":3,"seed":34,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=3"}'), + ('WAVE-GF-001-P1-k3-s55', 1, 3, 55, 2.998e-4, 'adamw', 256, 'gf16', + '{"k":3,"phi_lr_k":3,"seed":55,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=3"}'), + ('WAVE-GF-001-P1-k3-s89', 1, 3, 89, 2.998e-4, 'adamw', 256, 'gf16', + '{"k":3,"phi_lr_k":3,"seed":89,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=3"}'); + +-- k=4 lr ≈ 2.356e-4 +INSERT INTO experiment_queue (canon_name, phase, priority, seed, lr, optimizer, d_model, dtype, config_json) VALUES + ('WAVE-GF-001-P1-k4-s34', 1, 4, 34, 2.356e-4, 'adamw', 256, 'gf16', + '{"k":4,"phi_lr_k":4,"seed":34,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=4"}'), + ('WAVE-GF-001-P1-k4-s55', 1, 4, 55, 2.356e-4, 'adamw', 256, 'gf16', + '{"k":4,"phi_lr_k":4,"seed":55,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=4"}'), + ('WAVE-GF-001-P1-k4-s89', 1, 4, 89, 2.356e-4, 'adamw', 256, 'gf16', + '{"k":4,"phi_lr_k":4,"seed":89,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=4"}'); + +-- k=5 lr ≈ 1.851e-4 +INSERT INTO experiment_queue (canon_name, phase, priority, seed, lr, optimizer, d_model, dtype, config_json) VALUES + ('WAVE-GF-001-P1-k5-s34', 1, 4, 34, 1.851e-4, 'adamw', 256, 'gf16', + '{"k":5,"phi_lr_k":5,"seed":34,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=5"}'), + ('WAVE-GF-001-P1-k5-s55', 1, 4, 55, 1.851e-4, 'adamw', 256, 'gf16', + '{"k":5,"phi_lr_k":5,"seed":55,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=5"}'), + ('WAVE-GF-001-P1-k5-s89', 1, 4, 89, 1.851e-4, 'adamw', 256, 'gf16', + '{"k":5,"phi_lr_k":5,"seed":89,"d":256,"batch":64,"steps":27000,"notes":"Quick-3 k=5"}');