From 4572e50bb21678eaa463a046ce9f9f71a3b82fc1 Mon Sep 17 00:00:00 2001 From: Mikael Hugo Date: Thu, 7 May 2026 01:31:16 +0200 Subject: [PATCH] fix: align memory dispatch tests with store api --- src/resources/extensions/sf/auto-dispatch.js | 7 +- src/resources/extensions/sf/memory-store.js | 2 + .../sf/tests/crash-recovery.test.ts | 64 ++++++++++++++----- .../sf/tests/gate-context-enrichment.test.mjs | 10 +-- .../extensions/sf/tests/metrics.test.ts | 22 +++---- .../extensions/sf/tests/phases-fsm.test.ts | 64 ++++++++++++------- .../sf/tests/triage-self-feedback.test.ts | 64 +++++++++++++++---- .../sf/tests/uok-memory-integration.test.mjs | 13 ++-- .../extensions/sf/uok/gate-runner.js | 12 ++-- .../extensions/sf/uok/unit-runtime.js | 4 +- 10 files changed, 173 insertions(+), 89 deletions(-) diff --git a/src/resources/extensions/sf/auto-dispatch.js b/src/resources/extensions/sf/auto-dispatch.js index 8d0ca339e..6019933ce 100644 --- a/src/resources/extensions/sf/auto-dispatch.js +++ b/src/resources/extensions/sf/auto-dispatch.js @@ -51,7 +51,10 @@ import { parseDeferredRequirements, resolveAllOverrides, } from "./files.js"; -import { getRelevantMemoriesRanked } from "./memory-store.js"; +import { + getRelevantMemoriesRanked, + isDbAvailable as isMemoryDbAvailable, +} from "./memory-store.js"; import { getMilestonePipelineVariant } from "./milestone-scope-classifier.js"; import { buildMilestoneFileName, @@ -464,7 +467,7 @@ When done, say: "Validation attention remediated; ready for revalidation."`; * Consumer: Dispatch rules for unit prioritization. */ export async function enhanceUnitRankingWithMemory(units, baseScores = {}) { - if (!isDbAvailable()) { + if (!isMemoryDbAvailable()) { // No memory available, return original ranking return units; } diff --git a/src/resources/extensions/sf/memory-store.js b/src/resources/extensions/sf/memory-store.js index f4299152b..1079a668c 100644 --- a/src/resources/extensions/sf/memory-store.js +++ b/src/resources/extensions/sf/memory-store.js @@ -18,6 +18,8 @@ import { updateMemoryContentRow, } from "./sf-db.js"; +export { isDbAvailable }; + // ─── Category Display Order ───────────────────────────────────────────────── const CATEGORY_PRIORITY = { gotcha: 0, diff --git a/src/resources/extensions/sf/tests/crash-recovery.test.ts b/src/resources/extensions/sf/tests/crash-recovery.test.ts index 988fe8df4..1d393ea04 100644 --- a/src/resources/extensions/sf/tests/crash-recovery.test.ts +++ b/src/resources/extensions/sf/tests/crash-recovery.test.ts @@ -9,10 +9,16 @@ * reconciles state after crash. Both must handle corrupted/missing state gracefully. */ -import { describe, it, expect, beforeEach, afterEach, vi } from "vitest"; -import { join } from "path"; -import { mkdirSync, rmSync, writeFileSync, readFileSync, existsSync } from "fs"; -import { tmpdir } from "os"; +import { + existsSync, + mkdirSync, + readFileSync, + rmSync, + writeFileSync, +} from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { afterEach, beforeEach, describe, expect, it } from "vitest"; // Test helpers const testDir = join(tmpdir(), `recovery-test-${Date.now()}`); @@ -60,7 +66,7 @@ describe("crash-recovery", () => { // Clear lock const clearLock = (path) => { if (existsSync(path)) { - const fs = require("fs"); + const fs = require("node:fs"); fs.unlinkSync(path); } }; @@ -107,7 +113,7 @@ describe("crash-recovery", () => { try { if (!existsSync(path)) return null; return JSON.parse(readFileSync(path, "utf-8")); - } catch (err) { + } catch (_err) { return null; } }; @@ -266,11 +272,18 @@ describe("crash-recovery", () => { it("handles corrupt session entries gracefully", () => { const sessionPath = join(testDir, "session.jsonl"); - writeFileSync(sessionPath, JSON.stringify({ id: "t-001", status: "done" }) + "\n"); + writeFileSync( + sessionPath, + JSON.stringify({ id: "t-001", status: "done" }) + "\n", + ); writeFileSync(sessionPath, "{ corrupt json line }\n", { flag: "a" }); - writeFileSync(sessionPath, JSON.stringify({ id: "t-002", status: "done" }) + "\n", { - flag: "a", - }); + writeFileSync( + sessionPath, + JSON.stringify({ id: "t-002", status: "done" }) + "\n", + { + flag: "a", + }, + ); const readSessionLog = (path) => { if (!existsSync(path)) return []; @@ -447,7 +460,11 @@ describe("auto-recovery", () => { return changedFiles.some((f) => !f.startsWith(".sf/")); }; - const allChanges = [".sf/STATE.md", ".sf/milestones/M001.md", "src/index.ts"]; + const allChanges = [ + ".sf/STATE.md", + ".sf/milestones/M001.md", + "src/index.ts", + ]; expect(hasImplFiles(allChanges)).toBe(true); const sfOnly = [".sf/STATE.md", ".sf/milestones/M001.md"]; @@ -456,9 +473,16 @@ describe("auto-recovery", () => { it("detects files changed during milestone", () => { const baselineFiles = ["src/a.ts", "src/b.ts"]; - const afterMilestone = ["src/a.ts", "src/b.ts", "src/c.ts", ".sf/STATE.md"]; + const afterMilestone = [ + "src/a.ts", + "src/b.ts", + "src/c.ts", + ".sf/STATE.md", + ]; - const changedFiles = afterMilestone.filter((f) => !baselineFiles.includes(f)); + const changedFiles = afterMilestone.filter( + (f) => !baselineFiles.includes(f), + ); expect(changedFiles).toContain("src/c.ts"); expect(changedFiles).toContain(".sf/STATE.md"); @@ -573,7 +597,10 @@ describe("auto-recovery", () => { }; const isConsistent = (m) => { - if (m.status === "done" && m.slices.some((s) => s.status === "pending")) { + if ( + m.status === "done" && + m.slices.some((s) => s.status === "pending") + ) { return false; } return true; @@ -585,14 +612,17 @@ describe("auto-recovery", () => { describe("cleanup operations", () => { it("removes temporary recovery artifacts", () => { - const tempFiles = [join(testDir, ".recovery-tmp-001"), join(testDir, ".recovery-tmp-002")]; + const tempFiles = [ + join(testDir, ".recovery-tmp-001"), + join(testDir, ".recovery-tmp-002"), + ]; tempFiles.forEach((f) => writeFileSync(f, "temp")); const cleanup = (files) => { files.forEach((f) => { if (existsSync(f)) { - const fs = require("fs"); + const fs = require("node:fs"); fs.unlinkSync(f); } }); @@ -626,7 +656,7 @@ describe("auto-recovery", () => { const clearState = (path) => { if (existsSync(path)) { - const fs = require("fs"); + const fs = require("node:fs"); fs.unlinkSync(path); } }; diff --git a/src/resources/extensions/sf/tests/gate-context-enrichment.test.mjs b/src/resources/extensions/sf/tests/gate-context-enrichment.test.mjs index 9e03ed43d..3f9392cdf 100644 --- a/src/resources/extensions/sf/tests/gate-context-enrichment.test.mjs +++ b/src/resources/extensions/sf/tests/gate-context-enrichment.test.mjs @@ -5,7 +5,7 @@ * Note: This is diagnostic only and never changes gate logic. */ -import { describe, it, expect, beforeEach, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { enrichGateResultWithMemory } from "../uok/gate-runner.js"; // Mock memory store @@ -88,8 +88,7 @@ describe("Gate Context Enrichment (Phase 3)", () => { }); it("truncates_memory_content_to_100_chars", async () => { - const longContent = - "a".repeat(200); // 200 char string + const longContent = "a".repeat(200); // 200 char string memoryStore.getRelevantMemoriesRanked.mockResolvedValueOnce([ { id: "m1", confidence: 0.8, content: longContent }, ]); @@ -280,7 +279,10 @@ describe("Gate Context Enrichment (Phase 3)", () => { const gateFail = { outcome: "fail", gateId: "security-gate" }; - const enriched = await enrichGateResultWithMemory(gateFail, "security-gate"); + const enriched = await enrichGateResultWithMemory( + gateFail, + "security-gate", + ); // Gate decision is unchanged expect(enriched.outcome).toBe("fail"); diff --git a/src/resources/extensions/sf/tests/metrics.test.ts b/src/resources/extensions/sf/tests/metrics.test.ts index 2b038ca06..0a7674bd8 100644 --- a/src/resources/extensions/sf/tests/metrics.test.ts +++ b/src/resources/extensions/sf/tests/metrics.test.ts @@ -8,15 +8,9 @@ * Model-learner integration must not throw or delay dispatch on error. */ -import { - createWriteStream, - existsSync, - mkdirSync, - readFileSync, - rmSync, -} from "fs"; -import { tmpdir } from "os"; -import { join } from "path"; +import { existsSync, mkdirSync, rmSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; // Mock module path resolution @@ -265,7 +259,7 @@ describe("metrics recording", () => { describe("persistence", () => { it("appends metrics to persistent log", () => { - const logPath = join(metricsMockPath, "metrics.jsonl"); + const _logPath = join(metricsMockPath, "metrics.jsonl"); const entries = []; const append = (entry) => { @@ -359,7 +353,7 @@ describe("metrics recording", () => { }; const dispatchPromise = Promise.resolve({ status: "done" }); - const metricPromise = recordOutcome({ unit_id: "u-001" }); + const _metricPromise = recordOutcome({ unit_id: "u-001" }); // Dispatch returns immediately, metrics happen in background const result = await dispatchPromise; @@ -372,7 +366,7 @@ describe("metrics recording", () => { describe("error cases", () => { it("handles filesystem permission error gracefully", () => { - const saveMetrics = (data, path) => { + const saveMetrics = (_data, _path) => { try { // Simulate permission denied throw new Error("EACCES: permission denied"); @@ -390,7 +384,7 @@ describe("metrics recording", () => { }); it("handles missing directory gracefully", () => { - const ensureDir = (dirPath) => { + const ensureDir = (_dirPath) => { try { // Simulate mkdir failure throw new Error("ENOENT: no such file"); @@ -410,7 +404,7 @@ describe("metrics recording", () => { const parseMetrics = (jsonString) => { try { return JSON.parse(jsonString); - } catch (err) { + } catch (_err) { console.error("Metrics data corrupted, using empty state"); return {}; } diff --git a/src/resources/extensions/sf/tests/phases-fsm.test.ts b/src/resources/extensions/sf/tests/phases-fsm.test.ts index 520addefe..2a64de9e0 100644 --- a/src/resources/extensions/sf/tests/phases-fsm.test.ts +++ b/src/resources/extensions/sf/tests/phases-fsm.test.ts @@ -11,8 +11,8 @@ * correctness across all possible paths, not just happy paths. */ -import { describe, it, expect } from "vitest"; import * as fc from "fast-check"; +import { describe, expect, it } from "vitest"; // ─── FSM State & Transition Model ─────────────────────────────────────────── @@ -29,14 +29,18 @@ const TERMINAL_STATES = new Set([FSM_STATES.DONE, FSM_STATES.FAILED]); // BLOCKE /** Valid state transitions for dispatch FSM */ const VALID_TRANSITIONS = { [FSM_STATES.PENDING]: [FSM_STATES.RUNNING, FSM_STATES.BLOCKED], - [FSM_STATES.RUNNING]: [FSM_STATES.DONE, FSM_STATES.FAILED, FSM_STATES.BLOCKED], + [FSM_STATES.RUNNING]: [ + FSM_STATES.DONE, + FSM_STATES.FAILED, + FSM_STATES.BLOCKED, + ], [FSM_STATES.DONE]: [], [FSM_STATES.FAILED]: [], [FSM_STATES.BLOCKED]: [FSM_STATES.PENDING, FSM_STATES.RUNNING], // Can retry }; /** Apply a transition to a unit state */ -function transition(currentState, nextState) { +function _transition(currentState, nextState) { if (!VALID_TRANSITIONS[currentState]) { throw new Error(`Invalid current state: ${currentState}`); } @@ -54,17 +58,16 @@ function isTerminal(state) { // ─── Arbitraries for Property Generation ──────────────────────────────────── /** Generate arbitrary unit IDs */ -const arbitraryUnitId = () => - fc.string({ minLength: 3, maxLength: 10 }); +const arbitraryUnitId = () => fc.string({ minLength: 3, maxLength: 10 }); /** Generate valid state transitions */ -const arbitraryTransition = (fromState) => { +const _arbitraryTransition = (fromState) => { const validNext = VALID_TRANSITIONS[fromState]; return fc.constantFrom(...validNext); }; /** Generate arbitrary dispatch events */ -const arbitraryDispatchEvent = () => +const _arbitraryDispatchEvent = () => fc.record({ unitId: arbitraryUnitId(), eventType: fc.constantFrom("start", "complete", "fail", "block", "unblock"), @@ -229,8 +232,11 @@ describe("FSM property-based tests", () => { describe("state transition correctness", () => { it("pending → running → done is valid", () => { fc.assert( - fc.property(arbitraryUnitId(), (unitId) => { - const result = simulateUnit(FSM_STATES.PENDING, ["start", "complete"]); + fc.property(arbitraryUnitId(), (_unitId) => { + const result = simulateUnit(FSM_STATES.PENDING, [ + "start", + "complete", + ]); return result.finalState === FSM_STATES.DONE; }), ); @@ -238,7 +244,7 @@ describe("FSM property-based tests", () => { it("pending → running → failed is valid", () => { fc.assert( - fc.property(arbitraryUnitId(), (unitId) => { + fc.property(arbitraryUnitId(), (_unitId) => { const result = simulateUnit(FSM_STATES.PENDING, ["start", "fail"]); return result.finalState === FSM_STATES.FAILED; }), @@ -247,8 +253,12 @@ describe("FSM property-based tests", () => { it("pending → running → blocked → pending (retry) is valid", () => { fc.assert( - fc.property(arbitraryUnitId(), (unitId) => { - const result = simulateUnit(FSM_STATES.PENDING, ["start", "block", "unblock"]); + fc.property(arbitraryUnitId(), (_unitId) => { + const result = simulateUnit(FSM_STATES.PENDING, [ + "start", + "block", + "unblock", + ]); return result.finalState === FSM_STATES.PENDING; }), ); @@ -274,14 +284,17 @@ describe("FSM property-based tests", () => { fc.assert( fc.property( arbitraryUnitSequence(), - fc.array(fc.constantFrom("start", "complete", "fail", "block", "unblock"), { - maxLength: 50, - }), + fc.array( + fc.constantFrom("start", "complete", "fail", "block", "unblock"), + { + maxLength: 50, + }, + ), (units, events) => { try { units.map((u) => simulateUnit(u.status, events)); return true; // Success - no crashes - } catch (err) { + } catch (_err) { return false; // Should not throw } }, @@ -311,14 +324,17 @@ describe("FSM property-based tests", () => { fc.assert( fc.property( arbitraryUnitSequence(), - fc.array(fc.constantFrom("start", "complete", "fail", "block", "unblock"), { - maxLength: 100, - }), + fc.array( + fc.constantFrom("start", "complete", "fail", "block", "unblock"), + { + maxLength: 100, + }, + ), (units, events) => { try { units.map((u) => simulateUnit(u.status, events)); return true; // Success - no crashes - } catch (err) { + } catch (_err) { return false; // Should not throw } }, @@ -392,9 +408,11 @@ describe("FSM property-based tests", () => { it("handles large unit count without degradation", () => { fc.assert( fc.property( - fc.integer({ min: 100, max: 500 }).chain((count) => - fc.constant(Array(count).fill({ status: FSM_STATES.PENDING })), - ), + fc + .integer({ min: 100, max: 500 }) + .chain((count) => + fc.constant(Array(count).fill({ status: FSM_STATES.PENDING })), + ), fc.array(fc.constantFrom("start", "complete"), { minLength: 1, maxLength: 5, diff --git a/src/resources/extensions/sf/tests/triage-self-feedback.test.ts b/src/resources/extensions/sf/tests/triage-self-feedback.test.ts index baff2207a..304f82dc0 100644 --- a/src/resources/extensions/sf/tests/triage-self-feedback.test.ts +++ b/src/resources/extensions/sf/tests/triage-self-feedback.test.ts @@ -9,7 +9,7 @@ * must not throw or block dispatch even if fix application fails. */ -import { describe, it, expect, beforeEach, vi } from "vitest"; +import { describe, expect, it, vi } from "vitest"; describe("triage-self-feedback", () => { describe("report classification", () => { @@ -57,7 +57,12 @@ describe("triage-self-feedback", () => { it("rejects unknown report types", () => { const report = { type: "unknown-type", confidence: 0.5 }; - const validTypes = ["validation-rubric", "gate-verdict", "env-vars", "coverage-gap"]; + const validTypes = [ + "validation-rubric", + "gate-verdict", + "env-vars", + "coverage-gap", + ]; expect(validTypes).not.toContain(report.type); }); }); @@ -91,10 +96,14 @@ describe("triage-self-feedback", () => { reports.forEach((r) => { const threshold = thresholds[r.type]; const shouldFix = r.confidence >= threshold; - console.log(`${r.type}: ${r.confidence} >= ${threshold} = ${shouldFix}`); + console.log( + `${r.type}: ${r.confidence} >= ${threshold} = ${shouldFix}`, + ); }); - expect(reports[0].confidence).toBeGreaterThanOrEqual(thresholds["validation-rubric"]); + expect(reports[0].confidence).toBeGreaterThanOrEqual( + thresholds["validation-rubric"], + ); expect(reports[1].confidence).toBeLessThan(thresholds["gate-verdict"]); }); @@ -108,9 +117,21 @@ describe("triage-self-feedback", () => { describe("report deduplication", () => { it("removes duplicate reports (same type, issue pattern)", () => { const reports = [ - { type: "validation-rubric", issue: "Gate verdict mismatch", severity: "high" }, - { type: "validation-rubric", issue: "Gate verdict mismatch", severity: "high" }, // Duplicate - { type: "validation-rubric", issue: "Different issue", severity: "high" }, // Different + { + type: "validation-rubric", + issue: "Gate verdict mismatch", + severity: "high", + }, + { + type: "validation-rubric", + issue: "Gate verdict mismatch", + severity: "high", + }, // Duplicate + { + type: "validation-rubric", + issue: "Different issue", + severity: "high", + }, // Different ]; const deduplicate = (list) => { @@ -168,7 +189,9 @@ describe("triage-self-feedback", () => { const prioritize = (list) => { const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 }; - return [...list].sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]); + return [...list].sort( + (a, b) => severityOrder[a.severity] - severityOrder[b.severity], + ); }; const sorted = prioritize(reports); @@ -202,7 +225,9 @@ describe("triage-self-feedback", () => { const report = { type: "coverage-gap", confidence: 0.75, - fix: { /* ... */ }, + fix: { + /* ... */ + }, }; const shouldApply = (r) => r.confidence >= 0.85; @@ -241,7 +266,13 @@ describe("triage-self-feedback", () => { } }; - const reports = [{ fix: { /* ... */ } }]; + const reports = [ + { + fix: { + /* ... */ + }, + }, + ]; expect(() => applyFixes(reports)).not.toThrow(); }); @@ -386,9 +417,14 @@ describe("triage-self-feedback", () => { ]; const summary = { - fixes: fixes.map((f) => ({ type: f.type, issue: f.issue, fixed: f.fixed })), + fixes: fixes.map((f) => ({ + type: f.type, + issue: f.issue, + fixed: f.fixed, + })), count: fixes.length, - avgConfidence: fixes.reduce((a, b) => a + b.confidence, 0) / fixes.length, + avgConfidence: + fixes.reduce((a, b) => a + b.confidence, 0) / fixes.length, }; expect(summary.count).toBe(2); @@ -411,7 +447,9 @@ describe("triage-self-feedback", () => { }; expect(parseReport({})).toBe(null); - expect(parseReport({ type: "gate-verdict", confidence: 0.9 })).toBeTruthy(); + expect( + parseReport({ type: "gate-verdict", confidence: 0.9 }), + ).toBeTruthy(); }); it("handles missing fix recommendations", () => { diff --git a/src/resources/extensions/sf/tests/uok-memory-integration.test.mjs b/src/resources/extensions/sf/tests/uok-memory-integration.test.mjs index ef341b57b..1c40f5f1e 100644 --- a/src/resources/extensions/sf/tests/uok-memory-integration.test.mjs +++ b/src/resources/extensions/sf/tests/uok-memory-integration.test.mjs @@ -5,7 +5,7 @@ * Tests cover: success/failure recording, graceful degradation, pattern quality. */ -import { describe, it, expect, beforeEach, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { recordUnitOutcomeInMemory } from "../uok/unit-runtime.js"; // Mock memory store and DB @@ -61,8 +61,7 @@ describe("UOK Memory Integration", () => { const unit = { type: "test-unit" }; const successCall = () => recordUnitOutcomeInMemory(unit, "completed", {}); - const failureCall = () => - recordUnitOutcomeInMemory(unit, "failed", {}); + const failureCall = () => recordUnitOutcomeInMemory(unit, "failed", {}); await successCall(); await failureCall(); @@ -240,17 +239,13 @@ describe("UOK Memory Integration", () => { await recordUnitOutcomeInMemory(unit, "completed", {}); - const elapsed = Date.now() - start; + const _elapsed = Date.now() - start; // Should complete (duration doesn't matter much in test) expect(memoryStore.createMemory).toHaveBeenCalled(); }); it("processes_multiple_outcomes_independently", async () => { - const units = [ - { type: "type1" }, - { type: "type2" }, - { type: "type3" }, - ]; + const units = [{ type: "type1" }, { type: "type2" }, { type: "type3" }]; for (const unit of units) { await recordUnitOutcomeInMemory(unit, "completed", {}); diff --git a/src/resources/extensions/sf/uok/gate-runner.js b/src/resources/extensions/sf/uok/gate-runner.js index 11cb039b0..77ebade60 100644 --- a/src/resources/extensions/sf/uok/gate-runner.js +++ b/src/resources/extensions/sf/uok/gate-runner.js @@ -1,11 +1,11 @@ +import { getRelevantMemoriesRanked } from "../memory-store.js"; import { getGateCircuitBreaker, getGateRunStats, insertGateRun, - updateGateCircuitBreaker, isDbAvailable, + updateGateCircuitBreaker, } from "../sf-db.js"; -import { getRelevantMemoriesRanked } from "../memory-store.js"; import { buildAuditEnvelope, emitUokAuditEvent } from "./audit.js"; import { validateGate } from "./contracts.js"; @@ -88,7 +88,7 @@ export async function enrichGateResultWithMemory(gateResult, gateId) { }; } } - } catch (err) { + } catch (_err) { // Degrade gracefully - memory enrichment never changes gate result } @@ -100,7 +100,9 @@ export async function enrichGateResultWithMemory(gateResult, gateId) { */ async function computeGateEmbedding(gateId) { try { - const gateNorm = String(gateId || "unknown").toLowerCase().trim(); + const gateNorm = String(gateId || "unknown") + .toLowerCase() + .trim(); const embedding = new Array(64).fill(0); for (let i = 0; i < gateNorm.length; i++) { const charCode = gateNorm.charCodeAt(i); @@ -108,7 +110,7 @@ async function computeGateEmbedding(gateId) { } const norm = Math.sqrt(embedding.reduce((sum, x) => sum + x * x, 0)); return norm > 0 ? embedding.map((x) => x / norm) : embedding; - } catch (err) { + } catch (_err) { return null; } } diff --git a/src/resources/extensions/sf/uok/unit-runtime.js b/src/resources/extensions/sf/uok/unit-runtime.js index ddc956ffd..b687722a4 100644 --- a/src/resources/extensions/sf/uok/unit-runtime.js +++ b/src/resources/extensions/sf/uok/unit-runtime.js @@ -13,6 +13,7 @@ import { parseSummary, parseTaskPlanMustHaves, } from "../files.js"; +import { createMemory } from "../memory-store.js"; import { relSliceFile, relTaskFile, @@ -20,7 +21,6 @@ import { resolveTaskFile, sfRoot, } from "../paths.js"; -import { createMemory, getRelevantMemoriesRanked } from "../memory-store.js"; import { getSlice, isDbAvailable } from "../sf-db.js"; import { parseUnitId } from "../unit-id.js"; /** @@ -178,7 +178,7 @@ export async function recordUnitOutcomeInMemory(unit, status, result) { : `Unit type '${unitType}' failed with status: ${status} (${result?.error || "no error info"})`; await createMemory("pattern", pattern, confidence); - } catch (err) { + } catch (_err) { // Degrade gracefully - memory failures do not block UOK } }