T04: deterministic semantic kernel
Alice/Bob/Carol runs end to end, deterministically, replayable from seed. 16 tests pass, no third-party dependencies. - src/testdriver: intent, provenance, world, actions, drivers, observers, oracles, evidence, energy, scenario, runner - lab/minimal.py: the SUT, exposing the independent observation channel required by D-07 - evidence is stratified S1/S2/S3; Runner refuses to attribute S2/S3 to an actor; claims are frozen and provenance-checked at construction - missing evidence yields INCONCLUSIVE, which outranks PASS in the run verdict - EnergyEvents captured, no scoring (H-005 dormant) The observation channel records both stored state and an out-of-band enforcement probe; their disagreement is an invariant and is what detects an authorization defect that leaves the audit trail intact. A seeded RevokeIsCosmetic lab fails the run via both the claim and that invariant. Also closes TD-WP-0001-T02 (stack and commands now exist). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 1629012@bnt-lap001 Assistant-Session: 78d4fb13-8a1e-474b-87a3-9b9261c49a39
This commit is contained in:
parent
8da4c5bf7a
commit
04e9573b5a
42 changed files with 1533 additions and 20 deletions
63
src/testdriver/intent.py
Normal file
63
src/testdriver/intent.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
"""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}")
|
||||
Loading…
Add table
Add a link
Reference in a new issue