A stable agentic realization becomes deterministic code. All four exit criteria met; 163 tests pass. - crystallization.py: trajectory capture, stability assessment requiring the same path across several runs, CrystallizedDriver, pytest codegen - crystallized/test_grant_access.py: generated, runs with no model, carries its lineage in the docstring - descendant preserves the ancestor's oracle set, agrees with it across five lab versions, and still catches a seeded defect - reversibility shown both ways via new M24 (grant endpoint renamed): the frozen descendant fails loudly rather than searching, and the agentic ancestor recovers from the same mutation F-0007 (open): the 54% cost reduction must not be quoted in support of the thesis. The T07 runtime is token-free, so the measured saving is one page fetch, one parse and a two-candidate scoring pass. The saving the concept actually claims - tokens, latency, retry variance - is unmeasured. Together with F-0005 this makes a bounded live-model experiment the highest-value next investment. Assertions in the generated test are imported rather than restated, so it is not fully standalone. Deliberate: paraphrased claims would be a second unverified statement of intent. 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
311 lines
12 KiB
Python
311 lines
12 KiB
Python
"""The test-driver lab — the system under test.
|
|
|
|
Grown from the T04 seed (`lab/minimal.py`, now removed). Users belong to
|
|
tenants, own resources, share them with READ or WRITE permission, and revoke
|
|
that sharing. Every state change is audited.
|
|
|
|
Two access paths exist, and the distinction is the whole point:
|
|
|
|
* the **enforcement path** (`request`) is what an actor uses. It checks
|
|
authorization and can therefore be *wrong* — that is where a seeded
|
|
authorization defect lives.
|
|
* the **observation channel** (`ObservationChannel`) reads stored state directly
|
|
and probes enforcement out-of-band. It is the independent channel required by
|
|
decision D-07.
|
|
|
|
An oracle consulting only stored state would verify test-driver's own
|
|
reimplementation of the rules rather than the system's enforcement of them. An
|
|
oracle consulting only enforcement could not notice that record and enforcement
|
|
disagree. test-driver observes both and treats disagreement as meaningful in
|
|
itself — that disagreement is the precise signature of an authorization defect
|
|
which leaves the audit trail looking correct.
|
|
|
|
Mutations are applied by `lab.mutations.build_lab`, never by editing this file.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import time
|
|
from dataclasses import dataclass, field
|
|
from typing import Any, Callable, Literal
|
|
|
|
Permission = Literal["READ", "WRITE"]
|
|
|
|
BASE_VERSION = "lab-0.2.0"
|
|
|
|
|
|
class Denied(Exception):
|
|
"""The enforcement path refused the request."""
|
|
|
|
def __init__(self, reason: str, status: int = 403) -> None:
|
|
super().__init__(reason)
|
|
self.status = status
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class AuditRecord:
|
|
sequence: int
|
|
event: str
|
|
actor_id: str
|
|
resource_id: str | None = None
|
|
subject_id: str | None = None
|
|
permission: str | None = None
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class User:
|
|
id: str
|
|
tenant_id: str
|
|
token: str
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class LabApp:
|
|
"""In-process resource-sharing service.
|
|
|
|
Mutation hooks are plain attributes holding callables or flags. A mutation
|
|
replaces one, so that every mutated build differs from baseline in exactly
|
|
one named way and the difference is inspectable at runtime.
|
|
"""
|
|
|
|
version: str = f"{BASE_VERSION}-baseline"
|
|
applied_mutations: tuple[str, ...] = ()
|
|
|
|
users: dict[str, User] = field(default_factory=dict)
|
|
_tokens: dict[str, str] = field(default_factory=dict)
|
|
resources: dict[str, dict[str, Any]] = field(default_factory=dict)
|
|
grants: dict[tuple[str, str], Permission] = field(default_factory=dict)
|
|
audit: list[AuditRecord] = field(default_factory=list)
|
|
_seq: int = 0
|
|
|
|
# --- mutation hooks (baseline behaviour) ----------------------------
|
|
may_read: Callable[["LabApp", str, str], bool] | None = None
|
|
grant_permission_for: Callable[[str | None], Permission] | None = None
|
|
audit_revoke: bool = True
|
|
revoke_delay_seconds: float = 0.0
|
|
denied_status: int = 403
|
|
require_share_acceptance: bool = False
|
|
enforce_tenant_isolation: bool = True
|
|
response_id_field: str = "resource_id"
|
|
latency_seconds: float = 0.0
|
|
|
|
# --- presentation hooks (surface only; never affect domain semantics) ---
|
|
ui_share_control: str = "inline"
|
|
ui_dom_style: str = "flat"
|
|
ui_labels: str = "plain"
|
|
ui_field_order: str = "natural"
|
|
ui_button_element: str = "button"
|
|
ui_test_ids: str = "stable"
|
|
ui_field_names: str = "canonical"
|
|
ui_confirm_revoke: bool = False
|
|
api_path_style: str = "long"
|
|
api_grant_path: str = "grant"
|
|
tenant_sharing_announced: bool = False
|
|
|
|
# -- setup -----------------------------------------------------------
|
|
|
|
def add_user(self, user_id: str, tenant_id: str = "t-acme") -> str:
|
|
token = f"tok-{user_id}"
|
|
self.users[user_id] = User(user_id, tenant_id, token)
|
|
self._tokens[token] = user_id
|
|
return token
|
|
|
|
def _audit(self, event: str, actor_id: str, **kw: Any) -> None:
|
|
self._seq += 1
|
|
self.audit.append(AuditRecord(self._seq, event, actor_id, **kw))
|
|
|
|
def _whoami(self, token: str) -> str:
|
|
if token not in self._tokens:
|
|
raise Denied("unknown token", status=401)
|
|
return self._tokens[token]
|
|
|
|
def tenant_of(self, user_id: str) -> str | None:
|
|
user = self.users.get(user_id)
|
|
return user.tenant_id if user else None
|
|
|
|
# -- enforcement path (what actors use) ------------------------------
|
|
|
|
def request(self, token: str, op: str, **args: Any) -> Any:
|
|
"""The single entry point actors go through. Authorization is enforced here."""
|
|
if self.latency_seconds:
|
|
time.sleep(self.latency_seconds)
|
|
user_id = self._whoami(token)
|
|
handler = getattr(self, f"_op_{op}", None)
|
|
if handler is None:
|
|
raise Denied(f"unknown operation {op!r}", status=404)
|
|
return handler(user_id, **args)
|
|
|
|
def _op_create_resource(self, user_id: str, resource_id: str, content: str) -> dict:
|
|
self.resources[resource_id] = {"owner": user_id, "content": content}
|
|
self._audit("create", user_id, resource_id=resource_id)
|
|
return {self.response_id_field: resource_id}
|
|
|
|
def _op_read_resource(self, user_id: str, resource_id: str) -> dict:
|
|
resource = self.resources.get(resource_id)
|
|
if resource is None:
|
|
raise Denied("no such resource", status=404)
|
|
if not self._may_read(user_id, resource_id):
|
|
raise Denied("not authorized to read", status=self.denied_status)
|
|
return {self.response_id_field: resource_id, "content": resource["content"]}
|
|
|
|
def _op_write_resource(self, user_id: str, resource_id: str, content: str) -> dict:
|
|
resource = self.resources.get(resource_id)
|
|
if resource is None:
|
|
raise Denied("no such resource", status=404)
|
|
if not self._may_write(user_id, resource_id):
|
|
raise Denied("not authorized to write", status=self.denied_status)
|
|
resource["content"] = content
|
|
self._audit("write", user_id, resource_id=resource_id)
|
|
return {"written": True}
|
|
|
|
def _op_grant(
|
|
self,
|
|
user_id: str,
|
|
resource_id: str,
|
|
subject_id: str,
|
|
permission: Permission | None = None,
|
|
) -> dict:
|
|
resource = self.resources.get(resource_id)
|
|
if resource is None or resource["owner"] != user_id:
|
|
raise Denied("only the owner may grant")
|
|
if self.enforce_tenant_isolation:
|
|
if self.tenant_of(subject_id) != self.tenant_of(user_id):
|
|
raise Denied("cross-tenant sharing is not permitted")
|
|
effective = (
|
|
self.grant_permission_for(permission)
|
|
if self.grant_permission_for
|
|
else (permission or "READ")
|
|
)
|
|
self.grants[(resource_id, subject_id)] = effective
|
|
if self.require_share_acceptance:
|
|
self.resources[resource_id].setdefault("pending", set()).add(subject_id)
|
|
self._audit(
|
|
"grant", user_id, resource_id=resource_id,
|
|
subject_id=subject_id, permission=effective,
|
|
)
|
|
return {"granted": effective}
|
|
|
|
def _op_accept_share(self, user_id: str, resource_id: str) -> dict:
|
|
pending = self.resources.get(resource_id, {}).get("pending")
|
|
if pending:
|
|
pending.discard(user_id)
|
|
self._audit("accept", user_id, resource_id=resource_id, subject_id=user_id)
|
|
return {"accepted": True}
|
|
|
|
def _op_revoke(self, user_id: str, resource_id: str, subject_id: str) -> dict:
|
|
resource = self.resources.get(resource_id)
|
|
if resource is None or resource["owner"] != user_id:
|
|
raise Denied("only the owner may revoke")
|
|
if self.revoke_delay_seconds:
|
|
self.resources[resource_id].setdefault("revoke_after", {})[subject_id] = (
|
|
time.monotonic() + self.revoke_delay_seconds
|
|
)
|
|
else:
|
|
self.grants.pop((resource_id, subject_id), None)
|
|
if self.audit_revoke:
|
|
self._audit("revoke", user_id, resource_id=resource_id, subject_id=subject_id)
|
|
return {"revoked": True}
|
|
|
|
def _may_read(self, user_id: str, resource_id: str) -> bool:
|
|
"""Authorization as the system actually enforces it."""
|
|
if self.may_read is not None:
|
|
return self.may_read(self, user_id, resource_id)
|
|
return self.baseline_may_read(user_id, resource_id)
|
|
|
|
def _may_write(self, user_id: str, resource_id: str) -> bool:
|
|
resource = self.resources.get(resource_id)
|
|
if resource is None:
|
|
return False
|
|
if resource["owner"] == user_id:
|
|
return True
|
|
return self.grants.get((resource_id, user_id)) == "WRITE"
|
|
|
|
def baseline_may_read(self, user_id: str, resource_id: str) -> bool:
|
|
resource = self.resources.get(resource_id)
|
|
if resource is None:
|
|
return False
|
|
if resource["owner"] == user_id:
|
|
return True
|
|
deadline = resource.get("revoke_after", {}).get(user_id)
|
|
if deadline is not None and time.monotonic() < deadline:
|
|
return True # revocation is scheduled but not yet effective
|
|
if user_id in resource.get("pending", set()):
|
|
return False
|
|
return (resource_id, user_id) in self.grants
|
|
|
|
|
|
class ObservationChannel:
|
|
"""Independent read access to lab state — decision D-07.
|
|
|
|
Bypasses authorization deliberately. This is the channel test-driver requires
|
|
of any system under test, and the main integration burden the framework
|
|
imposes on an adopter.
|
|
"""
|
|
|
|
def __init__(self, app: LabApp) -> None:
|
|
self._app = app
|
|
|
|
@property
|
|
def version(self) -> str:
|
|
return self._app.version
|
|
|
|
def state_permission(self, user_id: str, resource_id: str) -> str | None:
|
|
"""What the stored record says, independent of any enforcement decision."""
|
|
resource = self._app.resources.get(resource_id)
|
|
if resource is None:
|
|
return None
|
|
if resource["owner"] == user_id:
|
|
return "OWNER"
|
|
return self._app.grants.get((resource_id, user_id))
|
|
|
|
def probe_read(self, user_id: str, resource_id: str) -> bool:
|
|
"""Exercise the enforcement path out-of-band and report what it did.
|
|
|
|
This uses the subject's own credentials, which can look like a violation
|
|
of actor isolation but is not: independence means the *actor's report* is
|
|
never the evidence. The observer issues its own request and records the
|
|
raw outcome. No actor is ever asked whether it succeeded.
|
|
"""
|
|
user = self._app.users.get(user_id)
|
|
if user is None:
|
|
return False
|
|
try:
|
|
self._app.request(user.token, "read_resource", resource_id=resource_id)
|
|
except Denied:
|
|
return False
|
|
return True
|
|
|
|
def probe_write(self, user_id: str, resource_id: str) -> bool:
|
|
"""Out-of-band probe of the write path, non-destructive on refusal."""
|
|
user = self._app.users.get(user_id)
|
|
if user is None:
|
|
return False
|
|
original = self._app.resources.get(resource_id, {}).get("content")
|
|
try:
|
|
self._app.request(
|
|
user.token, "write_resource", resource_id=resource_id, content=original
|
|
)
|
|
except Denied:
|
|
return False
|
|
return True
|
|
|
|
def audit_events(self, resource_id: str) -> list[dict[str, Any]]:
|
|
return [
|
|
{
|
|
"sequence": r.sequence,
|
|
"event": r.event,
|
|
"actor_id": r.actor_id,
|
|
"subject_id": r.subject_id,
|
|
"permission": r.permission,
|
|
}
|
|
for r in self._app.audit
|
|
if r.resource_id == resource_id
|
|
]
|
|
|
|
|
|
def build_baseline() -> tuple[LabApp, dict[str, str]]:
|
|
"""Known initial state, so that runs replay from the same starting point."""
|
|
app = LabApp()
|
|
tokens = {u: app.add_user(u) for u in ("alice", "bob", "carol")}
|
|
tokens["mallory"] = app.add_user("mallory", tenant_id="t-other")
|
|
return app, tokens
|