Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e76f-be98-7ae3-965d-e0b31290a4c4
68 lines
2.1 KiB
Python
68 lines
2.1 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.
|
|
|
|
Public contract (TD-WP-0003-T05): predicates remain Python callables over
|
|
independent snapshots. Generated tests import these original claims; no
|
|
serialized claim language is promised. See TestDriverGeneralisationReview.
|
|
"""
|
|
|
|
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}")
|