Problem — server/services/taskLearning/metrics.js and taskLearning/routing.js statically import each other, so they form a two-module ESM cycle. In a static cycle whichever member evaluates first sees undefined for the other's bindings; any top-level const derived from one of those imports becomes a boot-time TDZ crash the moment module ordering shifts.
The edges
// taskLearning/metrics.js:31
import { deriveFailureSignalAvoidance, isNonRoutableLearnedTier } from './routing.js';
// taskLearning/routing.js:13
import { resetTaskTypeLearning } from './metrics.js';
Plan — pick the smaller side and extract it to a leaf both can import. resetTaskTypeLearning is the single symbol routing.js needs, so move it (with whatever store access it needs) into a leaf — taskLearning/reset.js or the existing store module — and have both files import the declaring module. Do not fix this with await import(): a deferred import dodges the guard rather than removing the cycle.
Tests — delete this component's entry from KNOWN_CYCLIC_COMPONENTS in server/services/serviceImportCycles.test.js. That suite fails if the entry is left behind, so the baseline can only shrink.
Related to #5693
Problem —
server/services/taskLearning/metrics.jsandtaskLearning/routing.jsstatically import each other, so they form a two-module ESM cycle. In a static cycle whichever member evaluates first seesundefinedfor the other's bindings; any top-levelconstderived from one of those imports becomes a boot-time TDZ crash the moment module ordering shifts.The edges
Plan — pick the smaller side and extract it to a leaf both can import.
resetTaskTypeLearningis the single symbolrouting.jsneeds, so move it (with whatever store access it needs) into a leaf —taskLearning/reset.jsor the existing store module — and have both files import the declaring module. Do not fix this withawait import(): a deferred import dodges the guard rather than removing the cycle.Tests — delete this component's entry from
KNOWN_CYCLIC_COMPONENTSinserver/services/serviceImportCycles.test.js. That suite fails if the entry is left behind, so the baseline can only shrink.Related to #5693