fix(subscriber): the disk fallback takes an audit status only when it is at least as new as the record
The audit mirror is written after the registry commits, so a redispatched record (attempt 2, pending) can sit next to attempt 1's completed status.json, and a failed mirror leaves it there. The fallback validated the token and attempt against the record, which say nothing about the audit status's provenance, and closed attempt 2 with attempt 1's completion (review P1, Issue #57). A versioned record (transition_seq) now takes the audit status only when its transition_seq is at least as new; an audit status without a sequence cannot prove which attempt it describes and is ignored by a versioned record. An unversioned record (never transitioned, or MAM_ENGINE_CAS=0) and a missing record keep the old rule. Regressions: the redispatch/flush interval, the failed-mirror leftover, the unversioned audit status, a newer audit-only terminal, and conflict refusals and legacy claims next to a moved registry. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
6d182b392c
commit
f299034d8d
2 files changed
+81
-2
No files matched your search
@@ -84,11 +84,13 @@ def _check_disk_fallback(
|
||||
disk_status = None
|
||||
rec_token = None
|
||||
rec_attempt = None
|
||||
rec_seq = None
|
||||
try:
|
||||
job_rec = load_job(jid, registry_dir)
|
||||
disk_status = job_rec.get("status")
|
||||
rec_token = job_rec.get("dispatch_token")
|
||||
rec_attempt = job_rec.get("attempt_id", job_rec.get("iteration"))
|
||||
rec_seq = job_rec.get("transition_seq")
|
||||
except Exception:
|
||||
job_rec = {}
|
||||
if not disk_status or disk_status not in ("completed", "error", "cancelled"):
|
||||
@@ -99,7 +101,20 @@ def _check_disk_fallback(
|
||||
except Exception:
|
||||
logged = None
|
||||
if logged:
|
||||
disk_status = logged.get("status")
|
||||
# The audit mirror is written after the registry commits, so a
|
||||
# record that is not terminal may sit next to the previous
|
||||
# attempt's terminal status. A versioned record (the engine's
|
||||
# transition_seq) takes the audit status only when the audit is
|
||||
# at least as new; an audit status without a sequence cannot
|
||||
# prove which attempt it describes, so a versioned record
|
||||
# ignores it. An unversioned record (never transitioned, or
|
||||
# MAM_ENGINE_CAS=0) and a missing record keep the old rule.
|
||||
aud_seq = logged.get("transition_seq")
|
||||
if rec_seq is not None and (aud_seq is None or int(aud_seq) < int(rec_seq)):
|
||||
logger.warning("disk fallback ignored audit status %r for %s: transition_seq %r is older "
|
||||
"than the record's %r", logged.get("status"), jid, aud_seq, rec_seq)
|
||||
else:
|
||||
disk_status = logged.get("status")
|
||||
|
||||
if disk_status in ("completed", "error", "cancelled"):
|
||||
if expected_dispatch_tokens:
|
||||
|
||||
Reference in new issue
Block a user