provisioning/.ontology/state.ncl
2026-05-12 02:40:14 +01:00

249 lines
17 KiB
Text

let d = import "ontology/defaults/state.ncl" in
{
dimensions = [
d.make_dimension {
id = "orchestrator-maturity",
name = "Orchestrator Maturity",
description = "Orchestrator service readiness — from functional prototype to production-grade task execution engine.",
current_state = "functional",
desired_state = "production",
horizon = 'Months,
states = [],
transitions = [
d.make_transition {
from = "functional",
to = "production",
condition = "All 6 SOLID enforcement layers passing, NATS streams stable, task state machine handles all error paths with rollback, formula DAG execution covers all taskserv dependency combinations.",
catalyst = "Control Center JWT auth and Cedar policy evaluation wired end-to-end; solo mode auth bypass verified against ADR-015 constraints.",
blocker = "Cedar policy definitions stored in SurrealDB not finalized; WebSocket task status streaming not connected to NATS push consumers.",
horizon = 'Months,
},
],
},
d.make_dimension {
id = "cli-maturity",
name = "CLI and Nushell Library Maturity",
description = "CLI v3 and core/nulib/ stability — the primary user interface and Nushell command library for all platform operations.",
current_state = "stable-v3",
desired_state = "stable-v3",
horizon = 'Continuous,
states = [],
transitions = [],
},
d.make_dimension {
id = "control-center-maturity",
name = "Control Center Maturity",
description = "Control Center service readiness — from bootstrapped to operational with live auth, Cedar policies, and WebSocket streaming.",
current_state = "bootstrapped",
desired_state = "operational",
horizon = 'Months,
states = [],
transitions = [
d.make_transition {
from = "bootstrapped",
to = "operational",
condition = "JWT auth middleware active in non-solo mode, Cedar policies loaded from SurrealDB and evaluated on all protected routes, WebSocket task status streaming connected to NATS push consumers.",
catalyst = "Solo mode (ADR-015) fully tested end-to-end as staging environment for multi-user auth path.",
blocker = "Cedar policy definitions not finalized; WebSocket streaming not connected to NATS; IaC detection and rules handlers partially commented out in router.",
horizon = 'Months,
},
],
},
d.make_dimension {
id = "schema-coverage",
name = "Schema Coverage",
description = "Nickel schema coverage across all configuration surfaces — from partial to comprehensive.",
current_state = "partial",
desired_state = "comprehensive",
horizon = 'Months,
states = [],
transitions = [
d.make_transition {
from = "partial",
to = "comprehensive",
condition = "All provider configs, workspace configs, platform service configs, extension metadata (taskserv dependency declarations), and TypeDialog forms covered by typed Nickel schemas. Extension metadata.ncl files cover all 10 built-in taskservs.",
catalyst = "Extension ontology evolution (ADR-019 AI surface) requiring schema for RAG indexing.",
blocker = "Some extensions still use raw TOML or KCL remnants for metadata. TypeDialog schemas cover workspace config but not all platform service configs.",
horizon = 'Months,
},
],
},
d.make_dimension {
id = "kcl-migration",
name = "KCL Migration",
description = "Migration from KCL to Nickel — completed, continuous maintenance only.",
current_state = "completed",
desired_state = "completed",
horizon = 'Continuous,
states = [],
transitions = [],
},
d.make_dimension {
id = "smart-interface-migration",
name = "Smart Interface Migration",
description = "Migration of all 37 Nushell operations from direct legacy dispatch to the three-tier fallback chain (HTTP daemon → provisioning-tool → Nushell closure). Infrastructure complete; operation wiring is the remaining work.",
current_state = "bootstrapped",
desired_state = "migrated",
horizon = 'Months,
states = [],
transitions = [
d.make_transition {
from = "bootstrapped",
to = "migrated",
condition = "All 37 operations call tool-call / tool-list with a real Nushell legacy closure; G3 contract test passes for each migrated operation; no handler calls the orchestrator or provider APIs directly from nulib without going through the Registry.",
catalyst = "G3 contract test gates each migration — an operation can only retire its tier-3 closure after G3 passes for it. Daemon install via `just daemon install` makes tier-1 available on developer machines.",
blocker = "36 operations still dispatch via Nushell legacy directly; only workspace_list is wired to the fallback chain. Migration is per-operation and non-breaking.",
horizon = 'Months,
},
],
},
d.make_dimension {
id = "extension-ecosystem-maturity",
name = "Internal Extension Mechanism Maturity",
description = "Maturity of the internal extension mechanism (taskservs and providers) — from basic metadata contracts to capability-aware DAG resolution to ontology-aware impact analysis. Distinct from federated integration modes (ADR-042) which governs cross-project integration via OCI domain artifacts.",
current_state = "capability-aware",
desired_state = "ontology-aware",
horizon = 'Months,
states = [],
transitions = [
d.make_transition {
from = "metadata-contracts",
to = "capability-aware",
condition = "All 10 built-in taskserv metadata.ncl files migrated with provides/requires/conflicts_with fields. provisioning-dag-integrity reflection mode runs clean. CLI `provisioning extensions capabilities` outputs correct capability table.",
catalyst = "Three-layer DAG architecture (ADR-016) requiring typed capability declarations for formula dependency resolution.",
blocker = "Completed — B2 (schema extension) and B3 (metadata migration) done in DAG architecture session.",
horizon = 'Continuous,
},
d.make_transition {
from = "capability-aware",
to = "ontology-aware",
condition = "Extension metadata.ncl can optionally declare ontology node IDs; orchestrator resolves extension DAG against platform ontology for impact analysis; CLI reports which ontology nodes are affected by a given workspace execution.",
catalyst = "AI RAG surface (ADR-019) requiring extension ontology data for schema-aware config generation.",
blocker = "Ontology node schema not yet added to metadata.ncl contract; no tooling to validate ontology references in extension metadata.",
horizon = 'Months,
},
],
},
d.make_dimension {
id = "ops-contract-evolution",
name = "Ops Contract Evolution (ADR-037)",
description = "Evolution of the dual-mode ops contract — from architectural decision to implemented crates to production deployment with multi-emitter coordination proven under load.",
current_state = "designed",
desired_state = "production",
horizon = 'Months,
states = [],
transitions = [
d.make_transition {
from = "designed",
to = "implemented",
condition = "ops-keeper crate (keeper-daemon + keeper-cli binaries) compiles and passes unit tests; ops-controller crate subscribes to OPS_CMD JetStream stream and applies ops idempotently with SurrealDB persistence of in-flight state; schemas/lib/ops_contract.ncl + keeper_policy.ncl validated; NATS JetStream streams OPS_PENDING/OPS_CMD/OPS_AUDIT created with correct retention.",
catalyst = "ADR-037 accepted; design discussion produced 23 implementation tasks with explicit per-layer (domain/project/workspace) impact mapping.",
blocker = "Implementation not yet started — designed but no crates exist. Ordered prerequisite: schemas first, then ops-keeper crate, then ops-controller crate, then NATS config.",
horizon = 'Months,
},
d.make_transition {
from = "implemented",
to = "production",
condition = "VM-ops workspace deployed with keeper-daemon running; libre-wuji ops-controller deployed with single-replica WorkQueue consumer; daoshi-CI Woodpecker pipelines emit ops via buildkit-launcher publish step; multi-emitter conflict scenario verified in staging (two emitters, second receives 409); operator-only mode tested via switch_to_operator_only playbook; pending queue depth and oldest-message-age observable in Prometheus.",
catalyst = "ops contract is gating for ADR-039 build infrastructure (build pipeline emits deploy ops via ops.pending) — production readiness blocks the deploy-from-CI path.",
blocker = "Implementation phase not complete; observability stack not deployed in libre-wuji; VM-ops workspace not yet provisioned.",
horizon = 'Months,
},
],
},
d.make_dimension {
id = "integration-modes-maturity",
name = "Federated Integration Modes Maturity (ADR-042)",
description = "Maturity of the federated integration modes protocol — from schema definitions and OCI domain artifacts to assembled context delivery to fully-wired invoke pipeline.",
current_state = "schema-defined",
desired_state = "assembled",
horizon = 'Months,
states = [],
transitions = [
d.make_transition {
from = "schema-defined",
to = "assembled",
condition = "context-assembler crate reads cabling.ncl + SOPS secrets + component outputs and produces a typed SecretDeliveryContext JSON envelope; `prvng integration invoke <mode-id>` pipes the assembled context to the mode binary stdin; lian-build provisioning mode receives the envelope and emits a valid ResultEnvelope; `prvng integration subscribe <mode-id>` scaffolds a cabling file skeleton in infra/<ws>/integrations/.",
catalyst = "context-assembler Nushell module complete (platform/integrations/context_assembler.nu); `prvng integration invoke/subscribe/validate` all wired; 7 domain artifacts in zot (secret-delivery, event-emission, result-reporting, compute-provisioning, registry-access, cache-management, backup-policy-binding 0.1.0); all signed with cosign; lian-build + cloudatasave modes declared with domain locks + libre-wuji cablings.",
blocker = "lian-build binary does not yet read stdin context — end-to-end live invoke not yet proven.",
horizon = 'Months,
},
d.make_transition {
from = "assembled",
to = "production",
condition = "cloudatasave integration mode declared with its own lock + cabling; cosign signing applied to all domain artifacts in zot; zot trust policy rejects unsigned domain artifacts; NATS event-emission domain wired to production JetStream subjects in each workspace cabling.",
catalyst = "cosign signing complete for all 9 artifacts (7 domains + 2 modes) ✓; zot imagetrust extension enabled in configmap ✓; cloudatasave mode + lock + cabling declared ✓; client-side cosign verify in domain-verify + subscribe ✓; key rotation documented in docs/guides/cosign-key-rotation.md ✓; ZOT_ADMIN_PASS in zot.sops.yaml + adminPolicy for regadm + server-side cosign trust key uploaded (HTTP 200) ✓.",
blocker = "NATS event-emission wiring not yet live; lian-build binary stdin implementation external dependency.",
horizon = 'Months,
},
],
},
d.make_dimension {
id = "governance-model-state",
name = "Decentralized Governance Model State (ADR-038)",
description = "Adoption state of Radicle Heartwood as governance and audit substrate across all workspaces.",
current_state = "designed",
desired_state = "active",
horizon = 'Months,
states = [],
transitions = [
d.make_transition {
from = "designed",
to = "bootstrapped",
condition = "Radicle Heartwood seed nodes installed on every operator laptop, on libre-daoshi designated node, on libre-wuji designated node, and on ops-vm; per-operator Radicle identities created; for each workspace, three repos (policy/desired/state) initialized with correct delegation profiles (M-of-N for policy/desired, single ops-controller for state); audit-mirror sidecar deployed in libre-wuji subscribing to ops.audit subjects with jti idempotency check.",
catalyst = "ADR-038 accepted; ops contract (ADR-037) requires the audit ledger to land somewhere durable and decentralized — Radicle is that target.",
blocker = "Implementation not started; Radicle CLI familiarity required across operators; bootstrap playbook not yet written; ops-controller signing keys not yet generated for state repo delegation.",
horizon = 'Months,
},
d.make_transition {
from = "bootstrapped",
to = "active",
condition = "policy-<workspace> patches signed by quorum and deployed in production; keeper-daemon polls policy repo for latest commit and applies declarative matcher; <workspace>-state ledger receiving live audit events from wuji; operator on/off-boarding playbooks tested with delegation patches; cross-replica gossip lag measured and within acceptable bounds (seconds-to-minutes for policy/desired updates).",
catalyst = "First production op signed via the new contract validates the end-to-end path: emitter → pending → keeper signs per policy → ops-controller applies → audit lands in Radicle state repo.",
blocker = "Bootstrap phase incomplete; production deployment requires both ADR-037 (ops) and ADR-038 (governance) implemented and validated together.",
horizon = 'Months,
},
],
},
d.make_dimension {
id = "build-infrastructure-state",
name = "Build Infrastructure State (ADR-039)",
description = "Maturity of ephemeral-runner + S3-backed zot build pattern — from architectural decision to operational golden image v1 to dynamic-sizing production.",
current_state = "designed",
desired_state = "production",
horizon = 'Months,
states = [],
transitions = [
d.make_transition {
from = "designed",
to = "golden-image-v1",
condition = "Initial buildkit-runner-golden image built off-platform (laptop or external CI) and pushed to bootstrap zot; weekly rebuild Woodpecker pipeline defined; orchestrator vm_pool extended with buildkit lifecycle (spawn from golden + cleanup hook); buildkit-launcher crate compiles; .build-spec.ncl schema validated against schemas/lib/build_spec.ncl.",
catalyst = "Vapora and other Rust workloads need a build path; current absence of build infrastructure means manual local builds — gating for production deploys.",
blocker = "Implementation not started; bootstrap golden image must be produced manually first time; zot relocation from libre-daoshi to libre-wuji not yet executed.",
horizon = 'Months,
},
d.make_transition {
from = "golden-image-v1",
to = "production",
condition = "zot deployed in libre-wuji with S3 backend (versioning + cross-region replication); multi-tenant auth configured (daoshi-CI write to /images /cache /sccache /crates; wuji-pods read /images; operators write /crates); BuildKit registry-cache and sccache S3 backend pointing at zot.wuji.local proven on Vapora-class build with measured cold-spawn-to-completion time; OOM auto-retry verified once and bounded; weekly golden image rebuild running on schedule with no manual intervention; cross-provider replication tested via failover drill.",
catalyst = "Production deploys via ops contract (ADR-037) require image artifacts in zot — build infrastructure is on the critical path for the deploy-from-CI flow.",
blocker = "Golden image v1 phase incomplete; zot still in libre-daoshi; observability for build metrics (Prometheus on builder VMs) not deployed.",
horizon = 'Months,
},
],
},
],
}