fix(registrar): scope identity preflight

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b22-9638-76d2-bbff-b7ea1770b118
This commit is contained in:
tegwick 2026-08-23 11:49:59 +02:00
parent 4398167580
commit 7a15f1da21
4 changed files with 152 additions and 2 deletions

View file

@ -51,6 +51,87 @@ def test_requires_explicit_primary_confirmation(tmp_path: Path) -> None:
assert result.error and result.error["code"] == "confirmation_required"
def test_unrelated_historical_collision_does_not_block_scoped_request(
tmp_path: Path,
) -> None:
repo = _fixture(tmp_path)
for number, task_uuid in (
(2, "22222222-2222-4222-8222-222222222222"),
(3, "33333333-3333-4333-8333-333333333333"),
):
(repo / "workplans" / f"DEMO-WP-000{number}.md").write_text(
f"""---
id: DEMO-WP-000{number}
type: workplan
title: Historical {number}
status: finished
state_hub_workstream_id: "{number}{'1' * 7}-1111-4111-8111-111111111111"
---
## Historical task
```task
id: DEMO-WP-9999-T01
status: done
priority: low
state_hub_task_id: "{task_uuid}"
```
""",
encoding="utf-8",
)
result = rr.registrar_reconcile(repo)
assert result.status == "rejected"
assert result.error and result.error["code"] == "confirmation_required"
assert result.evidence["record_identity"]["identity_collisions"]
assert result.evidence["blocking_identity_collisions"] == []
def test_requested_collision_still_fails_closed(tmp_path: Path) -> None:
repo = _fixture(tmp_path)
second = repo / "workplans" / "DEMO-WP-0002.md"
second.write_text(
"""---
id: DEMO-WP-0002
type: workplan
title: Conflicting request
status: active
---
## Conflicting task
```task
id: DEMO-WP-0001-T01
status: todo
priority: high
```
""",
encoding="utf-8",
)
result = rr.registrar_reconcile(repo)
assert result.status == "rejected"
assert result.error and result.error["code"] == "record_identity_collision"
assert result.evidence["blocking_identity_collisions"][0]["id"] == "DEMO-WP-0001-T01"
def test_requested_invalid_identifier_fails_before_registration(tmp_path: Path) -> None:
repo = _fixture(tmp_path)
workplan = repo / "workplans" / "DEMO-WP-0001.md"
workplan.write_text(
workplan.read_text(encoding="utf-8").replace("DEMO-WP-0001", "DEMO-INVALID"),
encoding="utf-8",
)
result = rr.registrar_reconcile(repo)
assert result.status == "rejected"
assert result.error and result.error["code"] == "record_identifier_invalid"
assert result.evidence["blocking_invalid_identifiers"][0]["id"] == "DEMO-INVALID"
def test_unlinked_closed_workplan_is_registrar_work(tmp_path: Path) -> None:
repo = _fixture(tmp_path)
workplan = repo / "workplans" / "DEMO-WP-0001.md"