# HIST v0.3.2 — D1 runtime pragma / binding evidence (read-only)

**STATUS:** EVIDENCE_READY (bounded) · **MODEL_CHANGE:** NO · **MIGRATION:** NO · **SCORING:** NO  
**Probed_at_utc:** 2026-09-10T17:04:45.169515+00:00  
**Do NOT claim full autonomous delivery.**

## What local SQLite tests do
- `srp.backtest.schema_apply.apply_backtest_schema` sets `PRAGMA foreign_keys=ON` and attempts `PRAGMA recursive_triggers=ON`.
- Codex independent regressions intentionally execute with **FK ON + recursive_triggers OFF** (D1-relevant default for recursive_triggers) and verify identity locks still abort REPLACE.
- Local in-memory SQLite defaults (this box): `foreign_keys=0`, `recursive_triggers=0` until explicitly set.

## Needed vs sufficient
| Pragma | Needed for? | Sufficient without? |
|--------|-------------|---------------------|
| `foreign_keys=ON` | Enforce FKs between pins/runs/manifests/scores | Schema identity locks do **not** replace FK integrity; keep ON for migrations/writes |
| `recursive_triggers=ON` | Make DELETE triggers fire during `INSERT OR REPLACE` | **Not required for safety** if v0.3.2 EXISTS…RAISE locks cover every immutable PRIMARY/UNIQUE conflict target (Codex local PASS under OFF) |

## Actual remote D1 probe (read-only; no DDL/DML on score tables)
- Account D1 name: `srp-observatory-v01` (uuid `315d3aab-83ea-4c49-accd-f9217a303f01`)
- Tool: `wrangler d1 execute … --remote` (session via Cloudflare API, **not** a Worker `env.DB` binding request)
- Results:
  - `PRAGMA foreign_keys` → **1 (ON)**
  - `PRAGMA recursive_triggers` → **0 (OFF)**
  - `changed_db=false`, `rows_written=0` on all pragma/list queries
- Table inventory (relevant): `backtest_runs`, `indicator_scores`, `coupling_scores` exist; **no** HIST v0.3.2 lock tables (`backtest_*_identity_locks`, `backtest_score_events`, etc.)
- Row counts probed: `backtest_runs=0`, `indicator_scores=0`
- `backtest_runs` schema on this DB is **legacy** (`id TEXT PK`, `payload TEXT`) — **not** HIST v0.3.2 DDL
- Triggers present: Wave1-style `immutable_*_update/delete` only — **not** HIST v0.3.2 lock triggers
- Worker binding: `[[d1_databases]]` remains **commented out** in `srp-observatory/wrangler.toml`; Worker reports `has_d1` from `env.DB` (currently unbound)

## Caveats (still unknown / not claimed)
1. Wrangler remote execute pragmas are **API-session** values; a future Worker binding may differ per-request unless the Worker sets pragmas on each connection/batch.
2. No Worker-bound D1 request path was exercised (binding absent) — **trusted service boundary for HIST writers on D1 is still unverified**.
3. HIST v0.3.2 schema is **not applied** to this D1; upgrade-over-existing-data behavior is unknown.
4. `PRAGMA compile_options` was denied (`SQLITE_AUTH`) — cannot enumerate compile-time SQLITE features from this API role.

## Fail-closed procedure (NO silent migration)
1. Do **not** apply `schema/d1_backtest.sql` to production D1 until Claude/Astra accept + explicit migration ticket.
2. Before any apply: re-probe `foreign_keys` / `recursive_triggers` on the **same** execution path the Writer will use (Worker binding), not only wrangler CLI.
3. Prefer isolated `TEST_ONLY_*` tables / separate D1 for first APPLY; never rewrite production `indicator_scores` / construct scores.
4. If Worker cannot set `recursive_triggers=ON`, rely on v0.3.2 locks + ban `INSERT OR REPLACE` in writers; still keep `foreign_keys=ON`.
5. Abort migration if any probe shows FK off, lock tables missing, or writer emits REPLACE on immutable tables.
