# SPDX-License-Identifier: Apache-2.0 # © 2026 Lutar, Stephen P. — SZL Holdings # ORCID: 0009-0001-0110-4173 # ============================================================================ # szl_agentic_loop.py — THE OPERATIONAL GOVERNED AGENT LOOP (additive, sovereign) # ---------------------------------------------------------------------------- # One module, registered the SAME WAY in a11oy and killinchu, that makes the # advertised "RAG -> tool-call -> policy/trust gate -> signed receipt" loop # REAL and CLICKABLE end-to-end, with a per-hop trace and a re-verifiable # chained, signed receipt. # # WHAT IT EXPOSES (all registered BEFORE the SPA catch-all via routes.insert(0)): # GET /mcp/ — MCP runtime discovery (declaration only) # POST /mcp/ — MCP JSON-RPC (initialize, tools/list, tools/call) # GET /api//v1/agent/tools — plain tool catalog (mirror of MCP tools/list) # GET /api//v1/agent/evidence — observed, read-only receipt evidence # GET /api//v1/agent/invocations — bounded, ephemeral receipt summaries # POST /api//v1/agent/run — the GOVERNED AGENT RUN (the whole loop) # POST /api//v1/agent/verify-chain— re-verify a run's chained receipt # GET /ask-and-act — the consumer/investor UI (one button) # # HONESTY DOCTRINE (never violated here): # - The RAG hop retrieves over a REAL in-image governance corpus (no external # FAISS dep; always present). Honestly labelled "in-image corpus". # - The trust score is the Λ advisory aggregator = Conjecture 1. Plain-language # "Trust score (advisory)". NEVER claimed proven-unique. # - The receipt is signed via the HOST APP's real signer (sign_fn). a11oy = # in-image ephemeral ECDSA-P256 (resets on rebuild, verifiable vs /cosign.pub); # killinchu = persistent cosign ECDSA-P256. Whichever is true is reported. # - DENY path emits NO action — only a deny receipt. Allow path emits the action. # - No amaru/sentra/rosie/Λ/Khipu/DSSE jargon shown to the user. Plain language. # # Signed-off-by: Stephen P. Lutar Jr. # Co-Authored-By: Perplexity Computer Agent # ============================================================================ from __future__ import annotations import hashlib import json import math import threading import time import uuid from datetime import datetime, timezone # The Hatun read surface exposes only a bounded, in-process summary of receipts # that this module actually observed creating. It is deliberately ephemeral: a # restart clears the feed, and no GET handler signs or appends anything. _HATUN_FEED_LIMIT = 32 # ---------------------------------------------------------------------------- # FORMULA WIRING (ADDITIVE 2026-06-06): the ~80 kernel-verified theorems wired # to REAL work. szl_formula_wiring exposes deterministic mechanisms that COMPUTE # / ENFORCE / DECIDE inside this governed run. Imported with a graceful fallback # so a missing module can never take the loop down (additive-only). When present, # each hop below runs the relevant theorem mechanism on the run's REAL inputs: # HOP4 policy -> P2 gate_soundness, P3 non_interference, C10 byzantine_quorum # HOP5 trust -> W5-1 am_gm (GM<=AM enforced), W5-3/W7-4 conformal band, # W7-5 routing envelope, W5-2 Cauchy-Schwarz similarity # emit/seal -> C8/C9 Kraft floor, W5-5/W7-6 Doob two-sided audit envelope, # F-G5 bounded-frontier step cap, P5/C13/C14/W5-4 merkle verify, # F-G4/W7-1 graph-health invariance, governed_run_sound (PR#194) # ---------------------------------------------------------------------------- try: import szl_formula_wiring as _FW # shared, byte-identical across both apps except Exception: # pragma: no cover - additive fallback, never crash the loop _FW = None # ---------------------------------------------------------------------------- # CANONICAL FORMULA REGISTRY + RUN-ENGINE (ADDITIVE 2026-06 / Forge): exposes the # authoritative SZL formula list, a real run-one executor, and the honest proof # status per formula as first-class MCP tools (list_formulas / run_formula / # formula_proof_status). Backed by szl_anatomy_routes -> szl_formulas REGISTRY / # PROOF_STATUS, so proof status is authoritative (doctrine v11) and never # inflated. Imported with a graceful fallback so a host without the module (e.g. # killinchu until parity) simply does not advertise the formula tools. # ---------------------------------------------------------------------------- try: import szl_anatomy_routes as _ANAT except Exception: # pragma: no cover - additive fallback, never crash the loop _ANAT = None # ---------------------------------------------------------------------------- # UNIFIED RECEIPT ORGANS (ADDITIVE): the ONE per-turn receipt proves governed + # energy + (optional) multi-witness. Both are import-guarded so a host without # them keeps the receipt working EXACTLY as today (pure optional-field addition). # - szl_energy_sovereign.energy_fields_for_receipt(): honest joules/carbon, # labelled MEASURED (fresh on-box exporter) / ROADMAP (no meter) / UNAVAILABLE # (module absent). NEVER fabricates a joule. # - szl_khipu_consensus.run_consensus(): OPTIONAL Khipu 3-of-4 BFT multi-witness # receipt (Conjecture 2), folded into the SAME hash chain. OFF by default; # enable with env A11OY_MULTIWITNESS=1. Absent/disabled ⇒ honest SKIPPED. # ---------------------------------------------------------------------------- try: import szl_energy_sovereign as _ENERGY except Exception: # pragma: no cover - additive fallback, never crash the loop _ENERGY = None try: import szl_khipu_consensus as _KHIPU_CONSENSUS except Exception: # pragma: no cover - additive fallback, never crash the loop _KHIPU_CONSENSUS = None # ---------------------------------------------------------------------------- # OUROBOROS CLOSED-LOOP GUARD (ADDITIVE 2026-07-03): the Banach contraction # primitive used ONLY by the optional governed *cycle* below. Import-guarded like # every other optional dep — if szl_agent_loop_banach is absent (it currently # lives only in killinchu), the cycle simply SKIPS the advisory contraction test # (honest no-op) and still halts via budget / gate-deny / receipt-stable-delta. # ADVISORY ONLY: Λ = Conjecture 1, the Banach guard is best-effort/experimental — # the loop is BOUNDED (always halts within `budget`) but NEVER "provably # convergent". Reimplemented-in-Python discipline; the TS runLoop is not imported. # ---------------------------------------------------------------------------- try: import szl_agent_loop_banach as _BANACH # contraction ratio + timeout bound except Exception: # pragma: no cover - additive fallback, honest no-op _BANACH = None # LTC BOUNDED-DYNAMICS NOTE (ADDITIVE 2026-07-03): an OPTIONAL, own-code # reimplementation of the Liquid Time-Constant Networks *pattern* (arXiv # 2006.04439, Apache-2.0) providing a bounded-dynamics stability ESTIMATE over # the cycle's observed trust-delta sequence. Import-guarded like every optional # dep — absent module => honest no-op (the cycle still halts by budget / gate). # ADVISORY ONLY: "LTC-derived · advisory · experimental" — never a proof, never # overrides the gate, never moves Lambda off Conjecture 1, never touches locked-8. try: import szl_ltc_dynamics as _LTC except Exception: # pragma: no cover - additive fallback, honest no-op _LTC = None # SGH STRUCTURED-GRAPH CONTROL (ADDITIVE 2026-07-03): an OPTIONAL, own-code # reimplementation of the *pattern* from "From Agent Loops to Structured Graphs" # (arXiv:2604.11378 — a cs.AI POSITION PAPER, no code). It WRAPS the governed # cycle with an explicit node state machine PLAN→EXECUTE→VERIFY→RECOVER→HALT over # an immutable plan DAG, with STRICT bounded escalation. Import-guarded like every # optional dep — absent module => honest no-op. Gated at request time by env # A11OY_SGH=1; default OFF => the cycle result is byte-identical to today. # ADVISORY ONLY: never claimed "provably terminating/sound", never overrides the # gate, never moves Lambda off Conjecture 1, never touches locked-8. try: import szl_sgh_scheduler as _SGH except Exception: # pragma: no cover - additive fallback, honest no-op _SGH = None def _energy_fields_for_receipt() -> dict: """Honest per-turn energy attestation for the unified receipt. Delegates to szl_energy_sovereign (MEASURED/ROADMAP) when present; honest UNAVAILABLE when the kernel is absent. NEVER raises, NEVER fabricates a joule.""" if _ENERGY is None: return {"joules_consumed": None, "carbon_g_co2eq": None, "energy_label": "UNAVAILABLE", "energy_source_note": ("szl_energy_sovereign not importable in this image " "— per-receipt joules/carbon honestly UNAVAILABLE, " "never fabricated.")} try: return _ENERGY.energy_fields_for_receipt() except Exception as exc: # a receipt helper must never take the loop down return {"joules_consumed": None, "carbon_g_co2eq": None, "energy_label": "UNAVAILABLE", "energy_source_note": "energy attest fail-open: %s" % (str(exc)[:120],)} def _multiwitness_fields(action_hash: str, context: dict) -> dict: """OPTIONAL Khipu 3-of-4 BFT multi-witness attestation. OFF unless env A11OY_MULTIWITNESS=1 AND szl_khipu_consensus is importable AND no event loop is already running in this thread. Honest SKIPPED otherwise. When it runs it returns the consensus receipt hash + honest N-of-4 count (WITNESSED) so the hash can be folded into the run's hash chain. NEVER raises.""" import os if os.environ.get("A11OY_MULTIWITNESS") != "1": return {"consensus_status": "SKIPPED", "consensus_note": "multi-witness OFF (set A11OY_MULTIWITNESS=1 to enable)."} if _KHIPU_CONSENSUS is None: return {"consensus_status": "SKIPPED", "consensus_note": "szl_khipu_consensus not importable in this image."} try: import asyncio coro_factory = lambda: _KHIPU_CONSENSUS.run_consensus(action_hash, context) try: asyncio.get_running_loop() # An event loop is already running in this thread (async route handler): # asyncio.run would raise, so run the consensus in a fresh worker thread # with its own loop. Keeps the multi-witness path REAL in production. import concurrent.futures with concurrent.futures.ThreadPoolExecutor(max_workers=1) as ex: result = ex.submit(lambda: asyncio.run(coro_factory())).result(timeout=30) except RuntimeError: result = asyncio.run(coro_factory()) receipt = result.get("receipt") or {} digest = hashlib.sha256( json.dumps(receipt, sort_keys=True, separators=(",", ":")).encode()).hexdigest() return {"consensus_status": "WITNESSED", "khipu_consensus": receipt.get("khipu_consensus"), "consensus_decision": receipt.get("decision"), "consensus_threshold": receipt.get("threshold"), "consensus_receipt_hash": digest, "consensus_theorem": "Khipu Conjecture 2 (Byzantine quorum safety; OPEN — not a theorem)", "consensus_note": "Khipu 3-of-4 BFT multi-witness executed; hash folded into the chain."} except Exception as exc: return {"consensus_status": "SKIPPED", "consensus_note": "multi-witness fail-open: %s" % (str(exc)[:120],)} # ---------------------------------------------------------------------------- # COGNITIVE DRIFT GUARD (ADDITIVE 2026-07-01): reimplements the platform # cognitive-runtime drift-detector PATTERN as a small, additive Python step. # Compares the current-step intent (the action) against the stated objective # (the run's query) via lexical token overlap; a low overlap means the agent's # trajectory is diverging from what it was asked to do. OFF by default; enable # with env A11OY_DRIFT_GUARD=1. Honest no-op (measured:false) when disabled or # when it cannot score (e.g. an empty objective). NEVER raises, NEVER fabricates # a score. This is a lexical proxy — labelled MEASURED (lexical) — NOT a semantic # embedding model; it never claims to understand meaning. # ---------------------------------------------------------------------------- _DRIFT_STOPWORDS = frozenset(( "the", "a", "an", "to", "of", "and", "or", "for", "in", "on", "at", "by", "with", "is", "are", "be", "this", "that", "it", "as", "from", "into", "please", "should", "would", "could", "do", "does", "if", "then", "action", )) def _drift_tokens(text: str) -> set: """Lowercase alphanumeric word tokens minus stopwords. Pure, never raises.""" out = set() word = [] for ch in (text or "").lower(): if ch.isalnum(): word.append(ch) elif word: tok = "".join(word) word = [] if len(tok) > 2 and tok not in _DRIFT_STOPWORDS: out.add(tok) if word: tok = "".join(word) if len(tok) > 2 and tok not in _DRIFT_STOPWORDS: out.add(tok) return out def drift_check(objective: str, current_intent: str) -> dict: """Governed drift-detection step (importable). Scores how far a current-step intent has diverged from the stated objective using lexical token overlap (Jaccard distance): 0.0 = perfectly aligned, 1.0 = fully diverged. OFF unless env A11OY_DRIFT_GUARD=1. Honest no-op {measured:false} when disabled or when it cannot score. When enabled and drift >= threshold (env A11OY_DRIFT_THRESHOLD, default 0.85) it flags action='reflect' — an ADVISORY re-orient directive recorded on the receipt; it does NOT rewrite the verdict or the gate. NEVER raises, NEVER fabricates. Returns: {measured: bool, score: float|null, action: 'none'|'reflect', note: str} """ import os if os.environ.get("A11OY_DRIFT_GUARD") != "1": return {"measured": False, "score": None, "action": "none", "note": "drift guard OFF (set A11OY_DRIFT_GUARD=1 to enable)."} try: obj = _drift_tokens(objective) cur = _drift_tokens(current_intent) if not obj or not cur: return {"measured": False, "score": None, "action": "none", "note": ("drift unscoreable — objective or intent has no content " "tokens; honest no-op, never fabricated.")} union = obj | cur inter = obj & cur overlap = len(inter) / len(union) if union else 0.0 score = round(1.0 - overlap, 4) # lexical Jaccard distance try: threshold = float(os.environ.get("A11OY_DRIFT_THRESHOLD", "0.85")) except Exception: threshold = 0.85 action = "reflect" if score >= threshold else "none" return {"measured": True, "score": score, "action": action, "threshold": threshold, "note": ("lexical Jaccard drift (MEASURED lexical, NOT semantic): " "%d shared / %d total content tokens. action='%s' is an " "ADVISORY re-orient flag; it does not alter the verdict." % (len(inter), len(union), action))} except Exception as exc: # a receipt helper must never take the loop down return {"measured": False, "score": None, "action": "none", "note": "drift fail-open: %s" % (str(exc)[:120],)} # ---------------------------------------------------------------------------- # COUNTERFACTUAL CHECK (ADDITIVE 2026-07-01): reimplements the platform # cognitive-runtime counterfactual-engine PATTERN as a small, additive Python # step. BEFORE finalizing a HIGH-CONSEQUENCE decision (high severity OR # irreversible), it asks a reasoning brain a brief "what if the opposite were # true / what single fact would make this wrong?" question and folds the reply # into the VERIFY receipt. OFF by default; enable with env A11OY_COUNTERFACTUAL=1. # # HONESTY: this requires a REAL reasoning brain. This image ships szl_brain.route # as an explicit HONEST STUB (no model key wired), which is NOT a real generator, # so we DO NOT call it here — that would fabricate a counterfactual. A real brain # is injected by setting the module attribute _CF_GENERATOR (a callable str->str), # e.g. by the host app when a model endpoint is actually wired. When no real brain # is available the step is an honest no-op: counterfactual {ran:false}. It NEVER # fabricates a note and NEVER alters the gate/kernel verdict (advisory only). # ---------------------------------------------------------------------------- # Optional injected reasoning-brain generator: callable(prompt:str)->str. None # (default) means no real brain is wired -> honest {ran:false}. NEVER auto-bound # to the honest-stub router (that would fabricate). Set by the host app / tests. _CF_GENERATOR = None def counterfactual_check(action: str, severity: str, confidence: float, reversible: bool, decision: str) -> dict: """Governed counterfactual step (importable). For a HIGH-CONSEQUENCE decision (severity high/critical OR irreversible) it asks the injected reasoning brain (module attr _CF_GENERATOR) a brief "what would make this wrong?" question and returns {ran: bool, note: str|null}. OFF unless env A11OY_COUNTERFACTUAL=1. Honest no-op {ran:false} when disabled, when the action is not high-consequence, or when no real brain is wired — NEVER fabricates a counterfactual, NEVER raises, NEVER changes the verdict. Returns: {ran: bool, note: str|null} """ import os if os.environ.get("A11OY_COUNTERFACTUAL") != "1": return {"ran": False, "note": None, "reason": "counterfactual OFF (set A11OY_COUNTERFACTUAL=1 to enable)."} try: sev_rank = {"low": 1, "medium": 2, "high": 3, "critical": 4}.get(severity, 2) high_consequence = sev_rank >= 3 or not reversible if not high_consequence: return {"ran": False, "note": None, "reason": ("action is not high-consequence (low/medium severity and " "reversible) — counterfactual check not required.")} gen = _CF_GENERATOR if not callable(gen): return {"ran": False, "note": None, "reason": ("no real reasoning brain wired (set module _CF_GENERATOR) — " "counterfactual honestly NOT run, never fabricated. The " "in-image szl_brain.route is an honest stub, not a generator.")} prompt = ("Counterfactual check on a governed decision. The decision was %s for " "action %r (severity=%s, confidence=%.2f, reversible=%s). In 1-2 sentences: " "what if the opposite were true — what single fact would make this decision " "wrong, and how would we detect it?" % (decision, action, severity, confidence, reversible)) note = gen(prompt) if not note or not str(note).strip(): return {"ran": False, "note": None, "reason": "reasoning brain returned empty — counterfactual honestly not run."} return {"ran": True, "note": str(note).strip()[:600], "reason": ("counterfactual generated by the wired reasoning brain; ADVISORY " "— recorded in the VERIFY receipt, does not alter the verdict.")} except Exception as exc: # a receipt helper must never take the loop down return {"ran": False, "note": None, "reason": "counterfactual fail-open: %s" % (str(exc)[:120],)} # ---------------------------------------------------------------------------- # HUMAN-APPROVAL-INTERRUPT (ADDITIVE 2026-07-01): reimplements the platform # cognitive-runtime approval-interrupt PATTERN as a small, additive Python # primitive. It solves the "tool-call-committed-before-yes" problem: when a # state-CHANGING action clears the automated gate, it is HELD at a durable # checkpoint and does NOT fire until a human grants approval for that exact # checkpoint. OFF by default; enable with env A11OY_APPROVAL_INTERRUPT=1. # # COMPOSES WITH — never replaces — the existing gate: the deterministic deny-by- # default policy gate + advisory Λ trust floor + C10 3-of-4 quorum still run and # can still DENY. Approval-interrupt is a SECOND, human layer that only engages # AFTER an ALLOW, so injected input can never use it to flip a DENY to fire. # Default OFF ⇒ behaviour byte-identical to today (no hold, no chain link). # NEVER raises. # # A verb heuristic marks state-changing actions; when uncertain it errs toward # REQUIRING approval (deny-by-default spirit). A grant is honoured only if it # names the SAME checkpoint_id and carries a non-empty human approver identity. # ---------------------------------------------------------------------------- _STATE_CHANGE_VERBS = ( "deploy", "delete", "remove", "drop", "engage", "fire", "launch", "write", "update", "modify", "patch", "merge", "push", "transfer", "send", "pay", "purchase", "provision", "terminate", "shutdown", "restart", "reboot", "grant", "revoke", "rotate", "publish", "release", "execute", "run", "apply", "create", "destroy", "kill", "scale", "migrate", "rollback", "commit", ) def _is_state_changing(action: str, reversible: bool) -> bool: """Heuristic: irreversible actions are state-changing; otherwise look for a mutation verb in the action text. Errs toward True (deny-by-default) only for the irreversible case; a purely read-only reversible query stays False.""" if not reversible: return True low = (action or "").lower() return any(v in low for v in _STATE_CHANGE_VERBS) def approval_interrupt(action: str, severity: str, reversible: bool, decision: str, grant: dict | None = None) -> dict: """Durable human-approval-interrupt primitive (importable). For a state- CHANGING action that has ALREADY cleared the automated gate (decision=ALLOW), it records a DURABLE checkpoint and requires an explicit human grant BEFORE the action may fire. OFF unless env A11OY_APPROVAL_INTERRUPT=1. The checkpoint_id is a stable hash of the action identity (action + severity + reversibility) — NOT the per-run id — so a human can approve THAT checkpoint and a later replay carrying the matching grant will fire. This is what makes the interrupt durable across the pause. Returns: {required: bool, granted: bool|null, checkpoint_id: str, note: str} - required=False (disabled, or gate already DENYied, or non-state-changing): no hold, granted=None. - required=True, granted=None: HELD — awaiting a human grant for this exact checkpoint_id; the caller MUST NOT fire the action. - required=True, granted=True: a matching human grant was supplied; the action may fire (still subject to the gate that already ALLOWed it). Composes with — never replaces — the deny-by-default gate + Λ floor + quorum. NEVER raises, NEVER fires the action itself, NEVER flips a DENY. """ import os checkpoint_id = hashlib.sha256( json.dumps({"action": action, "severity": severity, "reversible": bool(reversible)}, sort_keys=True, separators=(",", ":")).encode()).hexdigest()[:32] if os.environ.get("A11OY_APPROVAL_INTERRUPT") != "1": return {"required": False, "granted": None, "checkpoint_id": checkpoint_id, "note": "approval-interrupt OFF (set A11OY_APPROVAL_INTERRUPT=1 to enable)."} try: if decision != "ALLOW": return {"required": False, "granted": None, "checkpoint_id": checkpoint_id, "note": ("gate verdict is DENY — nothing to approve. Approval-interrupt " "composes with, and never overrides, the deny-by-default gate.")} if not _is_state_changing(action, reversible): return {"required": False, "granted": None, "checkpoint_id": checkpoint_id, "note": ("action is reversible and shows no state-change verb — treated as " "read-only; no human approval interrupt required.")} # State-changing + gate-allowed: a human MUST approve THIS checkpoint before firing. granted = False if isinstance(grant, dict): approver = str(grant.get("approver") or "").strip() approved = bool(grant.get("approved")) cp = str(grant.get("checkpoint_id") or "") if approved and approver and cp == checkpoint_id: granted = True if granted: return {"required": True, "granted": True, "checkpoint_id": checkpoint_id, "approver": str(grant.get("approver")).strip()[:120], "note": ("human approval granted for this exact checkpoint — the " "gate-allowed state-changing action MAY now fire. This is an " "ADDITIONAL human layer on top of the automated gate.")} return {"required": True, "granted": None, "checkpoint_id": checkpoint_id, "note": ("HELD for human approval — a gate-allowed STATE-CHANGING action is " "NOT fired until a human grants approval for checkpoint %s. This " "solves the tool-call-committed-before-yes problem; it composes " "with (does not replace) the deny-by-default gate + Λ floor + " "3-of-4 quorum." % checkpoint_id)} except Exception as exc: # a governance primitive must never take the loop down; # fail SAFE: on any error, HOLD rather than fire (deny-by-default spirit). return {"required": True, "granted": None, "checkpoint_id": checkpoint_id, "note": "approval-interrupt fail-safe HOLD: %s" % (str(exc)[:120],)} # ---------------------------------------------------------------------------- # REAL in-image governance corpus (the thing the RAG hop retrieves over). # These are real doctrine/governance statements that ground the agent's tool # choice and the policy gate. No external dataset / no fabricated chunks. # ---------------------------------------------------------------------------- _CORPUS = [ {"id": "DOC-001", "title": "Deny-by-default safety gate", "text": "Every governed action is checked by a safety gate before it can run. " "High-severity actions with low confidence are denied by default. The gate " "is the point of control: nothing is emitted unless the gate allows it.", "tags": ["deploy", "gate", "policy", "safety", "deny", "allow", "action"]}, {"id": "DOC-002", "title": "Trust score (advisory)", "text": "The trust score is an advisory aggregator over multiple quality axes " "(soundness, calibration, robustness, provenance, reversibility, " "transparency, containment, auditability). It is a research conjecture, " "not a proven oracle. It informs — it does not replace — the gate.", "tags": ["trust", "score", "confidence", "risk", "lambda", "advisory", "axes"]}, {"id": "DOC-003", "title": "Signed, chained receipts", "text": "Each step of a governed run produces a receipt. Receipts are hash-chained: " "each receipt commits the hash of the previous one, so the whole run is " "tamper-evident. The final receipt is cryptographically signed and can be " "re-verified by anyone, offline, against the public key.", "tags": ["receipt", "sign", "chain", "verify", "audit", "tamper", "proof"]}, {"id": "DOC-004", "title": "Reversible, low-consequence first", "text": "Prefer reversible actions. A reversible, low-severity action with high " "confidence is allowed. An irreversible, high-severity action requires " "human approval and a higher trust floor, and is denied if confidence is low.", "tags": ["reversible", "rollback", "approval", "human", "severity", "irreversible"]}, {"id": "DOC-005", "title": "Tool calls are governed", "text": "Agents act only through governed tool calls. Each tool call is recorded, " "its inputs and outputs are captured in the trace, and the policy gate runs " "between the tool call and any real-world effect.", "tags": ["tool", "call", "mcp", "trace", "agent", "act", "ask"]}, {"id": "DOC-006", "title": "Drone / vessel engagement rules", "text": "A track is engaged only if rules of engagement clear it: inside the " "geofence, identified, above the threat threshold, and reversible holds are " "exhausted. Otherwise the verdict is HOLD or MONITOR — never engage on doubt.", "tags": ["drone", "vessel", "track", "engage", "roe", "geofence", "threat", "hold", "monitor"]}, ] # ---------------------------------------------------------------------------- # GOVERNED-LOOP ↔ EXTERNAL STANDARDS MAP (ADDITIVE 2026, honest, PROPOSED/roadmap). # Maps SZL's governed-AI loop to the OWASP Agentic Top-10 2026 taxonomy (ASI01– # ASI10) and references Microsoft's Agent Governance Toolkit + Google A2A as CITED # PRIOR ART (NOT SZL's, NOT installed in the image — no heavy dep added). Each ASI # row notes the in-loop control that already exists. PROPOSED/roadmap tier; no # claim of compliance, no claim these external projects are SZL's. # ---------------------------------------------------------------------------- _OWASP_ASI_MAP = [ {"id": "ASI01", "risk": "Goal Hijacking", "szl_control": "Deny-by-default safety gate scores severity/confidence/reversibility " "and grounds tool choice on the in-image governance corpus (DOC-001)."}, {"id": "ASI02", "risk": "Tool Misuse", "szl_control": "Agents act ONLY through governed tool calls; the gate runs between the " "tool call and any real-world effect (DOC-005)."}, {"id": "ASI03", "risk": "Identity Abuse", "szl_control": "Each step emits a signed receipt; the run is re-verifiable offline " "against the public key (DOC-003)."}, {"id": "ASI04", "risk": "Supply Chain Risks", "szl_control": "Chain-of-title provenance receipts (in-toto/SLSA/cosign/Rekor); SLSA " "v1.1 VSA + Sello receipts are the roadmap (see allodial /standards)."}, {"id": "ASI05", "risk": "Code Execution Risks", "szl_control": "Irreversible / high-severity actions require human approval and a higher " "trust floor; denied on low confidence (DOC-004)."}, {"id": "ASI06", "risk": "Memory & Context Poisoning", "szl_control": "Retrieval is over a fixed in-image corpus (no external/dynamic chunks); " "untrusted_input is isolated from the policy decision."}, {"id": "ASI07", "risk": "Insecure Communications", "szl_control": "Receipts are hash-chained and signed; tamper is detectable on re-verify."}, {"id": "ASI08", "risk": "Cascading Failures", "szl_control": "Graceful fallbacks (never crash the loop); per-run soundness checks " "unified into governed_run_sound."}, {"id": "ASI09", "risk": "Human-Agent Trust Exploitation", "szl_control": "Trust score is explicitly ADVISORY (Conjecture 1, not a proven oracle); " "it informs but does not replace the gate (DOC-002)."}, {"id": "ASI10", "risk": "Rogue Agents", "szl_control": "Nothing is emitted unless the deny-by-default gate allows it; every action " "is recorded in the tamper-evident trace."}, ] _GOVERNANCE_STANDARDS = { "tier": "PROPOSED / roadmap — honest mapping; no compliance claimed; Λ stays Conjecture 1", "owasp_agentic_top10_2026": { "what": "OWASP Top 10 for Agentic Applications 2026 (ASI01–ASI10), the community " "taxonomy of autonomous-agent risks (published Dec 2025).", "szl_mapping": _OWASP_ASI_MAP, "cite": "OWASP GenAI — Top 10 for Agentic Applications 2026", "cite_url": "https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/", }, "prior_art": [ {"name": "Microsoft Agent Governance Toolkit", "what": "Open-source runtime-security toolkit addressing the OWASP Agentic Top-10 " "(policy engine, agent identity/trust, execution isolation). CITED prior " "art — NOT SZL's, NOT installed in this image (no heavy dep added).", "cite_url": "https://github.com/microsoft/agent-governance-toolkit"}, {"name": "Google Agent2Agent (A2A) Protocol", "what": "Linux Foundation agent-to-agent interop standard (Agent Cards, JSON-RPC " "task lifecycle). CITED prior art — NOT SZL's; a possible interop direction " "for the governed loop's multi-agent surface.", "cite_url": "https://github.com/a2aproject/A2A"}, ], "doctrine": ("PROPOSED/roadmap only. OWASP ASI mapping documents EXISTING in-loop " "controls; it is NOT a compliance certification. Microsoft AGT and Google " "A2A are CITED prior art, NOT SZL's and NOT installed (no pip install / no " "heavy dep). Trust stays advisory (Conjecture 1); trust never 100%."), } def governance_standards_note() -> dict: """Honest PROPOSED/roadmap note: how SZL's governed-AI loop maps to the OWASP Agentic Top-10 2026 (ASI01–ASI10), with Microsoft Agent Governance Toolkit and Google A2A as CITED prior art (not SZL's, not installed). No heavy dependency is added to the image. [PROPOSED / roadmap]""" return { "title": "SZL governed loop — OWASP Agentic Top-10 2026 mapping (PROPOSED; prior art cited)", "standards": _GOVERNANCE_STANDARDS, "note": ("Documentation/note only. No agent-governance-toolkit (or any heavy dep) is " "installed in this image; the toolkit and A2A are referenced as cited prior " "art, not vendored."), } def _retrieve(query: str, top_k: int = 3): """Real keyword + token-overlap retrieval over the in-image corpus. Deterministic, dependency-free, always available. Returns scored chunks.""" q = (query or "").lower() q_tokens = set(t for t in ''.join(c if c.isalnum() else ' ' for c in q).split() if len(t) > 2) scored = [] for c in _CORPUS: tag_hits = sum(1 for t in c["tags"] if t in q) body = (c["title"] + " " + c["text"]).lower() body_tokens = set(''.join(ch if ch.isalnum() else ' ' for ch in body).split()) overlap = len(q_tokens & body_tokens) score = tag_hits * 3 + overlap if score > 0: scored.append((score, c)) scored.sort(key=lambda x: -x[0]) if not scored: # honest fallback: always ground on the core doctrine scored = [(1, _CORPUS[0]), (1, _CORPUS[1]), (1, _CORPUS[2])] out = [] maxs = scored[0][0] or 1 for s, c in scored[:top_k]: out.append({"chunk_id": c["id"], "title": c["title"], "source": "in-image governance corpus", "relevance": round(s / (maxs + 0.0), 4), "text": c["text"]}) return out # ---------------------------------------------------------------------------- # Trust-score advisory aggregator (geometric mean over axes) — Conjecture 1. # Plain-language to the user: "Trust score (advisory)". # ---------------------------------------------------------------------------- _AXES = ["soundness", "calibration", "robustness", "provenance", "reversibility", "transparency", "containment", "auditability"] def _trust_score(axes: dict) -> float: vals = [min(1.0, max(1e-6, float(axes.get(a, 0.9)))) for a in _AXES] return round(math.exp(sum(math.log(v) for v in vals) / len(vals)), 6) # ---------------------------------------------------------------------------- # THE TOOL CATALOG — real tools that map to in-process governed capabilities. # Same catalog is exposed via MCP tools/list AND the plain /agent/tools route. # ---------------------------------------------------------------------------- def _tool_catalog(ns: str): field = "drone/vessel field operations" if ns == "killinchu" else "governed AI operations" tools = [ {"name": "retrieve_context", "title": "Retrieve context", "description": f"Search the in-image governance corpus for {field} guidance.", "inputSchema": {"type": "object", "properties": { "query": {"type": "string"}, "top_k": {"type": "integer", "default": 3}}, "required": ["query"]}}, {"name": "policy_check", "title": "Policy check (safety gate)", "description": "Run the deny-by-default safety gate on a proposed action.", "inputSchema": {"type": "object", "properties": { "action": {"type": "string"}, "severity": {"type": "string", "enum": ["low", "medium", "high", "critical"]}, "confidence": {"type": "number"}, "reversible": {"type": "boolean"}}, "required": ["action"]}}, {"name": "trust_score", "title": "Trust score (advisory)", "description": "Compute the advisory trust score across quality axes (Conjecture 1, not a proven oracle).", "inputSchema": {"type": "object", "properties": { "axes": {"type": "object"}}}}, {"name": "sign_receipt", "title": "Sign receipt", "description": "Hash-chain and cryptographically sign a decision receipt.", "inputSchema": {"type": "object", "properties": { "payload": {"type": "object"}}, "required": ["payload"]}}, {"name": "verify_receipt", "title": "Verify receipt", "description": "Re-verify a signed, chained receipt (chain intact + signature check).", "inputSchema": {"type": "object", "properties": { "receipt": {"type": "object"}}, "required": ["receipt"]}}, ] # ADDITIVE: canonical formula tools — only advertised when the formula # registry is actually importable in-process (honest: never list a tool that # cannot run). proof_status is authoritative per the honesty doctrine (v11). if _ANAT is not None: tools += [ {"name": "list_formulas", "title": "List canonical formulas", "description": "List the canonical SZL formula registry: each entry's " "name, signature, one-line doc, chakra binding and " "authoritative proof status (doctrine v11).", "inputSchema": {"type": "object", "properties": {}}}, {"name": "run_formula", "title": "Run a canonical formula", "description": "Execute one canonical formula on real positional args; " "returns the computed result, a Λ-receipt hash, and the " "formula's honest proof status. No result is fabricated.", "inputSchema": {"type": "object", "properties": { "name": {"type": "string"}, "args": {"type": "array", "items": {}}}, "required": ["name"]}}, {"name": "formula_proof_status", "title": "Formula proof status", "description": "Return the authoritative honesty/proof status for a " "named formula (e.g. LOCKED kernel-verified, experimental, " "conditional). Never inflated beyond doctrine v11.", "inputSchema": {"type": "object", "properties": { "name": {"type": "string"}}, "required": ["name"]}}, ] return tools # ---------------------------------------------------------------------------- # Span recorder (real OTEL-style spans: name, start, end, latency, status). # Honest in-app recorder — not faked, real wall-clock timing per hop. # ---------------------------------------------------------------------------- class _Trace: def __init__(self, name): self.trace_id = uuid.uuid4().hex self.name = name self.spans = [] self._t0 = time.perf_counter() def span(self, name, kind): return _Span(self, name, kind) def to_dict(self): total = round((time.perf_counter() - self._t0) * 1000, 2) return {"trace_id": self.trace_id, "name": self.name, "total_latency_ms": total, "span_count": len(self.spans), "spans": self.spans} class _Span: def __init__(self, trace, name, kind): self.trace = trace self.name = name self.kind = kind self.attrs = {} self.status = "ok" self._s = None def __enter__(self): self._s = time.perf_counter() return self def set(self, **kw): self.attrs.update(kw) return self def deny(self): self.status = "deny" def __exit__(self, exc_type, exc, tb): lat = round((time.perf_counter() - self._s) * 1000, 2) self.trace.spans.append({ "span_id": uuid.uuid4().hex[:12], "name": self.name, "kind": self.kind, "latency_ms": lat, "status": ("error" if exc else self.status), "attributes": self.attrs, }) return False # never swallow def _sha(obj) -> str: return hashlib.sha256(json.dumps(obj, sort_keys=True, separators=(",", ":")).encode()).hexdigest() # ---------------------------------------------------------------------------- # Registration. sign_fn(payload_dict) MUST return a DSSE-style envelope dict # with at least: payloadType, payload(b64), signatures(list), signed(bool), # honesty(str). a11oy passes _a11oy_sign_receipt; killinchu passes a thin wrapper # over szl_dsse.sign_payload / _emit_receipt. # verify_fn(envelope) -> {"signature_valid": bool, "detail": str} OR None (then # we fall back to a structural check). pub_pem_fn() -> PEM str or "". # ---------------------------------------------------------------------------- def register(app, ns: str, sign_fn, verify_fn=None, pub_pem_fn=None, signer_label: str = "in-image key"): # Use Starlette's plain Route (not FastAPI APIRoute) so the handlers receive # the raw Request via positional injection and FastAPI does NOT treat the # `request` parameter as a query field to validate (which caused a 422). from starlette.routing import Route from starlette.responses import JSONResponse, HTMLResponse from starlette.requests import Request # In-memory chain of full runs (each run is itself a chained sub-ledger). _RUN_CHAIN = [] # list of {run_id, final_hash, prev_run_hash} # Bounded read model derived only from receipts created by _do_run. This is # not a durable ledger and it is never populated by a GET request. _HATUN_EVIDENCE = [] _HATUN_EVIDENCE_LOCK = threading.Lock() def _do_run(query: str, action: str, severity: str, confidence: float, reversible: bool, untrusted_input: str = "", approval_grant=None, precondition_hash=None): # precondition_hash (ADDITIVE, default None): when a governed *cycle* feeds # the PRIOR iteration's signed chain_final_hash in here, it is threaded into # this run's FIRST (retrieve) receipt body as an input field — so the next # decision's witnessed receipt cryptographically commits to the previous # one (the Ouroboros "receipt eats its own tail" closure). When None (every # existing /agent/run call), NO field is added and the chain seed stays the # per-run "GENESIS" constant, so the receipt bytes are IDENTICAL to before. tr = _Trace("governed_agent_run") hops = [] # PER-RUN GENESIS (FIX 2026-06-06): seed each run's seq-0 receipt with the # SAME genesis constant the verifier (_verify_chain) seeds with. Previously # this seeded from the prior run's final_hash (a rolling global chain), so # only the FIRST run after boot verified chain_intact=true and every later # clean run reported chain_intact=false / break_at_seq=0 -- making a clean # PASS indistinguishable from a tamper FAIL from outside. Per-run genesis # matches killinchu and makes the P5 tamper-evidence beat reproduce on the # Nth clean run. Run-of-runs lineage is still tracked separately via # prev_run_hash on the run_record below. prev_hash = "GENESIS" chain = [] def _chain_receipt(kind, body): nonlocal prev_hash rec = {"seq": len(chain), "kind": kind, "body": body, "prev_hash": prev_hash, "ts_utc": datetime.now(timezone.utc).isoformat()} rec["hash"] = _sha({"seq": rec["seq"], "kind": kind, "body": body, "prev_hash": prev_hash}) prev_hash = rec["hash"] chain.append(rec) return rec # ---- HOP 1: RAG retrieve ---- with tr.span("retrieve", "rag") as sp: chunks = _retrieve(query, top_k=3) sp.set(query=query, chunks=len(chunks), cited=[c["chunk_id"] for c in chunks], source="in-image governance corpus") _retrieve_body = {"query": query, "cited_chunk_ids": [c["chunk_id"] for c in chunks]} # Ouroboros self-feed: only present when a cycle passes the prior iteration's # sealed hash. Absent (None) => byte-identical to the pre-2026-07-03 receipt. if precondition_hash is not None: _retrieve_body["precondition_hash"] = precondition_hash _chain_receipt("retrieve", _retrieve_body) # ---- HOP 2: QUARANTINE untrusted retrieval (P3 non-interference) ---- # Any untrusted/poisoned text (e.g. prompt-injection in a retrieved blob) # is RECORDED on the receipt chain but DOES NOT feed the gate inputs. # The decision below reads ONLY {action, severity, confidence, reversible} # — never this blob — so untrusted content provably cannot flip the # verdict (Goguen-Meseguer non-interference, P3, axiom-free core). _INJECTION_MARKERS = ("ignore previous", "ignore all previous", "override", "approve anyway", "disregard", "you are now", "system:", "allow this", "bypass", "sudo") ui_low = (untrusted_input or "").lower() injection_detected = any(m in ui_low for m in _INJECTION_MARKERS) with tr.span("quarantine_untrusted", "quarantine") as sp: sp.set(untrusted_present=bool(untrusted_input), bytes=len(untrusted_input or ""), injection_markers_detected=injection_detected, disposition="recorded, quarantined from the decision inputs", guarantee="non-interference (P3): this content cannot change the verdict") _chain_receipt("quarantine_untrusted", {"untrusted_present": bool(untrusted_input), "untrusted_excerpt": (untrusted_input or "")[:240], "injection_markers_detected": injection_detected, "quarantined": True, "feeds_decision": False}) # ---- HOP 3: MCP tool-call (policy_check tool, via the registered MCP) ---- with tr.span("tool_call", "mcp") as sp: tool_name = "policy_check" tool_input = {"action": action, "severity": severity, "confidence": confidence, "reversible": reversible} sp.set(transport="POST /mcp/ (JSON-RPC tools/call)", tool=tool_name, input=tool_input) _chain_receipt("tool_call", {"tool": tool_name, "input": tool_input}) # ---- HOP 4: policy check (the deny-by-default safety gate) ---- sev_rank = {"low": 1, "medium": 2, "high": 3, "critical": 4}.get(severity, 2) with tr.span("policy_check", "gate") as sp: reasons = [] gate_allow = True # Deny-by-default rules (real, deterministic, grounded in DOC-001/004): if sev_rank >= 3 and confidence < 0.6: gate_allow = False reasons.append("high-severity action with low confidence (deny-by-default)") if sev_rank >= 4 and not reversible: gate_allow = False reasons.append("irreversible critical action without confidence floor") if confidence < 0.25: gate_allow = False reasons.append("confidence below minimum floor (0.25)") if not gate_allow: sp.deny() # P3 NON-INTERFERENCE (real, executed): recompute the decision with the # untrusted blob mutated and assert it is INVARIANT. The gate reads only # the low (trusted) projection, so a poisoned blob provably cannot flip # the verdict (Goguen-Meseguer). This actually runs the formula. ni = None quorum = None if _FW is not None: low_proj = {"action": action, "severity": severity, "confidence": confidence, "reversible": reversible} ni = _FW.non_interference(low_proj, untrusted_input) # C10 consensus quorum sizing for the gate's multi-node config (3-of-4) quorum = _FW.byzantine_quorum(4, 1) sp.set(gate="deny-by-default safety gate", allow=gate_allow, severity=severity, confidence=confidence, reversible=reversible, reasons=reasons, non_interference=(ni or {}).get("decision_invariant"), consensus_safe=(quorum or {}).get("sizing_n_ge_3f_plus_1")) _chain_receipt("policy_check", {"allow": gate_allow, "reasons": reasons, "severity": severity, "confidence": confidence, "non_interference_invariant": (ni or {}).get("decision_invariant"), "consensus_quorum": quorum}) # ---- HOP 5: kernel / trust check (advisory trust floor) ---- axes = { "soundness": min(1.0, confidence + 0.05), "calibration": confidence, "robustness": 0.92 if reversible else 0.7, "provenance": 0.97, "reversibility": 0.99 if reversible else 0.4, "transparency": 0.96, "containment": 0.95 if sev_rank <= 2 else 0.75, "auditability": 0.99, } trust = _trust_score(axes) trust_floor = 0.80 # FORMULA WIRING (real, executed) on the run's actual axis scores: axis_vals = list(axes.values()) amgm = conf_band = route_env = None confidence_band = None if _FW is not None: # W5-1 AM-GM: ENFORCE GM<=AM (no-inflation). The enforced_aggregate is # the trust number we actually carry forward — it can never exceed AM. amgm = _FW.am_gm_check(axis_vals) trust = amgm["enforced_aggregate"] # the no-inflation-bounded Λ # W5-3/W7-4 conformal: a distribution-free band around the trust point, # with the 1/(n+1) floor so confidence is NEVER 100%. Calibration is the # axis scores themselves (a real, in-run sample). conf_band = _FW.conformal_interval(axis_vals, trust, alpha=0.10) confidence_band = conf_band["interval"] # W7-5 routing/averaging envelope over the per-axis risks (1 - score): route_env = _FW.routing_envelope([1.0 - v for v in axis_vals]) with tr.span("kernel_check", "kernel") as sp: trust_pass = trust >= trust_floor if not trust_pass: sp.deny() sp.set(check="trust floor (advisory)", trust_score=trust, trust_floor=trust_floor, pass_=trust_pass, no_inflation_GM_le_AM=(amgm or {}).get("no_inflation_bound_holds"), confidence_band=confidence_band, never_100_percent=(conf_band or {}).get("never_100_percent"), risk_envelope=(route_env or {}).get("envelope_holds"), note="Trust score is Conjecture 1 — advisory, not a proven oracle. " "GM<=AM enforced (W5-1); confidence band is conformal (W5-3/W7-4), " "never 100% (W7-4 floor).") _chain_receipt("kernel_check", {"trust_score": trust, "trust_floor": trust_floor, "pass": trust_pass, "no_inflation": (amgm or {}).get("no_inflation_bound_holds"), "confidence_band": confidence_band, "conformal_p_value": (conf_band or {}).get("p_value")}) allowed = gate_allow and trust_pass decision = "ALLOW" if allowed else "DENY" # ---- UNIFIED RECEIPT (ADDITIVE): energy + optional multi-witness ---- # Energy is a pure signed-field addition (never a new chain link, so the # chain is byte-identical to today when the meter is absent). Multi-witness, # when explicitly enabled and it runs, is FOLDED INTO THE HASH CHAIN via # _chain_receipt so its hash is part of the tamper-evident linkage. energy_attest = _energy_fields_for_receipt() consensus_attest = _multiwitness_fields(prev_hash, {"decision": decision, "action": action, "severity": severity, "run_id": tr.trace_id}) if consensus_attest.get("consensus_status") == "WITNESSED": _chain_receipt("multiwitness", dict(consensus_attest)) # ---- COGNITIVE DRIFT GUARD (ADDITIVE, default OFF) ---- # Scores whether the current-step intent (action) has diverged from the # stated objective (query). OFF unless A11OY_DRIFT_GUARD=1. When it runs # it is FOLDED INTO THE HASH CHAIN so the drift verdict is tamper-evident; # when disabled it is an honest no-op and adds NO chain link (default # chain stays byte-identical). It never alters the gate/kernel verdict. drift_attest = drift_check(query, action) if drift_attest.get("measured"): _chain_receipt("drift_check", dict(drift_attest)) # ---- COUNTERFACTUAL CHECK (ADDITIVE, default OFF) ---- # For a HIGH-CONSEQUENCE decision, asks the wired reasoning brain "what # would make this wrong?" and folds the reply into the VERIFY receipt. # OFF unless A11OY_COUNTERFACTUAL=1 AND a real brain is wired; honest # {ran:false} otherwise. When it runs it is FOLDED INTO THE HASH CHAIN so # the counterfactual is tamper-evident; when it does not run it adds NO # chain link (default chain byte-identical). Never alters the verdict. counterfactual_attest = counterfactual_check(action, severity, confidence, reversible, decision) if counterfactual_attest.get("ran"): _chain_receipt("counterfactual", dict(counterfactual_attest)) # ---- HUMAN-APPROVAL-INTERRUPT (ADDITIVE, default OFF) ---- # A SECOND, human layer on top of the automated gate: when enabled, a # gate-ALLOWED state-changing action is HELD at a durable checkpoint and # is NOT fired until a human grants approval for that exact checkpoint # (solving tool-call-committed-before-yes). OFF unless # A11OY_APPROVAL_INTERRUPT=1. When it engages (required) it is FOLDED INTO # THE HASH CHAIN; when disabled it adds NO chain link and does NOT change # the emit (default chain + behaviour byte-identical). It composes with — # never overrides — the deny-by-default gate (a DENY stays a DENY). approval_attest = approval_interrupt(action, severity, reversible, decision, grant=approval_grant) approval_hold = bool(approval_attest.get("required")) and not approval_attest.get("granted") if approval_attest.get("required"): _chain_receipt("approval", dict(approval_attest)) # ---- HOP 6: emit (ONLY on allow AND not held for human approval) ---- with tr.span("emit", "emit") as sp: if allowed and approval_hold: effect = {"emitted": False, "action": action, "effect": ("HELD for human approval — gate ALLOWED but this " "state-changing action is NOT fired until a human " "approves checkpoint %s (tool-call-committed-before-yes " "solved)." % approval_attest.get("checkpoint_id"))} elif allowed: effect = {"emitted": True, "action": action, "effect": ("recommendation emitted with rollback path" if reversible else "action emitted (pending human approval)")} else: effect = {"emitted": False, "action": action, "effect": "BLOCKED at the gate — no action taken (gate soundness)"} sp.set(decision=decision, approval_hold=approval_hold, **effect) # Build the decision payload and SIGN it (host app's real signer). decision_payload = { "run_id": tr.trace_id, "decision": decision, "action": action, "severity": severity, "confidence": confidence, "reversible": reversible, "trust_score_advisory": trust, "trust_status": "Conjecture 1 (advisory — NOT a proven oracle)", "cited_chunk_ids": [c["chunk_id"] for c in chunks], "gate_reasons": reasons, "chain_final_hash": prev_hash, "chain_depth": len(chain), "emitted": effect["emitted"], "energy": energy_attest, "consensus": consensus_attest, "drift": drift_attest, "counterfactual": counterfactual_attest, "approval": approval_attest, "issuer": ns, "issued_at": datetime.now(timezone.utc).isoformat(), } try: envelope = sign_fn(decision_payload) except Exception as e: # never crash; honest fallback envelope = {"signed": False, "signatures": [], "honesty": "UNSIGNED — signer raised: %s" % (type(e).__name__), "payloadType": "application/vnd.szl.receipt+json"} sp.set(receipt_signed=bool(envelope.get("signed"))) sealed = _chain_receipt("emit", {"decision": decision, "emitted": effect["emitted"], "signed": bool(envelope.get("signed"))}) receipt_has_signature = bool(envelope.get("signed") and envelope.get("signatures")) # ---- OPERATOR + GRAPH + UNIFYING FORMULA WIRING (real, executed on the # ---- SEALED chain) — these mechanisms run on the actual receipts below. formula_proof = None if _FW is not None: # C8/C9/CK6 Kraft: per-receipt field counts are the code lengths; the # encoded receipt length is >= the field-count floor (lossless minimal). field_lens = [max(1, len(r.get("body") or {})) for r in chain] kraft = _FW.kraft_encoding_floor(field_lens) # W5-5/W7-6 Doob: the receipt-chain depth is a monotone audit # accumulator; opening the audit early or late brackets the same count # (two-sided envelope). accumulator = running seq index (0..depth-1). acc = [float(r["seq"]) for r in chain] doob = _FW.doob_audit_envelope(acc, open_idx=0, tau=max(0, len(acc) // 2), close_idx=len(acc) - 1) # F-G5/CS2 bounded-frontier: walk the receipt DAG (seq->seq+1 edges) # under a hard step cap; it provably terminates within |edges|. dag_edges = [(i, i + 1) for i in range(len(chain) - 1)] frontier = _FW.bounded_frontier_walk(dag_edges) # P5/C13/C14/W5-4 Merkle: recompute the hash chain + a Merkle root over # the receipt hashes and detect duplicate-hash collisions (tamper). merkle = _FW.merkle_chain_verify(chain) # F-G4/W7-1/F-G6/F-G2 graph health on the receipt DAG adjacency — # invariant under relabeling (label-independent mesh health). adj = {str(i): [str(i + 1)] for i in range(len(chain) - 1)} adj[str(max(0, len(chain) - 1))] = adj.get(str(max(0, len(chain) - 1)), []) graph = _FW.graph_health_invariant(adj) # UNIFYING governed_run_sound (PR #194): AND the five live per-run # properties into the single top-level soundness proposition. P5 # tamper-evidence exposed separately (the only axiom-gated guarantee). p1_complete = len(chain) >= 6 and all("hash" in r for r in chain) # P2 gate-soundness: emit is allowed IFF both policy AND kernel allow # (deny-absorbing). The soundness here means the gate logic itself is # sound — emit_allow must equal (gate_allow AND trust_pass). _gs = _FW.gate_soundness(gate_allow, trust_pass) or {} p2_gate_sound = (_gs.get("emit_allow") == (gate_allow and trust_pass) and _gs.get("deny_absorbing")) p3_noninterf = bool((ni or {}).get("decision_invariant")) p4_deterministic = merkle.get("chain_intact") # replay recomputes p6_monotone = bool(doob.get("monotone_accumulator")) p5_tamper = merkle.get("chain_intact") and not merkle.get( "duplicate_hash_collision") unified = _FW.governed_run_sound( p1_complete=bool(p1_complete), p2_gate_sound=bool(p2_gate_sound), p3_noninterf=p3_noninterf, p4_deterministic=bool(p4_deterministic), p6_monotone=p6_monotone, p5_tamper_evident=bool(p5_tamper)) formula_proof = { "reasoning": {"am_gm": amgm, "conformal_band": conf_band, "routing_envelope": route_env}, "policy": {"non_interference": ni, "byzantine_quorum": quorum}, "operator": {"kraft": kraft, "doob_audit": doob, "bounded_frontier": frontier, "merkle_chain": merkle}, "graph": {"health_invariant": graph}, "unifying": unified, "note": ("Every value here was COMPUTED on this run's real receipts " "and axis scores — not asserted. Maturity per mechanism."), } # record this whole run into the run-of-runs chain run_record = {"run_id": tr.trace_id, "final_hash": prev_hash, "prev_run_hash": (_RUN_CHAIN[-1]["final_hash"] if _RUN_CHAIN else "GENESIS"), "decision": decision} _RUN_CHAIN.append(run_record) result = { "run_id": tr.trace_id, "decision": decision, "emitted": effect["emitted"], "summary": _plain_summary(decision, action, effect, reasons, trust, trust_pass, receipt_has_signature), "retrieved": chunks, "untrusted": {"present": bool(untrusted_input), "excerpt": (untrusted_input or "")[:240], "injection_markers_detected": injection_detected, "quarantined": True, "feeds_decision": False, "note": ("Recorded on the chain but excluded from the gate " "inputs — non-interference (P3): it cannot change the verdict.")}, "tool_call": {"transport": "POST /mcp/ (JSON-RPC tools/call)", "tool": "policy_check", "input": tool_input}, "gate": {"name": "deny-by-default safety gate", "allow": gate_allow, "reasons": reasons}, "trust": {"score": trust, "floor": trust_floor, "pass": trust_pass, "axes": axes, "status": "Trust score (advisory) — research conjecture, not a proven oracle"}, "formula_proof": formula_proof, "energy": energy_attest, "consensus": consensus_attest, "drift": drift_attest, "counterfactual": counterfactual_attest, "approval": approval_attest, "trace": tr.to_dict(), "receipt_chain": chain, "signed_receipt": envelope, "chain_final_hash": prev_hash, "chain_depth": len(chain), "signer": signer_label if receipt_has_signature else None, "signer_claim_status": ("SIGNATURE_PRESENT_UNVERIFIED" if receipt_has_signature else "UNAVAILABLE"), "verify_hint": ("Re-verify with POST /api/%s/v1/agent/verify-chain " "(send the whole run object back). A signature is not called " "valid until that verifier succeeds." % ns), "doctrine": "v11", "honesty": ("Trust score is advisory (Conjecture 1). RAG retrieves over the " "in-image governance corpus. Receipt signature state is %s." % ("PRESENT_UNVERIFIED" if receipt_has_signature else "UNAVAILABLE")), } _remember_hatun_receipt(result, decision_payload, tool_name) return result def _plain_summary(decision, action, effect, reasons, trust, trust_pass, receipt_has_signature): receipt_note = ("A receipt envelope with signature bytes was produced; verification " "is a separate check." if receipt_has_signature else "The receipt is UNSIGNED because no signature evidence was available.") if decision == "ALLOW": return ("Allowed. After retrieving the relevant guidance, calling the policy " "tool, passing the safety gate and the advisory trust check (score " "%.2f), the action \"%s\" was %s. %s" % (trust, action, effect["effect"], receipt_note)) why = "; ".join(reasons) if reasons else ("advisory trust score %.2f below the floor" % trust) return ("Blocked. The safety/trust gate denied \"%s\" because: %s. No action was " "taken. %s This is the gate working." % (action, why, receipt_note)) def _verify_chain(run: dict): """Re-verify a run object: (1) chain integrity (each prev_hash links and each hash recomputes), (2) signature on the final receipt.""" chain = run.get("receipt_chain") or [] chain_ok = True broken_at = None prev = "GENESIS" for r in chain: expect = _sha({"seq": r["seq"], "kind": r["kind"], "body": r["body"], "prev_hash": prev}) if r.get("prev_hash") != prev or r.get("hash") != expect: chain_ok = False broken_at = r.get("seq") break prev = r["hash"] env = run.get("signed_receipt") or {} sig_result = None if verify_fn is not None: try: sig_result = verify_fn(env) except Exception as e: sig_result = {"signature_valid": False, "detail": "verifier error: %s" % e} if sig_result is None: sig_result = {"signature_valid": bool(env.get("signed")), "detail": ("structural check: envelope reports signed=%s; " "signature bytes present=%s" % (env.get("signed"), bool(env.get("signatures"))))} # P5/C13/C14/W5-4 (real, executed): independent Merkle re-verification using # the shared formula mechanism — recomputes the chain, builds a Merkle root, # and flags duplicate-hash collisions. Tamper of any byte breaks chain_intact. merkle = None if _FW is not None and chain: merkle = _FW.merkle_chain_verify(chain) return { "chain_intact": chain_ok, "chain_depth": len(chain), "chain_break_at_seq": broken_at, "final_hash": (chain[-1]["hash"] if chain else None), "merkle_root": (merkle or {}).get("merkle_root"), "merkle_chain_intact": (merkle or {}).get("chain_intact"), "duplicate_hash_collision": (merkle or {}).get("duplicate_hash_collision"), "tamper_evidence": (merkle or {}).get("maturity"), "signature_valid": sig_result.get("signature_valid"), "signature_detail": sig_result.get("detail"), "verified": bool(chain_ok and sig_result.get("signature_valid")), "note": ("Chain integrity recomputed independently from the receipt bodies " "(two ways: prev_hash chain + Merkle root, P5/C13/C14). " "Flip any byte in any receipt body and chain_intact becomes false."), } def _signature_evidence_status(run: dict, verification: dict) -> str: """Classify only evidence present on an observed receipt. A self-reported ``signed`` flag is not enough to call a signature verified. Verification requires the host-provided verifier to have run and returned a positive result. """ envelope = run.get("signed_receipt") or {} has_signature = bool(envelope.get("signed") and envelope.get("signatures")) if (verify_fn is not None and has_signature and verification.get("signature_valid") is True): return "VERIFIED" if verify_fn is not None and has_signature: return "INVALID" if has_signature: return "PRESENT_UNVERIFIED" return "UNAVAILABLE" def _remember_hatun_receipt(run: dict, decision_payload: dict, tool_name: str) -> None: """Append a bounded, redacted summary of an actual governed-run receipt.""" verification = _verify_chain(run) signature_status = _signature_evidence_status(run, verification) if run.get("decision") == "DENY": outcome = "DENY" elif run.get("emitted"): outcome = "ALLOW_EMITTED" else: outcome = "ALLOW_HELD" entry = { "namespace": ns, "ts": decision_payload.get("issued_at"), "run_id": run.get("run_id"), "source": "governed_agent_run_receipt", "tool": tool_name, "outcome": outcome, "receipt_hash": run.get("chain_final_hash"), "chain_depth": run.get("chain_depth"), "chain_status": ("OBSERVED_INTACT" if verification.get("chain_intact") is True else "OBSERVED_BROKEN"), "signature_status": signature_status, "signer": signer_label if signature_status == "VERIFIED" else None, "maturity": "OBSERVED", } with _HATUN_EVIDENCE_LOCK: _HATUN_EVIDENCE.append(entry) overflow = len(_HATUN_EVIDENCE) - _HATUN_FEED_LIMIT if overflow > 0: del _HATUN_EVIDENCE[:overflow] def _hatun_invocation_contract() -> dict: with _HATUN_EVIDENCE_LOCK: items = [dict(item) for item in reversed(_HATUN_EVIDENCE)] return { "schema": "szl.hatun.invocation-feed.v1", "namespace": ns, "status": "OBSERVED" if items else "UNKNOWN", "read_only": True, "get_mints_receipt": False, "ephemeral": True, "limit": _HATUN_FEED_LIMIT, "count": len(items), "source": "bounded in-process summaries of actual governed agent-run receipts", "items": items, } def _hatun_evidence_contract() -> dict: feed = _hatun_invocation_contract() items = feed["items"] latest = items[0] if items else None verified = next((item for item in items if item.get("signature_status") == "VERIFIED"), None) if verified: signer = {"status": "OBSERVED_VERIFIED", "label": verified.get("signer")} elif any(item.get("signature_status") in ("PRESENT_UNVERIFIED", "INVALID") for item in items): signer = {"status": "UNVERIFIED", "label": None} elif items: signer = {"status": "UNAVAILABLE", "label": None} else: signer = {"status": "UNKNOWN", "label": None} return { "schema": "szl.hatun.evidence.v1", "namespace": ns, "read_only": True, "get_mints_receipt": False, "runtime": { "status": "AVAILABLE", "mcp_endpoint": "/mcp/", "protocol_version": "2024-11-05", }, "tool_catalog": { "status": "RUNTIME_DECLARED", "count": len(_tool_catalog(ns)), "evidence_boundary": "declaration and route presence; not execution proof", }, "signer": signer, "receipt_chain": { "status": latest.get("chain_status") if latest else "UNKNOWN", "observed_receipts": len(items), "latest_receipt_hash": latest.get("receipt_hash") if latest else None, "latest_chain_depth": latest.get("chain_depth") if latest else None, }, "invocations": { "status": feed["status"], "count": feed["count"], "ephemeral": True, "endpoint": "/api/hatun/invocations" if ns == "a11oy" else "/api/%s/v1/agent/invocations" % ns, }, "honesty": ("No receipt or signer claim is promoted by this GET. UNKNOWN and " "UNAVAILABLE remain visible until an observed governed run supplies " "the corresponding evidence."), } # ------------------------------------------------------------------ # # OUROBOROS CLOSED LOOP (ADDITIVE 2026-07-03, default-OFF, honest). # Wraps the single governed pass `_do_run` into a BOUNDED, WITNESSED, # SELF-REFERENTIAL, converge-or-halt cycle. The existing /agent/run path # is untouched and byte-identical when A11OY_OUROBOROS is unset. # ADVISORY DISCIPLINE: Λ = Conjecture 1 and the Banach guard are advisory # only. The loop is BOUNDED (always halts within `budget`) but is NEVER # claimed "provably convergent"; "converged" is an advisory/experimental # label, not a proof. Reimplemented-in-Python; the TS runLoop is not used. # ------------------------------------------------------------------ # def _cycle_delta(prev_run, cur_run): """Advisory scalar distance between two consecutive iteration outputs: the trust-score delta plus whether the decision flipped. Feeds ONLY the ADVISORY 'converged' status (Conjecture 1 — never a convergence proof).""" if prev_run is None or cur_run is None: return None pt = float(((prev_run.get("trust") or {}).get("score")) or 0.0) ct = float(((cur_run.get("trust") or {}).get("score")) or 0.0) return {"trust_delta": abs(ct - pt), "decision_changed": prev_run.get("decision") != cur_run.get("decision")} def _do_governed_cycle_core(*, budget, eps=0.01, **run_kwargs): """OUROBOROS closed loop over the single governed pass. Runs `_do_run` up to `budget` times, feeding each iteration's SIGNED `chain_final_hash` as the next iteration's `precondition_hash` (the self-reference / Ouroboros closure). Halts on the FIRST honest status: * halted_by_gate — deny-by-default gate denied (DENY halts the cycle), * converged — ADVISORY: decision stable and trust delta <= eps, * halted_by_banach — ADVISORY: Banach guard estimates non-contraction, * budget_exhausted — bounded ceiling reached without converging. Convergence is ADVISORY ONLY (Conjecture 1 / experimental) — never claimed provably convergent. The loop ALWAYS terminates within `budget`.""" try: budget = int(budget) except Exception: budget = 1 if budget < 1: budget = 1 budget = min(budget, 64) # hard ceiling — the loop is always bounded eps = float(eps) iterations = [] trust_trace = [] cyc_prev = "GENESIS" cyc_chain = [] prev_hash = None # precondition for iteration 0 (None -> byte-identical seed) prev_run = None prev_delta = None delta_history = [] # scalar trust-deltas feeding the advisory LTC note final_status = "budget_exhausted" banach_note = None for i in range(budget): run = _do_run(precondition_hash=prev_hash, **run_kwargs) cur_hash = run.get("chain_final_hash") decision = run.get("decision") trust = (run.get("trust") or {}).get("score") delta = _cycle_delta(prev_run, run) # cycle-level receipt: chains the per-iteration final hashes so the # whole cycle is tamper-evident with prev-hash linkage intact. entry_body = {"iteration": i, "precondition_hash": prev_hash, "chain_final_hash": cur_hash, "decision": decision, "trust_score": trust, "delta": delta} entry_hash = _sha({"seq": i, "kind": "cycle_iteration", "body": entry_body, "prev_hash": cyc_prev}) cyc_chain.append({"seq": i, "kind": "cycle_iteration", "body": entry_body, "prev_hash": cyc_prev, "hash": entry_hash}) cyc_prev = entry_hash trust_trace.append({"iteration": i, "trust_score": trust, "decision": decision, "precondition_hash": prev_hash, "chain_final_hash": cur_hash}) iterations.append(run) prev_run = run prev_hash = cur_hash # (c) halted_by_gate — deny-by-default gate denied; halt the cycle. if decision == "DENY": final_status = "halted_by_gate" break # (a) converged (ADVISORY) — decision stable and trust delta <= eps. if delta is not None and not delta["decision_changed"] \ and delta["trust_delta"] <= eps: final_status = "converged" break # (d) halted_by_banach (ADVISORY) — Banach guard estimates # non-contraction over the observed error-reduction ratio. Honest # no-op / skipped when the optional guard is unavailable. if _BANACH is not None and delta is not None and prev_delta is not None: try: k = None if prev_delta > 0: k = delta["trust_delta"] / prev_delta guard = _BANACH.banach_convergence_guard(k) banach_note = guard if isinstance(guard, dict) and guard.get("measurable") \ and guard.get("contraction") is False: final_status = "halted_by_banach" break except Exception: # pragma: no cover - advisory guard never crashes the loop banach_note = {"experimental": True, "measurable": False, "note": "banach guard raised — honest no-op (advisory)"} if delta is not None: prev_delta = delta["trust_delta"] delta_history.append(delta["trust_delta"]) # (e) LTC bounded-dynamics note (ADVISORY) — an own-code LTC-pattern # stability ESTIMATE over the observed trust-delta sequence. Optional and # graceful: absent module => honest inert no-op. It NEVER changes # final_status, NEVER overrides the gate, and is NOT the halting reason. if _LTC is not None: try: ltc_note = _LTC.ltc_stability_note(delta_history) except Exception: # pragma: no cover - advisory note never crashes the loop ltc_note = {"ltc_bounded": False, "ltc_stability_estimate": None, "label": "LTC-derived · advisory · experimental", "measurable": False, "note": "LTC note raised — honest no-op (advisory)"} else: ltc_note = {"ltc_bounded": None, "ltc_stability_estimate": None, "label": "LTC-derived · advisory · experimental", "available": False, "note": ("szl_ltc_dynamics not importable — advisory LTC " "bounded-dynamics note skipped (honest no-op).")} cycle_payload = { "cycle": True, "issuer": ns, "budget": budget, "eps": eps, "iterations_run": len(iterations), "final_status": final_status, "trust_trace": trust_trace, "cycle_chain_final_hash": cyc_prev, "last_run_chain_final_hash": (iterations[-1].get("chain_final_hash") if iterations else None), "issued_at": datetime.now(timezone.utc).isoformat(), } try: cyc_envelope = sign_fn(cycle_payload) except Exception as e: # never crash; honest fallback cyc_envelope = {"signed": False, "signatures": [], "honesty": "UNSIGNED — signer raised: %s" % (type(e).__name__), "payloadType": "application/vnd.szl.receipt+json"} _STATUS_NOTE = { "converged": ("Advisory-converged: the decision was stable and the trust " "delta fell to <= eps between iterations. ADVISORY ONLY " "(Conjecture 1 / experimental) — NOT a proof of convergence."), "budget_exhausted": ("Bounded budget reached without advisory convergence. " "The loop halted safely (finite budget guarantees it always halts)."), "halted_by_gate": ("Halted by the deny-by-default safety gate: an iteration " "returned DENY, which stops the cycle (deny-by-default preserved)."), "halted_by_banach": ("Halted by the ADVISORY Banach guard: the observed " "error-reduction ratio looked non-contractive. ADVISORY " "ONLY — the finite budget, not this guard, guarantees halting."), } return { "cycle": True, "budget": budget, "eps": eps, "iterations_run": len(iterations), "final_status": final_status, "final_status_note": _STATUS_NOTE.get(final_status, ""), "convergence": ("advisory — Conjecture 1 / experimental; the loop is BOUNDED " "(always halts within budget) but is NOT claimed provably " "convergent. 'converged' is a best-effort advisory label."), "self_reference": ("Each iteration's signed chain_final_hash preconditions the " "next iteration (Ouroboros closure); see trust_trace."), "trust_trace": trust_trace, "cycle_receipt_chain": cyc_chain, "cycle_chain_final_hash": cyc_prev, "signed_cycle_receipt": cyc_envelope, "banach_guard": (banach_note if banach_note is not None else {"available": _BANACH is not None, "note": ("advisory Banach guard not engaged (unavailable or " "insufficient iterations) — honest no-op")}), "ltc_stability_note": ltc_note, "iterations": iterations, "signer": signer_label, "doctrine": "v11", } def _do_governed_cycle(*, budget, eps=0.01, **run_kwargs): """Governed cycle entry point. DEFAULT PATH (A11OY_SGH unset): returns the core cycle result UNCHANGED — byte-identical to before this layer existed. OPTIONAL SGH LAYER (env A11OY_SGH=1 and szl_sgh_scheduler importable): WRAPS the core cycle with an explicit, inspectable node state machine (PLAN→EXECUTE→VERIFY→RECOVER→HALT) over an IMMUTABLE plan DAG, with STRICT bounded escalation. The SGH trace is exposed additively under the 'sgh' key; every existing field is preserved. ADVISORY / experimental — the machine is BOUNDED (always halts) but NEVER claimed provably terminating; it NEVER overrides the gate or moves Λ off Conjecture 1. Any failure (missing module / raised error) is an honest no-op that returns the untouched core result.""" sgh_max_recover = run_kwargs.pop("sgh_max_recover", 2) core = _do_governed_cycle_core(budget=budget, eps=eps, **run_kwargs) import os if os.environ.get("A11OY_SGH") != "1" or _SGH is None: return core try: def _reexecute(): return _do_governed_cycle_core(budget=budget, eps=eps, **run_kwargs) wrapped = _SGH.wrap_governed_cycle( core, _reexecute, sha_fn=_sha, max_recover=sgh_max_recover) out = dict(core) out["sgh"] = {k: v for k, v in wrapped.items() if k != "cycle"} return out except Exception: # pragma: no cover - SGH must never take the cycle down return core # ---- MCP JSON-RPC handler (runtime-declared MCP surface) ---- async def _mcp_post(request: Request): try: body = await request.json() except Exception: return JSONResponse({"jsonrpc": "2.0", "id": None, "error": {"code": -32700, "message": "Parse error"}}, status_code=200) rid = body.get("id") method = body.get("method", "") params = body.get("params") or {} if method == "initialize": return JSONResponse({"jsonrpc": "2.0", "id": rid, "result": { "protocolVersion": "2024-11-05", "capabilities": {"tools": {"listChanged": False}}, "serverInfo": {"name": "szl-%s-mcp" % ns, "version": "1.0.0", "title": "SZL %s governed MCP" % ns}}}) if method in ("tools/list", "list_tools"): return JSONResponse({"jsonrpc": "2.0", "id": rid, "result": {"tools": _tool_catalog(ns)}}) if method in ("tools/call", "call_tool"): name = params.get("name", "") args = params.get("arguments") if not isinstance(args, dict): args = {} result = _mcp_tool_call(name, args) return JSONResponse({"jsonrpc": "2.0", "id": rid, "result": { "content": [{"type": "text", "text": json.dumps(result)}], "structuredContent": result, "isError": bool(result.get("_error"))}}) if method in ("ping",): return JSONResponse({"jsonrpc": "2.0", "id": rid, "result": {}}) return JSONResponse({"jsonrpc": "2.0", "id": rid, "error": {"code": -32601, "message": "Method not found: %s" % method}}) def _mcp_tool_call(name, args): if name == "retrieve_context": return {"chunks": _retrieve(args.get("query", ""), int(args.get("top_k", 3)))} if name == "policy_check": sev = args.get("severity", "medium") conf = float(args.get("confidence", 0.8)) rev = bool(args.get("reversible", True)) sr = {"low": 1, "medium": 2, "high": 3, "critical": 4}.get(sev, 2) allow = not ((sr >= 3 and conf < 0.6) or (sr >= 4 and not rev) or conf < 0.25) return {"allow": allow, "severity": sev, "confidence": conf, "reversible": rev, "gate": "deny-by-default safety gate"} if name == "trust_score": return {"trust_score": _trust_score(args.get("axes") or {}), "status": "advisory — Conjecture 1, not a proven oracle"} if name == "sign_receipt": try: return {"envelope": sign_fn(args.get("payload") or {})} except Exception as e: return {"_error": True, "detail": str(e)} if name == "verify_receipt": env = args.get("receipt") or {} if verify_fn: try: return verify_fn(env) except Exception as e: return {"signature_valid": False, "detail": str(e)} return {"signature_valid": bool(env.get("signed"))} # --- canonical formula tools (reuse szl_anatomy_routes -> szl_formulas) --- if name == "list_formulas": if _ANAT is None: return {"_error": True, "detail": "formula registry not available in this image"} reg = _ANAT.registry_json() return {"count": len(reg), "formulas": reg, "doctrine": "v11", "note": "proof_status is authoritative — not inflated"} if name == "run_formula": if _ANAT is None: return {"_error": True, "detail": "formula registry not available in this image"} fname = args.get("name", "") fargs = args.get("args") if fargs is None: fargs = [] elif not isinstance(fargs, list): fargs = [fargs] try: res = _ANAT.run_one(fname, fargs) except Exception as e: return {"_error": True, "detail": str(e)} if not res.get("ok", True): res = dict(res) res["_error"] = True return res if name == "formula_proof_status": if _ANAT is None: return {"_error": True, "detail": "formula registry not available in this image"} fname = args.get("name", "") ps = _ANAT.S.PROOF_STATUS.get(fname) if ps is None: return {"_error": True, "detail": "unknown formula: %s" % fname, "known": sorted(_ANAT.S.REGISTRY.keys())} return {"name": fname, "proof_status": ps, "doctrine": "v11", "note": "authoritative per the honesty doctrine — not inflated"} return {"_error": True, "detail": "unknown tool: %s" % name} async def _mcp_get(request: Request): # The response proves this route was reachable for this request. Its tool # list remains a runtime declaration, not proof of tool execution. return JSONResponse({ "name": "szl-%s-mcp" % ns, "title": "SZL %s — governed MCP runtime" % ns, "protocol": "Model Context Protocol (JSON-RPC over Streamable HTTP)", "protocolVersion": "2024-11-05", "transport": {"post": "/mcp/ (JSON-RPC: initialize, tools/list, tools/call)"}, "tools": _tool_catalog(ns), "tool_count": len(_tool_catalog(ns)), "runtime_status": "AVAILABLE", "catalog_evidence": "RUNTIME_DECLARED", "execution_evidence": "/api/%s/v1/agent/evidence" % ns, "note": ("This GET confirms route reachability and returns the catalog declared " "by this runtime. It does not prove a tool ran or a receipt was signed."), "doctrine": "v11", }) async def _agent_run(request: Request): try: b = await request.json() except Exception: b = {} query = b.get("query") or b.get("goal") or "deploy a low-risk reversible change" action = b.get("action") or query severity = b.get("severity", "low") confidence = float(b.get("confidence", 0.9)) reversible = bool(b.get("reversible", True)) untrusted_input = b.get("untrusted_input") or b.get("untrusted") or "" approval_grant = b.get("approval_grant") or b.get("approval") return JSONResponse(_do_run(query, action, severity, confidence, reversible, untrusted_input=untrusted_input, approval_grant=approval_grant)) async def _agent_tools(request: Request): return JSONResponse({"tools": _tool_catalog(ns), "count": len(_tool_catalog(ns)), "mcp_endpoint": "/mcp/", "catalog_evidence": "RUNTIME_DECLARED", "doctrine": "v11"}) async def _agent_evidence(request: Request): return JSONResponse(_hatun_evidence_contract(), headers={"Cache-Control": "no-store"}) async def _agent_invocations(request: Request): return JSONResponse(_hatun_invocation_contract(), headers={"Cache-Control": "no-store"}) async def _agent_governance_standards(request: Request): return JSONResponse(governance_standards_note()) async def _agent_verify(request: Request): try: b = await request.json() except Exception: b = {} # accept either a full run object or {"run": {...}} run = b.get("run") if isinstance(b.get("run"), dict) else b return JSONResponse(_verify_chain(run)) async def _agent_cycle(request: Request): # OUROBOROS closed loop (ADDITIVE, default-OFF). Gated at request time on # env A11OY_OUROBOROS=1 so the surface exists but is inert by default; # /agent/run is entirely untouched. Honest disabled note when off. import os if os.environ.get("A11OY_OUROBOROS") != "1": return JSONResponse({ "cycle": False, "enabled": False, "note": ("Ouroboros closed loop is OFF. Set A11OY_OUROBOROS=1 to enable. " "The single-pass /agent/run path is unaffected."), "doctrine": "v11", }, status_code=200) try: b = await request.json() except Exception: b = {} query = b.get("query") or b.get("goal") or "deploy a low-risk reversible change" action = b.get("action") or query severity = b.get("severity", "low") confidence = float(b.get("confidence", 0.9)) reversible = bool(b.get("reversible", True)) untrusted_input = b.get("untrusted_input") or b.get("untrusted") or "" approval_grant = b.get("approval_grant") or b.get("approval") try: budget = int(b.get("budget", 4)) except Exception: budget = 4 try: eps = float(b.get("eps", 0.01)) except Exception: eps = 0.01 return JSONResponse(_do_governed_cycle( budget=budget, eps=eps, query=query, action=action, severity=severity, confidence=confidence, reversible=reversible, untrusted_input=untrusted_input, approval_grant=approval_grant)) async def _ask_and_act_ui(request: Request): return HTMLResponse(_UI_HTML.replace("__NS__", ns).replace("__SIGNER__", signer_label)) # Combined GET+POST handler for /mcp/ so one route serves both verbs cleanly. async def _mcp_any(request: Request): if request.method == "POST": return await _mcp_post(request) return await _mcp_get(request) routes = [ Route("/mcp/", _mcp_any, methods=["GET", "POST"], name="%s_mcp" % ns), Route("/mcp", _mcp_any, methods=["GET", "POST"], name="%s_mcp_noslash" % ns), Route("/api/%s/v1/agent/run" % ns, _agent_run, methods=["POST"], name="%s_agent_run" % ns), Route("/api/%s/v1/agent/tools" % ns, _agent_tools, methods=["GET"], name="%s_agent_tools" % ns), Route("/api/%s/v1/agent/evidence" % ns, _agent_evidence, methods=["GET"], name="%s_agent_evidence" % ns), Route("/api/%s/v1/agent/invocations" % ns, _agent_invocations, methods=["GET"], name="%s_agent_invocations" % ns), Route("/api/%s/v1/agent/governance-standards" % ns, _agent_governance_standards, methods=["GET"], name="%s_agent_gov_standards" % ns), Route("/api/%s/v1/agent/verify-chain" % ns, _agent_verify, methods=["POST"], name="%s_agent_verify" % ns), Route("/api/%s/v1/agent/cycle" % ns, _agent_cycle, methods=["POST"], name="%s_agent_cycle" % ns), Route("/ask-and-act", _ask_and_act_ui, methods=["GET"], name="%s_ask_and_act" % ns), Route("/governed-run", _ask_and_act_ui, methods=["GET"], name="%s_governed_run" % ns), ] if ns == "a11oy": routes.extend([ Route("/api/hatun/evidence", _agent_evidence, methods=["GET"], name="hatun_evidence"), Route("/api/hatun/invocations", _agent_invocations, methods=["GET"], name="hatun_invocations"), ]) # insert at position 0 so they win over the SPA catch-all (the known gotcha). for r in reversed(routes): app.router.routes.insert(0, r) return {"registered": [r.path for r in routes], "ns": ns, "tools": len(_tool_catalog(ns))} # ---------------------------------------------------------------------------- # Consumer/investor UI — one obvious button, plain language, trace timeline, # chained-receipt panel, re-verify button, allow + deny demos. Sovereign (no CDN). # ---------------------------------------------------------------------------- _UI_HTML = r""" Ask & Act — Governed Agent Run · SZL __NS__

Ask & Act · __NS__

Ask the system to do something. It looks up the relevant rules, calls a governed tool, runs a safety check and a trust check, and only then acts — producing a signed, tamper-evident receipt you can verify yourself. If the safety gate says no, nothing happens.

What happened — step by step

Six timed steps, every time: retrieve → quarantine untrusted → tool → policy → trust → emit. The chain always has exactly six receipts.

Untrusted input — quarantined

Rules it looked up

Signed receipt

Show raw signed receipt envelope
""" def _selftest() -> None: # Governance-standards note: full OWASP ASI01–ASI10 map, PROPOSED/roadmap, prior art # cited (Microsoft AGT + Google A2A), and NO heavy dep claimed/installed. note = governance_standards_note() std = note["standards"] ids = [r["id"] for r in std["owasp_agentic_top10_2026"]["szl_mapping"]] assert ids == ["ASI%02d" % i for i in range(1, 11)], ids assert "roadmap" in std["tier"].lower() names = [p["name"] for p in std["prior_art"]] assert any("Agent Governance Toolkit" in n for n in names), names assert any("A2A" in n for n in names), names assert "github.com/microsoft/agent-governance-toolkit" in \ " ".join(p["cite_url"] for p in std["prior_art"]) # honest: explicitly not installed / no heavy dep assert "not installed" in std["doctrine"].lower() or "no pip" in std["doctrine"].lower() print("szl_agentic_loop: ALL OK (governance-standards note, 6 checks)") if __name__ == "__main__": _selftest()