@@ -1094,3 +1094,30 @@ Bu dosya yalnız sonuçları değil; kararları, reddedilen alternatifleri, migr
10941094 its active identity, aggregate record counts, a signed next cursor and
10951095 private detail for a deleted/moderated owned reply without mutating
10961096 production data.
1097+
1098+ ### 2026-07-29 — Stale backup-run reconciliation
1099+
1100+ - Investigated daily backup run
1101+ ` 019fabe1-0776-75c5-80a1-6b46e4b7ce00 ` , which remained ` running ` after the
1102+ Worker execution ended. The backup flow previously depended on its local
1103+ ` catch ` block to mark failures; a terminated Worker cannot execute that
1104+ cleanup, and no later operation reconciled the abandoned row.
1105+ - Every R2 backup now atomically marks ` running ` rows older than 30 minutes as
1106+ ` failed ` with ` backup_run_stale_timeout ` before starting a new run. The
1107+ reconciliation emits only a structured count and never logs run IDs,
1108+ object keys, checksums or encryption material. A one-minute active run is
1109+ deliberately left untouched.
1110+ - Full proof passed: 110 D1/workerd tests, Astro zero diagnostics, 54
1111+ production-config assertions, four Actions-scope tests and the production
1112+ Worker build/dry-run. The regression seeds both stale and fresh runs and
1113+ verifies only the stale row is closed.
1114+ - Fix commit ` 7b83a1ff1d12a4b95e1c291a6d8cfc6f66df1e38 ` was pushed to
1115+ ` main ` . Deploy run ` 30451801039 ` and CodeQL run ` 30451801043 ` completed
1116+ successfully.
1117+ - The exact abandoned production row was then closed with a guarded update
1118+ requiring its immutable ID, ` status = 'running' ` and a null completion time.
1119+ Exactly one row changed. Its final state is ` failed ` with
1120+ ` backup_run_stale_timeout ` ; production now has zero running backup rows.
1121+ The successful encrypted manual backup
1122+ ` 019fadc5-bba8-701e-9b84-949bffd521f3 ` remains intact, ` /healthz ` is 200 and
1123+ ` PRAGMA foreign_key_check ` remains empty.
0 commit comments