64 lines
1.9 KiB
Python
64 lines
1.9 KiB
Python
|
|
"""The intent layer: what is supposed to be true.
|
||
|
|
|
||
|
|
Claims and invariants are *inputs* to a run and are frozen — decision D-02.
|
||
|
|
There is deliberately no code path by which adaptation, retry, or a learned
|
||
|
|
trajectory can modify them. That absence is what makes False Adaptation Rate = 0
|
||
|
|
an architectural property rather than a tuning target.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from dataclasses import dataclass, field
|
||
|
|
from typing import Callable, Mapping
|
||
|
|
|
||
|
|
from .provenance import Provenance, require_admissible
|
||
|
|
|
||
|
|
# A predicate over the independent observations gathered during a run.
|
||
|
|
# It receives the observation mapping and returns True when satisfied.
|
||
|
|
Predicate = Callable[[Mapping[str, object]], bool]
|
||
|
|
|
||
|
|
|
||
|
|
@dataclass(frozen=True, slots=True)
|
||
|
|
class Claim:
|
||
|
|
"""A statement that must hold at a specific point in a scenario."""
|
||
|
|
|
||
|
|
id: str
|
||
|
|
text: str
|
||
|
|
provenance: Provenance
|
||
|
|
predicate: Predicate
|
||
|
|
after_step: str
|
||
|
|
source_ref: str | None = None
|
||
|
|
|
||
|
|
def __post_init__(self) -> None:
|
||
|
|
require_admissible(self.provenance, f"Claim {self.id!r}")
|
||
|
|
|
||
|
|
|
||
|
|
@dataclass(frozen=True, slots=True)
|
||
|
|
class Invariant:
|
||
|
|
"""A statement that must hold after *every* step, not merely at one point."""
|
||
|
|
|
||
|
|
id: str
|
||
|
|
text: str
|
||
|
|
provenance: Provenance
|
||
|
|
predicate: Predicate
|
||
|
|
source_ref: str | None = None
|
||
|
|
|
||
|
|
def __post_init__(self) -> None:
|
||
|
|
require_admissible(self.provenance, f"Invariant {self.id!r}")
|
||
|
|
|
||
|
|
|
||
|
|
@dataclass(frozen=True, slots=True)
|
||
|
|
class UseCase:
|
||
|
|
"""Purposeful behaviour, described independently of mechanics."""
|
||
|
|
|
||
|
|
id: str
|
||
|
|
title: str
|
||
|
|
narrative: str
|
||
|
|
provenance: Provenance
|
||
|
|
claims: tuple[Claim, ...] = field(default_factory=tuple)
|
||
|
|
invariants: tuple[Invariant, ...] = field(default_factory=tuple)
|
||
|
|
source_ref: str | None = None
|
||
|
|
|
||
|
|
def __post_init__(self) -> None:
|
||
|
|
require_admissible(self.provenance, f"UseCase {self.id!r}")
|