T05: the lab and its labelled mutation catalogue

lab/app.py (users, tenants, auth, resources, sharing, read/write, revoke,
audit), lab/http_api.py (JSON API + browser UI, stdlib only), 20 labelled
composable version-stamped mutations, ground-truth matrix. 48 tests pass.

Detection against the reference scenario: MECHANICAL 0/10 flagged (correct),
DEFECT 6/6, SEMANTIC 2/4 with both inert cases declared.

- F-0002: M16 and M18 initially escaped detection entirely. A use case
  protects exactly what it asserts. Resolved by adding two claims already
  stated as intent in INTENT.md; the six-mutation catalogue would never have
  surfaced this.
- test-id axis added: stable selectors survive most UI mutations, which would
  make H-001 trivially false. Mutations now vary on preserves_test_ids so the
  hypothesis is analysed split by that axis rather than rigged.
- M12 (semantic deferred revoke) and M19 (defect race) are behaviourally
  identical and asserted as such - the discrimination problem as a test.

lab/minimal.py removed; superseded by lab/app.py.

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:
tegwick 2026-08-22 23:31:22 +02:00
parent 4d3421ca57
commit 4ddb2f896c
22 changed files with 1091 additions and 207 deletions

View file

@ -10,8 +10,8 @@ from testdriver import Runner, Stratum, Verdict
from scenarios.alice_bob_carol import build
def run_once(variant: str = "baseline"):
world, driver, observer, asset, oracle = build(variant)
def run_once(*mutations: str):
world, driver, observer, asset, oracle = build(*mutations)
return Runner(world, driver, observer, oracle).run(asset), world
@ -52,7 +52,7 @@ def test_evidence_is_stratified_and_serializable():
assert pack.of_stratum(Stratum.JUDGMENT)
parsed = json.loads(pack.to_json())
assert parsed["run_id"] == result.run_id
assert parsed["sut_version"] == "lab-0.1.0-baseline"
assert parsed["sut_version"] == "lab-0.2.0-baseline"
def test_evidence_records_claim_provenance():