77 type DirectAnswerWiringInput ,
88} from "./direct-answer-wiring.js" ;
99import { DEFAULT_TAXONOMY } from "./taxonomy/default-taxonomy.js" ;
10- import type { MemoryFile , PluginConfig } from "./types.js" ;
10+ import type { MemoryFile } from "./types.js" ;
1111import type { TrustZoneName } from "./trust-zones.js" ;
1212
1313type WiringConfig = DirectAnswerWiringInput [ "config" ] ;
@@ -94,7 +94,8 @@ test("tryDirectAnswer disabled-path does not call any source accessor", async ()
9494 const result = await tryDirectAnswer ( {
9595 query : "does not matter" ,
9696 namespace : "default" ,
97- config : { ...BASE_CONFIG , recallDirectAnswerEnabled : false } ,
97+ config : BASE_CONFIG ,
98+ enabled : false ,
9899 sources,
99100 } ) ;
100101 assert . equal ( result . eligible , false ) ;
@@ -104,6 +105,42 @@ test("tryDirectAnswer disabled-path does not call any source accessor", async ()
104105 assert . deepEqual ( sources . calls . importance , [ ] ) ;
105106} ) ;
106107
108+ // ── Backward-compat (#1523): omit top-level `enabled`, fall back to config ──
109+
110+ test ( "tryDirectAnswer falls back to config.recallDirectAnswerEnabled when `enabled` is omitted (disabled)" , async ( ) => {
111+ // Old input shape: config carries recallDirectAnswerEnabled: false and no
112+ // top-level `enabled`. Must short-circuit as "disabled" (identical to the
113+ // pre-#1523 behavior) rather than treating undefined as enabled.
114+ const sources = makeMockSources ( { memories : [ makeMemory ( ) ] } ) ;
115+ const result = await tryDirectAnswer ( {
116+ query : "does not matter" ,
117+ namespace : "default" ,
118+ config : { ...BASE_CONFIG , recallDirectAnswerEnabled : false } ,
119+ sources,
120+ } ) ;
121+ assert . equal ( result . eligible , false ) ;
122+ assert . equal ( result . reason , "disabled" ) ;
123+ assert . equal ( sources . calls . listCandidates , 0 ) ;
124+ } ) ;
125+
126+ test ( "tryDirectAnswer falls back to config.recallDirectAnswerEnabled when `enabled` is omitted (enabled)" , async ( ) => {
127+ // Old input shape with recallDirectAnswerEnabled: true and no `enabled` must
128+ // NOT short-circuit — it proceeds to materialize candidates.
129+ const sources = makeMockSources ( {
130+ memories : [ makeMemory ( { tags : [ "pnpm" ] , content : "remnic uses pnpm" } ) ] ,
131+ trustZones : { m1 : "trusted" } ,
132+ importance : { m1 : 0.9 } ,
133+ } ) ;
134+ const result = await tryDirectAnswer ( {
135+ query : "package manager remnic" ,
136+ namespace : "default" ,
137+ config : BASE_CONFIG , // recallDirectAnswerEnabled: true
138+ sources,
139+ } ) ;
140+ assert . notEqual ( result . reason , "disabled" ) ;
141+ assert . equal ( sources . calls . listCandidates , 1 ) ;
142+ } ) ;
143+
107144// ── Empty-query short-circuit: no I/O ───────────────────────────────────────
108145
109146test ( "tryDirectAnswer skips all I/O when query normalizes to zero searchable tokens" , async ( ) => {
@@ -119,6 +156,7 @@ test("tryDirectAnswer skips all I/O when query normalizes to zero searchable tok
119156 query : "? !!! " ,
120157 namespace : "default" ,
121158 config : BASE_CONFIG ,
159+ enabled : true ,
122160 sources,
123161 } ) ;
124162 assert . equal ( result . reason , "empty-query" ) ;
@@ -135,6 +173,7 @@ test("tryDirectAnswer with empty memory list returns no-candidates", async () =>
135173 query : "package manager remnic" ,
136174 namespace : "default" ,
137175 config : BASE_CONFIG ,
176+ enabled : true ,
138177 sources,
139178 } ) ;
140179 assert . equal ( result . reason , "no-candidates" ) ;
@@ -158,6 +197,7 @@ test("tryDirectAnswer skips importance resolution for non-trusted memories", asy
158197 query : "package manager remnic" ,
159198 namespace : "default" ,
160199 config : BASE_CONFIG ,
200+ enabled : true ,
161201 sources,
162202 } ) ;
163203 assert . equal ( result . eligible , false ) ;
@@ -182,6 +222,7 @@ test("tryDirectAnswer skips importance for quarantine-zone memories", async () =
182222 query : "package manager remnic" ,
183223 namespace : "default" ,
184224 config : BASE_CONFIG ,
225+ enabled : true ,
185226 sources,
186227 } ) ;
187228 assert . equal ( result . eligible , false ) ;
@@ -203,6 +244,7 @@ test("tryDirectAnswer skips importance when trust zone is missing (null)", async
203244 query : "package manager remnic" ,
204245 namespace : "default" ,
205246 config : BASE_CONFIG ,
247+ enabled : true ,
206248 sources,
207249 } ) ;
208250 assert . equal ( result . eligible , false ) ;
@@ -229,6 +271,7 @@ test("tryDirectAnswer skips importance when taxonomy bucket is not eligible", as
229271 query : "package manager remnic" ,
230272 namespace : "default" ,
231273 config : BASE_CONFIG ,
274+ enabled : true ,
232275 sources,
233276 } ) ;
234277 assert . equal ( result . eligible , false ) ;
@@ -254,6 +297,7 @@ test("tryDirectAnswer returns eligible for a single trusted user-confirmed decis
254297 query : "package manager remnic" ,
255298 namespace : "default" ,
256299 config : BASE_CONFIG ,
300+ enabled : true ,
257301 sources,
258302 } ) ;
259303 assert . equal ( result . eligible , true ) ;
@@ -284,6 +328,7 @@ test("tryDirectAnswer defers to hybrid when two trusted candidates are within am
284328 query : "package manager remnic" ,
285329 namespace : "default" ,
286330 config : BASE_CONFIG ,
331+ enabled : true ,
287332 sources,
288333 } ) ;
289334 assert . equal ( result . eligible , false ) ;
@@ -327,6 +372,7 @@ test("tryDirectAnswer throws AbortError when signal aborts mid-loop", async () =
327372 query : "package manager remnic" ,
328373 namespace : "default" ,
329374 config : BASE_CONFIG ,
375+ enabled : true ,
330376 sources,
331377 abortSignal : controller . signal ,
332378 } ) ,
@@ -363,6 +409,7 @@ test("tryDirectAnswer throws when abort lands during trustZoneFor on the only me
363409 query : "package manager remnic" ,
364410 namespace : "default" ,
365411 config : BASE_CONFIG ,
412+ enabled : true ,
366413 sources,
367414 abortSignal : controller . signal ,
368415 } ) ,
@@ -391,6 +438,7 @@ test("tryDirectAnswer throws when abort lands during trustZoneFor on the last of
391438 query : "package manager remnic" ,
392439 namespace : "default" ,
393440 config : BASE_CONFIG ,
441+ enabled : true ,
394442 sources,
395443 abortSignal : controller . signal ,
396444 } ) ,
@@ -408,6 +456,7 @@ test("tryDirectAnswer throws when signal is already aborted before I/O", async (
408456 query : "anything" ,
409457 namespace : "default" ,
410458 config : BASE_CONFIG ,
459+ enabled : true ,
411460 sources,
412461 abortSignal : controller . signal ,
413462 } ) ,
@@ -434,6 +483,7 @@ test("tryDirectAnswer passes the requested namespace to listCandidateMemories",
434483 query : "anything" ,
435484 namespace : "project-x" ,
436485 config : BASE_CONFIG ,
486+ enabled : true ,
437487 sources,
438488 } ) ;
439489 assert . equal ( observedNamespace , "project-x" ) ;
@@ -465,6 +515,7 @@ test("tryDirectAnswer forwards queryEntityRefs to the eligibility gate", async (
465515 query : "package manager remnic" ,
466516 namespace : "default" ,
467517 config : BASE_CONFIG ,
518+ enabled : true ,
468519 sources,
469520 queryEntityRefs : [ "remnic" ] ,
470521 } ) ;
0 commit comments