// Three-layer stack: how surface, core, and providence-cache compose
// over one SQLite file per shard.
//
// Surface = ingested docs (Merkle-rooted, FTS5-indexed).
// Core = distillates, bound back to surfaces via per-chunk inclusion
//        proofs in derivations.proof_blob. Recursive (depth-N → N+1).
// Providence cache = Q&A records keyed on the v9.8 8-dim invariant,
//        each carrying audit_mode (STRICT / HYBRID / UNGROUNDED) +
//        a Merkle proof binding the answer to its source chunks.
//
// Render: dot -Tsvg three-layer-stack.dot -o three-layer-stack.svg

digraph three_layer_stack {
    rankdir=BT
    node [shape=box, style="rounded,filled", fontname="Helvetica", fontsize=10]
    edge [fontname="Helvetica", fontsize=9]
    bgcolor="white"

    subgraph cluster_surface {
        label="SURFACE — ingested documents"
        labeljust="l"
        fontname="Helvetica-Bold"
        style="rounded,filled"
        fillcolor="#fff7e6"
        margin=12

        s_wiki [label="Wikipedia\nXML / SQL dump", fillcolor="#fff0d0"]
        s_html [label="HTML page\n(crawler)", fillcolor="#fff0d0"]
        s_grok [label="Grok export\nconversation", fillcolor="#fff0d0"]
        s_vcs  [label="git / hg\nrepo HEAD walk", fillcolor="#fff0d0"]
        s_tex  [label="textbook_tex\nProject Gutenberg LaTeX", fillcolor="#fff0d0"]
        s_root [label="document_root (32 bytes)\nMerkle root over canonical chunks\nidentity = content, not URI", fillcolor="#ffe2a8", shape=note]
    }

    subgraph cluster_core {
        label="CORE — distillates"
        labeljust="l"
        fontname="Helvetica-Bold"
        style="rounded,filled"
        fillcolor="#e7ffe7"
        margin=12

        c_first [label="first_sentence\n(lead extraction)", fillcolor="#d0f0d0"]
        c_tfidf [label="tfidf\n(keyword core)", fillcolor="#d0f0d0"]
        c_recur [label="depth-N → depth-N+1\nrecursive distillation", fillcolor="#d0f0d0"]
        c_proof [label="derivations.proof_blob\nper contributing chunk:\n  • leaf_hash\n  • sibling path\n  • verify_proof() ≡ True\nbinding survives compression", fillcolor="#b8e6b8", shape=note]
    }

    subgraph cluster_prov {
        label="PROVIDENCE CACHE — Q&A records"
        labeljust="l"
        fontname="Helvetica-Bold"
        style="rounded,filled"
        fillcolor="#e6f0ff"
        margin=12

        p_key [label="cache_key (8-dim)\nsource_root | question_hash |\nmodel_profile | conversation |\ngovernance_policy | schema_v |\ncanonicalization_v | chunking_v", fillcolor="#cfdfff", shape=note]
        p_audit [label="audit_mode ∈\n{STRICT, HYBRID, UNGROUNDED}\nset by verifier, never asserted", fillcolor="#cfdfff"]
        p_state [label="falsification_state ∈\n{live, failed, stale, quarantined}\ncache reads filter on state='live'", fillcolor="#cfdfff"]
        p_proof [label="merkle_proof\nbinds answer ↔ source chunks\nverifies offline, across peers", fillcolor="#a8c8ff", shape=note]
    }

    // Surface composes into one document_root
    s_wiki -> s_root
    s_html -> s_root
    s_grok -> s_root
    s_vcs  -> s_root
    s_tex  -> s_root

    // Core binds back to surface via per-chunk proofs
    s_root -> c_proof [label="ingested chunks\nbind cores back", color="#2d6a2d"]
    c_first -> c_proof
    c_tfidf -> c_proof
    c_recur -> c_proof
    c_recur -> c_recur [label="self-recursion", color="#2d6a2d"]

    // Providence carries source_root from surface + Merkle proof
    s_root -> p_key [label="source_root", color="#1a3a8a"]
    c_proof -> p_proof [label="proof structure\nreused", color="#1a3a8a", style="dashed"]

    p_key -> p_audit [style=invis]
    p_audit -> p_state [style=invis]
    p_state -> p_proof [style=invis]

    // Layer separation hint at right edge
    {rank=same; s_root; c_proof; p_proof}
}
