// arborist/mesh — what flows between peers.
//
// Arborist is content-addressed: two peers ingesting the same dump
// compute bit-identical document_roots. Gossip exchanges identifiers,
// derivations, falsifications, and witness signatures. Bulk content
// only flows on cache miss, by Merkle proof of inclusion.
//
// HTTP wire (mesh sync, mesh serve) is the next milestone; this
// diagram fixes the protocol contract that wire will implement.
//
// Render: dot -Tpng docs/diagrams/mesh-data-flow.dot -o /tmp/x.png

digraph mesh_data_flow {
    rankdir=LR;
    bgcolor="white";
    compound=true;
    node [shape=box, style="rounded,filled", fontname="Helvetica"];
    edge [fontname="Helvetica", fontsize=10];

    subgraph cluster_alice {
        label="peer: alice (admin)";
        style="rounded,filled";
        fillcolor="#fff7d6";

        a_docs    [label="documents\n(surface + core)", fillcolor="#ffffff"];
        a_deriv   [label="derivations\n(surface -> core proof_blob)", fillcolor="#ffffff"];
        a_prov    [label="providence_cache\n(8-dim cache_key, audit_mode)", fillcolor="#ffffff"];
        a_falsif  [label="falsifications\n('this answer is wrong')", fillcolor="#ffffff"];
        a_audit   [label="audit_events\n(append-only chain)", fillcolor="#ffffff"];
    }

    subgraph cluster_bob {
        label="peer: bob (member)";
        style="rounded,filled";
        fillcolor="#d6ecff";

        b_docs    [label="documents\n(surface + core)", fillcolor="#ffffff"];
        b_deriv   [label="derivations", fillcolor="#ffffff"];
        b_prov    [label="providence_cache", fillcolor="#ffffff"];
        b_falsif  [label="falsifications", fillcolor="#ffffff"];
        b_audit   [label="audit_events", fillcolor="#ffffff"];
    }

    subgraph cluster_wire {
        label="gossip messages (Ed25519-signed, optional AEAD)";
        style="rounded,dashed";
        color="#666666";

        m_root  [label="ANNOUNCE_ROOT\ndocument_root, source_uri,\nchunking_version, schema_version", fillcolor="#e8ffe8"];
        m_der   [label="ANNOUNCE_DERIVATION\ncore_root <- surface_root(s),\ndistiller_id, proof_blob hash", fillcolor="#e8ffe8"];
        m_prov  [label="ANNOUNCE_PROVIDENCE\ncache_key, audit_mode,\nanswer_hash", fillcolor="#e8ffe8"];
        m_fals  [label="ANNOUNCE_FALSIFICATION\ncache_key, reason, signed by witness", fillcolor="#ffe0e0"];
        m_pull  [label="REQUEST_BODY\ndocument_root or chunk_root\n(only on local miss)", fillcolor="#fff7d6"];
        m_resp  [label="DELIVER_BODY\nbytes + Merkle proof of inclusion\nrecipient verifies before insert", fillcolor="#fff7d6"];
    }

    a_docs   -> m_root  [lhead=cluster_wire];
    a_deriv  -> m_der   [lhead=cluster_wire];
    a_prov   -> m_prov  [lhead=cluster_wire];
    a_falsif -> m_fals  [lhead=cluster_wire];

    m_root  -> b_docs   [ltail=cluster_wire];
    m_der   -> b_deriv  [ltail=cluster_wire];
    m_prov  -> b_prov   [ltail=cluster_wire];
    m_fals  -> b_falsif [ltail=cluster_wire];

    b_docs -> m_pull [label="miss on root", color="#cc6600"];
    m_pull -> a_docs [color="#cc6600"];
    a_docs -> m_resp [color="#cc6600"];
    m_resp -> b_docs [label="verify proof,\nthen ingest", color="#cc6600"];

    a_audit -> b_audit [label="audit chain merge\n(prev_event_hash gates inserts)", style=dashed, color="#0066cc", constraint=false];
}
