Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a1468b-63fa-7710-85dc-8f2e16b3ebfa
113 lines
4.7 KiB
Python
113 lines
4.7 KiB
Python
"""Synthetic attended admission/dispatch regressions; no owner/native actions."""
|
|
from dataclasses import replace
|
|
|
|
import pytest
|
|
|
|
from tests.test_case_admission_modes import admit, mode_step
|
|
from tests.test_case_run import fixture_catalog, lane_entry, make_rig
|
|
from warden.case_receipt_state import Outcome, Refused
|
|
from warden.case_type import check_follow_through
|
|
from warden.routing.catalog import CatalogError, _parse_entry, load_catalog
|
|
|
|
|
|
def attended(rig, entries):
|
|
return admit(rig, step=mode_step(False, True), entries=entries,
|
|
desc=dict(effect="change", revocation_scopes=("parent-session",)))
|
|
|
|
|
|
@pytest.mark.parametrize("operation", ["run", "rollback", "reconcile"])
|
|
@pytest.mark.parametrize("marker", ["agent-1", "", None])
|
|
def test_identity_change_refuses_before_any_write_or_callback(tmp_path, monkeypatch, operation, marker):
|
|
monkeypatch.delenv("WARDEN_AGENT_ID", raising=False)
|
|
rig = make_rig(tmp_path)
|
|
executor = rig[0]
|
|
admitted = attended(rig, [dict(lane_entry(), lane="login")])
|
|
executor.evidence_verifier = lambda *_: True
|
|
if operation == "rollback":
|
|
executor.run(*admitted)
|
|
elif operation == "reconcile":
|
|
old = executor.adapters[admitted[0].adapter]
|
|
def lost(_):
|
|
raise RuntimeError("synthetic lost reply")
|
|
executor.adapters[old.reference] = replace(old, invoke=lost)
|
|
executor.run(*admitted)
|
|
calls = []
|
|
old = executor.adapters[admitted[0].adapter]
|
|
callback = getattr(old, "invoke" if operation == "run" else operation)
|
|
def observed(*args):
|
|
calls.append(args)
|
|
return callback(*args)
|
|
executor.adapters[old.reference] = replace(old, **{
|
|
"invoke" if operation == "run" else operation: observed,
|
|
})
|
|
def rows():
|
|
return tuple(executor.journal.db.execute(f"SELECT COUNT(*) FROM {table}").fetchone()[0]
|
|
for table in ("intents", "receipts"))
|
|
before = rows()
|
|
if marker is None:
|
|
result = getattr(executor, operation)(*admitted)
|
|
assert result.last.outcome is {"run": Outcome.SUCCESS,
|
|
"rollback": Outcome.ROLLED_BACK,
|
|
"reconcile": Outcome.NO_CHANGE}[operation]
|
|
assert len(calls) == 1
|
|
assert rows() != before
|
|
return
|
|
monkeypatch.setenv("WARDEN_AGENT_ID", marker)
|
|
with pytest.raises(Refused, match="attended step requires a human parent session"):
|
|
getattr(executor, operation)(*admitted)
|
|
assert rows() == before
|
|
assert not calls
|
|
|
|
|
|
def entries_for(case):
|
|
change = dict(lane_entry(), lane="attended-change", session_lane="login-lane")
|
|
login = dict(lane_entry("login-lane"), lane="login")
|
|
if case == "missing":
|
|
return [change]
|
|
if case == "draft-login":
|
|
login["status"] = "draft"
|
|
elif case == "unreviewed-login":
|
|
login["reviewed"] = ""
|
|
elif case == "wrong-kind-login":
|
|
login["lane"] = "secret"
|
|
elif case == "draft-change":
|
|
change["status"] = "draft"
|
|
elif case == "unreviewed-change":
|
|
change["reviewed"] = ""
|
|
elif case == "missing-session-field":
|
|
del change["session_lane"]
|
|
elif case in ("secret", "ceremony"):
|
|
change["lane"] = case
|
|
del change["session_lane"]
|
|
return [change, login]
|
|
|
|
|
|
@pytest.mark.parametrize("case, code", [
|
|
("valid", None), ("missing", "LANE-KIND"), ("draft-login", "LANE-KIND"),
|
|
("unreviewed-login", "LANE-KIND"), ("wrong-kind-login", "LANE-KIND"),
|
|
("draft-change", "LANE-UNREVIEWED"), ("unreviewed-change", "LANE-UNREVIEWED"),
|
|
("secret", "LANE-KIND"), ("ceremony", "LANE-KIND"),
|
|
])
|
|
def test_attended_change_planner_and_executor_agree(tmp_path, monkeypatch, case, code):
|
|
monkeypatch.delenv("WARDEN_AGENT_ID", raising=False)
|
|
entries = entries_for(case)
|
|
path = tmp_path / "catalog.yaml"
|
|
path.write_bytes(fixture_catalog(*entries))
|
|
catalog = load_catalog(path)
|
|
step = dict(mode_step(False, True)[0], attended_justification="synthetic test",
|
|
entry_point="owner/test", auth="synthetic session", value_handling="none")
|
|
doc = {"spec": {"follow_through": [step], "rollback": [{"reverses": step["id"]}]}}
|
|
report = check_follow_through(doc, catalog)
|
|
assert [f.code for f in report.findings] == ([] if code is None else [code])
|
|
rig = make_rig(tmp_path)
|
|
if code:
|
|
with pytest.raises(Refused):
|
|
attended(rig, entries)
|
|
assert rig[0].journal.db.execute("SELECT COUNT(*) FROM receipts").fetchone()[0] == 0
|
|
else:
|
|
assert attended(rig, entries)[1].lane == "issuer-lane"
|
|
|
|
|
|
def test_attended_change_missing_session_is_parser_rejection():
|
|
with pytest.raises(CatalogError, match="must name session_lane"):
|
|
_parse_entry(entries_for("missing-session-field")[0], 0)
|