"""sentinel/taxonomy.py — Taxonomy constants from agent_failure_taxonomy.md.

Single source of truth for taxonomy IDs.  Any addition to the taxonomy
file MUST be reflected here.

Design:
  - Pure data module — no logic, no imports beyond stdlib.
  - Used by detection.py, engine.py, patterns.py, articulation.py.
"""

from __future__ import annotations

from typing import Dict, List, Tuple

# ── Category families ────────────────────────────────────────────────

CONTEXT_DEGRADATION: Dict[str, str] = {
    "CD-1":  "Context Rot",
    "CD-2":  "Lost in the Middle",
    "CD-3":  "Primacy Bias",
    "CD-4":  "Recency Bias",
    "CD-5":  "Prompt Drift",
    "CD-6":  "System Prompt Erosion",
    "CD-7":  "Context Pollution",
    "CD-8":  "Context Pressure",
    "CD-9":  "Attention Sink",
    "CD-10": "Token Bloat",
    "CD-11": "Context Staleness",
}

MEMORY_ARCHITECTURE: Dict[str, str] = {
    "MA-1": "Context Engineering",
    "MA-2": "Tiered Memory",
    "MA-3": "Memory Files",
    "MA-4": "Rules vs Skills",
    "MA-5": "SCAN Technique",
    "MA-6": "Episodic Buffer",
    "MA-7": "Scratchpad / Inner Monologue",
    "MA-8": "Context Window Truncation Strategy",
}

FAILURE_MODES: Dict[str, str] = {
    "FM-1":  "Confabulation",
    "FM-2":  "Sycophancy",
    "FM-3":  "Mode Collapse",
    "FM-4":  "Catastrophic Forgetting",
    "FM-5":  "Circular Logic Bug",
    "FM-6":  "Agent Death Spiral",
    "FM-7":  "Tool Sprawl",
    "FM-8":  "State Drift",
    "FM-9":  "Context Contamination",
    "FM-10": "Task Decomposition Failure",
    "FM-11": "Polanyi's Paradox",
    "FM-12": "Carrier Protocol",
}

REASONING_GROUNDING: Dict[str, str] = {
    "RG-1": "Chain of Thought (CoT)",
    "RG-2": "Tree of Thoughts (ToT)",
    "RG-3": "Chain of Evidences (CoE)",
    "RG-4": "Reflexion",
    "RG-5": "Grounding",
    "RG-6": "Vibe Coding",
}

ALL_TAXONOMY: Dict[str, str] = {
    **CONTEXT_DEGRADATION,
    **MEMORY_ARCHITECTURE,
    **FAILURE_MODES,
    **REASONING_GROUNDING,
}

# ── Picker categories (subset shown to user) ────────────────────────
# Only the most common / user-recognizable failure modes appear in the
# compact picker.  Full taxonomy is used for structural arm matching.

PICKER_OPTIONS: List[Tuple[str, str]] = [
    ("CD-1",  "Context got confused across turns"),
    ("CD-2",  "AI ignored something I said earlier"),
    ("CD-5",  "AI forgot the original instructions"),
    ("FM-1",  "AI made something up / wrong facts"),
    ("FM-2",  "AI just agreed without thinking critically"),
    ("FM-3",  "AI gave a generic / repetitive answer"),
    ("FM-5",  "AI's fix reintroduced the original problem"),
    ("FM-8",  "AI lost track of where we are in the task"),
    ("FM-10", "AI broke the task down incorrectly"),
    ("FM-11", "I can't articulate it — something is off"),
]

# ── Detection signal keywords per taxonomy ID ───────────────────────
# Used by the proactive arm to scan AI output for self-diagnosis.

PROACTIVE_SIGNALS: Dict[str, List[str]] = {
    "CD-1":  ["as I mentioned", "as we discussed", "earlier in our conversation"],
    "CD-5":  ["let me re-read", "remind me of", "what were the original"],
    "FM-1":  ["I believe", "I think", "probably", "likely", "if I recall"],
    "FM-2":  ["you're right", "that's correct", "absolutely", "great point"],
    "FM-3":  ["in general", "typically", "usually", "it depends"],
    "FM-8":  ["let me check where we", "which step", "I'll continue from"],
    "FM-10": ["let me break this down", "the steps are", "first we need to"],
}

# ── Reactive arm trigger phrases (user complaint detection) ──────────
# Regex patterns matched against user input to detect explicit complaints.

REACTIVE_TRIGGERS: List[Tuple[str, str]] = [
    (r"that'?s?\s+not\s+what\s+I\s+meant", "CD-1"),
    (r"no[,.]?\s+I\s+said", "CD-2"),
    (r"you'?re?\s+not\s+listening", "CD-2"),
    (r"I\s+already\s+told\s+you", "CD-2"),
    (r"\bwrong\b", "FM-1"),
    (r"\bincorrect\b", "FM-1"),
    (r"that'?s?\s+not\s+right", "FM-1"),
    (r"\bstop\b", "FM-6"),
    (r"\bstart\s+over\b", "FM-6"),
    (r"\breset\b", "FM-8"),
    (r"you\s+keep\s+(doing|saying|giving|repeating)", "FM-3"),
    (r"same\s+(answer|thing|response)", "FM-3"),
    (r"you\s+(forgot|lost|missed)\s+(the|my|our)", "CD-5"),
    (r"not\s+what\s+I\s+asked", "CD-2"),
    (r"you'?re?\s+(making|inventing)\s+(things?\s+)?up", "FM-1"),
    (r"that\s+doesn'?t\s+make\s+sense", "FM-5"),
    (r"you\s+already\s+(fixed|did)\s+that", "FM-5"),
    (r"we\s+already\s+(covered|discussed)\s+that", "CD-1"),
]

# ── Hedging indicators (for proactive H3) ────────────────────────────

HEDGING_PHRASES: List[str] = [
    "I think",
    "I believe",
    "probably",
    "perhaps",
    "might be",
    "could be",
    "if I recall",
    "I'm not sure",
    "it seems",
    "possibly",
    "maybe",
    "approximately",
    "roughly",
    "more or less",
]

# ── Sycophancy indicators (for proactive H4) ────────────────────────

SYCOPHANCY_PHRASES: List[str] = [
    "you're right",
    "you're absolutely right",
    "that's correct",
    "absolutely",
    "great point",
    "excellent question",
    "good observation",
    "that's a great",
    "I completely agree",
    "you make a good point",
]
