Models a nation's critical infrastructure as a transverse-field Ising lattice. Alert levels emerge from quantum phase transitions, not rule thresholds.
16 infrastructure nodes (energy, transport, comms, finance) are spins in a weighted Ising Hamiltonian. OSINT signals inject a transverse field h_i per node. As social friction rises, the system approaches a quantum critical point — magnetization drops, entanglement entropy peaks. That's the threat signal.
H = -Σ_{<i,j>} J_ij σ_i^z σ_j^z - Σ_i h_i σ_i^x
NAA level maps to the order parameter √⟨M²⟩:
| level | condition | meaning |
|---|---|---|
| 1 | M > 0.8 | ferromagnetic, stable |
| 2 | 0.5 < M ≤ 0.8 | slight disorder |
| 3 | 0.2 < M ≤ 0.5 | critical region |
| 4 | 0.05 < M ≤ 0.2 | near-collapse |
| 5 | M ≤ 0.05 | paramagnetic, max threat |
The critical point (entropy peak) sits around h_c ≈ J. The Python demo sweeps h from 0.1 to 3.0 and prints the transition.
EIGEN/
├── cuda/
│ ├── include/eigen_lanczos.h # C ABI for the CUDA solver
│ └── src/lanczos.cu # GPU Lanczos — written, not yet compiled
├── eigen/
│ ├── demo.py # CLI phase-transition sweep, runs now
│ ├── cuda/
│ │ └── ising_simulator.py # scipy sparse + CuPy Ising solver
│ └── topology/
│ └── spain.py # 16-node Spain coupling matrix
├── rust/
│ ├── Cargo.toml
│ ├── migrations/
│ │ └── 0001_initial_schema.sql # 7 tables: nodes, OSINT, friction, states, audit
│ └── src/
│ ├── main.rs # eframe entry, watch channel, tokio thread
│ ├── engine.rs # background loop, calls pure-Rust solver
│ ├── ising_solver.rs # pure-Rust Lanczos, N=16, dim=65536
│ ├── lanczos_bridge.rs # FFI to libeigen_lanczos.a — stub (unlinked)
│ ├── db.rs # SQLite/WAL layer, full CRUD + audit chain
│ ├── state.rs # TacticalState, NodeState, BlochCoords
│ └── ui.rs # egui 4-panel dashboard, 60 FPS
├── pyproject.toml
└── README.md
| component | status | notes |
|---|---|---|
| pure-Rust Lanczos (N=16) | works | implicit H|ψ⟩, QR+Wilkinson shift, extracts E₀, M, S_vN, purity, ⟨σᵢᶻ⟩ |
| egui native dashboard | works | NAA gauge, node scatter map, entropy/mag timeline, event log |
| engine → UI watch channel | works | lock-free, always-latest-value, ~1–2 Hz solve rate |
| Python Ising simulator | works | scipy sparse eigsh (CPU) + CuPy eigsh (GPU), ITE fallback |
| Spain coupling topology | works | 16 nodes, inter-sector J_ij based on real dependencies |
| Python demo (CLI sweep) | works | python -m eigen.demo — phase transition with ANSI output |
| SQLite schema + db.rs | complete, unwired | 7 tables, SHA-256 audit chain, all queries written; init_pool() never called from main |
| CUDA Lanczos | written, not compiled | lanczos.cu implements cuBLAS + ising_matvec kernel + LAPACK dstev_; no build.rs/Makefile; lanczos_bridge.rs exists but engine never calls it |
| OSINT ingestion | stub | engine fakes headlines from a hardcoded array; reqwest/feed-rs are in Cargo.toml; no real HTTP polling loop |
| NLP friction model | absent | inject_friction(h_vector) interface exists in Python; no NLP code written |
| Python dashboard | absent | dash/plotly in pyproject.toml, no dashboard.py |
┌─────────────────────────────────┐
OSINT (STUB) │ Rust — background tokio thread │
hardcoded headlines ──▶ │ engine::run_engine() │
│ ├─ IsingConfig (weighted bonds) │
real path (todo): │ ├─ ising_solver::solve() │ ◀── pure Rust (active)
Twitter/GDELT/RSS ──▶ │ │ Lanczos N=16, dim=65536 │
h_vector from NLP │ └─ watch::Sender<TacticalState> │
└────────────┬────────────────────┘
│ lock-free watch channel
┌────────────▼────────────────────┐
│ Rust — main thread (eframe) │
│ ui::EigenApp::update() @ 60 FPS │
│ ├─ NAA gauge (left panel) │
│ ├─ node scatter map (center) │
│ ├─ entropy timeline (right) │
│ └─ OSINT event log (bottom) │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ CUDA path (not yet wired) │
│ cuda/src/lanczos.cu │
│ → libeigen_lanczos.a │
│ → lanczos_bridge.rs (FFI) │
│ → engine.rs (replace solver) │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ SQLite (not yet wired) │
│ db.rs: insert_osint_event() │
│ insert_friction_tensor() │
│ insert_quantum_state() │
│ append_audit() (chained) │
│ → shared bus for all components │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ Python (standalone, works now) │
│ eigen/cuda/ising_simulator.py │
│ eigen/topology/spain.py │
│ eigen/demo.py │
└─────────────────────────────────┘
Rust · CUDA · Python · egui/eframe · tokio · cuBLAS · scipy.sparse · CuPy · SQLite/WAL · sqlx · LAPACK (dstev_)
pip install -e ".[dev]"
python -m eigen.demosweeps h from 0.1 → 3.0, prints phase transition table with NAA levels and per-node spin states. GPU (CuPy) used automatically if available; falls back to scipy.
cd rust
cargo run --releaseopens a native 1400×900 window. pure-Rust Lanczos runs at ~1–2 Hz. OSINT feed shows simulated headlines. no CUDA required for this path.
dependencies: eframe needs wgpu — on Linux, needs a display and either libvulkan or libGL.
next step: write cuda/CMakeLists.txt or build.rs, compile lanczos.cu against libcublas/libcurand/liblapack, output libeigen_lanczos.a, wire lanczos_bridge.rs into engine.rs. the FFI signature is already defined on both sides.
pip install cupy-cuda12x
python -m eigen.demo # GPU_AVAILABLE = True auto-detected- compile CUDA path and replace
ising_solver.rswithlanczos_bridge.rsin engine - wire
db::init_pool()intomain.rs, connect engine loop toinsert_quantum_state()/insert_osint_event() - real OSINT: implement
reqwestpolling for GDELT events API + RSS feeds, parse intoOsintEvent, computeh_vectorfrom keyword/entity scoring - NLP friction model: map text → per-node sentiment →
h_iinjection into Hamiltonian - Python dashboard:
dash+plotlyalready in pyproject, implementeigen/dashboard.pyreading from SQLite
16 Spanish infrastructure nodes, 4 sectors. coupling weights reflect real interdependencies.
energy : Nuclear_Vandellós · Grid_REE · Gas_Medgaz · Renewables_Sur
transport : AVE_Madrid · Port_Algeciras · Airport_Barajas · Freight_Zaragoza
comms : Telco_Telefónica · IX_Espanix · Sat_Hispasat · 5G_Core_Madrid
finance : IBEX_DC · Payment_SNCE · BancoEspaña · Crypto_Hub
critical cross-sector bonds: Grid_REE → Telco (J=0.85), IX_Espanix → IBEX_DC (J=0.90). these are the cascade paths.
the Hilbert space is 2¹⁶ = 65536. the Hamiltonian is never materialized as a dense matrix — H|ψ⟩ is applied implicitly in O(N·dim) time per matvec. the Rust solver uses Krylov subspace (Lanczos) with QR iteration and Wilkinson shift on the tridiagonal. the Python solver uses ARPACK via scipy.sparse.linalg.eigsh, same algorithm.
magnetization reported is √⟨M²⟩, not ⟨M⟩. for a finite Z₂-symmetric system, ⟨M⟩ = 0 by symmetry even in the ordered phase. ⟨M²⟩ is the correct finite-size order parameter.
entropy is Rényi-2 (S₂ = −log₂ Tr(ρ_A²)) in the Rust path, von Neumann in the Python path. both peak at the critical point. the Python path computes the full reduced density matrix via reshape → ρ_A = ψ ψ†; the Rust path computes Tr(ρ_A²) directly without building ρ_A.
security is a quantum observable. measure it or lose it.