6.9 KiB
Platform Changelog
[Unreleased]
Added
ops control plane (crates/ops-keeper, crates/ops-controller)
New two-component ops control plane implementing secure, auditable operation dispatch.
ops-keeper — policy gate before any operation reaches the orchestrator:
- Glob-based
PolicyDefmatching onop_type,image_patterns,target_patterns Signerissues compact Ed25519 JWTs (OpsClaims) on policy approval- NATS JetStream pull consumer on
ops.pending.* AuditEventemission toops.audit.*on every terminal decision
ops-controller — durable executor with at-least-once delivery:
- Verifies keeper-signed JWT before dispatching to orchestrator HTTP API
- SurrealDB idempotency store;
reconcile_pendingreconciles stale ops on startup - Structured
AckResult(Ack / Nak / Term) per JetStream semantics - Emits audit events to
ops.audit.*on every terminal outcome
ADR: ADR-038 (ops control plane design)
audit-mirror (crates/audit-mirror)
Sidecar that consumes ops.audit.* and creates a signed git commit per event in a local Radicle repository, then announces the repo. JTI deduplication prevents double-commits on consumer redelivery.
ADR: ADR-038
contract-tests (crates/contract-tests)
G3 contract test suite verifying semantic equivalence across three tiers:
- Tier A: direct registry invocation (reference baseline)
- Tier B: axum HTTP daemon on ephemeral port
- Tier C: in-process MCP
handle_request
Normaliser strips volatile fields; JSON schema validates every tier output against listing_output_schema. Regression guard for CLI↔HTTP↔MCP drift.
control-center: NATS→WebSocket bridge (src/handlers/nats_bridge.rs)
Eliminates long-polling between control-center UI and orchestrator. Durable JetStream consumer cc-task-status-bridge subscribes to TASKS stream and re-broadcasts each TaskStatusPayload to all connected WebSocket clients via WebSocketManager.
API catalog endpoints (crates/ai-service, crates/control-center)
GET /api-catalog added to ai-service and control-center. Each handler uses inventory::iter::<ApiRouteEntry>() to emit a sorted JSON catalog of all registered routes — self-describing API surface without a separate OpenAPI toolchain.
SOLID boundary pre-commit check (.pre-commit-hooks/solid-boundary-check.sh)
Shell hook enforced in .pre-commit-config.yaml. Fails the commit if a crate imports across declared SOLID layer boundaries, keeping dependency direction consistent before code reaches CI.
Removed / Lifted
crates/backup-manager— lifted tocloudatasave(LibreCloud/cloudDataSave). ADR-041.crates/buildkit-launcher— lifted tolian-build. ADR-040.crates/daemon—Cargo.tomlremoved; binary consolidated intoprovisioning-daemon.prov-ecosystem/crates/nu-daemon/daemon-cli— excluded from workspace;rustls=0.23.28pin conflicts with surrealdb@3 (^0.23.36). Build standalone withcargo build -p nu-daemonuntilnu-commandrelaxes the pin.
[3.6.0] — 2026-04-17
Added
ncl-sync daemon (crates/ncl-sync/)
New Rust daemon that eliminates nickel export latency from CLI commands by pre-compiling NCL files and maintaining a shared cache.
- File watching:
notifywatcher on workspace NCL directories; re-exports automatically on file change - Warm-up: on
prvng platform start, scans all NCL files in the workspace and exports stale entries concurrently (configurable concurrency) - Shared cache:
~/.cache/provisioning/config-cache/— same directory and key strategy asnu_plugin_nickel - Content-addressed keys:
SHA256(file_content + sorted_import_paths + format)— zero coordination overhead between daemon and plugin - Sync requests: Nu processes write
.sync-<pid>.jsonsidecars after mutations; daemon drains them within 500 ms - CLI subcommands:
daemon,warm,invalidate,key,stats - Config-driven via
platform-config:platform/config/ncl-sync.ncl— idle timeout, concurrency, poll interval, extra import paths - No platform dependencies: intentionally avoids NATS, SurrealDB, and orchestrator to prevent bootstrap circularity
Platform lifecycle integration
prvng platform startnow launchesncl-sync daemon(viancl-sync-startinservice-manager.nu)prvng platform stopstops ncl-sync (via PID file)prvng platform statusshows ncl-sync running state
Nu cache layer
lib_provisioning/config/cache/core.nu: implementedcache-lookup,cache-write,write-sync-request(previously no-ops)lib_provisioning/config/cache/nickel.nu: implementedlookup-nickel-cache,derive-ncl-cache-key,request-ncl-sync
nickel_processor wrappers
New lib_provisioning/utils/nickel_processor.nu functions:
ncl-eval: drop-in for^nickel export ... | from json— checks plugin cache, propagates error on failurencl-eval-soft: soft-failure variant with configurable fallback value
nu_plugin_nickel updates
nickel-evalandnickel-exportnow accept--import-path LISTflag (-I)- New command
nickel-cache-key: prints the cache key for a file (parity testing) - Cache key derivation updated to
SHA256(file_content + sorted_import_paths + format)— aligned with ncl-sync - Cache key now includes import paths: same file with different import paths produces different cache entries
Hot-path migration (C1)
Replaced ^nickel export ... | from json with ncl-eval/ncl-eval-soft in the four highest-frequency call sites:
main_provisioning/dispatcher.nu— commands-registry loadmain_provisioning/components.nu— workspace settings exportmain_provisioning/workflow.nu— workflow NCL exportsmain_provisioning/extensions.nu— per-extension metadata
Extended migration (C2 + C3)
Migrated remaining high-value call sites (~55 additional sites across 30+ files) including config/export.nu, taskservs/discover.nu, servers/create.nu, ontoref-queries.nu, service-manager.nu, dag.nu, and others.
ADRs
adrs/adr-022-ncl-sync-daemon.ncl: daemon design decisions, key strategy rationale, constraint enforcementadrs/adr-023-ncl-export-wrapper.ncl:ncl-eval/ncl-eval-softwrapper design, migration strategy
Tests
tests/cache/test_key_parity.nu: validates that ncl-sync and nu_plugin_nickel produce identical keys for the same(file, import_paths, format)triple
Performance
| Command | Before | After (warm cache) |
|---|---|---|
prvng component list |
3–7 s | ~1.5 s |
prvng workflow list |
3–5 s | ~1.5 s |
prvng deploy |
15–30 s | ~3–5 s |
| Multi-export commands (ontoref) | 12–30 s | ~1.5 s |
Nu module parse startup (~1.2 s) is unaffected — separate concern.
[3.5.0] — 2025-10-07
Initial platform version with orchestrator, control center, installer, MCP server, vault service, and extension registry.