← Files LegalQuants TransactionalARCHIVED FILE
skills/definition-check/scripts/definition_check/bundle.py
20.5 KB · Oct 3, 2026 · 06:34 UTC
"""Load and validate bounded agent-review records without mutating a ledger."""
from __future__ import annotations
import json
import math
import re
from dataclasses import dataclass
from pathlib import Path
from typing import Any
from .models import (
CandidateProposal,
ContextRequest,
EvidenceItem,
Finding,
Location,
ReviewTrace,
)
from .occurrence_review import OccurrenceSubmission
from .reference_review import ReferenceSubmission
from .semantic_review import AdjudicationSubmission
_MAX_BUNDLE_BYTES = 10 * 1024 * 1024
AGENT_BUNDLE_SCHEMA_VERSION = "agent-bundle-v1"
_ALLOWED_KEYS = frozenset(
{
"schema_version",
"evidence",
"context_requests",
"candidate_proposals",
"review_traces",
"semantic_findings",
"semantic_adjudications",
"occurrence_adjudications",
"reference_adjudications",
"discovery_review",
}
)
_RECORD_FIELDS = {
"evidence": {
"id",
"location",
"excerpt",
"stance",
"method",
},
"context_requests": {
"id",
"candidate_id",
"request_type",
"query",
"reason",
"requested_by",
"status",
"hop",
"max_results",
"result_evidence_ids",
},
"candidate_proposals": {
"id",
"candidate_id",
"term",
"normalized_term",
"location",
"state",
"agent_role",
"revision",
"rationale_summary",
"confidence",
"definition_text",
"evidence_for",
"evidence_against",
"context_request_ids",
"reason_codes",
"supersedes",
"model_id",
"prompt_version",
},
"review_traces": {
"id",
"subject_type",
"subject_id",
"action",
"agent_role",
"rationale_summary",
"evidence_for",
"evidence_against",
"context_request_ids",
"reason_codes",
"confidence",
"uncertainty",
"model_id",
"prompt_version",
"visibility",
},
"semantic_findings": {
"id",
"rule_id",
"kind",
"severity",
"message",
"normalized_term",
"evidence",
"confidence",
"review_state",
},
"semantic_adjudications": {
"review_id",
"decision",
"evidence_indexes",
"rationale_summary",
"reason_codes",
"confidence",
"agent_role",
"definition_text",
"definition_context_index",
"definition_start",
"definition_end",
"canonical_term",
"model_id",
"prompt_version",
"definition_spans",
"review_reason",
},
"occurrence_adjudications": {
"review_id",
"decision",
"rationale_summary",
"reason_codes",
"confidence",
"agent_role",
"model_id",
"prompt_version",
"review_reason",
},
"reference_adjudications": {
"review_id",
"decision",
"evidence_indexes",
"rationale_summary",
"reason_codes",
"confidence",
"agent_role",
"model_id",
"prompt_version",
"review_reason",
},
}
_REQUIRED_RECORD_FIELDS = {
"evidence": {"id", "location", "excerpt", "stance", "method"},
"context_requests": {
"id",
"candidate_id",
"request_type",
"query",
"reason",
"requested_by",
},
"candidate_proposals": {
"id",
"candidate_id",
"term",
"normalized_term",
"location",
"state",
"agent_role",
"revision",
"rationale_summary",
},
"review_traces": {
"id",
"subject_type",
"subject_id",
"action",
"agent_role",
"rationale_summary",
},
"semantic_findings": {"id", "rule_id", "kind", "severity", "message"},
"semantic_adjudications": {"review_id", "decision", "rationale_summary"},
"occurrence_adjudications": {"review_id", "decision", "rationale_summary"},
"reference_adjudications": {"review_id", "decision", "rationale_summary"},
}
class AgentBundleError(ValueError):
"""Raised when an agent bundle cannot be trusted as structured input."""
@dataclass(frozen=True)
class AgentBundle:
evidence: tuple[EvidenceItem, ...]
context_requests: tuple[ContextRequest, ...]
candidate_proposals: tuple[CandidateProposal, ...]
review_traces: tuple[ReviewTrace, ...]
semantic_findings: tuple[Finding, ...]
semantic_adjudications: tuple[AdjudicationSubmission, ...]
occurrence_adjudications: tuple[OccurrenceSubmission, ...]
reference_adjudications: tuple[ReferenceSubmission, ...]
discovery_review: dict[str, Any] | None = None
def _discovery_review(value: object) -> dict[str, Any]:
"""Read a source-bound record of completed discovery packet responses."""
fields = {"source_sha256", "prompt_sha256", "queue_sha256", "responses"}
if not isinstance(value, dict) or set(value) != fields:
raise AgentBundleError("discovery_review has invalid fields")
for field in fields - {"responses"}:
if not isinstance(value[field], str) or not re.fullmatch(
r"[0-9a-f]{64}", value[field]
):
raise AgentBundleError(f"discovery_review {field} must be a SHA-256 hash")
responses = value["responses"]
if not isinstance(responses, list):
raise AgentBundleError("discovery_review responses must be an array")
seen = set()
for response in responses:
if not isinstance(response, dict) or set(response) != {"packet", "rows"}:
raise AgentBundleError("discovery_review response fields are invalid")
packet = response["packet"]
if (
isinstance(packet, bool)
or not isinstance(packet, int)
or packet < 1
or packet in seen
):
raise AgentBundleError(
"discovery_review packet ordinals must be unique positive integers"
)
if not isinstance(response["rows"], list):
raise AgentBundleError("discovery_review rows must be an array")
seen.add(packet)
# Exact source spans and exhaustive packet coverage are checked against the
# freshly rebuilt discovery manifest by the pipeline, not inferred here.
return value
def _location(value: Any) -> Location:
if not isinstance(value, dict):
raise AgentBundleError("location must be an object")
try:
return Location(
part=str(value["part"]),
block_id=str(value["block_id"]),
block_order=int(value["block_order"]),
char_start=int(value["char_start"]),
char_end=int(value["char_end"]),
)
except (KeyError, TypeError, ValueError) as exc:
raise AgentBundleError("location is invalid") from exc
def _tuple_strings(value: Any, field: str) -> tuple[str, ...]:
if not isinstance(value, list) or any(not isinstance(item, str) for item in value):
raise AgentBundleError(f"{field} must be an array of strings")
if len(value) != len(set(value)):
raise AgentBundleError(f"{field} must not contain duplicates")
return tuple(value)
def _definition_spans(value: Any) -> tuple[tuple[int, int, int], ...]:
if value is None:
return ()
if not isinstance(value, list):
raise AgentBundleError("definition_spans must be an array")
spans = []
for span in value:
if (
not isinstance(span, list)
or len(span) != 3
or any(isinstance(item, bool) or not isinstance(item, int) for item in span)
):
raise AgentBundleError("definition_spans must contain three-integer arrays")
spans.append((span[0], span[1], span[2]))
if len(spans) != len(set(spans)):
raise AgentBundleError("definition_spans must be unique")
return tuple(spans)
def _optional_string(value: Any, field: str) -> str | None:
if value is None:
return None
if not isinstance(value, str):
raise AgentBundleError(f"{field} must be a string or null")
return value
def _optional_confidence(value: Any, field: str = "confidence") -> float | None:
if value is None:
return None
if isinstance(value, bool) or not isinstance(value, int | float):
raise AgentBundleError(f"{field} must be a number between 0 and 1 or null")
number = float(value)
if not math.isfinite(number) or not 0 <= number <= 1:
raise AgentBundleError(f"{field} must be a number between 0 and 1 or null")
return number
def _records(payload: dict[str, Any], field: str) -> list[dict[str, Any]]:
value = payload.get(field, [])
if not isinstance(value, list) or any(not isinstance(item, dict) for item in value):
raise AgentBundleError(f"{field} must be an array of objects")
allowed = _RECORD_FIELDS[field]
required = _REQUIRED_RECORD_FIELDS[field]
for item in value:
extra = set(item) - allowed
missing = required - set(item)
if extra:
raise AgentBundleError(
f"{field} record contains unsupported fields: {sorted(extra)}"
)
if missing:
raise AgentBundleError(
f"{field} record is missing required fields: {sorted(missing)}"
)
return value
def load_agent_bundle(path: str | Path) -> AgentBundle:
source = Path(path)
try:
size = source.stat().st_size
except OSError as exc:
raise AgentBundleError(f"unable to access agent bundle {source!s}") from exc
if size > _MAX_BUNDLE_BYTES:
raise AgentBundleError("agent bundle exceeds the 10 MiB limit")
try:
payload = json.loads(source.read_text(encoding="utf-8-sig"))
except (OSError, UnicodeError, json.JSONDecodeError) as exc:
raise AgentBundleError("agent bundle is not readable UTF-8 JSON") from exc
if not isinstance(payload, dict):
raise AgentBundleError("agent bundle root must be an object")
extra = set(payload) - _ALLOWED_KEYS
if extra:
raise AgentBundleError(
f"agent bundle contains unsupported fields: {sorted(extra)}"
)
if payload.get("schema_version") != AGENT_BUNDLE_SCHEMA_VERSION:
raise AgentBundleError("agent bundle has an unsupported schema_version")
discovery_review = (
_discovery_review(payload["discovery_review"])
if "discovery_review" in payload
else None
)
try:
evidence = tuple(
EvidenceItem(
id=str(item["id"]),
location=_location(item["location"]),
excerpt=str(item["excerpt"]),
stance=str(item["stance"]),
method=str(item["method"]),
)
for item in _records(payload, "evidence")
)
requests = tuple(
ContextRequest(
id=str(item["id"]),
candidate_id=str(item["candidate_id"]),
request_type=str(item["request_type"]),
query=str(item["query"]),
reason=str(item["reason"]),
requested_by=str(item["requested_by"]),
status=str(item.get("status", "requested")),
hop=int(item.get("hop", 1)),
max_results=int(item.get("max_results", 20)),
result_evidence_ids=_tuple_strings(
item.get("result_evidence_ids", []), "result_evidence_ids"
),
)
for item in _records(payload, "context_requests")
)
proposals = tuple(
CandidateProposal(
id=str(item["id"]),
candidate_id=str(item["candidate_id"]),
term=str(item["term"]),
normalized_term=str(item["normalized_term"]),
location=_location(item["location"]),
state=str(item["state"]),
agent_role=str(item["agent_role"]),
revision=int(item["revision"]),
rationale_summary=str(item["rationale_summary"]),
confidence=_optional_confidence(item.get("confidence")),
definition_text=_optional_string(
item.get("definition_text"), "definition_text"
),
evidence_for=_tuple_strings(
item.get("evidence_for", []), "evidence_for"
),
evidence_against=_tuple_strings(
item.get("evidence_against", []), "evidence_against"
),
context_request_ids=_tuple_strings(
item.get("context_request_ids", []), "context_request_ids"
),
reason_codes=_tuple_strings(
item.get("reason_codes", []), "reason_codes"
),
supersedes=_optional_string(item.get("supersedes"), "supersedes"),
model_id=_optional_string(item.get("model_id"), "model_id"),
prompt_version=_optional_string(
item.get("prompt_version"), "prompt_version"
),
)
for item in _records(payload, "candidate_proposals")
)
traces = tuple(
ReviewTrace(
id=str(item["id"]),
subject_type=str(item["subject_type"]),
subject_id=str(item["subject_id"]),
action=str(item["action"]),
agent_role=str(item["agent_role"]),
rationale_summary=str(item["rationale_summary"]),
evidence_for=_tuple_strings(
item.get("evidence_for", []), "evidence_for"
),
evidence_against=_tuple_strings(
item.get("evidence_against", []), "evidence_against"
),
context_request_ids=_tuple_strings(
item.get("context_request_ids", []), "context_request_ids"
),
reason_codes=_tuple_strings(
item.get("reason_codes", []), "reason_codes"
),
confidence=_optional_confidence(item.get("confidence")),
uncertainty=_optional_string(item.get("uncertainty"), "uncertainty"),
model_id=_optional_string(item.get("model_id"), "model_id"),
prompt_version=_optional_string(
item.get("prompt_version"), "prompt_version"
),
visibility=str(item.get("visibility", "internal")),
)
for item in _records(payload, "review_traces")
)
findings = tuple(
Finding(
id=str(item["id"]),
rule_id=str(item["rule_id"]),
kind=str(item["kind"]),
severity=str(item["severity"]),
message=str(item["message"]),
normalized_term=_optional_string(
item.get("normalized_term"), "normalized_term"
),
evidence=tuple(
_location(location) for location in item.get("evidence", [])
),
confidence=_optional_confidence(item.get("confidence")),
review_state=str(item.get("review_state", "open")),
)
for item in _records(payload, "semantic_findings")
)
adjudications = tuple(
AdjudicationSubmission(
review_id=str(item["review_id"]),
decision=str(item["decision"]),
evidence_indexes=tuple(
int(index) for index in item.get("evidence_indexes", [])
),
rationale_summary=str(item["rationale_summary"]),
reason_codes=_tuple_strings(
item.get("reason_codes", []), "reason_codes"
),
confidence=_optional_confidence(item.get("confidence")),
agent_role=str(item.get("agent_role", "semantic_reviewer")),
definition_text=_optional_string(
item.get("definition_text"), "definition_text"
),
definition_context_index=(
int(item["definition_context_index"])
if item.get("definition_context_index") is not None
else None
),
definition_start=(
int(item["definition_start"])
if item.get("definition_start") is not None
else None
),
definition_end=(
int(item["definition_end"])
if item.get("definition_end") is not None
else None
),
canonical_term=_optional_string(
item.get("canonical_term"), "canonical_term"
),
model_id=_optional_string(item.get("model_id"), "model_id"),
prompt_version=_optional_string(
item.get("prompt_version"), "prompt_version"
),
definition_spans=_definition_spans(item.get("definition_spans")),
review_reason=_optional_string(
item.get("review_reason"), "review_reason"
),
)
for item in _records(payload, "semantic_adjudications")
)
occurrence_adjudications = tuple(
OccurrenceSubmission(
review_id=str(item["review_id"]),
decision=str(item["decision"]),
rationale_summary=str(item["rationale_summary"]),
reason_codes=_tuple_strings(
item.get("reason_codes", []), "reason_codes"
),
confidence=_optional_confidence(item.get("confidence")),
agent_role=str(item.get("agent_role", "occurrence_reviewer")),
model_id=_optional_string(item.get("model_id"), "model_id"),
prompt_version=_optional_string(
item.get("prompt_version"), "prompt_version"
),
review_reason=_optional_string(
item.get("review_reason"), "review_reason"
),
)
for item in _records(payload, "occurrence_adjudications")
)
reference_adjudications = tuple(
ReferenceSubmission(
review_id=str(item["review_id"]),
decision=str(item["decision"]),
evidence_indexes=tuple(
int(index) for index in item.get("evidence_indexes", [])
),
rationale_summary=str(item["rationale_summary"]),
reason_codes=_tuple_strings(
item.get("reason_codes", []), "reason_codes"
),
confidence=_optional_confidence(item.get("confidence")),
agent_role=str(item.get("agent_role", "reference_reviewer")),
model_id=_optional_string(item.get("model_id"), "model_id"),
prompt_version=_optional_string(
item.get("prompt_version"), "prompt_version"
),
review_reason=_optional_string(
item.get("review_reason"), "review_reason"
),
)
for item in _records(payload, "reference_adjudications")
)
except (KeyError, TypeError, ValueError) as exc:
if isinstance(exc, AgentBundleError):
raise
raise AgentBundleError(f"agent bundle record is invalid: {exc}") from exc
if any(item.kind != "semantic" for item in findings):
raise AgentBundleError("semantic_findings may contain only semantic findings")
if any(
item.status == "requested" and item.request_type != "escalate_review"
for item in requests
):
raise AgentBundleError(
"non-escalation context requests must be resolved before finalization"
)
if not any(
(
evidence,
requests,
proposals,
traces,
findings,
adjudications,
occurrence_adjudications,
reference_adjudications,
discovery_review,
)
):
raise AgentBundleError("agent bundle must contain at least one review record")
return AgentBundle(
evidence,
requests,
proposals,
traces,
findings,
adjudications,
occurrence_adjudications,
reference_adjudications,
discovery_review,
)
SHA-256: 4db2075e549fe2580169ce22fdeff5bf766eba40ad24720ba9c21f51cfa169a6