#!/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