"""Layer 2 — Context Matrix (persona + tensions + cultural context).""" from __future__ import annotations import json from pathlib import Path from typing import Literal from pydantic import BaseModel, Field class GreimasSquare(BaseModel): S1: str S2: str not_S1: str not_S2: str class TensionArchetype(BaseModel): id: str name: str description: str = "" greimas_square: GreimasSquare emotional_payoff: str class Demographic(BaseModel): age_range: str | None = None gender: str | None = None income_band: str | None = None education: str | None = None region: str | None = None class Psychographic(BaseModel): values: list[str] = Field(default_factory=list) pain_points: list[str] = Field(default_factory=list) aspirations: list[str] = Field(default_factory=list) media_habits: list[str] = Field(default_factory=list) class TargetPersona(BaseModel): demographic: Demographic = Field(default_factory=Demographic) psychographic: Psychographic = Field(default_factory=Psychographic) free_text: str | None = None class CulturalContext(BaseModel): korean_specific: list[str] = Field(default_factory=list) global_universal: list[str] = Field(default_factory=list) forbidden_zones: list[str] = Field(default_factory=list) class FlochAxis(BaseModel): axis: str value_type: Literal["practical", "utopian", "critical", "playful"] description: str | None = None class ContextMatrix(BaseModel): target_persona: TargetPersona = Field(default_factory=TargetPersona) tension_archetypes: list[TensionArchetype] = Field(min_length=6) cultural_context: CulturalContext = Field(default_factory=CulturalContext) setting_archetypes: list[str] = Field(default_factory=list) floch_consumption_axis: list[FlochAxis] = Field(default_factory=list) def get_tension(self, tension_id: str) -> TensionArchetype: for t in self.tension_archetypes: if t.id == tension_id: return t raise KeyError(f"Tension '{tension_id}' not found") def load_context(path: str | Path) -> ContextMatrix: """Load ContextMatrix from a tensions JSON file.""" data = json.loads(Path(path).read_text(encoding="utf-8")) return ContextMatrix.model_validate(data)