feat(messaging): implement Track 0 fault tolerance (B-14, B-15) and add 10 regression guards (G-1 to G-10)

This commit is contained in:
2026-08-20 12:16:40 +09:00
parent 4025623958
commit c6b6c77ce4
6 changed files with 692 additions and 38 deletions
@@ -192,15 +192,19 @@ def main(argv=None) -> int:
attempts=args.attempts,
exceptions=(OSError, TimeoutError, ConnectionError, ValueError),
)
publish_ok = True
publish_error: Optional[str] = None
try:
publish(config, topic, body, retain)
except Exception as exc:
publish_ok = False
publish_error = str(exc)
logger.error("publish failed after %d attempts: %s", args.attempts, exc)
return 2
# Persistent audit log: record the exact payload we put on the wire so the
# publish is reproducible from the log alone. Best-effort (isolated inside
# append_event) — never fails the publish.
# Persistent audit log: record the exact payload we put on the wire (or intended to).
# Best-effort (isolated inside append_event) — never fails the publish.
# Policy Note: Seq consumption on failure is intentionally maintained for monotonic replay
# defense (> highest accepted seq), with failure documented explicitly in the audit record.
mqtt_common.append_event(job_id, {
"event": "published",
"source_event": args.event,
@@ -210,6 +214,8 @@ def main(argv=None) -> int:
"timestamp": payload["timestamp"],
"detail": args.detail,
"payload": payload,
"published": publish_ok,
"publish_error": publish_error,
})
# Best-effort side effects: registry status sync + (debug) event log. Never
@@ -222,6 +228,9 @@ def main(argv=None) -> int:
except Exception as exc: # pragma: no cover - best effort
logger.warning("status sync failed: %s", exc)
if not publish_ok:
return 2
logger.info("published %s seq=%d job=%s retain=%s", args.event, seq, job_id, retain)
return 0