let m = import "ontology/defaults/manifest.ncl" in m.make_manifest { project = "provisioning", repo_kind = 'Mixed, description = "Multi-crate Rust platform for cloud infrastructure provisioning: typed Nickel schemas validated at the NCL layer, formula DAG execution engine, SOLID-enforced service boundaries, pluggable providers and taskservs, NATS-brokered orchestration, Cedar authorization, and full-architecture solo mode for single-operator deployments.", consumption_modes = [ m.make_consumption_mode { consumer = 'Developer, needs = ['OntologyExport], audit_level = 'Standard, description = "Uses provisioning CLI and workspace definitions to manage infrastructure. Extends via providers and taskservs.", }, m.make_consumption_mode { consumer = 'Agent, needs = ['OntologyExport, 'JsonSchema], audit_level = 'Quick, description = "Reads .ontology/core.ncl to understand constraints and boundaries. Uses CLI and orchestrator APIs for infrastructure operations.", }, ], layers = [ m.make_layer { id = "schemas", paths = ["schemas/"], committed = true, description = "Nickel type schemas for all infrastructure configuration: providers, workspaces, platform services, extensions.", }, m.make_layer { id = "core", paths = ["core/"], committed = true, description = "CLI, libraries, plugins, Nushell scripts — the user-facing surface of provisioning.", }, m.make_layer { id = "platform", paths = ["platform/"], committed = true, description = "Orchestrator, Control Center, Vault, Extension Registry — the control plane services.", }, m.make_layer { id = "catalog", paths = ["catalog/"], committed = true, description = "Providers, taskservs, clusters, components, domain artifacts — IaC building block catalog and federated integration domain contracts.", }, m.make_layer { id = "config", paths = ["config/", "templates/"], committed = true, description = "Default configuration files and infrastructure templates.", }, m.make_layer { id = "self-description", paths = [".ontology/"], committed = true, description = "Provisioning consuming on+re: axioms, tensions, practices, state, gates, ADRs.", }, ], operational_modes = [ m.make_op_mode { id = "dev", visible_layers = ["schemas", "core", "platform", "catalog", "config", "self-description"], description = "Full development view — all layers visible.", }, m.make_op_mode { id = "platform-focus", visible_layers = ["schemas", "platform", "config"], description = "Platform engineering focus — schemas, platform services, and configuration.", }, m.make_op_mode { id = "catalog-focus", visible_layers = ["schemas", "catalog", "config"], description = "Catalog development focus — schemas, providers, taskservs, components, and configuration.", }, ], config_surface = m.make_config_surface { config_root = ".typedialog/provisioning/", entry_point = "config.ncl", kind = 'TypeDialog, contracts_path = ".typedialog/provisioning/schemas", overrides_dir = ".typedialog/provisioning/generated", sections = [ m.make_config_section { id = "provisioning", file = "config.ncl", contract = "schemas/provisioning-config.ncl", description = "Root workspace configuration generated by TypeDialog — project metadata, services, database, deployment target, network, storage, monitoring, security.", rationale = "Consumer projects declare what infrastructure they need via an interactive TypeDialog form. The NCL output is the single source of truth fed to the orchestrator. TypeDialog fragments (database-postgres, deployment-k8s, etc.) ensure only valid combinations are generated.", mutable = true, consumers = [ m.make_config_consumer { id = "orchestrator", kind = 'RustStruct, ref = "provisioning_orchestrator::config::OrchestratorConfig", fields = ["services", "deployment", "database"] }, m.make_config_consumer { id = "configure-nu", kind = 'NuScript, ref = ".typedialog/provisioning/configure.nu" }, m.make_config_consumer { id = "ci-woodpecker", kind = 'CiPipeline, ref = ".woodpecker/ci.yml" }, ], }, m.make_config_section { id = "database", file = "schemas/database.ncl", contract = "schemas/database.ncl", description = "Database type and connection parameters — supports sqlite, postgres, surrealdb, mysql. Generated into the root config via TypeDialog database-* fragments.", rationale = "Database configuration is the most provider-specific section. TypeDialog fragments enforce valid parameter combinations per engine (e.g. journal_mode only valid for SQLite).", mutable = false, consumers = [ m.make_config_consumer { id = "orchestrator", kind = 'RustStruct, ref = "provisioning_orchestrator::config::OrchestratorConfig", fields = ["database"] }, ], }, m.make_config_section { id = "deployment", file = "schemas/deployment.ncl", contract = "schemas/deployment.ncl", description = "Deployment target — docker-compose or kubernetes. Drives which taskservs are activated and which providers are called.", rationale = "Deployment target selection is the primary branching decision in workspace execution. TypeDialog deployment-docker and deployment-k8s fragments capture the full parameter space for each target.", mutable = false, consumers = [ m.make_config_consumer { id = "orchestrator", kind = 'RustStruct, ref = "provisioning_orchestrator::config::OrchestratorConfig", fields = ["deployment"] }, ], }, m.make_config_section { id = "monitoring", file = "schemas/monitoring.ncl", contract = "schemas/monitoring.ncl", description = "Observability configuration — metrics, logging, alerting. Optional; defaults from .typedialog/provisioning/defaults/monitoring-defaults.ncl.", mutable = false, consumers = [ m.make_config_consumer { id = "orchestrator", kind = 'RustStruct, ref = "provisioning_orchestrator::config::OrchestratorConfig", fields = ["monitoring"] }, ], }, ], }, capabilities = [ m.make_capability { id = "formula-dag-execution", name = "Formula DAG Execution Engine", summary = "Typed DAG-based workflow execution with topological parallelism, retry, and rollback.", rationale = "Positional task arrays collapse on dependency ambiguity and lack parallelism signals. Formula nodes declare depends_on, on_error, parallel, max_retries — enabling the orchestrator to derive a topological execution plan without imperative scripting.", how = "Workspace TOML declares Formula nodes; orchestrator's formula.rs converts to DependencyGraph via topological sort; BatchExecutor executes ready nodes in parallel via NATS work queues.", artifacts = ["schemas/lib/formula.ncl", "platform/crates/orchestrator/src/formula.rs", "platform/crates/orchestrator/src/batch.rs"], adrs = ["adr-016-workspace-formula-dag"], nodes = ["formula-dag-execution"], }, m.make_capability { id = "workspace-contract", name = "Typed Workspace Contracts", summary = "Nickel-validated workspace definitions that compose providers, taskservs, and ingredients into infrastructure DAGs.", rationale = "Raw TOML workspace files have no type safety — invalid configs surface as runtime errors. Nickel schemas catch structural errors at write time, before any provider API is called.", how = "CLI validates workspace TOML against schemas/config/workspace_config/ contracts via nickel export before submitting to orchestrator. Orchestrator re-validates on receipt.", artifacts = ["schemas/config/workspace_config/", "core/crates/", "examples/workspaces/"], nodes = ["workspace-contract"], }, m.make_capability { id = "provider-plugin-system", name = "Provider Plugin System", summary = "25-function pluggable interface for infrastructure providers — add a provider without changing the platform.", rationale = "Hardcoded provider logic makes multi-cloud support a fork, not an extension. The provider interface isolates provider specifics behind a stable contract.", how = "Each provider implements the ProviderInterface trait (25 functions). Orchestrator dispatches operations via the interface; provider implementations are loaded from catalog/providers/.", artifacts = ["catalog/providers/", "platform/crates/orchestrator/src/"], nodes = ["provider-abstraction", "taskserv-pattern"], }, m.make_capability { id = "solo-mode-deployment", name = "Solo Mode — Full-Architecture Single-Operator Deployment", summary = "Run the full platform on a laptop: embedded SurrealDB (RocksDB), child NATS server, solo_auth_middleware replacing JWT+Cedar.", rationale = "Simplified mono-binary for solo creates two divergent code paths. Solo mode keeps the same binaries and NATS subjects — scripts written for solo work in multi-user unchanged.", how = "--mode solo flag activates solo_auth_middleware (auto-injects admin session), SurrealDB switches to kv-surrealkv (RocksDB), NATS starts as child process. service-manager.nu orchestrates startup.", artifacts = ["platform/crates/control-center/src/middleware/", "platform/crates/orchestrator/src/nats.rs"], adrs = ["adr-015-solo-mode-architecture"], nodes = ["solo-mode"], }, m.make_capability { id = "nats-brokered-orchestration", name = "NATS JetStream Orchestration", summary = "All inter-service task dispatch via NATS JetStream work queues with at-least-once delivery and state machine tracking.", rationale = "HTTP synchronous task dispatch couples orchestrator latency to provider API latency. NATS decouples dispatch from execution, enables fan-out to taskserv workers, and provides durable state even if a worker crashes mid-task.", how = "Orchestrator publishes tasks to JetStream streams per provider type. Taskserv workers consume via pull consumers with ack/nack. Task state machine tracks pending → running → completed/failed in SurrealDB.", artifacts = ["platform/crates/orchestrator/src/workflow.rs", "platform/crates/platform-nats/"], adrs = ["adr-012-nats-event-broker"], nodes = ["platform-dispatch"], }, m.make_capability { id = "nickel-config-hierarchy", name = "Nickel-Validated Configuration Hierarchy", summary = "5-level config precedence with NCL contracts: runtime args > env vars > user config > infra config > system defaults.", rationale = "Ad-hoc env var overrides without schema validation cause silent misconfiguration. The Nickel merge layer validates every override level against the same contracts before deserialization.", how = "platform-config's ConfigLoader trait runs collect_env_overrides() → nickel export → serde::Deserialize. Override files are written to config/*.overrides.ncl and merged via & at the entry point.", artifacts = ["platform/crates/platform-config/src/format.rs", "schemas/config/"], adrs = ["adr-013-surrealdb-global-store"], nodes = ["config-hierarchy", "type-safety-nickel"], }, m.make_capability { id = "solid-enforcement", name = "SOLID Boundary Enforcement", summary = "6 compile-time and runtime SOLID boundaries: orchestrator-only provider calls, control-center-only auth, vault-only secrets.", rationale = "Without enforced boundaries, authorization and secrets logic diffuses across services. ADR-014 documents 6 hard boundaries with 6 enforcement layers (compile-time, dev-time, pre-commit, CI, runtime, audit).", how = "Clippy rules, grep CI checks, Cedar policies, and runtime middleware enforce the boundaries. solo_auth_middleware is the only documented auth bypass and requires --mode solo.", artifacts = ["platform/crates/orchestrator/", "platform/crates/control-center/", "platform/secretumvault/"], adrs = ["adr-014-solid-enforcement"], nodes = ["solid-boundaries"], }, ], requirements = [ m.make_requirement { id = "rust", name = "Rust toolchain", kind = 'Tool, env = 'Development, version = "1.75+", impact = "Platform services and CLI cannot compile.", provision = "rustup toolchain install stable", }, m.make_requirement { id = "nushell", name = "Nushell", kind = 'Tool, env = 'Both, version = "0.110+", impact = "Reflection modes, service-manager.nu, and CLI scripts cannot execute.", provision = "cargo install nu", }, m.make_requirement { id = "nickel", name = "Nickel", kind = 'Tool, env = 'Both, version = "1.15+", impact = "Schema validation and config export cannot run. platform-config's ConfigLoader cannot operate.", provision = "cargo install nickel-lang-cli", }, m.make_requirement { id = "surrealdb", name = "SurrealDB", kind = 'Service, env = 'Production, version = "2.3+", required = false, impact = "Multi-user deployments cannot persist task state, Cedar policies, or audit logs. Solo mode uses embedded RocksDB.", provision = "Deploy surrealdb container or binary; solo mode uses kv-surrealkv.", }, m.make_requirement { id = "nats-server", name = "NATS Server (JetStream)", kind = 'Service, env = 'Both, impact = "Orchestrator cannot dispatch tasks; taskserv workers cannot receive work items. Solo mode manages nats-server as a child process.", provision = "Install nats-server in PATH for solo mode; deploy NATS cluster for multi-user.", }, m.make_requirement { id = "cedar-policy", name = "Cedar policy engine", kind = 'Infrastructure, env = 'Production, required = false, impact = "Cedar-based authorization unavailable in multi-user mode. Solo mode uses solo_auth_middleware which bypasses Cedar entirely.", provision = "Policies stored in SurrealDB; loaded by control-center at startup.", }, ], critical_deps = [ m.make_critical_dep { id = "surrealdb-crate", name = "SurrealDB client crate", ref = "surrealdb@3", used_for = "Task state machine persistence, Cedar policy storage, audit log, workspace history.", failure_impact = "All stateful operations (task tracking, policy evaluation, audit) stop. Solo mode continues via kv-surrealkv but loses SurrealDB WS protocol.", mitigation = "Feature-gated: --no-default-features disables SurrealDB for dev builds. Solo mode uses embedded kv-surrealkv (RocksDB).", }, m.make_critical_dep { id = "async-nats", name = "async-nats", ref = "async-nats@0.46", used_for = "All inter-service task dispatch, NATS JetStream work queues, taskserv worker consumers.", failure_impact = "Orchestrator cannot dispatch workflows; taskserv workers go idle. Solo mode manages nats-server as child — child crash is fatal.", mitigation = "Feature-gated via platform-nats crate. Solo mode restarts nats-server on SIGTERM.", }, m.make_critical_dep { id = "cedar-policy-crate", name = "cedar-policy", ref = "cedar-policy@4.8", used_for = "Authorization decisions in control-center: policy evaluation, RBAC, resource-level access control.", failure_impact = "All authorization decisions in multi-user mode fail closed. Solo mode unaffected (solo_auth_middleware bypasses Cedar).", mitigation = "Compile-time link; no runtime loading. cedar-policy is the Cedar Reference Implementation — stable API surface.", }, m.make_critical_dep { id = "secretumvault", name = "secretumvault", ref = "secretumvault (local path ../../../Development/secretumvault)", used_for = "Secrets management: age key management, Shamir threshold unsealing, secret storage for provider credentials.", failure_impact = "Vault service cannot start; provider credential injection fails. All infrastructure operations that require provider API keys stop.", mitigation = "Local path dependency — pinned to checkout. Solo mode uses filesystem backend (age key).", }, m.make_critical_dep { id = "axum", name = "axum", ref = "axum@0.8", used_for = "HTTP API layer for orchestrator, control-center, extension-registry, ai-service, mcp-server.", failure_impact = "All HTTP API surfaces become unavailable. CLI falls back to NATS direct where supported.", mitigation = "axum@0.8 is maintained by the Tokio project; API stability is high.", }, ], domain_provides = { id = "provisioning-platform", name = "Provisioning Platform", schema_path = "reflection/schemas/", impl_repo_kind = "DevWorkspace", kind = 'Implicit, description = "Workspace infrastructure contracts: cluster topology, state dimensions, gate membranes, and operational modes for DevWorkspace projects.", }, registry_provides = m.make_registry_provides { participant = "provisioning", registries = m.make_registries_config { default = "primary", registries = [ m.make_registry_entry { id = "primary", endpoint = "reg.librecloud.online", role = 'primary, tls = true, namespaces = { own = ["domains/provisioning/", "modes/provisioning/"], prefixes = ["domains/provisioning/", "modes/provisioning/"], }, }, ], }, }, level = { index = 'Domain, name = "provisioning-domain", parent = "ontoref-base", }, }