"""The alteration engine: a knob vector -> a layered RenderPlan (design §4, §5). Replaces the 2026-06-04 nearest-match *selection* with a *transformation* of a neutral base clip. Given the four experience knobs, it produces three layers that compose per §4.2: - Substrate transforms (alter pixels, blend with each other): * Restyle -- the Right axis: a pre-baked generative v2v dreamlike restyle. * ColorGrade -- the mood axis (Dark/Light): a deterministic color grade. - Overlay (composited on top of the substrate): * AnalyticalOverlay -- the Left axis: HUD/labels/measurement. Left and Right are NOT opposites; they live on different layers and stack (§4.2). Dark and Light are the two poles of one mood grade whose center is the identity (§5). Calibration note: the knob->strength curves below are the single source of truth for how a 0..4 position maps to a transform strength. See the session 0006 transcript Deferred decisions for the §3-vs-§4.2/§5 reconciliation. """ from __future__ import annotations from dataclasses import dataclass from hef.selection import Coordinate KNOB_MAX = 4 # knob full-scale (0..4) @dataclass(frozen=True) class ColorGrade: """Mood-axis grade (§5). `tone` is signed: >0 warm yellow->white (light), <0 cool blue->black (dark), 0 = identity (raw, ungraded).""" tone: float @property def is_identity(self) -> bool: return self.tone == 0.0 @dataclass(frozen=True) class AnalyticalOverlay: """Left axis (§4.1): analytical HUD/annotation/labels, composited on top. `intensity` 0..1 (0 = no overlay).""" intensity: float @dataclass(frozen=True) class Restyle: """Right axis (§4.1): pre-baked generative v2v dreamlike substrate. `blend` 0..1 (0 = raw substrate, no restyle).""" blend: float @dataclass(frozen=True) class RenderPlan: """The full layered alteration for one knob vector (§4.2).""" grade: ColorGrade overlay: AnalyticalOverlay restyle: Restyle @property def is_identity(self) -> bool: """True when the plan leaves the neutral base un-altered.""" return ( self.grade.is_identity and self.overlay.intensity == 0.0 and self.restyle.blend == 0.0 ) def _overlay_intensity(left: int) -> float: """Left knob -> analytical-overlay intensity (0..1).""" return left / KNOB_MAX def _restyle_blend(right: int) -> float: """Right knob -> v2v restyle blend (0..1).""" return right / KNOB_MAX def _mood_tone(dark: int, light: int) -> float: """(dark, light) -> signed mood grade in [-1, 1]; equal -> 0 identity (§5).""" return (light - dark) / KNOB_MAX def plan_alteration(coord: Coordinate) -> RenderPlan: """Map a knob vector to its layered RenderPlan (design §4).""" return RenderPlan( grade=ColorGrade(tone=_mood_tone(coord.dark, coord.light)), overlay=AnalyticalOverlay(intensity=_overlay_intensity(coord.left)), restyle=Restyle(blend=_restyle_blend(coord.right)), )