RED QUEEN BUILD PHASE A2: Mission-State- und Work-Package-State-Machine. Minimaler Missions-Metadata-Layer (missions.db) auf nativer Hermes-Kanban-Basis (KanbanMirror best effort). Deterministische Validierung, Idempotenz, STATE_ERROR fail-closed, Restart-Persistenz. 61 deterministische Tests PASS. Keine autonome Orchestrierung/Loops/Cron.
121 lines
3.6 KiB
Python
121 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Red Queen — A2: Deterministische Zustandsmaschinen (MISSION + WORK PACKAGE).
|
|
|
|
Single source of truth fuer alle erlaubten/verbotenen Transitions, gemaeß
|
|
`red-queen-architecture/MISSION_STATE_MACHINE.md` (autoritativer Vertrag).
|
|
|
|
Dieses Modul enthaelt KEINE Persistenz und KEINE Orchestrierung — nur die
|
|
reinen State-Mengen und Transition-Tabellen. Die Anwendung (Persistenz,
|
|
Validierung, Kanban-Mirror) liegt in `rq_mission.py`.
|
|
|
|
Transitions sind deterministisch: fuer ein gegebenes (von, nach) Paar gibt es
|
|
genau eine Antwort (erlaubt / verboten).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Dict, FrozenSet, Set, Tuple
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# State-Mengen
|
|
# --------------------------------------------------------------------------- #
|
|
MISSION_STATES: FrozenSet[str] = frozenset(
|
|
{
|
|
"CREATED",
|
|
"PLANNING",
|
|
"READY",
|
|
"RUNNING",
|
|
"REVIEW",
|
|
"COMPLETED",
|
|
"BLOCKED",
|
|
"PAUSED",
|
|
"FAILED",
|
|
"CANCELLED",
|
|
"ESCALATED",
|
|
}
|
|
)
|
|
|
|
WP_STATES: FrozenSet[str] = frozenset(
|
|
{
|
|
"TODO",
|
|
"READY",
|
|
"IN_PROGRESS",
|
|
"CHECKING",
|
|
"DONE",
|
|
"FAILED",
|
|
"BLOCKED",
|
|
"ESCALATED",
|
|
}
|
|
)
|
|
|
|
# Endzustaende (keine Reaktivierung ohne Neuanlage).
|
|
MISSION_TERMINAL: FrozenSet[str] = frozenset({"FAILED", "CANCELLED"})
|
|
WP_TERMINAL: FrozenSet[str] = frozenset({"FAILED"}) # DONE ist terminal im
|
|
# Sinne "nicht mehr normal weiter", aber idempotent akzeptiert.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Transition-Tabellen — MISSION
|
|
# ---------------------------------------------------------------------------
|
|
# MISSION_STATE_MACHINE.md §4 (Mission): (von, nach) -> erlaubt
|
|
MISSION_TRANSITIONS: Set[Tuple[str, str]] = {
|
|
("CREATED", "PLANNING"),
|
|
("PLANNING", "READY"),
|
|
("PLANNING", "BLOCKED"),
|
|
("READY", "RUNNING"),
|
|
("RUNNING", "REVIEW"),
|
|
("REVIEW", "COMPLETED"),
|
|
("REVIEW", "RUNNING"),
|
|
("RUNNING", "PAUSED"),
|
|
("PAUSED", "RUNNING"),
|
|
("RUNNING", "BLOCKED"),
|
|
("BLOCKED", "PAUSED"),
|
|
("BLOCKED", "RUNNING"),
|
|
("BLOCKED", "ESCALATED"),
|
|
("PAUSED", "CANCELLED"),
|
|
("RUNNING", "FAILED"),
|
|
("RUNNING", "CANCELLED"),
|
|
("BLOCKED", "CANCELLED"),
|
|
("ESCALATED", "RUNNING"),
|
|
("ESCALATED", "CANCELLED"),
|
|
("ESCALATED", "COMPLETED"),
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Transition-Tabellen — WORK PACKAGE
|
|
# ---------------------------------------------------------------------------
|
|
WP_TRANSITIONS: Set[Tuple[str, str]] = {
|
|
("TODO", "READY"),
|
|
("READY", "IN_PROGRESS"),
|
|
("IN_PROGRESS", "CHECKING"),
|
|
("CHECKING", "DONE"),
|
|
("CHECKING", "IN_PROGRESS"),
|
|
("IN_PROGRESS", "FAILED"),
|
|
("IN_PROGRESS", "BLOCKED"),
|
|
("BLOCKED", "IN_PROGRESS"),
|
|
("BLOCKED", "ESCALATED"),
|
|
("ESCALATED", "IN_PROGRESS"),
|
|
("ESCALATED", "FAILED"),
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# API
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def is_mission_state(state: str) -> bool:
|
|
return state in MISSION_STATES
|
|
|
|
|
|
def is_wp_state(state: str) -> bool:
|
|
return state in WP_STATES
|
|
|
|
|
|
def mission_transition_allowed(current: str, target: str) -> bool:
|
|
"""Deterministische Antwort, ob (current -> target) erlaubt ist."""
|
|
return (current, target) in MISSION_TRANSITIONS
|
|
|
|
|
|
def wp_transition_allowed(current: str, target: str) -> bool:
|
|
"""Deterministische Antwort, ob (current -> target) erlaubt ist."""
|
|
return (current, target) in WP_TRANSITIONS
|