Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions docs/audit/live-drift-forensics-2026-08.md
Original file line number Diff line number Diff line change
Expand Up @@ -2053,7 +2053,7 @@ $ supabase migration list --linked --project-ref sjrfecxgysukkwxsowpy
empty and the step should now pass. **No guard migration is owed**: the row carries executed
statements, so it is not a history repair and cannot surface in the `migration_history` probe.

#### The D4 conclusion needs re-testing — the 2026-08-19 test could not detect deploy-on-merge
#### D4: strong evidence of deploy-on-mergebut the toggle itself has not been read

`created_by` and `idempotency_key` are NULL for every row from `20260818090000` to `20260820120000`,
including the ones this programme applied by operator `db push`, so the history table carries **no
Expand All @@ -2067,9 +2067,42 @@ distinction is the whole of D4:

The 2026-08-19 observation recorded as "D4 is OFF" was that the four `20260819` migrations _sat
pending while the PR was open_. That tests deploy-while-open, **not** deploy-on-merge, so it never
contradicted §3.7 — and today's result fits both observations at once. **Treat D4 as UNRESOLVED and
re-verify in the Supabase dashboard before relying on merge being safe.** Until then, assume merging a
migration PR deploys it to production.
contradicted §3.7 — and today's result fits both observations at once.

**Settled the same day by reading the platform instead of the history table.**
`list_branches(sjrfecxgysukkwxsowpy)` returns exactly one record:

```json
{
"name": "main",
"is_default": true,
"git_branch": "main",
"project_ref": "sjrfecxgysukkwxsowpy",
"created_at": "2026-06-27T14:10:20.550361+00:00",
"updated_at": "2026-07-04T08:15:07.640507+00:00"
}
```

Production is **still bound to git `main`**, and `updated_at` predates 2026-08-19 — so whatever was
changed that day never touched this binding, and the §3.7 mechanism is intact. Together with §3.7's
34-second apply and `20260820120000` arriving unpushed, that is strong evidence of deploy-on-merge.

**It remains an inference, and the difference matters.** No field of the branch record reports the
"Deploy to production" setting. The superseded 2026-08-19 account describes that setting being changed
without the binding being deleted, so "toggle off, binding intact" cannot be ruled out from here — and
the two failure modes are not symmetric. Declaring D4 ON tells operators to skip `db push`; if the
toggle is in fact off, every merged migration then sits unapplied and drift returns silently, which is
the original incident. Declaring it OFF risks only a redundant no-op push.

**So the operative rule is the one that is correct under both states, and it must not be shortened:**

1. Never merge a migration PR outside its approved window — correct if deploys happen on merge.
2. After any migration merges, run `supabase migration list --linked --project-ref <ref>` and
`db push` anything still pending — correct if they do not.

One extra command, wrong under neither hypothesis. What would replace this rule with a fact is a
dashboard read of the toggle, or a deployment-settings API that reports it. Raised as a P1 by the Codex
review of PR #2205, and correctly: the earlier wording here presented the inference as a direct read.

#### Staging is one version behind — blocked, not skipped

Expand Down
25 changes: 19 additions & 6 deletions docs/database-remediation-coordination.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ no mark-applied path was used, and production received zero writes. Verified rea
`ok`; ten `work_mem` values = D1; live-drift run `32131517648` = **0 function mismatches**,
20 `missing_live`, 2 `unexpected_live`, 15 `migration_history`. The RPC track of `#316` is closed.

**KEY FINDING — D4 DECIDED (auto-deploy disabled).** The Supabase GitHub integration (Branching, production
**KEY FINDING — D4: strong evidence of deploy-on-merge; the "disabled" reading does not hold (2026-08-20, below). The toggle itself has not been read — act on the safe-either-way rule, not on the inference.** The Supabase GitHub integration (Branching, production
bound to git `main`, branch record from 2026-06-27) auto-applies every migration merged to `main`
onto production — live-drift bracketed `110000–112000` to ~34 s after #2106 merged. This undermines
the explicit-window model the plan and playbook assume: a merged migration IS a production deploy.
Expand Down Expand Up @@ -150,15 +150,28 @@ needs the same migration by the Phase 2 method. Until that window runs, the week
this one step and #1963 will not self-close.

**Update 2026-08-20 (window) — the alignment fix is LIVE on production; staging is one version behind;
D4 is UNRESOLVED again.** PR #2198 merged before the window (squash `a341832af`), and the pre-flight
D4: strong evidence of deploy-on-merge, toggle not directly read.** PR #2198 merged before the window (squash `a341832af`), and the pre-flight
found `20260820120000` **already applied** — `stmt_count 3`, executed statements, not mark-applied — so
`db push` was never run against production. Verified read-only: `prosecdef true`, `provolatile s`,
`search_path=""`, `proacl postgres=X/postgres | service_role=X/postgres`, and the function returns
`probe: ok` with `version_count 211` against 211 history rows and 211 local files. No guard migration is
owed. **Two things for the owner:** (1) `created_by` is NULL on every recent row, so nothing proves how
it arrived; the 2026-08-19 "D4 is OFF" test only showed migrations sitting pending _while a PR was
open_, which never contradicted §3.7's 34-second deploy after #2106's squash-merge — re-verify the
dashboard toggle and, until then, assume merging a migration PR deploys it. (2) Staging
owed. **Two things for the owner:** (1) **D4: the "disabled" reading does not hold, but the toggle has
not been read.** `created_by` is NULL on every recent history row, so the database itself proves
nothing. `list_branches(sjrfecxgysukkwxsowpy)` still returns a live Git branch record binding
**production** to git `main`:
`{"name":"main","is_default":true,"git_branch":"main","project_ref":"sjrfecxgysukkwxsowpy","created_at":"2026-06-27","updated_at":"2026-07-04"}`.
`updated_at` predates 2026-08-19, so whatever was changed that day never touched this binding, and the
2026-08-19 "D4 is OFF" test only showed migrations sitting pending _while a PR was open_ — which never
exercised deploy-on-merge. Together with §3.7's 34-second apply and `20260820120000` arriving unpushed,
that is strong evidence of deploy-on-merge. **It is still an inference:** no field of the branch record
reports the "Deploy to production" setting, and the superseded account above describes that setting
being changed without the binding being deleted, so a disabled toggle with the binding intact cannot be
ruled out from here. **Therefore act on the rule that is correct under both states, and do not shorten
it:** never merge a migration PR outside its approved window (correct if deploys happen on merge), and
after any migration merges, run `supabase migration list --linked --project-ref <ref>` and `db push`
anything still pending (correct if they do not). One extra command; wrong under neither hypothesis. A
dashboard read of the toggle, or a deployment-settings API, is what would replace this rule with a
fact. (2) Staging
(`ikoiolksxqxfxgiyqpnu`) is at 210 rows without the function; its pending set is exactly one version,
but both write paths were denied by the session auto-mode classifier (live-Supabase confirmation rule
from PR #2196), so Phase 4's staging parity is open again by one version until an operator applies it.
Expand Down
Loading