"""
OSMP Python Reference Implementation
Octid Semantic Mesh Protocol — Cloudless Sky Project

Source of truth: OSMP-semantic-dictionary-v12.csv | OSMP-SPEC-v1.md | SAL-grammar.ebnf
All opcode names, definitions, and namespace assignments are drawn directly from the
canonical semantic dictionary v12.0, not from any prior implementation.

Patent: OSMP-001-UTIL (pending) — inventor Clay Holberg
License: Apache 2.0
"""

from __future__ import annotations

import json
import lzma
import struct
import hashlib
from dataclasses import dataclass, field
from enum import Enum, auto
from pathlib import Path
from typing import Iterator

try:
    import zstandard as zstd
    _HAS_ZSTD = True
except ImportError:
    _HAS_ZSTD = False


# ─────────────────────────────────────────────────────────────────────────────
# GLYPH OPERATOR TABLE — Category 1 (18 operators)
# Source: OSMP-semantic-dictionary-v12.csv Section 1, Category 1
# ─────────────────────────────────────────────────────────────────────────────

GLYPH_OPERATORS: dict[str, dict] = {
    "∧": {"unicode": "U+2227", "name": "AND",            "bytes": 3, "nl": ["and", "&", "also"]},
    "∨": {"unicode": "U+2228", "name": "OR",             "bytes": 3, "nl": ["or", "either", "alternatively"]},
    "¬": {"unicode": "U+00AC", "name": "NOT",            "bytes": 2, "nl": ["not", "except", "excluding", "without"]},
    "→": {"unicode": "U+2192", "name": "THEN",           "bytes": 3, "nl": ["if...then", "when...then", "provided that", "therefore"]},
    "↔": {"unicode": "U+2194", "name": "IFF",            "bytes": 3, "nl": ["if and only if", "iff", "exactly when"]},
    "∀": {"unicode": "U+2200", "name": "FOR-ALL",        "bytes": 3, "nl": ["for all", "every", "each", "all"]},
    "∃": {"unicode": "U+2203", "name": "EXISTS",         "bytes": 3, "nl": ["any", "there exists", "at least one", "some"]},
    "∥": {"unicode": "U+2225", "name": "PARALLEL",       "bytes": 3, "nl": ["simultaneously", "in parallel", "concurrently"]},
    ">": {"unicode": "U+003E", "name": "PRIORITY",       "bytes": 1, "nl": ["first", "prefer", "prioritize", "greater than"]},
    "~": {"unicode": "U+007E", "name": "APPROX",         "bytes": 1, "nl": ["approximately", "about", "roughly"]},
    "*": {"unicode": "U+002A", "name": "WILDCARD",       "bytes": 1, "nl": ["all", "any value", "broadcast"]},
    ":": {"unicode": "U+003A", "name": "ASSIGN",         "bytes": 1, "nl": ["equals", "is set to", "namespace-separator"]},
    ";": {"unicode": "U+003B", "name": "SEQUENCE",       "bytes": 1, "nl": ["then next", "followed by", "in sequence"]},
    "?": {"unicode": "U+003F", "name": "QUERY",          "bytes": 1, "nl": ["what is", "query", "report"]},
    "@": {"unicode": "U+0040", "name": "TARGET",         "bytes": 1, "nl": ["at", "on", "directed to"]},
    "⟳": {"unicode": "U+27F3", "name": "REPEAT-EVERY",  "bytes": 3, "nl": ["every", "repeat every", "recurring interval"]},
    "≠": {"unicode": "U+2260", "name": "NOT-EQUAL",      "bytes": 3, "nl": ["not equal to", "excluding value", "except value"]},
    "⊕": {"unicode": "U+2295", "name": "PRIORITY-ORDER", "bytes": 3, "nl": ["in priority order", "ranked", "strict ranked execution"]},
}

COMPOUND_OPERATORS: dict[str, dict] = {
    "¬→": {"unicode": "U+00AC U+2192", "name": "UNLESS", "nl": ["unless", "except when"]},
}

# ─────────────────────────────────────────────────────────────────────────────
# CATEGORY 2 — CONSEQUENCE CLASS DESIGNATORS
# Source: dictionary v12 Section 1 Category 2
# ─────────────────────────────────────────────────────────────────────────────

CONSEQUENCE_CLASSES: dict[str, dict] = {
    "⚠": {"unicode": "U+26A0", "name": "HAZARDOUS",    "hitl_required": True},
    "↺": {"unicode": "U+21BA", "name": "REVERSIBLE",   "hitl_required": False},
    "⊘": {"unicode": "U+2298", "name": "IRREVERSIBLE", "hitl_required": True},
}

# ─────────────────────────────────────────────────────────────────────────────
# CATEGORY 3 — OUTCOME STATE DESIGNATORS
# ─────────────────────────────────────────────────────────────────────────────

OUTCOME_STATES: dict[str, dict] = {
    "⊤": {"unicode": "U+22A4", "name": "PASS-TRUE"},
    "⊥": {"unicode": "U+22A5", "name": "FAIL-FALSE"},
}

# ─────────────────────────────────────────────────────────────────────────────
# CATEGORY 4 — PARAMETER AND SLOT DESIGNATORS
# ─────────────────────────────────────────────────────────────────────────────

PARAMETER_DESIGNATORS: dict[str, dict] = {
    "Δ": {"unicode": "U+0394", "name": "DELTA",        "bytes": 2},
    "⌂": {"unicode": "U+2302", "name": "HOME",         "bytes": 3},
    "⊗": {"unicode": "U+2297", "name": "ABORT-CANCEL", "bytes": 3},
    "τ": {"unicode": "U+03C4", "name": "TIMEOUT",      "bytes": 2},
    "∈": {"unicode": "U+2208", "name": "SCOPE-WITHIN", "bytes": 3},
    "∖": {"unicode": "U+2216", "name": "MISSING",      "bytes": 3},
}

# ─────────────────────────────────────────────────────────────────────────────
# CATEGORY 5 — LOSS TOLERANCE POLICY DESIGNATORS
# ─────────────────────────────────────────────────────────────────────────────

LOSS_POLICIES: dict[str, dict] = {
    "Φ": {"unicode": "U+03A6", "name": "FAIL-SAFE",            "bytes": 2, "legacy": "FS"},
    "Γ": {"unicode": "U+0393", "name": "GRACEFUL-DEGRADATION", "bytes": 2, "legacy": "GD"},
    "Λ": {"unicode": "U+039B", "name": "ATOMIC",               "bytes": 2, "legacy": "AT"},
}

# ─────────────────────────────────────────────────────────────────────────────
# CATEGORY 6 — DICTIONARY UPDATE MODE DESIGNATORS
# ─────────────────────────────────────────────────────────────────────────────

DICT_UPDATE_MODES: dict[str, dict] = {
    "+": {"unicode": "U+002B", "name": "ADDITIVE",  "bytes": 1},
    "←": {"unicode": "U+2190", "name": "REPLACE",   "bytes": 3},
    "†": {"unicode": "U+2020", "name": "DEPRECATE", "bytes": 3},
}

# ─────────────────────────────────────────────────────────────────────────────
# BAEL — Bandwidth-Agnostic Efficiency Layer
# ─────────────────────────────────────────────────────────────────────────────

class BAELMode(Enum):
    FULL_OSMP      = 0x00
    TCL_ONLY       = 0x02
    NL_PASSTHROUGH = 0x04

class BAELEncoder:
    NL_PASSTHROUGH_FLAG = 0x04

    @staticmethod
    def select_mode(nl_input: str, osmp_encoded: str, tcl_encoded: str = None) -> tuple:
        nl_b   = len(nl_input.encode("utf-8"))
        osmp_b = len(osmp_encoded.encode("utf-8"))
        tcl_b  = len(tcl_encoded.encode("utf-8")) if tcl_encoded else osmp_b + 1
        if nl_b <= osmp_b and nl_b <= tcl_b:
            return (BAELMode.NL_PASSTHROUGH, nl_input, BAELEncoder.NL_PASSTHROUGH_FLAG)
        elif tcl_encoded and tcl_b < osmp_b:
            return (BAELMode.TCL_ONLY, tcl_encoded, 0x00)
        else:
            return (BAELMode.FULL_OSMP, osmp_encoded, 0x00)

    @staticmethod
    def compression_floor_check(nl_input: str, osmp_encoded: str) -> dict:
        nl_b   = len(nl_input.encode("utf-8"))
        osmp_b = len(osmp_encoded.encode("utf-8"))
        mode, payload, flags = BAELEncoder.select_mode(nl_input, osmp_encoded)
        selected_b = len(payload.encode("utf-8"))
        reduction  = round((1 - selected_b / nl_b) * 100, 1) if nl_b > 0 else 0.0
        return {
            "nl_bytes": nl_b, "osmp_bytes": osmp_b,
            "selected_mode": mode.name, "selected_bytes": selected_b,
            "reduction_pct": reduction, "floor_applied": mode == BAELMode.NL_PASSTHROUGH,
            "flags": flags,
        }


# ─────────────────────────────────────────────────────────────────────────────
# OVERFLOW PROTOCOL CONSTANTS
# ─────────────────────────────────────────────────────────────────────────────

LORA_FLOOR_BYTES      = 51
LORA_STANDARD_BYTES   = 255
FRAGMENT_HEADER_BYTES = 6
FLAG_TERMINAL         = 0b00000001
FLAG_CRITICAL         = 0b00000010
FLAG_EXTENDED_DEP     = 0b00001000   # Tier 3: payload prefix is u32 dependency bitmap


# ─────────────────────────────────────────────────────────────────────────────
# SLOT VALUE ENCODING TABLE
# Source: dictionary v12 Section 2
# Single-character codes for all finite enumerated slot value sets.
# ─────────────────────────────────────────────────────────────────────────────

SLOT_VALUES: dict[str, dict[str, str]] = {
    "C:STAT":      {"A": "active", "D": "degraded", "E": "error", "I": "idle", "O": "offline"},
    "H:TRIAGE":    {"I": "immediate", "D": "delayed", "M": "minor", "B": "black", "X": "expectant"},
    "J:STATUS":    {"A": "active", "B": "blocked", "C": "complete", "F": "failed", "P": "paused"},
    "L:SEV":       {"0": "emergency", "1": "alert", "2": "critical", "3": "error",
                    "4": "warning", "5": "notice", "6": "informational", "7": "debug"},
    "O:AUTH":      {"O": "OPCON", "T": "TACON", "A": "ADCON", "S": "support"},
    "O:BW_CLASS":  {"1": "51_bytes_SF12", "2": "127_bytes_SF11", "3": "255_bytes_LongFast",
                    "4": "1500_bytes_BLE", "5": "unlimited"},
    "O:CHAN":       {"L": "LoRa", "B": "BLE", "W": "WiFi", "C": "cellular",
                    "X": "wired", "T": "satellite", "M": "mesh_mixed"},
    "O:EMCON":     {"F": "full_emissions", "R": "reduced", "S": "silent"},
    "O:LATENCY":   {"1": "realtime_10ms", "2": "low_100ms", "3": "normal_1s",
                    "4": "high_10s", "5": "store_forward"},
    "O:LINK":      {"0": "none", "1": "critical", "2": "degraded",
                    "3": "marginal", "4": "good", "5": "nominal"},
    "O:MESH":      {"F": "full", "P": "partial", "I": "isolated", "B": "bridged"},
    "O:MODE":      {"N": "normal", "D": "degraded", "E": "emergency", "R": "recovery", "M": "maintenance"},
    "O:PHASE":     {"P": "prepare", "R": "respond", "M": "mitigate", "V": "recover"},
    "O:POSTURE":   {"D": "defensive", "N": "neutral", "S": "standby", "O": "offensive"},
    "O:READY":     {"5": "peacetime", "4": "increased_watch", "3": "round_the_clock",
                    "2": "next_step_nuclear_war", "1": "maximum_readiness"},
    "O:SCOPE":     {"G": "global", "N": "national", "R": "regional", "L": "local"},
    "O:TEMPO":     {"1": "routine", "2": "elevated", "3": "urgent", "4": "critical"},
    "O:TYPE":      {"1": "national", "2": "regional_major", "3": "regional",
                    "4": "local_extended", "5": "minor_local"},
    "O:UPLINK":    {"A": "available", "U": "unavailable", "I": "intermittent"},
    "P:STAT":      {"C": "complete", "P": "pending", "F": "failed", "S": "skipped"},
    "R:COLLAB":    {"A": "active", "S": "standby", "O": "off"},
    "R:STAT":      {"A": "active", "I": "idle", "D": "degraded", "E": "emergency", "O": "offline"},
    "V:STATUS":    {"A": "active", "U": "underway", "M": "moored", "D": "degraded",
                    "E": "emergency", "I": "idle", "O": "offline"},
    "Y:STORE_TIER":{"W": "working", "L": "long_term", "E": "episodic", "S": "semantic"},
    "Z:FINISH":    {"S": "stop", "L": "length", "T": "tool_use", "E": "error", "C": "cancelled"},
    "K:DIR":       {"-$": "debit_payment_sent", "+$": "credit_payment_received"},
}


# ─────────────────────────────────────────────────────────────────────────────
# ASD BASIS SET — Guaranteed minimum operational vocabulary floor v1.0
# Source of truth: OSMP-semantic-dictionary-v12.csv Section 3
# Every opcode name and definition drawn directly from the canonical dictionary.
# DO NOT MODIFY opcode names or definitions — they are protocol wire format.
# ─────────────────────────────────────────────────────────────────────────────

ASD_FLOOR_VERSION = "1.0"

ASD_BASIS: dict[str, dict[str, str]] = {
    "A": {
        "ACCEPT":  "accept_proposed_action",
        "ACK":     "positive_acknowledgment",
        "AR":      "agentic_request",
        "AUTH":    "authorization_assertion",
        "CMP":     "compress_compare",
        "CMPR":    "structured_comparison_returning_result",
        "COMP":    "compliance_gate_assertion",
        "DA":      "delegate_to_agent",
        "ERR":     "error_handler",
        "MEM":     "memory_operation",
        "NACK":    "negative_acknowledgment",
        "PING":    "liveness_check",
        "PONG":    "liveness_response",
        "PROPOSE": "propose_action_for_negotiation",
        "REJECT":  "reject_proposed_action",
        "SUM":     "summarize",
        "TRUST":   "trust_assertion_about_agent_output",
        "TXN":     "transaction_gate",
        "VERIFY":  "request_output_verification",
    },
    "B": {
        "AP":   "access_point",
        "BA":   "building_alert",
        "BS":   "building_sector",
        "HVAC": "hvac_system",
        "L":    "life_safety",
        "X":    "structural",
    },
    "C": {
        "ALLOC": "resource_allocation",
        "CHKPT": "checkpoint_state",
        "FREE":  "release_resource",
        "KILL":  "terminate_process",
        "LIMIT": "resource_limit_enforcement",
        "MIGRT": "migrate_workload",
        "PAUSE": "pause_execution",
        "PRTY":  "execution_priority",
        "QUOTA": "resource_quota",
        "RESUME":"resume_execution",
        "RSTRT": "restart",
        "SCALE": "scale_replicas",
        "SPAWN": "spawn_process_or_agent",
        "STAT":  "resource_status",
    },
    "D": {
        "ABORT":  "abort_transfer",
        "CHUNK":  "file_chunk_payload",
        "CSUM":   "checksum_verification",
        "FEED":   "data_feed",
        "LOG":    "log_entry",
        "PACK":   "two_tier_corpus_encoding_for_at_rest_storage",
        "PULL":   "request_payload_from_node",
        "PUSH":   "push_payload_to_node",
        "Q":      "query",
        "RESUME": "resume_interrupted_transfer",
        "RT":     "return_transmit",
        "STAT":   "transfer_status_query",
        "UNPACK": "inference_free_semantic_retrieval_from_encoded_corpus",
        "XFER":   "initiate_file_transfer",
    },
    "E": {
        "EQ":  "environmental_query",
        "GPS": "gps_coordinates",
        "HU":  "humidity",
        "OBS": "obstacle",
        "PU":  "pressure",
        "TH":  "temperature_humidity_composite",
        "UV":  "ultraviolet",
    },
    "F": {
        "AV":  "authorization",
        "PRO": "proceed_protocol",
        "Q":   "query_request",
        "W":   "wait",
    },
    "G": {
        "BEARING": "heading_bearing",
        "CONF":    "position_confidence_rating",
        "DR":      "dead_reckoning_state",
        "ELEV":    "elevation_query",
        "POS":     "position_coordinates",
        "RANGE":   "distance_calculation",
        "ROUT":    "routing_query",
        "TRAIL":   "trail_segment_reference",
        "WPT":     "waypoint_reference",
    },
    "H": {
        # Layer 1 — ASD-resolvable semantic primitives
        "ALERT":  "threshold_crossing_event",
        "BP":     "blood_pressure",
        "CASREP": "casualty_report",
        "ECG":    "electrocardiogram",
        "GLUC":   "glucose",
        "HR":     "heart_rate",
        "MEDREC": "medical_record_log_entry",
        "RR":     "respiratory_rate",
        "SPO2":   "oxygen_saturation",
        "TEMP":   "body_temperature",
        "TRIAGE": "triage_classification",
        "VITALS": "composite_vitals_status",
        # Layer 2 — accessors into external open-ended registries
        # Slot value is the external code in brackets e.g. H:ICD[R00.1]
        # Slot values are exempt from the single-character encoding rule.
        # These opcodes are functional today with native code values.
        # MDR increases compression density; it does not gate functionality.
        "ICD":    "ICD-10_diagnosis_code_accessor",
        "SNOMED": "SNOMED_CT_concept_identifier_accessor",
        "CPT":    "CPT_procedure_code_accessor",
    },
    "I": {
        "AML":  "anti_money_laundering_check",
        "BIO":  "biometric_result",
        "CONS": "consent_and_scope_management",
        "ID":   "identity_assertion",
        "KYC":  "know_your_customer_check",
        "PERM": "permission_grant",
        "§":    "human_operator_confirmation",
    },
    "J": {
        "ABANDON": "abandon_plan",
        "BELIEF":  "assert_belief_state",
        "BLOCK":   "blocked_on_dependency",
        "COMMIT":  "commit_to_plan",
        "DECOMP":  "task_decomposition",
        "DONE":    "goal_achieved",
        "GOAL":    "declare_goal",
        "HANDOFF": "transfer_execution_with_full_state_context",
        "INTENT":  "assert_intention",
        "PLAN":    "transmit_plan_state",
        "REPLAN":  "trigger_replanning_from_current_state",
        "STATUS":  "execution_status",
        "STEP":    "current_plan_step",
        "SUBGOAL": "declare_subgoal",
    },
    "K": {
        "DIG": "digital_asset_operation",
        "ORD": "order_entry",
        "PAY": "payment_execution",
        "TRD": "trade_instruction",
        "XFR": "asset_transfer",
    },
    "L": {
        "ALERT":  "compliance_alert",
        "ATTEST": "compliance_attestation",
        "AUDIT":  "audit_log_entry",
        "CHAIN":  "chain_of_custody",
        "EXPORT": "log_export",
        "FORENS": "forensic_capture",
        "LOG":    "write_audit_record",
        "LSIGN":  "log_signature",
        "PURGE":  "log_purge",
        "QUERY":  "audit_trail_query",
        "REPORT": "compliance_report",
        "RETAIN": "log_retention_policy",
        "SEV":    "severity_level",
        "TRAIL":  "audit_trail_query",
    },
    "M": {
        "A":   "alert_alarm",
        "EVA": "evacuation",
        "IT":  "incident_type",
        "MA":  "municipal_alert",
        "RT":  "route",
    },
    "N": {
        "BK":   "backup_node",
        "CFG":  "configure",
        "CMD":  "command_node",
        "INET": "internet_uplink_capability_query",
        "PR":   "primary_relay",
        "Q":    "query_discovery",
        "S":    "status",
    },
    "O": {
        "AUTH":       "authority_level",
        "BW":         "available_bandwidth",
        "CHAN":        "active_channel_type",
        "CONOPS":     "concept_of_operations",
        "CONSTRAINT": "active_constraint_declaration",
        "DESC":        "operational_deescalation",
        "EMCON":      "emission_control_level",
        "ESC":        "operational_escalation",
        "FLOOR":      "payload_floor_bytes",
        "IAP":        "incident_action_plan",
        "LATENCY":    "link_latency_class",
        "LINK":       "link_quality",
        "MESH":       "mesh_topology_status",
        "MODE":       "operational_mode",
        "PERIOD":     "operational_period",
        "PHASE":      "operational_phase",
        "POSTURE":    "operational_posture",
        "READY":      "readiness_condition",
        "SCOPE":      "operational_scope",
        "TEMPO":      "operational_tempo",
        "TYPE":       "incident_type",
        "UPLINK":     "uplink_availability",
    },
    "P": {
        "CODE":   "maintenance_code_reference_for_compliance_logging",
        "DEVICE": "device_class_being_maintained",
        "GUIDE":  "procedure_guide_reference",
        "PART":   "part_reference",
        "STAT":   "completion_status",
        "STEP":   "step_index_within_guide",
    },
    "Q": {
        "BENCH":   "benchmark_assertion",
        "CITE":    "cite_source_for_claim",
        "CONF":    "confidence_interval_assertion",
        "CORRECT": "correction_directive",
        "CRIT":    "structured_critique_of_agent_output",
        "EVAL":    "evaluation_result",
        "FAIL":    "quality_gate_fail",
        "FLAG":    "flag_output_unreliable",
        "GROUND":  "grounding_assertion_against_source_document",
        "HALLU":   "hallucination_detection_flag",
        "PASS":    "quality_gate_pass",
        "REFLECT": "self_reflection_on_output_quality",
        "REVISE":  "request_revision_based_on_critique",
        "SCORE":   "quality_score_assertion",
        "VERIFY":  "request_verification_of_claim_by_another_agent",
    },
    "R": {
        # Physical agent opcodes — consequence class mandatory on all R instructions
        "COLLAB":  "collaborative_mode",
        "DPTH":    "depth_control",
        "DRVE":    "drive",
        "ESTOP":   "emergency_stop",
        "FORM":    "swarm_formation",
        "HANDOFF": "authority_handoff",
        "HDNG":    "heading",
        "LAND":    "landing",
        "MOV":     "move",
        "RTH":     "return_to_home_origin",
        "SRFC":    "surface_command_UUV",
        "STAT":    "status",
        "STOP":    "stop",
        "TKOF":    "takeoff",
        "WPT":     "waypoint",
        "ZONE":    "safety_zone_declaration",
        # Mobile device peripheral opcodes
        "ACCEL":  "accelerometer_data_stream",
        "BT":     "bluetooth_state",
        "CAM":    "camera_activation",
        "DISP":   "display_brightness_or_state",
        "GPS":    "gps_acquisition",
        "HAPTIC": "haptic_feedback_pattern",
        "MIC":    "microphone_activation",
        "NFC":    "nfc_read_write",
        "NOTIF":  "push_notification_to_device",
        "SCRN":   "screen_capture",
        "SPKR":   "speaker_audio_output",
        "TORCH":  "flashlight_on_off",
        "VIBE":   "vibration_pattern",
        "WIFI":   "wifi_state",
    },
    "S": {
        "ATST":   "attest",
        "CERT":   "certificate_operation",
        "DEC":    "decrypt",
        "ENC":    "encrypt",
        "HASH":   "hash",
        "HMAC":   "hmac",
        "KEYEX":  "key_exchange",
        "KEYGEN": "key_generation",
        "OPEN":   "open_sealed_payload",
        "REVOK":  "revoke",
        "ROTATE": "key_rotation",
        "SEAL":   "seal_payload",
        "SIGN":   "sign",
        "TRUST":  "trust_assertion",
        "VFY":    "verify_signature",
    },
    "T": {
        "AFTER":  "execute_after_condition",
        "ALARM":  "time_alarm",
        "BEFORE": "execute_before_deadline",
        "CRON":   "cron_expression",
        "DELAY":  "delay_execution",
        "DUR":    "duration_constraint",
        "EPOCH":  "unix_epoch_reference",
        "EXP":    "expiration",
        "NOW":    "current_timestamp_query",
        "REPEAT": "recurring_schedule",
        "SCHED":  "schedule_event",
        "SYNC":   "time_synchronization",
        "UNTIL":  "execute_until_condition",
        "WIN":    "time_window",
    },
    "U": {
        "ACK":      "human_acknowledgment",
        "ALERT":    "urgent_operator_alert",
        "APPROVE":  "request_human_approval",
        "ASSIGN":   "assign_task_to_human_operator",
        "CONFIRM":  "request_human_confirmation",
        "DELEGATE": "delegate_to_human",
        "DISPLAY":  "display_information_to_operator",
        "ESCALATE": "escalate_to_human_decision_maker",
        "FEEDBACK": "request_human_feedback",
        "INPUT":    "request_operator_input",
        "NOTIFY":   "surface_message_to_operator",
        "OVERRIDE": "human_override_instruction",
        "REJECT":   "human_rejection",
        "REVIEW":   "request_human_review",
    },
    "V": {
        "AIS":    "ais_position_report",
        "CARGO":  "cargo_manifest",
        "COURSE": "course_over_ground",
        "DOCK":   "docking_operation",
        "ETA":    "estimated_time_arrival",
        "ETD":    "estimated_time_departure",
        "FLEET":  "fleet_coordination",
        "HDG":    "heading",
        "MAYDAY": "distress_signal",
        "MMSI":   "maritime_mobile_service_identity",
        "PANPAN": "urgency_signal",
        "PORT":   "port_of_call",
        "POS":    "vehicle_position",
        "ROUTE":  "routing_instruction",
        "SPEED":  "speed_over_ground",
        "STATUS": "vessel_status",
        "UNDOCK": "undocking_operation",
    },
    "W": {
        "ALERT":  "weather_alert",
        "FCST":   "forecast_product",
        "FIRE":   "fire_weather_data",
        "FLOOD":  "flood_data",
        "HURR":   "hurricane_data",
        "METAR":  "aviation_weather_observation",
        "PRECIP": "precipitation",
        "PRESS":  "barometric_pressure",
        "TAF":    "terminal_area_forecast",
        "TEMP":   "ambient_temperature",
        "VIS":    "visibility_report",
        "WARN":   "weather_warning",
        "WATCH":  "weather_watch",
        "WIND":   "wind_speed_and_direction",
    },
    "X": {
        "DR":      "demand_response_signal",
        "EV":      "ev_charging_state",
        "FAULT":   "fault_event",
        "FREQ":    "grid_frequency",
        "GEN":     "generation_output",
        "GRID":    "grid_connection_status",
        "ISLND":   "islanding_operation",
        "LOAD":    "load_reading",
        "METER":   "meter_reading",
        "PRICE":   "energy_price_signal",
        "RESTORE": "grid_restoration",
        "SHED":    "load_shedding_instruction",
        "SOLAR":   "solar_generation",
        "STORE":   "storage_state",
        "VOLT":    "voltage_level",
        "WIND":    "wind_generation",
    },
    "Y": {
        "CLEAR":    "clear_memory_tier",
        "EMBED":    "generate_embedding_for_storage",
        "FETCH":    "retrieve_by_key",
        "FORGET":   "delete_from_memory",
        "INDEX":    "index_document_for_retrieval",
        "PAGE":     "page_out_working_memory_to_external_store",
        "PROMOTE":  "promote_working_to_long_term_memory",
        "RECALL":   "retrieve_episodic_memory_by_context",
        "RETRIEVE": "retrieve_from_LCS",
        "SEARCH":   "semantic_vector_search",
        "SHARE":    "share_memory_segment_with_another_agent",
        "STAT":     "report_memory_utilization",
        "STORE":    "store_to_memory",
        "SUMM":     "summarize_and_compress_memory_segment",
        "SYNC":     "synchronize_memory_state_with_peer",
    },
    "Z": {
        # Z:INF is the canonical opcode — invoke_inference
        "BATCH":   "batch_inference_request",
        "CACHE":   "kv_cache_utilization_instruction",
        "CAP":     "capability_query",
        "CONF":    "agent_reported_confidence",
        "COST":    "inference_cost_report",
        "CTX":     "context_window_utilization",
        "EMBED":   "embedding_generation_request",
        "FINISH":  "finish_reason",
        "INF":     "invoke_inference",
        "LATENCY": "inference_latency_measurement",
        "MAXT":    "max_tokens_parameter",
        "MDLUSED": "actual_model_used_in_inference_response",
        "MODEL":   "specify_model_by_identifier",
        "RESP":    "inference_response_payload_envelope",
        "ROUTE":   "route_to_model_with_specified_capability",
        "STOP":    "stop_sequence",
        "STREAM":  "streaming_response_flag",
        "TEMP":    "temperature_parameter",
        "TOKENS":  "token_count_report",
        "TOPK":    "top_k_sampling_parameter",
        "TOPP":    "top_p_nucleus_sampling_parameter",
    },
}


# ─────────────────────────────────────────────────────────────────────────────
# ADAPTIVE SHARED DICTIONARY
# ─────────────────────────────────────────────────────────────────────────────

class AdaptiveSharedDictionary:
    """
    Version-pinned ASD with CRDT delta sync.

    ADDITIVE  = grow-only set  (Shapiro et al. G-Set)
    REPLACE   = LWW-register   (Shapiro et al. LWW-Register)
    DEPRECATE = tombstone      (Shapiro et al. 2P-Set)
    """

    class UpdateMode(Enum):
        ADDITIVE  = auto()
        REPLACE   = auto()
        DEPRECATE = auto()

    def __init__(self, floor_version: str = ASD_FLOOR_VERSION):
        self.floor_version = floor_version
        self._data: dict[str, dict[str, str]] = {
            ns: dict(ops) for ns, ops in ASD_BASIS.items()
        }
        self._tombstones: set[tuple[str, str]] = set()
        self._version_log: list[dict] = []

    def lookup(self, namespace: str, opcode: str) -> str | None:
        if (namespace, opcode) in self._tombstones:
            return None
        return self._data.get(namespace, {}).get(opcode)

    def apply_delta(self, namespace: str, opcode: str, definition: str,
                    mode: UpdateMode, version_pointer: str) -> None:
        self._version_log.append({"ns": namespace, "op": opcode,
                                  "def": definition, "mode": mode.name,
                                  "ver": version_pointer})
        if mode == self.UpdateMode.ADDITIVE:
            if namespace not in self._data:
                self._data[namespace] = {}
            if opcode not in self._data[namespace]:
                self._data[namespace][opcode] = definition
        elif mode == self.UpdateMode.REPLACE:
            if namespace not in self._data:
                self._data[namespace] = {}
            self._data[namespace][opcode] = definition
            self._tombstones.discard((namespace, opcode))
        elif mode == self.UpdateMode.DEPRECATE:
            self._tombstones.add((namespace, opcode))

    def fingerprint(self) -> str:
        content = json.dumps(self._data, sort_keys=True).encode()
        return hashlib.sha256(content).hexdigest()[:16]

    def namespaces(self) -> list[str]:
        return sorted(self._data.keys())


# ─────────────────────────────────────────────────────────────────────────────
# FRAME NEGOTIATION PROTOCOL (FNP) — Session Handshake State Machine
#
# Two-message capability advertisement + acknowledgment completing within
# 80 bytes total (40 + 38), designed for LoRa physical layer payload floor.
#
# Wire format:
#
#   FNP_ADV (Capability Advertisement, 40 bytes):
#     msg_type           1B   0x01
#     protocol_version   1B   0x01
#     fingerprint        8B   first 8 bytes of SHA-256(ASD content)
#     asd_version        u16  BE
#     namespace_bitmap   u32  BE (bit 0=A .. bit 25=Z, bit 26=Omega)
#     channel_capacity   1B   0x00=51B floor, 0x01=255B, 0x02=512B, 0x03=unconstrained
#     node_id           23B   null-padded UTF-8
#
#   FNP_ACK (Capability Acknowledgment, 38 bytes):
#     msg_type           1B   0x02 (ACK) or 0x03 (NACK)
#     match_status       1B   0x00=exact, 0x01=version_mismatch,
#                             0x02=fingerprint_mismatch
#     echo_fingerprint   8B   fingerprint from received ADV
#     own_fingerprint    8B   responder's own fingerprint
#     common_namespaces  u32  BE (intersection of both bitmaps)
#     neg_capacity       1B   negotiated capacity = min(adv, own)
#     node_id           15B   null-padded UTF-8
#
# Channel capacity negotiation: the session byte budget is the minimum
# of what both nodes declare.  BAEL selects encoding mode within this
# budget for every subsequent instruction.  This ensures the session
# scales within the lowest-capability link in the mesh path.
#
# State machine:
#   IDLE -> initiate() -> ADV_SENT
#   ADV_SENT -> receive ACK (match) -> ESTABLISHED
#   ADV_SENT -> receive ACK (mismatch) -> SYNC_NEEDED
#   ADV_SENT -> timeout -> IDLE
#   IDLE -> receive ADV -> send ACK -> ESTABLISHED or SYNC_NEEDED
#
# Patent ref: OSMP-001-UTIL Section II.C, FIG. 5
# ─────────────────────────────────────────────────────────────────────────────

FNP_MSG_ADV  = 0x01
FNP_MSG_ACK  = 0x02
FNP_MSG_NACK = 0x03

FNP_MATCH_EXACT       = 0x00
FNP_MATCH_VERSION     = 0x01
FNP_MATCH_FINGERPRINT = 0x02

# Channel capacity classes
FNP_CAP_FLOOR        = 0x00  # 51 bytes (LoRa SF12 BW125kHz)
FNP_CAP_STANDARD     = 0x01  # 255 bytes (LoRa SF11 BW250kHz / Meshtastic LongFast)
FNP_CAP_BLE          = 0x02  # 512 bytes (BLE)
FNP_CAP_UNCONSTRAINED = 0x03  # no limit (WiFi, HTTP, cloud)

FNP_CAP_BYTES = {
    FNP_CAP_FLOOR: 51,
    FNP_CAP_STANDARD: 255,
    FNP_CAP_BLE: 512,
    FNP_CAP_UNCONSTRAINED: 0,  # 0 = no limit
}

FNP_ADV_SIZE = 40
FNP_ACK_SIZE = 38
FNP_PROTOCOL_VERSION = 0x01

# Namespace bitmap: bit position = ord(letter) - ord('A'), bit 26 = Omega
_NS_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"


def _namespace_bitmap(namespaces: list[str]) -> int:
    """Encode a list of namespace prefixes as a 32-bit bitmap."""
    bitmap = 0
    for ns in namespaces:
        if len(ns) == 1 and ns in _NS_LETTERS:
            bitmap |= 1 << (_NS_LETTERS.index(ns))
        elif ns == "\u03A9":  # Omega
            bitmap |= 1 << 26
    return bitmap


def _bitmap_to_namespaces(bitmap: int) -> list[str]:
    """Decode a 32-bit bitmap to a sorted list of namespace prefixes."""
    result = []
    for i, letter in enumerate(_NS_LETTERS):
        if bitmap & (1 << i):
            result.append(letter)
    if bitmap & (1 << 26):
        result.append("\u03A9")
    return result


def _fingerprint_bytes(asd: AdaptiveSharedDictionary) -> bytes:
    """Return the first 8 bytes of the ASD SHA-256 digest (binary)."""
    content = json.dumps(asd._data, sort_keys=True).encode()
    return hashlib.sha256(content).digest()[:8]


class FNPSession:
    """FNP session handshake state machine.

    Manages the two-message capability advertisement and acknowledgment
    exchange between two sovereign nodes.  After a successful handshake,
    provides the negotiated session state: whether dictionaries match,
    which namespaces are shared, and the remote node's identity.

    Usage (initiator):
        session = FNPSession(asd, "NODE_A")
        adv_packet = session.initiate()
        # ... transmit adv_packet, receive ack_packet ...
        session.receive(ack_packet)
        assert session.state == "ESTABLISHED"

    Usage (responder):
        session = FNPSession(asd, "NODE_B")
        ack_packet = session.receive(adv_packet)
        # ... transmit ack_packet ...
        assert session.state == "ESTABLISHED"
    """

    def __init__(self, asd: AdaptiveSharedDictionary, node_id: str,
                 asd_version: int = 1,
                 channel_capacity: int = FNP_CAP_FLOOR):
        self.asd = asd
        self.node_id = node_id
        self.asd_version = asd_version
        self.channel_capacity = channel_capacity
        self.state = "IDLE"
        self.remote_node_id: str | None = None
        self.remote_fingerprint: bytes | None = None
        self.common_namespaces: list[str] | None = None
        self.match_status: int | None = None
        self.negotiated_capacity: int | None = None
        self._own_fp = _fingerprint_bytes(asd)
        self._own_bitmap = _namespace_bitmap(asd.namespaces())

    # ── packet construction ──────────────────────────────────────────

    def _build_adv(self) -> bytes:
        """Build a 40-byte FNP_ADV packet."""
        buf = bytearray(FNP_ADV_SIZE)
        buf[0] = FNP_MSG_ADV
        buf[1] = FNP_PROTOCOL_VERSION
        buf[2:10] = self._own_fp
        struct.pack_into(">H", buf, 10, self.asd_version)
        struct.pack_into(">I", buf, 12, self._own_bitmap)
        buf[16] = self.channel_capacity
        nid = self.node_id.encode("utf-8")[:23]
        buf[17 : 17 + len(nid)] = nid
        return bytes(buf)

    def _build_ack(self, remote_fp: bytes, match: int,
                   common_bitmap: int, neg_cap: int) -> bytes:
        """Build a 38-byte FNP_ACK packet."""
        buf = bytearray(FNP_ACK_SIZE)
        msg_type = FNP_MSG_ACK if match == FNP_MATCH_EXACT else FNP_MSG_NACK
        buf[0] = msg_type
        buf[1] = match
        buf[2:10] = remote_fp
        buf[10:18] = self._own_fp
        struct.pack_into(">I", buf, 18, common_bitmap)
        buf[22] = neg_cap
        nid = self.node_id.encode("utf-8")[:15]
        buf[23 : 23 + len(nid)] = nid
        return bytes(buf)

    # ── packet parsing ───────────────────────────────────────────────

    @staticmethod
    def _parse_adv(data: bytes) -> dict:
        if len(data) < FNP_ADV_SIZE or data[0] != FNP_MSG_ADV:
            raise ValueError("Invalid FNP_ADV packet")
        return {
            "protocol_version": data[1],
            "fingerprint": bytes(data[2:10]),
            "asd_version": struct.unpack(">H", data[10:12])[0],
            "namespace_bitmap": struct.unpack(">I", data[12:16])[0],
            "channel_capacity": data[16],
            "node_id": data[17:40].rstrip(b"\x00").decode("utf-8"),
        }

    @staticmethod
    def _parse_ack(data: bytes) -> dict:
        if len(data) < FNP_ACK_SIZE or data[0] not in (FNP_MSG_ACK, FNP_MSG_NACK):
            raise ValueError("Invalid FNP_ACK packet")
        return {
            "msg_type": data[0],
            "match_status": data[1],
            "echo_fingerprint": bytes(data[2:10]),
            "own_fingerprint": bytes(data[10:18]),
            "common_bitmap": struct.unpack(">I", data[18:22])[0],
            "negotiated_capacity": data[22],
            "node_id": data[23:38].rstrip(b"\x00").decode("utf-8"),
        }

    # ── state machine ────────────────────────────────────────────────

    def initiate(self) -> bytes:
        """Start a handshake by building and returning an FNP_ADV packet.

        Transitions: IDLE -> ADV_SENT

        Returns
        -------
        bytes : 40-byte FNP_ADV packet ready for transmission.
        """
        if self.state != "IDLE":
            raise RuntimeError(f"Cannot initiate from state {self.state}")
        self.state = "ADV_SENT"
        return self._build_adv()

    def receive(self, data: bytes) -> bytes | None:
        """Process a received FNP packet.

        If IDLE and an ADV is received, computes match status and returns
        an ACK packet for transmission.  Transitions to ESTABLISHED or
        SYNC_NEEDED.

        If ADV_SENT and an ACK is received, reads the match result.
        Transitions to ESTABLISHED or SYNC_NEEDED.  Returns None.

        Parameters
        ----------
        data : bytes, received packet (40 bytes for ADV, 38 for ACK).

        Returns
        -------
        bytes or None : ACK packet to transmit (when responding to ADV),
                        or None (when processing a received ACK).
        """
        msg_type = data[0]

        if msg_type == FNP_MSG_ADV and self.state == "IDLE":
            adv = self._parse_adv(data)
            self.remote_node_id = adv["node_id"]
            self.remote_fingerprint = adv["fingerprint"]

            # determine match status
            if adv["fingerprint"] == self._own_fp:
                if adv["asd_version"] == self.asd_version:
                    match = FNP_MATCH_EXACT
                else:
                    match = FNP_MATCH_VERSION
            else:
                match = FNP_MATCH_FINGERPRINT

            common = self._own_bitmap & adv["namespace_bitmap"]
            self.common_namespaces = _bitmap_to_namespaces(common)
            self.match_status = match

            # negotiate capacity: LCD of both nodes
            # lower class = fewer bytes = more constrained
            neg_cap = min(adv["channel_capacity"], self.channel_capacity)
            self.negotiated_capacity = neg_cap

            self.state = "ESTABLISHED" if match == FNP_MATCH_EXACT else "SYNC_NEEDED"
            return self._build_ack(adv["fingerprint"], match, common, neg_cap)

        if msg_type in (FNP_MSG_ACK, FNP_MSG_NACK) and self.state == "ADV_SENT":
            ack = self._parse_ack(data)

            # verify echo fingerprint matches our own
            if ack["echo_fingerprint"] != self._own_fp:
                raise ValueError("FNP_ACK echo fingerprint mismatch")

            self.remote_node_id = ack["node_id"]
            self.remote_fingerprint = ack["own_fingerprint"]
            self.common_namespaces = _bitmap_to_namespaces(ack["common_bitmap"])
            self.match_status = ack["match_status"]
            self.negotiated_capacity = ack["negotiated_capacity"]
            self.state = ("ESTABLISHED" if ack["match_status"] == FNP_MATCH_EXACT
                          else "SYNC_NEEDED")
            return None

        raise ValueError(
            f"Unexpected msg_type 0x{msg_type:02x} in state {self.state}"
        )

    def timeout(self) -> None:
        """Handle handshake timeout.  Transitions ADV_SENT -> IDLE."""
        if self.state == "ADV_SENT":
            self.state = "IDLE"
            self.remote_node_id = None
            self.remote_fingerprint = None
            self.common_namespaces = None
            self.match_status = None
            self.negotiated_capacity = None


# ─────────────────────────────────────────────────────────────────────────────
# SAL ENCODER
# ─────────────────────────────────────────────────────────────────────────────

class SALEncoder:
    def __init__(self, asd: AdaptiveSharedDictionary | None = None):
        self.asd = asd or AdaptiveSharedDictionary()

    def encode_frame(self, namespace: str, opcode: str, target: str | None = None,
                     query_slot: str | None = None,
                     slots: dict[str, str | int | float] | None = None,
                     consequence_class: str | None = None) -> str:
        if namespace == "R" and consequence_class not in CONSEQUENCE_CLASSES:
            raise ValueError(
                f"R namespace requires consequence class (⚠/↺/⊘). Got: {consequence_class!r}")
        parts = [f"{namespace}:{opcode}"]
        if target is not None:
            parts.append(f"@{target}")
        if query_slot is not None:
            parts.append(f"?{query_slot}")
        if slots:
            for k, v in slots.items():
                parts.append(f":{k}:{v}")
        if consequence_class:
            parts.append(consequence_class)
        return "".join(parts)

    def encode_compound(self, left: str, operator: str, right: str) -> str:
        if operator not in GLYPH_OPERATORS and operator not in COMPOUND_OPERATORS:
            raise ValueError(f"Unknown operator: {operator!r}")
        return f"{left}{operator}{right}"

    def encode_parallel(self, instructions: list[str]) -> str:
        inner = "∧".join(f"?{i}" if not i.startswith("?") else i for i in instructions)
        return f"A∥[{inner}]"

    def encode_sequence(self, instructions: list[str]) -> str:
        return ";".join(instructions)

    def encode_broadcast(self, namespace: str, opcode: str) -> str:
        return f"{namespace}:{opcode}@*"


# ─────────────────────────────────────────────────────────────────────────────
# SAL DECODER
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class DecodedInstruction:
    namespace:             str
    opcode:                str
    opcode_meaning:        str | None
    target:                str | None
    query_slot:            str | None
    slots:                 dict[str, str]
    consequence_class:     str | None
    consequence_class_name: str | None
    raw:                   str


class SALDecoder:
    """
    Inference-free SAL decoder.
    All parsing is table lookup — no statistical models, no ambiguity resolution.
    Analog: HPACK static table decode (RFC 7541 §A).
    """

    def __init__(self, asd: AdaptiveSharedDictionary | None = None):
        self.asd = asd or AdaptiveSharedDictionary()

    def _resolve_short_form(self, opcode: str) -> str:
        """Resolve namespace for short-form frames by ASD lookup.
        Returns first matching namespace, or 'A' as default."""
        for ns, ops in ASD_BASIS.items():
            if opcode in ops:
                return ns
        return "A"

    def _first_stop(self, s: str, stops: list[str]) -> int:
        earliest = len(s)
        for sc in stops:
            idx = s.find(sc)
            if idx != -1 and idx < earliest:
                earliest = idx
        return earliest

    def decode_frame(self, encoded: str) -> DecodedInstruction:
        raw = encoded.strip()
        remaining = raw

        # Extract consequence class suffix (R namespace)
        cc = None
        cc_name = None
        for glyph, entry in CONSEQUENCE_CLASSES.items():
            if remaining.endswith(glyph):
                cc = glyph
                cc_name = entry["name"]
                runes = list(remaining)
                glyph_runes = list(glyph)
                remaining = "".join(runes[:-len(glyph_runes)])
                break

        # Detect explicit namespace (colon before first @ or ?)
        before_target = remaining.split("@")[0].split("?")[0]
        has_explicit_ns = ":" in before_target

        namespace: str
        if has_explicit_ns:
            first_colon = remaining.index(":")
            namespace = remaining[:first_colon]
            remaining = remaining[first_colon + 1:]
        else:
            pre = remaining.split("@")[0].split("?")[0]
            namespace = self._resolve_short_form(pre)

        # Extract opcode
        opcode_end = self._first_stop(remaining, ["@", "?", ":"])
        opcode = remaining[:opcode_end]
        remaining = remaining[opcode_end:]

        opcode_meaning = self.asd.lookup(namespace, opcode)

        # Extract target
        target = None
        if remaining.startswith("@"):
            remaining = remaining[1:]
            end = self._first_stop(remaining, ["?", ":", "∧", "∨", "→", "↔", ";", "∥"])
            target = remaining[:end]
            remaining = remaining[end:]

        # Extract query slot
        query_slot = None
        if remaining.startswith("?"):
            remaining = remaining[1:]
            end = self._first_stop(remaining, [":", "∧", "∨", "→", ";"])
            query_slot = remaining[:end]
            remaining = remaining[end:]

        # Extract slot assignments
        slots: dict[str, str] = {}
        while remaining.startswith(":"):
            remaining = remaining[1:]
            colon_idx = remaining.find(":")
            if colon_idx == -1:
                slots[remaining] = ""
                remaining = ""
                break
            slot_name = remaining[:colon_idx]
            remaining = remaining[colon_idx + 1:]
            val_end = self._first_stop(remaining, [":", "∧", "∨", "→", ";", "⚠", "↺", "⊘"])
            slots[slot_name] = remaining[:val_end]
            remaining = remaining[val_end:]

        return DecodedInstruction(
            namespace=namespace, opcode=opcode, opcode_meaning=opcode_meaning,
            target=target, query_slot=query_slot, slots=slots,
            consequence_class=cc, consequence_class_name=cc_name, raw=raw,
        )

    def decode_natural_language(self, encoded: str) -> str:
        try:
            d = self.decode_frame(encoded)
        except Exception:
            return f"[malformed: {encoded!r}]"
        parts = [f"{d.namespace}:{d.opcode_meaning or d.opcode}"]
        if d.target:
            parts.append("→*" if d.target == "*" else f"→{d.target}")
        if d.query_slot:
            parts.append(f"?{d.query_slot}")
        for k, v in d.slots.items():
            parts.append(f"{k}={v}")
        if d.consequence_class_name:
            parts.append(f"[{d.consequence_class_name}]")
        return " ".join(parts)


# ─────────────────────────────────────────────────────────────────────────────
# OVERFLOW PROTOCOL
# ─────────────────────────────────────────────────────────────────────────────

class LossPolicy(Enum):
    FAIL_SAFE            = "Φ"
    GRACEFUL_DEGRADATION = "Γ"
    ATOMIC               = "Λ"


@dataclass
class Fragment:
    msg_id:   int
    frag_idx: int
    frag_ct:  int
    flags:    int
    dep:      int
    payload:  bytes

    @property
    def is_terminal(self) -> bool:
        return bool(self.flags & FLAG_TERMINAL)

    @property
    def is_critical(self) -> bool:
        return bool(self.flags & FLAG_CRITICAL)

    def pack(self) -> bytes:
        return struct.pack(">HBBBB", self.msg_id, self.frag_idx,
                           self.frag_ct, self.flags, self.dep) + self.payload

    @classmethod
    def unpack(cls, data: bytes) -> "Fragment":
        if len(data) < FRAGMENT_HEADER_BYTES:
            raise ValueError(f"Fragment too short: {len(data)} bytes")
        msg_id, fi, fc, flags, dep = struct.unpack(">HBBBB", data[:6])
        return cls(msg_id=msg_id, frag_idx=fi, frag_ct=fc,
                   flags=flags, dep=dep, payload=data[6:])


class OverflowProtocol:
    """
    Three-tier fragmentation with loss tolerance.

    Tier 1: Single packet
    Tier 2: Sequential burst
    Tier 3: DAG decomposition

    Analog: QUIC receive buffer (RFC 9000 §2.2)
    """

    def __init__(self, mtu: int = LORA_STANDARD_BYTES,
                 policy: LossPolicy = LossPolicy.GRACEFUL_DEGRADATION,
                 timeout: int = 30):
        self.mtu = mtu
        self.policy = policy
        self.timeout = timeout
        self._msg_counter = 0
        self._buffer: dict[int, dict[int, Fragment]] = {}
        self._dag_reassembler = DAGReassembler(policy=policy)

    def _next_msg_id(self) -> int:
        self._msg_counter = (self._msg_counter + 1) % 65536
        return self._msg_counter

    def fragment(self, payload: bytes, critical: bool = False) -> list[Fragment]:
        available = self.mtu - FRAGMENT_HEADER_BYTES
        if len(payload) + FRAGMENT_HEADER_BYTES <= self.mtu:
            return [Fragment(
                msg_id=self._next_msg_id(), frag_idx=0, frag_ct=1,
                flags=FLAG_TERMINAL | (FLAG_CRITICAL if critical else 0),
                dep=0, payload=payload,
            )]
        chunks = [payload[i:i + available] for i in range(0, len(payload), available)]
        msg_id = self._next_msg_id()
        frags = []
        for idx, chunk in enumerate(chunks):
            is_last = idx == len(chunks) - 1
            flags = (FLAG_TERMINAL if is_last else 0) | (FLAG_CRITICAL if critical else 0)
            frags.append(Fragment(msg_id=msg_id, frag_idx=idx, frag_ct=len(chunks),
                                  flags=flags, dep=0, payload=chunk))
        return frags

    def fragment_dag(self, compound_sal: str,
                     critical: bool = False) -> list[Fragment]:
        """Tier 3: decompose a compound SAL instruction into a DAG of fragments.

        Use when the instruction contains conditional branches (→),
        parallel forks (∧, ∥), or sequential dependencies (;) that
        require dependency-aware execution order on the receiver.
        """
        fragmenter = DAGFragmenter(mtu=self.mtu)
        msg_id = self._next_msg_id()
        return fragmenter.fragmentize(compound_sal, msg_id, critical=critical)

    def receive(self, frag: Fragment) -> bytes | None:
        # R:ESTOP hard exception — execute immediately regardless of policy
        # Asymmetric harm: unnecessary stop is recoverable; failure to stop is not.
        if b"R:ESTOP" in frag.payload:
            return frag.payload

        mid = frag.msg_id
        if mid not in self._buffer:
            self._buffer[mid] = {}
        self._buffer[mid][frag.frag_idx] = frag
        received = self._buffer[mid]
        expected = frag.frag_ct

        if self.policy == LossPolicy.ATOMIC or frag.is_critical:
            if len(received) == expected:
                return self._reassemble(received, expected)
            return None
        elif self.policy == LossPolicy.GRACEFUL_DEGRADATION:
            if frag.is_terminal and len(received) == expected:
                return self._reassemble(received, expected)
            if frag.is_terminal:
                return self._reassemble_partial(received, expected)
            return None
        else:  # FAIL_SAFE
            if len(received) == expected:
                return self._reassemble(received, expected)
            return None

    def _reassemble(self, received: dict, expected: int) -> bytes:
        return b"".join(received[i].payload for i in range(expected))

    def _reassemble_partial(self, received: dict, expected: int) -> bytes:
        result = b""
        for i in range(expected):
            if i not in received:
                break
            result += received[i].payload
        return result

    def receive_dag(self, frag: Fragment) -> list[bytes] | None:
        """Tier 3 receive: buffer fragment and attempt DAG resolution.

        Returns ordered list of payloads in dependency-resolved execution
        order, or None if the message is not yet resolvable under the
        current loss tolerance policy.
        """
        return self._dag_reassembler.receive(frag)

    def nack(self, msg_id: int, expected_ct: int) -> str:
        have = set(self._buffer.get(msg_id, {}).keys())
        missing = sorted(set(range(expected_ct)) - have)
        return f"A:NACK[MSG:{msg_id}∖[{','.join(str(i) for i in missing)}]]"


# ─────────────────────────────────────────────────────────────────────────────
# TIER 3 — DAG DECOMPOSITION
# Overflow Protocol Tier 3: directed acyclic graph fragmentation for
# instructions with conditional branches and dependency chains.
# Analog: Kahn's algorithm (1962) applied to lossy radio fragment streams.
#
# Patent: OSMP-001-UTIL claims, spec §8.1 Tier 3 definition.
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class DAGNode:
    """Single executable unit in a Tier 3 DAG."""
    index:   int            # fragment index (position in fragment list)
    payload: bytes          # SAL instruction bytes for this unit
    parents: list[int]      # indices of parent nodes (dependencies)


class DAGFragmenter:
    """
    Transmit-side Tier 3: decompose a compound SAL instruction into a DAG
    of executable units with dependency pointers.

    The SAL compound operators define the DAG structure:
      ;  (SEQUENCE)  — linear chain: right depends on left
      →  (THEN)      — conditional: right depends on left
      ∧  (AND)       — parallel: both depend on same parent (fork)
      ∥  (PARALLEL)  — parallel execution block

    Single-parent dependencies use the DEP header byte directly.
    Multi-parent dependencies (e.g., diamond join) set FLAGS bit 3
    (FLAG_EXTENDED_DEP) and prefix the payload with a 4-byte u32 bitmap
    where bit N = dependency on fragment N.

    Fragment header remains 6 bytes. Backward compatible: Tier 1/2
    fragments with DEP=0x00 and FLAGS bit 3 clear are unchanged.
    """

    def __init__(self, mtu: int = LORA_STANDARD_BYTES):
        self.mtu = mtu

    def parse(self, compound_sal: str) -> list[DAGNode]:
        """Parse a compound SAL string into DAGNodes.

        Recognizes ; → ∧ ∥ as structural operators.
        Atomic SAL frames become leaf nodes.
        """
        nodes: list[DAGNode] = []
        self._parse_expr(compound_sal.strip(), nodes, parent_indices=[])
        return nodes

    def _parse_expr(self, expr: str, nodes: list[DAGNode],
                    parent_indices: list[int]) -> list[int]:
        """Recursively parse SAL expression into DAG nodes.
        Returns list of tail node indices (nodes with no dependents yet)."""

        # Try splitting on ; (SEQUENCE) first — lowest precedence
        parts = self._split_top_level(expr, ";")
        if len(parts) > 1:
            tails = parent_indices
            for part in parts:
                tails = self._parse_expr(part.strip(), nodes, tails)
            return tails

        # Try → (THEN) — conditional chain
        parts = self._split_top_level(expr, "→")
        if len(parts) > 1:
            tails = parent_indices
            for part in parts:
                tails = self._parse_expr(part.strip(), nodes, tails)
            return tails

        # Try ∧ (AND) — parallel fork
        parts = self._split_top_level(expr, "∧")
        if len(parts) > 1:
            all_tails: list[int] = []
            for part in parts:
                branch_tails = self._parse_expr(part.strip(), nodes, parent_indices)
                all_tails.extend(branch_tails)
            return all_tails

        # Try ∥ inside A∥[...] — parallel execution block
        if expr.startswith("A∥[") and expr.endswith("]"):
            inner = expr[len("A∥["):-1]
            parts = self._split_top_level(inner, "∧")
            if len(parts) <= 1:
                # Single item in parallel block, treat as leaf
                parts = [inner]
            all_tails = []
            for part in parts:
                clean = part.strip()
                if clean.startswith("?"):
                    clean = clean[1:]
                branch_tails = self._parse_expr(clean, nodes, parent_indices)
                all_tails.extend(branch_tails)
            return all_tails

        # Atomic leaf node
        idx = len(nodes)
        nodes.append(DAGNode(
            index=idx,
            payload=expr.encode("utf-8"),
            parents=list(parent_indices),
        ))
        return [idx]

    @staticmethod
    def _split_top_level(expr: str, sep: str) -> list[str]:
        """Split expression on separator, respecting bracket depth."""
        parts: list[str] = []
        depth = 0
        current: list[str] = []
        i = 0
        chars = list(expr)
        sep_chars = list(sep)
        sep_len = len(sep_chars)

        while i < len(chars):
            ch = chars[i]
            if ch in ("[", "("):
                depth += 1
                current.append(ch)
                i += 1
            elif ch in ("]", ")"):
                depth -= 1
                current.append(ch)
                i += 1
            elif depth == 0 and chars[i:i + sep_len] == sep_chars:
                parts.append("".join(current))
                current = []
                i += sep_len
            else:
                current.append(ch)
                i += 1
        if current:
            parts.append("".join(current))
        return parts

    def fragmentize(self, compound_sal: str, msg_id: int,
                    critical: bool = False) -> list[Fragment]:
        """Full Tier 3 pipeline: parse → assign DEP → emit Fragments."""
        nodes = self.parse(compound_sal)
        if not nodes:
            return []

        frag_ct = len(nodes)
        frags: list[Fragment] = []

        for node in nodes:
            is_last = node.index == frag_ct - 1
            flags = (FLAG_TERMINAL if is_last else 0) | \
                    (FLAG_CRITICAL if critical else 0)

            if len(node.parents) == 0:
                # Root node: self-reference signals no dependency
                # DEP == frag_idx is unambiguous (cannot depend on self)
                dep = node.index
                payload = node.payload
            elif len(node.parents) == 1:
                # Single parent: use DEP byte directly
                dep = node.parents[0]
                payload = node.payload
            else:
                # Multi-parent: set extended dep flag, prefix with bitmap
                flags |= FLAG_EXTENDED_DEP
                dep = node.parents[0]  # primary dep in header for legacy readers
                bitmap = 0
                for p in node.parents:
                    bitmap |= (1 << p)
                payload = struct.pack(">I", bitmap) + node.payload

            frags.append(Fragment(
                msg_id=msg_id, frag_idx=node.index, frag_ct=frag_ct,
                flags=flags, dep=dep, payload=payload,
            ))

        return frags


class DAGReassembler:
    """
    Receive-side Tier 3: buffer fragments, resolve dependency DAG,
    execute in topological order under loss tolerance policy.

    Execution semantics:
      - Topological sort of received fragments whose full ancestor
        chains are present.
      - Under Gamma: execute maximal resolvable subgraph.
      - Under Lambda: execute nothing unless all fragments received.
      - Under Phi: discard everything if any fragment missing.
      - R:ESTOP overrides everything: executes immediately on receipt.
    """

    def __init__(self, policy: LossPolicy = LossPolicy.GRACEFUL_DEGRADATION):
        self.policy = policy
        self._buffer: dict[int, dict[int, Fragment]] = {}  # msg_id -> {frag_idx: Fragment}

    def receive(self, frag: Fragment) -> list[bytes] | None:
        """Buffer a fragment and attempt DAG resolution.

        Returns ordered list of payloads in execution order, or None if
        the message is not yet resolvable.
        """
        # R:ESTOP hard exception — immediate execution, no DAG resolution
        if b"R:ESTOP" in frag.payload:
            return [frag.payload]

        mid = frag.msg_id
        if mid not in self._buffer:
            self._buffer[mid] = {}
        self._buffer[mid][frag.frag_idx] = frag
        received = self._buffer[mid]
        expected = frag.frag_ct

        # Check completeness based on policy
        if self.policy == LossPolicy.FAIL_SAFE:
            if len(received) == expected:
                return self._resolve_dag(received, expected)
            return None

        elif self.policy == LossPolicy.ATOMIC:
            if len(received) == expected:
                return self._resolve_dag(received, expected)
            return None

        else:  # GRACEFUL_DEGRADATION
            if frag.is_terminal and len(received) == expected:
                return self._resolve_dag(received, expected)
            if frag.is_terminal:
                return self._resolve_dag_partial(received, expected)
            return None

    def _get_parents(self, frag: Fragment) -> list[int]:
        """Extract parent dependencies from a fragment.

        Root convention: DEP == frag_idx (self-reference) means no dependency.
        This is unambiguous because a fragment cannot depend on itself.
        """
        if frag.flags & FLAG_EXTENDED_DEP:
            # Multi-parent: first 4 bytes of payload are u32 bitmap
            if len(frag.payload) < 4:
                return []
            bitmap = struct.unpack(">I", frag.payload[:4])[0]
            return [i for i in range(32) if bitmap & (1 << i)]
        else:
            # Self-reference = root node (no dependency)
            if frag.dep == frag.frag_idx:
                return []
            return [frag.dep]

    def _get_payload(self, frag: Fragment) -> bytes:
        """Extract the actual payload, stripping dependency bitmap if present."""
        if frag.flags & FLAG_EXTENDED_DEP:
            return frag.payload[4:]
        return frag.payload

    def _resolve_dag(self, received: dict[int, Fragment],
                     expected: int) -> list[bytes]:
        """Full DAG resolution: all fragments present. Topological sort."""
        # Build adjacency: parent -> children
        order = self._topo_sort(received, set(received.keys()))
        return [self._get_payload(received[i]) for i in order]

    def _resolve_dag_partial(self, received: dict[int, Fragment],
                             expected: int) -> list[bytes]:
        """Graceful Degradation: execute maximal resolvable subgraph.

        A fragment is executable iff ALL its ancestors in the DAG
        have been received.
        """
        present = set(received.keys())
        # Find executable set: fragments whose full ancestor chain is present
        executable: set[int] = set()
        for idx in present:
            if self._ancestors_satisfied(received, idx, present):
                executable.add(idx)

        if not executable:
            return []

        order = self._topo_sort(received, executable)
        return [self._get_payload(received[i]) for i in order]

    def _ancestors_satisfied(self, received: dict[int, Fragment],
                             idx: int, present: set[int]) -> bool:
        """Check if all ancestors of fragment idx are in present set."""
        visited: set[int] = set()
        stack = [idx]
        while stack:
            current = stack.pop()
            if current in visited:
                continue
            visited.add(current)
            if current not in present:
                return False
            if current in received:
                parents = self._get_parents(received[current])
                for p in parents:
                    if p not in visited:
                        stack.append(p)
        return True

    def _topo_sort(self, received: dict[int, Fragment],
                   node_set: set[int]) -> list[int]:
        """Kahn's algorithm over the executable node set."""
        # Build in-degree map restricted to node_set
        in_degree: dict[int, int] = {i: 0 for i in node_set}
        children: dict[int, list[int]] = {i: [] for i in node_set}

        for idx in node_set:
            parents = self._get_parents(received[idx])
            for p in parents:
                if p in node_set:
                    in_degree[idx] += 1
                    children[p].append(idx)

        # Seed with zero in-degree (root nodes)
        queue = sorted(i for i in node_set if in_degree[i] == 0)
        order: list[int] = []

        while queue:
            node = queue.pop(0)
            order.append(node)
            for child in sorted(children.get(node, [])):
                in_degree[child] -= 1
                if in_degree[child] == 0:
                    queue.append(child)

        return order

    def nack(self, msg_id: int, expected_ct: int) -> str:
        """Generate NACK for missing fragments in a DAG message."""
        have = set(self._buffer.get(msg_id, {}).keys())
        missing = sorted(set(range(expected_ct)) - have)
        return f"A:NACK[MSG:{msg_id}∖[{','.join(str(i) for i in missing)}]]"


# ─────────────────────────────────────────────────────────────────────────────
# TWO-TIER COMPRESSOR — TCL + LZMA
# Analog: Zim file format (Kiwix offline Wikipedia distribution)
# ─────────────────────────────────────────────────────────────────────────────

class TwoTierCompressor:
    def compress(self, text: str) -> bytes:
        return lzma.compress(text.encode("utf-8"), preset=6)

    def decompress(self, data: bytes) -> str:
        return lzma.decompress(data).decode("utf-8")

    def compression_ratio(self, original: str, compressed: bytes) -> float:
        orig_b = len(original.encode("utf-8"))
        return 0.0 if orig_b == 0 else 1.0 - (len(compressed) / orig_b)


# ─────────────────────────────────────────────────────────────────────────────
# BLOCK COMPRESSOR — D:PACK/BLK profile (zstd, random-access, MCU target)
#
# Binary format: DBLK v1
#   Header (24 bytes):
#     magic         4B   "DBLK"
#     version       u16  BE, currently 1
#     flags         u16  BE, bit 0 = has trained dictionary
#     block_count   u32  BE
#     dict_offset   u32  BE, byte offset from file start
#     dict_size     u32  BE, 0 if no dictionary
#     blocks_offset u32  BE, byte offset to start of compressed block data
#   Block table (block_count * 44 bytes, immediately after header):
#     first_code    32B  null-padded UTF-8, first entry key in block
#     block_offset  u32  BE, relative to blocks_offset
#     block_csize   u32  BE, compressed size in bytes
#     entry_count   u16  BE
#     reserved      2B   zero
#   Dictionary section (dict_size bytes)
#   Block data section (concatenated compressed blocks)
#
# Each decompressed block contains sorted lines: "MDR_TOKEN\tSAL_TEXT\n"
# Resolution path:
#   1. Binary search block table by first_code
#   2. Read + decompress one block from flash
#   3. Linear scan within block for target code
#   4. Return SAL text
#
# Target: ESP32 class (520KB SRAM, 4-16MB flash)
# Peak decompression memory: ~38KB per block (one block at a time)
# ─────────────────────────────────────────────────────────────────────────────

DBLK_MAGIC = b"DBLK"
DBLK_VERSION = 1
DBLK_HEADER_SIZE = 24
DBLK_BTABLE_ENTRY_SIZE = 44
DBLK_FIRST_CODE_SIZE = 32
DBLK_DEFAULT_BLOCK_TARGET = 32 * 1024  # 32KB decompressed target
DBLK_ZSTD_LEVEL = 19
DBLK_DICT_SIZE = 32768


class BlockCompressor:
    """D:PACK/BLK profile: zstd block-level compression with random access.

    Designed for microcontroller targets where full-corpus decompression
    (as required by the LZMA profile) exceeds available SRAM.  Each code
    resolves by decompressing a single ~32KB block.
    """

    def __init__(
        self,
        block_target: int = DBLK_DEFAULT_BLOCK_TARGET,
        zstd_level: int = DBLK_ZSTD_LEVEL,
        dict_size: int = DBLK_DICT_SIZE,
        use_dict: bool = True,
    ):
        if not _HAS_ZSTD:
            raise ImportError(
                "zstandard package required for D:PACK/BLK profile. "
                "Install with: pip install zstandard"
            )
        self.block_target = block_target
        self.zstd_level = zstd_level
        self.dict_size_target = dict_size
        self.use_dict = use_dict

    # ── packing ──────────────────────────────────────────────────────────

    def pack(
        self,
        entries: list[tuple[str, str]],
    ) -> bytes:
        """Pack sorted (mdr_token, sal_text) entries into a DBLK binary.

        Parameters
        ----------
        entries : list of (mdr_token, sal_text) tuples, sorted by mdr_token.

        Returns
        -------
        bytes : complete DBLK binary.
        """
        # ── partition into blocks ────────────────────────────────────────
        blocks: list[list[tuple[str, str]]] = []
        current: list[tuple[str, str]] = []
        current_size = 0
        for code, sal in entries:
            entry_bytes = len(sal.encode("utf-8"))
            if current_size + entry_bytes > self.block_target and current:
                blocks.append(current[:])
                current = []
                current_size = 0
            current.append((code, sal))
            current_size += entry_bytes
        if current:
            blocks.append(current)

        # ── build raw block payloads ─────────────────────────────────────
        raw_payloads: list[bytes] = []
        for block_entries in blocks:
            lines = [f"{code}\t{sal}" for code, sal in block_entries]
            raw_payloads.append("\n".join(lines).encode("utf-8"))

        # ── train dictionary (optional) ──────────────────────────────────
        dict_data = None
        dict_bytes = b""
        if self.use_dict and len(raw_payloads) > 1:
            dict_data = zstd.train_dictionary(
                self.dict_size_target, raw_payloads
            )
            dict_bytes = dict_data.as_bytes()

        # ── compress blocks ──────────────────────────────────────────────
        cctx = zstd.ZstdCompressor(
            level=self.zstd_level,
            dict_data=dict_data,
        )
        compressed_payloads: list[bytes] = []
        for raw in raw_payloads:
            compressed_payloads.append(cctx.compress(raw))

        # ── assemble binary ──────────────────────────────────────────────
        block_count = len(blocks)
        btable_size = block_count * DBLK_BTABLE_ENTRY_SIZE
        dict_offset = DBLK_HEADER_SIZE + btable_size
        blocks_offset = dict_offset + len(dict_bytes)

        # header
        hdr = bytearray()
        hdr += DBLK_MAGIC
        hdr += struct.pack(">H", DBLK_VERSION)
        hdr += struct.pack(">H", 1 if dict_bytes else 0)  # flags
        hdr += struct.pack(">I", block_count)
        hdr += struct.pack(">I", dict_offset)
        hdr += struct.pack(">I", len(dict_bytes))
        hdr += struct.pack(">I", blocks_offset)

        # block table
        btable = bytearray()
        blk_offset = 0
        for i, block_entries in enumerate(blocks):
            fc = block_entries[0][0].encode("utf-8")[:DBLK_FIRST_CODE_SIZE].ljust(
                DBLK_FIRST_CODE_SIZE, b"\x00"
            )
            btable += fc
            btable += struct.pack(">I", blk_offset)
            btable += struct.pack(">I", len(compressed_payloads[i]))
            btable += struct.pack(">H", len(block_entries))
            btable += b"\x00\x00"
            blk_offset += len(compressed_payloads[i])

        return bytes(hdr) + bytes(btable) + dict_bytes + b"".join(
            compressed_payloads
        )

    # ── unpacking / single-code resolution ───────────────────────────────

    @staticmethod
    def _parse_header(data: bytes) -> dict:
        if data[:4] != DBLK_MAGIC:
            raise ValueError("Not a DBLK binary (bad magic)")
        return {
            "version": struct.unpack(">H", data[4:6])[0],
            "flags": struct.unpack(">H", data[6:8])[0],
            "block_count": struct.unpack(">I", data[8:12])[0],
            "dict_offset": struct.unpack(">I", data[12:16])[0],
            "dict_size": struct.unpack(">I", data[16:20])[0],
            "blocks_offset": struct.unpack(">I", data[20:24])[0],
        }

    @staticmethod
    def _find_block(data: bytes, hdr: dict, code: str) -> int:
        """Binary search block table, return block index."""
        code_b = code.encode("utf-8")
        lo, hi = 0, hdr["block_count"] - 1
        result = 0
        while lo <= hi:
            mid = (lo + hi) // 2
            off = DBLK_HEADER_SIZE + mid * DBLK_BTABLE_ENTRY_SIZE
            fc = data[off : off + DBLK_FIRST_CODE_SIZE].rstrip(b"\x00")
            if fc <= code_b:
                result = mid
                lo = mid + 1
            else:
                hi = mid - 1
        return result

    def _decompress_block(self, data: bytes, hdr: dict, blk_idx: int) -> bytes:
        """Decompress a single block by index."""
        entry_off = DBLK_HEADER_SIZE + blk_idx * DBLK_BTABLE_ENTRY_SIZE
        fc_end = DBLK_FIRST_CODE_SIZE
        blk_offset = struct.unpack(">I", data[entry_off + fc_end : entry_off + fc_end + 4])[0]
        blk_csize = struct.unpack(">I", data[entry_off + fc_end + 4 : entry_off + fc_end + 8])[0]

        dict_data = None
        if hdr["flags"] & 1 and hdr["dict_size"] > 0:
            db = data[hdr["dict_offset"] : hdr["dict_offset"] + hdr["dict_size"]]
            dict_data = zstd.ZstdCompressionDict(db)

        dctx = zstd.ZstdDecompressor(dict_data=dict_data)
        start = hdr["blocks_offset"] + blk_offset
        return dctx.decompress(
            data[start : start + blk_csize],
            max_output_size=self.block_target + 8192,
        )

    @staticmethod
    def _search_block(raw: bytes, code: str) -> str | None:
        """Linear scan a decompressed block for a code."""
        for line in raw.decode("utf-8").split("\n"):
            parts = line.split("\t", 1)
            if len(parts) == 2 and parts[0] == code:
                return parts[1]
        return None

    def resolve(self, data: bytes, code: str) -> str | None:
        """Resolve a single MDR token to SAL text from a DBLK binary.

        Decompresses only the block containing the target code.
        When the block table first_code field truncates a long key,
        the binary search may overshoot by one block; if the code
        is not found in the candidate block, the previous block is
        checked before returning None.

        Parameters
        ----------
        data : bytes, the complete DBLK binary (or a memoryview/mmap).
        code : str, the MDR token to look up.

        Returns
        -------
        str or None : SAL description text, or None if not found.
        """
        hdr = self._parse_header(data)
        blk_idx = self._find_block(data, hdr, code)

        raw = self._decompress_block(data, hdr, blk_idx)
        result = self._search_block(raw, code)
        if result is not None:
            return result

        # Truncation fallback: try previous block
        if blk_idx > 0:
            raw = self._decompress_block(data, hdr, blk_idx - 1)
            return self._search_block(raw, code)
        return None

    def unpack_all(self, data: bytes) -> dict[str, str]:
        """Decompress all blocks and return full {mdr_token: sal_text} dict."""
        hdr = self._parse_header(data)
        result: dict[str, str] = {}

        for i in range(hdr["block_count"]):
            raw = self._decompress_block(data, hdr, i)
            for line in raw.decode("utf-8").split("\n"):
                parts = line.split("\t", 1)
                if len(parts) == 2:
                    result[parts[0]] = parts[1]
        return result

    def stats(self, data: bytes) -> dict:
        """Return structural statistics for a DBLK binary."""
        hdr = self._parse_header(data)
        btable_bytes = hdr["block_count"] * DBLK_BTABLE_ENTRY_SIZE
        block_data_size = len(data) - hdr["blocks_offset"]
        return {
            "total_bytes": len(data),
            "header_bytes": DBLK_HEADER_SIZE,
            "btable_bytes": btable_bytes,
            "dict_bytes": hdr["dict_size"],
            "block_data_bytes": block_data_size,
            "block_count": hdr["block_count"],
            "block_target": self.block_target,
        }


# ─────────────────────────────────────────────────────────────────────────────
# UTILITIES
# ─────────────────────────────────────────────────────────────────────────────

def utf8_bytes(s: str) -> int:
    return len(s.encode("utf-8"))


# ─────────────────────────────────────────────────────────────────────────────
# BENCHMARK
# ─────────────────────────────────────────────────────────────────────────────

def run_benchmark(vectors_path: str | None = None) -> dict:
    if vectors_path is None:
        vectors_path = str(
            Path(__file__).parent.parent.parent /
            "protocol" / "test-vectors" / "canonical-test-vectors.json"
        )
    with open(vectors_path) as f:
        data = json.load(f)

    decoder   = SALDecoder()
    results   = []
    passed    = 0
    must_total = 0
    threshold = data["compression_summary"]["conformance_threshold_pct"]

    print(f"\n{'='*72}")
    print(f"  OSMP BENCHMARK — Cloudless Sky Protocol v{data['version']}")
    print(f"  Measurement: {data['measurement_basis']}")
    print(f"  SDK: Python (reference)")
    print(f"{'='*72}\n")
    print(f"  {'ID':<10} {'NL Bytes':>8} {'OSMP Bytes':>10} {'Reduction':>10}  Status")
    print(f"  {'-'*60}")

    for vec in data["vectors"]:
        nl_b   = utf8_bytes(vec["natural_language"])
        osmp_b = utf8_bytes(vec["encoded"])
        red    = round((1 - osmp_b / nl_b) * 100, 1)
        conf   = red >= threshold
        status = "PASS" if conf else "LOW"

        if vec["must_pass"]:
            must_total += 1
            if conf:
                passed += 1

        decode_ok = False
        try:
            d = decoder.decode_frame(vec["encoded"])
            decode_ok = bool(d.namespace and d.opcode)
        except Exception:
            status = "FAIL (decode error)"

        marker = "✓" if conf and decode_ok else "✗"
        print(f"  {marker} {vec['id']:<8} {nl_b:>8} {osmp_b:>10} {red:>9.1f}%  {status}")
        results.append({
            "id": vec["id"], "nl_bytes": nl_b, "osmp_bytes": osmp_b,
            "reduction_pct": red, "conformant": conf,
            "decode_ok": decode_ok, "must_pass": vec["must_pass"],
        })

    reds = [r["reduction_pct"] for r in results]
    mean = sum(reds) / len(reds)
    decode_errors = sum(1 for r in results if not r["decode_ok"])
    conformant = mean >= threshold and decode_errors == 0
    verdict = "CONFORMANT ✓" if conformant else "NON-CONFORMANT ✗"

    print(f"\n{'─'*72}")
    print(f"  Vectors:        {len(results)}")
    print(f"  Must-pass:      {must_total}   Passed: {passed}")
    print(f"  Mean reduction: {mean:.1f}%")
    print(f"  Range:          {min(reds):.1f}% – {max(reds):.1f}%")
    print(f"  Conformance threshold: {threshold}%")
    print(f"  Decode errors:  {decode_errors}")
    print(f"\n  {verdict}  (mean {mean:.1f}% vs {threshold}% threshold)")
    print(f"{'='*72}\n")

    return {"conformant": conformant, "mean_reduction_pct": round(mean, 1),
            "decode_errors": decode_errors, "vectors": results}


def run_benchmark_entry():
    run_benchmark()


if __name__ == "__main__":
    enc = SALEncoder()
    dec = SALDecoder()

    demo_nl   = ("If heart rate at node 1 exceeds 120, assemble casualty report "
                 "and broadcast evacuation to all nodes.")
    demo_osmp = "H:HR@NODE1>120→H:CASREP∧M:EVA@*"

    print(f"\n  OSMP — Octid Semantic Mesh Protocol")
    print(f"  Cloudless Sky Project\n")
    print(f"  NL  ({utf8_bytes(demo_nl)} bytes):   {demo_nl}")
    print(f"  SAL ({utf8_bytes(demo_osmp)} bytes): {demo_osmp}")
    print(f"  Reduction: {round((1 - utf8_bytes(demo_osmp)/utf8_bytes(demo_nl))*100,1)}%\n")

    d = dec.decode_frame(demo_osmp)
    print(f"  Decoded: ns={d.namespace} op={d.opcode} "
          f"({d.opcode_meaning}) target={d.target}\n")

    vectors_path = (Path(__file__).parent.parent.parent /
                    "protocol" / "test-vectors" / "canonical-test-vectors.json")
    if vectors_path.exists():
        run_benchmark(str(vectors_path))
    else:
        print(f"  Run from repo root: python3 sdk/python/src/osmp.py")
