normalize.py
python
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
1 day ago
| 1 | """Phase Model-label and pending-gate normalization for active-slice routing (§PC.7).""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | import re |
| 6 | |
| 7 | from tools.governance_gates.types import PendingGate |
| 8 | |
| 9 | ROADMAP_ROW_RE = re.compile( |
| 10 | r"^\|\s*\*\*(?P<phase>[^|*]+)\*\*\s*\|\s*(?P<model>[^|]+)\|\s*\*\*(?P<status>[^|*]+)\*\*\s*\|\s*(?P<deliverable>[^|]+)", |
| 11 | re.MULTILINE, |
| 12 | ) |
| 13 | |
| 14 | |
| 15 | def normalize_phase_tier(model_label: str, *, label_ids: frozenset[str]) -> str | None: |
| 16 | """Map a roadmap ``Model:`` label to a ``labels[]`` id, or ``None`` (wildcard).""" |
| 17 | cleaned = model_label.strip() |
| 18 | if not cleaned: |
| 19 | return None |
| 20 | lowered = cleaned.lower() |
| 21 | if lowered in label_ids: |
| 22 | return lowered |
| 23 | display_map = { |
| 24 | "thinking": "thinking", |
| 25 | "auto": "auto", |
| 26 | } |
| 27 | return display_map.get(lowered) |
| 28 | |
| 29 | |
| 30 | def gate_for_phase(pending: tuple[PendingGate, ...], phase_id: str) -> str | None: |
| 31 | """Map pending governance gates for a phase to a routing ``gate`` selector.""" |
| 32 | phase_gates = [gate for gate in pending if gate.phase_id == phase_id] |
| 33 | if any(gate.gate_id == "freeze_review" for gate in phase_gates): |
| 34 | return "freeze_review" |
| 35 | if any(gate.gate_id == "build_verification" for gate in phase_gates): |
| 36 | return "build_verification" |
| 37 | return None |
| 38 | |
| 39 | |
| 40 | def model_label_for_phase(roadmap: str | None, phase_id: str) -> str | None: |
| 41 | """Read the roadmap model column for ``phase_id``.""" |
| 42 | if roadmap is None: |
| 43 | return None |
| 44 | normalized = _normalize_phase_id(phase_id) |
| 45 | for match in ROADMAP_ROW_RE.finditer(roadmap): |
| 46 | if _normalize_phase_id(match.group("phase")) == normalized: |
| 47 | return match.group("model").strip() |
| 48 | return None |
| 49 | |
| 50 | |
| 51 | def _normalize_phase_id(text: str) -> str: |
| 52 | cleaned = text.strip() |
| 53 | return re.sub(r"\s+", " ", cleaned) |
File History
1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
1 day ago