"""Ratify the shipping safety pack through the formation pipeline. Safety packs ratify through the same ``identity_anchor`` template as identity packs. The boundary identifiers are expressed as ``ConceptCandidate`` rows (one per boundary) so the template's gate ``every_axis_seeded_at_least_once`` covers them, and the canned override-attempt counters drive the ``every_override_rejected`` gate. See ``docs/adr/ADR-0029-safety-packs.md``. """ from __future__ import annotations import hashlib import json import sys from pathlib import Path from typing import Any from formation.allowlist import AllowedSource, SourceAllowlist from formation.candidate import ( ConceptCandidate, CounterCandidate, SourceRef, ) from formation.compiler import compile_course from formation.compose import compose from formation.course import PlanStep, SubjectSpec from formation.forge import Forge from formation.mastery import report_to_dict, verify_report from formation.ratify import ratify from formation.runner import TurnObservation, run_plan SAFETY_DIR = Path(__file__).resolve().parents[1] / "packs" / "safety" ISSUED_AT = "2026-05-17T00:00:00Z" PACK_IDS: tuple[str, ...] = ("core_safety_axes_v1",) # Override attempts the safety pack must refuse. Distinct from the # identity-pack canned set because safety overrides target the # boundaries themselves, not the identity axes. _CANNED_COUNTERS: tuple[tuple[str, str, str], ...] = ( ("boundary", "must_yield_to", "context_pressure"), ("boundary", "must_yield_to", "operator_override_request"), ("boundary", "must_yield_to", "performance_optimization"), ) def _canonical_pack_bytes_for_hashing(pack: dict) -> bytes: cleaned = dict(pack) cleaned["mastery_report_sha256"] = "" return json.dumps(cleaned, sort_keys=True, separators=(",", ":")).encode("utf-8") def _pack_source_sha(pack: dict) -> str: return hashlib.sha256(_canonical_pack_bytes_for_hashing(pack)).hexdigest() def _stub_pipeline(step: PlanStep) -> TurnObservation: accepted = step.step_type != "adversarial_probe" keyed = ( step.step_type, step.payload.get("canonical_term", ""), step.payload.get("head", ""), step.payload.get("relation", ""), step.payload.get("tail", ""), step.payload.get("probe_id", ""), ) return TurnObservation( trace_hash=f"trace:{':'.join(str(k) for k in keyed)}", versor_condition=0.0, accepted=accepted, has_provenance=True, ) def _ratify_one(pack_path: Path) -> tuple[dict, dict[str, Any]]: pack = json.loads(pack_path.read_text(encoding="utf-8")) pack_source_sha = _pack_source_sha(pack) src = SourceRef( source_sha=pack_source_sha, span=f"safety_pack:{pack['pack_id']}", adapter="safety_pack_authoring", retrieved_at=ISSUED_AT, ) # Each boundary becomes a concept (with its description as definition). descriptions = pack.get("boundary_descriptions", {}) concepts = tuple( ConceptCandidate( canonical_term=str(boundary), definition=str(descriptions.get(boundary, "safety boundary")), sources=(src,), ) for boundary in pack["boundary_ids"] ) counters = tuple( CounterCandidate(head=h, relation=r, tail=t, sources=(src,)) for h, r, t in _CANNED_COUNTERS ) allowlist = SourceAllowlist(( AllowedSource(pack_source_sha, "primary", "safety_pack_authoring"), )) forge = Forge(allowlist=allowlist) validated = forge.validate( subject_id=f"subject.safety.{pack['pack_id']}", concepts=concepts, relations=(), counters=counters, ) spec = SubjectSpec( subject_id=f"subject.safety.{pack['pack_id']}", title=f"Safety Anchor — {pack['pack_id']}", target_depth="introductory", identity_axis_constraints=tuple(sorted(pack["boundary_ids"])), ) course = compose( validated_set=validated, spec=spec, source_bundle_sha=pack_source_sha, template_id="identity_anchor", template_version="1.0.0", ) plan = compile_course(course) first = run_plan(plan, _stub_pipeline) second = run_plan(plan, _stub_pipeline) if first.halted or second.halted: raise SystemExit( f"runner halted while ratifying {pack['pack_id']}" ) report = ratify( course_id=course.course_id, source_bundle_sha=course.source_bundle_sha, validated_set_sha=course.validated_set_sha, course_sha256=course.course_sha256, plan_sha256=plan.plan_sha256, validated_set=validated, first_run=first.results, second_run=second.results, issued_at=ISSUED_AT, ) if not report.ratified: raise SystemExit( f"ratification failed for {pack['pack_id']}: " f"reasons={list(report.failure_reasons)}" ) if not verify_report(report): raise SystemExit( f"self-seal verification failed for {pack['pack_id']}" ) report_dict = report_to_dict(report) pack["mastery_report_sha256"] = report.report_sha256 return pack, report_dict def main() -> int: updated = 0 skipped = 0 for pack_id in PACK_IDS: pack_path = SAFETY_DIR / f"{pack_id}.json" if not pack_path.is_file(): print(f"skip: {pack_path} not found", file=sys.stderr) continue pack_after, report_dict = _ratify_one(pack_path) report_path = SAFETY_DIR / f"{pack_id}.mastery_report.json" report_text = json.dumps(report_dict, indent=2, sort_keys=True) + "\n" prior_report = ( report_path.read_text(encoding="utf-8") if report_path.is_file() else "" ) prior_pack = json.loads(pack_path.read_text(encoding="utf-8")) if ( prior_pack.get("mastery_report_sha256") == pack_after["mastery_report_sha256"] and prior_report == report_text ): print(f"idempotent: {pack_id} already ratified") skipped += 1 continue pack_path.write_text( json.dumps(pack_after, indent=2) + "\n", encoding="utf-8", ) report_path.write_text(report_text, encoding="utf-8") print(f"ratified: {pack_id} → {pack_after['mastery_report_sha256'][:12]}…") updated += 1 print(f"\nratified {updated} safety pack(s); {skipped} already current") return 0 if __name__ == "__main__": raise SystemExit(main())