let m = import "../ontology/defaults/manifest.ncl" in

m.make_manifest {
  project     = "ontoref",
  repo_kind   = 'DevWorkspace,
  description = "Protocol specification and tooling layer for structured self-knowledge in software projects. Provides schemas, Nushell automation, and Rust crates so projects can describe what they are, record architectural decisions, track operational state, and execute formalized procedures as typed, queryable artifacts.",

  content_assets = [
    m.make_asset {
      id          = "logo-horizontal",
      kind        = 'Logo,
      source_path = "assets/branding/ontoref-h.svg",
      variants    = ["assets/branding/ontoref-h-static.svg", "assets/branding/ontoref-dark-h.svg", "assets/branding/ontoref-mono-black-h.svg", "assets/branding/ontoref-mono-white-h.svg"],
      description = "Primary horizontal logo — animated SVG with static and dark/mono variants.",
    },
    m.make_asset {
      id          = "logo-vertical",
      kind        = 'Logo,
      source_path = "assets/branding/ontoref-v.svg",
      variants    = ["assets/branding/ontoref-v-static.svg", "assets/branding/ontoref-dark-v.svg", "assets/branding/ontoref-mono-black-v.svg", "assets/branding/ontoref-mono-white-v.svg"],
      description = "Vertical logo — animated SVG with static and dark/mono variants.",
    },
    m.make_asset {
      id          = "logo-icon",
      kind        = 'Icon,
      source_path = "assets/branding/ontoref-icon.svg",
      variants    = ["assets/branding/ontoref-icon-static.svg"],
      description = "Square icon mark — animated and static variants.",
    },
    m.make_asset {
      id          = "logo-text",
      kind        = 'Logo,
      source_path = "assets/branding/ontoref-text.svg",
      description = "Logotype text-only mark.",
    },
    m.make_asset {
      id          = "logo-pakua",
      kind        = 'Logo,
      source_path = "assets/branding/pakua/ontoref_pakua_img.svg",
      variants    = ["assets/branding/pakua/ontoref-pakua-dark-v.svg"],
      description = "Pakua symbol variant of the logo.",
    },
    m.make_asset {
      id          = "diagram-architecture",
      kind        = 'Diagram,
      source_path = "assets/architecture.svg",
      description = "Current architecture diagram showing the three-layer protocol model.",
    },
    m.make_asset {
      id          = "screenshot-graph-dark",
      kind        = 'Screenshot,
      source_path = "assets/ontoref_graph_view-dark.png",
      variants    = ["assets/ontoref_graph_view-light.png"],
      description = "Graph view UI screenshot — dark and light variants.",
    },
    m.make_asset {
      id          = "presentation-deck",
      kind        = 'Document,
      source_path = "assets/presentation/slides.md",
      description = "Slidev presentation deck for ontoref protocol introduction.",
    },
  ],

  templates = [
    m.make_template {
      id          = "project-full-adoption-prompt",
      kind        = 'AgentPrompt,
      source_path = "reflection/templates/project-full-adoption-prompt.md",
      description = "Master adoption prompt for new and existing projects: protocol infrastructure, ontology enrichment, config surface (nickel-validated-overrides + ConfigFields derive), API surface (#[onto_api]), and manifest self-interrogation (capabilities/requirements/critical_deps). Orchestrates all other templates.",
    },
    m.make_template {
      id          = "update-ontology-prompt",
      kind        = 'AgentPrompt,
      source_path = "reflection/templates/update-ontology-prompt.md",
      description = "8-phase ontology enrichment prompt: core.ncl nodes/edges, state.ncl dimension transitions, manifest assets, connections, ADR check_hint migration. Called from Phase 2 of project-full-adoption-prompt.",
    },
    m.make_template {
      id          = "manifest-self-interrogation-prompt",
      kind        = 'AgentPrompt,
      source_path = "reflection/templates/manifest-self-interrogation-prompt.md",
      description = "Focused prompt for populating capabilities[], requirements[], and critical_deps[] in manifest.ncl. Called from Phase 5 of project-full-adoption-prompt.",
    },
    m.make_template {
      id          = "vendor-frontend-assets-prompt",
      kind        = 'AgentPrompt,
      source_path = "reflection/templates/vendor-frontend-assets-prompt.md",
      description = "Guide for vendoring frontend JS dependencies locally: directory layout (assets/vendor/), just recipe structure (assets.just with pinned version variables), Tera template integration, CDN asset verification steps, and agent execution checklist. Reusable across any ontoref-protocol project with a static-file-serving daemon.",
    },
  ],

  consumption_modes = [
    m.make_consumption_mode {
      consumer    = 'Developer,
      needs       = ['OntologyExport],
      audit_level = 'Standard,
      description = "Clones repo, runs ./ontoref, imports Nushell modules. Uses reflection tooling to manage project self-description.",
    },
    m.make_consumption_mode {
      consumer    = 'Agent,
      needs       = ['OntologyExport, 'JsonSchema],
      audit_level = 'Quick,
      description = "Reads .ontology/core.ncl via nickel export. Queries nodes, edges, and ADRs to understand project constraints before acting.",
    },
  ],

  config_surface = m.make_config_surface {
    config_root    = ".ontoref",
    entry_point    = "config.ncl",
    kind           = 'SingleFile,
    contracts_path = ".ontoref",

    sections = [
      m.make_config_section {
        id          = "nickel_import_paths",
        file        = "config.ncl",
        description = "Ordered list of directories added to NICKEL_IMPORT_PATH when invoking nickel.",
        rationale   = "Ontoref resolves ontology schemas, ADRs, and reflection schemas through this path list. Order matters: earlier entries shadow later ones.",
        mutable     = true,
        consumers   = [
          m.make_config_consumer {
            id     = "env",
            kind   = 'NuScript,
            ref    = "reflection/modules/env.nu",
            fields = ["nickel_import_paths"],
          },
          m.make_config_consumer {
            id     = "daemon-main",
            kind   = 'RustStruct,
            ref    = "crates/ontoref-daemon/src/main.rs",
            fields = ["nickel_import_paths"],
          },
        ],
      },
      m.make_config_section {
        id          = "ui",
        file        = "config.ncl",
        description = "Daemon HTTP/UI settings: template directory, static assets, TLS certs, logo override.",
        rationale   = "Allows dev-mode templates to be served from the source tree instead of the installed path, and TLS to be toggled without recompiling.",
        mutable     = true,
        consumers   = [
          m.make_config_consumer {
            id     = "daemon-main",
            kind   = 'RustStruct,
            ref    = "crates/ontoref-daemon/src/main.rs",
            fields = ["templates_dir", "public_dir", "tls_cert", "tls_key", "logo"],
          },
        ],
      },
      m.make_config_section {
        id          = "log",
        file        = "config.ncl",
        contract    = "contracts.ncl → LogConfig",
        description = "Daemon structured logging: level, rotation policy, archive and retention.",
        rationale   = "Daily rotation with 7-file retention keeps log footprint bounded; separate archive path allows cold storage without disrupting active logs.",
        mutable     = true,
        consumers   = [
          m.make_config_consumer {
            id     = "daemon-main",
            kind   = 'RustStruct,
            ref    = "crates/ontoref-daemon/src/main.rs",
            fields = ["level", "path", "rotation", "compress", "archive", "max_files"],
          },
        ],
      },
      m.make_config_section {
        id          = "mode_run",
        file        = "config.ncl",
        description = "ACL rules for which actors may execute which reflection modes.",
        rationale   = "Agent and CI actors need unrestricted mode access; human actors are gated per mode to prevent accidental destructive operations.",
        mutable     = true,
        consumers   = [
          m.make_config_consumer {
            id     = "daemon-main",
            kind   = 'RustStruct,
            ref    = "crates/ontoref-daemon/src/main.rs",
            fields = ["rules"],
          },
        ],
      },
      m.make_config_section {
        id          = "nats_events",
        file        = "config.ncl",
        description = "NATS event bus integration: enabled flag, server URL, emit/subscribe topic lists, handlers directory.",
        rationale   = "Disabled by default to keep ontoref zero-dependency for projects without a NATS deployment. Feature-gated in the daemon crate.",
        mutable     = true,
        consumers   = [
          m.make_config_consumer {
            id     = "daemon-main",
            kind   = 'RustStruct,
            ref    = "crates/ontoref-daemon/src/main.rs",
            fields = ["enabled", "url", "emit", "subscribe", "handlers_dir"],
          },
        ],
      },
      m.make_config_section {
        id          = "actor_init",
        file        = "config.ncl",
        description = "Per-actor bootstrap: which reflection mode to auto-run on first invocation.",
        rationale   = "Agents always auto-run 'describe capabilities' so they orient themselves before acting; developers and CI start clean.",
        mutable     = true,
        consumers   = [
          m.make_config_consumer {
            id     = "env",
            kind   = 'NuScript,
            ref    = "reflection/modules/env.nu",
            fields = ["actor", "mode", "auto_run"],
          },
        ],
      },
      m.make_config_section {
        id          = "quick_actions",
        file        = "config.ncl",
        description = "Shortcut actions surfaced in the daemon UI dashboard: id, label, icon, category, mode, allowed actors.",
        rationale   = "Frequently used modes (generate-mdbook, sync-ontology, coder-workflow) promoted to one-click access without navigating the modes list.",
        mutable     = true,
        consumers   = [
          m.make_config_consumer {
            id     = "daemon-ui",
            kind   = 'RustStruct,
            ref    = "crates/ontoref-daemon/src/ui/handlers.rs",
            fields = ["id", "label", "icon", "category", "mode", "actors"],
          },
        ],
      },
      m.make_config_section {
        id          = "daemon",
        file        = "config.ncl",
        contract    = "contracts.ncl → DaemonConfig",
        description = "Runtime overrides for daemon CLI defaults: port, timeouts, sweep intervals, notification limits.",
        rationale   = "All fields are optional — absent fields use the daemon's built-in CLI defaults. Set only when the defaults need project-specific tuning without rebuilding the binary.",
        mutable     = true,
        consumers   = [
          m.make_config_consumer {
            id     = "daemon-config",
            kind   = 'RustStruct,
            ref    = "crates/ontoref-daemon/src/config.rs → DaemonRuntimeConfig",
            fields = ["port", "idle_timeout", "invalidation_interval", "actor_sweep_interval", "actor_stale_timeout", "max_notifications", "notification_ack_required"],
          },
        ],
      },
    ],
  },

  capabilities = [
    m.make_capability {
      id        = "protocol-spec",
      name      = "Protocol Specification",
      summary   = "Typed NCL schemas for nodes, edges, ADRs, state, gates, and manifests.",
      rationale = "Projects need a contract layer to describe what they are — not just code comments. NCL provides typed, queryable, git-versionable schemas with contract enforcement at export time. Alternatives (TOML/JSON/YAML) lack contracts; Rust-only structs are not adoption-friendly.",
      how       = "ontology/schemas/ defines all type contracts. adrs/adr-schema.ncl defines the ADR lifecycle contract. ontology/defaults/ exposes builders (make_node, make_edge, make_adr) so consumer projects never write raw NCL records. nickel export validates against declared contracts before any JSON reaches Rust or Nushell.",
      artifacts = ["ontology/schemas/", "ontology/defaults/", "adrs/adr-schema.ncl", "adrs/adr-defaults.ncl"],
      nodes     = ["dag-formalized", "protocol-not-runtime", "adr-lifecycle"],
    },
    m.make_capability {
      id        = "daemon-api",
      name      = "Daemon HTTP + MCP Surface",
      summary   = "HTTP UI (11 pages), 29 MCP tools, annotated API catalog, Q&A store, search bookmarks, config surface, per-file versioning.",
      rationale = "Agents and developers need a queryable interface to ontology state without spawning nickel on every request. The NCL export cache reduces full-sync from ~2m42s to <30s. 29 MCP tools give agents structured access to every capability without screen-scraping the CLI. ADR-002 records the architectural decision to extract the daemon; ADR-007 covers the #[onto_api] catalog pattern; ADR-008 covers the config override layer.",
      how       = "crates/ontoref-daemon uses axum for HTTP. #[onto_api(...)] proc-macro + inventory::submit! registers every route at link time; GET /api/catalog aggregates via inventory::collect!. NclCache (DashMap<PathBuf, CachedExport>) keyed on path + mtime. File watcher (notify) triggers cache invalidation and drift detection after 15s debounce. MCP over stdio and streamable-HTTP.",
      artifacts = [
        "crates/ontoref-daemon/",
        "GET /api/catalog",
        "GET /projects/{slug}/ontology",
        "GET /projects/{slug}/config/coherence",
        "MCP: ontoref_guides, ontoref_api_catalog, ontoref_validate, ontoref_impact",
      ],
      adrs  = ["adr-002", "adr-004", "adr-007", "adr-008"],
      nodes = ["ontoref-daemon", "api-catalog-surface", "config-surface"],
    },
    m.make_capability {
      id        = "reflection-modes",
      name      = "Reflection Mode Executor",
      summary   = "NCL DAG workflow engine executing ADR lifecycle, project adoption, content modes, and operational procedures.",
      rationale = "Structured procedures expressed as typed DAGs rather than ad-hoc scripts. Every step has a declared dep graph — the executor validates it before running. Agent-safe: modes are NCL contracts, not imperative scripts, so agents can read and reason about them before execution.",
      how       = "crates/ontoref-reflection loads a mode NCL file, validates the DAG contract (no cycles, declared deps exist), then executes steps via Nushell subprocesses. reflection/modules/ contains 16 Nushell modules that implement the actual step logic. reflection/modes/ contains the typed NCL DAG definitions.",
      artifacts = ["reflection/modes/", "reflection/modules/", "crates/ontoref-reflection/"],
      nodes    = ["reflection-modes", "adopt-ontoref-tooling"],
    },
  ],

  requirements = [
    m.make_requirement {
      id        = "nushell",
      name      = "Nushell",
      env       = 'Both,
      kind      = 'Tool,
      version   = "0.110.0",
      required  = true,
      impact    = "All reflection modes and the ./ontoref dispatcher are Nushell scripts. Without Nu nothing executes — no mode runs, no describe subcommands, no sync.",
      provision = "https://www.nushell.sh/ — cargo install nu or OS package manager.",
    },
    m.make_requirement {
      id        = "nickel",
      name      = "Nickel",
      env       = 'Both,
      kind      = 'Tool,
      version   = "",
      required  = true,
      impact    = "All schema evaluation, ADR parsing, config export blocked. Daemon NCL cache inoperable. Config surface mutation cannot validate overrides.",
      provision = "https://nickel-lang.org/ — cargo install nickel-lang-cli or nix flake.",
    },
    m.make_requirement {
      id        = "rust-nightly",
      name      = "Rust nightly toolchain",
      env       = 'Development,
      kind      = 'Tool,
      version   = "",
      required  = true,
      impact    = "cargo +nightly fmt fails — pre-commit hook blocks all commits.",
      provision = "rustup toolchain install nightly",
    },
    m.make_requirement {
      id        = "surrealdb",
      name      = "SurrealDB",
      env       = 'Production,
      kind      = 'Service,
      version   = "",
      required  = false,
      impact    = "Daemon db feature disabled; ontology not projected into DB. Daemon still works via --no-default-features for local-only use.",
      provision = "https://surrealdb.com/ — binary or container. Feature-gated: cargo build -p ontoref-daemon --no-default-features omits it.",
    },
    m.make_requirement {
      id        = "stratumiops",
      name      = "stratumiops repo checkout",
      env       = 'Development,
      kind      = 'Infrastructure,
      version   = "",
      required  = false,
      impact    = "ontoref-daemon (db/nats features) and ontoref-reflection (nats feature) cannot build. Build with --no-default-features to work without it.",
      provision = "git clone at ../../../stratumiops relative to this repo root.",
    },
  ],

  critical_deps = [
    m.make_critical_dep {
      id             = "nickel-lang",
      name           = "nickel-lang",
      ref            = "crates.io: nickel-lang-core / nickel-lang-cli",
      used_for       = "Schema evaluation, contract enforcement, config export, ADR parsing. Every nickel export call in the daemon cache and in Nushell modules.",
      failure_impact = "Total loss of typed schema layer. All NCL export operations fail. Daemon cache inoperable. Config override mutation cannot validate before committing. describe guides and ontoref_guides MCP tool return empty data.",
      mitigation     = "Pin to a specific Nickel release in PATH. Nickel is a subprocess dep (never linked into Rust binary) — breakage manifests at runtime as nickel export exit code != 0, which all callers handle gracefully (daemon-export-safe returns null, callers use | default []).",
    },
    m.make_critical_dep {
      id             = "inventory",
      name           = "inventory",
      ref            = "crates.io: inventory 0.3",
      used_for       = "#[onto_api] HTTP catalog registration and #[derive(ConfigFields)] config coherence registry. Both use inventory::submit! at link time; GET /api/catalog and GET /config/coherence use inventory::iter! at runtime.",
      failure_impact = "GET /api/catalog returns empty. Config coherence endpoint loses Rust struct field data. ontoref_api_catalog MCP tool blind. API version change would require updating both onto_api and ConfigFields derive macros simultaneously.",
      mitigation     = "inventory uses linker sections (zero runtime overhead). Version is pinned in Cargo.toml. ontoref-derive and ontoref-ontology both declare it — version must stay in sync.",
    },
    m.make_critical_dep {
      id             = "axum",
      name           = "axum",
      ref            = "crates.io: axum",
      used_for       = "All 11 UI pages and REST API endpoints in ontoref-daemon. Router, handlers, extractors, middleware.",
      failure_impact = "Daemon does not compile. Full HTTP surface down: UI, REST API, MCP over HTTP, session management, config surface endpoints.",
      mitigation     = "ontoref-ontology and the ./ontoref CLI are axum-free. Reflection modes, ADR tooling, and describe subcommands continue working without the daemon.",
    },
  ],

  layers = [
    m.make_layer {
      id          = "protocol",
      paths       = ["ontology/", "adrs/", "reflection/schemas/"],
      committed   = true,
      description = "Protocol specification: Nickel schemas, ADR tooling, and reflection schemas. The contract layer that projects implement.",
    },
    m.make_layer {
      id          = "tooling",
      paths       = ["reflection/", "install/", "nats/", "templates/", "ontoref"],
      committed   = true,
      description = "Operational tooling: Nushell modules, modes, forms, dispatcher, bash entry point, install scripts, default config resources, and NATS stream topology.",
    },
    m.make_layer {
      id          = "crates",
      paths       = ["crates/", "Cargo.toml"],
      committed   = true,
      description = "Rust implementation: ontoref-ontology (load/query .ontology/ as typed structs) and ontoref-reflection (execute reflection modes against project state).",
    },
    m.make_layer {
      id          = "self-description",
      paths       = [".ontology/"],
      committed   = true,
      description = "Ontoref consuming ontoref: the project's own ontology, state, gate, and manifest.",
    },
    m.make_layer {
      id          = "process",
      paths       = [".coder/"],
      committed   = false,
      description = "Session artifacts: plans, investigations, summaries. Process memory for actors.",
    },
  ],
}
