diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 4c7b80d..7032b7f 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -62,9 +62,12 @@ jobs: APPDATA: ${{ runner.temp }}/kit-home/AppData/Roaming run: node bin/agentic-kit.mjs x verify security - # Non-blocking: ruflo neural train crashes on macos-latest with a native - # libc++abi mutex abort, tracked upstream at ruvnet/ruflo#2885 (open as of - # 2026-08-06). Remove continue-on-error once that issue closes. + # Non-blocking: a native libc++abi mutex abort on macos-latest poisons ruflo + # exit codes, tracked upstream at ruvnet/ruflo#2885 (open as of 2026-08-13). + # Scope is NOT neural-train-specific: upstream evidence (2026-08-12) shows the + # same teardown abort on store-touching commands (`memory search` → correct + # output, rc 134), so an `x verify memory` step added here would need the same + # guard. Remove continue-on-error once that issue closes. - name: Deep proof against the live packages (learning) continue-on-error: true env: diff --git a/src/templates/statusline-footer.cjs b/src/templates/statusline-footer.cjs index 71bc507..5992119 100644 --- a/src/templates/statusline-footer.cjs +++ b/src/templates/statusline-footer.cjs @@ -56,7 +56,7 @@ function rufloActivationSegments(cwd){ } } catch(e){ rufloStatuslineDebug("quota-tee", e); } function bar(n, max){ n = Math.max(0, Math.min(max, n)); return "[" + "●".repeat(n) + "○".repeat(max - n) + "]"; } - // ── self-learning (SONA): own line with a volume bar (patterns/traj/HNSW) plus a + // ── self-learning (SONA): own line with a volume bar (patterns/traj) plus a // LIVE micro-LoRA adaptation field (Δ‖W‖, appended further below). The Δ‖W‖ tracker // is maintained inline in this same function — see the "micro-LoRA LIVE adaptation" // block after the route-Q segment. @@ -69,7 +69,6 @@ function rufloActivationSegments(cwd){ if (pn > 0 || tj > 0) { if (pn > 0) parts.push(pn + " patterns"); if (tj > 0) parts.push(tj + " traj"); - if (fs.existsSync(path.join(cwd, ".swarm", "hnsw.index"))) parts.push(G + "⚡ HNSW" + R); var dots = Math.max(0, Math.min(5, Math.round(pn / 10))); // volume gauge: ~10 patterns per dot learn = C + "🧠 SONA" + R + " " + DIM + bar(dots, 5) + R + " " + parts.join(DIM + " · " + R); } diff --git a/tests/statusline-segments.test.cjs b/tests/statusline-segments.test.cjs index 7f62eb0..fd69108 100644 --- a/tests/statusline-segments.test.cjs +++ b/tests/statusline-segments.test.cjs @@ -107,6 +107,17 @@ test('SONA segment absent when counts are zero', () => { absent(out, '🧠 SONA'); }); +// #140: index-file existence proves nothing about the active search path +// (upstream default is brute-force cosine, ruflo#2922) — the footer shows only +// genuinely active features, so no HNSW claim at all. +test('hnsw.index on disk produces no HNSW claim (#140)', () => { + const out = strip(rufloActivationSegments(mkFixture({ + '.claude-flow/neural/stats.json': { patternsLearned: 50, trajectoriesRecorded: 110 }, + '.swarm/hnsw.index': 'binary-ish', + }))); + absent(out, 'HNSW'); +}); + // ── route Q-learner segment ─────────────────────────────────────────────── test('route 📈 RL renders ε/δ̄/|Q|/upd when updateCount > 0', () => { const out = strip(rufloActivationSegments(mkFixture({ @@ -521,7 +532,7 @@ test('unresolvable ruflo → silent (a probe miss must never fail loud and wrong // Test-quality Finding 5: bump deliberately when adding/removing a test — // see admin-model.test.cjs's identical guard for the full rationale. -const EXPECTED = 45; +const EXPECTED = 46; if (passed + failed !== EXPECTED) { console.error(`\nPLAN MISMATCH: expected ${EXPECTED} tests, ran ${passed + failed}`); process.exit(1);