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:
parent
4398167580
commit
7a15f1da21
4 changed files with 152 additions and 2 deletions
|
|
@ -101,6 +101,42 @@ def _missing_identifiers(repo: Path) -> dict[str, list[str]]:
|
|||
}
|
||||
|
||||
|
||||
def _requested_identity_findings(
|
||||
identity: dict[str, Any],
|
||||
requested: dict[str, list[str]],
|
||||
*,
|
||||
full_repository: bool = False,
|
||||
) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:
|
||||
"""Return invalid IDs and collisions that can affect this invocation.
|
||||
|
||||
Ordinary registrar reconciliation is deliberately scoped to the records
|
||||
missing projection UUIDs. Historical defects elsewhere in the repository
|
||||
remain visible in ``record_identity`` evidence, but cannot prevent safe
|
||||
assignment of an unrelated canonical ID. A full empty-projection rebuild
|
||||
still requires the entire repository identity set to be valid.
|
||||
"""
|
||||
if full_repository:
|
||||
return (
|
||||
list(identity["invalid_identifiers"]),
|
||||
list(identity["identity_collisions"]),
|
||||
)
|
||||
|
||||
requested_by_kind = {
|
||||
"workplan": set(requested["workplans"]),
|
||||
"task": set(requested["tasks"]),
|
||||
"intake": set(requested["intakes"]),
|
||||
"decision": set(requested["decisions"]),
|
||||
}
|
||||
|
||||
def affects_request(item: dict[str, Any]) -> bool:
|
||||
return item.get("id") in requested_by_kind.get(str(item.get("kind")), set())
|
||||
|
||||
return (
|
||||
[item for item in identity["invalid_identifiers"] if affects_request(item)],
|
||||
[item for item in identity["identity_collisions"] if affects_request(item)],
|
||||
)
|
||||
|
||||
|
||||
def _check_git(repo: Path) -> tuple[dict[str, Any], str | None]:
|
||||
status = _git(repo, "status", "--porcelain")
|
||||
if status.returncode != 0:
|
||||
|
|
@ -390,13 +426,30 @@ def registrar_reconcile(
|
|||
"record_identity": identity,
|
||||
}
|
||||
|
||||
if identity["identity_collisions"]:
|
||||
blocking_invalid, blocking_collisions = _requested_identity_findings(
|
||||
identity,
|
||||
before,
|
||||
full_repository=bootstrap_empty_projection,
|
||||
)
|
||||
evidence["blocking_invalid_identifiers"] = blocking_invalid
|
||||
evidence["blocking_identity_collisions"] = blocking_collisions
|
||||
if blocking_invalid:
|
||||
return RegistrarResult(
|
||||
"rejected",
|
||||
evidence,
|
||||
{
|
||||
"code": "record_identifier_invalid",
|
||||
"message": "a requested work-record id is not accepted by the canon registry",
|
||||
},
|
||||
cid,
|
||||
)
|
||||
if blocking_collisions:
|
||||
return RegistrarResult(
|
||||
"rejected",
|
||||
evidence,
|
||||
{
|
||||
"code": "record_identity_collision",
|
||||
"message": "same canonical work-record id has conflicting or incomplete UUID assignments",
|
||||
"message": "a requested canonical work-record id has conflicting or incomplete UUID assignments",
|
||||
},
|
||||
cid,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue