diff --git a/training/dashboard/static/dashboard.js b/training/dashboard/static/dashboard.js
index af7ee09..96f5935 100644
--- a/training/dashboard/static/dashboard.js
+++ b/training/dashboard/static/dashboard.js
@@ -2272,11 +2272,10 @@ def train_nn(*, model, X_train, y_train, X_val, y_val,
const PROFILES = ['cpu-saturate', 'ransomware-lite', 'bursty-c2', 'fork-bomb', 'crypto-miner'];
const PHASES = ['clean', 'armed', 'infecting', 'infected_running', 'dormant'];
let counter = 0;
- // Inference rate is bounded by how often new 10-second windows
- // close on the fleet, not by A100 forward-pass speed. With ~3
- // hosts × one window every 10 s × 5 models = ~1.5 events/sec
- // total — so the demo ticks every 2.5 s to stay honest. Going
- // any faster is misleading about real deployment cadence.
+ // ~1 event/sec — slow enough that the audience can read each
+ // prediction as it lands, fast enough that the lanes feel
+ // alive. Real ceiling is ~1.5/sec (3 hosts × 5 models × one
+ // window every 10 s) so we're under it but not by a lot.
demoTimer = setInterval(() => {
const m = MODELS[counter % MODELS.length];
counter++;
@@ -2297,7 +2296,7 @@ def train_nn(*, model, X_train, y_train, X_val, y_val,
window_idx: counter,
t_wall: Date.now() / 1000,
});
- }, 2500);
+ }, 1000);
}
function demoStop() {
demoActive = false;
diff --git a/training/dashboard/static/index.html b/training/dashboard/static/index.html
index 7e97501..4f3c5a4 100644
--- a/training/dashboard/static/index.html
+++ b/training/dashboard/static/index.html
@@ -1313,6 +1313,6 @@
-
+