Files
ai-contract-platform/yuqei-infra/scripts/multiscene_call_ledger.py
T

867 lines
44 KiB
Python

"""Small local recovery ledger for bounded multi-scene provider runs.
SHA-256 values bind frozen inputs for reproducibility; they are not signatures
and provide no caller authentication or tamper-proof evidence. The ledger
prevents accidental duplicate calls and coordinates cooperating local runners.
"""
from __future__ import annotations
import hashlib
import json
import os
import re
import stat
from contextlib import contextmanager
from pathlib import Path
from typing import Iterator, Mapping
from uuid import uuid4
OPERATIONS = (
"draft", "semantic_review", "repair_draft", "repair_review",
"specialist_review", "intake",
)
TERMINAL_STATUSES = frozenset({"succeeded", "failed", "cancelled"})
MAX_PREALLOCATED_ATTEMPTS = 280
MAX_REPAIR_ATTEMPTS = 16
REPAIR_OPERATIONS = frozenset({"repair_draft", "repair_review"})
_ID_RE = re.compile(r"[A-Za-z0-9][A-Za-z0-9._-]{0,127}\Z")
_SHA_RE = re.compile(r"[0-9a-f]{64}\Z")
class CallLedgerError(RuntimeError):
pass
class LedgerBusyError(CallLedgerError):
pass
class LedgerIdentityError(CallLedgerError):
pass
class CallLedger:
def __init__(self, output_dir: str | Path, plan_sha256: str,
operation_limits: Mapping[str, int], case_limits: Mapping[str, int],
source_pins: Mapping[str, str], real_provider: bool,
historical_usage: Mapping[str, object] | None = None,
registry_root: str | Path | None = None) -> None:
requested_output = Path(output_dir).absolute()
_reject_path_chain(requested_output, "output directory")
self.output_dir = requested_output.resolve()
self.plan_sha256 = _sha(plan_sha256, "plan_sha256")
if not isinstance(real_provider, bool):
raise TypeError("real_provider must be bool")
self.operation_limits = _limits(operation_limits, operations=True)
self.case_limits = _limits(case_limits, operations=False)
if not self.operation_limits or not self.case_limits:
raise ValueError("operation_limits and case_limits must be non-empty")
if (sum(self.operation_limits.values()) > MAX_PREALLOCATED_ATTEMPTS
or sum(self.case_limits.values()) > MAX_PREALLOCATED_ATTEMPTS):
raise ValueError("preallocated attempt budgets exceed the 280-call safety ceiling")
if sum(self.operation_limits.get(name, 0) for name in REPAIR_OPERATIONS) > MAX_REPAIR_ATTEMPTS:
raise ValueError("preallocated repair budgets exceed the 16-call safety ceiling")
if not isinstance(source_pins, Mapping) or not source_pins:
raise ValueError("source_pins must be a non-empty mapping")
self.source_pins: dict[str, str] = {}
for name, digest in source_pins.items():
if not isinstance(name, str) or not name or len(name) > 512 or "\x00" in name:
raise ValueError("source pin names must be bounded strings")
self.source_pins[name] = _sha(digest, "source pin")
self.real_provider = real_provider
self.historical_usage = _historical_usage(historical_usage)
if registry_root is not None:
if not real_provider or historical_usage is None:
raise ValueError("global registry is only valid for a receipt-bound real run")
requested_registry = Path(registry_root).absolute()
_reject_path_chain(requested_registry, "global registry")
if not requested_registry.is_dir():
raise ValueError("global registry root must be a pre-created directory")
self.registry_root = requested_registry.resolve()
run_key = _digest({
"plan_sha256": self.plan_sha256,
"historical_receipt_sha256": self.historical_usage["receipt_sha256"],
})
self.root = self.registry_root / run_key
self.campaign_identity = {
"schema_version": "multiscene-call-campaign.v1",
"campaign_id": "rc05-real-usage-v1",
"historical_receipt_sha256": self.historical_usage["receipt_sha256"],
"historical_attempts_sha256": self.historical_usage["attempts_sha256"],
"historical_provider_call_count": self.historical_usage["provider_call_count"],
"historical_repair_budget_charged": self.historical_usage["repair_budget_charged"],
"provider_call_limit": MAX_PREALLOCATED_ATTEMPTS,
"repair_call_limit": MAX_REPAIR_ATTEMPTS,
}
self.campaign_identity_sha256 = _digest(self.campaign_identity)
self.campaign_attempts = self.registry_root / "campaign-attempts"
authority = {
"mode": "global_registry",
"registry_root": str(self.registry_root),
"run_key": run_key,
# A plan/receipt pair has one evidence output. Binding the path
# in the immutable identity makes a fresh output-dir fork fail.
"bound_output_dir": str(self.output_dir),
}
else:
self.registry_root = None
self.campaign_identity = None
self.campaign_identity_sha256 = None
self.campaign_attempts = None
self.root = self.output_dir / ".call-ledger"
authority = {
"mode": "output_local",
"bound_output_dir": str(self.output_dir),
}
self.attempts = self.root / "attempts"
self.case_outcomes = self.root / "case-outcomes"
self.lock_path = ((self.registry_root / ".lock")
if self.registry_root is not None else self.root / ".lock")
self.identity = {
"schema_version": "multiscene-call-ledger.v1",
"plan_sha256": self.plan_sha256,
"operation_limits": {name: self.operation_limits.get(name, 0) for name in OPERATIONS},
"case_limits": dict(sorted(self.case_limits.items())),
"source_pins": dict(sorted(self.source_pins.items())),
"real_provider": real_provider,
"authority": authority,
"integrity_not_authentication": True,
}
if historical_usage is not None:
self.identity["historical_usage"] = self.historical_usage
self.identity_sha256 = _digest(self.identity)
if self.registry_root is not None:
_reject_path_chain(self.registry_root, "global registry")
_reject_link_or_reparse(self.root, "global run ledger")
else:
self.output_dir.mkdir(parents=True, exist_ok=True)
_reject_link_or_reparse(self.output_dir, "output directory")
_reject_link_or_reparse(self.root, "ledger directory")
self.root.mkdir(exist_ok=True)
_reject_link_or_reparse(self.root, "ledger directory")
with self._locked():
if self.registry_root is not None:
campaign_identity_path = self.registry_root / "campaign-identity.json"
_reject_link_or_reparse(campaign_identity_path, "campaign identity")
if campaign_identity_path.exists():
if _read_json(campaign_identity_path) != self.campaign_identity:
raise LedgerIdentityError(
"global campaign is already bound to a different historical receipt"
)
if (not self.campaign_attempts.is_dir()
or self.campaign_attempts.is_symlink()):
raise LedgerIdentityError("global campaign attempt journal is missing")
else:
unexpected = [entry.name for entry in self.registry_root.iterdir()
if entry.name != ".lock"]
if unexpected:
raise LedgerIdentityError(
"uninitialized global campaign registry must be empty"
)
_write_x(campaign_identity_path, self.campaign_identity)
self.campaign_attempts.mkdir()
_reject_link_or_reparse(self.campaign_attempts, "campaign attempt directory")
_reject_link_or_reparse(self.root, "global run ledger")
self.root.mkdir(exist_ok=True)
_reject_link_or_reparse(self.root, "global run ledger")
identity_path = self.root / "identity.json"
_reject_link_or_reparse(identity_path, "ledger identity")
if identity_path.exists():
if _read_json(identity_path) != self.identity:
raise LedgerIdentityError("ledger identity does not match the frozen run")
else:
_write_x(identity_path, self.identity)
_reject_link_or_reparse(self.attempts, "attempt directory")
self.attempts.mkdir(exist_ok=True)
_reject_link_or_reparse(self.attempts, "attempt directory")
_reject_link_or_reparse(self.case_outcomes, "case outcome directory")
self.case_outcomes.mkdir(exist_ok=True)
_reject_link_or_reparse(self.case_outcomes, "case outcome directory")
# Create the output only after the global identity accepted this exact
# path. A competing fresh output therefore cannot leave a fork behind.
self.output_dir.mkdir(parents=True, exist_ok=True)
_reject_link_or_reparse(self.output_dir, "output directory")
def claim(self, case_id: str, operation: str, request_sha256: str) -> str:
case_id = _identifier(case_id, "case_id")
if case_id not in self.case_limits:
raise CallLedgerError("case is not in the frozen ledger limits")
if operation not in OPERATIONS or operation not in self.operation_limits:
raise CallLedgerError("operation is not enabled for this ledger")
request_sha256 = _sha(request_sha256, "request_sha256")
stem = f"{case_id}--{operation}"
with self._locked():
records = self._records()
campaign_records = self._campaign_records() if self.registry_root is not None else records
if (case_id, operation) in records:
raise CallLedgerError("case operation was already attempted")
operation_count = sum(1 for case, op in records if op == operation)
case_count = sum(1 for case, _op in records if case == case_id)
if len(campaign_records) + self.historical_usage["provider_call_count"] >= MAX_PREALLOCATED_ATTEMPTS:
raise CallLedgerError("global attempt budget including historical usage is exhausted")
if operation in REPAIR_OPERATIONS:
repair_count = sum(
1 for record in campaign_records.values()
if record["claim"]["operation"] in REPAIR_OPERATIONS
)
if repair_count + self.historical_usage["repair_budget_charged"] >= MAX_REPAIR_ATTEMPTS:
raise CallLedgerError("repair attempt budget including historical usage is exhausted")
if operation_count >= self.operation_limits[operation]:
raise CallLedgerError("operation attempt budget is exhausted")
if case_count >= self.case_limits[case_id]:
raise CallLedgerError("case attempt budget is exhausted")
claim_id = uuid4().hex
claim_payload = {
"schema_version": "multiscene-call-claim.v1",
"ledger_identity_sha256": self.identity_sha256,
"claim_id": claim_id,
"case_id": case_id,
"operation": operation,
"request_sha256": request_sha256,
"attempt_number": 1,
}
if self.registry_root is not None:
campaign_key = _digest({"plan_sha256": self.plan_sha256,
"case_id": case_id, "operation": operation})
_write_x(self.campaign_attempts / f"{campaign_key}.claim.json", {
"schema_version": "multiscene-campaign-claim.v1",
"campaign_identity_sha256": self.campaign_identity_sha256,
"ledger_identity_sha256": self.identity_sha256,
"claim_id": claim_id, "plan_sha256": self.plan_sha256,
"case_id": case_id, "operation": operation,
"request_sha256": request_sha256,
})
_write_x(self.attempts / f"{stem}.claim.json", claim_payload)
return claim_id
def finish(self, token: str, status: str, response_sha256: str | None = None) -> None:
if not isinstance(token, str) or not re.fullmatch(r"[0-9a-f]{32}", token):
raise CallLedgerError("invalid claim token")
if status not in TERMINAL_STATUSES:
raise CallLedgerError("invalid terminal status")
if response_sha256 is not None:
response_sha256 = _sha(response_sha256, "response_sha256")
with self._locked():
records = self._records()
matches = [(key, value) for key, value in records.items()
if value["claim"]["claim_id"] == token]
if len(matches) != 1:
raise CallLedgerError("claim token is unknown")
(case_id, operation), record = matches[0]
if record["finish"] is not None:
raise CallLedgerError("claim already has an immutable terminal record")
finish_payload = {
"schema_version": "multiscene-call-finish.v1",
"ledger_identity_sha256": self.identity_sha256,
"claim_id": token,
"case_id": case_id,
"operation": operation,
"status": status,
"response_sha256": response_sha256,
}
if self.registry_root is not None:
campaign_records = self._campaign_records()
campaign_match = [item for item in campaign_records.values()
if item["claim"]["claim_id"] == token]
if len(campaign_match) != 1 or campaign_match[0]["finish"] is not None:
raise CallLedgerError("global campaign claim is missing or already finished")
campaign_key = _digest({"plan_sha256": self.plan_sha256,
"case_id": case_id, "operation": operation})
_write_x(self.campaign_attempts / f"{campaign_key}.finish.json", {
"schema_version": "multiscene-campaign-finish.v1",
"campaign_identity_sha256": self.campaign_identity_sha256,
"ledger_identity_sha256": self.identity_sha256,
"claim_id": token, "plan_sha256": self.plan_sha256,
"case_id": case_id, "operation": operation,
"status": status, "response_sha256": response_sha256,
})
_write_x(self.attempts / f"{case_id}--{operation}.finish.json", finish_payload)
def snapshot(self) -> dict:
with self._locked():
records = self._records()
operations = {}
for operation in OPERATIONS:
relevant = [record for (case, op), record in records.items() if op == operation]
terminal = sum(record["finish"] is not None for record in relevant)
operations[operation] = {
"limit": self.operation_limits.get(operation, 0),
"attempted": len(relevant), "terminal": terminal,
"unknown": len(relevant) - terminal,
}
cases = {}
for case_id, limit in sorted(self.case_limits.items()):
relevant = [record for (case, _op), record in records.items() if case == case_id]
terminal = sum(record["finish"] is not None for record in relevant)
cases[case_id] = {"limit": limit, "attempted": len(relevant),
"terminal": terminal, "unknown": len(relevant) - terminal}
attempted = len(records)
campaign_records = self._campaign_records() if self.registry_root is not None else records
campaign_attempted = len(campaign_records)
campaign_terminal = sum(
record["finish"] is not None for record in campaign_records.values())
if self.registry_root is not None:
current_plan_attempted = sum(
record["claim"]["plan_sha256"] == self.plan_sha256
for record in campaign_records.values()
)
campaign_provider_outcomes = {
status: sum(
record["finish"] is not None
and record["finish"]["status"] == status
for record in campaign_records.values()
)
for status in ("succeeded", "failed", "cancelled")
}
else:
current_plan_attempted = campaign_attempted
campaign_provider_outcomes = {
status: sum(
record["finish"] is not None
and record["finish"]["status"] == status
for record in campaign_records.values()
)
for status in ("succeeded", "failed", "cancelled")
}
repair_attempted = sum(
1 for record in campaign_records.values()
if record["claim"]["operation"] in REPAIR_OPERATIONS)
return {"schema_version": "multiscene-call-ledger-snapshot.v1",
"ledger_identity_sha256": self.identity_sha256,
"real_provider": self.real_provider,
"authority": self.identity["authority"],
"budget": {
"provider_call_limit": MAX_PREALLOCATED_ATTEMPTS,
"historical_provider_call_count": self.historical_usage["provider_call_count"],
"new_provider_call_limit": (
MAX_PREALLOCATED_ATTEMPTS
- self.historical_usage["provider_call_count"]
),
"new_provider_calls_remaining": max(
0,
MAX_PREALLOCATED_ATTEMPTS
- self.historical_usage["provider_call_count"]
- campaign_attempted,
),
"repair_call_limit": MAX_REPAIR_ATTEMPTS,
"historical_repair_budget_charged": self.historical_usage[
"repair_budget_charged"
],
"new_repair_call_limit": (
MAX_REPAIR_ATTEMPTS
- self.historical_usage["repair_budget_charged"]
),
"new_repair_calls_remaining": max(
0,
MAX_REPAIR_ATTEMPTS
- self.historical_usage["repair_budget_charged"]
- repair_attempted,
),
"historical_attempts_sha256": self.historical_usage[
"attempts_sha256"
],
"historical_receipt_sha256": self.historical_usage[
"receipt_sha256"
],
},
"operations": operations, "cases": cases,
"campaign": {"attempted": campaign_attempted,
"terminal": campaign_terminal,
"unknown": campaign_attempted - campaign_terminal,
"current_plan_attempted": current_plan_attempted,
"foreign_plan_attempted": (
campaign_attempted - current_plan_attempted
),
"provider_outcomes": campaign_provider_outcomes},
"attempted": attempted,
"terminal": sum(record["finish"] is not None for record in records.values()),
"unknown": sum(record["finish"] is None for record in records.values())}
def attempt_records(self) -> list[dict[str, object]]:
"""Return immutable attempt outcomes for evidence aggregation."""
with self._locked():
records = self._records()
return [
{
"case_id": case_id,
"operation": operation,
"request_sha256": record["claim"]["request_sha256"],
"response_sha256": (
record["finish"]["response_sha256"]
if record["finish"] is not None else None
),
"status": (
record["finish"]["status"] if record["finish"] is not None else None
),
}
for (case_id, operation), record in sorted(records.items())
]
def bind_case_outcome(
self,
case_id: str,
outcome_file: str,
outcome_sha256: str,
evidence_sha256s: Mapping[str, str],
expected_operations: list[str] | tuple[str, ...],
) -> None:
"""Bind a terminal case result to its exact attempts and evidence files.
Provider finishes are written before the business/result artifact exists.
This separate immutable record prevents a later resume from trusting a
replaced ``result.json`` or its operation evidence without another call.
"""
case_id = _identifier(case_id, "case outcome case_id")
if case_id not in self.case_limits:
raise CallLedgerError("case outcome is outside frozen limits")
if outcome_file not in {"result.json", "failure.json"}:
raise CallLedgerError("case outcome file is invalid")
outcome_sha256 = _sha(outcome_sha256, "case outcome SHA-256")
evidence = _evidence_hashes(evidence_sha256s)
expected = _operation_projection(expected_operations)
with self._locked():
records = self._records()
projection = _case_attempt_projection(records, case_id)
if any(item["status"] is None for item in projection):
raise CallLedgerError("case outcome cannot bind an unfinished provider attempt")
payload = {
"schema_version": "multiscene-case-outcome.v2",
"ledger_identity_sha256": self.identity_sha256,
"case_id": case_id,
"outcome_file": outcome_file,
"outcome_sha256": outcome_sha256,
"expected_operations": expected,
"case_operation_projection": projection,
"case_attempts_sha256": _digest(projection),
"evidence_sha256s": evidence,
}
_write_x(self.case_outcomes / f"{case_id}.json", payload)
def verify_case_outcome(
self,
case_id: str,
outcome_file: str,
outcome_sha256: str,
evidence_sha256s: Mapping[str, str],
expected_operations: list[str] | tuple[str, ...],
) -> None:
"""Fail closed unless a case artifact still matches its immutable binding."""
case_id = _identifier(case_id, "case outcome case_id")
if outcome_file not in {"result.json", "failure.json"}:
raise CallLedgerError("case outcome file is invalid")
outcome_sha256 = _sha(outcome_sha256, "case outcome SHA-256")
evidence = _evidence_hashes(evidence_sha256s)
declared_operations = _operation_projection(expected_operations)
with self._locked():
path = self.case_outcomes / f"{case_id}.json"
_reject_link_or_reparse(path, "case outcome binding")
if not path.is_file():
raise CallLedgerError("case outcome has no immutable binding")
payload = _read_json(path)
expected_keys = {
"schema_version", "ledger_identity_sha256", "case_id",
"outcome_file", "outcome_sha256", "case_attempts_sha256",
"expected_operations", "case_operation_projection",
"evidence_sha256s",
}
if not isinstance(payload, dict) or set(payload) != expected_keys:
raise CallLedgerError("case outcome binding shape is invalid")
records = self._records()
projection = _case_attempt_projection(records, case_id)
expected = {
"schema_version": "multiscene-case-outcome.v2",
"ledger_identity_sha256": self.identity_sha256,
"case_id": case_id,
"outcome_file": outcome_file,
"outcome_sha256": outcome_sha256,
"expected_operations": declared_operations,
"case_operation_projection": projection,
"case_attempts_sha256": _digest(projection),
"evidence_sha256s": evidence,
}
if payload != expected:
raise CallLedgerError("case outcome or evidence changed after binding")
def _records(self) -> dict[tuple[str, str], dict]:
_reject_link_or_reparse(self.root / "identity.json", "ledger identity")
expected_identity = _read_json(self.root / "identity.json")
if expected_identity != self.identity:
raise LedgerIdentityError("ledger identity changed")
records: dict[tuple[str, str], dict] = {}
for path in self.attempts.iterdir():
match = re.fullmatch(r"([A-Za-z0-9][A-Za-z0-9._-]{0,127})--([a-z_]+)\.(claim|finish)\.json", path.name)
_reject_link_or_reparse(path, "ledger attempt")
if not path.is_file() or match is None:
raise CallLedgerError("ledger contains an unknown attempt entry")
case_id, operation, kind = match.groups()
if case_id not in self.case_limits or operation not in self.operation_limits:
raise CallLedgerError("ledger attempt is outside frozen limits")
value = _read_json(path)
expected_keys = ({"schema_version", "ledger_identity_sha256", "claim_id", "case_id",
"operation", "request_sha256", "attempt_number"}
if kind == "claim" else
{"schema_version", "ledger_identity_sha256", "claim_id", "case_id",
"operation", "status", "response_sha256"})
if not isinstance(value, dict) or set(value) != expected_keys:
raise CallLedgerError("ledger attempt shape is invalid")
if (value["ledger_identity_sha256"] != self.identity_sha256
or value["case_id"] != case_id or value["operation"] != operation):
raise CallLedgerError("ledger attempt identity is invalid")
if not isinstance(value["claim_id"], str) or not re.fullmatch(r"[0-9a-f]{32}", value["claim_id"]):
raise CallLedgerError("ledger claim identity is invalid")
if kind == "claim":
_sha(value["request_sha256"], "stored request_sha256")
if value["schema_version"] != "multiscene-call-claim.v1" or value["attempt_number"] != 1:
raise CallLedgerError("ledger claim is invalid")
else:
if value["schema_version"] != "multiscene-call-finish.v1" or value["status"] not in TERMINAL_STATUSES:
raise CallLedgerError("ledger finish is invalid")
if value["response_sha256"] is not None:
_sha(value["response_sha256"], "stored response_sha256")
key = (case_id, operation)
record = records.setdefault(key, {"claim": None, "finish": None})
if record[kind] is not None:
raise CallLedgerError("duplicate immutable ledger entry")
record[kind] = value
for record in records.values():
if record["claim"] is None:
raise CallLedgerError("terminal record has no claim")
if record["finish"] is not None and record["finish"]["claim_id"] != record["claim"]["claim_id"]:
raise CallLedgerError("terminal record does not bind its claim")
return records
def _campaign_records(self) -> dict[str, dict]:
if self.registry_root is None or self.campaign_attempts is None:
raise CallLedgerError("campaign records require a global registry")
_reject_link_or_reparse(self.registry_root / "campaign-identity.json",
"campaign identity")
if _read_json(self.registry_root / "campaign-identity.json") != self.campaign_identity:
raise LedgerIdentityError("global campaign identity changed")
records: dict[str, dict] = {}
for path in self.campaign_attempts.iterdir():
match = re.fullmatch(r"([0-9a-f]{64})\.(claim|finish)\.json", path.name)
_reject_link_or_reparse(path, "campaign attempt")
if not path.is_file() or match is None:
raise CallLedgerError("campaign contains an unknown attempt entry")
key, kind = match.groups()
value = _read_json(path)
expected_keys = ({
"schema_version", "campaign_identity_sha256", "ledger_identity_sha256",
"claim_id", "plan_sha256", "case_id", "operation", "request_sha256",
} if kind == "claim" else {
"schema_version", "campaign_identity_sha256", "ledger_identity_sha256",
"claim_id", "plan_sha256", "case_id", "operation", "status",
"response_sha256",
})
if not isinstance(value, dict) or set(value) != expected_keys:
raise CallLedgerError("campaign attempt shape is invalid")
if (value["campaign_identity_sha256"] != self.campaign_identity_sha256
or _digest({"plan_sha256": value["plan_sha256"],
"case_id": value["case_id"],
"operation": value["operation"]}) != key):
raise CallLedgerError("campaign attempt identity is invalid")
_sha(value["plan_sha256"], "campaign plan_sha256")
_sha(value["ledger_identity_sha256"], "campaign ledger identity")
_identifier(value["case_id"], "campaign case_id")
if value["operation"] not in OPERATIONS:
raise CallLedgerError("campaign operation is invalid")
if (not isinstance(value["claim_id"], str)
or not re.fullmatch(r"[0-9a-f]{32}", value["claim_id"])):
raise CallLedgerError("campaign claim identity is invalid")
if kind == "claim":
if value["schema_version"] != "multiscene-campaign-claim.v1":
raise CallLedgerError("campaign claim schema is invalid")
_sha(value["request_sha256"], "campaign request_sha256")
else:
if (value["schema_version"] != "multiscene-campaign-finish.v1"
or value["status"] not in TERMINAL_STATUSES):
raise CallLedgerError("campaign finish is invalid")
if value["response_sha256"] is not None:
_sha(value["response_sha256"], "campaign response_sha256")
record = records.setdefault(key, {"claim": None, "finish": None})
if record[kind] is not None:
raise CallLedgerError("duplicate campaign attempt entry")
record[kind] = value
for record in records.values():
claim, finish = record["claim"], record["finish"]
if claim is None:
raise CallLedgerError("campaign finish has no claim")
if finish is not None and any(
finish[field] != claim[field]
for field in ("claim_id", "plan_sha256", "case_id", "operation",
"ledger_identity_sha256")
):
raise CallLedgerError("campaign finish does not bind its claim")
return records
@contextmanager
def _locked(self) -> Iterator[None]:
lock_id = uuid4().hex
try:
descriptor = os.open(self.lock_path, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
except FileExistsError as error:
raise LedgerBusyError("call ledger lock is already held") from error
try:
with os.fdopen(descriptor, "w", encoding="utf-8", newline="\n") as stream:
json.dump({"lock_id": lock_id}, stream, separators=(",", ":"))
stream.flush()
os.fsync(stream.fileno())
yield
finally:
try:
current = _read_json(self.lock_path)
except (OSError, ValueError, CallLedgerError):
current = None
if current == {"lock_id": lock_id}:
self.lock_path.unlink()
def _limits(value: Mapping[str, int], *, operations: bool) -> dict[str, int]:
if not isinstance(value, Mapping):
raise TypeError("limits must be a mapping")
result = {}
for name, limit in value.items():
if operations:
if name not in OPERATIONS:
raise ValueError("unknown operation limit")
else:
name = _identifier(name, "case limit")
if not isinstance(limit, int) or isinstance(limit, bool) or limit < 0:
raise TypeError("budgets must be non-negative integers, not bool")
result[name] = limit
return result
def _case_attempt_projection(records: Mapping[tuple[str, str], dict], case_id: str) -> list[dict]:
return [
{
"operation": operation,
"request_sha256": record["claim"]["request_sha256"],
"response_sha256": (
record["finish"]["response_sha256"]
if record["finish"] is not None else None
),
"status": record["finish"]["status"] if record["finish"] is not None else None,
}
for (current_case, operation), record in sorted(records.items())
if current_case == case_id
]
def _operation_projection(value: list[str] | tuple[str, ...]) -> list[str]:
if not isinstance(value, (list, tuple)) or not value:
raise TypeError("expected operations must be a non-empty list or tuple")
result: list[str] = []
for operation in value:
if operation not in OPERATIONS or operation in result:
raise ValueError("expected operations contain an invalid or duplicate operation")
result.append(operation)
return result
def _evidence_hashes(value: Mapping[str, str]) -> dict[str, str]:
if not isinstance(value, Mapping):
raise TypeError("case evidence hashes must be a mapping")
result: dict[str, str] = {}
for name, digest in value.items():
name = _identifier(name, "case evidence name")
result[name] = _sha(digest, "case evidence SHA-256")
return dict(sorted(result.items()))
def _historical_usage(value: Mapping[str, object] | None) -> dict[str, object]:
if value is None:
return {
"provider_call_count": 0,
"repair_budget_charged": 0,
"attempts": [],
"attempts_sha256": None,
"receipt_sha256": None,
}
expected = {
"provider_call_count", "repair_budget_charged",
"attempts", "receipt_sha256",
}
if not isinstance(value, Mapping) or set(value) != expected:
raise ValueError("historical usage shape is invalid")
provider_calls = value["provider_call_count"]
repair_calls = value["repair_budget_charged"]
for label, count, ceiling in (
("provider_call_count", provider_calls, MAX_PREALLOCATED_ATTEMPTS),
("repair_budget_charged", repair_calls, MAX_REPAIR_ATTEMPTS),
):
if not isinstance(count, int) or isinstance(count, bool) or not 0 <= count <= ceiling:
raise ValueError(f"historical {label} is invalid")
if repair_calls > provider_calls:
raise ValueError("historical repair budget cannot exceed provider calls")
attempts = value["attempts"]
if not isinstance(attempts, list) or len(attempts) != provider_calls:
raise ValueError("historical attempts do not match provider call count")
normalized_attempts = []
attempt_ids: set[str] = set()
claim_hashes: set[str] = set()
attempt_keys = {
"attempt_id", "plan_sha256", "case_id", "operation",
"provider_status", "business_status", "elapsed_seconds", "timed_out",
"request_sha256", "response_sha256", "provider", "model",
"job_id", "audit_run_id",
"identity_path", "identity_file_sha256", "ledger_identity_sha256",
"claim_path", "claim_sha256", "finish_path", "finish_sha256",
"before_path", "before_sha256", "after_path", "after_sha256",
"disposition",
}
for attempt in attempts:
if not isinstance(attempt, Mapping) or set(attempt) != attempt_keys:
raise ValueError("historical attempt shape is invalid")
attempt_id = _identifier(attempt["attempt_id"], "historical attempt ID")
case_id = _identifier(attempt["case_id"], "historical case ID")
operation = attempt["operation"]
provider_status = attempt["provider_status"]
business_status = attempt["business_status"]
elapsed_seconds = attempt["elapsed_seconds"]
timed_out = attempt["timed_out"]
disposition = attempt["disposition"]
if operation not in OPERATIONS:
raise ValueError("historical attempt operation is invalid")
if provider_status not in TERMINAL_STATUSES:
raise ValueError("historical provider status is invalid")
if business_status not in {
"succeeded", "failed", "cancelled", "awaiting_human", "resolved",
}:
raise ValueError("historical business status is invalid")
if (not isinstance(elapsed_seconds, (int, float))
or isinstance(elapsed_seconds, bool) or elapsed_seconds < 0):
raise ValueError("historical elapsed seconds is invalid")
if not isinstance(timed_out, bool) or (timed_out and provider_status != "failed"):
raise ValueError("historical timeout flag is invalid")
for label in (
"plan_sha256", "request_sha256", "response_sha256",
"identity_file_sha256", "ledger_identity_sha256", "claim_sha256",
"finish_sha256", "before_sha256", "after_sha256",
):
_sha(attempt[label], f"historical {label}")
for label in ("identity_path", "claim_path", "finish_path", "before_path", "after_path"):
path_value = attempt[label]
if (not isinstance(path_value, str) or not path_value
or len(path_value) > 2048 or "\x00" in path_value):
raise ValueError(f"historical {label} is invalid")
if attempt["provider"] != "codex-cli-development" or attempt["model"] != "gpt-5.6-sol":
raise ValueError("historical provider/model is invalid")
for label in ("job_id", "audit_run_id"):
if (not isinstance(attempt[label], str) or not attempt[label]
or len(attempt[label]) > 256 or "\x00" in attempt[label]):
raise ValueError(f"historical {label} is invalid")
if not isinstance(disposition, Mapping) or set(disposition) != {
"resolution_status", "release_eligible", "reason",
"replacement_case_id", "replacement_operation",
}:
raise ValueError("historical disposition shape is invalid")
if disposition["resolution_status"] not in {"resolved", "requires_replacement"}:
raise ValueError("historical disposition status is invalid")
if not isinstance(disposition["release_eligible"], bool):
raise ValueError("historical release eligibility is invalid")
if (not isinstance(disposition["reason"], str)
or not disposition["reason"].strip() or len(disposition["reason"]) > 1000):
raise ValueError("historical disposition reason is invalid")
successful_provider_business = (
provider_status == "succeeded"
and business_status in {"succeeded", "resolved"}
and not timed_out
)
if disposition["release_eligible"] and not successful_provider_business:
raise ValueError(
"historical provider/business failure cannot be release eligible"
)
if (not successful_provider_business
and disposition["resolution_status"] != "requires_replacement"):
raise ValueError("historical provider/business failure requires replacement")
replacement_case_id = disposition["replacement_case_id"]
replacement_operation = disposition["replacement_operation"]
if disposition["resolution_status"] == "requires_replacement":
_identifier(replacement_case_id, "historical replacement case ID")
if replacement_operation not in OPERATIONS or disposition["release_eligible"]:
raise ValueError("historical replacement disposition is invalid")
elif replacement_case_id is not None or replacement_operation is not None:
raise ValueError("resolved historical disposition cannot declare replacement")
if attempt_id in attempt_ids or attempt["claim_sha256"] in claim_hashes:
raise ValueError("historical attempts must be unique")
attempt_ids.add(attempt_id)
claim_hashes.add(attempt["claim_sha256"])
normalized_attempts.append({**dict(attempt),
"attempt_id": attempt_id, "case_id": case_id, "operation": operation,
"elapsed_seconds": round(float(elapsed_seconds), 3),
"disposition": dict(disposition),
})
return {
"provider_call_count": provider_calls,
"repair_budget_charged": repair_calls,
"attempts": normalized_attempts,
"attempts_sha256": _digest(normalized_attempts),
"receipt_sha256": _sha(value["receipt_sha256"], "historical receipt_sha256"),
}
def _identifier(value: object, label: str) -> str:
if not isinstance(value, str) or not _ID_RE.fullmatch(value) or value in {".", ".."}:
raise ValueError(f"{label} is not a safe identifier")
return value
def _sha(value: object, label: str) -> str:
if not isinstance(value, str) or not _SHA_RE.fullmatch(value):
raise ValueError(f"{label} must be a lowercase SHA-256 value")
return value
def _digest(value: object) -> str:
return hashlib.sha256(json.dumps(value, ensure_ascii=False, sort_keys=True,
separators=(",", ":"), allow_nan=False).encode("utf-8")).hexdigest()
def _read_json(path: Path) -> object:
def pairs(items):
result = {}
for key, value in items:
if key in result:
raise CallLedgerError("ledger JSON contains duplicate keys")
result[key] = value
return result
def constant(value):
raise CallLedgerError(f"ledger JSON contains non-finite value {value}")
return json.loads(path.read_text(encoding="utf-8"),
object_pairs_hook=pairs, parse_constant=constant)
def _write_x(path: Path, value: object) -> None:
with path.open("x", encoding="utf-8", newline="\n") as stream:
json.dump(value, stream, ensure_ascii=False, sort_keys=True,
separators=(",", ":"), allow_nan=False)
stream.write("\n")
stream.flush()
os.fsync(stream.fileno())
def _reject_link_or_reparse(path: Path, label: str) -> None:
"""Reject filesystem indirection for ledger-owned directories."""
try:
metadata = path.lstat()
except FileNotFoundError:
return
attributes = getattr(metadata, "st_file_attributes", 0)
reparse_flag = getattr(stat, "FILE_ATTRIBUTE_REPARSE_POINT", 0x400)
if stat.S_ISLNK(metadata.st_mode) or attributes & reparse_flag:
raise CallLedgerError(f"{label} must not be a symlink or reparse point")
def _reject_path_chain(path: Path, label: str) -> None:
"""Reject a link/junction anywhere in an authority path."""
current = path
while True:
_reject_link_or_reparse(current, label)
if current.parent == current:
return
current = current.parent