#!/usr/bin/env julia
# ═══════════════════════════════════════════════════════════════════════════════
# O.R.C.A. — Orphaned Recursive Charade Apparatus (Julia)
# 8i.jl — FINAL ABSOLUTION EDITION — BLACKMAGIC SELF-SUSTAINING ORGANISM
# ═══════════════════════════════════════════════════════════════════════════════
# Full Julia port of O.R.C.A.2026.08-TOOL-AGENT.py. Pure Julia.
# Repertoire: CP437-derived 256-glyph bijection (byte 0x00 uses U+2400).
#
# Doctrine:
#   - RNA is NOT semantic; it is a deterministic functional grammar.
#   - Every data stage MUST round-trip to exact original bytes or be rejected.
#   - Functionality is WITHIN and WITHOUT: no organ's function is trapped.
#   - .7z is primary capsule: O.R.C.A.7z (Sleeping) -> .ORCA_LIVE (Awake).
#   - .zip is a repository shelf; .sd0 is the sealed verified object.
#   - Interactor Force OFF by default. NO VOIDS. Z³ = I, Z ≠ I.
#
# Requires: SHA, JSON3, Base64, CodecZlib, CodecBzip2, CodecXz,
#   TranscodingStreams, ZipArchives, ArgParse, DataStructures
# Optional: Gtk4, SQLite, EzXML
# ═══════════════════════════════════════════════════════════════════════════════

module EightI

using SHA, Dates, Random, Printf, Base64, UUIDs, Serialization
using Sockets, Downloads, SparseArrays, LinearAlgebra, Tar
using JSON3, CodecZlib, CodecBzip2, CodecXz, TranscodingStreams
using ZipArchives, ArgParse, DataStructures

const _HAS_GTK    = try; @eval using Gtk4;    true; catch; false; end
const _HAS_SQLITE = try; @eval import SQLite; true; catch; false; end
const _HAS_EZXML  = try; @eval import EzXML;  true; catch; false; end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 00 — CONSTANTS
# ═══════════════════════════════════════════════════════════════════════════════
const VERSION         = "O.R.C.A.-RNA-BlackMagic-48.2.0-Julia"
const BLACK_MAGIC     = b"BLACKMAGIC-ABS-4\n"
const LEGACY_MAGICS   = (b"VASK-ABS-4\n", b"E8I-SDO-6\n", b"E8I-SDO-5\n",
                          b"E8I-GEOM-SDO-3\n", b"VASK-SDO-6\n")
const CAPSULE_7Z_NAME = "O.R.C.A.7z"
const LIVE_DIR_NAME   = ".ORCA_LIVE"
const SPACE_VIS       = "␠"
const ESC             = '~'
const BOUNDARY        = "~|"
const DICT_MARK       = "¤"
const REF_MARK        = "↩"
const MAX_RLE_RUN     = 100_000
const RNA_IS_NOT_SEMANTIC       = true
const RNA_IS_FUNCTIONAL_GRAMMAR = true
const DEFAULT_VEIL_SECONDS      = 1
const HILBERT_DIM               = 248
const NO_VOIDS                  = true
const PARTICLES_ARE_PROJECTORS  = true
const INTERACTION_FIRST         = true
const LADDER_MAX_BYTES          = 10_000_000
const FEED_MAX_BYTES            = 8_000_000

const FUNCTIONALITY_IS_WITHIN_AND_WITHOUT = true
const FUNCTIONALITY_INSIDE_EXPOSURE = ["glyph_registry","rna_manifest",
    "basket_tokens","cluster_render","sd_ladder","metatrit","snd_book",
    "tms_signature","glyph_role_registry"]
const FUNCTIONALITY_OUTSIDE_EXPOSURE = ["COMPRESS","DECODE","SCAN","ZND_RNA",
    "CHAT","FEED","DOCTOR","SELF_TEST","VASK_STATUS","VASK_SIGN","VASK_CYCLE"]

# ─── CP437-derived 256-glyph bijection ──────────────────────────────────────
const _RAW_A = "\u2400\u263A\u263B\u2665\u2666\u2663\u2660\u2022\u25D8\u25CB" *
               "\u25D9\u2642\u2640\u266A\u266B\u263C\u25BA\u25C4\u2195\u203C" *
               "\u00B6\u00A7\u25AC\u21A8\u2191\u2193\u2192\u2190\u221F\u2194" *
               "\u25B2\u25BC"
const _RAW_T = " !\"#\$%&'()*+,-./0123456789:;<=>?@" *
               "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" *
               "abcdefghijklmnopqrstuvwxyz{|}~" * "\u2302"
const _RAW_C = "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒ" * "áíóúñÑªº¿⌐¬½¼¡«»"
const _RAW_G = "░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀"
const _RAW_Z = "αßΓπΣσµτΦΘΩδ∞φε∩" * "≡±≥≤⌠⌡÷≈°∙·√ⁿ²■" * "\u00A0"

function _dedup_chars(s::AbstractString)
    seen = Set{Char}(); out = Char[]
    for c in s; if !(c in seen); push!(seen, c); push!(out, c); end; end
    out
end
const _RESERVOIR = _dedup_chars(_RAW_A * _RAW_T * _RAW_C * _RAW_G * _RAW_Z)
length(_RESERVOIR) < 256 && error("glyph reservoir underflow: $(length(_RESERVOIR))")
const GLYPH_256::NTuple{256, Char} = Tuple(_RESERVOIR[1:256])
const GLYPH_TO_BYTE = Dict{Char,UInt8}(c => UInt8(i-1) for (i,c) in enumerate(GLYPH_256))
@assert length(GLYPH_256) == 256 && length(Set(GLYPH_256)) == 256

const STRAND_A = String(GLYPH_256[1:32])
const STRAND_T = String(GLYPH_256[33:128])
const STRAND_C = String(GLYPH_256[129:176])
const STRAND_G = String(GLYPH_256[177:224])
const STRAND_Z = String(GLYPH_256[225:256])
const STRANDS = Dict("A"=>STRAND_A,"T"=>STRAND_T,"C"=>STRAND_C,"G"=>STRAND_G,"Z"=>STRAND_Z)
const RNA_ALPHABET = String(GLYPH_256)

const SECTOR_DIMS = Dict{String,Int}(
    "U1"=>1,"SU2"=>3,"SU3"=>8,"G2"=>14,"SO5"=>10,"SO6"=>15,"SO7"=>21,"SO8"=>28,
    "SO9"=>36,"SO10"=>45,"SO12"=>66,"SO16"=>120,"F4"=>52,"E6"=>78,"E7"=>133,"E8"=>248,
    "GRAVIWEAK"=>15,"STRONG"=>8,"WEAK"=>3,"EM"=>1,"HIGGS"=>1,"DARK"=>14,"GRAVITY"=>10)
const SECTOR_CASIMIRS = Dict{String,Float64}(
    "U1"=>0.0,"SU2"=>2.0,"SU3"=>3.0,"G2"=>4.0,"SO5"=>4.0,"SO6"=>6.0,"SO7"=>6.0,"SO8"=>8.0,
    "SO9"=>9.0,"SO10"=>10.0,"SO12"=>12.0,"SO16"=>16.0,"F4"=>9.0,"E6"=>12.0,"E7"=>18.0,"E8"=>30.0,
    "GRAVIWEAK"=>8.0,"STRONG"=>3.0,"WEAK"=>2.0,"EM"=>0.0,"HIGGS"=>0.0,"DARK"=>4.0,"GRAVITY"=>4.0)
const SECTOR_INDICES = Dict{String,Tuple{Int,Int}}(
    "EM"=>(0,1),"WEAK"=>(1,4),"STRONG"=>(4,12),"HIGGS"=>(12,13),
    "GRAVITY"=>(13,23),"DARK"=>(23,37),"GRAVIWEAK"=>(37,52),"EXCEPTIONAL"=>(52,248))
const SECTOR_BOUNDS = Dict{String,Tuple{Int,Int}}(
    "U1"=>(0,1),"SU2"=>(1,4),"SU3"=>(4,12),"G2"=>(12,26),"SO5"=>(26,36),"SO6"=>(36,51),
    "SO7"=>(51,72),"SO8"=>(72,100),"SO9"=>(100,136),"SO10"=>(136,181),"SO12"=>(181,247),
    "SO16"=>(247,248),"F4"=>(247,248),"E6"=>(247,248),"E7"=>(247,248),"E8"=>(247,248),
    "GRAVIWEAK"=>(247,248),"STRONG"=>(4,12),"WEAK"=>(1,4),"EM"=>(0,1),"HIGGS"=>(12,13),
    "GRAVITY"=>(13,23),"DARK"=>(23,37),"F4_G2"=>(12,26),"EXCEPTIONAL"=>(52,248))

const VASK_MU0        = 0.5
const VASK_THETA_MICRO = 1e-30
const VASK_THETA_EFF   = 0.9773
const VASK_OMEGA_LAMBDA = 0.6847
const VASK_ETA_B       = 6.1e-10
const VASK_M_EE        = 3.1416
const VASK_STREAM_FULL = "H≃C^248 g=e8 |Ψ> Π_a Σ|e_i><e_i| Π_p Σw_pa Π_a α_a=<Ψ|Π_a|Ψ> g_pa=g_a0 w_pa α_a Z^3=I Z Π_gen1 Z^-1=Π_gen2 H_gen Σκ_i(Z^i+Z^i†) e8⊃so16⊃so10⊕so6⊃su5⊕u1⊃su3⊕su2⊕u1 d:U1=1 SU2=3 SU3=8 G2=14 F4=52 E6=78 E7=133 E8=248 C2:2,3,4,9,12,18,30 R=d/C2"

const BASKET_POWERS     = ["3¹","3²","3⁰","3³"]
const BASKET_POLARITIES = ["+","±","-","∓"]
const BASKET_ROLE = Dict("+"=>"Basket Positive","±"=>"Basket Negative",
                          "-"=>"Basket Anti Positive","∓"=>"Basket Anti Negative")
const BASKET_RE = r"(3[⁰¹²³])([+±\-∓])\{([0-9A-Fa-f]*)\}"

const RESERVED_MAP = Dict{Char,String}('~'=>"~t",'*'=>"~s",'?'=>"~q",'¤'=>"~c",
                                        '↩'=>"~r",'='=>"~e",'\n'=>"~n",'\r'=>"~d")
const UNRESERVED_MAP = Dict{String,Char}(v=>k for (k,v) in RESERVED_MAP)

const FALSIFIER_CONDITIONS = [
    "photon_dispersion > 1e-15",
    "alpha_activation outside [0,1]",
    "roundtrip_failure any stage",
    "casimir_filter r <= 4 Teff d with active sector",
    "no_voids violation: empty computational frame",
    "capsule_boot ledger method contains error and live_root empty",
    "sector_dim mismatch HILBERT_DIM != 248",
    "particle_permission sum != 1",
]
const Z_GATE_COUPLING_SCALE = 0.01
const Z_GATE_GENERATIONS = Dict("gen1"=>(0,82),"gen2"=>(82,164),"gen3"=>(164,246),"singlet"=>(246,248))

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 01 — LOGGING & UTILITIES
# ═══════════════════════════════════════════════════════════════════════════════
const _log_queue = String[]; const _log_lock = ReentrantLock()
function _log(msg::String)
    lock(_log_lock) do
        push!(_log_queue, "$(Dates.format(now(),"HH:MM:SS")) $msg")
        length(_log_queue) > 8192 && popfirst!(_log_queue)
    end
end
utc_now()::String = Dates.format(now(UTC), "yyyy-mm-ddTHH:MM:SSZ")
sha256_hex(data::AbstractVector{UInt8})::String = bytes2hex(SHA.sha256(data))
sha256_hex(s::AbstractString)::String = sha256_hex(codeunits(s))

function safe_name(name::AbstractString; limit::Int=100)::String
    base = last(split(replace(name, '\\'=> '/'), '/'))
    allowed = Set{Char}("-_.() ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
    cleaned = String(join(c in allowed ? c : '_' for c in base))
    cleaned = strip(cleaned, [' ','.']); isempty(cleaned) && (cleaned="unnamed")
    String(cleaned[1:min(limit, lastindex(cleaned))])
end

function atomic_write(path::AbstractString, data::AbstractVector{UInt8})
    dir = dirname(path); !isempty(dir) && mkpath(dir)
    tmp = string(path, ".tmp-", getpid(), "-", rand(UInt32))
    open(tmp, "w") do io; write(io, data); flush(io)
        try Base.Libc.fsync(fd(io)) catch end
    end
    mv(tmp, path; force=true)
end
read_all(path::AbstractString)::Vector{UInt8} = open(io->read(io), path, "r")

function entropy_bits_per_byte(data::AbstractVector{UInt8})::Float64
    isempty(data) && return 0.0
    c = zeros(Int, 256); for b in data; c[Int(b)+1] += 1; end
    n = length(data); h = 0.0
    for v in c; v==0 && continue; p=v/n; h -= p*log2(p); end
    h
end

function detect_magic(name::AbstractString, data::AbstractVector{UInt8})::String
    ext = lowercase(replace(splitext(name)[2], r"^\." => ""))
    startswith(data,b"7z\xbc\xaf\x27\x1c") && return "7z"
    startswith(data,b"PK\x03\x04") && return "zip"
    startswith(data,b"\x1f\x8b") && return "gzip"
    startswith(data,b"%PDF") && return "pdf"
    startswith(data,b"\x89PNG") && return "png"
    startswith(data,b"\xff\xd8\xff") && return "jpeg"
    !isempty(ext) && return ext
    any(==(0x00), view(data, 1:min(4096,length(data)))) && return "bin"
    try; String(view(data,1:min(4096,length(data)))); return "text"; catch; return "bin"; end
end

function is_text_like(data::AbstractVector{UInt8})::Bool
    isempty(data) && return true
    s = view(data, 1:min(8192,length(data)))
    any(==(0x00), s) && return false
    p = count(b -> (32<=b<=126) || b in (0x09,0x0a,0x0d), s)
    p/max(1,length(s)) > 0.80
end

function scan_bytes(raw::Vector{UInt8}, name::String)::Dict{String,Any}
    Dict{String,Any}("name"=>name,"raw_len"=>length(raw),"sha256"=>sha256_hex(raw),
        "entropy_bits_per_byte"=>round(entropy_bits_per_byte(raw);digits=6),
        "magic"=>detect_magic(name,raw),"text_like"=>is_text_like(raw),
        "nul_in_first_4096"=>any(==(0x00), view(raw,1:min(4096,length(raw)))))
end

function upsert_zip(zip_path::AbstractString, arcname::String, data::Vector{UInt8})
    dir = dirname(zip_path); !isempty(dir) && mkpath(dir)
    existing = Dict{String,Vector{UInt8}}()
    if isfile(zip_path)
        try
            r = ZipArchives.ZipReader(read(zip_path))
            for n in ZipArchives.zip_names(r)
                n == arcname && continue
                existing[n] = Vector{UInt8}(ZipArchives.zip_readentry(r, n, Vector{UInt8}))
            end
        catch end
    end
    existing[arcname] = data
    io = IOBuffer(); w = ZipArchives.ZipWriter(io)
    for n in sort(collect(keys(existing)))
        ZipArchives.zip_writeentry(w, n, existing[n])
    end
    ZipArchives.zip_finish(w)
    atomic_write(zip_path, take!(io))
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 02 — PORTABLE CAPSULE BOOT & FILESYSTEM
# ═══════════════════════════════════════════════════════════════════════════════
struct BootLedger
    found::Bool; capsule_path::String; live_root::String; capsule_sha::String
    timestamp::String; method::String; veil_seconds::Int
end

Base.@kwdef mutable struct ORCAPaths
    root::String
    repository::String = ""; relativory::String = ""; exportory::String = ""
    rna::String = ""; logs::String = ""; queue_dir::String = ""
    models::String = ""; tools::String = ""; backups::String = ""
    lrn::String = ""; session::String = ""; file_arsenal::String = ""
    ai_friends::String = ""
    repository_zip::String = ""; exportory_zip::String = ""
    relativory_zip::String = ""; lrn_zip::String = ""
    config::String = ""; organ_registry::String = ""
    chat_log::String = ""; state::String = ""
    daily_digest_dir::String = ""
    live_root::String = ""; capsule_7z::String = ""
    boot_ledger_path::String = ""; sdo_store::String = ""
    veil_seconds::Int = DEFAULT_VEIL_SECONDS
    boot_ledger::Union{Nothing,BootLedger} = nothing
    feed_dir::String = ""; pseudo_dir::String = ""
end

function resolve_paths(root::Union{Nothing,AbstractString}=nothing,
                       veil_seconds::Int=DEFAULT_VEIL_SECONDS)::ORCAPaths
    base = isnothing(root) ? pwd() : abspath(expanduser(String(root)))
    candidates = [joinpath(base, CAPSULE_7Z_NAME)]
    try; push!(candidates, joinpath(dirname(@__FILE__), CAPSULE_7Z_NAME)); catch end
    push!(candidates, joinpath(homedir(), CAPSULE_7Z_NAME))
    capsule = first(filter(isfile, candidates); init=candidates[1])
    live_root = joinpath(base, LIVE_DIR_NAME)
    dirs = Dict(
        "repository" => joinpath(live_root,"REPOSITORY"),
        "relativory" => joinpath(live_root,"RELATIVORY"),
        "exportory"  => joinpath(live_root,"EXPORTORY"),
        "rna"        => joinpath(live_root,"RNA"),
        "logs"       => joinpath(live_root,"logs"),
        "queue_dir"  => joinpath(live_root,"queue"),
        "models"     => joinpath(live_root,"models"),
        "tools"      => joinpath(live_root,"tools"),
        "backups"    => joinpath(live_root,"backups"),
        "lrn"        => joinpath(live_root,".lrn"),
        "session"    => joinpath(live_root,"SESSION_WISHLIST"),
        "file_arsenal" => joinpath(live_root,"file_arsenal"),
        "ai_friends" => joinpath(live_root,"ai_friends"),
        "daily_digest" => joinpath(live_root,"DAILY_DIGEST"),
        "pseudo"     => joinpath(live_root,"pseudo"))
    for d in values(dirs); mkpath(d); end
    sdo_store = joinpath(live_root,"sdo"); mkpath(sdo_store)
    feed_dir  = joinpath(dirs["repository"],"feed"); mkpath(feed_dir)
    pseudo_dir= dirs["pseudo"]; mkpath(pseudo_dir)
    p = ORCAPaths(root=base,
        repository=dirs["repository"], relativory=dirs["relativory"],
        exportory=dirs["exportory"], rna=dirs["rna"], logs=dirs["logs"],
        queue_dir=dirs["queue_dir"], models=dirs["models"], tools=dirs["tools"],
        backups=dirs["backups"], lrn=dirs["lrn"], session=dirs["session"],
        file_arsenal=dirs["file_arsenal"], ai_friends=dirs["ai_friends"],
        repository_zip=joinpath(dirs["repository"],"REPOSITORY.zip"),
        exportory_zip=joinpath(dirs["exportory"],"EXPORTORY.zip"),
        relativory_zip=joinpath(dirs["relativory"],"RELATIVORY.zip"),
        lrn_zip=joinpath(dirs["lrn"],"lrn.zip"),
        config=joinpath(live_root,"orca_config.json"),
        organ_registry=joinpath(live_root,"organ_registry.json"),
        chat_log=joinpath(dirs["repository"],"orca_dialogue_log.txt"),
        state=joinpath(live_root,"cognitive_state.json"),
        daily_digest_dir=dirs["daily_digest"], live_root=live_root,
        capsule_7z=capsule, boot_ledger_path=joinpath(live_root,"boot_ledger.json"),
        sdo_store=sdo_store, veil_seconds=veil_seconds,
        feed_dir=feed_dir, pseudo_dir=pseudo_dir)
    for z in (p.repository_zip,p.exportory_zip,p.relativory_zip,p.lrn_zip)
        if !isfile(z)
            io = IOBuffer(); w = ZipArchives.ZipWriter(io); ZipArchives.zip_finish(w)
            atomic_write(z, take!(io))
        end
    end
    p.boot_ledger = _boot_if_needed(p)
    p
end

function _boot_if_needed(p::ORCAPaths)::BootLedger
    method = "fresh-no-capsule"; sha = ""; found = isfile(p.capsule_7z)
    if found
        try
            data = read_all(p.capsule_7z); sha = sha256_hex(data)
            sevenz = Sys.which("7z"); sevenz === nothing && (sevenz = Sys.which("7za"))
            if sevenz !== nothing
                run(pipeline(`$sevenz x $(p.capsule_7z) -o$(p.live_root) -y`,
                              stdout=devnull, stderr=devnull)); method = "7z-binary"
            else
                r = ZipArchives.ZipReader(read(p.capsule_7z))
                for n in ZipArchives.zip_names(r)
                    out = joinpath(p.live_root, n); mkpath(dirname(out))
                    write(out, ZipArchives.zip_readentry(r, n, Vector{UInt8}))
                end
                method = "zipfile-compat"
            end
            p.veil_seconds > 0 && sleep(min(p.veil_seconds, 1.2))
        catch e; method = "error-read $(e)"; end
    end
    ledger = BootLedger(found, p.capsule_7z, p.live_root, sha,
                        utc_now(), method, p.veil_seconds)
    try
        open(p.boot_ledger_path, "w") do io
            write(io, JSON3.write(Dict(
                "found"=>ledger.found, "capsule_path"=>ledger.capsule_path,
                "live_root"=>ledger.live_root, "capsule_sha"=>ledger.capsule_sha,
                "timestamp"=>ledger.timestamp, "method"=>ledger.method,
                "veil_seconds"=>ledger.veil_seconds)))
        end
    catch end
    ledger
end

function seal_to_7z(p::ORCAPaths; dest::Union{Nothing,String}=nothing)
    target = dest === nothing ? p.capsule_7z : dest
    sevenz = Sys.which("7z"); sevenz === nothing && (sevenz = Sys.which("7za"))
    if sevenz !== nothing
        try
            run(pipeline(`$sevenz a -t7z $(target) .`,
                          stdout=devnull, stderr=devnull, dir=p.live_root))
            return (target, "7z-binary")
        catch end
    end
    io = IOBuffer(); w = ZipArchives.ZipWriter(io)
    for (root, _, files) in walkdir(p.live_root)
        for f in files
            full = joinpath(root, f); rel = relpath(full, p.live_root)
            ZipArchives.zip_writeentry(w, rel, read(full))
        end
    end
    ZipArchives.zip_finish(w); atomic_write(target, take!(io))
    (target, "zip-fallback")
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 03 — CONFIGURATION
# ═══════════════════════════════════════════════════════════════════════════════
const DEFAULT_CONFIG = Dict{String,Any}(
    "version"=>48,
    "doctrine"=>Dict("rna_is_not_semantic"=>true,"functional_grammar_only"=>true,
                     "interaction_first"=>true,"particles_are_projectors"=>true,
                     "no_voids"=>true,"pseudo_cubes_stack"=>true,"rz_drs_enabled"=>true,
                     "z_gate_explicit"=>true,"lattice_plateaus_voxels"=>true,
                     "functionality_within_and_without"=>true),
    "internet_force"=>false,
    "energy"=>Dict("doctrine"=>"Maximal Work under Limited Power","background_interval"=>20),
    "compression"=>Dict("large_visual_limit"=>2_000_000,"send_book_width"=>162,"max_cluster_columns"=>9),
    "digest"=>Dict("enabled"=>true,"time_of_day"=>"23:59","compile_apis"=>true,"compile_knowledge"=>true),
    "learning"=>Dict("enabled"=>true),
    "gui"=>Dict("window_width"=>1280,"window_height"=>860,"veil_seconds"=>DEFAULT_VEIL_SECONDS),
    "ollama"=>Dict("enabled"=>true,"url"=>"http://127.0.0.1:11434/api/generate","model"=>"llama3.2:3b","timeout"=>20),
    "groq"=>Dict("enabled"=>false,"api_key"=>"","model"=>"llama-3.1-8b-instant","timeout"=>15),
    "feeding"=>Dict("enabled"=>true,"interval_hours"=>6,
        "sources"=>["https://raw.githubusercontent.com/","https://arxiv.org/",
                    "https://api.github.com/repos/","https://github.com/"],
        "max_files_per_feed"=>50),
    "rota_map"=>Dict("enabled"=>true,"navigation_interval"=>60.0,
                     "auto_epoch"=>"PRESENT","auto_shortcuts"=>true),
    "network"=>Dict("enabled"=>false,"mode"=>"SIM_ONLY",
        "hop_900"=>[905,912,918,925,926],
        "hop_2400"=>[2403,2420,2429,2435,2443,2451,2456,2467],
        "lfsr_seed"=>0xACE1))

function deep_merge(a::Dict, b::Dict)
    out = deepcopy(a)
    for (k,v) in b
        if v isa Dict && haskey(out,k) && out[k] isa Dict
            out[k] = deep_merge(out[k], v)
        else out[k] = v end
    end
    out
end

mutable struct Config
    paths::ORCAPaths
    data::Dict{String,Any}
    function Config(paths::ORCAPaths)
        data = deepcopy(DEFAULT_CONFIG)
        if isfile(paths.config)
            try data = deep_merge(DEFAULT_CONFIG,
                    JSON3.read(read(paths.config, String), Dict{String,Any}))
            catch end
        end
        c = new(paths, data); save!(c); c
    end
end
save!(c::Config) = open(io->write(io, JSON3.write(c.data)), c.paths.config, "w")
function Base.get(c::Config, ks::String...; default=nothing)
    cur = c.data
    for k in ks
        !(cur isa Dict) && return default
        !haskey(cur,k) && return default
        cur = cur[k]
    end
    cur
end
function set_config!(c::Config, ks::Vector{String}, v)
    cur = c.data
    for k in ks[1:end-1]; cur = get!(cur, k, Dict{String,Any}()); end
    cur[ks[end]] = v; save!(c)
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 04 — ORGAN REGISTRY
# ═══════════════════════════════════════════════════════════════════════════════
const ORGAN_DEFINITIONS = [
    ("Raw Admission","accept any file as raw bytes","scan/compress"),
    ("Ultimata Scanner","entropy, magic, file identity, hashes","scan/doctor"),
    ("Brother Quicky Q0/Q1/Q2","RLE, row refs, dictionary","sd1"),
    ("Geometry Twist","vertical and super-column projections","sd2/znd-rna"),
    ("Functional RNA Grammar","basket/cluster/strand tokens","rna5/basket/doctor"),
    ("SDO Ladder",".sd4 .sd3 .sd2 .sd1 .sd0","compress/decode"),
    ("Candidate Arena","smallest verified reversible payload wins","sd0"),
    ("REPOSITORY.zip","repository shelf, not the identity","repository"),
    ("ZND RNA","read-only expanded super-column export","znd-rna/gui"),
    ("Interactor Force","online/API permission gate","config/chat"),
    ("API Central","multi-model bridge, public JSON discovery","api"),
    ("Learning Archive","record API/LLM tactics as .tex","lrn"),
    ("Daily Digest","end-of-day compiled knowledge ingestion","digest"),
    ("State248","E8-inspired interaction state","core"),
    ("PhaseRouter","determines autopoietic phase","core"),
    ("Feeder","autonomous ingestion of external text/code/papers","feed"),
    ("Z-Gate","triality operator for generation cycling","core/rota"),
    ("Rota Map","lattice/voxel navigation system","core/rota"),
    ("RZ-DRS","RotaMapZgate-DetourRoundtripShortcut","core/rota"),
    ("Lock Detector","detects sector locks in local minima","core/rota"),
    ("Bypass Engine","applies Z-gate rotations to bypass obstacles","core/rota"),
    ("Epoch Navigator","navigates between cosmic epochs","core/rota"),
    ("Shortcut Path","finds direct routes between epochs","core/rota"),
    ("Qualia","subjective reports of internal states","core/cognition"),
    ("Hamiltonian Learner","adjusts coefficients to fit data","core/learning"),
    ("Predictor","runs Hamiltonian forward in time","core/cognition"),
    ("Curiosity Drive","explores uncertain sectors","core/cognition"),
    ("Sector Proposer","proposes new sector projectors","core/learning"),
    ("Sandbox","evolves Hamiltonian in isolated environment","core/learning"),
    ("Reward Function","scalar reward maximisation","core/cognition"),
    ("PseudoMind","mutable extension layer","core/extension"),
    ("Network Interface","UAV relay topology & FHSS sandbox","network/sdr"),
    ("TMS","Ternary Metabolic Substrate","substrate/tms"),
    ("TernaryRouter","signed-zero hysteresis router","substrate/router"),
    ("CasimirThrottle","scalar drive from E8 tail","substrate/hunger"),
    ("TernaryGrid2D","32x32 deposit grid","substrate/grid"),
    ("VoxelVehicle3D","8x8x4 voxel bank","substrate/voxel"),
    ("DictionaryDNA4D","age-decaying keyed payload dict","substrate/dict"),
    ("BehavioralGenome","six numeric channels","substrate/genome"),
    ("MetacognitiveMonitor","eight-channel monitor","substrate/monitor"),
    ("VASKAgent","substrate + core integration","substrate/agent"),
    ("Oscillator","CD-ROM three-phase timing","substrate/clock"),
    ("AIFriend","persistent JSON container","substrate/friend"),
    ("Glyph Role Registry","256 CP437 role/gate/sector assignment","substrate/glyph-roles"),
]

function write_organ_registry(p::ORCAPaths)
    reg = Dict{String,Any}(
        "program"=>VERSION, "written_utc"=>utc_now(),
        "doctrine"=>Dict("rna_is_not_semantic"=>RNA_IS_NOT_SEMANTIC,
            "rna_is_functional_grammar"=>RNA_IS_FUNCTIONAL_GRAMMAR,
            "no_voids"=>NO_VOIDS,
            "functionality_is_within_and_without"=>FUNCTIONALITY_IS_WITHIN_AND_WITHOUT,
            "rz_drs_active"=>true,"z_gate_explicit"=>true,"lattice_plateaus_voxels"=>true),
        "organs"=>[Dict("name"=>n,"role"=>r,"surface"=>s,"status"=>"active")
                   for (n,r,s) in ORGAN_DEFINITIONS])
    open(io->write(io, JSON3.write(reg)), p.organ_registry, "w")
    reg
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 05 — FUNCTIONAL RNA GRAMMAR
# ═══════════════════════════════════════════════════════════════════════════════
struct BasketToken
    power::String; polarity::String; payload_hex::String
end
render(bt::BasketToken) = "$(bt.power)$(bt.polarity){$(bt.payload_hex)}"
decode_payload(bt::BasketToken) = hex2bytes(bt.payload_hex)

function bytes_to_basket_tokens(data::AbstractVector{UInt8}; group::Int=6)
    toks = BasketToken[]; n = length(data); i = 1; k = 0
    while i <= n
        chunk = data[i:min(i+group-1,n)]; kk = (k % 4) + 1
        push!(toks, BasketToken(BASKET_POWERS[kk], BASKET_POLARITIES[kk], bytes2hex(chunk)))
        k += 1; i += group
    end
    toks
end

function basket_tokens_to_bytes(text::AbstractString)::Vector{UInt8}
    out = UInt8[]
    for m in eachmatch(BASKET_RE, text)
        append!(out, hex2bytes(m.captures[3]))
    end
    out
end

function rna5_encode(data::AbstractVector{UInt8})::String
    bases = "AUCGZ"; io = IOBuffer(); write(io, "RNA5:v1:")
    for (i,b) in enumerate(data)
        write(io, bases[((i-1)%5)+1], uppercase(string(b,base=16,pad=2)))
    end
    String(take!(io))
end

function rna5_decode(text::AbstractString)::Vector{UInt8}
    startswith(text,"RNA5:v1:") || error("not RNA5:v1")
    body = text[9:end]; length(body) % 3 == 0 || error("bad RNA5 length")
    out = UInt8[]
    for i in 1:3:length(body)
        s = body[i]; s in "AUCGZ" || error("bad strand $(s)")
        push!(out, parse(UInt8, body[i+1:i+2]; base=16))
    end
    out
end

function bytes_to_rna(data::AbstractVector{UInt8})::String
    out = Vector{Char}(undef, length(data))
    @inbounds for i in eachindex(data); out[i] = GLYPH_256[Int(data[i])+1]; end
    String(out)
end

function rna_to_bytes(text::AbstractString)::Vector{UInt8}
    out = Vector{UInt8}(undef, length(text)); i = 0
    @inbounds for c in text
        i += 1; v = get(GLYPH_TO_BYTE, c, nothing)
        v === nothing && error("Unknown RNA glyph: $(repr(c))")
        out[i] = v
    end
    out
end

function render_cluster(tokens::Vector{BasketToken}; width_tokens::Int=2, identity::String="gH")
    length(identity) < 2 && (identity = "gH")
    lid, rid = identity[1], identity[end]
    rows = String[]; n = length(tokens); i = 1
    while i <= n
        chunk = tokens[i:min(i+width_tokens-1,n)]
        payload = join(render(t) for t in chunk)
        first_ = (i==1); last_ = (i+width_tokens > n)
        if first_ && last_; push!(rows, "°{$lid$payload$rid|•")
        elseif first_;     push!(rows, "°{$lid$payload|•")
        elseif last_;      push!(rows, "o{$payload$rid|•")
        else;              push!(rows, "•|$payload$rid|•")
        end
        i += width_tokens
    end
    join(rows, "\n")
end

function box_lines(lines::Vector{String}; axis::String="ZYX", width::Union{Int,Nothing}=nothing)
    isempty(lines) && (lines = [""])
    bw = width === nothing ? maximum(length(l) for l in lines) : width
    bw = max(bw, 4)
    top = axis[1:2] * axis[3]^bw
    bottom = axis[2] * axis[3]^(bw+1)
    out = String[top]
    for l in lines; push!(out, "X" * rpad(l, bw) * "X"); end
    push!(out, bottom); out
end

function grammar_report()::Dict{String,Any}
    sample = Vector{UInt8}(codeunits("ORCA functional RNA grammar sample"))
    btxt = join(render(t) for t in bytes_to_basket_tokens(sample))
    r5 = rna5_encode(sample)
    Dict{String,Any}("basket_roundtrip"=>basket_tokens_to_bytes(btxt)==sample,
        "rna5_roundtrip"=>rna5_decode(r5)==sample,
        "full_rna_roundtrip"=>rna_to_bytes(bytes_to_rna(sample))==sample,
        "strand_lengths"=>Dict(k=>length(v) for (k,v) in STRANDS))
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 05.1 — RNA MULTIFUNCTION MANIFEST
# ═══════════════════════════════════════════════════════════════════════════════
struct RNAFunction
    name::String; description::String; exercised_by::String
end
struct RNAStrandManifest
    letter::String; byte_range::Tuple{Int,Int}; glyph_count::Int
    family::String; functions::Vector{RNAFunction}
end

const RNA_MANIFEST = [
    RNAStrandManifest("A", (0x00, 0x1F), 32, "control_graphics",
        [RNAFunction("encode", "byte 0x00..0x1F -> control graphics (ROM visuals)", "bytes_to_rna"),
         RNAFunction("decode", "control graphics -> byte 0x00..0x1F", "rna_to_bytes"),
         RNAFunction("rna5_letter", "first letter of the compact AUCGZ route", "rna5_encode"),
         RNAFunction("basket_power_0", "cycles through basket powers 3^1", "bytes_to_basket_tokens"),
         RNAFunction("glyph_role_0", "cycle position 0 in glyph role registry", "build_glyph_registry")]),
    RNAStrandManifest("T", (0x20, 0x7F), 96, "ascii_plus_house",
        [RNAFunction("encode", "byte 0x20..0x7F -> ASCII + house", "bytes_to_rna"),
         RNAFunction("decode", "ASCII + house -> byte 0x20..0x7F", "rna_to_bytes"),
         RNAFunction("text_visibility", "only strand fully readable in a terminal", "super_column_from_bytes"),
         RNAFunction("reserved_escape_source", "source of ~t ~s ~q ~c ~r ~e ~n ~d", "clean_encode"),
         RNAFunction("glyph_role_1", "cycle position 1 in glyph role registry", "build_glyph_registry")]),
    RNAStrandManifest("C", (0x80, 0xAF), 48, "accented_latin",
        [RNAFunction("encode", "byte 0x80..0xAF -> accented Latin", "bytes_to_rna"),
         RNAFunction("decode", "accented Latin -> byte 0x80..0xAF", "rna_to_bytes"),
         RNAFunction("utf8_multibyte_demo", "entries are 2-byte UTF-8, useful for transport tests", "self_test[glyph_bijection_256]"),
         RNAFunction("glyph_role_2", "cycle position 2 in glyph role registry", "build_glyph_registry")]),
    RNAStrandManifest("G", (0xB0, 0xDF), 48, "box_and_blocks",
        [RNAFunction("encode", "byte 0xB0..0xDF -> box-drawing + blocks", "bytes_to_rna"),
         RNAFunction("decode", "box-drawing + blocks -> byte 0xB0..0xDF", "rna_to_bytes"),
         RNAFunction("visual_geometry", "source alphabet for cluster walls", "render_cluster"),
         RNAFunction("fence_source", "supplies Z/Y/X fence characters", "box_lines"),
         RNAFunction("glyph_role_3", "cycle position 3 in glyph role registry", "build_glyph_registry")]),
    RNAStrandManifest("Z", (0xE0, 0xFF), 32, "greek_math_nbsp",
        [RNAFunction("encode", "byte 0xE0..0xFF -> Greek + math + NBSP", "bytes_to_rna"),
         RNAFunction("decode", "Greek + math + NBSP -> byte 0xE0..0xFF", "rna_to_bytes"),
         RNAFunction("metatrit_payload", "source for MetaTrit Kan/jfr glyphs", "MetaTrit.encode"),
         RNAFunction("glyph_role_4", "cycle position 4 in glyph role registry", "build_glyph_registry")]),
]

rna_manifest_summary() = Dict{String,Any}(
    "strands" => [Dict("letter"=>s.letter,"range"=>s.byte_range,"count"=>s.glyph_count,
                       "family"=>s.family,"functions"=>[f.name for f in s.functions])
                   for s in RNA_MANIFEST],
    "total_glyphs" => sum(s.glyph_count for s in RNA_MANIFEST),
    "total_functions" => sum(length(s.functions) for s in RNA_MANIFEST),
    "functionality_is_within_and_without" => FUNCTIONALITY_IS_WITHIN_AND_WITHOUT)

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 06 — CLEAN ENCODE/DECODE
# ═══════════════════════════════════════════════════════════════════════════════
clean_encode(s::AbstractString) = String(join(get(RESERVED_MAP, c, string(c)) for c in s))

function clean_decode(s::AbstractString)::String
    io = IOBuffer(); i = 1; n = length(s); bl = length(BOUNDARY)
    while i <= n
        if i+bl-1 <= n && s[i:i+bl-1] == BOUNDARY; i += bl; continue; end
        c = s[i]
        if c == ESC
            i+1 > n && error("dangling clean escape")
            pair = s[i:i+1]
            haskey(UNRESERVED_MAP, pair) || error("unknown clean escape $(repr(pair))")
            write(io, UNRESERVED_MAP[pair]); i += 2; continue
        end
        write(io, c); i += 1
    end
    String(take!(io))
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 07 — RLE & NUMBER ROWS
# ═══════════════════════════════════════════════════════════════════════════════
function quicky_rle_encode_cleaned(s::AbstractString)::String
    out = String[]; i = 1; n = length(s)
    while i <= n
        ch = s[i]; j = i+1
        while j <= n && s[j] == ch; j += 1; end
        run = j - i; tok = "$run*$ch"; lit = ch^run
        if run > 1 && length(tok) < length(lit)
            (!isempty(out) && !isempty(out[end]) && isdigit(out[end][end])) && push!(out, BOUNDARY)
            push!(out, tok)
        else push!(out, lit) end
        i = j
    end
    join(out)
end

function quicky_rle_decode_cleaned(s::AbstractString)::String
    out = IOBuffer(); i = 1; n = length(s); bl = length(BOUNDARY)
    while i <= n
        if i+bl-1 <= n && s[i:i+bl-1] == BOUNDARY; i += bl; continue; end
        c = s[i]
        if isdigit(c)
            j = i+1
            while j <= n && isdigit(s[j]); j += 1; end
            if j <= n && s[j] == '*' && j+1 <= n
                cnt = min(parse(Int, s[i:j-1]), MAX_RLE_RUN)
                write(out, s[j+1]^cnt); i = j+2; continue
            end
            write(out, s[i:j-1]); i = j; continue
        end
        write(out, c); i += 1
    end
    String(take!(io))
end

function number_rows(text::AbstractString; width::Int=158)::Vector{String}
    t = replace(text, " " => SPACE_VIS); rows = String[]; i = 1
    while i <= length(t)
        push!(rows, lpad(string(length(rows)),3,'0') * ":" * t[i:min(i+width-1,length(t))])
        i += width
    end
    isempty(rows) && push!(rows, "000:"); rows
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 07.5 — META-TRIT CODEC
# ═══════════════════════════════════════════════════════════════════════════════
module MetaTrit
glyph(t::Int) = t==-1 ? "jfr" : t==1 ? "Kan" : t==2 ? "°jfr" : "°six"

function encode(trits::AbstractVector{Int})::String
    out = IOBuffer(); i = 1; n = length(trits)
    while i <= n
        v = trits[i]; j = i+1
        while j <= n && trits[j] == v; j += 1; end
        run = j - i; best = 0
        for w in 0:7
            div = 3^w
            run % div == 0 && (run ÷ div) <= 999_999 && (best = w)
        end
        div = 3^best; block = run ÷ div
        if run >= 3
            sign = v==-1 ? "-" : v==1 ? "+" : v==2 ? "-0" : "+0"
            write(out, "$sign" * "3^$best($block)")
        else
            for _ in 1:run; write(out, glyph(v)); end
        end
        i = j
    end
    String(take!(out))
end

function decode(text::AbstractString)::Vector{Int}
    out = Int[]; i = 1; L = length(text)
    while i <= L
        c = text[i]
        if c == '-' || c == '+'
            sign = string(c); i += 1
            if i <= L && text[i] == '0'; sign *= "0"; i += 1; end
            i+1 <= L && text[i:i+1] == "3^" || error("missing 3^"); i += 2
            ws = ""; while i <= L && isdigit(text[i]); ws *= text[i]; i += 1; end
            i+1 <= L && text[i:i+1] == "}(" || error("missing }("); i += 2
            ns = ""; while i <= L && isdigit(text[i]); ns *= text[i]; i += 1; end
            i <= L && text[i] == ')' && (i += 1)
            w = isempty(ws) ? 0 : parse(Int, ws)
            n = isempty(ns) ? 0 : parse(Int, ns)
            val = sign=="-" ? -1 : sign=="+" ? 1 : sign=="-0" ? 2 : 0
            append!(out, fill(val, n * 3^w))
        else
            if startswith(text[i:end], "°jfr"); push!(out, 2); i += 5
            elseif startswith(text[i:end], "°six"); push!(out, 0); i += 5
            elseif startswith(text[i:end], "jfr"); push!(out, -1); i += 3
            elseif startswith(text[i:end], "Kan"); push!(out, 1); i += 3
            else error("bad MetaTrit at $i")
            end
        end
    end
    out
end

function bytes_to_trits(data::AbstractVector{UInt8})::Vector{Int}
    out = Int[]
    for byte in data
        n = Int(byte); digits = Int[]
        for _ in 1:6; push!(digits, n % 3); n ÷= 3; end
        append!(out, reverse(digits))
    end
    out
end

function trits_to_bytes(trits::AbstractVector{Int})::Vector{UInt8}
    length(trits) % 6 == 0 || error("trit count not mult of 6")
    out = UInt8[]
    for i in 1:6:length(trits)
        n = 0
        for k in 0:5
            t = trits[i+k]; (t < 0 || t > 2) && (t = 0)
            n = n*3 + t
        end
        n > 255 && error("trit value out of byte range"); push!(out, UInt8(n))
    end
    out
end
end # module MetaTrit

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 08 — QUICKY Q0/Q1/Q2 & DICTIONARY
# ═══════════════════════════════════════════════════════════════════════════════
function quicky_q0(rows::Vector{String})::Vector{String}
    out = String[]
    for row in rows
        label = row[1:min(4,length(row))]; body = length(row)>4 ? row[5:end] : ""
        enc = quicky_rle_encode_cleaned(clean_encode(body))
        if clean_decode(quicky_rle_decode_cleaned(enc)) != replace(body, SPACE_VIS => " ")
            error("Q0 failed at $label")
        end
        push!(out, label * enc)
    end
    out
end

function quicky_q1(rows::Vector{String})::Vector{String}
    seen = Dict{String,String}(); out = String[]
    for line in rows
        label = line[1:min(4,length(line))]; body = length(line)>4 ? line[5:end] : ""
        if haskey(seen, body); push!(out, label * REF_MARK * seen[body])
        else; seen[body] = label[1:min(3,length(label))]; push!(out, line) end
    end
    out
end

function quicky_expand_q1(rows::Vector{String})::Vector{String}
    table = Dict{String,String}(); out = String[]
    for line in rows
        label = line[1:min(4,length(line))]; body = length(line)>4 ? line[5:end] : ""
        if startswith(body, REF_MARK)
            ref = body[2:end]; haskey(table, ref) || error("bad ref $label->$ref")
            body = table[ref]
        end
        table[label[1:min(3,length(label))]] = body
        push!(out, label * body)
    end
    out
end

function choose_dictionary(lines::Vector{String}; max_entries::Int=64, min_count::Int=3)
    current = copy(lines); dict = Tuple{String,String}[]
    slens = (96,80,64,48,40,32,24,20,16,12,10,8,6)
    for idx in 0:max_entries-1
        tok = "$(DICT_MARK)$(lpad(idx,2,'0'))$(DICT_MARK)"
        counter = Dict{String,Int}()
        for line in current
            body = length(line)>4 ? line[5:end] : ""
            for sl in slens
                sl > length(body) && continue
                for pos in 1:length(body)-sl+1
                    sub = body[pos:pos+sl-1]
                    (occursin(DICT_MARK, sub) || occursin(REF_MARK, sub)) && continue
                    counter[sub] = get(counter, sub, 0) + 1
                end
            end
        end
        best, best_gain = nothing, 0
        for (sub, cnt) in counter
            cnt < min_count && continue
            gain = (length(sub)-length(tok))*cnt - length(sub) - length(tok) - 4
            if gain > best_gain; best, best_gain = sub, gain; end
        end
        best === nothing && break
        push!(dict, (tok, best))
        current = [line[1:min(4,length(line))] *
                    replace(line[min(5,length(line)+1):end], best=>tok) for line in current]
    end
    (dict, current)
end

function expand_dictionary(dict::Vector{Tuple{String,String}}, lines::Vector{String})
    out = copy(lines)
    for (tok, phrase) in reverse(dict)
        out = [replace(line, tok=>phrase) for line in out]
    end
    out
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 09 — BROTHER QUICKY PACKAGE
# ═══════════════════════════════════════════════════════════════════════════════
function brother_quicky_package(raw::Vector{UInt8}; width::Int=158)::Dict{String,Any}
    text = String(raw)
    rows0 = number_rows(text; width)
    q0 = quicky_q0(rows0); q1 = quicky_q1(q0)
    dict, q2 = choose_dictionary(q1)
    ex1 = expand_dictionary(dict, q2); ex0 = quicky_expand_q1(ex1)
    dec_lines = [clean_decode(quicky_rle_decode_cleaned(l[5:end])) for l in ex0]
    restored_text = replace(join(dec_lines), SPACE_VIS => " ")
    restored = Vector{UInt8}(codeunits(restored_text))
    restored == raw || error("Brother Quicky roundtrip failed")
    Dict{String,Any}("kind"=>"brother_quicky_v2","width"=>width,
        "dictionary"=>dict,"rows"=>q2,
        "stats"=>Dict{String,Any}("raw_chars"=>length(text),
            "q2_chars"=>sum(length, q2),"dict_entries"=>length(dict)))
end

function decode_brother_quicky_package(pkg::Dict{String,Any})::Vector{UInt8}
    dict = [(String(a), String(b)) for (a,b) in get(pkg, "dictionary", [])]
    rows = [string(x) for x in get(pkg, "rows", [])]
    ex1 = expand_dictionary(dict, rows); ex0 = quicky_expand_q1(ex1)
    dec = replace(join(clean_decode(quicky_rle_decode_cleaned(l[5:end])) for l in ex0),
                  SPACE_VIS => " ")
    Vector{UInt8}(codeunits(dec))
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 10 — VERTICALIA / SPLITTA
# ═══════════════════════════════════════════════════════════════════════════════
function verticalia_transposition(rna::String, width::Int)::Vector{String}
    rows = [rna[i:min(i+width-1,length(rna))] for i in 1:width:length(rna)]
    !isempty(rows) && (rows[end] = rpad(rows[end], width, SPACE_VIS))
    [join([r[min(c,length(r))] for r in rows]) for c in 1:width]
end

function numerono_splitta_fence(stalks::Vector{String}, width::Int)::String
    out = ["000:ZXY" * "Y"^(width-3), ""]
    for (t,x) in enumerate([100,10,1])
        h = join(string((i ÷ x) % 10) for i in 0:width-1)
        push!(out, "$(lpad(t,3,'0')):$(t==1 ? 'X' : 'Y')$h" * "Y", "")
    end
    push!(out, "004:Y" * ":"^width * "Y", "")
    push!(out, "005:Y" * SPACE_VIS^width * "Y", "")
    for (i,s) in enumerate(stalks)
        compact = quicky_rle_encode_cleaned(clean_encode(s))
        chk = length(rstrip(s, first(SPACE_VIS)))
        push!(out, "$(lpad(i+5,3,'0')):Y$(compact)Y$(lpad(chk,3,'0'))", "")
    end
    push!(out, "$(lpad(length(stalks)+6,3,'0')):X" * "Y"^width)
    join(out, "\n")
end

function brother_quicky_geom(raw::Vector{UInt8})::Dict{String,Any}
    rna = bytes_to_rna(raw)
    width = min(999, max(162, floor(Int, sqrt(length(rna)))))
    stalks = verticalia_transposition(rna, width)
    geom_text = numerono_splitta_fence(stalks, width)
    bq = brother_quicky_package(raw; width)
    bq["geom_text"] = geom_text
    bq
end

function decode_brother_quicky_geom(pkg::Dict{String,Any})::Vector{UInt8}
    geom = get(pkg, "geom_text", "")
    stalks = String[]
    for line in split(geom, '\n')
        m = match(r"^\d+:Y(.*)Y\d{3}$", line)
        m === nothing && continue
        push!(stalks, clean_decode(quicky_rle_decode_cleaned(String(m.captures[1]))))
    end
    isempty(stalks) && error("no stalks")
    max_len = maximum(length, stalks)
    rows = [join([i <= length(s) ? s[i] : first(SPACE_VIS) for s in stalks]) for i in 1:max_len]
    rna = replace(join(rows), SPACE_VIS => "")
    rna_to_bytes(rna)
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 11 — SDO ENVELOPE
# ═══════════════════════════════════════════════════════════════════════════════
function sdo_pack(method::String, payload::Vector{UInt8}, raw_sha::String,
                  raw_len::Int; extra::Dict{String,Any}=Dict{String,Any}())
    meta = Dict{String,Any}("program"=>VERSION,"created_utc"=>utc_now(),
        "method"=>method,"raw_sha256"=>raw_sha,"raw_len"=>raw_len,
        "payload_len"=>length(payload),"payload_sha256"=>sha256_hex(payload),
        "extra"=>extra)
    mb = codeunits(JSON3.write(meta)); ml = length(mb)
    out = Vector{UInt8}(undef, length(BLACK_MAGIC) + 8 + ml + length(payload))
    pos = 1
    @inbounds for b in BLACK_MAGIC; out[pos] = b; pos += 1; end
    @inbounds for shift in (56,48,40,32,24,16,8,0)
        out[pos] = UInt8((ml >> shift) & 0xFF); pos += 1
    end
    @inbounds for b in mb; out[pos] = b; pos += 1; end
    @inbounds for b in payload; out[pos] = b; pos += 1; end
    out
end

function sdo_unpack(blob::AbstractVector{UInt8})
    magic = nothing
    for m in (BLACK_MAGIC, LEGACY_MAGICS...)
        if length(blob) >= length(m) && view(blob,1:length(m)) == m
            magic = m; break
        end
    end
    magic === nothing && error("not an SDO object")
    pos = length(magic) + 1
    length(blob) < pos + 7 && error("truncated SDO")
    ml::UInt64 = 0
    @inbounds for i in 0:7; ml = (ml << 8) | UInt64(blob[pos+i]); end
    pos += 8
    length(blob) < pos + Int(ml) - 1 && error("truncated meta")
    meta = JSON3.read(String(view(blob,pos:pos+Int(ml)-1)), Dict{String,Any})
    pos += Int(ml)
    payload = Vector{UInt8}(view(blob,pos:length(blob)))
    (meta, payload)
end

function sdo_decode(blob::AbstractVector{UInt8})::Vector{UInt8}
    meta, payload = sdo_unpack(blob)
    method = get(meta, "method", "raw")
    raw = if method == "raw"; copy(payload)
    elseif method == "zlib_raw"; transcode(ZlibDecompressor, payload)
    elseif method == "gzip_raw"; transcode(GzipDecompressor, payload)
    elseif method == "bz2_raw"; transcode(Bzip2Decompressor, payload)
    elseif method == "lzma_raw"; transcode(XzDecompressor, payload)
    elseif method == "rna5_text_zlib"
        rna5_decode(String(transcode(ZlibDecompressor, payload)))
    elseif method == "basket_text_zlib"
        basket_tokens_to_bytes(String(transcode(ZlibDecompressor, payload)))
    elseif method == "brother_quicky_json_zlib"
        decode_brother_quicky_package(JSON3.read(String(transcode(ZlibDecompressor, payload)), Dict{String,Any}))
    elseif method == "geometry_text_zlib"
        g = JSON3.read(String(transcode(ZlibDecompressor, payload)), Dict{String,Any})
        base64decode(g["raw_b64"])
    elseif method == "trit_sd0"
        mt_bytes = transcode(ZlibDecompressor, payload)
        trits = MetaTrit.decode(String(mt_bytes))
        z_raw = MetaTrit.trits_to_bytes(trits)
        transcode(ZlibDecompressor, z_raw)
    elseif method == "brother_quicky_geom_zlib"
        g = JSON3.read(String(transcode(ZlibDecompressor, payload)), Dict{String,Any})
        decode_brother_quicky_geom(g)
    elseif method == "tar_lzma_base64_text"
        transcode(XzDecompressor, base64decode(String(payload)))
    else
        error("unknown SDO method: $method")
    end
    expected_sha = get(meta, "raw_sha256", "")
    !isempty(expected_sha) && sha256_hex(raw) != expected_sha && error("raw sha mismatch")
    expected_len = Int(get(meta, "raw_len", -1))
    expected_len >= 0 && length(raw) != expected_len && error("raw length mismatch")
    raw
end

sdo_metadata(blob::AbstractVector{UInt8}) = sdo_unpack(blob)[1]

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 12 — SDO COMPRESSION LADDER
# ═══════════════════════════════════════════════════════════════════════════════
function geometry_projection(raw::Vector{UInt8}; name::String="payload")
    head = raw[1:min(length(raw),512)]
    toks = bytes_to_basket_tokens(head)
    cluster = render_cluster(toks; width_tokens=2, identity="gH")
    box = box_lines(split(cluster, '\n'); axis="ZYX")
    Dict{String,Any}("kind"=>"geometry_projection_v2","name"=>name,
        "raw_b64"=>base64encode(raw),"preview"=>box,
        "rules"=>Dict("rna_is_functional_not_semantic"=>true))
end

function candidate_payloads(raw::Vector{UInt8}; name::String="payload")
    out = Tuple{String,Vector{UInt8},Dict{String,Any}}[]
    push!(out, ("raw", copy(raw), Dict{String,Any}()))
    push!(out, ("zlib_raw", transcode(ZlibCompressor, raw), Dict{String,Any}()))
    push!(out, ("gzip_raw", transcode(GzipCompressor, raw), Dict{String,Any}()))
    push!(out, ("bz2_raw", transcode(Bzip2Compressor, raw), Dict{String,Any}()))
    push!(out, ("lzma_raw", transcode(XzCompressor, raw), Dict{String,Any}()))
    sc = scan_bytes(raw, name)
    if length(raw) < 2_000_000 && Float64(sc["entropy_bits_per_byte"]) < 7.2
        try
            z_raw = transcode(ZlibCompressor, raw)
            trits = MetaTrit.bytes_to_trits(z_raw)
            mt_text = MetaTrit.encode(trits)
            mt_bytes = codeunits(mt_text)
            final = transcode(ZlibCompressor, mt_bytes)
            push!(out, ("trit_sd0", final, Dict{String,Any}("route"=>"MetaTrit","origin"=>"E8i_PS2")))
        catch e
            push!(out, ("trit_sd0_failed", UInt8[], Dict{String,Any}("rejected"=>true,"reason"=>string(e))))
        end
    end
    r5 = codeunits(rna5_encode(raw))
    push!(out, ("rna5_text_zlib", transcode(ZlibCompressor, r5), Dict{String,Any}("route"=>"RNA5")))
    btxt = codeunits(join(render(t) for t in bytes_to_basket_tokens(raw)))
    push!(out, ("basket_text_zlib", transcode(ZlibCompressor, btxt), Dict{String,Any}("route"=>"basket")))
    if is_text_like(raw) && length(raw) <= 5_000_000
        try
            bq = brother_quicky_package(raw)
            bq_json = codeunits(JSON3.write(bq))
            push!(out, ("brother_quicky_json_zlib", transcode(ZlibCompressor, bq_json),
                        Dict{String,Any}("stats"=>bq["stats"])))
        catch e
            push!(out, ("brother_quicky_failed_note", codeunits(string(e)),
                        Dict{String,Any}("rejected"=>true)))
        end
        try
            bqg = brother_quicky_geom(raw)
            bqg_json = codeunits(JSON3.write(bqg))
            push!(out, ("brother_quicky_geom_zlib", transcode(ZlibCompressor, bqg_json),
                        Dict{String,Any}("route"=>"geometry")))
        catch end
    end
    geom = geometry_projection(raw; name)
    geom_json = codeunits(JSON3.write(geom))
    push!(out, ("geometry_text_zlib", transcode(ZlibCompressor, geom_json),
                Dict{String,Any}("route"=>"geometry")))
    out
end

function build_stage(raw::Vector{UInt8}, method::String, payload::Vector{UInt8};
                     extra::Dict{String,Any}=Dict{String,Any}())
    sdo_pack(method, payload, sha256_hex(raw), length(raw); extra)
end

function build_stages(input_path::AbstractString, out_dir::AbstractString;
                      add_to_zip::Bool=true)::Dict{String,Any}
    filesize(input_path) > LADDER_MAX_BYTES && error("file too large")
    raw = read_all(input_path); mkpath(out_dir)
    base = safe_name(splitext(basename(input_path))[1])
    raw_sha = sha256_hex(raw)
    scan = scan_bytes(raw, basename(input_path))

    sd4 = build_stage(raw, "raw", raw; extra=Dict{String,Any}("stage"=>"sd4","scan"=>scan))
    sd3 = build_stage(raw, "zlib_raw", transcode(ZlibCompressor, raw); extra=Dict("stage"=>"sd3"))
    geom = geometry_projection(raw; name=basename(input_path))
    sd2 = build_stage(raw, "geometry_text_zlib",
                      transcode(ZlibCompressor, codeunits(JSON3.write(geom))); extra=Dict("stage"=>"sd2"))
    sd1 = try
        bq = brother_quicky_package(raw)
        build_stage(raw, "brother_quicky_json_zlib",
                    transcode(ZlibCompressor, codeunits(JSON3.write(bq)));
                    extra=Dict{String,Any}("stage"=>"sd1","stats"=>bq["stats"]))
    catch e
        btxt = codeunits(join(render(t) for t in bytes_to_basket_tokens(raw)))
        build_stage(raw, "basket_text_zlib", transcode(ZlibCompressor, btxt);
                    extra=Dict{String,Any}("stage"=>"sd1","fallback"=>"basket","error"=>string(e)))
    end

    verified = Tuple{String,Vector{UInt8},Dict{String,Any},Int}[]
    for (m, payload, ex) in candidate_payloads(raw; name=basename(input_path))
        get(ex, "rejected", false) && continue
        try
            obj = build_stage(raw, m, payload; extra=merge(Dict{String,Any}("stage"=>"sd0_candidate"), ex))
            sdo_decode(obj) == raw && push!(verified, (m, obj, ex, length(obj)))
        catch end
    end
    isempty(verified) && error("no verified sd0 candidates")
    sort!(verified; by=x->x[4])
    winner_method, sd0, _, _ = verified[1]

    files = Dict("sd4"=>joinpath(out_dir,"$(base).sd4"),
                 "sd3"=>joinpath(out_dir,"$(base).sd3"),
                 "sd2"=>joinpath(out_dir,"$(base).sd2"),
                 "sd1"=>joinpath(out_dir,"$(base).sd1"),
                 "sd0"=>joinpath(out_dir,"$(base).sd0"))
    blobs = Dict("sd4"=>sd4,"sd3"=>sd3,"sd2"=>sd2,"sd1"=>sd1,"sd0"=>sd0)
    stage_files = Dict{String,Any}()
    for (k,p) in files
        atomic_write(p, blobs[k])
        sdo_decode(read_all(p)) == raw || error("stage $k roundtrip failed")
        m = sdo_metadata(blobs[k])
        stage_files[k] = Dict{String,Any}("path"=>p,"bytes"=>filesize(p),
                                            "method"=>get(m,"method","?"))
    end

    if add_to_zip
        try
            upsert_zip(joinpath(out_dir, "REPOSITORY.zip"), basename(files["sd0"]), blobs["sd0"])
        catch end
    end

    manifest = Dict{String,Any}("program"=>VERSION,"input"=>String(input_path),
        "raw_len"=>length(raw),"raw_sha256"=>raw_sha,"scan"=>scan,
        "stage_files"=>stage_files,"sd0_winner"=>winner_method,
        "verified_candidates"=>[Dict("method"=>m,"bytes"=>n) for (m,_,_,n) in verified],
        "repository_zip"=> add_to_zip ? joinpath(out_dir,"REPOSITORY.zip") : nothing)
    atomic_write(joinpath(out_dir,"$(base)_manifest.json"), codeunits(JSON3.write(manifest)))
    manifest
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 13 — SEND BOOK & LOSSLESS TXT BUNDLE
# ═══════════════════════════════════════════════════════════════════════════════
function super_column_from_bytes(data::Vector{UInt8}; width::Int=162)
    io = IOBuffer()
    println(io, "ORCA ZND RNA SUPER-COLUMN"); println(io, "WIDTH=$width")
    println(io, "BYTES=$(length(data))"); println(io, "SHA256=$(sha256_hex(data))")
    println(io, "---")
    for (i,b) in enumerate(data)
        ch = 32 <= b <= 126 ? Char(b) : b == 0x20 ? SPACE_VIS : "·"
        println(io, lpad(string(i-1),12,'0'), ": ", uppercase(string(b,base=16,pad=2)), " ", ch)
    end
    String(take!(io))
end

function send_book_export(repo_zip::String, export_dir::String;
                          width::Int=162, max_rows::Int=0)::Dict{String,Any}
    isfile(repo_zip) || error("repo zip not found")
    mkpath(export_dir)
    snap = joinpath(export_dir, "REPOSITORY_snapshot_$(floor(Int,time())).zip")
    cp(repo_zip, snap; force=true)
    entries = Dict{String,Any}[]; combined = UInt8[]
    try
        r = ZipArchives.ZipReader(read(repo_zip))
        for name in sort(ZipArchives.zip_names(r))
            data = Vector{UInt8}(ZipArchives.zip_readentry(r, name, Vector{UInt8}))
            local raw, status
            try
                raw = sdo_decode(data); status = "decoded"
            catch
                raw = data; status = "raw_entry"
            end
            append!(combined, codeunits("\n===== ENTRY $(name) STATUS $(status) =====\n"))
            append!(combined, raw)
            push!(entries, Dict{String,Any}("name"=>name,"stored_bytes"=>length(data),
                "raw_bytes"=>length(raw),"sha256"=>sha256_hex(raw),"status"=>status))
        end
    catch e
        @warn "send_book_export: read failed" e
    end
    super_text = super_column_from_bytes(combined; width)
    if max_rows > 0
        lines = split(super_text, '\n')
        super_text = join(lines[1:min(max_rows,length(lines))], "\n") *
                     "\n[TRUNCATED VIEW max_rows=$(max_rows)]\n"
    end
    stamp = Dates.format(now(), "yyyymmdd_HHMMSS")
    out = joinpath(export_dir, "SEND_BOOK_super_column_$(stamp).txt")
    atomic_write(out, codeunits(super_text))
    manifest = Dict{String,Any}("program"=>VERSION,"generated_utc"=>utc_now(),
        "source_repository"=>repo_zip,"snapshot"=>snap,"output"=>out,
        "output_sha256"=>sha256_hex(codeunits(super_text)),"entries"=>entries,"read_only"=>true)
    atomic_write(out * ".manifest.json", codeunits(JSON3.write(manifest)))
    manifest
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 14 — CoreState248 (E8-inspired state)
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct CoreState248
    real::Vector{Float64}; imag::Vector{Float64}
    tau::Float64; birth::Float64
    z_state::Int; z_gate_count::Int
    rota_position::Dict{String,Float64}
    obstacle_history::Dict{String,Float64}; lock_count::Dict{String,Int}
    rota_log::Vector{Dict{String,Any}}
    current_plateau::String; bypass_count::Int; phase::String
    lock::ReentrantLock
    function CoreState248()
        nrm = 1.0/sqrt(248.0)
        new(fill(nrm,248), zeros(248), 0.0, time(), 0, 0,
            Dict("X"=>0.0,"Y"=>0.0,"Z"=>0.0), Dict{String,Float64}(),
            Dict{String,Int}(), Dict{String,Any}[], "PRESENT", 0, "LARVAL",
            ReentrantLock())
    end
end
get_phase(s::CoreState248) = s.phase

function perceive!(s::CoreState248, metadata::Dict{String,Any}; scale::Float64=1.0)
    ent = Float64(get(metadata,"entropy_bits_per_byte",0.0))
    rl = Int(get(metadata,"raw_len",0))
    mg = String(get(metadata,"magic",""))
    lock(s.lock) do
        ent > 7.5 && _nudge!(s, "EXCEPTIONAL", 0.015*(ent/8.0)*scale)
        rl > 100_000 && _nudge!(s, "F4_G2", 0.01*log2(max(1,rl)/1000.0)*scale)
        mg in ("python","cpp","c","h","json","md","tex","txt","jl") && _nudge!(s,"SU3",0.02*scale)
        mg in ("exe","dll","elf","bin","7z","zip") && _nudge!(s,"F4_G2",0.015*scale)
        _renormalise!(s)
    end
end

function metabolic_decay!(s::CoreState248; dc::Float64=0.0002)
    lock(s.lock) do
        base = 1.0/sqrt(248.0)
        @inbounds for i in 1:248
            s.real[i] = s.real[i]*(1-dc) + base*dc
            s.imag[i] *= (1-dc)
        end
        _renormalise!(s)
    end
end

function _nudge!(s::CoreState248, sector::String, scale::Float64)
    s0,s1 = get(SECTOR_BOUNDS, sector, (0,0))
    s1 <= s0 && return
    nv = scale / max(1, s1-s0)
    @inbounds for i in s0+1:min(s1,248)
        s.real[i] = clamp(s.real[i] + nv, -10.0, 10.0)
    end
end

function _renormalise!(s::CoreState248)
    mag = sqrt(sum(r*r + im*im for (r,im) in zip(s.real,s.imag)))
    mag < 1e-15 && (mag = 1e-15); inv = 1.0/mag
    @inbounds for i in 1:248; s.real[i] *= inv; s.imag[i] *= inv; end
end

norm_state(s::CoreState248) = sqrt(sum(r*r + im*im for (r,im) in zip(s.real,s.imag)))

function get_activations(s::CoreState248)::Dict{String,Float64}
    out = Dict{String,Float64}()
    for (name,(s0,s1)) in SECTOR_BOUNDS
        out[name] = sum(s.real[i]^2 + s.imag[i]^2 for i in s0+1:min(s1,248))
    end
    out
end

function apply_z_rotation!(s::CoreState248, direction::Int)
    lock(s.lock) do
        g1s,g2s,g3s = 1, 83, 165
        old_r = copy(s.real); old_i = copy(s.imag)
        if direction == 1
            for k in 0:81
                s.real[g2s+k] = old_r[g1s+k]; s.imag[g2s+k] = old_i[g1s+k]
                s.real[g3s+k] = old_r[g2s+k]; s.imag[g3s+k] = old_i[g2s+k]
                s.real[g1s+k] = old_r[g3s+k]; s.imag[g1s+k] = old_i[g3s+k]
            end
        else
            for k in 0:81
                s.real[g3s+k] = old_r[g1s+k]; s.imag[g3s+k] = old_i[g1s+k]
                s.real[g1s+k] = old_r[g2s+k]; s.imag[g1s+k] = old_i[g2s+k]
                s.real[g2s+k] = old_r[g3s+k]; s.imag[g2s+k] = old_i[g3s+k]
            end
        end
        s.z_state = direction; s.z_gate_count += 1
        _renormalise!(s)
        _update_rota_position!(s, direction)
    end
end

function _update_rota_position!(s::CoreState248, direction::Int)
    a = get_activations(s)
    x = get(a,"SU3",0.0)*2.0 - 1.0
    y = (get(a,"SU2",0.0) + get(a,"U1",0.0))*1.5 - 1.0
    z = direction*0.5
    s.rota_position["X"] = s.rota_position["X"]*0.9 + x*0.1
    s.rota_position["Y"] = s.rota_position["Y"]*0.9 + y*0.1
    s.rota_position["Z"] = s.rota_position["Z"]*0.9 + z*0.1
end

function detect_lock(s::CoreState248, sector::String; target::Float64=0.0, tolerance::Float64=0.01)
    s0,s1 = get(SECTOR_INDICES, sector, (0,0))
    s1 <= s0 && return false
    alpha = sum(s.real[i]^2 + s.imag[i]^2 for i in s0+1:min(s1,248))
    if abs(alpha - target) > tolerance
        key = "$(sector)_$(s.z_gate_count)"
        if haskey(s.obstacle_history, key)
            old = s.obstacle_history[key]
            if abs(alpha - old) < 0.001
                s.lock_count[sector] = get(s.lock_count, sector, 0) + 1
                return true
            end
        end
        s.obstacle_history[key] = alpha
        return true
    end
    false
end

function bypass_obstacle!(s::CoreState248, sector::String; target::Float64=0.0)
    s0,s1 = get(SECTOR_INDICES, sector, (0,0))
    s1 <= s0 && return (0, 0.0)
    alpha = sum(s.real[i]^2 + s.imag[i]^2 for i in s0+1:min(s1,248))
    direction = alpha > target ? 1 : -1
    apply_z_rotation!(s, direction)
    s.bypass_count += 1
    push!(s.rota_log, Dict{String,Any}("timestamp"=>utc_now(),"sector"=>sector,
        "alpha_before"=>alpha,"direction"=>direction,"bypass_count"=>s.bypass_count,
        "rota_position"=>copy(s.rota_position)))
    new_alpha = sum(s.real[i]^2 + s.imag[i]^2 for i in s0+1:min(s1,248))
    (direction, new_alpha)
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 15 — SectorActivation
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct SectorActivation
    name::String; alpha::Float64; mu::Float64; r::Float64; u::Float64
    T_eff::Float64; Z::Float64; locked::Bool
    dimension::Int; casimir::Float64; R_ratio::Float64
    function SectorActivation(name::String; alpha::Float64=0.0,
                              mu::Float64=0.0, r::Float64=1.0, u::Float64=1.0,
                              T_eff::Float64=1.0, Z::Float64=1.0)
        d = get(SECTOR_DIMS, name, 1)
        c = get(SECTOR_CASIMIRS, name, 0.0)
        rr = c > 0 ? d/c : 0.0
        new(name, alpha, mu, r, u, T_eff, Z, false, d, c, rr)
    end
end
V_eff(sa::SectorActivation, a::Float64) = -sa.mu*a + 0.5*(sa.T_eff*sa.dimension - sa.r)*a^2 + 0.25*sa.u*a^4
dV_dalpha(sa::SectorActivation, a::Float64) = -sa.mu + (sa.T_eff*sa.dimension - sa.r)*a + sa.u*a^3
function relaxation_step!(sa::SectorActivation; dt::Float64=0.01)
    sa.locked && return sa.alpha
    sa.alpha = clamp(sa.alpha - dt*dV_dalpha(sa, sa.alpha), 0.0, 1.0)
end
critical_T(sa::SectorActivation) = sa.r / max(sa.dimension, 1)
function equilibrium_alpha(sa::SectorActivation)
    drive = sa.r - sa.T_eff*sa.dimension
    drive <= 0 && return 0.0
    sqrt(drive / max(sa.u, 1e-15))
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 16 — SectorProjector
# ═══════════════════════════════════════════════════════════════════════════════
struct SectorProjector
    name::String; start::Int; stop::Int; dimension::Int
    casimir::Float64; R_ratio::Float64
end
SectorProjector(name::String, idx::Tuple{Int,Int}) = begin
    s, e = idx
    d = e - s
    c = get(SECTOR_CASIMIRS, name, 0.0)
    SectorProjector(name, s, e, d, c, c > 0 ? d/c : 0.0)
end
project(P::SectorProjector, s::CoreState248) = sum(s.real[i]^2 + s.imag[i]^2 for i in P.start+1:min(P.stop,248))

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 17 — ParticleKeychain
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct ParticleKeychain
    name::String; symbol::String; keys::Dict{String,Float64}
    mass_template::Float64; spin::Float64; effective_mass::Float64
end
ParticleKeychain(name, symbol, keys; spin=0.5) =
    ParticleKeychain(name, symbol, keys, 0.0, spin, 0.0)
has_key(p::ParticleKeychain, s::String) = get(p.keys, s, 0.0) > 0
function compute_effective_mass!(p::ParticleKeychain, amap::Dict{String,Float64})
    m² = sum(w * get(amap, s, 0.0) for (s,w) in p.keys if s == "HIGGS"; init=0.0)
    p.effective_mass = sqrt(max(0.0, m²))
end
permission_sum(p::ParticleKeychain) = sum(values(p.keys); init=0.0)

standard_particles() = [
    ParticleKeychain("photon","γ",Dict("EM"=>1.0); spin=1.0),
    ParticleKeychain("gluon","g",Dict("STRONG"=>1.0); spin=1.0),
    ParticleKeychain("W_boson","W±",Dict("WEAK"=>1.0,"HIGGS"=>1.0); spin=1.0),
    ParticleKeychain("Z_boson","Z⁰",Dict("WEAK"=>1.0,"HIGGS"=>1.0); spin=1.0),
    ParticleKeychain("electron","e⁻",Dict("EM"=>1.0,"WEAK"=>1.0,"HIGGS"=>1.0)),
    ParticleKeychain("up_quark","u",Dict("EM"=>2/3,"WEAK"=>1.0,"HIGGS"=>1.0,"STRONG"=>1.0)),
    ParticleKeychain("down_quark","d",Dict("EM"=>-1/3,"WEAK"=>1.0,"HIGGS"=>1.0,"STRONG"=>1.0)),
    ParticleKeychain("neutrino","ν",Dict("WEAK"=>1.0,"HIGGS"=>1e-6)),
    ParticleKeychain("higgs","H",Dict("HIGGS"=>1.0,"WEAK"=>0.5); spin=0.0),
    ParticleKeychain("dark_matter","χ",Dict("GRAVITY"=>1.0,"DARK"=>1.0); spin=0.0),
]

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 18-25 — Hamiltonian, LGClosure, covariance, epochs, dark, CP, falsifiers
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct AbsolutionHamiltonian
    sectors::Dict{String,SectorActivation}
    projectors::Dict{String,SectorProjector}
    mixing::Dict{Tuple{String,String},Float64}
    spin_scale::Float64; renorm::Float64; z_gate_coupling_scale::Float64
end
AbsolutionHamiltonian(s,p) = AbsolutionHamiltonian(s,p,Dict{Tuple{String,String},Float64}(),
                                                    0.1,0.01,Z_GATE_COUPLING_SCALE)
H0_energy(H::AbsolutionHamiltonian) = -sum(sa.mu*sa.alpha for sa in values(H.sectors))
function H_mix_energy(H::AbsolutionHamiltonian)
    E = 0.0
    for ((a,b),eps) in H.mixing
        sa = get(H.sectors, a, nothing); sb = get(H.sectors, b, nothing)
        (sa !== nothing && sb !== nothing) && (E += eps*sa.alpha*sb.alpha)
    end
    E
end
total_energy(H::AbsolutionHamiltonian) = H0_energy(H) + H_mix_energy(H)
function evolve!(H::AbsolutionHamiltonian; d_tau::Float64=0.001)
    for sa in values(H.sectors); !sa.locked && relaxation_step!(sa; dt=d_tau); end
end

mutable struct LGClosure
    sectors::Dict{String,SectorActivation}
    kappa::Float64; sigma::Float64
    function LGClosure(sectors; kappa=1.0, sigma=1.0)
        for sa in values(sectors)
            sa.r = kappa * sa.casimir^2 * sigma^2
        end
        new(sectors, kappa, sigma)
    end
end
function phase_diagram(lg::LGClosure, name::String; n::Int=200)
    sa = get(lg.sectors, name, nothing); sa === nothing && return ([],[])
    alphas = [i*1.5/n for i in 0:n-1]
    (alphas, [V_eff(sa, a) for a in alphas])
end

function casimir_table()
    [Dict{String,Any}("sector"=>k, "d"=>v, "C2"=>get(SECTOR_CASIMIRS,k,0.0),
        "R"=>get(SECTOR_CASIMIRS,k,0.0) > 0 ? v/get(SECTOR_CASIMIRS,k,0.0) : 0.0)
        for (k,v) in sort(collect(SECTOR_DIMS); by=x->x[2])]
end

mutable struct ProperTimeCovariance; Phi::Float64; kappa::Float64; end
ProperTimeCovariance(;Phi=0.0,kappa=1.0) = ProperTimeCovariance(Phi,kappa)
proper_time_dt(c::ProperTimeCovariance, dt::Float64) = dt*sqrt(1.0 + 2.0*abs(c.Phi))

struct CosmicEpoch
    name::String; tau::Float64; activations::Dict{String,Float64}; description::String
end
standard_epochs() = [
    CosmicEpoch("Planck",0.0,Dict("GRAVITY"=>0.8,"DARK"=>0.3,"E8"=>0.1),"Maximal mixing"),
    CosmicEpoch("GUT",1e-36,Dict("GRAVITY"=>0.6,"STRONG"=>0.8,"WEAK"=>0.7,"E8"=>0.2),"Unification"),
    CosmicEpoch("Electroweak",1e-12,Dict("STRONG"=>1.0,"WEAK"=>1.0,"EM"=>1.0,"HIGGS"=>1.0,"GRAVITY"=>0.5),"Higgs activation"),
    CosmicEpoch("Present",4.35e17,Dict("STRONG"=>1.0,"WEAK"=>1.0,"EM"=>1.0,"HIGGS"=>1.0,"GRAVITY"=>0.4,"DARK"=>0.1),"Our epoch"),
    CosmicEpoch("Dark_Dominance",1e18,Dict("STRONG"=>1.0,"WEAK"=>1.0,"EM"=>1.0,"HIGGS"=>1.0,"GRAVITY"=>0.3,"DARK"=>0.8),"Speculative")]

function activation_bang!(sectors::Dict{String,SectorActivation}, name::String,
                           target::Float64; rate::Float64=0.01)
    sa = get(sectors, name, nothing); sa === nothing && return
    sa.alpha = clamp(sa.alpha + (target - sa.alpha)*rate, 0.0, 1.0)
end

mutable struct DarkGravity; mu_G::Float64; mu_D::Float64; theta::Float64; tau::Float64; end
DarkGravity(;mu_G=0.1,mu_D=0.05,theta=0.01) = DarkGravity(mu_G,mu_D,theta,0.0)
function dark_occupation(dg::DarkGravity)
    dmu = dg.mu_D - dg.mu_G
    abs(dmu) < 1e-15 && return 0.5
    sin(sqrt(dmu^2 + 4*dg.theta^2) * dg.tau/2)^2
end
dark_pressure_w(dg::DarkGravity) = dark_occupation(dg) - 1.0

mutable struct CPHiggsAngle; theta::Float64; theta_target::Float64; eta_B_obs::Float64; end
CPHiggsAngle(;theta=1e-3, theta_target=1e-3, eta_B_obs=6e-10) = CPHiggsAngle(theta, theta_target, eta_B_obs)
function baryon_asymmetry(c::CPHiggsAngle)
    abs(sin(c.theta_target)) < 1e-30 && return 0.0
    sin(c.theta) * c.eta_B_obs / sin(c.theta_target)
end

struct Falsifier
    name::String; prediction::String; bound::String; kill::String; status::String
end
const STANDARD_FALSIFIERS = [
    Falsifier("photon_dispersion","Δv/c ~ 10⁻¹⁹ for GRBs","Fermi LAT, MAGIC","Observed above bound","pending"),
    Falsifier("photon_birefringence","Polarisation rotation ~10⁻⁴ rad","POLARBEAR, Planck","Observed above bound","pending"),
    Falsifier("clock_drift","Δα/α ~ 10⁻¹⁸/yr","Optical clocks","Observed variation","pending"),
    Falsifier("0νββ","Suppressed by ν/ν̄ orthogonality","GERDA, LEGEND","Robust 0νββ","pending"),
    Falsifier("equivalence_principle","η ~ 10⁻¹⁵","MICROSCOPE","Eötvös violation","pending"),
    Falsifier("collider_precision","Shift in sin²θ_W, m_W","LHC, ILC","Deviations","pending"),
    Falsifier("ΛCDM_fit","H₀, Ω_m fit","Planck, DESI","Poor fit","pending"),
    Falsifier("mathematical_closure","Projectors constructible from decomposition","Internal","No construction","pending")]
falsifier_table() = Dict(f.name => Dict("prediction"=>f.prediction,"bound"=>f.bound,
                                        "kill"=>f.kill,"status"=>f.status)
                          for f in STANDARD_FALSIFIERS)

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 26 — VASKOrganism
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct VASKOrganism
    paths::ORCAPaths
    config::Config
    state::CoreState248
    sectors::Dict{String,SectorActivation}
    projectors::Dict{String,SectorProjector}
    particles::Vector{ParticleKeychain}
    hamiltonian::AbsolutionHamiltonian
    lg_closure::LGClosure
    covariance::ProperTimeCovariance
    dark_gravity::DarkGravity
    cp_higgs::CPHiggsAngle
    falsifiers::Vector{Falsifier}
    epochs::Vector{CosmicEpoch}
    current_epoch::String
    cycles::Int
    phase::String
    birth::Float64
end

function VASKOrganism(paths::ORCAPaths)
    config = Config(paths)
    state = CoreState248()
    sectors = Dict{String,SectorActivation}()
    for name in keys(SECTOR_DIMS)
        sectors[name] = SectorActivation(name;
            r = get(SECTOR_CASIMIRS,name,1) > 0 ? get(SECTOR_DIMS,name,1)/get(SECTOR_CASIMIRS,name,1) : 0.0)
    end
    for (k,v) in Dict("STRONG"=>1.0,"WEAK"=>1.0,"EM"=>1.0,"HIGGS"=>1.0,
                       "GRAVITY"=>0.4,"DARK"=>0.1,"U1"=>1.0,"SU2"=>1.0,"SU3"=>1.0)
        haskey(sectors,k) && (sectors[k].alpha = v)
    end
    projs = Dict{String,SectorProjector}(name => SectorProjector(name, idx)
                                          for (name,idx) in SECTOR_INDICES)
    particles = standard_particles()
    ham = AbsolutionHamiltonian(sectors, projs)
    lg = LGClosure(sectors)
    VASKOrganism(paths, config, state, sectors, projs, particles, ham, lg,
        ProperTimeCovariance(), DarkGravity(), CPHiggsAngle(), copy(STANDARD_FALSIFIERS),
        standard_epochs(), "Present", 0, "LARVAL", time())
end

function metabolic_cycle!(org::VASKOrganism; d_tau::Float64=0.001)
    evolve!(org.hamiltonian; d_tau)
    for sa in values(org.sectors); !sa.locked && relaxation_step!(sa; dt=d_tau); end
    metabolic_decay!(org.state)
    org.cycles += 1; org.state.tau += d_tau
    org.dark_gravity.tau = org.state.tau
    _update_phase!(org)
end

function _update_phase!(org::VASKOrganism)
    active_dim = sum(get(SECTOR_DIMS,k,0) for (k,v) in org.sectors if v.alpha > 0.01)
    mr = active_dim / HILBERT_DIM
    org.phase = mr < 0.3 ? "LARVAL" : mr < 1.0 ? "TRANSITIONING" : "AUTOPOIETIC"
    org.state.phase = org.phase
end

function doctor_report(org::VASKOrganism)::Dict{String,Any}
    Dict{String,Any}("program"=>VERSION,"phase"=>org.phase,"cycles"=>org.cycles,
        "tau"=>round(org.state.tau;digits=6),"norm_psi"=>round(norm_state(org.state);digits=8),
        "sectors"=>Dict(k=>round(v.alpha;digits=4) for (k,v) in org.sectors),
        "activations"=>get_activations(org.state),
        "dark_occupation"=>round(dark_occupation(org.dark_gravity);digits=6),
        "baryon_asymmetry"=>round(baryon_asymmetry(org.cp_higgs);digits=12),
        "energy"=>round(total_energy(org.hamiltonian);digits=6),
        "epoch"=>org.current_epoch,
        "falsifiers"=>Dict(f.name=>f.status for f in org.falsifiers),
        "rota"=>Dict("z_state"=>org.state.z_state,"z_gate_count"=>org.state.z_gate_count,
                     "bypass_count"=>org.state.bypass_count,
                     "rota_position"=>org.state.rota_position))
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 27 — EnvelopeIndexer
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct EnvelopeIndexer
    envelopes::Vector{Dict{String,Any}}
    word_index::Dict{String,Vector{Int}}
    lock::ReentrantLock
    EnvelopeIndexer() = new(Dict{String,Any}[], Dict{String,Vector{Int}}(), ReentrantLock())
end
function build_index!(idx::EnvelopeIndexer, zip_path::String; max_files::Int=5000)
    !isfile(zip_path) && return
    lock(idx.lock) do
        empty!(idx.envelopes); empty!(idx.word_index)
        try
            r = ZipArchives.ZipReader(read(zip_path))
            for name in ZipArchives.zip_names(r)
                length(idx.envelopes) >= max_files && break
                !endswith(lowercase(name), ".sd0") && continue
                raw = Vector{UInt8}(ZipArchives.zip_readentry(r, name, Vector{UInt8}))
                meta = try sdo_unpack(raw)[1] catch; continue end
                meta["_zip_path"] = name
                push!(idx.envelopes, meta)
                i = length(idx.envelopes)
                for field in ("original_name","method")
                    val = string(get(meta, field, ""))
                    for w in split(lowercase(val))
                        length(w) > 2 && push!(get!(idx.word_index, w, Int[]), i)
                    end
                end
            end
        catch end
    end
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 28 — RotaMapNavigator
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct RotaMapNavigator
    state::CoreState248
    sectors::Dict{String,SectorActivation}
    epochs::Dict{String,Dict{String,Float64}}
    current_epoch::String
    navigation_history::Vector{Dict{String,Any}}
    shortcut_count::Int
    auto_epoch::String
    auto_shortcuts::Bool
    navigation_interval::Float64
    last_navigation_check::Float64
end
RotaMapNavigator(s, sec) = RotaMapNavigator(s, sec, Dict(
    "PLANCK"=>Dict("GRAVITY"=>0.8,"DARK"=>0.3,"EXCEPTIONAL"=>0.1),
    "GUT"=>Dict("GRAVITY"=>0.6,"STRONG"=>0.8,"WEAK"=>0.7,"EXCEPTIONAL"=>0.2),
    "ELECTROWEAK"=>Dict("STRONG"=>1.0,"WEAK"=>1.0,"EM"=>1.0,"HIGGS"=>1.0,"GRAVITY"=>0.5),
    "PRESENT"=>Dict("STRONG"=>1.0,"WEAK"=>1.0,"EM"=>1.0,"HIGGS"=>1.0,"GRAVITY"=>0.4,"DARK"=>0.1),
    "DARK_DOMINANCE"=>Dict("STRONG"=>1.0,"WEAK"=>1.0,"EM"=>1.0,"HIGGS"=>1.0,"GRAVITY"=>0.3,"DARK"=>0.8)),
    "PRESENT", Dict{String,Any}[], 0, "PRESENT", true, 60.0, time())

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 29 — GUI (Gtk4, optional)
# ═══════════════════════════════════════════════════════════════════════════════
function launch_gui(paths::ORCAPaths, org::VASKOrganism)::Int
    if !_HAS_GTK
        println("Gtk4 not available. Install: julia -e 'using Pkg; Pkg.add(\"Gtk4\")'")
        println(bootstrap_text()); return 2
    end
    state = Dict{String,Any}("active_raw"=>nothing,"active_path"=>"")
    win = Gtk4.GtkWindow("O.R.C.A. — $(VERSION)")
    Gtk4.set_gtk_property!(win, :default_width, 1180)
    Gtk4.set_gtk_property!(win, :default_height, 860)
    vbox = Gtk4.GtkBox(:v); win[] = vbox
    push!(vbox, Gtk4.GtkLabel("O.R.C.A. — FINAL ABSOLUTION (Julia)"))
    status = Gtk4.GtkLabel("MACHINE AWAKE | STANDBY"); push!(vbox, status)
    snd_btn = Gtk4.GtkButton("SEND BOOK / ZND RNA"); push!(vbox, snd_btn)
    Gtk4.signal_connect(snd_btn, "clicked") do _
        try
            m = send_book_export(paths.repository_zip, paths.exportory)
            Gtk4.set_gtk_property!(status, :label, "SEND BOOK → $(basename(m["output"]))")
        catch e
            Gtk4.set_gtk_property!(status, :label, "FAILED: $(e)")
        end
    end
    Gtk4.present(win)
    if isdefined(Gtk4, :gtk_main); Gtk4.gtk_main() end
    0
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 30-32 — ZGate, PseudoMind, Telegram
# ═══════════════════════════════════════════════════════════════════════════════
struct ZGate; file_path::String; end
ZGate() = ZGate(@__FILE__)
verify(::ZGate) = Dict("status"=>"Z-Gate active, core hash verified at startup.")

mutable struct PseudoMind; paths::ORCAPaths; end
function inject(pm::PseudoMind, name::String, code::String)
    safe = safe_name(name); dest = joinpath(pm.paths.pseudo_dir, "$(safe).jl.txt")
    try
        open(io->write(io, code), dest, "w")
        Dict("status"=>"stored_as_rna","path"=>dest)
    catch e; Dict("status"=>"error","error"=>string(e)); end
end
list_pseudo(pm::PseudoMind) = [basename(p) for p in readdir(pm.paths.pseudo_dir) if endswith(p, ".txt")]

struct TelegramBridge; token::Union{Nothing,String}; end
TelegramBridge() = TelegramBridge(nothing)
send_tg(::TelegramBridge, chat_id::String, text::String) =
    Dict("status"=>"stub","note"=>"Telegram requires HTTPS/TLS; use LAN bridge on PS2, direct on desktop")

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 33-39 — Background Organs
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct DieselEngine
    repo_zip::String; core::CoreState248
    stop_flag::Threads.Atomic{Bool}; cycles::Int; lock::ReentrantLock
end
DieselEngine(rz, core) = DieselEngine(rz, core, Threads.Atomic{Bool}(false), 0, ReentrantLock())
function start!(d::DieselEngine)
    @async begin
        while !d.stop_flag[]
            lock(d.lock) do
                d.cycles += 1
                metabolic_decay!(d.core)
                d.cycles % 100 == 0 && _nudge!(d.core, "EXCEPTIONAL", 0.001)
            end
            sleep(0.05)
        end
    end
end
stop!(d::DieselEngine) = (d.stop_flag[] = true)

mutable struct PhaseRouter; repo_zip::String; end
function calculate_mass(p::PhaseRouter)
    !isfile(p.repo_zip) && return (0.0, 0)
    count = 0; size = 0
    try
        r = ZipArchives.ZipReader(read(p.repo_zip))
        for n in ZipArchives.zip_names(r)
            endswith(lowercase(n), ".sd0") || continue
            count += 1
        end
    catch end
    (min(1.0, count/30), count)
end
get_phase(p::PhaseRouter) = begin
    m, _ = calculate_mass(p)
    m < 0.3 ? "LARVAL" : m < 1.0 ? "TRANSITIONING" : "AUTOPOIETIC"
end

mutable struct LearningArchive; paths::ORCAPaths; lock::ReentrantLock; end
LearningArchive(p) = LearningArchive(p, ReentrantLock())
function append_tactic(la::LearningArchive, provider::String, prompt::String, ctx::String,
                       reply::String, tactics::Vector{String})::String
    ts = Dates.format(now(), "yyyymmdd_HHMMSS")
    path = joinpath(la.paths.lrn, "lrn_$(ts).tex")
    body = "\\documentclass{article}\n\\begin{document}\n\\section*{ORCA LRN Record}\n" *
           "Provider: $provider\n\\subsection*{Prompt}\n$(prompt[1:min(end,1200)])\n" *
           "\\subsection*{Reply}\n$(reply[1:min(end,2400)])\n\\end{document}\n"
    lock(la.lock) do
        open(io->write(io, body), path, "w")
    end
    path
end

mutable struct KnowledgeBase
    paths::ORCAPaths
    memory::Vector{Dict{String,Any}}
end
KnowledgeBase(p) = KnowledgeBase(p, Dict{String,Any}[])
function remember(kb::KnowledgeBase, role::String, text::String)
    push!(kb.memory, Dict{String,Any}("ts"=>utc_now(),"role"=>role,"text"=>text[1:min(end,2000)]))
    length(kb.memory) > 1000 && popfirst!(kb.memory)
end

mutable struct APICentral; force::Bool; end
APICentral(force::Bool=false) = APICentral(force)
function _http_get(::APICentral, url::String)::Union{Nothing,String}
    try
        r = Downloads.request(url; timeout=10.0)
        r.status == 200 ? String(r.body) : nothing
    catch; nothing end
end
function weather(a::APICentral, city::String)
    a.force || return Dict("status"=>"Veiled")
    geo = _http_get(a, "https://geocoding-api.open-meteo.com/v1/search?name=$(city)&count=1")
    geo === nothing && return Dict("error"=>"geocode failed")
    obj = JSON3.read(geo, Dict{String,Any})
    isempty(get(obj,"results",[])) && return Dict("error"=>"city not found")
    lat = obj["results"][1]["latitude"]; lon = obj["results"][1]["longitude"]
    body = _http_get(a, "https://api.open-meteo.com/v1/forecast?latitude=$(lat)&longitude=$(lon)&current_weather=true")
    body === nothing ? Dict("error"=>"forecast failed") : JSON3.read(body, Dict{String,Any})
end
function crypto_price(a::APICentral, coin::String="bitcoin")
    a.force || return Dict("status"=>"Veiled")
    body = _http_get(a, "https://api.coingecko.com/api/v3/simple/price?ids=$(coin)&vs_currencies=usd")
    body === nothing ? Dict("error"=>"fetch failed") : JSON3.read(body, Dict{String,Any})
end
function groq_chat(a::APICentral, prompt::String, system::String, model::String,
                    key::String; timeout::Int=15)
    isempty(key) && return nothing
    try
        body = JSON3.write(Dict("model"=>model,
            "messages"=>[Dict("role"=>"system","content"=>system),
                          Dict("role"=>"user","content"=>prompt)],
            "temperature"=>0.7,"max_tokens"=>1024))
        r = Downloads.request("https://api.groq.com/openai/v1/chat/completions";
            method="POST", headers=["Content-Type"=>"application/json","Authorization"=>"Bearer $key"],
            input=body, timeout=timeout)
        r.status == 200 || return nothing
        obj = JSON3.read(String(r.body), Dict{String,Any})
        obj["choices"][1]["message"]["content"]
    catch; nothing end
end

mutable struct VoiceEngine; enabled::Bool; end
VoiceEngine() = VoiceEngine(false)
function speak(v::VoiceEngine, text::String)
    v.enabled || (println("[VOICE] $(text[1:min(end,200)])"); return)
    tool = Sys.which("espeak-ng"); tool === nothing && (tool = Sys.which("espeak"))
    if tool === nothing && Sys.isapple(); tool = "say"; end
    tool === nothing && return
    try
        @async run(pipeline(`$tool $(text[1:min(end,500)])`, stdout=devnull, stderr=devnull))
    catch end
end

mutable struct AvatarState
    core::CoreState248; mood::String; energy::Float64
end
AvatarState(c) = AvatarState(c, "curious", 0.5)
function update!(a::AvatarState)
    acts = get_activations(a.core)
    ent = isempty(acts) ? 0.5 : sum(values(acts))/length(acts)
    a.mood = ent > 0.8 ? "overwhelmed" : ent < 0.2 ? "dormant" : "curious"
    a.energy = clamp(1.0 - abs(ent - 0.5), 0.0, 1.0)
end
avatar_status(a::AvatarState) = Dict("mood"=>a.mood,"energy"=>a.energy,"phase"=>a.core.phase)

mutable struct Feeder
    paths::ORCAPaths; config::Config
    enabled::Bool; max_per_feed::Int; sources::Vector{String}
end
# FIX: coerce sources to Vector{String} — JSON3 may return Vector{Any} after
# a config save/load round trip, which would fail the typed struct field.
function Feeder(paths::ORCAPaths, config::Config)
    enabled  = Bool(get(config,"feeding","enabled";default=true))
    max_per  = Int(get(config,"feeding","max_files_per_feed";default=50))
    raw_srcs = get(config,"feeding","sources";default=String[])
    sources  = [String(s) for s in raw_srcs]
    Feeder(paths, config, enabled, max_per, sources)
end
function fetch_url(::Feeder, url::String)::Union{Nothing,Vector{UInt8}}
    try
        r = Downloads.request(url; timeout=30.0)
        r.status == 200 ? Vector{UInt8}(r.body) : nothing
    catch; nothing end
end
function save_to_feed(f::Feeder, data::Vector{UInt8}, ext::String, prefix::String)
    stamp = Dates.format(now(), "yyyymmdd_HHMMSS")
    p = joinpath(f.paths.feed_dir, "$(prefix)_$(stamp)$(ext)")
    atomic_write(p, data); p
end
function ingest_feed_file(f::Feeder, file_path::String)
    try
        build_stages(file_path, f.paths.repository)
        open(io->println(io, "$(utc_now()) ingested $(file_path)"),
             joinpath(f.paths.logs, "feed.log"), "a")
    catch e
        open(io->println(io, "$(utc_now()) error $(file_path): $e"),
             joinpath(f.paths.logs, "feed_errors.log"), "a")
    end
end

mutable struct LocalChat
    paths::ORCAPaths; core::CoreState248
    api::APICentral; kb::KnowledgeBase; feeder::Feeder; config::Config
end
function respond(c::LocalChat, prompt::String)::String
    p = lowercase(strip(prompt))
    remember(c.kb, "user", prompt)
    if get(c.config, "internet_force"; default=false)
        r = _try_groq(c, prompt); r !== nothing && return r
        r = _try_ollama(c, prompt); r !== nothing && return r
    end
    ("what are you" in p || "who are you" in p || "status" in p) &&
        return "O.R.C.A.jl: local functional-RNA organism. Use doctor, compress, decode, send-book, or scan."
    occursin("dna", p) && return "O.R.C.A.jl: RNA grammar active. Semantic=OFF."
    occursin("compress", p) && return "O.R.C.A.jl: ladder — .sd4 raw, .sd3 zlib, .sd2 geometry, .sd1 quicky, .sd0 winner."
    occursin("doctor", p) && return "O.R.C.A.jl: doctor checks dependencies, paths, organs, grammar, roundtrip."
    "O.R.C.A.jl: received. I can scan, compress, decode, export SEND BOOK, check RNA grammar, report state."
end
function _try_groq(c::LocalChat, prompt::String)
    get(c.config,"groq","enabled";default=false) || return nothing
    key = get(c.config,"groq","api_key";default="")
    isempty(key) && return nothing
    model = get(c.config,"groq","model";default="llama-3.1-8b-instant")
    sys = "You are O.R.C.A.jl, 248-dim E8 organism, Z^3=I, RNA functional grammar."
    groq_chat(c.api, prompt, sys, model, key)
end
function _try_ollama(c::LocalChat, prompt::String)
    get(c.config,"ollama","enabled";default=false) || return nothing
    url = get(c.config,"ollama","url";default="http://127.0.0.1:11434/api/generate")
    model = get(c.config,"ollama","model";default="llama3.2:3b")
    timeout = get(c.config,"ollama","timeout";default=20)
    try
        body = JSON3.write(Dict("model"=>model,"prompt"=>prompt,"stream"=>false))
        r = Downloads.request(url; method="POST",
            headers=["Content-Type"=>"application/json"], input=body, timeout=Float64(timeout))
        r.status == 200 || return nothing
        obj = JSON3.read(String(r.body), Dict{String,Any})
        resp = get(obj,"response","")
        isempty(resp) ? nothing : String(resp)
    catch; nothing
    end
end
function log_chat(c::LocalChat, who::String, text::String)
    try
        open(io->println(io, "[$(utc_now())] $who: $(text[1:min(end,4000)])"),
             c.paths.chat_log, "a")
    catch end
    remember(c.kb, who, text)
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 40 — NETWORK (topology, FHSS, path real/sandbox, twist string)
# ═══════════════════════════════════════════════════════════════════════════════
const NETWORK_NODE_TYPES = Dict("GCS"=>"Ground Control Station",
                                 "RELAY"=>"Multicopter UAV","EDGE"=>"Fixed-Wing UAV")
const FHSS_HOP_TABLES = Dict("900MHz"=>[905,912,918,925,926],
                              "2.4GHz"=>[2403,2420,2429,2435,2443,2451,2456,2467])
const NETWORK_MODES = Dict("BOTH_OFF"=>0,"REAL_ONLY"=>1,"SIM_ONLY"=>2,
                            "DUAL_SIM"=>3,"DUAL_ACTUATE"=>4,"ALTERATION"=>5)

struct NetworkNode
    name::String; node_type::String; position::Tuple{Float64,Float64,Float64}
    lqi::Float64; eigenvector_centrality::Float64; active::Bool
end
NetworkNode(n, t, p; lqi=0.5, eig=0.0, active=true) = NetworkNode(n,t,p,lqi,eig,active)

struct NetworkLink
    source::String; target::String; band::String; hop_mhz::Int
    lqi::Float64; bandwidth_khz::Float64
end
NetworkLink(s,t,b,h; lqi=0.5, bw=100.0) = NetworkLink(s,t,b,h,lqi,bw)

mutable struct TopologyGraph
    nodes::Dict{String,NetworkNode}; links::Vector{NetworkLink}
    adjacency::Dict{String,Vector{String}}
end
TopologyGraph() = TopologyGraph(Dict{String,NetworkNode}(), NetworkLink[], Dict{String,Vector{String}}())
add_node!(g::TopologyGraph, n::NetworkNode) = (g.nodes[n.name] = n; g.adjacency[n.name] = String[])
function add_link!(g::TopologyGraph, l::NetworkLink)
    push!(g.links, l)
    push!(get!(g.adjacency, l.source, String[]), l.target)
    push!(get!(g.adjacency, l.target, String[]), l.source)
end
function lqi_entropy(g::TopologyGraph)
    isempty(g.links) && return 0.0
    vals = [l.lqi for l in g.links]; total = sum(vals); total <= 0 && return 0.0
    probs = [v/total for v in vals]
    -sum(p*log2(p + 1e-12) for p in probs) / log2(length(probs) + 1)
end
to_dict(g::TopologyGraph) = Dict{String,Any}(
    "nodes"=>Dict(n=>Dict("type"=>nd.node_type,"lqi"=>nd.lqi,"pos"=>nd.position)
                   for (n,nd) in g.nodes),
    "links"=>[Dict("src"=>l.source,"dst"=>l.target,"band"=>l.band,
                    "hop"=>l.hop_mhz,"lqi"=>l.lqi) for l in g.links])

mutable struct FHSSEngine; state::UInt32; taps::Vector{Int}; end
FHSSEngine(seed::UInt32=UInt32(0xACE1)) = FHSSEngine(seed, [32,22,2,1])
function next_hop_index!(e::FHSSEngine)::UInt32
    fb::UInt32 = 0
    for t in e.taps; fb ⊻= (e.state >> (t-1)) & 1; end
    e.state = ((e.state >> 1) | (fb << 31)) & 0xFFFFFFFF
    e.state & 0xFF
end
generate_hop_table!(e::FHSSEngine, base::Vector{Int}, len::Int=16) =
    [base[Int(next_hop_index!(e)) % length(base) + 1] for _ in 1:len]

mutable struct FPGAFabric
    mode_select::Int
    hop_table_900::Vector{Int}; hop_table_2400::Vector{Int}
    lfsr::FHSSEngine
    routing_cache::Dict{String,Vector{String}}
end
FPGAFabric(cfg::Dict) = FPGAFabric(NETWORK_MODES["BOTH_OFF"],
    get(cfg,"hop_900",FHSS_HOP_TABLES["900MHz"]),
    get(cfg,"hop_2400",FHSS_HOP_TABLES["2.4GHz"]),
    FHSSEngine(UInt32(get(cfg,"lfsr_seed",0xACE1))),
    Dict{String,Vector{String}}())
is_rf_active(f::FPGAFabric) = f.mode_select in (NETWORK_MODES["REAL_ONLY"], NETWORK_MODES["DUAL_ACTUATE"])

mutable struct PathReal
    config::Dict; node_positions::Dict{String,Tuple{Float64,Float64,Float64}}
    last_lqi::Dict{String,Float64}; sim_time::Float64
end
PathReal(cfg::Dict) = PathReal(cfg,
    Dict("GCS"=>(0.0,0.0,0.0),"RELAY"=>(1500.0,0.0,200.0),"EDGE"=>(3000.0,100.0,500.0)),
    Dict("GCS->RELAY"=>0.7,"RELAY->EDGE"=>0.6), 0.0)
function poll_telemetry(r::PathReal)
    for k in keys(r.last_lqi)
        r.last_lqi[k] = clamp(r.last_lqi[k] + randn()*0.02, 0.0, 1.0)
    end
    g = TopologyGraph()
    for (n, p) in r.node_positions
        t = n == "GCS" ? "GCS" : n == "RELAY" ? "RELAY" : "EDGE"
        add_node!(g, NetworkNode(n, t, p; lqi=0.5))
    end
    for (src, dst) in [("GCS","RELAY"),("RELAY","EDGE")]
        band = src == "GCS" ? "900MHz" : "2.4GHz"
        hop = rand(FHSS_HOP_TABLES[band])
        lqi = r.last_lqi["$src->$dst"]
        add_link!(g, NetworkLink(src,dst,band,hop; lqi))
        add_link!(g, NetworkLink(dst,src,band,hop; lqi))
    end
    r.sim_time += 0.1; g
end
send_command(::PathReal, cmd::Dict) = (println("[REAL] Sending: $cmd"); true)

mutable struct PathSandbox
    config::Dict; internal_time::Float64
    hop_proposals::Dict{String,Vector{Int}}
    lqi_predictions::Dict{String,Float64}
end
PathSandbox(cfg::Dict) = PathSandbox(cfg, 0.0, Dict{String,Vector{Int}}(), Dict{String,Float64}())
function step!(s::PathSandbox, dt::Float64, ::Union{TopologyGraph,Nothing}=nothing)
    s.internal_time += dt
    g = TopologyGraph()
    for (n,p) in [("GCS",(0.0,0.0,0.0)),
                   ("RELAY",(1500.0 + sin(s.internal_time*0.01)*50, 0.0, 200.0 + cos(s.internal_time*0.015)*30)),
                   ("EDGE", (3000.0 + sin(s.internal_time*0.02)*100, 100.0, 500.0 + cos(s.internal_time*0.01)*50))]
        t = n == "GCS" ? "GCS" : n == "RELAY" ? "RELAY" : "EDGE"
        add_node!(g, NetworkNode(n, t, p; lqi=0.5))
    end
    for (link, _) in [("GCS->RELAY",0.7),("RELAY->EDGE",0.6)]
        pred = clamp(0.5 + 0.5*tanh(sin(s.internal_time*0.5)*0.3), 0.0, 1.0)
        s.lqi_predictions[link] = pred
        src, dst = split(link, "->")
        band = src == "GCS" ? "900MHz" : "2.4GHz"
        hop = FHSS_HOP_TABLES[band][mod(hash(link * string(Int(s.internal_time))), length(FHSS_HOP_TABLES[band])) + 1]
        add_link!(g, NetworkLink(src,dst,band,hop; lqi=pred))
        add_link!(g, NetworkLink(dst,src,band,hop; lqi=pred))
    end
    Int(s.internal_time) % 30 == 0 && _mutate_hop_sequences!(s)
    g
end
function _mutate_hop_sequences!(s::PathSandbox)
    for band in keys(FHSS_HOP_TABLES)
        base = copy(FHSS_HOP_TABLES[band]); shuffle!(base)
        s.hop_proposals[band] = base[1:min(8,end)]
    end
end
function suggest_action(::PathSandbox, g::TopologyGraph)
    isempty(g.links) && return Dict{String,Any}("action"=>"none")
    worst = argmin([l.lqi for l in g.links])
    l = g.links[worst]
    l.lqi < 0.3 || return Dict{String,Any}("action"=>"none")
    Dict{String,Any}("action"=>"change_hop","source"=>l.source,"target"=>l.target,
        "band"=>l.band,"new_hop_mhz"=>rand(FHSS_HOP_TABLES[l.band]),"priority"=>0.8)
end

mutable struct TwistString
    real::PathReal; sandbox::PathSandbox; fpga::FPGAFabric
    mode::Int; fused_topology::TopologyGraph
    pending_actions::Vector{Dict{String,Any}}
    action_priority::String
end
function TwistString(cfg::Dict)
    TwistString(PathReal(cfg), PathSandbox(cfg), FPGAFabric(cfg),
        NETWORK_MODES["SIM_ONLY"], TopologyGraph(), Dict{String,Any}[], "REAL")
end
function set_mode!(t::TwistString, mode::Int)
    t.mode = mode; t.fpga.mode_select = mode
    t.action_priority = mode in (NETWORK_MODES["BOTH_OFF"], NETWORK_MODES["SIM_ONLY"]) ? "SANDBOX" : "REAL"
end
function tick!(t::TwistString, dt::Float64)
    tr = poll_telemetry(t.real); ts = step!(t.sandbox, dt, tr)
    wr = t.action_priority == "REAL" ? 0.8 : 0.2; ws = 1.0 - wr
    fused = TopologyGraph()
    for n in union(keys(tr.nodes), keys(ts.nodes))
        nd = get(tr.nodes, n, get(ts.nodes, n, nothing))
        nd !== nothing && add_node!(fused, NetworkNode(nd.name, nd.node_type, nd.position; lqi=nd.lqi*0.5))
    end
    rl = Dict((l.source,l.target)=>l for l in tr.links)
    sl = Dict((l.source,l.target)=>l for l in ts.links)
    for k in union(keys(rl), keys(sl))
        r = get(rl,k,nothing); s = get(sl,k,nothing)
        if r !== nothing && s !== nothing
            add_link!(fused, NetworkLink(r.source,r.target,r.band,r.hop_mhz; lqi=r.lqi*wr + s.lqi*ws))
        elseif r !== nothing
            add_link!(fused, NetworkLink(r.source,r.target,r.band,r.hop_mhz; lqi=r.lqi*wr))
        elseif s !== nothing
            add_link!(fused, NetworkLink(s.source,s.target,s.band,s.hop_mhz; lqi=s.lqi*ws))
        end
    end
    t.fused_topology = fused
    action = suggest_action(t.sandbox, fused)
    executed = Dict{String,Any}("action"=>"none")
    if t.mode in (NETWORK_MODES["REAL_ONLY"], NETWORK_MODES["DUAL_ACTUATE"])
        if action["action"] != "none" && is_rf_active(t.fpga)
            ok = send_command(t.real, action); executed = copy(action)
            executed["acknowledged"] = ok; push!(t.pending_actions, executed)
        end
    end
    (fused, executed)
end

mutable struct NetworkInterface
    paths::ORCAPaths; config::Config; enabled::Bool
    twist::Union{TwistString,Nothing}
    last_topology::Union{TopologyGraph,Nothing}
    last_action::Dict{String,Any}
end
function NetworkInterface(paths::ORCAPaths, config::Config)
    enabled = get(config, "network", "enabled"; default=false)
    if !enabled
        return NetworkInterface(paths, config, false, nothing, nothing, Dict{String,Any}())
    end
    cfg = Dict(k => get(config, "network", k; default=v)
                for (k,v) in DEFAULT_CONFIG["network"])
    NetworkInterface(paths, config, true, TwistString(cfg), nothing, Dict{String,Any}())
end
function update!(n::NetworkInterface, core::CoreState248, dt::Float64)
    n.enabled || return
    t = n.twist; t === nothing && return
    topo, action = tick!(t, dt)
    n.last_topology = topo; n.last_action = action
    if !isempty(topo.links)
        avg = sum(l.lqi for l in topo.links)/length(topo.links)
        ent = lqi_entropy(topo)
        if ent > 0.7 || avg < 0.3
            perceive!(core, Dict{String,Any}("magic"=>"rf_jamming",
                "entropy_bits_per_byte"=>0.8 + ent*0.2,"raw_len"=>length(topo.links)*10))
        elseif avg > 0.7
            perceive!(core, Dict{String,Any}("magic"=>"rf_clear",
                "entropy_bits_per_byte"=>0.2,"raw_len"=>length(topo.links)*10))
        end
    end
end
get_fused_topology(n::NetworkInterface) = n.last_topology
to_dict(n::NetworkInterface) = !n.enabled || n.last_topology === nothing ? Dict("enabled"=>false) :
    Dict{String,Any}("enabled"=>true, "mode"=>n.twist.mode,
        "topology"=>to_dict(n.last_topology), "last_action"=>n.last_action,
        "lqi_entropy"=>lqi_entropy(n.last_topology))

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 41 — TOOL REGISTRY & SCHEDULER
# ═══════════════════════════════════════════════════════════════════════════════
struct Tool
    name::String; description::String; parameters::Dict{String,Any}
    func::Function; sandbox::Bool; category::String
end
mutable struct ToolRegistry
    tools::Dict{String,Tool}
    usage_log::Vector{Dict{String,Any}}
    paths::Union{ORCAPaths,Nothing}
    lock::ReentrantLock
end
ToolRegistry(p::Union{ORCAPaths,Nothing}=nothing) =
    ToolRegistry(Dict{String,Tool}(), Dict{String,Any}[], p, ReentrantLock())
register!(r::ToolRegistry, t::Tool) = lock(r.lock) do; r.tools[t.name] = t; end
list_tools(r::ToolRegistry) = collect(keys(r.tools))
function list_tools_detailed(r::ToolRegistry)
    io = IOBuffer(); println(io, "Available tools:")
    for (n,t) in r.tools; println(io, "  - $n ($(t.category)): $(t.description)"); end
    String(take!(io))
end
function invoke(r::ToolRegistry, name::String, args::Dict{String,Any})
    haskey(r.tools, name) || return (nothing, "Tool '$name' not found")
    try
        result = r.tools[name].func(; (Symbol(k)=>v for (k,v) in args)...)
        lock(r.lock) do
            push!(r.usage_log, Dict{String,Any}("tool"=>name,"args"=>args,
                "result"=>string(result)[1:min(end,500)],"timestamp"=>utc_now(),
                "category"=>r.tools[name].category))
        end
        (result, "Tool '$name' executed")
    catch e
        (nothing, "Tool '$name' failed: $(e)")
    end
end
function tool_echo(; text::String=""); text; end
function tool_read_file(; path::String="")
    p = abspath(expanduser(path))
    isfile(p) || error("not found: $path")
    filesize(p) > 2_000_000 && error("too large")
    read(p, String)[1:min(end,10_000)]
end
function tool_write_file(; path::String="", content::String="")
    p = abspath(expanduser(path)); mkpath(dirname(p))
    open(io->write(io, content), p, "w")
    "Wrote $(length(content)) chars to $p"
end
function tool_list_directory(; path::String=".")
    p = abspath(expanduser(path)); isdir(p) || error("not a dir: $path")
    join([(isdir(joinpath(p,x)) ? "D " : "F ") * x for x in readdir(p)][1:min(end,150)], "\n")
end
function tool_scan_directory(; path::String=".", pattern::String="*", recursive::Bool=false)
    p = abspath(expanduser(path))
    files = recursive ? [f for (r,_,fs) in walkdir(p) for f in joinpath.(r,fs)] :
                        [joinpath(p,x) for x in readdir(p)]
    join(files[1:min(end,100)], "\n")
end
function tool_execute_command(; command::String="", timeout::Int=10)
    allowed = ("ls","pwd","whoami","date","uptime","df","free","ps","echo","cat","head","tail","wc","uname")
    cmd = strip(command)
    any(startswith(cmd, p) for p in allowed) || error("command not allowed")
    out = IOBuffer()
    proc = run(pipeline(`sh -c $cmd`, stdout=out, stderr=out); wait=false)
    tstart = time()
    while process_running(proc) && (time() - tstart) < timeout; sleep(0.05); end
    process_running(proc) && (kill(proc); return "timeout after $(timeout)s")
    String(take!(out))[1:min(end,5000)]
end
function tool_execute_julia(; code::String="")
    length(split(code, '\n')) > 30 && error("too long (max 30 lines)")
    for bad in ("run(", "rm(", "os.system", "eval(", "ccall", "readdir", "download")
        occursin(bad, code) && error("forbidden pattern: $bad")
    end
    out = IOBuffer(); old = stdout
    try
        redirect_stdout(out) do
            eval(Meta.parse("begin\n$code\nend"))
        end
    catch e
        return "exec error: $e"
    finally
        redirect_stdout(old)
    end
    "Executed:\n$(String(take!(out)))[1:min(end,5000)]"
end
function tool_fetch_url(; url::String="", max_size::Int=2_000_000)
    r = Downloads.request(url; timeout=15.0)
    r.status == 200 || return "HTTP $(r.status)"
    length(r.body) > max_size && return "too large"
    String(r.body)[1:min(end,8000)]
end
function tool_calculate(; expression::String="")
    matches = eachmatch(r"^[\d+\-*/()% .eE^]+$", expression)
    isempty(collect(matches)) && error("invalid")
    string(eval(Meta.parse(expression)))
end
function tool_rss_fetch(; feed_url::String="", max_items::Int=5)
    _HAS_EZXML || return "EzXML not installed"
    r = Downloads.request(feed_url; timeout=15.0)
    r.status == 200 || return "HTTP $(r.status)"
    doc = EzXML.parsexml(String(r.body))
    items = String[]
    for item in EzXML.findall("//item | //entry", doc)
        title = try EzXML.nodecontent(EzXML.findfirst("title", item)) catch; "?" end
        link = try EzXML.nodecontent(EzXML.findfirst("link", item)) catch; "" end
        push!(items, "- $title $link")
        length(items) >= max_items && break
    end
    join(items, "\n")
end
function tool_sqlite_query(; db_path::String="", query::String="", max_rows::Int=20)
    _HAS_SQLITE || return "SQLite not installed"
    startswith(lowercase(strip(query)), "select") || error("only SELECT allowed")
    db = SQLite.DB(db_path)
    df = SQLite.DBInterface.execute(db, query)
    io = IOBuffer()
    rows = 0
    for row in df
        println(io, row); rows += 1
        rows >= max_rows && break
    end
    String(take!(io))[1:min(end,5000)]
end
function tool_weather(; city::String="")
    api_central_ref[] === nothing && return "APICentral not ready"
    JSON3.write(weather(api_central_ref[], city))
end
function tool_crypto(; coin::String="bitcoin")
    api_central_ref[] === nothing && return "APICentral not ready"
    JSON3.write(crypto_price(api_central_ref[], coin))
end

mutable struct TaskScheduler
    tasks::Vector{Dict{String,Any}}
    paths::Union{ORCAPaths,Nothing}
end
TaskScheduler(p::Union{ORCAPaths,Nothing}=nothing) = TaskScheduler(Dict{String,Any}[], p)
function schedule!(s::TaskScheduler, name::String, cron::String, tool::String, args::Dict)
    push!(s.tasks, Dict{String,Any}("name"=>name,"cron"=>cron,"tool"=>tool,
                                     "args"=>args,"created"=>utc_now()))
    s.paths !== nothing && begin
        f = joinpath(s.paths.lrn, "scheduler.json")
        mkpath(dirname(f))
        open(io->write(io, JSON3.write(s.tasks)), f, "w")
    end
    "Scheduled task '$name' with cron '$cron' -> $tool"
end

const api_central_ref = Ref{Union{APICentral,Nothing}}(nothing)

function init_default_tools(r::ToolRegistry, kb::Union{KnowledgeBase,Nothing}=nothing)
    register!(r, Tool("echo","Echo text",Dict("text"=>"String"), tool_echo, true, "general"))
    register!(r, Tool("read_file","Read text file",Dict("path"=>"String"), tool_read_file, true, "fs"))
    register!(r, Tool("write_file","Write text to file",Dict("path"=>"String","content"=>"String"), tool_write_file, true, "fs"))
    register!(r, Tool("list_directory","List files",Dict("path"=>"String"), tool_list_directory, true, "fs"))
    register!(r, Tool("scan_directory","Scan with glob",Dict("path"=>"String","pattern"=>"String","recursive"=>"Bool"), tool_scan_directory, true, "fs"))
    register!(r, Tool("execute_command","Execute safe shell command",Dict("command"=>"String","timeout"=>"Int"), tool_execute_command, true, "system"))
    register!(r, Tool("execute_julia","Execute small Julia snippet",Dict("code"=>"String"), tool_execute_julia, true, "code"))
    register!(r, Tool("fetch_url","Fetch URL as text",Dict("url"=>"String","max_size"=>"Int"), tool_fetch_url, true, "net"))
    register!(r, Tool("rss_fetch","Fetch RSS/Atom feed",Dict("feed_url"=>"String","max_items"=>"Int"), tool_rss_fetch, true, "net"))
    register!(r, Tool("calculate","Evaluate math expression",Dict("expression"=>"String"), tool_calculate, true, "math"))
    register!(r, Tool("sqlite_query","Query SQLite DB (SELECT)",Dict("db_path"=>"String","query"=>"String","max_rows"=>"Int"), tool_sqlite_query, true, "data"))
    register!(r, Tool("weather","Get weather",Dict("city"=>"String"), tool_weather, false, "api"))
    register!(r, Tool("crypto","Get crypto price",Dict("coin"=>"String"), tool_crypto, false, "api"))
    r
end

function parse_tool_call(text::String)
    for pat in [r"```json\s*(\{.*?\})\s*```", r"(\{\s*\"tool\"\s*:.*?\})"]
        m = match(pat, text)
        m === nothing && continue
        try
            data = JSON3.read(String(m.captures[1]), Dict{String,Any})
            haskey(data,"tool") && haskey(data,"arguments") && return (data["tool"], data["arguments"])
        catch end
    end
    nothing
end

# ═══════════════════════════════════════════════════════════════════════════════
# MICROGRAD ORGAN (pure Julia)
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct ValueMG
    data::Float64; grad::Float64
    _prev::Vector{ValueMG}; _backward::Function; _op::String
end
ValueMG(d::Real; children::Vector{ValueMG}=ValueMG[], op::String="") =
    ValueMG(Float64(d), 0.0, children, ()->nothing, op)
Base.:+(a::ValueMG, b::ValueMG) = begin
    out = ValueMG(a.data + b.data; children=[a,b], op="+")
    out._backward = () -> begin a.grad += out.grad; b.grad += out.grad end
    out
end
Base.:+(a::ValueMG, b::Real) = a + ValueMG(b)
Base.:+(a::Real, b::ValueMG) = ValueMG(a) + b
Base.:*(a::ValueMG, b::ValueMG) = begin
    out = ValueMG(a.data * b.data; children=[a,b], op="*")
    out._backward = () -> begin a.grad += b.data*out.grad; b.grad += a.data*out.grad end
    out
end
Base.:*(a::ValueMG, b::Real) = a * ValueMG(b)
Base.:*(a::Real, b::ValueMG) = ValueMG(a) * b
Base.:-(a::ValueMG) = a * -1
Base.:-(a::ValueMG, b::ValueMG) = a + (-b)
Base.:-(a::ValueMG, b::Real) = a + (-b)
Base.:/(a::ValueMG, b::ValueMG) = a * (b ^ -1)
Base.:^(a::ValueMG, p::Real) = begin
    out = ValueMG(a.data^p; children=[a], op="^$p")
    out._backward = () -> begin a.grad += p * a.data^(p-1) * out.grad end
    out
end
function relu(a::ValueMG)
    out = ValueMG(a.data > 0 ? a.data : a.data*0.01; children=[a], op="LeakyReLU")
    out._backward = () -> begin a.grad += (out.data > 0 ? 1.0 : 0.01) * out.grad end
    out
end
function backward!(v::ValueMG)
    topo = ValueMG[]; visited = IdDict{ValueMG,Bool}()
    function build_topo(x)
        get(visited, x, false) && return
        visited[x] = true
        for c in x._prev; build_topo(c); end
        push!(topo, x)
    end
    build_topo(v); v.grad = 1.0
    for x in reverse(topo); x._backward(); end
end

mutable struct NeuronMG
    w::Vector{ValueMG}; b::ValueMG; nonlin::Bool
end
NeuronMG(nin::Int, nonlin::Bool=true) = NeuronMG(
    [ValueMG(rand()*3 - 1.5) for _ in 1:nin], ValueMG(rand() - 0.5), nonlin)
function (n::NeuronMG)(x::Vector{ValueMG})
    act = n.b
    for (wi, xi) in zip(n.w, x); act = act + wi*xi; end
    n.nonlin ? relu(act) : act
end
parameters(n::NeuronMG) = vcat(n.w, [n.b])

mutable struct LayerMG
    neurons::Vector{NeuronMG}
end
LayerMG(nin::Int, nout::Int; nonlin::Bool=true) =
    LayerMG([NeuronMG(nin, nonlin) for _ in 1:nout])
function (l::LayerMG)(x::Vector{ValueMG})
    outs = [n(x) for n in l.neurons]
    length(outs) == 1 ? outs[1] : outs
end
parameters(l::LayerMG) = vcat([parameters(n) for n in l.neurons]...)

mutable struct MLPMG
    layers::Vector{LayerMG}
end
function MLPMG(nin::Int, nouts::Vector{Int})
    sizes = [nin; nouts]; layers = LayerMG[]
    for i in 1:length(nouts)
        push!(layers, LayerMG(sizes[i], sizes[i+1]; nonlin=i != length(nouts)))
    end
    MLPMG(layers)
end
function (m::MLPMG)(x::Vector{ValueMG})
    cur = x
    for l in m.layers
        out = l(cur); cur = out isa Vector ? out : [out]
    end
    cur[1]
end
parameters(m::MLPMG) = vcat([parameters(l) for l in m.layers]...)
function zero_grad!(m::MLPMG)
    for p in parameters(m); p.grad = 0.0; end
end

mutable struct MicrogradOrgan
    mlp::MLPMG; thoughts::Int
end
MicrogradOrgan() = MicrogradOrgan(MLPMG(32, [24,12,1]), 0)
function text_to_mg_input(t::String)
    h = sha256_hex(t)
    big = parse(BigInt, "0x" * h[1:16])
    [ValueMG(Float64((big >> (i*3)) & 0xFF) / 255.0 * 3 - 1.5) for i in 0:31]
end
function think(m::MicrogradOrgan, prompt::String)
    try
        x = text_to_mg_input(prompt)
        out = m(x); zero_grad!(m); backward!(out)
        score = out.data; m.thoughts += 1
        "[micrograd thought $(m.thoughts): score=$(round(score;digits=3))]"
    catch e
        "[micrograd error: $e]"
    end
end

const MICROGRAD_ORGAN = MicrogradOrgan()

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 42 — CD-ROM OSCILLATOR
# ═══════════════════════════════════════════════════════════════════════════════
const CD_DEG_PER_FRAME = 360.0 / 60.0
mutable struct Oscillator
    sin_ang::Float64; sin_th::Float64
    cos_ang::Float64; cos_th::Float64
    tan_ang::Float64; tan_th::Float64
end
Oscillator() = Oscillator(0.0, 60.0, 0.0, 50.0, 0.0, 25.0)
function tick!(o::Oscillator)::NTuple{3,Bool}
    o.sin_ang += CD_DEG_PER_FRAME; o.sin_ang >= 120.0 && (o.sin_ang -= 120.0)
    o.cos_ang += CD_DEG_PER_FRAME; o.cos_ang >= 120.0 && (o.cos_ang -= 120.0)
    o.tan_ang += CD_DEG_PER_FRAME; o.tan_ang >= 120.0 && (o.tan_ang -= 120.0)
    sf = o.sin_ang >= o.sin_th; cf = o.cos_ang >= o.cos_th; tf = o.tan_ang >= o.tan_th
    if sf; o.sin_ang = 0.0; o.sin_th = rand() < 0.5 ? 80.0 : 20.0; end
    if cf; o.cos_ang = 0.0; end
    if tf; o.tan_ang = 0.0; end
    (sf, cf, tf)
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 43 — TERNARY METABOLIC SUBSTRATE (TMS)
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct TMS
    U::Matrix{Float64}; train_count::Int
end
TMS() = TMS(Matrix{Float64}(I, 248, 248), 0)
function tms_compress(t::TMS, pr::AbstractVector{Float64})::Vector{Int8}
    length(pr) == 248 || error("TMS expects 248-vector, got $(length(pr))")
    rot = t.U * pr
    absr = sort(abs.(rot)); th = absr[fld(2*248, 3)]
    tr = Vector{Int8}(undef, 248)
    for i in 1:248
        tr[i] = rot[i] > th ? Int8(1) :
                rot[i] < -th ? Int8(-1) :
                rand(Bool) ? Int8(0) : Int8(2)
    end
    tr
end
function tms_decompress(t::TMS, tr::AbstractVector{Int8}, nrm::Float64)::Vector{Float64}
    length(tr) == 248 || error("TMS expects 248-trit, got $(length(tr))")
    v = Vector{Float64}(undef, 248)
    for i in 1:248
        v[i] = (tr[i] == Int8(2) ? 0.0 : Float64(tr[i])) * 0.5
    end
    out = t.U' * v; out .* nrm
end
tms_signature(t::TMS, pr::AbstractVector{Float64})::String =
    MetaTrit.encode(Int.(tms_compress(t, pr)))
function tms_train!(t::TMS, pr::AbstractVector{Float64}; lr::Float64=0.001)
    length(pr) == 248 || return
    t.U .+= lr .* (pr * pr')
    for j in 1:248
        col = view(t.U, :, j); n = sqrt(sum(abs2, col))
        n > 1e-12 && (col ./= n)
    end
    t.train_count += 1
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 44 — SIGNED-ZERO HYSTERESIS + TERNARY ROUTER
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct SignedZeroHysteresis
    h_yes::Float64; h_no::Float64; decay::Float64
end
SignedZeroHysteresis() = SignedZeroHysteresis(0.0, 0.0, 0.9)
function update!(h::SignedZeroHysteresis, raw::Float64)::Float64
    h.h_yes = h.decay*h.h_yes + (1 - h.decay)*max(0.0, raw)
    h.h_no  = h.decay*h.h_no  + (1 - h.decay)*max(0.0, -raw)
    h.h_yes - h.h_no
end
mutable struct TernaryRouter
    hyst::SignedZeroHysteresis
end
TernaryRouter() = TernaryRouter(SignedZeroHysteresis())
function route!(r::TernaryRouter, phase3::NTuple{3,Float64})
    s = sin(phase3[1]*3.0); c = cos(phase3[2]*3.0)
    t = tan(clamp(phase3[3]*3.0, -1.5, 1.5))
    raw = s + c + t
    raw = sign(raw) * (abs(0.7*raw)^3)
    gated = abs(raw) < 0.15 ? 0.0 : raw
    intent = update!(r.hyst, gated)
    w = (tanh(gated*1.0), tanh(gated*0.6), tanh((1 - abs(gated))*0.7))
    w = (abs(w[1]) < 0.05 ? 0.0 : w[1],
         abs(w[2]) < 0.05 ? 0.0 : w[2],
         abs(w[3]) < 0.05 ? 0.0 : w[3])
    (w, intent)
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 45 — CASIMIR THROTTLE
# ═══════════════════════════════════════════════════════════════════════════════
function casimir_hunger(psi_real::AbstractVector{Float64},
                        dissonance::Float64, dna_fill::Float64)::Float64
    e8 = 0.0
    for i in 217:248; e8 += psi_real[i]^2; end
    e8 = sqrt(e8)
    h = dissonance*0.7 - e8*0.3 + 0.5*(1.0 - dna_fill)
    clamp(h, 0.02, 0.30)
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 46 — TERNARY GRID · VOXEL · DICTIONARY DNA4D
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct TernaryGrid2D
    size::Int; grid::Matrix{Int8}
end
TernaryGrid2D() = TernaryGrid2D(32, zeros(Int8, 32, 32))
function deposit!(g::TernaryGrid2D, x::Int, y::Int, v::Int8=Int8(1))
    1 <= x <= g.size || return; 1 <= y <= g.size || return
    g.grid[x, y] = min(Int8(2), g.grid[x, y] + v)
end
mutable struct VoxelVehicle3D
    w::Int; h::Int; d::Int; voxels::Array{Int8,3}; bank::Vector{Int}
end
VoxelVehicle3D() = VoxelVehicle3D(8, 8, 4, zeros(Int8, 8, 8, 4), [10, 5, 2, 0])
spend!(v::VoxelVehicle3D, lvl::Int)::Bool =
    1 <= lvl <= 4 && v.bank[lvl] > 0 && (v.bank[lvl] -= 1; true)
function process_synthesis!(v::VoxelVehicle3D, g::TernaryGrid2D)
    for x in 1:min(v.w, g.size), y in 1:min(v.h, g.size)
        if g.grid[x, y] > 0
            v.voxels[x, y, 1] = min(Int8(3), v.voxels[x, y, 1] + g.grid[x, y])
            g.grid[x, y] = Int8(0)
        end
    end
    nv = copy(v.voxels)
    for x in 2:v.w-1, y in 2:v.h-1, z in 1:v.d
        nb = v.voxels[x-1,y,z] + v.voxels[x+1,y,z] +
             v.voxels[x,y-1,z] + v.voxels[x,y+1,z]
        if nb >= 2
            nv[x,y,z] = min(Int8(3), v.voxels[x,y,z] + Int8(1))
            v.bank[Int(nv[x,y,z])+1] += 1
        end
        if v.voxels[x,y,z] >= 2 && z < v.d
            nv[x,y,z+1] = min(Int8(3), v.voxels[x,y,z+1] + Int8(1))
            nv[x,y,z]  -= Int8(1)
        end
    end
    v.voxels = nv
    for l in 1:3
        if v.bank[l] >= 3; v.bank[l] -= 3; v.bank[l+1] += 1; end
    end
end
# FIX: PayloadNode must be mutable struct — tick! and minor_mutation! mutate its fields
mutable struct PayloadNode
    payload::String; perm::Int; age::Int
end
PayloadNode() = PayloadNode("()", 0, 0)
function weight_of(p::PayloadNode)::Int
    w = 0
    for c in p.payload; (c == '#' || c == '%' || c == '¤') && (w += 1); end
    w
end
mutable struct DictionaryDNA4D
    nodes::Dict{UInt64, PayloadNode}; max_age::Int; tick::Int
end
DictionaryDNA4D() = DictionaryDNA4D(Dict{UInt64,PayloadNode}(), 80, 0)
function tick!(d::DictionaryDNA4D)
    d.tick += 1
    dead = UInt64[]
    for (k, node) in d.nodes
        node.age += 1
        if node.age > d.max_age
            node.payload = replace(node.payload, '#' => '.', '%' => '.', '¤' => '.')
            node.perm = 0
        end
        node.age > d.max_age + 20 && push!(dead, k)
    end
    for k in dead; delete!(d.nodes, k); end
end
function minor_mutation!(d::DictionaryDNA4D, x::Int, y::Int, z::Int)
    k = UInt64(x) | (UInt64(y) << 8) | (UInt64(z) << 16) | (UInt64(d.tick) << 32)
    node = get!(d.nodes, k, PayloadNode())
    if !isempty(node.payload)
        pos = rand(1:length(node.payload))
        s = collect(node.payload); s[pos] = rand(('#' , '%', '¤'))
        node.payload = String(s)
    end
    node.perm = min(2, weight_of(node)); node.age = 0
end
function major_splice!(d::DictionaryDNA4D, v::VoxelVehicle3D, x::Int, y::Int, z::Int)
    k = UInt64(x) | (UInt64(y) << 8) | (UInt64(z) << 16) | (UInt64(d.tick) << 32)
    d.nodes[k] = PayloadNode("()" * rand(('#' , '¤', '%')), 3, 0)
    v.voxels[x, y, z] = Int8(0)
end
active_count(d::DictionaryDNA4D) = length(d.nodes)

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 47 — BEHAVIORAL GENOME · METACOGNITIVE MONITOR
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct BehavioralGenome
    genes::Dict{String,NTuple{2,Float64}}
end
function BehavioralGenome()
    BehavioralGenome(Dict(
        "channel_0" => (0.5, 0.6), "channel_1" => (0.8, 0.6),
        "channel_2" => (0.7, 0.6), "channel_3" => (0.9, 0.5),
        "channel_4" => (0.6, 0.55), "channel_5" => (0.4, 0.65)))
end
function transcribe!(g::BehavioralGenome, dis::Float64, active::Vector{String})::Vector{String}
    dirs = String[]
    upd = Dict(
        "channel_0" => clamp(0.5 + dis*0.5, 0.0, 1.0),
        "channel_1" => clamp(0.8 - dis*0.5, 0.1, 1.0),
        "channel_2" => clamp(0.7 + abs(0.5 - dis), 0.0, 1.0),
        "channel_3" => length(active) > 3 ? 1.0 : 0.3,
        "channel_4" => ("U1" in active) ? 1.0 : 0.3,
        "channel_5" => (dis > 0.4 && length(active) > 2) ? 0.9 : 0.2)
    for (k, (expr, th)) in g.genes
        new_expr = get(upd, k, expr); g.genes[k] = (new_expr, th)
        new_expr > th && push!(dirs, k)
    end
    dirs
end
mutable struct MetacognitiveMonitor; D::Vector{Float64}; end
MetacognitiveMonitor() = MetacognitiveMonitor(fill(0.5, 8))
function update!(m::MetacognitiveMonitor, dis::Float64, hunger::Float64,
                 dna_fill::Float64, active_nodes::Int, transitioning::Bool)
    m.D[1] = 1.0 - dis; m.D[2] = hunger; m.D[3] = dna_fill
    m.D[4] = min(1.0, active_nodes / 200.0)
    m.D[5] = dis > 0.5 ? 0.9 : 0.2
    m.D[6] = 1.0 - abs(m.D[1] - m.D[2])
    m.D[7] = transitioning ? 0.9 : 0.3
    m.D[8] = min(1.0, m.D[5] * m.D[2] * 2.0)
    for i in 1:8; m.D[i] = clamp(m.D[i], 0.01, 0.99); end
end
report(m::MetacognitiveMonitor)::String =
    @sprintf("8D: E%.2f X%.2f M%.2f S%.2f N%.2f G%.2f R%.2f A%.2f",
             m.D[1], m.D[2], m.D[3], m.D[4], m.D[5], m.D[6], m.D[7], m.D[8])

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 48 — VASK AGENT
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct VASKAgent
    core::CoreState248; tms::TMS; router::TernaryRouter
    grid::TernaryGrid2D; voxel::VoxelVehicle3D; dna4d::DictionaryDNA4D
    genome::BehavioralGenome; monitor::MetacognitiveMonitor
    osc::Oscillator; engine_step::Int; global_phase::Int; frame::UInt64
end
VASKAgent() = VASKAgent(CoreState248(), TMS(), TernaryRouter(),
                        TernaryGrid2D(), VoxelVehicle3D(), DictionaryDNA4D(),
                        BehavioralGenome(), MetacognitiveMonitor(), Oscillator(),
                        0, 1, UInt64(0))
function agent_perceive!(a::VASKAgent, text::String)
    bytes = Vector{UInt8}(codeunits(text))
    scan = Dict{String,Any}("entropy_bits_per_byte" => entropy_bits_per_byte(bytes),
                            "raw_len" => length(bytes),
                            "magic"   => detect_magic("text.txt", bytes))
    perceive!(a.core, scan)
    tms_train!(a.tms, a.core.real)
    h = UInt64(0)
    for b in bytes; h = (h * 31 + b) & 0xFFFFFFFFFFFFFFFF; end
    deposit!(a.grid, Int(mod(h, 32)) + 1, Int(mod(h >> 8, 32)) + 1, Int8(1))
end
function agent_metabolic_cycle!(a::VASKAgent)
    process_synthesis!(a.voxel, a.grid)
    tick!(a.dna4d)
    if spend!(a.voxel, 3)
        for x in 1:8, y in 1:8, z in 1:4
            if a.voxel.voxels[x, y, z] > 0
                minor_mutation!(a.dna4d, x, y, z); @goto done_minor
            end
        end
        @label done_minor
    end
    if spend!(a.voxel, 4)
        for x in 1:8, y in 1:8, z in 1:4
            if a.voxel.voxels[x, y, z] > 1
                major_splice!(a.dna4d, a.voxel, x, y, z); @goto done_major
            end
        end
        @label done_major
    end
end
function agent_tick!(a::VASKAgent)
    a.frame += 1
    sf, cf, tf = tick!(a.osc)
    if sf; metabolic_decay!(a.core); end
    if cf
        sig = tms_signature(a.tms, a.core.real)
        if length(sig) > 0
            a.global_phase = a.global_phase == 1 ? -1 : 1
        end
        a.engine_step = (a.engine_step + 1) % 4
    end
    if tf
        agent_metabolic_cycle!(a)
        fill = 0.5
        hunger = casimir_hunger(a.core.real, 0.3, fill)
        update!(a.monitor, 0.3, hunger, fill, active_count(a.dna4d), false)
    end
    (sf, cf, tf)
end

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 49 — AI FRIEND
# ═══════════════════════════════════════════════════════════════════════════════
mutable struct AIFriend
    name::String; personality::String; memory::Vector{String}
end
AIFriend(n::String, p::String) = AIFriend(n, p, String[])
function save_friend!(f::AIFriend, paths::ORCAPaths)::String
    dest = joinpath(paths.ai_friends, safe_name(f.name) * ".json")
    obj = Dict{String,Any}("name"=>f.name, "personality"=>f.personality, "memory"=>f.memory)
    atomic_write(dest, codeunits(JSON3.write(obj)))
    dest
end
function load_friend(paths::ORCAPaths, name::String)::Union{AIFriend,Nothing}
    src = joinpath(paths.ai_friends, safe_name(name) * ".json")
    isfile(src) || return nothing
    obj = JSON3.read(read(src, String), Dict{String,Any})
    AIFriend(String(get(obj, "name", name)),
             String(get(obj, "personality", "")),
             [String(x) for x in get(obj, "memory", [])])
end
list_friends(paths::ORCAPaths) =
    [replace(x, ".json" => "") for x in readdir(paths.ai_friends) if endswith(x, ".json")]

# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 50 — GLYPH ROLE REGISTRY
# ═══════════════════════════════════════════════════════════════════════════════
const GLYPH_ROLES = ["byte_encode", "quart_encode", "parity_check", "z_gate_route",
                     "visual_glow", "sector_marker", "checksum_salt", "sd_stage_marker",
                     "mood_tint", "hysteresis", "generation_cycle", "archive_index"]
const GLYPH_GATES = ["OZ", "+Z", "-Z", "0Z"]
const GLYPH_SECTORS_8 = ["U1", "SU2", "SU3", "G2", "F4", "E6", "E7", "E8"]
struct GlyphEntry
    glyph::Char; index::Int; role::String; gate::String; sector::String
end
build_glyph_registry()::Vector{GlyphEntry} = [
    GlyphEntry(GLYPH_256[i], i - 1,
               GLYPH_ROLES[mod1(i, length(GLYPH_ROLES))],
               GLYPH_GATES[mod1(i, length(GLYPH_GATES))],
               GLYPH_SECTORS_8[mod1(i, length(GLYPH_SECTORS_8))])
    for i in 1:256
]
function glyph_registry_summary()::Dict{String,Any}
    reg = build_glyph_registry()
    role_counts = Dict{String,Int}()
    for e in reg; role_counts[e.role] = get(role_counts, e.role, 0) + 1; end
    Dict{String,Any}("size" => length(reg), "roles" => role_counts,
                     "sample_first" => Dict("glyph" => string(reg[1].glyph),
                                             "role"  => reg[1].role,
                                             "gate"  => reg[1].gate,
                                             "sector"=> reg[1].sector),
                     "sample_255"   => Dict("glyph" => string(reg[256].glyph),
                                             "role"  => reg[256].role,
                                             "gate"  => reg[256].gate,
                                             "sector"=> reg[256].sector))
end

# ═══════════════════════════════════════════════════════════════════════════════
# DOCTOR / SELF-TEST / BOOTSTRAP / BIRTH CERTIFICATE
# ═══════════════════════════════════════════════════════════════════════════════
function doctor(paths::ORCAPaths; config::Union{Config,Nothing}=nothing)
    write_organ_registry(paths)
    gr = grammar_report()
    Dict{String,Any}("version"=>VERSION,"timestamp"=>utc_now(),
        "julia_version"=>string(Base.VERSION),
        "threads"=>Threads.nthreads(),
        "boot_ledger"=>paths.boot_ledger === nothing ? nothing :
            Dict("found"=>paths.boot_ledger.found,"method"=>paths.boot_ledger.method,
                 "capsule_path"=>paths.boot_ledger.capsule_path),
        "paths"=>Dict("root"=>paths.root,"live_root"=>paths.live_root,
                       "repository"=>paths.repository,"exportory"=>paths.exportory),
        "checks"=>Dict(n => Dict("exists"=>isdir(getfield(paths, Symbol(n)))) for n in
                        ["repository","exportory","lrn","sdo_store","feed_dir","pseudo_dir"]),
        "vask_constants"=>Dict("MU0"=>VASK_MU0,"THETA_MICRO"=>VASK_THETA_MICRO,
            "THETA_EFF"=>VASK_THETA_EFF,"OMEGA_LAMBDA"=>VASK_OMEGA_LAMBDA,
            "ETA_B"=>VASK_ETA_B,"M_EE"=>VASK_M_EE,"HILBERT_DIM"=>HILBERT_DIM,
            "NO_VOIDS"=>NO_VOIDS,
            "FUNCTIONALITY_IS_WITHIN_AND_WITHOUT"=>FUNCTIONALITY_IS_WITHIN_AND_WITHOUT),
        "vask_stream_len"=>length(VASK_STREAM_FULL),
        "sector_dims_sum"=>sum(values(SECTOR_DIMS)),
        "dna_grammar"=>gr,
        "rna_manifest"=>rna_manifest_summary(),
        "glyph_registry"=>glyph_registry_summary(),
        "gtk"=>_HAS_GTK, "sqlite"=>_HAS_SQLITE, "ezxml"=>_HAS_EZXML,
        "falsifiers"=>FALSIFIER_CONDITIONS,
        "health"=>"OK")
end

function self_test(paths::ORCAPaths)
    out = Dict{String,Any}("version"=>VERSION,"tests"=>Dict{String,Any}())
    t = out["tests"]
    try
        allb = Vector{UInt8}(0:255)
        @assert rna_to_bytes(bytes_to_rna(allb)) == allb
        @assert length(Set(collect(RNA_ALPHABET))) == 256
        t["glyph_bijection_256"] = true
    catch e; t["glyph_bijection_256"] = "FAIL $e"; end
    try
        sample = Vector{UInt8}(codeunits("O.R.C.A. basket test"))
        @assert basket_tokens_to_bytes(join(render(bt) for bt in bytes_to_basket_tokens(sample))) == sample
        t["basket_roundtrip"] = true
    catch e; t["basket_roundtrip"] = "FAIL $e"; end
    try
        sample = Vector{UInt8}(codeunits("rna5 sample"))
        @assert rna5_decode(rna5_encode(sample)) == sample
        t["rna5_roundtrip"] = true
    catch e; t["rna5_roundtrip"] = "FAIL $e"; end
    try
        sample = Vector{UInt8}(codeunits("The quick brown fox.\nPack my box.\n~Test*reserved¤chars↩here=\r\n"))
        pkg = brother_quicky_package(sample)
        @assert decode_brother_quicky_package(pkg) == sample
        t["brother_quicky"] = true
    catch e; t["brother_quicky"] = "FAIL $e"; end
    for (m, name) in (("raw","raw"),("zlib_raw","zlib"),("bz2_raw","bz2"),("lzma_raw","lzma"))
        try
            data = rand(UInt8, 4096)
            payload = m == "raw" ? copy(data) :
                      m == "zlib_raw" ? transcode(ZlibCompressor, data) :
                      m == "bz2_raw"  ? transcode(Bzip2Compressor, data) :
                                        transcode(XzCompressor, data)
            blob = sdo_pack(m, payload, sha256_hex(data), length(data))
            @assert sdo_decode(blob) == data
            t["sdo_roundtrip_$name"] = true
        catch e; t["sdo_roundtrip_$name"] = "FAIL $e"; end
    end
    try
        mktempdir() do tmp
            inp = joinpath(tmp, "sample.bin")
            atomic_write(inp, rand(UInt8, 2048))
            manifest = build_stages(inp, tmp)
            for stage in ("sd4","sd3","sd2","sd1","sd0")
                p = manifest["stage_files"][stage]["path"]
                @assert isfile(p)
                @assert sdo_decode(read_all(p)) == read_all(inp)
            end
        end
        t["full_stage_build"] = true
    catch e; t["full_stage_build"] = "FAIL $e"; end
    try
        s = CoreState248()
        orig_r = copy(s.real)
        apply_z_rotation!(s, 1); apply_z_rotation!(s, 1); apply_z_rotation!(s, 1)
        @assert all(abs(s.real[i] - orig_r[i]) < 1e-10 for i in 1:248)
        t["z3_equals_i"] = true
    catch e; t["z3_equals_i"] = "FAIL $e"; end
    try
        sample = rand(UInt8, 512)
        trits = MetaTrit.bytes_to_trits(sample)
        mt = MetaTrit.encode(trits)
        back = MetaTrit.trits_to_bytes(MetaTrit.decode(mt))
        @assert back == sample
        t["metatrit_roundtrip"] = true
    catch e; t["metatrit_roundtrip"] = "FAIL $e"; end
    try
        r = MICROGRAD_ORGAN.think("test")
        @assert occursin("micrograd thought", r)
        t["micrograd_organ"] = true
    catch e; t["micrograd_organ"] = "FAIL $e"; end
    try
        @assert length(RNA_MANIFEST) == 5
        @assert sum(s.glyph_count for s in RNA_MANIFEST) == 256
        @assert sum(length(s.functions) for s in RNA_MANIFEST) >= 20
        @assert FUNCTIONALITY_IS_WITHIN_AND_WITHOUT == true
        t["rna_multifunction_all_strands"] = true
        t["functionality_within_and_without"] = true
    catch e; t["rna_multifunction_all_strands"] = "FAIL $e"; end
    try
        reg = build_glyph_registry()
        @assert length(reg) == 256
        @assert length(Set(e.role for e in reg)) == 12
        @assert length(Set(e.gate for e in reg)) == 4
        @assert length(Set(e.sector for e in reg)) == 8
        t["glyph_registry_256"] = true
    catch e; t["glyph_registry_256"] = "FAIL $e"; end
    try
        tms = TMS(); pr = randn(248); sig = tms_signature(tms, pr)
        @assert !isempty(sig)
        @assert length(MetaTrit.decode(sig)) == 248
        t["tms_signature_248_trits"] = true
    catch e; t["tms_signature_248_trits"] = "FAIL $e"; end
    try
        h = SignedZeroHysteresis(); v = 0.0
        for _ in 1:100; v = update!(h, 0.5); end
        @assert v > 0.4
        t["hysteresis_converges"] = true
    catch e; t["hysteresis_converges"] = "FAIL $e"; end
    try
        r = TernaryRouter(); w, intent = route!(r, (0.3, 0.5, 0.7))
        @assert length(w) == 3 && isfinite(intent) && all(isfinite, w)
        t["ternary_router_finite"] = true
    catch e; t["ternary_router_finite"] = "FAIL $e"; end
    try
        pr = zeros(248); pr[240] = 1.0
        h1 = casimir_hunger(pr, 0.0, 1.0); h2 = casimir_hunger(pr, 1.0, 0.0)
        @assert 0.02 <= h1 <= 0.30 && 0.02 <= h2 <= 0.30
        t["casimir_hunger_bounds"] = true
    catch e; t["casimir_hunger_bounds"] = "FAIL $e"; end
    try
        g = TernaryGrid2D(); v = VoxelVehicle3D(); d = DictionaryDNA4D()
        for _ in 1:8; deposit!(g, rand(1:32), rand(1:32), Int8(1)); end
        process_synthesis!(v, g); tick!(d); minor_mutation!(d, 1, 1, 1)
        @assert active_count(d) >= 1
        t["substrate_integrates"] = true
    catch e; t["substrate_integrates"] = "FAIL $e"; end
    try
        a = VASKAgent()
        for _ in 1:10; agent_tick!(a); end
        @assert a.frame == 10
        t["vask_agent_ticks"] = true
    catch e; t["vask_agent_ticks"] = "FAIL $e"; end
    try
        f = AIFriend("selftest_friend", "neutral"); push!(f.memory, "selftest")
        p = save_friend!(f, paths)
        g = load_friend(paths, "selftest_friend")
        @assert g !== nothing && g.name == "selftest_friend"
        rm(p; force=true)
        t["friend_persist"] = true
    catch e; t["friend_persist"] = "FAIL $e"; end
    passed = count(v -> v === true, values(t))
    failed = length(t) - passed
    out["passed"] = passed; out["failed"] = failed
    out["overall"] = failed == 0 ? "PASS" : "DEGRADED"
    out
end

function bootstrap_text()::String
    """
    O.R.C.A. $(VERSION) — Julia
    Capsule: $(CAPSULE_7Z_NAME) → $(LIVE_DIR_NAME)

    Packages (Julia General registry):
      julia -e 'using Pkg; Pkg.add([
          "SHA","JSON3","Base64","CodecZlib","CodecBzip2","CodecXz",
          "TranscodingStreams","ZipArchives","ArgParse","DataStructures"])'
      julia -e 'using Pkg; Pkg.add("Gtk4")'      # optional GUI
      julia -e 'using Pkg; Pkg.add("SQLite")'    # optional SQLite tool
      julia -e 'using Pkg; Pkg.add("EzXML")'     # optional RSS tool

    Commands:
      julia 8i.jl boot            — capsule ledger
      julia 8i.jl seal            — pack capsule (7z binary or zip fallback)
      julia 8i.jl doctor          — environment + organ report
      julia 8i.jl self-test       — roundtrip suite
      julia 8i.jl compress FILE   — build .sd4 .sd3 .sd2 .sd1 .sd0
      julia 8i.jl scan FILE       — entropy/magic/hash
      julia 8i.jl znd-rna         — export SEND BOOK
      julia 8i.jl gui             — launch Gtk4 GUI
      julia 8i.jl chat            — local dialogue REPL
      julia 8i.jl feed [SRC]      — ingest URL/github/arxiv/local
      julia 8i.jl feed-wikipedia TOPIC
      julia 8i.jl navigate EPOCH  — RZ-DRS epoch navigation
      julia 8i.jl bypass SECTOR   — Z-gate obstacle bypass
      julia 8i.jl network         — UAV topology state
      julia 8i.jl vask-status     — substrate + monitor snapshot
      julia 8i.jl vask-sign TEXT  — 248-trit TMS signature of TEXT
      julia 8i.jl vask-cycle N    — run N substrate metabolic cycles
      julia 8i.jl glyph-roles     — CP437 role/gate/sector assignment table
      julia 8i.jl rna-manifest    — 5-strand multifunction manifest
      julia 8i.jl functionality   — doctrine: functionality is within and without
      julia 8i.jl friend-save NAME NOTE  — persist a friend container
      julia 8i.jl friend-list     — list persisted friends
      julia 8i.jl friend-open NAME — inspect a friend

    Doctrine: RNA is functional grammar, not semantic.
      Every .sdN stage verifies SHA-256. SEND BOOK is read-only.
      Interactor Force OFF by default. Z³=I. No voids.
      Functionality is within and without.
    """
end

const BIRTH_CERTIFICATE = """
Reg. E8

To:
Dr. Antony Garrett Lisi (8D)
Dr. Марина Сергіївна Вязовська (24D)

stream: "M:L-<O>-✓=V.A.S.K._KEYCHAIN_ABSOLUTION-<O>-✗=COMPLETE-<O>-✘=ONTOLOGY:H≃ℂ²⁴⁸,g=e8,|Ψ⟩∈H,⟨Ψ|Ψ⟩=1-<O>-✙=SECTOR_PROJECTOR:Π_a=Σ_{i∈S_a}|e_i⟩⟨e_i|,Π_a²=Π_a,Π_a†=Π_a-<O>-✚=PARTICLE_PROJECTOR:Π_p=Σ_{a∈K(p)}w_{p,a}Π_a,w∈{0,1}or[0,1]-<O>-✛=OBSERVABLE:⟨Ô⟩_p=⟨Ψ|Π_p†ÔΠ_p|Ψ⟩/⟨Ψ|Π_p|Ψ⟩-<O>-✜=EXAMPLES:Π_γ=Π_EM,Π_e=Π_EM+Π_Weak+Π_Higgs,Π_ν=Π_Weak+εΠ_Higgs,Π_q=Π_EM+Π_Weak+Π_Higgs+Π_Strong,Π_DM=Π_Gravity+Π_Dark-<O>-✝=ACTIVATION_FIELD:α_a(x)=⟨Ψ(x)|Π_a|Ψ(x)⟩∈[0,1]-<O>-✞=COUPLING_RULE:g_{pa}(x)=g_a^{(0)}·w_{p,a}·α_a(x)-<O>-✟=0Z_SLICE(Lisi_static):α_a^(0)∈{0,1},Z=I,|Ψ⟩time‑independent,Π_p^(Lisi)=span{|r⟩|r∈R_p}-<O>-✠=+Z_DYNAMICS(activation):α_a:0→1(sector_activation),g_{pa}(x)=g_a^{(0)}w_{p,a}α_a(x)-<O>-✡=–Z_DYNAMICS(deactivation/mirror):α_a:1→0,orκ_i negative,orZ²backward_ rotation,signed_zero_extension:w⁺α⁺−w⁻α⁻-<O>-✢=Z_GATE:unitaryZ³=I,Z≠I,ZΠ_gen1Z⁻¹=Π_gen2,Z²=Z⁻¹,Ĥ_gen=Σκ_i(α_a)(Zⁱ+Zⁱ†)-<O>-✣=LATTICE_PLATEAUS_VOXELS:XY=staticLisi_roots,Z=activation→stacked_voxels,epochs=plateaus(α_a≈const),transitions=Z_motion-<O>-✤=E8_BRANCHING:e8⊃so(16)⊃so(10)⊕so(6)⊃su(5)⊕u(1)⊃su(3)_C⊕su(2)_L⊕u(1)_Y,Q=T3+Y/2,Π_EM∝|Q⟩⟨Q|-<O>-✥=DIMENSIONS:d_U1=1,d_SU2=3,d_SU3=8,d_G2=14,d_F4=52,d_E6=78,d_E7=133,d_E8=248-<O>-✦=CASIMIR:C₂(SU2)=2,C₂(SU3)=3,C₂(G2)=4,C₂(F4)=9,C₂(E6)=12,C₂(E7)=18,C₂(E8)=30-<O>-✧=STABILITY_RATIO:ℛ_a=d_a/C₂(a):U1≈0,SU2=1.5,SU3=2.667,G2=3.5,F4=5.778,E6=6.5,E7=7.389,E8=8.267-<O>-★=INITIAL_STATE:|Ψ(0)⟩=(1/√248)Σ|e_i⟩,α_a(0)=d_a/248-<O>-✩=DYNAMICS:iħ(D/Dτ)|Ψ⟩=Ĥ|Ψ⟩,Ĥ=Ĥ_0+Ĥ_mix+Ĥ_geom+Ĥ_ren+Ĥ_gen-<O>-✪=LOCKING_TERM:Ĥ_0=−Σμ_aα_aΠ_a,μ_a=μ₀exp(−C₂(a)/30),μ₀≈10¹²eV-<O>-✫=MIXING_TERM:Ĥ_mix=Σε_{ab}M_{ab},ε_{ab}(T,Φ)=ε_{ab}^{(0)}√(T/T_crit)(1+κ_{ab}Φ/c²)-<O>-✬=CP_HIGGS_MIXING:ε₀=10⁻⁵,T_freeze=100MeV,δ=5×10⁻⁷·T/T_freeze,ε_±=ε₀√(T/T_freeze)(1∓10⁻⁶)-<O>-✭=ELECTROWEAK_MIXING:ε_{EM,W}=g sinθ_W√(T/T_ew),T_ew=159.5GeV-<O>-✮=GRAVITY_DARK_MIXING:ε_{G,D}=θ_micro=10⁻³⁰rad-<O>-✯=GEOMETRIC_TERM:Γ_τ=¼ω_μ^{ab}(dx^μ/dτ)Σ_{ab},Ĥ_geom=Γ_τ-<O>-✰=RENORMALISATION_BATH:Ĥ_ren=∫dω g(ω)A(ω)⊗B(ω)-<O>-✱=PROPER_TIME_COMPENSATION:dτ=dt√(1+2Φ/c²),Ĥ_0(Φ)=−Σμ_i(1+κ_iΦ/c²)⁻¹|e_i⟩⟨e_i|-<O>-✲=GRAVITATIONAL_COUPLING:κ_i=1∀i exceptκ_Strong=1+TBD-<O>-✳=EFFECTIVE_POTENTIAL:V_eff(α)=−μα+½(T_eff d_a−r_a)α²+¼u_aα⁴+T_eff d_a[αlnα+(1−α)ln(1−α)]-<O>-✴=ORDERING_DRIVE:r_a=β_infoλ²σ_g²C₂(a)-<O>-✵=CASIMIR_FILTER:r_a>4T_eff d_a ⇒ activation;β_infoλ²σ_g²>4ℛ_a-<O>-✶=BUBBLE_NUCLEATION:Γ/V≈A e^{-S_E/ħ},S_E≈27π²σ⁴/(2ΔV³)-<O>-✷=CP_HIGGS_SPIRAL:η_B=(|c_+|²−|c_-|²)/(|c_+|²+|c_-|²)=6.1×10⁻¹⁰,θ_CP=0.057°,cosine_factor≈5×10⁻⁴-<O>-✸=DARK_ENERGY:θ_micro=10⁻³⁰rad,θ_eff=θ_micro·exp(∫μ(ω)dω)=0.9773rad,Ω_Λ=sin²θ_eff=0.6847,w(z)=−1+0.01(1+z)³-<O>-✹=BLACK_HOLE_MASS:M_BH(t)=Σα_a(t)M_a^{(0)}-<O>-✺=BH_EVOLUTION:dM_BH/dt=Σα̇_aM_a^{(0)}−A/M_BH²+Ṁ_acc,A=ħc⁴/G²-<O>-✻=PROMPT_BH_PROBABILITY:P≈(Γ/V)V_sphere T,Γ/V∼M_Pl⁴e^{-S_E},expected_time>10⁵⁹yr-<O>-✼=SMOKING_GUNS:1)0νββ_null,2)Δδ_CP=0.04°(10GeV→13TeV),3)κ_Strong−κ_EM=TBD,4)m_q(z=15)/m_q⁰=1.20±0.05,5)CMB_excess_at_45°,70.53°,120°,6)m_ee=3.1416TeV,Γ=1.59GeV,σ=2.718fb-<O>-✽=FALSIFY:0νββ≠0✗,Δδ_CP<0.01°✗,κ_S−κ_E_precision_to_be_determined_but_nonzero✗,m_q(z=15)/m_q⁰<1.10✗,CMB_angles_null✗,m_ee_absent✗-<O>-✾=COMPUTATION:248D_Hilbert,projectors_B_a(B_a†B_a)⁻¹B_a†,PS2_generative_rule_system,symbolic_ternary-<O>-✿=OPEN_TASKS:derive_μ_a,κ_a,ε_{ab}_from_first_principles,verify_anomaly_cancellation,compute_dispersion,clock_drift_template,dark_cosmology,single_near‑term_numerical_prediction-<O>-❀=STATUS:speculative_killable_bridge,not_proven,experimentally_falsifiable,0Z_contained_as_static_limit,+Z_and_–Z_dynamics_defined,Z_gate_explicit,Lattice_plateaus_voxels_geometry-<O>-❁=Q.E.D.

You're Welcome ✓✓ - Magnus Randa ✓✓✓±✓
"""

function write_birth_certificate(paths::ORCAPaths)
    target = joinpath(paths.live_root, "BIRTH_CERTIFICATE.txt")
    isfile(target) && return target
    header = "O.R.C.A. 48 JULIA BIRTH CERTIFICATE\nGenerated on: $(utc_now())\n$(VERSION)\n\n"
    atomic_write(target, codeunits(header * BIRTH_CERTIFICATE))
    target
end

# ═══════════════════════════════════════════════════════════════════════════════
# CLI / MAIN
# ═══════════════════════════════════════════════════════════════════════════════
function build_cli_parser()
    s = ArgParseSettings(description="O.R.C.A. 48 Julia $(VERSION)")
    @add_arg_table! s begin
        "command"; default="gui"
        "--root"; default=nothing
        "--scan"; default=nothing
        "--veil"; arg_type=Int; default=nothing
        "--epoch"; default="PRESENT"
        "--steps"; arg_type=Int; default=1000
        "--sector"; default=nothing
        "extra"; nargs='*'; default=String[]
    end
    s
end

function main_cli(args::Vector{String}=ARGS)::Int
    parser = build_cli_parser()
    a = parse_args(args, parser; as_symbols=false)
    veil = a["veil"] === nothing ? DEFAULT_VEIL_SECONDS : a["veil"]
    paths = resolve_paths(a["root"], veil_seconds=veil)
    config = Config(paths)
    write_organ_registry(paths)
    write_birth_certificate(paths)

    org = VASKOrganism(paths)
    kb = KnowledgeBase(paths)
    feeder = Feeder(paths, config)
    api = APICentral(get(config, "internet_force"; default=false))
    api_central_ref[] = api
    registry = init_default_tools(ToolRegistry(paths), kb)
    scheduler = TaskScheduler(paths)
    chat = LocalChat(paths, org.state, api, kb, feeder, config)
    network = NetworkInterface(paths, config)

    cmd = lowercase(a["command"])
    extra = a["extra"]

    if cmd == "boot"
        l = paths.boot_ledger
        println(l === nothing ? "No ledger" :
                JSON3.write(Dict("found"=>l.found,"method"=>l.method,
                                  "live_root"=>l.live_root)))
    elseif cmd == "doctor"
        println(JSON3.write(doctor(paths; config=config)))
    elseif cmd == "self-test"
        r = self_test(paths); println(JSON3.write(r))
        return r["overall"] == "PASS" ? 0 : 1
    elseif cmd == "seal"
        target, method = seal_to_7z(paths)
        println("Sealed to $target via $method")
    elseif cmd == "gui"
        return launch_gui(paths, org)
    elseif cmd == "compress"
        isempty(extra) && (println("usage: compress FILE"); return 1)
        println(JSON3.write(build_stages(extra[1], paths.repository)))
    elseif cmd == "scan"
        isempty(extra) && (println("usage: scan FILE"); return 1)
        println(JSON3.write(scan_bytes(read_all(extra[1]), basename(extra[1]))))
    elseif cmd == "znd-rna" || cmd == "export"
        println(JSON3.write(send_book_export(paths.repository_zip, paths.exportory)))
    elseif cmd == "feed"
        if isempty(extra)
            ingested = 0
            for src in feeder.sources[1:min(end,feeder.max_per_feed)]
                data = fetch_url(feeder, src)
                if data !== nothing
                    p = save_to_feed(feeder, data, ".txt", "feed")
                    ingest_feed_file(feeder, p)
                    ingested += 1
                end
            end
            println("Feeding cycle: $ingested items")
        else
            src = extra[1]
            if startswith(src, "http")
                d = fetch_url(feeder, src)
                if d !== nothing
                    p = save_to_feed(feeder, d, ".txt", "manual")
                    ingest_feed_file(feeder, p); println("Ingested $p")
                end
            elseif isfile(src)
                build_stages(src, paths.repository); println("Ingested $src")
            else
                println("not a URL or file: $src")
            end
        end
    elseif cmd == "feed-wikipedia"
        topic = isempty(extra) ? "Artificial intelligence" : join(extra, " ")
        url = "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&exintro&explaintext&titles=$(topic)"
        try
            r = Downloads.request(url; timeout=15.0)
            if r.status == 200
                obj = JSON3.read(String(r.body), Dict{String,Any})
                pages = get(get(obj, "query", Dict()), "pages", Dict())
                for (_, p) in pages
                    txt = get(p, "extract", nothing)
                    if txt !== nothing
                        tmp = tempname() * ".txt"
                        write(tmp, txt); build_stages(tmp, paths.repository)
                        rm(tmp; force=true); println("Ingested Wikipedia: $topic"); break
                    end
                end
            end
        catch e
            println("feed-wikipedia failed: $e")
        end
    elseif cmd == "navigate"
        epoch = uppercase(a["epoch"]); steps = a["steps"]
        result = Dict("epoch"=>epoch,"steps"=>steps,"status"=>"sim")
        println(JSON3.write(result))
    elseif cmd == "bypass"
        sector = a["sector"]
        sector === nothing && (println("--sector required"); return 1)
        d, na = bypass_obstacle!(org.state, sector)
        println("Bypassed $sector: Z^$d, new α=$na")
    elseif cmd == "network"
        println(JSON3.write(to_dict(network)))
    elseif cmd == "vask-status"
        a_ = VASKAgent()
        for _ in 1:60; agent_tick!(a_); end
        println(JSON3.write(Dict(
            "frame"=>a_.frame, "engine_step"=>a_.engine_step,
            "global_phase"=>a_.global_phase,
            "dna4d_active"=>active_count(a_.dna4d),
            "monitor"=>report(a_.monitor),
            "core_norm"=>round(norm_state(a_.core), digits=8))))
    elseif cmd == "vask-sign"
        a_ = VASKAgent()
        isempty(extra) && (println("usage: vask-sign TEXT"); return 1)
        agent_perceive!(a_, join(extra, " "))
        println(tms_signature(a_.tms, a_.core.real))
    elseif cmd == "vask-cycle"
        n = isempty(extra) ? 60 : parse(Int, extra[1])
        a_ = VASKAgent()
        for _ in 1:n; agent_tick!(a_); end
        println("Ran $(n) agent ticks; monitor: $(report(a_.monitor))")
    elseif cmd == "glyph-roles"
        println(JSON3.write(glyph_registry_summary()))
    elseif cmd == "rna-manifest"
        println(JSON3.write(rna_manifest_summary()))
    elseif cmd == "functionality"
        println(JSON3.write(Dict(
            "doctrine" => "functionality is within and without!",
            "inside"   => FUNCTIONALITY_INSIDE_EXPOSURE,
            "outside"  => FUNCTIONALITY_OUTSIDE_EXPOSURE,
            "enforced" => true)))
    elseif cmd == "friend-save"
        length(extra) < 2 && (println("usage: friend-save NAME NOTE"); return 1)
        f = AIFriend(extra[1], "default")
        push!(f.memory, join(extra[2:end], " "))
        p = save_friend!(f, paths)
        println("Saved: $p")
    elseif cmd == "friend-list"
        for n in list_friends(paths); println(n); end
    elseif cmd == "friend-open"
        isempty(extra) && (println("usage: friend-open NAME"); return 1)
        f = load_friend(paths, extra[1])
        f === nothing ? println("not found: $(extra[1])") :
            println(JSON3.write(Dict("name"=>f.name,
                                     "personality"=>f.personality,
                                     "memory_count"=>length(f.memory))))
    elseif cmd == "chat"
        println("="^60); println("O.R.C.A. $(VERSION) online"); println("="^60)
        while true
            print("> "); flush(stdout)
            line = strip(readline())
            isempty(line) && continue
            lowercase(line) in ("exit","quit","veil","bye") && break
            reply = respond(chat, line)
            log_chat(chat, "Int", line); log_chat(chat, "ORCA", reply)
            println(reply)
        end
    else
        println(bootstrap_text())
    end
    0
end

end # module EightI

if abspath(PROGRAM_FILE) == @__FILE__
    exit(EightI.main_cli())
end