trading-system-docs/a5/DESIGN.md
Red Queen 968094498a feat(a5): Controlled Heartbeat & Resume v1
- a5/rq_heartbeat.py: HeartbeatStore + Heartbeat.run_tick (thin scheduler/resume layer)
- a5/rq_heartbeat_cli.py: status/tick/enable/disable/resume/approve/deny/priority
- a5/test_a5.py: 31 deterministic tests (tick-lock incl. ownership, eligibility, kill-switch, approval, circuit, git-conflict, bounded single A4)
- a5/DESIGN.md, a5/README.md, a5/scripts/a5_heartbeat_tick.sh
- a2/rq_mission.py: add read-only mission_list() for A5 enumeration (additive)
- Fresh checker: PASS after tick-lock ownership repair (Regressionschutz lock_owned)
2026-08-24 23:04:16 +00:00

2.4 KiB

A5 DESIGN — CONTROLLED HEARTBEAT & RESUME v1

Integrations (verified from source)

  • A2 MissionStore (a2/rq_mission.py, missions.db):
    • mission_list() [NEW, read-only, added for A5] — enumerate missions.
    • mission_read(id) -> dict with work_packages, dependencies, state.
    • mission_state(id), wp_state(id).
    • Transitions: mission_transition(id,target,actor,evidence), mission_pause, mission_resume, mission_complete, wp_transition, wp_complete.
    • Transition tables in a2/rq_state_machine.py: eligible mission states {READY,RUNNING,REVIEW,PAUSED-resume-capable}; PAUSED->RUNNING allowed; BLOCKED->IN_PROGRESS (wp) allowed; REVIEW->RUNNING allowed.
  • A3 SafetyStore (a3/rq_safety.py, safety_db):
    • check_safety_state(mid,wp) — fail-closed STATE_INCONSISTENT.
    • evaluate_next_action(mid,wp,is_mutating,persist) — decision + circuit.
    • circuit_state(scope_type,scope_id), open_circuit, attempts, attempts_count, safety_evidence, redact_secret.
  • A4 Orchestrator (a4/rq_orchestrator.py):
    • __init__(mission_db, safety_db, child_dispatcher=None, max_bounded_runtime=...).
    • run_bounded(mission_id, max_steps=1, actor) — EXACTLY-N bounded steps, guarantees return. Without child_dispatcher returns dispatch contracts; with dispatcher runs full Maker+Checker.
    • attempt_mission_complete(mission_id, final_review_pass=...).
    • run_one_step = 1 child cycle. A4 has own limits (no loop).
  • Hermes native cron: .tick.lock, executions.db, no_agent, workdir, delivery. Baseline regression A2=61, A3=69, A4=83 PASS.

A5 result codes (§10)

HB_NO_ACTIVE_MISSION, HB_MISSION_NOT_ELIGIBLE, HB_SAFETY_BLOCKED, HB_STATE_CONFLICT, HB_NO_RUNNABLE_WORK, HB_BOUNDED_RUN_COMPLETE, HB_MISSION_COMPLETED, HB_APPROVAL_REQUIRED, HB_ESCALATED, HB_CIRCUIT_OPEN, HB_TIMEOUT, HB_INTERNAL_ERROR, plus HB_LOCKED, HB_KILL_SWITCH_OFF, HB_PAUSED, HB_CANCELLED, HB_GIT_CONFLICT, HB_RECOVERY_REQUIRED.

Key invariants (spec §5,§9,§18,§25,§29,§30)

  • A5 is a thin layer: never fabricates states/retries/circuits. Delegates to A2/A3/A4.
  • Exactly ONE A4 run_bounded(max_steps=1) per tick per mission; MAX 1 mission per tick.
  • No while-true, no self-reschedule, no background child dependency.
  • Kill switch default OFF; blocks all mutation, read-only health allowed.
  • Fail-closed: any gate failure -> NO mutation, stable result code.
  • Dedup notifications by (mission, reason_code, evidence_hash).