@dzhechkov/harness-core 0.8.33 → 0.8.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/apply-leg.js CHANGED
@@ -27,8 +27,87 @@
27
27
  * @packageDocumentation
28
28
  */
29
29
  import { existsSync, readFileSync } from 'node:fs';
30
+ import { connect as netConnect } from 'node:net';
30
31
  import { join } from 'node:path';
31
32
  import { hookCommandsOf } from './managed-hooks.js';
33
+ /**
34
+ * FR-6 (feature `hook-recall-hybrid-parity`, ADR-001 C-4): send ONE `op: recall` probe to a LIVE
35
+ * embed daemon socket and report the `engine` it answers with (`'hybrid'` | `'cosine-fallback'`) —
36
+ * `dz doctor` prints this so an operator can SEE which engine is actually serving prompts, rather
37
+ * than trusting the daemon's mere presence. Honest-degrade contract, matching every other doctor
38
+ * probe: a non-socket path (e.g. a plain file, as every non-live doctor fixture in this repo uses),
39
+ * a connection error, an unparsable reply, or a timeout all resolve to `undefined` — NEVER a thrown
40
+ * error, and never distinguishable from "no daemon" in the caller's output (the existing "socket
41
+ * present/absent" line already carries that half of the truth).
42
+ *
43
+ * `timeoutMs` defaults to 1000 ms — comfortably above the documented `HOOK_RECALL_BUDGET_MS` default
44
+ * (500 ms): under that default, a cold `recallHybrid` semantic leg routinely exceeds the budget in
45
+ * this environment (MEASURED — see the manifest's NFR-1 discussion), so the daemon's OWN answer
46
+ * time is closer to ~500-550 ms than to the socket round-trip cost alone; a shorter probe timeout
47
+ * would silently miss a live, correctly-answering daemon and report no engine at all.
48
+ *
49
+ * AM-8 (fix round 1): lives HERE, not in `operations.ts` — this module already owns the daemon's
50
+ * wire protocol (`recallHookSource`/`embedDaemonSource`'s generated `op: recall` handshake) and its
51
+ * socket-path resolution; `operations.ts`'s `runDoctor` reaches it via a dynamic `import()`
52
+ * (matching its existing `embed-socket-path.js` import one line above the call site) rather than
53
+ * duplicating a second, independent `node:net` IO surface in a file whose job is orchestration, not
54
+ * protocol.
55
+ */
56
+ export function probeRecallEngine(socketPath, timeoutMs = 1000) {
57
+ return new Promise((resolvePromise) => {
58
+ let settled = false;
59
+ const done = (v) => {
60
+ if (settled)
61
+ return;
62
+ settled = true;
63
+ try {
64
+ sock.destroy();
65
+ }
66
+ catch {
67
+ /* already gone */
68
+ }
69
+ resolvePromise(v);
70
+ };
71
+ let sock;
72
+ try {
73
+ sock = netConnect(socketPath);
74
+ }
75
+ catch {
76
+ resolvePromise(undefined);
77
+ return;
78
+ }
79
+ const timer = setTimeout(() => done(undefined), timeoutMs);
80
+ timer.unref?.();
81
+ let buf = '';
82
+ sock.on('connect', () => {
83
+ try {
84
+ sock.write(`${JSON.stringify({ op: 'recall', prompt: 'dz doctor probe', limit: 1 })}\n`);
85
+ }
86
+ catch {
87
+ done(undefined);
88
+ }
89
+ });
90
+ sock.on('data', (chunk) => {
91
+ buf += chunk.toString('utf-8');
92
+ const nl = buf.indexOf('\n');
93
+ if (nl === -1)
94
+ return;
95
+ clearTimeout(timer);
96
+ try {
97
+ const msg = JSON.parse(buf.slice(0, nl));
98
+ // Codex round-3: only the protocol's own vocabulary is reported; anything else is "unknown" (undefined)
99
+ done(msg.engine === 'hybrid' || msg.engine === 'cosine-fallback' || msg.engine === 'none' ? msg.engine : undefined);
100
+ }
101
+ catch {
102
+ done(undefined);
103
+ }
104
+ });
105
+ sock.on('error', () => {
106
+ clearTimeout(timer);
107
+ done(undefined);
108
+ });
109
+ });
110
+ }
32
111
  /**
33
112
  * Version stamped into BOTH generated helper files as `// dz-apply-leg-version: N` (line 2, right
34
113
  * after the shebang). Bump on ANY change to {@link recallHookSource} or {@link embedDaemonSource}'s
@@ -46,8 +125,26 @@ import { hookCommandsOf } from './managed-hooks.js';
46
125
  * compiled module), the daemon writes a `.dz/embed.sock.path` pointer when it picks the tmpdir-short
47
126
  * branch, and `ready` is now printed only after `existsSync(SOCKET)` confirms the bind actually
48
127
  * landed (previously logged unconditionally, before `listen` even ran).
128
+ *
129
+ * Bumped 4→5 (feature `hook-recall-hybrid-parity`, ADR-001 D1/D2): the daemon's `op: recall`
130
+ * handler now tries core's `recallHybrid` FIRST — under a time budget (`HOOK_RECALL_BUDGET_MS`,
131
+ * default 500 ms) — via the SAME `CORE_DIST_DIR` + `loadCoreModule` mechanism the hook already
132
+ * used only for its policy modules; on budget overrun, engine error, or no resolvable core module
133
+ * it falls back to today's brute-force cosine, honestly labelled `engine: 'cosine-fallback'` with a
134
+ * `reason`. The hook now reads `engine`/`reason` off the daemon's reply (stderr-only, never
135
+ * context) and applies its relevance floor to the NEW `score` format when `engine === 'hybrid'`,
136
+ * preserving today's cosine-calibrated floor unchanged for the `cosine-fallback` path.
137
+ *
138
+ * Bumped 5→6 (`hook-recall-hybrid-parity`, fix round 1 — AM-1/AM-2/AM-3/AM-5): the daemon now
139
+ * (a) fires a fire-and-forget engine warm-up before `listen()` (AM-1) so the first REAL `op: recall`
140
+ * is less likely to pay a cold `resolveAgentdbEmbedder` init; (b) arms the budget timer BEFORE
141
+ * `loadCoreModule()`, not after (AM-2, wall clock from request receipt); (c) treats ANY failure
142
+ * past the budget race — a malformed hit, `patternRecordId()` throwing — as an honest cosine
143
+ * fallback rather than a bare protocol error (AM-3); (d) reports the RAW core RRF score, unchanged,
144
+ * instead of a locally re-normalized [0,1] value (AM-5) — the hook's own `HOOK_SCORE_FLOOR` default
145
+ * moved from `0.01` to `0.005` to match (see that constant's own comment for the measurement).
49
146
  */
50
- export const APPLY_LEG_VERSION = 4;
147
+ export const APPLY_LEG_VERSION = 6;
51
148
  /**
52
149
  * Parse the `dz-apply-leg-version` stamp from a deployed helper file. Unlike
53
150
  * `writerVersionOf` (which floors an absent stamp at `0`), this returns `-1` for "no stamp at
@@ -174,8 +271,34 @@ function resolveEffectiveEmbedSocketPath(projectRoot, env) {
174
271
  }
175
272
  const SOCKET = resolveEffectiveEmbedSocketPath(PROJECT, process.env).path;
176
273
  const USAGE_LOG = process.env.DZ_RECALL_USAGE_LOG || path.join(PROJECT, '.dz', 'recall-usage.jsonl');
274
+ // Measured (2026-09-14, apply-leg-socket.test.ts): an ordinary hook round-trip (spawn + one socket
275
+ // op) took 81-121 ms; 800 ms leaves a wide margin for a loaded daemon while still bounding the AM-2
276
+ // worst case — a daemon synchronously blocked never replies at all, so THIS timeout (not the
277
+ // daemon's own internal budget race, which cannot preempt synchronous work) is what actually
278
+ // rescues the hook from hanging.
177
279
  const TIMEOUT_MS = Number(process.env.DZ_RECALL_HOOK_TIMEOUT_MS || 800);
178
280
 
281
+ // FR-5 (hook-recall-hybrid-parity, ADR-001 D2): the RRF-based \`score\` the daemon returns for
282
+ // \`engine: 'hybrid'\` is NOT on the cosine scale DEFAULT_RECALL_FLOORS (recall-hook-policy.ts) was
283
+ // calibrated on — applying the cosine floor to an RRF score would either admit everything or cut
284
+ // everything, so the hybrid path gets its OWN floor, applied to BOTH languages alike (the RRF score
285
+ // carries no language-baseline shift the way raw cosine did).
286
+ //
287
+ // AM-5 (fix round 1), MEASURED not a placeholder: recallHybrid(RRF_K=60) over a live 14-lesson
288
+ // fixture (this environment, 2026-09-14 — reproducer in the manifest's Fix-round 1 section) shows
289
+ // raw RRF score is only WEAKLY discriminating per-hit: an exact-lexical-match hit scored 0.03252
290
+ // (both legs agree at rank 0), but a genuinely IRRELEVANT query ("xkcd banana quantum toaster
291
+ // nonsense") still returned a top hit at 0.01639 — HIGHER than several truly relevant tail hits in
292
+ // OTHER queries (0.01471-0.01538). This is structural, not a fixture artifact: RRF encodes RANK,
293
+ // not similarity, and a nearest-neighbor search always returns SOME top-1 even for a garbage query.
294
+ // A raw-score floor therefore cannot cleanly separate signal from noise at the per-hit level the
295
+ // way the cosine floor does — true filtering here has to come from \`limit\` and \`selectHookHits\`'s
296
+ // own budget, not from this number. The floor's honest job is only to reject a DEGENERATE score
297
+ // (zero/negative/NaN from a malformed hit), so it is set well BELOW the measured noise floor
298
+ // (0.01471) rather than attempting to rank-filter — deliberately permissive, matching ADR-001 D2's
299
+ // stated intent that an exact lexical match (FR-4) must never be defeated by an unmeasured cutoff.
300
+ const HOOK_SCORE_FLOOR = Number(process.env.DZ_RECALL_HOOK_SCORE_FLOOR || 0.005);
301
+
179
302
  const safe = (fn, fb) => {
180
303
  try {
181
304
  return fn();
@@ -291,6 +414,9 @@ function readLogTail(chain, file) {
291
414
  }, chain && chain.EMPTY_LOG_TAIL);
292
415
  }
293
416
 
417
+ // FR-6 (hook-recall-hybrid-parity): the reply now carries \`engine\`/\`reason\` alongside \`hits\` —
418
+ // returned as a small object rather than the bare hit array, so the caller can apply the RIGHT
419
+ // floor (FR-5) and print the engine to stderr ONLY (never into the injected context, FR-2).
294
420
  function askDaemon(prompt) {
295
421
  return new Promise((resolve) => {
296
422
  if (!fs.existsSync(SOCKET)) return resolve(undefined);
@@ -312,7 +438,15 @@ function askDaemon(prompt) {
312
438
  if (nl === -1) return;
313
439
  clearTimeout(timer);
314
440
  const msg = safe(() => JSON.parse(buf.slice(0, nl)), undefined);
315
- done(msg && Array.isArray(msg.hits) ? msg.hits : undefined);
441
+ done(
442
+ msg && Array.isArray(msg.hits)
443
+ ? {
444
+ hits: msg.hits,
445
+ engine: typeof msg.engine === 'string' ? msg.engine : undefined,
446
+ reason: typeof msg.reason === 'string' ? msg.reason : undefined,
447
+ }
448
+ : undefined,
449
+ );
316
450
  });
317
451
  sock.on('error', () => {
318
452
  clearTimeout(timer);
@@ -504,8 +638,8 @@ async function main() {
504
638
  const policy = await loadPolicy();
505
639
  if (!policy) return emitContext(debt);
506
640
 
507
- const hits = await askDaemon(prompt);
508
- if (!hits) {
641
+ const daemonReply = await askDaemon(prompt);
642
+ if (!daemonReply) {
509
643
  // SELF-HEAL (2026-07-28): the daemon is started at SessionStart only, so when it dies mid-way
510
644
  // through a long-lived session NOTHING restarts it — the apply leg was silently dead for 19
511
645
  // days (MEASURED: recall-usage.jsonl last record 2026-07-09, socket absent). Spawn it
@@ -513,9 +647,19 @@ async function main() {
513
647
  reviveDaemon();
514
648
  return emitContext(debt);
515
649
  }
650
+ const { hits, engine, reason } = daemonReply;
651
+ // FR-6/FR-2: the engine (and, on fallback, why) is the caller's business, not the model's — it
652
+ // NEVER rides into additionalContext, only stderr, which Claude Code does not read as context.
653
+ if (typeof engine === 'string') {
654
+ safe(() => process.stderr.write(\`[dz-recall] engine=\${engine}\${reason ? \` reason=\${reason}\` : ''}\\n\`));
655
+ }
516
656
  if (hits.length === 0) return emitContext(debt); // daemon alive, nothing relevant — silence is correct
517
657
 
518
- const selection = policy.selectHookHits(prompt, hits);
658
+ // FR-5 (ADR-001 D2): a hybrid-engine reply carries an RRF-based score — its OWN floor, applied to
659
+ // both languages. A cosine-fallback reply (or an old daemon that never sent \`engine\` at all)
660
+ // keeps today's cosine-calibrated DEFAULT_RECALL_FLOORS untouched.
661
+ const floorOpts = engine === 'hybrid' ? { floors: { ru: HOOK_SCORE_FLOOR, en: HOOK_SCORE_FLOOR } } : {};
662
+ const selection = policy.selectHookHits(prompt, hits, floorOpts);
519
663
  // lesson-quarantine AM-2: an excluded hypothesis is logged, never a silent context shrink.
520
664
  if (typeof selection.quarantinedExcluded === 'number' && selection.quarantinedExcluded > 0) {
521
665
  try {
@@ -566,13 +710,22 @@ export function resolveIdleMs(raw) {
566
710
  }
567
711
  /**
568
712
  * Generate `.claude/helpers/dz-embed-daemon.mjs`. Behaviourally identical to the pre-existing
569
- * hand-committed hub file except for: the version stamp (new, line 2) and `resolveDeps()`, which
570
- * now tries `@huggingface/transformers` before falling back to `@xenova/transformers` — AM-3,
713
+ * hand-committed hub file except for: the version stamp (new, line 2), `resolveDeps()`, which
714
+ * tries `@huggingface/transformers` before falling back to `@xenova/transformers` — AM-3,
571
715
  * dz-harness-hub issue #10 defect 3: `agentdb >= 3.0.0-alpha` depends on the former, and an older
572
716
  * agentdb install still carries the latter, so probing only one name silently starved the daemon
573
- * on either side of that agentdb version boundary.
717
+ * on either side of that agentdb version boundary — and (feature `hook-recall-hybrid-parity`,
718
+ * ADR-001 D1) the `op: recall` handler, which now tries core's `recallHybrid` under a time budget
719
+ * before falling back to the brute-force cosine below.
720
+ *
721
+ * `coreDistDir` (new parameter, ADR-001 D1) is baked in exactly like {@link recallHookSource}'s own
722
+ * parameter of the same name — the FIRST resolve candidate for `loadCoreModule`. `null` (the
723
+ * default, and what every existing zero-arg call site gets) is the same PORTABLE marker
724
+ * `recallHookSource(null)` uses: `loadCoreModule` falls through to the project-relative fallback
725
+ * candidates, resolved from `DZ_PROJECT_ROOT`/`cwd()` at daemon RUNTIME, which is correct in any
726
+ * clone and for any consumer whose `harness-core` install is reachable under its own project tree.
574
727
  */
575
- export function embedDaemonSource() {
728
+ export function embedDaemonSource(coreDistDir = null) {
576
729
  return `#!/usr/bin/env node
577
730
  // dz-apply-leg-version: ${APPLY_LEG_VERSION}
578
731
  /**
@@ -594,11 +747,18 @@ export function embedDaemonSource() {
594
747
  * - it exits on SIGINT/SIGTERM/SIGHUP and unlinks its socket.
595
748
  *
596
749
  * PROTOCOL — newline-delimited JSON over a unix socket:
597
- * → {"op":"recall","prompt":"…","limit":8} ← {"hits":[{"dzId","pattern","score","domain"}]}
750
+ * → {"op":"recall","prompt":"…","limit":8} ← {"hits":[{"dzId","pattern","score","domain"}],"engine":"hybrid"|"cosine-fallback","reason"?}
598
751
  * → {"op":"ping"} ← {"ok":true,"model":"…","uptimeMs":N}
599
752
  * → {"op":"stop"} ← {"ok":true} (then exits)
600
753
  *
601
- * \`score\` is COSINE RELEVANCE in [0,1] — never the teaching reward. The caller applies the floor.
754
+ * ADR-001 (feature \`hook-recall-hybrid-parity\`): \`op: recall\` first tries core's \`recallHybrid\`
755
+ * (same engine \`dz recall\` uses) under \`HOOK_RECALL_BUDGET_MS\` (default 500 ms, < the hook's own
756
+ * 800 ms timeout); on budget overrun, engine error, or no resolvable core module it falls back to
757
+ * the brute-force cosine below. \`score\` on \`engine:"hybrid"\` is the RAW core RRF score, UNCHANGED
758
+ * (AM-5, fix round 1) — the exact same number \`dz recall --json\` reports as \`relevance\`, never
759
+ * locally re-normalized; on \`engine:"cosine-fallback"\` it is COSINE RELEVANCE in [0,1] as before —
760
+ * two DIFFERENT scales, never the teaching reward either way. The caller applies the right floor
761
+ * for whichever scale \`engine\` names.
602
762
  */
603
763
 
604
764
  import { createServer } from 'node:net';
@@ -608,6 +768,7 @@ import { createRequire } from 'node:module';
608
768
  import { connect } from 'node:net';
609
769
  import { createHash } from 'node:crypto';
610
770
  import { tmpdir } from 'node:os';
771
+ import { pathToFileURL } from 'node:url';
611
772
 
612
773
  const log = (...a) => console.error('[dz-embed]', ...a);
613
774
 
@@ -615,6 +776,64 @@ const log = (...a) => console.error('[dz-embed]', ...a);
615
776
  console.log = (...a) => console.error(...a);
616
777
 
617
778
  const PROJECT = process.env['DZ_PROJECT_ROOT'] ?? process.cwd();
779
+
780
+ // ADR-001 (hook-recall-hybrid-parity, D1): the SAME candidate-list resolution the hook uses for its
781
+ // own policy modules — the baked \`coreDistDir\` first (a real install's absolute dist path), then
782
+ // project-relative fallbacks resolved from PROJECT at RUNTIME. \`null\` (the hub's own portable
783
+ // marker, matching \`recallHookSource(null)\`) skips straight to the fallbacks. Loaded ONCE and
784
+ // memoized (\`coreModulePromise\`) — a fresh \`import()\` per recall would defeat FR-3's "opened once".
785
+ const CORE_DIST_DIR = ${coreDistDir === null ? 'null' : JSON.stringify(coreDistDir)};
786
+ let coreModulePromise;
787
+ function loadCoreModule() {
788
+ if (coreModulePromise !== undefined) return coreModulePromise;
789
+ coreModulePromise = (async () => {
790
+ const candidates = [
791
+ ...(CORE_DIST_DIR ? [join(CORE_DIST_DIR, 'index.js')] : []),
792
+ join(PROJECT, 'node_modules', '@dzhechkov', 'harness-core', 'dist', 'index.js'),
793
+ join(PROJECT, 'packages', '@dzhechkov', 'harness-core', 'dist', 'index.js'),
794
+ ];
795
+ for (const c of candidates) {
796
+ if (!existsSync(c)) continue;
797
+ try {
798
+ const mod = await import(pathToFileURL(c).href);
799
+ if (typeof mod.recallHybrid === 'function' && typeof mod.patternRecordId === 'function') return mod;
800
+ } catch {
801
+ /* try the next candidate */
802
+ }
803
+ }
804
+ return undefined;
805
+ })();
806
+ return coreModulePromise;
807
+ }
808
+
809
+ // FR-2 (hook-recall-hybrid-parity): the hybrid leg is time-boxed so a slow/cold engine can never make ONE prompt pay the full
810
+ // cost — it falls back to the warm cosine below instead. 500 ms leaves the hook's own 800 ms
811
+ // timeout (recallHookSource's TIMEOUT_MS) headroom for the socket round-trip itself.
812
+ // Measured 2026-09-14 (nfr1-measure.mjs, real 743-pattern store, warm-up on, n=100 x2): hybrid p50 60-65 ms,
813
+ // p95 100-180 ms, max 374 ms; 500 ms ≈ 3x p95 and stays under the hook's own 800 ms client timeout.
814
+ const HOOK_RECALL_BUDGET_MS = Number(process.env['HOOK_RECALL_BUDGET_MS'] || 500);
815
+ // Codex round-2 (2026-09-14): a hybrid attempt that LOST the race keeps running in the background —
816
+ // this cap keeps a burst of slow requests from stacking unbounded engine work; past it, requests answer
817
+ // with cosine at once, honestly labelled. Real cancellation needs worker isolation (backlog 14c1316b).
818
+ const HYBRID_MAX_IN_FLIGHT = (() => {
819
+ const raw = Number(process.env['HOOK_HYBRID_MAX_IN_FLIGHT'] || 2);
820
+ // Codex round-3: NaN/Infinity/0/negative must not silently disable the cap — fall back to 2.
821
+ return Number.isFinite(raw) && raw >= 1 ? Math.floor(raw) : 2;
822
+ })();
823
+ let hybridInFlight = 0;
824
+ // Test-only fault injection (AC-2): a positive value delays the hybrid leg so the budget can be
825
+ // PROVEN to fire without a real slow engine. Absent/0 in every real deployment.
826
+ const DZ_EMBED_HYBRID_DELAY_MS = Number(process.env['DZ_EMBED_HYBRID_DELAY_MS'] || 0);
827
+ // AM-5 (fix round 1): the daemon used to re-normalize recallHybrid's raw RRF score into [0,1] with
828
+ // its OWN copy of vector-tier.ts's RRF_K constant — two numbers that could silently drift apart
829
+ // (this file is standalone generated text and cannot \`import\` the compiled core constant), AND a
830
+ // scale \`dz recall --json\`'s own \`relevance\` field (cli.ts: \`relevance: … h.score …\`) never
831
+ // applies — so the hook's floor and the CLI's floor were never comparable numbers even though both
832
+ // ultimately came from the same recallHybrid() call. Fixed: the daemon now reports \`h.score\`
833
+ // UNCHANGED — the exact raw core score \`dz recall --json\` already reports as \`relevance\` — so a
834
+ // floor calibrated against one is valid against the other (AM-4's parity test asserts the two are
835
+ // literally equal, not merely proportional).
836
+
618
837
  // embed-socket-short-path (FR-1): a unix socket path has a hard platform limit on \`sun_path\`
619
838
  // (Linux 108 bytes incl. NUL, macOS 104) — a deeply nested project's \`.dz/embed.sock\` can exceed
620
839
  // it, and \`listen()\` then fails while every OTHER part of the daemon looks healthy. This mirrors
@@ -792,6 +1011,116 @@ async function main() {
792
1011
  let patterns = loadPatterns();
793
1012
  let patternsAt = Date.now();
794
1013
 
1014
+ // ADR-001 (hook-recall-hybrid-parity, D1): try core's recallHybrid FIRST, budget-bounded.
1015
+ // AM-2 (fix round 1, wall clock from request receipt): the budget timer is armed BEFORE
1016
+ // \`loadCoreModule()\` runs, not after it resolves — the FIRST call's dynamic \`import()\` cost used
1017
+ // to be spent OUTSIDE the race, so a slow/cold module resolution could add its own latency on top
1018
+ // of the full \`HOOK_RECALL_BUDGET_MS\` window instead of eating into it.
1019
+ // NAMED LIMIT (AM-2): \`Promise.race\` cannot PREEMPT synchronous work — if \`core.recallHybrid\`
1020
+ // (or anything it calls) blocks the event loop synchronously, this race does not return until
1021
+ // that work finishes, budget or not; Node has no cooperative-preemption primitive for that. The
1022
+ // budget only bounds work that yields the event loop somewhere (every real I/O/await in
1023
+ // recallHybrid does). The hook's OWN client-side \`TIMEOUT_MS\` (recallHookSource, 800 ms) is the
1024
+ // actual backstop against a synchronously-blocked daemon: it times out the SOCKET, not the
1025
+ // daemon's internal race, so the hook always returns promptly even if this promise never does.
1026
+ //
1027
+ // \`hybridRecall\`'s own promise is left running past a timeout loss (never awaited a second time)
1028
+ // — its \`.catch\` below only silences a LATE rejection so a slow, eventually-failing engine call
1029
+ // can never become an unhandled-rejection crash for this long-lived process.
1030
+ async function hybridRecall(prompt, limit) {
1031
+ if (hybridInFlight >= HYBRID_MAX_IN_FLIGHT) {
1032
+ return { ok: false, reason: \`hybrid saturated (\${hybridInFlight} attempt(s) still in flight, cap \${HYBRID_MAX_IN_FLIGHT})\` };
1033
+ }
1034
+ const TIMED_OUT = Symbol('timed-out');
1035
+ let timer;
1036
+ const budget = new Promise((resolve) => {
1037
+ timer = setTimeout(() => resolve(TIMED_OUT), HOOK_RECALL_BUDGET_MS);
1038
+ timer.unref?.();
1039
+ });
1040
+ hybridInFlight += 1;
1041
+ const attempt = (async () => {
1042
+ const core = await loadCoreModule();
1043
+ if (core === undefined) return { unavailable: true };
1044
+ if (DZ_EMBED_HYBRID_DELAY_MS > 0) await new Promise((r) => setTimeout(r, DZ_EMBED_HYBRID_DELAY_MS));
1045
+ const result = await core.recallHybrid(PROJECT, prompt, { limit, mode: 'hook', deferExposures: true });
1046
+ return { unavailable: false, result, core };
1047
+ })();
1048
+ // the in-flight count follows the UNDERLYING attempt, not the race: a timed-out attempt still
1049
+ // occupies its slot until it settles (that is the whole point of the cap)
1050
+ attempt.then(() => { hybridInFlight -= 1; }, () => { hybridInFlight -= 1; });
1051
+ attempt.catch(() => {}); // swallow a rejection that arrives AFTER the budget already won the race
1052
+ try {
1053
+ const raced = await Promise.race([attempt, budget]);
1054
+ clearTimeout(timer);
1055
+ if (raced === TIMED_OUT) return { ok: false, reason: \`budget exceeded (\${HOOK_RECALL_BUDGET_MS} ms)\` };
1056
+ if (raced.unavailable) return { ok: false, reason: 'core module unavailable' };
1057
+ // AM-3 (fix round 1): everything past the race — reading result.hits, a hit missing its
1058
+ // required fields, patternRecordId() throwing on a malformed pattern — is now INSIDE this
1059
+ // try, so any such failure falls back to cosine with an honest \`reason\` instead of reaching
1060
+ // the socket handler's outer catch, which used to turn it into a bare protocol {error} reply
1061
+ // (never engine:'cosine-fallback') — the exact defect this amendment fixes.
1062
+ const { result, core } = raced;
1063
+ const hits = (result.hits || []).map((h) => ({
1064
+ dzId: core.patternRecordId(h.pattern),
1065
+ pattern: h.pattern.pattern,
1066
+ score: h.score, // AM-5: raw core score, unchanged — the same number \`dz recall --json\` reports as \`relevance\`
1067
+ domain: h.pattern.domain,
1068
+ ...(h.quarantined ? { quarantined: true } : {}),
1069
+ }));
1070
+ return { ok: true, hits: hits.slice(0, limit) };
1071
+ } catch (err) {
1072
+ clearTimeout(timer);
1073
+ return { ok: false, reason: \`recallHybrid failed: \${err?.message ?? err}\` };
1074
+ }
1075
+ }
1076
+
1077
+ /** \`op: recall\`'s whole answer: hybrid first (budget-bounded), cosine fallback on ANY failure —
1078
+ * always honestly labelled with \`engine\`/\`reason\` (FR-2/FR-6). */
1079
+ async function answerRecall(prompt, limitRaw) {
1080
+ const limit = Math.min(Number(limitRaw) || 8, 32);
1081
+ if (prompt.trim() === '') return { hits: [], engine: 'none', reason: 'empty prompt' }; // Codex round-2: every reply carries \`engine\`
1082
+ const hybrid = await hybridRecall(prompt, limit);
1083
+ if (hybrid.ok) return { hits: hybrid.hits, engine: 'hybrid' };
1084
+ // Reload the cosine mirror if it changed on disk (a \`dz teach\` between turns) — the SAME
1085
+ // staleness window as before this feature, just checked only when actually falling back.
1086
+ if (Date.now() - patternsAt > 5000) {
1087
+ try {
1088
+ patterns = loadPatterns();
1089
+ } catch {
1090
+ /* keep the previous snapshot */
1091
+ }
1092
+ patternsAt = Date.now();
1093
+ }
1094
+ if (patterns.length === 0) return { hits: [], engine: 'cosine-fallback', reason: hybrid.reason };
1095
+ const qv = await embed(prompt);
1096
+ const scored = patterns.map((p) => ({ dzId: p.dzId, pattern: p.pattern, score: cos(qv, p.vec), ...(p.quarantined ? { quarantined: true } : {}) }));
1097
+ scored.sort((a, b) => b.score - a.score);
1098
+ return { hits: scored.slice(0, limit), engine: 'cosine-fallback', reason: hybrid.reason };
1099
+ }
1100
+
1101
+ // AM-1 (fix round 1): warm resolveAgentdbEmbedder — cached PER PROCESS since db1521ba (cold
1102
+ // ~2-3.6 s, warm ~1 ms, MEASURED, see the manifest's T8/AM-1 discussion) — OFF the request path,
1103
+ // so the first REAL \`op: recall\` is not the one that pays the cold init. Fired fire-and-forget
1104
+ // right before \`listen()\` below, never awaited by startup: this is a best-effort head start, not
1105
+ // a guarantee — a request landing in the few-hundred-ms window before it completes still pays the
1106
+ // cold cost exactly as before this amendment, and a warm-up failure (no core module, engine
1107
+ // error) is silently swallowed — never-block applies to startup exactly as it does to a request.
1108
+ // Measured: the slowest cold resolveAgentdbEmbedder init observed in this environment was 3653 ms
1109
+ // (T8 log, 2026-09-14) — 10 s leaves a wide margin without risking an unbounded warm-up hang.
1110
+ const WARMUP_TIMEOUT_MS = 10_000;
1111
+ async function warmUpHybridEngine() {
1112
+ const core = await loadCoreModule();
1113
+ if (core === undefined) return;
1114
+ const guard = new Promise((resolve) => {
1115
+ const t = setTimeout(resolve, WARMUP_TIMEOUT_MS);
1116
+ t.unref?.();
1117
+ });
1118
+ // An empty-string query still exercises the FULL semantic leg (embed + engine.search), which is
1119
+ // exactly what needs warming; recallHybrid degrades any error inside it honestly, so nothing
1120
+ // here needs its own try/catch beyond the outer .catch(() => {}) at the call site below.
1121
+ await Promise.race([core.recallHybrid(PROJECT, '', { limit: 1, mode: 'hook', deferExposures: true }), guard]);
1122
+ }
1123
+
795
1124
  let idleTimer;
796
1125
  let lastActivityAt = Date.now();
797
1126
  const touch = () => {
@@ -826,24 +1155,8 @@ async function main() {
826
1155
  sock.write(JSON.stringify({ ok: true }) + '\\n');
827
1156
  return shutdown(0);
828
1157
  } else if (msg.op === 'recall') {
829
- // Reload the mirror if it changed on disk (a \`dz teach\` between turns).
830
- if (Date.now() - patternsAt > 5000) {
831
- try {
832
- patterns = loadPatterns();
833
- } catch {
834
- /* keep the previous snapshot */
835
- }
836
- patternsAt = Date.now();
837
- }
838
1158
  const prompt = typeof msg.prompt === 'string' ? msg.prompt : '';
839
- if (prompt.trim() === '' || patterns.length === 0) {
840
- reply = { hits: [] };
841
- } else {
842
- const qv = await embed(prompt);
843
- const scored = patterns.map((p) => ({ dzId: p.dzId, pattern: p.pattern, score: cos(qv, p.vec), ...(p.quarantined ? { quarantined: true } : {}) }));
844
- scored.sort((a, b) => b.score - a.score);
845
- reply = { hits: scored.slice(0, Math.min(Number(msg.limit) || 8, 32)) };
846
- }
1159
+ reply = await answerRecall(prompt, msg.limit);
847
1160
  } else {
848
1161
  reply = { error: \`unknown op \${String(msg.op)}\` };
849
1162
  }
@@ -882,6 +1195,9 @@ async function main() {
882
1195
 
883
1196
  for (const sig of ['SIGINT', 'SIGTERM', 'SIGHUP']) process.on(sig, () => shutdown(0));
884
1197
 
1198
+ // AM-1: fire-and-forget, never awaited — bind proceeds immediately regardless of warm-up outcome.
1199
+ warmUpHybridEngine().catch(() => {});
1200
+
885
1201
  // FR-3 ("absence of a receipt is not success"): \`ready\` is printed ONLY after \`listen\`'s callback
886
1202
  // AND a fresh \`existsSync(SOCKET)\` both confirm the socket file is actually on disk — a caller
887
1203
  // that greps stderr for "ready" must never see it for a socket that silently failed to bind.
@@ -1 +1 @@
1
- {"version":3,"file":"apply-leg.js","sourceRoot":"","sources":["../src/apply-leg.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apply-leg.js","sourceRoot":"","sources":["../src/apply-leg.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -89,7 +89,7 @@ export { statuslineData, readFeatureAdrState, writeFeatureAdrState, featureAdrSt
89
89
  export type { StatuslineData, StatuslineStoreHealth, FeatureAdrState, WriteFeatureAdrStateInput, WriteFeatureAdrStateResult } from './statusline.js';
90
90
  export { ETA_MAX_STAGE_MS, estimateEta, extractStageSamples, formatEta, parseCheckpointLines, segmentRun, } from './eta.js';
91
91
  export type { CheckpointObservation, EtaEstimate, EtaInput, IncompleteCoverageSample, RunSegment, StageDurationSample, StageSample } from './eta.js';
92
- export { indexPatternsToAgentdb, resolveAgentdbPath, searchAgentdbPatterns, listAgentdbDzIds, resolveAgentdbEmbedder, cosineSimilarity, importVectorsToAgentdb, reindexAgentdbRows, bumpAgentdbUses, clearAgentdbQuarantine, deleteAgentdbByDzIds, readAgentdbRowsByTaskType, DZ_OWNED_TASK_TYPES, ensureAgentdbSchema } from './agentdb-index.js';
92
+ export { indexPatternsToAgentdb, resolveAgentdbPath, searchAgentdbPatterns, listAgentdbDzIds, resolveAgentdbEmbedder, resetAgentdbEmbedderCache, getAgentdbEmbedderCacheStats, cosineSimilarity, importVectorsToAgentdb, reindexAgentdbRows, bumpAgentdbUses, clearAgentdbQuarantine, deleteAgentdbByDzIds, readAgentdbRowsByTaskType, DZ_OWNED_TASK_TYPES, ensureAgentdbSchema } from './agentdb-index.js';
93
93
  export type { AgentdbSearchHit, AgentdbSearchResult, AgentdbImportRow } from './agentdb-index.js';
94
94
  export { DEFAULT_EMBED_MODEL, LEGACY_EMBED_MODEL, DEFAULT_EMBED_DIM, KNOWN_EMBED_DIMS, resolveEmbedModel, readEmbedManifest, writeEmbedManifest, embedManifestPath, legacyEmbedManifest } from './embedding-config.js';
95
95
  export type { EmbedModelConfig, EmbedModelSource, EmbedManifest } from './embedding-config.js';
@@ -163,11 +163,11 @@ export type { PackageDownloads, DownloadsReport } from './downloads.js';
163
163
  export { discoverInstalled, checkUpgrades } from './upgrade.js';
164
164
  export type { InstalledSkill, UpgradeCheck, UpgradeReport } from './upgrade.js';
165
165
  export type { PublishResult, PublishReport, ProvenanceMode, ProvenanceDecision, PackedTarballArtifact, PackedTransportSmokeVerdict } from './publish.js';
166
- export { collectPackageFacts, selectAffectedPackages, planReleaseGates, classifyGateExecutions, buildFailureIssue, buildReleaseNotes, releaseTagName, firstOutputLine, RELEASE_GATE_ORDER, RELEASE_TIMEOUTS, } from './release.js';
166
+ export { collectPackageFacts, selectAffectedPackages, planReleaseGates, classifyGateExecutions, buildFailureIssue, buildReleaseNotes, releaseTagName, firstOutputLine, testsFailureDetail, outputTail, RELEASE_GATE_ORDER, RELEASE_TIMEOUTS, } from './release.js';
167
167
  export type { ReleaseGateId, ReleaseFailureClass, ReleaseSkipClass, ReleaseBinEntry, ReleasePackageFacts, GateStep, GateSkip, GatePlan, GateExecution, GateFailure, GateResult, ReleaseVerdict, PlanReleaseGatesOptions, FailureIssueContext, } from './release.js';
168
168
  export { formatPublishError } from './publish.js';
169
- export { detectSiblingDrift } from './publish-sibling-drift.js';
170
- export type { SiblingDriftStatus, SiblingDriftResult, FetchedPublished, FetchPublished, DetectSiblingDriftOptions, } from './publish-sibling-drift.js';
169
+ export { detectSiblingDrift, parseNpmPackInventory } from './publish-sibling-drift.js';
170
+ export type { SiblingDriftStatus, InventorySource, SiblingDriftResult, FetchedPublished, FetchPublished, DetectSiblingDriftOptions, PackInventory, PackInventoryUnavailable, LocalInventoryResult, PackedTree, LocalInventory, } from './publish-sibling-drift.js';
171
171
  export { planPackedInstallSmoke, judgePackedInstallSmoke, packedTarballName } from './packed-install-smoke.js';
172
172
  export type { PackedInstallStepKind, PackedInstallStep, PackedInstallPackageSpec, PackedInstallBinSpec, PlanPackedInstallSmokeOptions, PackedInstallPlan, PackedInstallExecution, PackedInstallBinVerdict, PackedInstallVerdict, } from './packed-install-smoke.js';
173
173
  export { computeRiskScore } from './risk-scoring.js';