NK-WP-0056-T11 done: bounded executor core runner

Consumes one admission once through the approval-engine carrier after an
effect-free preflight (validity, source pins, trust, window vs budget,
binding digest, actor, human aal2 approvers), emits run.started, runs steps
with settle-timed checks, reverts on failure with per-revert checks, retries
within attempts, stops on unknown outcomes, honours budget and kill switch,
and emits one value-free receipt (PDP not-evaluated). 22 tests with fakes.
BEA-9 extended to revert steps; examples regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 994874@bnt-lap001
Assistant-Session: 6017c416-d619-47eb-bd1a-f670a02d7d87
This commit is contained in:
tegwick 2026-10-31 16:00:52 +01:00
parent 3b1abc4054
commit d1cf754222
14 changed files with 834 additions and 23 deletions

View file

@ -0,0 +1,372 @@
"""Core runner tests (NK-WP-0056-T11). Fakes only: carrier, operations, checks, trust, audit, clocks."""
from __future__ import annotations
import copy
import datetime as dt
import hashlib
import importlib.util
import json
import pathlib
import sys
import tempfile
import unittest
HERE = pathlib.Path(__file__).resolve().parent
spec = importlib.util.spec_from_file_location("executor", HERE.parent / "executor.py")
X = importlib.util.module_from_spec(spec)
sys.modules["executor"] = X # dataclasses resolve deferred annotations through sys.modules
spec.loader.exec_module(X)
bea = X.bea
PILOT = bea.load(X.REPO / "examples/bounded-execution-admission/bind-rotation-svc-authelia.yaml")
ADMIN_SUB = "kc-sub-0f3a" # opaque KeyCape subject of the human approver `admin`
NOW = dt.datetime(2026, 11, 3, 9, 30, tzinfo=dt.UTC)
SECRET = "synthetic-bind-value-never-emitted"
class Clock:
def __init__(self):
self.t = 0.0
self.sleeps = []
def monotonic(self):
return self.t
def sleep(self, s):
self.sleeps.append(s)
self.t += s
class FakeCarrier:
"""approval-engine's object and consume semantics (store.Approval.as_dict, Engine.consume)."""
def __init__(self, admission, **over):
self.approval = {
"id": "apr-1", "status": "approved",
"binding": {"action": "bounded-execution", "actor": admission["spec"]["executor"]["identity"],
"principal": "admin", "purpose": admission["spec"]["purpose"],
"target": {"admission_id": admission["spec"]["id"],
"admission_digest": bea.admission_digest(admission)},
"human_control": True, "pdp_path": False},
"validity": {"not_before": admission["spec"]["window"]["not_before"],
"expires_at": admission["spec"]["window"]["not_after"]},
"entries": [{"subject_id": ADMIN_SUB, "assurance": "aal2", "principal_type": "human",
"approved_at": "2026-11-03T08:55:00Z"}],
}
for k, v in over.items():
self.approval[k] = v
self.consumes = 0
self.raise_on_consume = False
self.consume_lands = True
def get(self, approval_id):
return copy.deepcopy(self.approval)
def consume(self, approval_id, request_digest, decision_id):
self.consumes += 1
if self.consume_lands:
if self.approval["status"] == "consumed":
same = self.approval["consumption"]["request_digest"] == request_digest
if not same:
raise RuntimeError("409")
return {"approval_id": approval_id, "status": "consumed", "request_digest": request_digest,
"decision_id": self.approval["consumption"].get("decision_id"),
"consumed_at": "x", "idempotent": True}
self.approval["status"] = "consumed"
self.approval["consumption"] = {"request_digest": request_digest, "decision_id": decision_id,
"consumed_at": "2026-11-03T09:30:00Z"}
if self.raise_on_consume:
raise TimeoutError("connection reset")
return {"approval_id": approval_id, "status": "consumed", "request_digest": request_digest,
"decision_id": decision_id, "consumed_at": "2026-11-03T09:30:00Z", "idempotent": False}
class World:
def __init__(self, admission, clock):
self.calls = []
self.fail_check = {} # check id -> number of times to fail
self.raise_op = set() # operation names that raise
self.unknown_op = set()
self.slow_op = 0.0
self.events = []
self.alerts = []
self.audit_down = False
self.stop_after = None
self.clock = clock
self.carrier = FakeCarrier(admission)
self.trust_ok = True
def op(self, step, ctx):
if step["operation"] in self.unknown_op:
raise X.Unknown()
if step["id"] in self.raise_op:
raise RuntimeError("boom")
ctx.data["value"] = SECRET # operations may hold values; the runner must never emit them
self.calls.append(step["id"])
self.clock.t += self.slow_op
def check(self, check, ctx):
self.calls.append("check:" + check["id"])
left = self.fail_check.get(check["id"], 0)
if left:
self.fail_check[check["id"]] = left - 1
return False
return True
def emit(self, event):
if self.audit_down:
raise ConnectionError()
self.events.append(event)
def should_stop(self):
return self.stop_after is not None and len([c for c in self.calls if not c.startswith("check:")]) >= self.stop_after
def deps(self, admission):
ops = {s["operation"]: self.op for s in admission["spec"]["plan"]["steps"] + admission["spec"]["plan"]["revert_steps"]}
checks = {c["id"]: self.check for c in admission["spec"]["checks"]}
audit = type("A", (), {"emit": lambda _s, e: self.emit(e)})()
return X.Deps(carrier=self.carrier, operations=ops, checks=checks, trust=lambda s: self.trust_ok,
audit=audit, alert=lambda kind, info: self.alerts.append(kind),
should_stop=self.should_stop, wall=lambda: NOW,
monotonic=self.clock.monotonic, sleep=self.clock.sleep)
def synthetic_admission(root: pathlib.Path, mutate=None) -> dict:
"""The pilot example, with its pinned files replaced by temporary ones and the digest recomputed."""
doc = copy.deepcopy(PILOT)
files = []
for f in doc["spec"]["plan"]["source"]["files"]:
path = root / f["path"]
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("synthetic " + f["path"])
files.append({"path": f["path"], "sha256": hashlib.sha256(path.read_bytes()).hexdigest()})
doc["spec"]["plan"]["source"]["files"] = files
by_path = {f["path"]: f["sha256"] for f in files}
for c in doc["spec"]["checks"]:
c["sha256"] = by_path[c["ref"]]
if mutate:
mutate(doc["spec"])
doc["spec"]["plan_digest"] = bea.plan_digest(doc)
return doc
class Base(unittest.TestCase):
mutate = None
def setUp(self):
tmp = tempfile.TemporaryDirectory()
self.addCleanup(tmp.cleanup)
self.root = pathlib.Path(tmp.name)
self.doc = synthetic_admission(self.root, self.mutate)
self.clock = Clock()
self.w = World(self.doc, self.clock)
self.cfg = X.Config(executor_identity="service:nk-bind-executor",
runtime_principal="system:serviceaccount:sso:nk-bind-executor",
tenant="tenant:platform", environment="PRODUCTION",
approver_subjects={"admin": ADMIN_SUB}, source_root=self.root)
def run_it(self, doc=None):
doc = doc or self.doc
return X.Run(doc, "apr-1", self.cfg, self.w.deps(doc)).execute()
def ops(self):
return [c for c in self.w.calls if not c.startswith("check:")]
def assert_no_effect(self, result, reason):
self.assertEqual((result["outcome"], result["reason"]), ("refused", reason))
self.assertEqual(self.w.carrier.consumes, 0)
self.assertEqual(self.w.calls, [])
self.assertEqual(self.w.events, [])
class HappyPathTests(Base):
def test_completes_with_started_and_receipt(self):
result = self.run_it()
self.assertEqual(result["outcome"], "completed", result)
self.assertEqual(self.w.carrier.consumes, 1)
self.assertEqual(self.ops(), ["generate", "set-directory", "deliver", "restart"])
self.assertEqual([e["type"] for e in self.w.events], [X.STARTED, X.RECEIPT])
started, receipt = self.w.events
self.assertEqual(started["id"], f"run:{result['run_id']}:started")
data = receipt["data"]
self.assertEqual(data["pdp"], "not-evaluated")
self.assertEqual({r["label"] for r in data["decision_refs"]}, {"admission", "admission_digest", "approval"})
self.assertEqual(data["initiator"]["sub"], ADMIN_SUB)
self.assertEqual(data["artifact_digest"], self.doc["spec"]["plan_digest"])
self.assertFalse(data["reverted"])
self.assertNotIn(SECRET, json.dumps(self.w.events))
def test_consumed_with_admission_digest_and_run_id(self):
result = self.run_it()
consumption = self.w.carrier.approval["consumption"]
self.assertEqual(consumption["request_digest"], bea.admission_digest(self.doc))
self.assertEqual(consumption["decision_id"], result["run_id"])
class RefusalTests(Base):
def test_invalid_admission(self):
doc = copy.deepcopy(self.doc)
doc["spec"]["plan"]["steps"][0]["operation"] = "tampered"
self.w = World(doc, self.clock)
self.assertEqual(self.run_it(doc)["reason"], "admission_invalid:BEA-2")
self.assertEqual(self.w.carrier.consumes, 0)
def test_refusals_before_any_effect(self):
cases = {
"not_this_executor": lambda: setattr(self.cfg, "executor_identity", "service:other"),
"source_drift": lambda: (self.root / "tools/service-binds/bind-lane.py").write_text("changed"),
"trust_not_satisfied:runtime_secret_trust": lambda: setattr(self.w, "trust_ok", False),
"approval_binding": lambda: self.w.carrier.approval["binding"]["target"].update(admission_digest="sha256:" + "0" * 64),
"approval_status": lambda: self.w.carrier.approval.update(status="requested"),
"approval_entry": lambda: self.w.carrier.approval["entries"][0].update(assurance="aal1"),
"approval_expires_before_window_end": lambda: self.w.carrier.approval["validity"].update(expires_at="2026-11-03T10:00:00Z"),
}
for reason, mutate in cases.items():
with self.subTest(reason=reason):
self.setUp()
mutate()
self.assert_no_effect(self.run_it(), reason)
def test_approval_by_someone_not_listed_or_not_human(self):
for entry in ({"subject_id": "kc-sub-other", "assurance": "aal2", "principal_type": "human"},
{"subject_id": ADMIN_SUB, "assurance": "aal2", "principal_type": "service"}):
with self.subTest(entry=entry):
self.setUp()
self.w.carrier.approval["entries"] = [entry]
self.assert_no_effect(self.run_it(), "approval_entry")
def test_actor_must_be_this_executor(self):
self.w.carrier.approval["binding"]["actor"] = "service:someone-else"
self.assert_no_effect(self.run_it(), "approval_binding")
def test_outside_window(self):
self.w.deps = (lambda orig: (lambda doc: (lambda d: (setattr(d, "wall", lambda: NOW + dt.timedelta(hours=3)), d)[1])(orig(doc))))(self.w.deps)
self.assert_no_effect(self.run_it(), "outside_window")
def test_window_too_short_for_the_budget(self):
late = dt.datetime(2026, 11, 3, 10, 50, tzinfo=dt.UTC) # 10 min left, budget 20 min
orig = self.w.deps
self.w.deps = lambda doc: (lambda d: (setattr(d, "wall", lambda: late), d)[1])(orig(doc))
self.assert_no_effect(self.run_it(), "window_shorter_than_budget")
def test_already_consumed_is_never_reused(self):
self.w.carrier.approval["status"] = "consumed"
self.w.carrier.approval["consumption"] = {"request_digest": bea.admission_digest(self.doc), "decision_id": "earlier-run"}
self.assert_no_effect(self.run_it(), "approval_status")
def test_unknown_operation(self):
d = self.w.deps(self.doc)
d.operations.pop("eso.force-sync")
result = X.Run(self.doc, "apr-1", self.cfg, d).execute()
self.assert_no_effect(result, "unknown_operation")
class ConsumeTests(Base):
def test_unclear_consume_resolved_by_reading_back(self):
self.w.carrier.raise_on_consume = True # consume landed, response lost
result = self.run_it()
self.assertEqual(result["outcome"], "completed")
self.assertEqual(self.w.carrier.consumes, 1) # never consumed twice
def test_unclear_consume_that_did_not_land_stops(self):
self.w.carrier.raise_on_consume = True
self.w.carrier.consume_lands = False
result = self.run_it()
self.assertEqual((result["outcome"], result["reason"]), ("refused", "consume_not_confirmed"))
self.assertEqual((self.w.calls, self.w.events), ([], []))
self.assertIn("consume_unconfirmed", self.w.alerts)
def test_idempotent_consume_is_not_a_fresh_run(self):
original = self.w.carrier.consume
self.w.carrier.consume = lambda a, d, r: dict(original(a, d, r), idempotent=True)
result = self.run_it()
self.assertEqual(result["reason"], "consume_response")
self.assertEqual(self.w.calls, [])
def test_no_custody_no_run(self):
self.w.audit_down = True
result = self.run_it()
self.assertEqual((result["outcome"], result["reason"]), ("stopped", "audit_unavailable"))
self.assertEqual(self.w.calls, [])
self.assertIn("started_not_in_custody", self.w.alerts)
class FailureTests(Base):
def test_failed_check_reverts_in_reverse_and_verifies(self):
self.doc = synthetic_admission(self.root, lambda s: s["budget"].update(attempts=1))
self.w = World(self.doc, self.clock)
self.w.fail_check["eso-synced"] = 1
result = self.run_it()
self.assertEqual(result["outcome"], "reverted", result)
self.assertEqual(self.ops(), ["generate", "set-directory", "deliver", "redeliver", "restore-directory", "restore-kv"])
data = result["receipt"]["data"]
self.assertTrue(data["reverted"])
reverts = [x for x in data["steps"] if x["kind"] == "revert"]
self.assertEqual([x["checks"][0]["id"] for x in reverts], ["eso-synced", "bind-signs-in", "kv-advanced"])
self.assertTrue(all(x["outcome"] == "done" for x in reverts))
self.assertEqual(data["attempts"], 1)
def test_clean_revert_may_retry_within_attempts(self):
self.doc = synthetic_admission(self.root, lambda s: s["budget"].update(attempts=2))
self.w = World(self.doc, self.clock)
self.w.fail_check["synthetic-journey"] = 1
result = self.run_it()
self.assertEqual(result["outcome"], "completed")
self.assertEqual(result["receipt"]["data"]["attempts"], 2)
self.assertTrue(result["receipt"]["data"]["reverted"])
def test_revert_whose_check_fails_counts_as_failed(self):
self.doc = synthetic_admission(self.root, lambda s: s["budget"].update(attempts=1))
self.w = World(self.doc, self.clock)
self.w.fail_check["eso-synced"] = 2 # the forward check and the revert's own check
result = self.run_it()
self.assertEqual(result["outcome"], "revert_failed")
self.assertNotIn("restore-directory", self.ops())
def test_failed_revert_stops_and_alerts(self):
self.w.fail_check["eso-synced"] = 1
self.w.raise_op = {"restore-directory"}
result = self.run_it()
self.assertEqual(result["outcome"], "revert_failed")
self.assertIn("revert_failed", self.w.alerts)
self.assertNotIn("restore-kv", self.ops()) # stop at the failed revert, do not continue blindly
def test_unknown_outcome_stops_without_revert(self):
self.w.unknown_op = {"eso.force-sync"}
result = self.run_it()
self.assertEqual(result["outcome"], "unknown")
self.assertEqual(self.ops(), ["generate", "set-directory"])
self.assertFalse(result["receipt"]["data"]["reverted"])
self.assertIn("unknown", self.w.alerts)
def test_budget_exhausted_reverts(self):
self.w.slow_op = 700.0 # wall_time_seconds is 1200
result = self.run_it()
self.assertEqual(result["outcome"], "budget")
self.assertTrue(result["receipt"]["data"]["reverted"])
def test_kill_switch_reverts(self):
self.w.stop_after = 2
result = self.run_it()
self.assertEqual(result["outcome"], "stopped")
self.assertIn("restore-kv", self.ops())
self.assertNotIn("deliver", self.ops())
def test_settle_time_is_waited_and_counted(self):
self.doc = synthetic_admission(self.root, lambda s: s["checks"][3].update(settle_seconds=125))
self.w = World(self.doc, self.clock)
result = self.run_it()
self.assertEqual(result["outcome"], "completed")
self.assertIn(125, self.clock.sleeps)
def test_receipt_custody_failure_is_reported(self):
original = self.w.emit
self.w.emit = lambda e: (original(e) if e["type"] == X.STARTED else (_ for _ in ()).throw(ConnectionError()))
result = self.run_it()
self.assertEqual(result["reason"], "receipt_not_in_custody")
self.assertIn("receipt_not_in_custody", self.w.alerts)
if __name__ == "__main__":
unittest.main()