From cd4aee4e74a9d635ea6ca133eedc890f48a776dd Mon Sep 17 00:00:00 2001 From: legop3 Date: Mon, 28 Sep 2026 17:43:23 -0400 Subject: [PATCH] slop --- plans/rover learning service.md | 13 +++++++++++ .../services/roverLearningService/models.js | 23 ++++++++++++++++++- .../services/roverLearningService/runtime.js | 2 ++ server/src/services/turnService/index.js | 2 ++ .../components/vip/VipRoverLearningCard.jsx | 5 +--- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/plans/rover learning service.md b/plans/rover learning service.md index 86ce466d..4d51bfbc 100644 --- a/plans/rover learning service.md +++ b/plans/rover learning service.md @@ -786,3 +786,16 @@ no new training reset or configuration migration is required. - Focused Node syntax and Python worker entry-point checks passed. Targeted card lint is run for the UI change. End-to-end training/promotion, snapshot copying, active-session pinning and browser behavior remain unverified without live data. + + +### UI cleanup and obsolete models + +User explicitly requested removal of UI narration and deletion of obsolete models. +Removed snapshot/threshold explanatory prose and the old commented manual-control +note; idle status now says Stopped. Kept operational status/errors and diagnostics. +Enabled-service startup now deletes permanent model directories whose validated +manifest explicitly identifies policy format 1, even when training is disabled. +Format 2 snapshots, Latest/Previous, recordings and current training state remain. +This supersedes earlier promises to preserve incompatible format 1 model files. +Deletion occurs on the actual server when the updated service starts; no production +files were accessed from this development machine. diff --git a/server/src/services/roverLearningService/models.js b/server/src/services/roverLearningService/models.js index 019bc50a..ad9a794b 100644 --- a/server/src/services/roverLearningService/models.js +++ b/server/src/services/roverLearningService/models.js @@ -98,6 +98,27 @@ function saveSnapshot(root) { return model; }); } +// Explicitly retire format 1 models after the wheel-policy replacement. Only +// recognized old-format manifests qualify; malformed or future models are kept. +function removeObsoleteModels(root) { + return serial(async () => { + const directory = path.join(root, 'models'); + let entries; + try { entries = await fs.readdir(directory, { withFileTypes: true }); } + catch (error) { if (error.code === 'ENOENT') return; throw error; } + for (const entry of entries) { + if (!entry.isDirectory() || !UUID.test(entry.name)) continue; + const target = path.join(directory, entry.name); + let model; + try { model = await metadata(target); } + catch { continue; } + if (model.specification?.version === 1 && !leases.has(target)) { + await fs.rm(target, { recursive: true }); + } + } + }); +} + function listModels(root) { return serial(async () => { let entries; @@ -116,4 +137,4 @@ function listModels(root) { return models; }); } -module.exports = { listModels, acquireModel, adoptCheckpoint, saveSnapshot }; +module.exports = { removeObsoleteModels, listModels, acquireModel, adoptCheckpoint, saveSnapshot }; diff --git a/server/src/services/roverLearningService/runtime.js b/server/src/services/roverLearningService/runtime.js index c7580943..dfe2591e 100644 --- a/server/src/services/roverLearningService/runtime.js +++ b/server/src/services/roverLearningService/runtime.js @@ -13,6 +13,7 @@ const { createRecording } = require('./recording'); const { recoverRecordings, enforceRetention } = require('./storage'); const { createTrainer } = require('./training'); const { createDriving } = require('./driving'); +const { removeObsoleteModels } = require('./models'); const { createGateway } = require('./socketGateway'); function createRuntime({ config, logger }) { @@ -221,6 +222,7 @@ function createRuntime({ config, logger }) { async function start() { await fs.mkdir(recordingsRoot, { recursive: true }); await recoverRecordings(recordingsRoot); + await removeObsoleteModels(root); await trainer.start(); running = true; driving.attach(); diff --git a/server/src/services/turnService/index.js b/server/src/services/turnService/index.js index f73eac54..1d7f0206 100644 --- a/server/src/services/turnService/index.js +++ b/server/src/services/turnService/index.js @@ -397,6 +397,8 @@ function advanceTurn(roverId) { return; } if (queue.queue.length === 0) { + // Empty queues must not expose the departed driver through turn.currentId. + queue.current = null; stopRover(roverId); clearTurnTimer(roverId, queue); setActiveDriver(roverId, null); diff --git a/webui/src/components/vip/VipRoverLearningCard.jsx b/webui/src/components/vip/VipRoverLearningCard.jsx index ef9f4e72..96651053 100644 --- a/webui/src/components/vip/VipRoverLearningCard.jsx +++ b/webui/src/components/vip/VipRoverLearningCard.jsx @@ -130,7 +130,7 @@ function LearningCard({ roverId }) { return

- {session ? `${session.modelName} · ${session.status}` : state ? 'Choose a model to control your rover.' : 'Waiting for rover learning status…'} + {session ? `${session.modelName} · ${session.status}` : state ? 'Stopped' : 'Waiting for rover learning status…'}