Re-open INFD-WP-0002-T03 live accept; keep the sitting unsigned.

audit-core rollout made origin /readyz 200. Remaining gates are the
T03-only Flex Auth package, no approval:create requester for these
eight acts, and a live KeyCape subject. Attach writes bound copies
from a created receipt; it does not bind.

Assistant: grok
Assistant-Session: 01a09dc1-b21e-77e1-919e-fcad2f82b267
This commit is contained in:
tegwick 2026-09-15 00:35:14 +02:00
parent 6a386dd787
commit 6289ecbb68
9 changed files with 367 additions and 51 deletions

View file

@ -0,0 +1,97 @@
import json
from pathlib import Path
import pytest
from informed_decision.records import memo_from
import importlib.util
spec = importlib.util.spec_from_file_location(
"attach_compact_bindings",
Path(__file__).resolve().parents[1] / "tools" / "attach_compact_bindings.py",
)
attach_mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(attach_mod)
def _receipt(memo_ids, *, human_control=True, entries=None, status="requested"):
requests = []
for i, memo_id in enumerate(memo_ids, start=1):
digest = "sha256:" + f"{i:064x}"
requests.append(
{
"memo_id": memo_id,
"approval": {
"id": f"approval-{i:02d}",
"status": status,
"entries": entries or [],
"binding": {"digest": digest, "human_control": human_control},
},
}
)
return {"status": "created", "requests": requests}
def _memo_ids(root):
ids = []
for name in ("credentials", "decisions"):
index = json.loads((root / name / "index.json").read_text())
ids.extend(row["memo_id"] for row in index["ordinal"])
return ids
def test_attach_writes_bound_copies_and_leaves_drafts_unsigned(tmp_path):
src = Path(__file__).resolve().parents[1] / "docs" / "batches" / "2026-09-14"
root = tmp_path / "sitting"
for name in ("credentials", "decisions"):
(root / name).mkdir(parents=True)
for item in (src / name).iterdir():
(root / name / item.name).write_bytes(item.read_bytes())
(root / "sitting.json").write_bytes((src / "sitting.json").read_bytes())
ids = _memo_ids(root)
index = attach_mod.attach("human-subject-1", _receipt(ids), root)
assert index["principal"] == "human-subject-1"
assert len(index["memos"]) == 8
draft = memo_from(json.loads((root / "credentials" / "infd-20260914-c01.memo.json").read_text()))
assert draft.approval_id is None
assert draft.binding.principal.id == "pending-human-session"
bound = memo_from(json.loads((root / "bound" / "infd-20260914-c01.memo.json").read_text()))
assert bound.approval_id == "approval-01"
assert bound.approval_binding_digest.startswith("sha256:")
assert bound.binding.principal.id == "human-subject-1"
assert bound.question == draft.question
@pytest.mark.parametrize(
"fault",
["pending-human-session", "has space", "", "not-created", "wrong-count", "has-entry", "no-control"],
)
def test_attach_refuses_unsafe_inputs(tmp_path, fault):
src = Path(__file__).resolve().parents[1] / "docs" / "batches" / "2026-09-14"
root = tmp_path / "sitting"
for name in ("credentials", "decisions"):
(root / name).mkdir(parents=True)
for item in (src / name).iterdir():
(root / name / item.name).write_bytes(item.read_bytes())
(root / "sitting.json").write_bytes((src / "sitting.json").read_bytes())
ids = _memo_ids(root)
principal = "human-subject-1"
receipt = _receipt(ids)
if fault == "pending-human-session":
principal = "pending-human-session"
elif fault == "has space":
principal = "human subject"
elif fault == "":
principal = ""
elif fault == "not-created":
receipt["status"] = "draft"
elif fault == "wrong-count":
receipt["requests"] = receipt["requests"][:7]
elif fault == "has-entry":
receipt = _receipt(ids, entries=[{"subject_id": "someone"}])
elif fault == "no-control":
receipt = _receipt(ids, human_control=False)
with pytest.raises(ValueError):
attach_mod.attach(principal, receipt, root)
assert not (root / "bound").exists()