fix(auditlog): reconciliation abandons only row-intrinsic failures and only when a sibling row inserted (review 2026-10-21 follow-up M1)

This commit is contained in:
Joseph Doherty
2026-10-22 09:31:26 -04:00
parent 6b8a91cc83
commit 1f87942ce3
4 changed files with 225 additions and 73 deletions
+10 -4
View File
@@ -329,9 +329,14 @@ batch forever, failing each set-based insert at central into the per-row fallbac
transient refusal still lands, and a genuinely poison row is recorded centrally as
a `ReconciliationAbandoned` row before its cursor retires it. A transport fault (no
answer) is never counted as a refusal. Symmetrically, the reconciliation puller counts
only non-transient failures toward its permanent-abandon threshold: a timeout,
connection loss, deadlock or throttling error holds the cursor and retries without
ever abandoning the row. A cached-lifecycle row whose tracking
only **row-intrinsic** failures (the same narrow set the push path reports as rejected:
truncation, NULL into NOT NULL, conversion/overflow, constraint) toward its
permanent-abandon threshold: a timeout, connection loss, deadlock, throttling error, or
schema drift after a missed central migration (207/208) holds the cursor and retries
without ever abandoning the row. And even a row-intrinsic failure abandons a row only on a
tick where at least one *sibling* row of the same page inserted — a page where every row
fails identically is a database problem, and abandoning it would let the site mark every
row `Reconciled` and purge it (review 2026-10-21 follow-up M1). A cached-lifecycle row whose tracking
snapshot is gone past `CachedTrackingGraceSeconds` leaves the cached drain as
`PushAbandoned` (it used to be marked `Forwarded`, which only worked because the
pull re-served every `Forwarded` row). Cadence is short (default 5 s) when
@@ -665,7 +670,8 @@ MS SQL for direct-write events). Unredacted secrets never persist.
still report a non-draining backlog after paging up to `MaxPagesPerTick`, a
`SiteAuditTelemetryStalled` event fires.
- **Permanent-abandonment record.** A reconciliation pull row that fails to
insert on every retry up to the permanent-abandon threshold is dropped and the
insert with a row-intrinsic error on every retry up to the permanent-abandon
threshold, while a sibling row of its page inserts, is dropped and the
cursor advances past it (so one broken row can't block the site forever). The
loss is not silent: alongside the Critical log line the actor writes ONE
synthetic `ReconciliationAbandoned` audit row (fresh `EventId`, `Status=Failed`,