From fa6eca3eda89e88b01f58bc01ef60f3e7e5473fb Mon Sep 17 00:00:00 2001 From: Agando Date: Fri, 23 Oct 2026 14:39:45 +0200 Subject: fix(newos4): unmeasured skills are untracked, world-model writes verified, skill audit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit External review packet (os4-external-review-v4.6.51.html) triaged against the code: 2 findings confirmed and fixed, 4 could not be reproduced and were recorded as such. - module-memory-graph.js: getStaleSkills() treated a missing lastUsed as 999 days unused, so skill-audit recommended archiving every skill (22 of 22). Skills with no usage telemetry are now collected by getUntrackedSkills() and never counted stale. Live: "Stale: 0" + "Untracked: 22 (no usage telemetry — NOT stale)". - module-world-model.js: _saveToVFS() ignored fsWriteJSON()'s return value and promoted whatever a truthy read returned. Now write -> read-back -> byte compare -> promote, with every return checked. Regression test modules/test/test-world-model-save.js (red on the old code: promoted=true with errs=[]; green now). - scripts/newos4-skill-audit.py: 5 mechanical probes (version x3, read_file paging + context budget, selection symbols, required scripts, extKeys) + skill presence; exits non-zero on drift. 7/7 pass today. Weekly job cb6bc2a16216 runs it Mondays. Not reproduced (recorded in admin/docs/newos4-external-review-verification-2026-10-23.md): world_model_query empty-payload throw (live call returns JSON), pipes-as-command-names, ls skills empty (23 entries via fs.readDir), ~66 agent dirs (4 live). --- modules/ext/skill-pack-core.js | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'modules/ext/skill-pack-core.js') diff --git a/modules/ext/skill-pack-core.js b/modules/ext/skill-pack-core.js index f204e70..5c317a4 100644 --- a/modules/ext/skill-pack-core.js +++ b/modules/ext/skill-pack-core.js @@ -1054,8 +1054,10 @@ class SkillPackCoreModule { // 1. Stale check const mg = this.terminal?.moduleManager?.modules?.['MemoryGraphModule']; var staleSkills = []; + var untracked = []; if (mg && typeof mg.getStaleSkills === 'function') { staleSkills = mg.getStaleSkills(); + untracked = (typeof mg.getUntrackedSkills === 'function') ? mg.getUntrackedSkills() : []; } for (var s of staleSkills) { if (!index[s.name] || index[s.name].immune) continue; @@ -1093,6 +1095,9 @@ class SkillPackCoreModule { this.terminal.print('Total skills: ' + allNames.length, 'info'); this.terminal.print('Healthy: ' + healthy, 'success'); this.terminal.print('Stale: ' + stale.length + (stale.length > 0 ? ' (' + stale.join(', ') + ')' : ''), stale.length > 0 ? 'warning' : 'info'); + if (untracked.length) { + this.terminal.print('Untracked: ' + untracked.length + ' (no usage telemetry — NOT stale)', 'info'); + } this.terminal.print('Duplicates: ' + duplicates.length + (duplicates.length > 0 ? ' (' + duplicates.join(', ') + ')' : ''), duplicates.length > 0 ? 'warning' : 'info'); this.terminal.print('Broken refs: ' + brokenRefs, brokenRefs > 0 ? 'error' : 'info'); this.terminal.print('', ''); -- cgit v1.2.3