let d = import "../ontology/defaults/core.ncl" in

{
  nodes = [

    # ── Axioms (invariant = true) ─────────────────────────────────────────────

    d.make_node {
      id          = "protocol-not-runtime",
      name        = "Protocol, Not Runtime",
      pole        = 'Yang,
      level       = 'Axiom,
      description = "Onref is a protocol specification and tooling layer. It is never a runtime dependency. Projects implement the protocol; onref provides the schemas and modules to do so.",
      invariant   = true,
    },

    d.make_node {
      id          = "self-describing",
      name        = "Self-Describing",
      pole        = 'Yang,
      level       = 'Axiom,
      description = "Onref describes itself using its own protocol. The .ontology/, adrs/, and reflection/ directories in this repository are onref consuming ontoref.",
      invariant   = true,
      artifact_paths = [".ontology/core.ncl", ".ontology/state.ncl", "adrs/"],
    },

    d.make_node {
      id          = "no-enforcement",
      name        = "No Enforcement",
      pole        = 'Yang,
      level       = 'Axiom,
      description = "Onref defines contracts and patterns. There is no enforcement mechanism. Coherence is voluntary and emerges from justified adoption.",
      invariant   = true,
    },

    d.make_node {
      id          = "dag-formalized",
      name        = "DAG-Formalized Knowledge",
      pole        = 'Yin,
      level       = 'Axiom,
      description = "All project knowledge — concepts, tensions, decisions, state — is formalized as directed acyclic graphs. This enables transversal queries, impact analysis, and ecosystem-level visibility.",
      invariant   = true,
      artifact_paths = ["ontology/schemas/", "crates/ontoref-ontology/"],
    },

    # ── Tensions ──────────────────────────────────────────────────────────────

    d.make_node {
      id          = "formalization-vs-adoption",
      name        = "Formalization vs Adoption Friction",
      pole        = 'Spiral,
      level       = 'Tension,
      description = "Richer formalization produces better ecosystem visibility but increases the cost of adoption. The balance: schemas are optional layers, not mandatory gates.",
    },

    d.make_node {
      id          = "ontology-vs-reflection",
      name        = "Ontology vs Reflection",
      pole        = 'Spiral,
      level       = 'Tension,
      description = "Ontology captures what IS (invariants, structure, being). Reflection captures what BECOMES (operations, drift, memory). Both must coexist without one dominating. This tension is onref's core identity.",
    },

    # ── Practices ─────────────────────────────────────────────────────────────

    d.make_node {
      id          = "adr-lifecycle",
      name        = "ADR Lifecycle",
      pole        = 'Yang,
      level       = 'Practice,
      description = "Architectural decisions follow: Proposed → Accepted → Superseded. Superseded ADRs retain constraints for historical reconstruction. Active Hard constraints drive the constraint set.",
      artifact_paths = [
        "adrs/schema.ncl",
        "adrs/reflection.ncl",
        "adrs/_template.ncl",
        "adrs/adr-001-protocol-as-standalone-project.ncl",
        "adrs/adr-002-daemon-for-caching-and-notification-barrier.ncl",
        "CHANGELOG.md",
      ],
    },

    d.make_node {
      id          = "reflection-modes",
      name        = "Reflection Modes",
      pole        = 'Yang,
      level       = 'Practice,
      description = "Operational procedures are first-class artifacts encoded as NCL DAG contracts. Modes declare actors, steps, dependencies, and error strategies — not prose.",
      artifact_paths = ["reflection/modes/", "reflection/schemas/", "crates/ontoref-reflection/"],
    },

    d.make_node {
      id          = "coder-process-memory",
      name        = "Coder Process Memory",
      pole        = 'Yin,
      level       = 'Practice,
      description = "Session knowledge is captured as structured JSONL via coder record. Queryable, exportable, and promotable to reflection/knowledge/. The memory layer between sessions.",
      artifact_paths = ["reflection/modules/coder.nu", "reflection/schemas/coder.ncl"],
    },

    d.make_node {
      id          = "describe-query-layer",
      name        = "Describe Query Layer",
      pole        = 'Yang,
      level       = 'Practice,
      description = "describe.nu aggregates all project sources and answers self-knowledge queries: what IS this, what can I DO, what can I NOT do, what tools exist, what is the impact of changing X.",
      artifact_paths = ["reflection/modules/describe.nu"],
    },

    d.make_node {
      id          = "ontoref-ontology-crate",
      name        = "Ontoref Ontology Crate",
      pole        = 'Yang,
      level       = 'Practice,
      description = "Rust implementation for loading and querying .ontology/ NCL files as typed structs. Provides the Core, Gate, and State types for ecosystem-level introspection.",
      artifact_paths = ["crates/ontoref-ontology/"],
    },

    d.make_node {
      id          = "ontoref-reflection-crate",
      name        = "Ontoref Reflection Crate",
      pole        = 'Yang,
      level       = 'Practice,
      description = "Rust implementation for loading, validating, and executing Reflection modes as NCL DAG contracts against project state.",
      artifact_paths = ["crates/ontoref-reflection/"],
    },

    d.make_node {
      id          = "adopt-ontoref-tooling",
      name        = "Adopt Ontoref Tooling",
      pole        = 'Yang,
      level       = 'Practice,
      description = "Migration system for onboarding existing projects into the ontoref protocol. Provides .ontology/ stub templates, .ontoref/config.ncl template, scripts/ontoref thin wrapper, and the adopt_ontoref mode+form+script that wire everything up idempotently.",
      artifact_paths = [
        "ontoref",
        "justfile",
        "justfiles/ci.just",
        "templates/ontology/",
        "templates/ontoref-config.ncl",
        "templates/scripts-ontoref",
        "reflection/modes/adopt_ontoref.ncl",
        "reflection/forms/adopt_ontoref.ncl",
        "reflection/templates/adopt_ontoref.nu.j2",
      ],
    },

    d.make_node {
      id          = "web-presence",
      name        = "Web Presence",
      pole        = 'Yang,
      level       = 'Practice,
      description = "Landing page at assets/web/ describing the ontoref protocol to external audiences. Bilingual (EN/ES), covers protocol layers, yin/yang duality, crates, and adoption path. Self-description artifact.",
      artifact_paths = ["assets/web/src/index.html", "assets/web/index.html", "README.md", "assets/architecture.svg"],
    },

    d.make_node {
      id          = "ontoref-daemon",
      name        = "Ontoref Daemon",
      pole        = 'Yang,
      level       = 'Practice,
      description = "Runtime support daemon for the ontoref protocol. Provides NCL export caching, file watching, actor registry, notification barrier, HTTP API, MCP server (stdio + streamable-HTTP), Q&A NCL persistence, quick-actions catalog, and passive drift observation. Reads .ontoref/config.ncl at startup.",
      invariant   = false,
      artifact_paths = [
        "crates/ontoref-daemon/",
        "reflection/modules/services.nu",
        "crates/ontoref-daemon/src/ui/qa_ncl.rs",
        "crates/ontoref-daemon/src/ui/drift_watcher.rs",
        "crates/ontoref-daemon/src/mcp/mod.rs",
        "justfiles/ci.just",
      ],
    },

    d.make_node {
      id          = "qa-knowledge-store",
      name        = "Q&A Knowledge Store",
      pole        = 'Yin,
      level       = 'Practice,
      description = "Accumulated Q&A entries persisted as NCL — questions and answers captured during development sessions, AI interactions, and architectural reviews. Git-versioned, typed by QaEntry schema, queryable via MCP (ontoref_qa_list/add) and HTTP (/qa-json). Bridges session boundaries: knowledge is never lost between actor sessions.",
      artifact_paths = [
        "reflection/qa.ncl",
        "reflection/schemas/qa.ncl",
        "crates/ontoref-daemon/src/ui/qa_ncl.rs",
      ],
    },

    d.make_node {
      id          = "quick-actions",
      name        = "Quick Actions Catalog",
      pole        = 'Yang,
      level       = 'Practice,
      description = "Runnable shortcuts over existing reflection modes. Configured as quick_actions in .ontoref/config.ncl (id, label, icon, category, mode, actors). Accessible from UI (/actions), CLI (./ontoref), and MCP (ontoref_action_list/add). New modes created via ontoref_action_add are immediately available as actions. Reduces friction between knowing a mode exists and executing it.",
      artifact_paths = [
        ".ontoref/config.ncl",
        "crates/ontoref-daemon/templates/pages/actions.html",
        "reflection/modes/",
      ],
    },

    d.make_node {
      id          = "drift-observation",
      name        = "Passive Drift Observation",
      pole        = 'Spiral,
      level       = 'Practice,
      description = "Background observer that bridges Yang code artifacts with Yin ontology declarations. Watches crates/, .ontology/, adrs/, reflection/modes/ for changes; after a debounce window runs sync scan + sync diff; if MISSING/STALE/DRIFT/BROKEN items are found emits an ontology_drift notification. Never applies changes automatically — apply remains a deliberate human or agent act.",
      artifact_paths = [
        "crates/ontoref-daemon/src/ui/drift_watcher.rs",
        "reflection/modes/sync-ontology.ncl",
      ],
    },

  ],

  edges = [

    { from = "self-describing",    to = "dag-formalized",          kind = 'ManifestsIn,  weight = 'High   },
    { from = "self-describing",    to = "adr-lifecycle",           kind = 'ManifestsIn,  weight = 'High   },
    { from = "self-describing",    to = "reflection-modes",        kind = 'ManifestsIn,  weight = 'High   },
    { from = "ontology-vs-reflection", to = "dag-formalized",      kind = 'Resolves,     weight = 'High   },
    { from = "ontology-vs-reflection", to = "coder-process-memory", kind = 'Resolves,   weight = 'Medium },
    { from = "dag-formalized",     to = "ontoref-ontology-crate",  kind = 'ManifestsIn,  weight = 'High   },
    { from = "reflection-modes",   to = "ontoref-reflection-crate", kind = 'ManifestsIn, weight = 'High   },
    { from = "no-enforcement",     to = "formalization-vs-adoption", kind = 'Resolves,   weight = 'Medium },
    { from = "protocol-not-runtime", to = "no-enforcement",        kind = 'Implies,      weight = 'High   },
    { from = "adr-lifecycle",      to = "reflection-modes",        kind = 'Complements,  weight = 'Medium },
    { from = "describe-query-layer", to = "dag-formalized",        kind = 'DependsOn,    weight = 'High   },
    { from = "coder-process-memory", to = "describe-query-layer",  kind = 'Complements,  weight = 'Medium },
    { from = "ontoref-daemon",        to = "ontoref-ontology-crate",  kind = 'Complements,  weight = 'High   },
    { from = "ontoref-daemon",        to = "reflection-modes",        kind = 'Complements,  weight = 'Medium },
    { from = "protocol-not-runtime",  to = "ontoref-daemon",          kind = 'Contradicts,  weight = 'Low,
      note = "Daemon is optional runtime support, not a protocol requirement. Protocol functions without it." },
    { from = "no-enforcement",        to = "adopt-ontoref-tooling",   kind = 'ManifestsIn,  weight = 'High,
      note = "Adoption is voluntary — the tooling makes it easy but never mandatory." },
    { from = "adopt-ontoref-tooling", to = "reflection-modes",        kind = 'DependsOn,    weight = 'High   },
    { from = "self-describing",       to = "web-presence",            kind = 'ManifestsIn,  weight = 'Medium },
    { from = "web-presence",          to = "adopt-ontoref-tooling",   kind = 'Complements,  weight = 'Medium },

    # Q&A Knowledge Store edges
    { from = "qa-knowledge-store",    to = "dag-formalized",          kind = 'ManifestsIn,  weight = 'High,
      note = "Q&A entries are typed NCL records, git-versioned — knowledge as DAG." },
    { from = "qa-knowledge-store",    to = "coder-process-memory",    kind = 'Complements,  weight = 'High,
      note = "Q&A is the persistent layer; coder.nu is the session capture layer. Together they form the full memory stack." },
    { from = "ontoref-daemon",        to = "qa-knowledge-store",      kind = 'Contains,     weight = 'High   },

    # Quick Actions edges
    { from = "quick-actions",         to = "reflection-modes",        kind = 'DependsOn,    weight = 'High,
      note = "Each quick action invokes a reflection mode by id." },
    { from = "quick-actions",         to = "ontoref-daemon",          kind = 'ManifestsIn,  weight = 'Medium },
    { from = "describe-query-layer",  to = "quick-actions",           kind = 'Complements,  weight = 'Medium,
      note = "describe capabilities lists available modes; quick-actions makes them executable." },

    # Drift Observation edges
    { from = "drift-observation",     to = "ontoref-daemon",          kind = 'ManifestsIn,  weight = 'High   },
    { from = "drift-observation",     to = "ontology-vs-reflection",  kind = 'Resolves,     weight = 'Medium,
      note = "Drift observer continuously monitors the gap between Yin (ontology) and Yang (code). Passive resolution — it signals drift without forcing resolution." },
    { from = "drift-observation",     to = "reflection-modes",        kind = 'DependsOn,    weight = 'High,
      note = "Invokes sync-ontology mode steps (scan, diff) as read-only sub-processes." },

  ],
}
