MÓDULO VALIDATOR.Art¶
Central enrollment + role assignment + ML cortex orchestration brain.
Function¶
The bench's orchestration brain. Receives /enroll calls from
TBI-booting nodes, validates HMAC claim tokens issued by the
operator, computes role assignments from hardware fingerprint +
topology hints + cluster occupancy, returns a JoinBundle (k3s join
token + CA bundle + WireGuard peers + MÓDULO manifest refs).
Phase A (V-1..V-4) ships the receiver surface in SimulatedMode. Phase B wires CA.Art real cert issuance, k3s server token, WireGuard peer pinning. Phase E adds the ML cortex sidecar.
Identity¶
| Element | Value |
|---|---|
| Plane | MGMT (cloud-portable per discuss_validator_tech_stack_2026_05_10) |
| Internal code | validator-art |
| K8s namespace | oobi-fabric |
| OOBI slot | .97 (slot .84 from original memo reassigned to api-infra-art before scaffold) |
| Network | OOBI VLAN 99 only (no DATA-plane attachments) |
| ADR | ADR-0086 |
HTTP endpoints (port 8086 cluster-internal)¶
| Method | Path | Purpose |
|---|---|---|
| GET | /healthz |
liveness probe |
| GET | /metrics |
Prometheus text |
| GET | /status |
JSON snapshot (sim mode + counts + version) |
| POST | /enroll |
TBI boot agent → validator |
| POST | /heartbeat |
node liveness bump |
| GET | /nodes |
newest-first []NodeRegistration |
| GET | /nodes/{id} |
one node or 404 |
| GET | /claim-tokens |
[]ClaimToken |
| POST | /claim-tokens |
operator issues a new token |
Enrollment flow (Phase A SimulatedMode)¶
PHASE 1 Operator issues claim token via /admin/validator-art
→ POST /claim-tokens → token saved in store + (real-mode)
HMAC-signed wire string returned
PHASE 2 Operator embeds token in TBI cloud-init user-data OR
USB `claim.token` file
PHASE 3 TBI boots → ZTP boot agent gathers HardwareFingerprint
(lshw + ipmitool + dmidecode) → POSTs /enroll with the
claim-token string + hardware + tbi_version
PHASE 4 VALIDATOR.Art:
a. SimulatedMode → skip token verification
b. Real-mode → claimtoken.Verify (HMAC-SHA256 constant-time)
→ store check (consumed/expired) → fail-fast 401
c. roleassign.Compute(hw, hints, view) → role assignment
d. Record NodeRegistration + consume token if one-time-use
e. Return JoinBundle (k3s join token + CA bundle + peers
+ module manifests — placeholders in Phase A)
PHASE 5 TBI agent joins k3s + bootstraps Multus + applies MÓDULO
manifests from the JoinBundle (Phase B+)
PHASE 6 Ongoing: POST /heartbeat every 60s; status flips
enrolled → active → stale (no heartbeat for 10 min)
Role assignment heuristic (V-2)¶
Pure rules, no ML cortex (Phase E replaces). Operator hint wins when hardware fits, fallback rationale otherwise.
| Hardware floor | Assigned role | Plane |
|---|---|---|
| DPDK-capable + ≥ 16 cores + ≥ 16 GB | trex-agent |
DATA |
| GPU detected | ml-cortex |
MGMT |
| ≥ 8 cores + ≥ 32 GB | ngfw-dut |
DATA |
| ≥ 4 cores | agents |
DATA |
| else | infra |
MGMT |
DeploymentMode inferred from cluster occupancy:
- 1 node → single
- 2 → dual
- 3 → tri
- ≥ 4 → multi
K3SRole: first enrolled → server; all others → agent.
Claim token format¶
Wire format: <payload-b64url>.<sig-b64url>. Payload is JSON
{v: 1, id, issued_by, issued_at, expires_at, one_time, topology};
signature is HMAC-SHA256 over the body using the operator-supplied
secret (configured via VALIDATOR_CLAIM_TOKEN_SECRET env var from
the K8s Secret).
Verification uses subtle.ConstantTimeCompare so timing attacks
can't probe the secret one byte at a time. The HMAC alone proves
the token was issued by us; the store proves it hasn't already been
spent (one-time-use Consumed bit).
Operator controls¶
/admin/validator-art is the canonical surface (per CLAUDE.md
"Dashboard is the ONLY operator interface"):
| Section | Action |
|---|---|
| Live status header | Version + node count + token count; SimulatedMode warning banner when active. Polls /status 5s |
| Recent enrollments | Node row per enrolled TBI: node_id + hostname + hardware (cores · GB · DPDK · GPU) + role (node_role + k3s_role) + deployment_mode + colored status (green active / amber stale) + enrolled_at |
| Claim-token issuance | Form: issued_by (required) + expires_in_hours (1-168) + preferred_role (optional) + one_time checkbox. Active tokens table shows consumed-by indicator |
Tier policy¶
VALIDATOR.Art is foundational infrastructure — all tiers can use it. Without ZTP enrollment, multi-node deploy is impossible; gating it behind tier would make the product unusable for any customer beyond a single laptop. The operator pays for what runs on top of the enrolled nodes (TREX, KALI, HAR, etc. — those have tier caps).
Persistent storage¶
Two layers:
- Pod runtime — in-memory ring buffer (200 entries default, configurable via
--max-nodes). Survives pod restart by re-enrollment within the heartbeat window - Dashboard Postgres — Drizzle 0040 migration writes every enrollment + token issuance for long-term audit. Tables:
validator_art_enrollments+validator_art_claim_tokens. Bytes-level history not in the validator pod itself (which would defeat the cloud-portable design)
Key telemetry¶
| Metric | Description |
|---|---|
validator_art_nodes_total{status} |
Current enrolled-node count broken down by status (active / enrolled / stale) |
validator_art_claim_tokens_total |
Active claim tokens in the in-memory store |
validator_art_simulated_mode |
1 when /enroll returns synthetic JoinBundles, 0 in real-mode |
Hardware footprint¶
| Component | Image size | RAM baseline | CPU baseline |
|---|---|---|---|
| validator-art (Go) | ~25 MB | 128 MiB | 100m CPU |
| Postgres (shared with Dashboard) | ~150 MB | 1-4 GB | 1-2 vCPU |
| (Phase E) ml-cortex sidecar | ~500 MB | 1 GB | 2 vCPU |
Fits comfortably in any single host even on low-end 32GB/16-core hardware (Phase A only needs ~256 MiB).
Deferred (post-Phase-A)¶
- Phase B ✅ shipped (ADR-0089): 4 bridge adapters with Disabled/Fake/real triple — CA.Art via cert-manager
CertificateRequest, k3s join via on-disk node-token, WireGuard peers viaConfigMap(Phase B-late) or JSON file, ArgoCD App-of-Apps via remote git push (Phase B-late) or PVC writer - Phase C: Cascade ZTP relay daemon (multi-hop bootstrap)
- Phase D: TBI v0.5 + 7-mechanism passive discovery cascade
- Phase E: ML cortex sidecar (Python + PyTorch) replacing the heuristic role-assignment with a learned model
- Phase F: TBI v0.9 + active discovery (NMAP/SNMP) + cable forensics
- Phase G: Topology dashboard live force-directed graph
- Phase H: Multi-VALIDATOR federation HA + multi-site
- Phase I: TBI v1.0 production-grade multi-format release (ISO / IMG / PXE / OCI)
- Phase J: Air-gap heroics + intent-based provisioning
Related¶
- Strategic memo:
discuss_module_validator_tbi_2026_05_10 - Tech stack:
discuss_validator_tech_stack_2026_05_10 - Vs CLONER.Art:
project_validator_vs_cloner_clarification_2026_05_10 - ADR: ADR-0086
- Sibling MÓDULOs: TREX.Art (ADR-0085) · HAR.Art (ADR-0084) · KALI.Art (ADR-0083) · HyperBridge.Art (ADR-0036)
- Patent posture: no new claim in Phase A; Patent Family E reserved for Phase E ML cortex