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
2026-08-22 23:21:07 +02:00
|
|
|
"""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:
|
2026-09-28 12:06:24 +02:00
|
|
|
"""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.
|
|
|
|
|
"""
|
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
2026-08-22 23:21:07 +02:00
|
|
|
|
|
|
|
|
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}")
|