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
76
src/testdriver/drivers.py
Normal file
76
src/testdriver/drivers.py
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
"""Drivers realize semantic actions against a surface.
|
||||
|
||||
A driver knows mechanics. It emits S1 evidence describing *how* it acted and
|
||||
reports which surface it used, but it never reports whether the action was
|
||||
correct — that is S2/S3 and belongs to the observer and the oracle.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Protocol
|
||||
|
||||
from .actions import SemanticAction, Surface
|
||||
from .world import Actor
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class Realization:
|
||||
"""What a driver did, mechanically. Pure S1."""
|
||||
|
||||
surface_id: str
|
||||
mechanics: dict[str, Any]
|
||||
raised: str | None = None
|
||||
|
||||
|
||||
class Driver(Protocol):
|
||||
surface: Surface
|
||||
|
||||
def realize(self, actor: Actor, action: SemanticAction) -> Realization: ...
|
||||
|
||||
|
||||
class UnsupportedAction(Exception):
|
||||
"""The driver has no mechanical implementation for this semantic action."""
|
||||
|
||||
|
||||
class DirectDriver:
|
||||
"""Deterministic driver against the lab's enforcement path.
|
||||
|
||||
This is the T5 Deterministic end of the maturity continuum: a fixed mapping
|
||||
from semantic action to mechanics, with no discovery and no model.
|
||||
"""
|
||||
|
||||
def __init__(self, lab: Any, tokens: dict[str, str]) -> None:
|
||||
self._lab = lab
|
||||
self._tokens = tokens
|
||||
self.surface = Surface(
|
||||
id="api", kind="http-like", description="lab enforcement path"
|
||||
)
|
||||
|
||||
_MAPPING = {
|
||||
"create_resource": ("create_resource", ("resource_id", "content")),
|
||||
"grant_access": ("grant", ("resource_id", "subject_id", "permission")),
|
||||
"revoke_access": ("revoke", ("resource_id", "subject_id")),
|
||||
"read_resource": ("read_resource", ("resource_id",)),
|
||||
}
|
||||
|
||||
def realize(self, actor: Actor, action: SemanticAction) -> Realization:
|
||||
if action.name not in self._MAPPING:
|
||||
raise UnsupportedAction(action.name)
|
||||
action.check_surface(self.surface.id)
|
||||
|
||||
op, arg_names = self._MAPPING[action.name]
|
||||
args = {name: action.args[name] for name in arg_names if name in action.args}
|
||||
token = self._tokens[actor.id]
|
||||
|
||||
mechanics: dict[str, Any] = {
|
||||
"operation": op,
|
||||
"arguments": args,
|
||||
"actor": actor.id,
|
||||
}
|
||||
try:
|
||||
result = self._lab.request(token, op, **args)
|
||||
except Exception as exc: # the SUT refusing is data, not a framework error
|
||||
return Realization(self.surface.id, mechanics, raised=f"{type(exc).__name__}: {exc}")
|
||||
mechanics["result"] = result
|
||||
return Realization(self.surface.id, mechanics)
|
||||
Loading…
Add table
Add a link
Reference in a new issue