Spanda

Control Center

Web-based operational visibility for fleets, devices, readiness, and alerts. Phase E1 ships a REST API v1 and embedded UI served by the native CLI.

Related: enterprise-operations-roadmap.md · device-pool.md · device-provisioning.md · telemetry-store.md · configuration.md · troubleshooting.md (stale CLI, Unknown argument: generate)

Roadmap: Control Center Pillar 6 enhancement backlog is Stable (see feature-status.md).


Quick start

# Generate a key: spanda control-center api-key generate --export
export SPANDA_API_KEY="my-local-dev-key"

# Installed spanda — start API + UI (default http://127.0.0.1:8080)
spanda control-center serve

# Release build — cargo build -p spanda --release from repo root
./target/release/spanda control-center serve

# With project configuration (device pool from spanda.toml)
spanda control-center serve --config spanda.toml --bind 0.0.0.0:8080
./target/release/spanda control-center serve --config spanda.toml --bind 0.0.0.0:8080

# Native gRPC (tonic) on a separate port
spanda control-center serve --grpc-bind 127.0.0.1:50051
./target/release/spanda control-center serve --grpc-bind 127.0.0.1:50051

# Inspect or stop local instances (use the same binary you started with)
spanda control-center status
spanda control-center status --discover   # find local listeners when port is unknown
spanda control-center stop                # stop all local Control Center servers
spanda control-center stop --url http://127.0.0.1:8080
spanda control-center status --url http://127.0.0.1:8081 --json

./target/release/spanda control-center status
./target/release/spanda control-center status --discover
./target/release/spanda control-center stop
./target/release/spanda control-center stop --url http://127.0.0.1:8080

Copy-paste --config / --program examples: Local dev — Run with --config and --program.

Instance lifecycle

control-center serve runs until stopped. Each start binds a TCP port; interrupted smoke tests and cargo run … serve wrappers can leave orphaned listeners on random ports.

Task Command
List running servers spanda control-center status --discover
Inspect default (8080) spanda control-center status
Stop all local servers spanda control-center stop
Stop one URL spanda control-center stop --url http://127.0.0.1:8080
Force kill spanda control-center stop --force

CI smoke scripts source scripts/lib/control_center_smoke_lib.sh to kill the listener on CC_SMOKE_BIND on EXIT, INT, and TERM (not only the cargo run wrapper PID).

Access the UI

Method How
Embedded UI Open http://127.0.0.1:8080/ — React Control Center (same shell as @davalgi-spanda/web; rebuild with scripts/sync_control_center_embedded_ui.sh after UI changes)
Web package Use the Control Center view in @davalgi-spanda/web; set the API URL to your serve address. Paste a Bearer token in-panel (or set VITE_SPANDA_API_KEY at build time). Role-aware tabs and an Administration console match the embedded UI.
Desktop (Tauri) Start the API first, then npm run control-center:desktop:dev (Vite on port 5174); optional VITE_CONTROL_CENTER_URL=http://host:port. Sign in via the in-app token banner — no rebuild required for operator keys.
Remote CLI export SPANDA_CONTROL_CENTER_URL=http://127.0.0.1:8080 then spanda control-center dashboard (see Remote CLI)

Read-only views and GET /v1/* endpoints work without authentication. Mutations (POST, PATCH, DELETE) require a Bearer token — configure keys on the server before calling those endpoints.

Local dev: start & rebuild

Control Center has three layers. The API must run separately for every UI path except read-only CLI inspection.

Layer Package / crate Role
API backend spanda-api via spanda control-center serve REST /v1/*, gRPC, embedded static UI
React UI packages/web (@davalgi-spanda/web) Panels shared by browser, desktop, and web playground
Desktop shell packages/control-center-desktop (Tauri + Vite) Native window; does not embed the Rust API

Start (typical dev)

One-time (from repo root):

npm install

Terminal 1 — API (pick one invocation):

export SPANDA_API_KEY="my-local-dev-key"   # optional; see Authentication below

# Installed spanda
spanda control-center stop
spanda control-center serve --bind 127.0.0.1:8080

# Release build from repo root (cargo build -p spanda --release)
./target/release/spanda control-center stop
./target/release/spanda control-center serve --bind 127.0.0.1:8080

# Active Rust development (rebuilds on each run)
cargo run -p spanda -- control-center stop
cargo run -p spanda -- control-center serve --bind 127.0.0.1:8080

With --config and --program, see Run with --config and --program.

Browser only: open http://127.0.0.1:8080/ — no second terminal.

Terminal 2 — desktop (optional; hot-reloads React changes):

npm run control-center:desktop:dev

Equivalent: npm run dev --workspace=@spanda/control-center-desktop. Vite listens on port 5174. Point at a non-default API with VITE_CONTROL_CENTER_URL=http://host:port.

More detail: packages/control-center-desktop/README.md.

Rebuild after code changes

What you changed What to rebuild
Rust API (crates/spanda-api, CLI handlers, ops core) Stop serve, then cargo run -p spanda -- control-center serve … (dev) or cargo build -p spanda --release (install a release binary). If spanda on PATH is stale, use cargo run or reinstall — see troubleshooting.md — Stale CLI binary.
React panels (packages/web) for embedded browser UI (http://127.0.0.1:8080) ./scripts/sync_control_center_embedded_ui.sh then restart control-center serve. The script runs npm run build:control-center --workspace=@davalgi-spanda/web and copies dist-control-center/ into crates/spanda-api/src/static/control-center-ui/.
React panels for desktop dev Usually nothing — control-center:desktop:dev hot-reloads. Restart the dev shell if Vite gets stuck.
Desktop shell (Tauri config, native plugins) npm run control-center:desktop:check (compile check) or npm run build --workspace=@spanda/control-center-desktop (production bundle). Maintainer releases: desktop-release-runbook.md (TAURI_BUILD=1).
Operator API keys only No rebuild — paste the token in the in-app banner or set SPANDA_API_KEY and restart serve.

Embedded UI sync (browser):

./scripts/sync_control_center_embedded_ui.sh

spanda control-center stop
spanda control-center serve --bind 127.0.0.1:8080

./target/release/spanda control-center stop
./target/release/spanda control-center serve --bind 127.0.0.1:8080

Production desktop bundle:

npm run build --workspace=@spanda/control-center-desktop
# Artifacts: packages/control-center-desktop/src-tauri/target/release/bundle/

Or TAURI_BUILD=1 ./scripts/build_control_center_desktop.sh for the CI-style installer path.

Run with --config and --program

control-center serve accepts two optional paths. They are independent — mix any config with any program, or pass only one.

Flag Path What it loads
--config Project directory or spanda.toml file Device pool, discovery fixtures, facilities, fleet layout, Smart Spaces / ADAS device trees, HRI policy seeds
--program .sd mission file Default program for readiness, simulation, replay, traceability, govern-and-trace, recovery context

Path forms: --config accepts either a directory (looks for spanda.toml inside) or the file directly — both work:

--config crates/spanda-config/tests/fixtures/warehouse
--config crates/spanda-config/tests/fixtures/warehouse/spanda.toml   # equivalent

Run from the repository root unless paths are absolute. After changing flags, stop and restart serve (see Which spanda? below).

What needs which flag:

UI / API area --config --program
Dashboard (pool summary, alerts) helpful optional
Devices, Discovery, Provisioning, Mapping, Health required for real pool data
Readiness, Simulation, Replay, Digital Thread, Traceability required (or pass file in API body)
Smart Spaces, Humans, ADAS vehicle panels required (matching blueprint) recommended
Recovery orchestrator optional recommended
Govern-and-trace, drift vs baseline required required
Which spanda?

Examples use both common invocations. Paths (--config, --program) are identical — only the binary prefix changes.

Invocation When to use Stop a local server
./target/release/spanda Repo checkout; run cargo build -p spanda --release first ./target/release/spanda control-center stop
spanda Installed CLI on PATH (cargo install, package manager, CI image) spanda control-center stop
cargo run -p spanda -- Active Rust development (rebuilds on each run) cargo run -p spanda -- control-center stop
export SPANDA_API_KEY="my-local-dev-key"   # optional; see Authentication below

# Release build (from repository root):
cargo build -p spanda --release

# Verify which binary you are using:
./target/release/spanda --version
spanda --version

If spanda control-center is missing or flags like api-key generate fail, the installed binary may be stale — see troubleshooting.md — Stale CLI binary. Use ./target/release/spanda from a fresh cargo build or reinstall.

Copy-paste examples

Each example shows release build and installed forms. Swap --config / --program as needed; add --bind 127.0.0.1:8080 to override the default listen address.

Enterprise ops — warehouse device pool + compliance rover (same as scripts/enterprise_ops_smoke.sh):

./target/release/spanda control-center serve \
  --config crates/spanda-config/tests/fixtures/warehouse/spanda.toml \
  --program examples/showcase/compliance/defense_rover.sd

spanda control-center serve \
  --config crates/spanda-config/tests/fixtures/warehouse/spanda.toml \
  --program examples/showcase/compliance/defense_rover.sd

Flagship rover:

./target/release/spanda control-center serve \
  --config examples/showcase/autonomous_rover/spanda.toml \
  --program examples/showcase/autonomous_rover/src/rover.sd

spanda control-center serve \
  --config examples/showcase/autonomous_rover/spanda.toml \
  --program examples/showcase/autonomous_rover/src/rover.sd

Program only (readiness / sim; no device pool):

./target/release/spanda control-center serve \
  --program examples/rover.sd

spanda control-center serve \
  --program examples/rover.sd

ADAS — vehicle device tree + highway scenario:

./target/release/spanda control-center serve \
  --config examples/solutions/adas/spanda.toml \
  --program examples/solutions/adas/src/highway_drive.sd

spanda control-center serve \
  --config examples/solutions/adas/spanda.toml \
  --program examples/solutions/adas/src/highway_drive.sd

Smart Spaces — building blueprint:

./target/release/spanda control-center serve \
  --config examples/solutions/smart-spaces/spanda.toml \
  --program examples/solutions/smart-spaces/smart-building/floor_readiness.sd

spanda control-center serve \
  --config examples/solutions/smart-spaces/spanda.toml \
  --program examples/solutions/smart-spaces/smart-building/floor_readiness.sd

Humans / spatial computing:

./target/release/spanda control-center serve \
  --config examples/solutions/spatial-computing/spanda.toml \
  --program examples/solutions/spatial-computing/warehouse-ar/pick_mission.sd

spanda control-center serve \
  --config examples/solutions/spatial-computing/spanda.toml \
  --program examples/solutions/spatial-computing/warehouse-ar/pick_mission.sd

Recovery orchestrator:

./target/release/spanda control-center serve \
  --program examples/showcase/self_healing/rover.sd

spanda control-center serve \
  --program examples/showcase/self_healing/rover.sd

Warehouse logistics (end-to-end package):

./target/release/spanda control-center serve \
  --config examples/end_to_end/warehouse_delivery/spanda.toml \
  --program examples/end_to_end/warehouse_delivery/src/main.sd

spanda control-center serve \
  --config examples/end_to_end/warehouse_delivery/spanda.toml \
  --program examples/end_to_end/warehouse_delivery/src/main.sd

Basic packaged project:

./target/release/spanda control-center serve \
  --config examples/packages/basic_project/spanda.toml \
  --program examples/packages/basic_project/src/main.sd

spanda control-center serve \
  --config examples/packages/basic_project/spanda.toml \
  --program examples/packages/basic_project/src/main.sd

Optional bind address (default 127.0.0.1:8080):

./target/release/spanda control-center serve \
  --bind 127.0.0.1:8080 \
  --config crates/spanda-config/tests/fixtures/warehouse/spanda.toml \
  --program examples/showcase/compliance/defense_rover.sd

spanda control-center serve \
  --bind 127.0.0.1:8080 \
  --config crates/spanda-config/tests/fixtures/warehouse/spanda.toml \
  --program examples/showcase/compliance/defense_rover.sd
Mix --config and --program

Each subsection lists release build then installed commands with the same flags.

Same config, different program — swap --program only:

Release build:

./target/release/spanda control-center serve \
  --config examples/solutions/smart-spaces/spanda.toml \
  --program examples/solutions/smart-spaces/smart-home/night_mode.sd

./target/release/spanda control-center serve \
  --config examples/solutions/smart-spaces/spanda.toml \
  --program examples/solutions/smart-spaces/emergency-response/fire_response.sd

./target/release/spanda control-center serve \
  --config examples/solutions/adas/spanda.toml \
  --program examples/solutions/adas/lane_keeping/lane_keeping.sd

./target/release/spanda control-center serve \
  --config examples/solutions/adas/spanda.toml \
  --program examples/solutions/adas/automatic_emergency_braking/aeb.sd

Installed:

spanda control-center serve \
  --config examples/solutions/smart-spaces/spanda.toml \
  --program examples/solutions/smart-spaces/smart-home/night_mode.sd

spanda control-center serve \
  --config examples/solutions/smart-spaces/spanda.toml \
  --program examples/solutions/smart-spaces/emergency-response/fire_response.sd

spanda control-center serve \
  --config examples/solutions/adas/spanda.toml \
  --program examples/solutions/adas/lane_keeping/lane_keeping.sd

spanda control-center serve \
  --config examples/solutions/adas/spanda.toml \
  --program examples/solutions/adas/automatic_emergency_braking/aeb.sd

Different config, same program — devices / discovery tabs change:

Release build:

./target/release/spanda control-center serve \
  --config crates/spanda-config/tests/fixtures/warehouse/spanda.toml \
  --program examples/showcase/compliance/defense_rover.sd

./target/release/spanda control-center serve \
  --config examples/packages/basic_project/spanda.toml \
  --program examples/showcase/compliance/defense_rover.sd

./target/release/spanda control-center serve \
  --config examples/solutions/adas/applications/truck/spanda.toml \
  --program examples/solutions/adas/src/highway_drive.sd

./target/release/spanda control-center serve \
  --config examples/solutions/adas/applications/shuttle/spanda.toml \
  --program examples/solutions/adas/src/highway_drive.sd

Installed:

spanda control-center serve \
  --config crates/spanda-config/tests/fixtures/warehouse/spanda.toml \
  --program examples/showcase/compliance/defense_rover.sd

spanda control-center serve \
  --config examples/packages/basic_project/spanda.toml \
  --program examples/showcase/compliance/defense_rover.sd

spanda control-center serve \
  --config examples/solutions/adas/applications/truck/spanda.toml \
  --program examples/solutions/adas/src/highway_drive.sd

spanda control-center serve \
  --config examples/solutions/adas/applications/shuttle/spanda.toml \
  --program examples/solutions/adas/src/highway_drive.sd

See solutions/adas/applications for more ADAS device trees.

Config only (pool panels; no default mission):

./target/release/spanda control-center serve \
  --config examples/solutions/smart-spaces/spanda.toml

spanda control-center serve \
  --config examples/solutions/smart-spaces/spanda.toml
CLI demo → serve
./target/release/spanda demo adas
./target/release/spanda control-center stop
./target/release/spanda control-center serve \
  --config examples/solutions/adas/spanda.toml \
  --program examples/solutions/adas/src/highway_drive.sd

spanda demo adas
spanda control-center stop
spanda control-center serve \
  --config examples/solutions/adas/spanda.toml \
  --program examples/solutions/adas/src/highway_drive.sd

Open http://127.0.0.1:8080/ or run npm run control-center:desktop:dev in a second terminal. Demo catalog: overview/flagship-demos.md · showcase/README.md.

Demo / UI focus Highlights
Enterprise ops smoke Warehouse pool + compliance rover
Flagship rover spanda demo rover
ADAS ADAS dashboard
Smart Spaces Smart Spaces dashboard
Humans / spatial Human Interaction dashboard
Recovery Recovery dashboard
Warehouse logistics solutions/warehouse.md

Authentication & API keys

Generate a random operator token with the CLI, or choose your own secret for local dev. Clients send the token as Authorization: Bearer <token> on mutating requests.

# Human-readable output with setup steps
spanda control-center api-key generate

# Single copy-paste line for your shell
spanda control-center api-key generate --export

Example:

eval "$(spanda control-center api-key generate --export)"
spanda control-center serve

When SPANDA_API_KEY is unset and no SPANDA_API_KEYS_FILE is loaded, control-center serve prints a warning with the same generate command.

If generate fails with Unknown argument: generate and top-level help has no control-center section, reinstall the CLI — see troubleshooting.md — Unknown argument: generate.

The embedded Control Center UI shows an Operator API key banner when no token is configured in the browser. Paste a token registered on the server (SPANDA_API_KEYS_FILE or SPANDA_API_KEY at serve time). With Remember on this browser checked (default), the token is stored in localStorage scoped to the Control Center origin (host:port) and restored on refresh; use Forget token to clear it. The UI verifies the token with POST /v1/alerts/test before saving. Same-origin XSS could read a stored token — use Forget on shared machines. The @davalgi-spanda/web panel uses VITE_SPANDA_API_KEY at dev/build time instead.

Browser storage key: spanda.control_center.bearer_token.v1:<host> (for example spanda.control_center.bearer_token.v1:127.0.0.1:8080). Each host:port has its own entry; changing bind port or hostname requires pasting the token again unless you migrate the key in DevTools → Application → Local Storage.

Single operator key (local dev)

Any string works for quick local testing:

export SPANDA_API_KEY="my-local-dev-key"
spanda control-center serve

Use the same value from clients:

export SPANDA_API_KEY="my-local-dev-key"
curl -H "Authorization: Bearer $SPANDA_API_KEY" \
  -X POST http://127.0.0.1:8080/v1/alerts/test

A key from SPANDA_API_KEY is registered as role administrator (full mutation access).

Alternative: openssl or Python

openssl rand -hex 32
# or
python3 -c "import secrets; print(secrets.token_urlsafe(32))"

Export the output as SPANDA_API_KEY on the server and distribute it securely to operators. Do not commit tokens to git.

Multiple keys with roles

For several operators with different permissions, write a JSON file and point the server at it:

export SPANDA_API_KEYS_FILE=~/.spanda/api-keys.json
spanda control-center serve

Example api-keys.json:

[
  {
    "key_id": "alice",
    "token": "alice-admin-token-here",
    "role": "administrator",
    "tenant_id": "default"
  },
  {
    "key_id": "bob",
    "token": "bob-operator-token-here",
    "role": "operator",
    "tenant_id": "default"
  }
]

Keys from SPANDA_API_KEYS_FILE are merged with any key from SPANDA_API_KEY.

Role Typical use
administrator Full access (default for SPANDA_API_KEY)
supervisor All actions except delete
developer Deploy and operate
operator Operate, shutdown, recover
safety_officer Operate, approve, shutdown
auditor Read-only (no mutations)
guest Read-only (no mutations)

Inspect the live permission matrix: GET /v1/rbac/matrix. After pasting a Bearer token in the UI (embedded HTML or @davalgi-spanda/web / Tauri desktop), GET /v1/rbac/me returns your role, key_id, tenant_id, and allowed mutation permissions — the UI uses this to show your role badge, filter tabs by role, and enable action buttons per permission.

Administration (administrator role)

The Administration tab (administrator role only) manages operator keys and integrations:

Endpoint Description
GET /v1/admin/api-keys List key metadata (no token values)
POST /v1/admin/api-keys Create a key — response includes token once
PATCH /v1/admin/api-keys/{key_id} Update role or label
DELETE /v1/admin/api-keys/{key_id} Revoke a file-backed key (env-default from SPANDA_API_KEY cannot be revoked via API)
GET /v1/admin/integrations Alert channels and observability backend summary

File-backed keys persist to SPANDA_API_KEYS_FILE or .spanda/api-keys.json.

User directory

Endpoint Description
GET /v1/admin/users List operator accounts (seeds from [[humans]] in config when empty)
POST /v1/admin/users Create user
PATCH /v1/admin/users/{user_id} Update display name, email, role, linked API key, enabled flag
DELETE /v1/admin/users/{user_id} Remove user

Persisted to .spanda/admin-users.json.

Alert channels

Endpoint Description
GET /v1/admin/alert-channels Current dispatcher channels
PUT /v1/admin/alert-channels Replace channels (webhook, email, PagerDuty, Teams, log)

Persisted to .spanda/alert-channels.json. When unset, channels load from SPANDA_ALERT_* environment variables.

Simulation and Replay

Endpoint Description
GET /v1/programs/traces List .trace files under the project root
POST /v1/programs/simulation Plan or execute simulation (execute, inject_health_faults, record_trace, decision_trace)
POST /v1/programs/replay Inspect, deterministic replay, or playback

Control Center Simulation and Replay tabs expose these workflows in the desktop and web panel.

Mission control

Endpoint Description
GET /v1/operator/missions Mission entities from the loaded program
POST /v1/operator/mission/pause Pause mission (Operate)
POST /v1/operator/mission/resume Resume mission (Operate)
POST /v1/operator/mission/cancel Cancel mission (Shutdown)
GET /v1/operator/mission/approvals Pending approval queue
POST /v1/operator/mission/approve Approve or reject (Approve)

Differentiation (NOW signature capabilities)

Endpoint Description
GET /v1/programs/source Source text for the loaded --program file
POST /v1/programs/contract/verify Mission contract verification (spanda contract verify parity)
POST /v1/programs/explain Explainability report — body { "mode": "program\|readiness\|verify\|safety\|decision\|trace", "file": "…" }
POST /v1/programs/audit/decisions Decision audit trail from a .trace — optional "explain": true

Control Center Differentiation tab (Governance group) surfaces contract verify, explain modes, and trace audit. Assurance/Diagnosis runs POST /v1/programs/assure and /diagnose. Traceability loads the capability matrix via POST /v1/programs/verify/capabilities with traceability: true. Playground can load the server program via GET /v1/programs/source.

What requires authentication

Access Auth required?
Embedded UI at / No (read-only panels)
GET /v1/* (dashboard, devices, health, OpenAPI, …) No
POST / PATCH / PUT / DELETE (provision, OTA, approvals, quarantine, …) Yes — Authorization: Bearer <token>
gRPC mutating RPCs Same Bearer token in metadata

Multi-tenant isolation: Set SPANDA_TENANT_ID on the Control Center instance (default default). Each key may include a tenant_id field; authenticated requests with a mismatched tenant return 403.

Storage: Server-side keys are matched as plain strings (not hashed). Treat them like passwords — restrict file permissions on SPANDA_API_KEYS_FILE and rotate on compromise. The embedded UI may optionally persist a pasted Bearer token in browser localStorage under spanda.control_center.bearer_token.v1:<host> (per host:port, opt-in via Remember on this browser); this does not register the key on the server and is readable by any script on the same origin. Clear with Forget token or remove the key in browser DevTools.

ADAS dashboard

Launch with the ADAS Solution Blueprint for vehicle-centric operations:

./target/release/spanda control-center serve \
  --config examples/solutions/adas/spanda.toml \
  --program examples/solutions/adas/src/highway_drive.sd

spanda control-center serve \
  --config examples/solutions/adas/spanda.toml \
  --program examples/solutions/adas/src/highway_drive.sd

The ADAS tab shows vehicle health, sensor health, readiness pool summary, trust score, alerts, OTA status, assurance/diagnosis summaries, and replay workflow links. See solutions/adas.md.

Recovery dashboard

Launch with the self-healing showcase program:

./target/release/spanda control-center serve \
  --program examples/showcase/self_healing/rover.sd

spanda control-center serve \
  --program examples/showcase/self_healing/rover.sd

The Recovery tab (operator+ roles with Operate permission) shows:

Panel Content
Plans & metrics Active recovery plans and aggregated orchestrator metrics
Playbooks & history Built-in and plugin playbooks; persisted evidence history
Graph Recovery dependency graph (GET /v1/recovery/graph) — nodes and edges
Actions Plan, simulate, and execute recovery via REST (Bearer token required for execute)

Same panels ship in @davalgi-spanda/web RecoveryPanel. API reference: recovery-api.md · SDK: recovery-sdk.md.

Cognitive & Resilience dashboard

The Cognitive & Resilience tab (Health & incidents group; operator+ with Operate permission) organizes live panels by functional domain:

Panel Functional domain Content
Strategic Planning Strategic Planning Governance summary and deployment profiles (GET /v1/governance, /v1/deployment-profiles)
Reflex Events Reflex & Safety Platform reflex actions and traces (GET /v1/autonomy/reflex*)
Attention Queue Attention Engine Prioritized event window (GET /v1/autonomy/attention)
Homeostasis Homeostasis Engine Entity stability reports (GET /v1/autonomy/homeostasis)
Platform Immunity Platform Immunity Quarantine scan (GET /v1/autonomy/immunity)
Operational Memory Operational Memory Memory category refs (GET /v1/autonomy/memory)
Damage Risk Damage Risk Assessment Entity damage_risk from autonomy profile
Recovery Confidence Adaptive Learning Platform recovery confidence + entity profile

Per-entity autonomy profiles: GET /v1/entities/{id}/autonomy. gRPC parity: ListAutonomyReflexes, GetAutonomyHomeostasis, GetEntityAutonomy, and related RPCs (proto 1.0.13+).

Beta — live REST panels shipped; promotion to Stable follows Control Center P1 backlog in ROADMAP.md. Guide: cognitive-resilience-architecture.md · Maturity: cognitive-resilience-maturity.md · Smoke: ./scripts/cognitive_resilience_smoke.sh

Human Interaction dashboard

Launch with the Spatial Computing & Human-Robot Collaboration blueprint:

./target/release/spanda control-center serve \
  --config examples/solutions/spatial-computing/spanda.toml \
  --program examples/solutions/spatial-computing/warehouse-ar/pick_mission.sd

spanda control-center serve \
  --config examples/solutions/spatial-computing/spanda.toml \
  --program examples/solutions/spatial-computing/warehouse-ar/pick_mission.sd

The Humans tab shows operator dashboard, wearable inventory, AR/HRI sessions, VR training links, and health opt-in policy. The same panels ship in @davalgi-spanda/web ControlCenterPanel (parity with embedded HTML).

Before promoting Human Interaction to Stable: start HRI field soak (date -u +%Y-%m-%d > .spanda/hri-field-soak-start.txt), then run ./scripts/hri_stable_promotion_gate.sh — see stable-hardening-human-interaction.md.

Experimental (H4) — Human Interaction tab and panels:

Panel Content
Human Dashboard Fleet-wide human entities, roles, availability
Operator Dashboard Per-operator readiness, certifications, assignments
Wearable Inventory Connected wearables, battery, connectivity
AR Session Viewer Active AR/XR sessions, spatial anchors
VR Training Training session launcher, replay links
Live Collaboration Remote expert sessions, participant graph
Mission Collaboration Human + robot + drone task allocation
Operator Readiness Team readiness rollup, blocking dimensions
Approval Queue Mission, recovery, and config approvals (extends E1)

Planned REST endpoints (experimental — humans/wearables/health and HRI sessions implemented):

Endpoint Description
GET /v1/humans Human operator list
GET /v1/humans/{id}/readiness Per-operator readiness
GET /v1/humans/readiness Team readiness rollup (H5)
GET /v1/wearables Wearable inventory
GET /v1/human-health/policy Health opt-in gate
GET /v1/hri/sessions HRI / remote expert sessions
GET /v1/hri/collaboration Live collaboration participant graph (H5)
GET /v1/hri/context Hazard zones and human location context (H5)
GET /v1/humans/twins Human digital twin metadata (H6)
GET /v1/operator/mission/approvals Mission approval queue (H6)
POST /v1/hri/sessions/{id}/annotate AR annotation publish

See solutions/spatial-computing.md · human-interaction-spatial-computing-roadmap.md.

Smart Spaces dashboard

Launch with the Smart Spaces & Ambient Intelligence blueprint:

./target/release/spanda control-center serve \
  --config examples/solutions/smart-spaces/spanda.toml \
  --program examples/solutions/smart-spaces/smart-building/floor_readiness.sd

spanda control-center serve \
  --config examples/solutions/smart-spaces/spanda.toml \
  --program examples/solutions/smart-spaces/smart-building/floor_readiness.sd

The Smart Spaces tab (experimental) shows building and facility operations across residential, commercial, and campus deployments. See solutions/smart-spaces.md.

Experimental — Smart Spaces tab and panels:

Panel Content
Buildings Facility list, floor map, readiness rollup per building
Rooms & zones Zone tree, occupancy counts, ambient context
Occupancy Presence timeline, flow between zones
Devices IoT inventory, gateway primary/backup role, battery quorum
Robots Vacuum, service, inspection robot status and missions
Wearables Linked wearables, health opt-in indicator
Health Device pool health, degraded critical sensors
Readiness Pre-mode blockers (night, lockdown, evac)
Trust Lock/camera attestation, package trust scores
Energy Generation, storage SOC, EV sessions, demand-response events
Security Access audit, tamper alerts, lockdown state
Environmental CO₂, AQ, temperature baselines vs actuals
Emergency Fire, leak, power failure status and active missions

REST endpoints (experimental, shipped):

Endpoint Description
GET /v1/smart-spaces/summary Blueprint rollup (facilities, energy, emergency)
GET /v1/smart-spaces/devices IoT device inventory (?facility_id=)
GET /v1/facilities/{id}/floor-map Zone tree floor map
GET /v1/facilities/{id}/security Access control and lockdown status
GET /v1/facilities/{id}/health Device pool health for facility
GET /v1/zones/{id}/environment CO₂, temperature, humidity, AQ
GET /v1/energy/systems/{id} SOC, generation, EV session detail
GET /v1/facilities Building / facility entity list with zones and gateways
GET /v1/facilities/{id}/readiness Per-building readiness rollup
GET /v1/zones/{id}/occupancy Zone occupancy twin
GET /v1/energy/systems Solar, battery, EV, meter summary
GET /v1/emergency/status Active emergency missions and continuity pairs

Remote CLI:

spanda control-center smart-spaces summary
spanda control-center smart-spaces facilities
spanda control-center smart-spaces readiness --facility-id tower-demo
spanda control-center smart-spaces occupancy --zone-id floor-12
spanda control-center smart-spaces energy
spanda control-center smart-spaces emergency

Generic api get also works:

spanda control-center api get /v1/smart-spaces/summary
spanda control-center api get /v1/facilities/tower-demo/readiness
spanda control-center api get /v1/zones/floor-12/occupancy

Remote CLI (REST parity)

Query a running Control Center without curl — uses SPANDA_CONTROL_CENTER_URL (default http://127.0.0.1:8080) and SPANDA_API_KEY for mutations:

export SPANDA_CONTROL_CENTER_URL=http://127.0.0.1:8080
export SPANDA_API_KEY=your-operator-key

spanda control-center status
spanda control-center status --discover
spanda control-center stop
spanda control-center dashboard
spanda control-center drift --baseline-id <snapshot-id>
spanda control-center incidents list
spanda control-center approvals list
spanda control-center approvals submit --snapshot-id <id>
spanda control-center approvals approve <approval-id>
spanda control-center evidence list
spanda control-center sre summary
spanda control-center devices list
spanda control-center readiness run
spanda control-center ota plan --strategy canary --version 1.0 --dry-run
spanda control-center compliance export --profile defense
spanda control-center trust package --name spanda-mqtt

# Generic escape hatch for any /v1 path
spanda control-center api get /v1/sre/summary
spanda control-center api post /v1/ota/plan --body '{"strategy":"canary","version":"1.0","dry_run":true}'

Native gRPC (tonic)

spanda control-center serve --grpc-bind 127.0.0.1:50051 starts a tonic gRPC server alongside REST.

RPC Description
Health Liveness probe
GetTenant Instance tenant scope (GET /v1/tenant parity)
GetDashboard Dashboard JSON (device pool, fleet agents, alerts)
ListDevices Device pool entries (GET /v1/devices parity)
ListFleetAgents Registered fleet agents (GET /v1/fleet/agents parity)
EvaluateReadiness Readiness rollup (POST /v1/readiness/run parity)
GetSreSummary SRE availability rollup (GET /v1/sre/summary parity)
ListSreIncidents Incident list (GET /v1/sre/incidents parity)
CreateSreIncident Open incident (POST /v1/sre/incidents parity)
GetTrustPackage Package trust score (GET /v1/trust/package parity)
GetOpenApi OpenAPI 3.1 spec JSON (GET /v1/openapi.json parity)
GetOtlpMetrics OTLP metrics preview (GET /v1/observability/otlp/metrics)
GetObservabilityBackend Collector URL summary (GET /v1/observability/backend)
GetHealthSummary Health rollup (GET /v1/health/summary)
GetAssuranceSummary Assurance policy summary
GetDiagnosisSummary Diagnosis policy summary
GetExecutiveScorecard Executive scorecard
QueryDigitalThread Digital thread query (query = URL query string)
GetOtaStatus OTA rollout status
DiscoverDevices Single-transport discovery (query = URL query string)
RunDiscovery Multi-transport pool ingest (POST /v1/devices/discover parity)
ProvisionDevice Provisioning workflow (POST /v1/provision parity)
PlanOta OTA rollout plan (POST /v1/ota/plan parity)
OperatorQuarantine Operator quarantine workflow
OperatorMissionApprove Mission approval workflow
ExportCompliance Compliance export (query = profile=defense, …)
ListComplianceEvidence Append-only evidence log (GET /v1/compliance/evidence)
ListConfigApprovals Config publish approval queue (GET /v1/config/approvals)
SubmitConfigApproval Submit snapshot for approval (POST /v1/config/approvals)
ApproveConfigApproval Approve and publish snapshot (POST /v1/config/approvals/{id}/approve)
RejectConfigApproval Reject pending approval (POST /v1/config/approvals/{id}/reject)
DetectDrift Operational drift report (baseline_id in request)
ListEntities Entity inventory (GET /v1/entities parity)
GetEntity Entity detail (GET /v1/entities/{id} parity)
GetEntityGraph Full entity graph (GET /v1/entities/graph)
GetEntityTraceability Unified traceability (GET /v1/entities/traceability)
QueryEntities Structured entity query (POST /v1/entities/query)
GetEntityRelationships Relationship edges (GET /v1/entities/{id}/relationships)
GetEntityReadiness Readiness snapshot (GET /v1/entities/{id}/readiness)
RegisterEntity Register entity overlay (POST /v1/entities/register; Bearer)
TagEntity Add/remove tags (POST /v1/entities/{id}/tags; Bearer)
RelateEntities Relate entities (POST /v1/entities/relationships; Bearer)
SyncEntities Sync overlay to TOML (POST /v1/entities/sync; Bearer)
GetAnalyticsReadiness Readiness trends (GET /v1/analytics/readiness parity; query = URL query string)
GetAnalyticsWhatIf What-if failure scenarios (GET /v1/analytics/what-if parity)
GetAnalyticsMissionRisk Mission deployment risk (GET /v1/analytics/mission-risk parity)
GetAnalyticsReadinessForecast Readiness degradation forecast (GET /v1/analytics/readiness-forecast parity)
GetAnalyticsTrustGraph Trust-weighted dependency graph (GET /v1/analytics/trust-graph parity)

Proto: crates/spanda-api/proto/spanda/v1/control_center.proto — package spanda.v1. Pin semver and RPC count via GET /v1/versiongrpc.proto_semver and grpc.rpc_count (currently 1.0.14, 164 RPCs). gRPC reflection is enabled when tonic-reflection is compiled in.

# Example with grpcurl (reflection or proto file)
grpcurl -plaintext 127.0.0.1:50051 list
grpcurl -plaintext -import-path crates/spanda-api/proto -proto spanda/v1/control_center.proto \
  -d '{}' 127.0.0.1:50051 spanda.v1.ControlCenter/Health

REST API v1

Endpoint Method Auth Description
/v1/health GET Liveness
/v1/instance GET Runtime status (bind, config/program paths, pool summary, control_center_ui_version)
/v1/version GET API versioning policy; control_center_ui_version, spanda_version, gRPC proto metadata
/v1/tenant GET Active tenant (SPANDA_TENANT_ID)
/v1/dashboard GET Device pool summary, fleet agent count, alerts
/v1/devices GET Device pool entries
/v1/devices/{id} GET Single device record
/v1/devices/{id} PATCH Bearer Update lifecycle_state
/v1/devices/discover POST Bearer Multi-transport discovery (registers matches)
/v1/devices/{id}/provision POST Bearer Per-device provision workflow
/v1/devices/{id}/assign POST Bearer Assign device to robot
/v1/devices/{id}/quarantine POST Bearer Quarantine device
/v1/devices/{id}/trust POST Bearer (Approve) Operator trust / approve device
/v1/robots GET Robot inventory from device tree
/v1/fleets GET Fleet inventory
/v1/device-tree GET Hierarchy + logical/physical mapping JSON
/v1/readiness/run POST Device readiness impact check
/v1/device-reports GET Inventory, trust, calibration reports
/v1/fleet/agents GET Registered fleet agents (.spanda/fleet-agents.json)
/v1/alerts GET Alert history
/v1/alerts/test POST Bearer Dispatch test alert
/v1/secrets GET Bearer Secret metadata (no values)
/v1/rbac/matrix GET Role permission matrix
/v1/rbac/me GET Bearer Authenticated operator role and permissions
/v1/provision POST Bearer Run discover → ready workflow
/v1/discovery GET Package-backed discovery (?transport=mdns or subnet); response includes tls policy summary
/v1/config/snapshots GET/POST POST: Bearer List or save configuration snapshots (encrypt: true + SPANDA_CONFIG_SNAPSHOT_KEY for AES-256-GCM at rest)
/v1/config/approvals GET List config publish approval requests
/v1/config/approvals POST Bearer (Deploy) Submit approval request for a snapshot (required_approvals or SPANDA_CONFIG_APPROVALS_REQUIRED)
/v1/config/approvals/{id}/approve POST Bearer (Approve) Record approver vote; publish when quorum met (quorum.received / quorum.required)
/v1/config/approvals/{id}/reject POST Bearer (Approve) Reject a pending config publish
/v1/health/summary GET Device pool health rollup
/v1/assurance/summary GET Assurance policy from resolved config
/v1/diagnosis/summary GET Diagnosis policy from resolved config
/v1/openapi.json GET OpenAPI 3.1 specification
/v1/drift GET Operational drift vs baseline snapshot (?baseline_id=)
/v1/drift/scans GET Recorded drift scan history
/v1/drift/scan POST Bearer Trigger drift scan (optional baseline_id)
/v1/ota/plan POST Bearer Plan canary / staged / blue_green rollout; require_certify enforced when SPANDA_OTA_REQUIRE_CERTIFY or SPANDA_PRODUCTION_POLICY=production
/v1/ota/execute POST Bearer Execute rollout; rollback_on_readiness_fail gates post-deploy readiness; certification proof required in production policy
/v1/ota/status GET OTA deploy state (.spanda/deploy-state.json)
/v1/trust/package GET Package trust evaluation (?name=&version=)
/v1/sre/summary GET Availability, incidents, MTTR/MTBF hints, health_trends, readiness_trends, slo, and burn_rate
/v1/sre/incidents GET Incident list
/v1/sre/incidents POST Bearer Open incident
/v1/sre/incidents/{id}/ack POST Bearer Acknowledge incident
/v1/sre/incidents/{id}/resolve POST Bearer Resolve incident
/v1/integrations/pagerduty/webhook POST Bearer Inbound PagerDuty ack/resolve → incident workflow sync
/v1/observability/traces GET Recent API trace records
/v1/observability/otlp/traces GET OTLP/JSON trace preview for Jaeger
/v1/observability/otlp/metrics GET OTLP/JSON metrics preview
/v1/observability/backend GET Configured OTLP collector endpoints
/v1/observability/otlp/export POST Bearer Push API traces to OTLP collector
/v1/stream/telemetry WebSocket Live telemetry, traces, and alerts
/v1/operator/quarantine POST Bearer Quarantine a device
/v1/operator/mission/approve POST Bearer Approve or reject a mission
/v1/rpc POST gRPC-compatible JSON gateway
gRPC (tonic) Native ControlCenter service on --grpc-bind (see GET /v1/versiongrpc.rpc_count; full REST parity except JSON-RPC gateway)
/v1/compliance/export GET/POST Bearer Accreditation bundle (?profile=defense, iso26262, …); appends immutable evidence log
/v1/compliance/profiles GET Signed profile catalog (defense, medical, iso26262, iso13849, iec61508) with Ed25519 verification
/v1/compliance/evidence GET Bearer List append-only compliance evidence records
/v1/digital-thread/query GET Trace chain (?capability=, ?device_id=, ?lifecycle_phase=)
/v1/executive/scorecard GET Mission scorecard rollup
/v1/analytics/readiness GET Readiness trends and forecast
/v1/analytics/what-if GET scenario, all What-if failure scenario analysis
/v1/analytics/mission-risk GET Mission deployment risk score
/v1/analytics/readiness-forecast GET horizon, all Readiness degradation forecast
/v1/analytics/trust-graph GET format Trust-weighted dependency graph
/v1/reports/export GET Bearer Combined report (format=markdown, json, or pdf)
/v1/reports/schedules GET Bearer List scheduled report delivery jobs
/v1/reports/schedules POST Bearer Create scheduled webhook delivery (profile, format, destination_url, interval_hours)
/v1/audit/mutations GET Bearer Hash-chained mutation audit trail
/v1/audit/mutations/export GET Bearer SIEM export (?format=cef or jsonl)

Authenticate mutations with Authorization: Bearer <token>. See Authentication & API keys for how to create and configure tokens.

HA persistence: Alert history and API trace log hydrate from .spanda/control-center-alerts.json and .spanda/control-center-traces.json on startup (override directory with SPANDA_CONTROL_CENTER_STATE_DIR).

API versioning: GET /v1/version documents supported versions and returns control_center_ui_version (UI semver) and spanda_version (platform build). Clients may send X-Spanda-Api-Version: v1; unsupported values return 400. Breaking changes ship under a new /v2/ path prefix. Operator CLI: spanda control-center --version. See control-center-versioning.md.

Rate limiting: Set SPANDA_API_RATE_LIMIT_PER_MINUTE (per API key, or anonymous when unauthenticated). Excess requests return HTTP 429 with Retry-After (REST) or gRPC RESOURCE_EXHAUSTED.

Mutation audit: Successful POST/PATCH/PUT/DELETE requests append hash-chained audit records (GET /v1/audit/mutations, Bearer required). Export for SIEM: GET /v1/audit/mutations/export?format=cef|jsonl. Persisted to .spanda/control-center-mutations.jsonl (override with SPANDA_MUTATION_AUDIT_PATH).

Production policy: Set SPANDA_PRODUCTION_POLICY=production to enable fleet defaults: OTA certification required (SPANDA_OTA_REQUIRE_CERTIFY), discovery TLS required (SPANDA_DISCOVERY_REQUIRE_TLS). See stable-hardening-enterprise-ops.md.

Scheduled reports: Background delivery when SPANDA_REPORT_SCHEDULE_INTERVAL_SECS is set (e.g. 3600). Schedules persist under SPANDA_CONTROL_CENTER_STATE_DIR.

Discovery TLS: SPANDA_DISCOVERY_REQUIRE_TLS blocks insecure http:// / mqtt:// endpoints; SPANDA_DISCOVERY_TLS_CA_BUNDLE points at vendor CA PEM. Registry package: spanda-discovery-tls.

SRE burn monitor: Fast-burn alerts when SPANDA_SRE_BURN_SCAN_INTERVAL_SECS > 0 (SPANDA_SRE_BURN_RATE_FAST, SPANDA_SRE_BURN_WINDOW_HOURS).

Drift scans: Background scheduler when SPANDA_DRIFT_SCAN_INTERVAL_SECS > 0.

Pass optional X-Correlation-ID on any request; the server echoes it on the response and records traces for /v1/observability/traces.

Govern-and-trace endpoints require a loaded program:

./target/release/spanda control-center serve --config spanda.toml --program rover.sd
spanda control-center serve --config spanda.toml --program rover.sd

Control Center UI sections

The embedded HTML at / and the @davalgi-spanda/web Control Center panel share the same operational tabs. After signing in with a Bearer token, GET /v1/rbac/me drives role-aware navigation: each role (administrator, supervisor, developer, operator, safety_officer, auditor, guest) sees a tailored tab set, dashboard workspace panel, per-tab hints, and action buttons gated by RBAC permissions (Deploy, Operate, Approve, Provision, etc.).

The @davalgi-spanda/web Control Center panel includes:

Section Purpose
Dashboard Pool summary, alerts, fleet agents
Devices Device pool with lifecycle and assignment
Fleet Fleets, robots, agents
Discovery Multi-transport device discovery
Provisioning Device inspect and provision workflows
Mapping Logical ↔ physical mapping export
Health Pool health rollup
Readiness Readiness impact check
Compliance Signed profile picker + accreditation export + evidence log
Digital Thread Interactive capability→device graph with filters
Traceability Trust and identity trace view
Recovery Orchestrator plans, metrics, playbooks, history, graph, plan/simulate/execute
Cognitive & Resilience Functional domain panels — reflex, attention, homeostasis, immunity, memory, damage risk (/v1/autonomy/*)
Administration API keys, users, alert channels, integrations (administrator)
Simulation Program sim execute with decision traces
Replay Trace library, deterministic replay
Telemetry Live WebSocket stream (/v1/stream/telemetry)
Trends Readiness forecast charts and SRE trend rollup
Continuity Fleet-agent continuity poll and mission pause/resume/cancel
Fleet map Grid/geospatial markers (GET /v1/fleet/map)
Reports Scheduled report CRUD and compliance preview
Playground In-browser WASM check/run
Marketplace Installed plugin and Control Center panel browser
Chaos Fault injection catalog and simulation (/v1/chaos/*)

Enhancements on existing tabs: SRE observability bridge (Grafana embed when SPANDA_GRAFANA_URL is set, Jaeger/trace links), config change history + deploy gate modal, bulk device quarantine/trust, OTA rollout progress, decision policy editor, Smart Spaces floor-plan SVG, analytics trust graph + certification pack download, Twin Cloud usage meters, OIDC/Slack OAuth wizards with callback landing pages (/admin/oauth/*) and PKCE, offline dashboard cache, plugin bundle loader, Humans collaboration graph + AR annotate, entity graph default view, saved connection profile switcher, Discovery transport wizards, desktop spawn_control_center_api + native notifications + system tray.

New REST APIs: GET /v1/fleet/map, GET /v1/config/history, GET /v1/deploy/gate, GET|PUT /v1/admin/oidc, POST /v1/admin/oidc/sync, GET|POST /v1/admin/slack, GET /v1/chaos/injections, POST /v1/chaos/simulate. gRPC server reflection enabled (tonic-reflection).


Python SDK

pip install -e packages/sdk-python
export SPANDA_API_KEY=your-key
python -c "from spanda_sdk import ControlCenterClient; print(ControlCenterClient().health())"

Integration tests: SPANDA_SDK_INTEGRATION=1 SPANDA_CONTROL_CENTER_URL=http://127.0.0.1:8080 pytest packages/sdk-python/tests

WebSocket streaming (pip install -e 'packages/sdk-python[stream]'):

from spanda_sdk import TelemetryStream
TelemetryStream("http://127.0.0.1:8080").wait_for_hello()

OTLP traces (Jaeger)

Control Center API spans export as OTLP/JSON traces:

export SPANDA_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
export SPANDA_OTLP_TRACE_AUTO_PUSH=1   # optional: push each API span
curl -H "Authorization: Bearer $SPANDA_API_KEY" \
  -X POST "http://127.0.0.1:8080/v1/observability/otlp/export"

Preview payload: GET /v1/observability/otlp/traces

Live telemetry WebSocket: ws://127.0.0.1:8080/v1/stream/telemetry (hello + telemetry/trace/alert events)


Device Pool lifecycle

Devices in [[devices]] or the device tree carry optional lifecycle fields:

State Meaning
discovered Seen but not verified
quarantined Blocked pending review
verified Identity and trust checks passed
assigned Bound to a robot
active Operational (healthy is an alias)
degraded / offline / failed Runtime posture
retired Removed from active pool

Set in TOML:

[[devices]]
id = "lidar-front"
type = "lidar"
lifecycle_state = "active"
assigned_robot = "rover-1"
logical_name = "front_lidar"

See device-pool.md and device-provisioning.md.


Alerting

Configure delivery channels via environment variables:

Variable Effect
SPANDA_ALERT_WEBHOOK_URL POST JSON alert payload
SPANDA_ALERT_EMAIL_TO Email recipient (logs if SPANDA_SMTP_HOST unset)
SPANDA_ALERT_EMAIL_DRY_RUN=1 Log email without sending
SPANDA_ALERT_DEDUP_WINDOW_*_SECS Per-severity dedup windows before dispatch
SPANDA_PAGERDUTY_WEBHOOK_SECRET Optional HMAC for inbound PagerDuty webhook

Registry packages: spanda-alert-pagerduty (bi-directional sync), spanda-alert-escalation, spanda-alert-slack, spanda-alert-teams.

Default: log to stderr.


Smoke test

./scripts/enterprise_ops_smoke.sh
./scripts/control_center_desktop_smoke.sh
./scripts/security_audit_prep.sh      # third-party audit intake
./scripts/field_soak_gate.sh          # after 30-day pilot start date
./scripts/verify_sdk_publish_ready.sh # PyPI + npm pack readiness
./scripts/verify_desktop_release_ready.sh # desktop version sync + Tauri compile # PyPI + npm pack readiness

Stable promotion

Enterprise operations E1–E4 are Stable with full stable-hardening checklist items shipped in code. SDKs 0.4.2 (registry) and Control Center desktop 0.6.3 (desktop-v0.6.3, with sidebar/CLI/API version display) are published via registry tags and GitHub Releases. Remaining organizational gates: third-party security audit sign-off and 30-day field soak. See stable-hardening-enterprise-ops.md · field-soak-gate.md · security-audit-third-party.md · desktop-release-runbook.md · control-center-versioning.md.


Versioning

Control Center has an independent desktop release stream (desktop-v*) and a UI semver shown in the sidebar, CLI, and API.

Surface How to read the version
UI sidebar vX.Y.Z under the Control Center title
CLI spanda control-center --version · spanda control-center statusUI version
API GET /v1/versioncontrol_center_ui_version · GET /v1/instance
Serve startup Spanda Control Center vX.Y.Z listening on …

Automatic bump: PRs labeled release:patch|minor|major that change Control Center paths trigger a matching desktop bump after CI Integration on main. Manual: python3 scripts/bump_version.py minor --stream desktop.

Full policy, path list, and troubleshooting: control-center-versioning.md · release runbook: desktop-release-runbook.md.


Desktop (Tauri)

Package: @spanda/control-center-desktop (packages/control-center-desktop).

  1. Start the API:
    • ./target/release/spanda control-center serve --bind 127.0.0.1:8080 (release build), or
    • spanda control-center serve --bind 127.0.0.1:8080 (installed)
  2. Dev shell: npm run control-center:desktop:dev (Vite on port 5174)
  3. Optional API URL: VITE_CONTROL_CENTER_URL=http://host:port

The desktop shell reuses ControlCenterPanel from @davalgi-spanda/web; it does not embed spanda-api. Production installers ship via desktop-v* tags → .github/workflows/desktop-release.yml → GitHub Release (macOS .dmg / .app.tar.gz) plus workflow artifacts. Pre-flight: ./scripts/verify_desktop_release_ready.sh. Optional codesign/notarize: ./scripts/sign_tauri_macos.sh when Apple secrets are set. See packages/control-center-desktop/README.md · desktop-release-runbook.md · control-center-versioning.md.

Current release: 0.6.3 — tag desktop-v0.6.3 on GitHub Releases.


Status

Stable (Phase E1–E4). Includes device pool provisioning, multi-transport discovery with production TLS policy, WebSocket telemetry streaming, OTLP trace/metrics export, SLO burn-rate monitor, PagerDuty bi-directional sync, compliance export with signed profile catalog, scheduled report delivery, digital thread query with full lifecycle graph UI, executive scorecard, report composer (including PDF), Grafana dashboard templates (spanda-grafana-dashboards), official SDKs 0.4.2, and Tauri desktop 0.6.3 production release (desktop-v0.6.3) with sidebar/CLI/API version display.