@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/.dz-manifest.json CHANGED
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "path": "README.md",
12
- "sha256": "70cf5d858ca889a834345fe7c00f7312fc65477f5e5c3f6d2f4dd7d742ca2ed3"
12
+ "sha256": "7fb2af101753ac28e469a24a8f15789d0235d5749dd3a3cda42422d61ff13c0d"
13
13
  },
14
14
  {
15
15
  "path": "dist/__tests__/golden-baseline.test.d.ts",
@@ -29,19 +29,19 @@
29
29
  },
30
30
  {
31
31
  "path": "dist/agentdb-index.d.ts",
32
- "sha256": "69023233508c656035c8a27b95690bcfddab535d25dffb85f2041c4bfbf77f64"
32
+ "sha256": "6e86eca1e1b3db58f83c5e60b3af2943cb97a7365eb9754825b3e2fcdde5fe22"
33
33
  },
34
34
  {
35
35
  "path": "dist/agentdb-index.d.ts.map",
36
- "sha256": "965f21e2cb4c4f6ac8cf51b0238a64c3c44b0442ecc2ec198d67463bd7e76b31"
36
+ "sha256": "601500870a060848fd75912b8473b1d715ab4c97ea1d8c91db0711e0a0ebf352"
37
37
  },
38
38
  {
39
39
  "path": "dist/agentdb-index.js",
40
- "sha256": "2975c8ee201c4b6e7d78d0a7fc34e976d2d1c97692e6fce82c56417d90d397cd"
40
+ "sha256": "fdb88618197b66d9b107c50ac75b625e23a4498ddb20d13d8e9168d7e6aee790"
41
41
  },
42
42
  {
43
43
  "path": "dist/agentdb-index.js.map",
44
- "sha256": "866790c8dcb6614538513927c389231e3617ec5c883470e1e15c19d1f3b2128b"
44
+ "sha256": "8ada5fd59f070ece1436c97b0d4e96bc9067a2ab042a06637a4592ee9fcf74e9"
45
45
  },
46
46
  {
47
47
  "path": "dist/agentdb-reindex-marker.d.ts",
@@ -125,19 +125,19 @@
125
125
  },
126
126
  {
127
127
  "path": "dist/apply-leg.d.ts",
128
- "sha256": "a3b35c162ce1059ec52e66250f4d5eb40ea80031bc6ba211cf2c239125da2dab"
128
+ "sha256": "7d405581035820ac6e35fc3acf30685fb66f97120f4222d4389e81182cb234b6"
129
129
  },
130
130
  {
131
131
  "path": "dist/apply-leg.d.ts.map",
132
- "sha256": "a16afc919647db2ea568e29bf0e835df023a025716bf73e60ab5294300fee486"
132
+ "sha256": "1ec81dba7e182385ee9cebd1d4c41128915549797fb07bbff0cc540b7f72287a"
133
133
  },
134
134
  {
135
135
  "path": "dist/apply-leg.js",
136
- "sha256": "604ff5b789bf969728c174c560a0b463d64307f0120699feb28ed839d0e42afa"
136
+ "sha256": "94a7c64d577a8134413cd508b37ec346cf729571b86b0d0cb55168d9a67f7a76"
137
137
  },
138
138
  {
139
139
  "path": "dist/apply-leg.js.map",
140
- "sha256": "78b6f40ca672f6ea40ce4d29c9ae9baab74c74252400a5e05540272a612201b1"
140
+ "sha256": "cc1ed9820f186de277c75bbcffd102e651e34283a7728307d4c377ad7e207b7a"
141
141
  },
142
142
  {
143
143
  "path": "dist/apply.d.ts",
@@ -1037,19 +1037,19 @@
1037
1037
  },
1038
1038
  {
1039
1039
  "path": "dist/index.d.ts",
1040
- "sha256": "9268dcea6b76bcc172de258f26b263384be72751ecd80bf695d30fa956ce3255"
1040
+ "sha256": "0ec8aabd62c19b421d56b9ddfc3a769ca88a6edad072e6b458a9ec0dce144847"
1041
1041
  },
1042
1042
  {
1043
1043
  "path": "dist/index.d.ts.map",
1044
- "sha256": "525593dc52d74876f41071fc906828b3b1807d5b8d1bf0e570589b8f5e23a6cd"
1044
+ "sha256": "d55811cc24161673964196697f78774b618ceff986f12d61233129af1309a06e"
1045
1045
  },
1046
1046
  {
1047
1047
  "path": "dist/index.js",
1048
- "sha256": "645544ee8ebb51df85c94f1150134c76885678ac0c54dfaaacfaa38090549ee6"
1048
+ "sha256": "db5d3897a75a8b5f41e4d63fc2b89e1ba0ad59d81c9ec7409f4a4e4bcaef3ed2"
1049
1049
  },
1050
1050
  {
1051
1051
  "path": "dist/index.js.map",
1052
- "sha256": "0a45a791953cdecc4fb0bff3d39ea158f1d204ba5c3507783affd94fc38c559a"
1052
+ "sha256": "7ed1c3d692bf9f60b3239b2ec714552c524139f98a666529c1c614c00b1928a2"
1053
1053
  },
1054
1054
  {
1055
1055
  "path": "dist/integration-apply.d.ts",
@@ -1489,15 +1489,15 @@
1489
1489
  },
1490
1490
  {
1491
1491
  "path": "dist/operations.d.ts.map",
1492
- "sha256": "f147b33e2edd6766f4d8256f980315a1458f0408bb0683f5324ccee28e0b8223"
1492
+ "sha256": "5e21fd824b54842ab455e1c2b4d381d3ba81eaefb37ee525ab44b61f3e1a4719"
1493
1493
  },
1494
1494
  {
1495
1495
  "path": "dist/operations.js",
1496
- "sha256": "568d5ea2e70f3672deadf656384e0dedc8f02136e1aacfbff18b523ee0c90fa9"
1496
+ "sha256": "cb895bd26042f722c29594f1c5d0db6471146516745de6b366ed3b1a06af1906"
1497
1497
  },
1498
1498
  {
1499
1499
  "path": "dist/operations.js.map",
1500
- "sha256": "43e8044e64abc740d5db2486e149acdc943c58a046d9b0c94038e53c207fc0af"
1500
+ "sha256": "3d7103bd1f9c96aefe9ade44d53a321ae5c057171a6556b228350fc3faf74f33"
1501
1501
  },
1502
1502
  {
1503
1503
  "path": "dist/package-skill-layouts.d.ts",
@@ -1677,19 +1677,19 @@
1677
1677
  },
1678
1678
  {
1679
1679
  "path": "dist/publish-sibling-drift.d.ts",
1680
- "sha256": "63e4bb439f1366114d21b9796489fec34308c34818bddeb6b69f590b8882c0fd"
1680
+ "sha256": "8e39c9f1d527ddaaa8b8655ee1e2fa0ee005926e25da8c3218cf0fb9cbed5502"
1681
1681
  },
1682
1682
  {
1683
1683
  "path": "dist/publish-sibling-drift.d.ts.map",
1684
- "sha256": "6c564150ddcb07ce2994c63764a0acb3d282bd702ed79dc906c886affc3e84e9"
1684
+ "sha256": "257237bac3a1d173113b4525ea19dbb4f7984a08ad017ebdd7af164ba6cc7cfe"
1685
1685
  },
1686
1686
  {
1687
1687
  "path": "dist/publish-sibling-drift.js",
1688
- "sha256": "b99fca72e63868d9177052aefe47390e9f5e08ff6869d65299dc0286c8bdfd18"
1688
+ "sha256": "16ac3f704998f295ed42c112277482d6adfb5d26e4c8a4c89781d24b63118f6f"
1689
1689
  },
1690
1690
  {
1691
1691
  "path": "dist/publish-sibling-drift.js.map",
1692
- "sha256": "504ecc5393016745aef5c60dfa9162a6531625a56b34ced46f4f8ee31d72bf11"
1692
+ "sha256": "8143d41cd1c706713fe6d9a742b71d9a28b3519a72072ca4683837ab54732d30"
1693
1693
  },
1694
1694
  {
1695
1695
  "path": "dist/publish-signing.d.ts",
@@ -1901,19 +1901,19 @@
1901
1901
  },
1902
1902
  {
1903
1903
  "path": "dist/release.d.ts",
1904
- "sha256": "cf5750b9c6d474c45cfd81b7cbb2f92a18b452fa1c069e4e3fbfc4dac06267d9"
1904
+ "sha256": "937161c359ffed77233d43ba2b5280cd8f34962baa1758daf8479805e23621ef"
1905
1905
  },
1906
1906
  {
1907
1907
  "path": "dist/release.d.ts.map",
1908
- "sha256": "6eaca079115921991149d68189ed8ef8c61be6efd12c426df8d091c1b39da5b9"
1908
+ "sha256": "6ce025a95be2b36246e6a8dbe3b324539e60d3f79febe1330071e51fced1282a"
1909
1909
  },
1910
1910
  {
1911
1911
  "path": "dist/release.js",
1912
- "sha256": "627e5efa90298701d01bee346790647f5688dc0f10c4727b348298490c35d219"
1912
+ "sha256": "0030839d3dfaa43dabed352703255a7f6f0e11c8e3db01abaa4341fddb57e211"
1913
1913
  },
1914
1914
  {
1915
1915
  "path": "dist/release.js.map",
1916
- "sha256": "a539f499cf28923856c6cb6f40417d67d662c6771b4df8fe4e7fe5ab9f2a7121"
1916
+ "sha256": "2f1cfa37c4f868859e6ea2b5aba4b896bd106e8ed1a9a8b5285b9ad30e52d896"
1917
1917
  },
1918
1918
  {
1919
1919
  "path": "dist/repo-boundary.d.ts",
@@ -2653,19 +2653,19 @@
2653
2653
  },
2654
2654
  {
2655
2655
  "path": "dist/vector-tier.d.ts",
2656
- "sha256": "289cc4a73d023af16d44ab00caa4c1cad2cbe6bd6720b6eddf932ef37e200a5b"
2656
+ "sha256": "cdf68fa28b6a7e78d0381a5b2d23647ae812fee004e31b4c8c3893a897fd6f6f"
2657
2657
  },
2658
2658
  {
2659
2659
  "path": "dist/vector-tier.d.ts.map",
2660
- "sha256": "52e4813a1af157a58ea91b7787c44c09dfc68e44b0baee315182467913c4dc08"
2660
+ "sha256": "2943b848f7af427dcfecf801a778fe7eb2a6f899e395956aca5f45a9fcce3d79"
2661
2661
  },
2662
2662
  {
2663
2663
  "path": "dist/vector-tier.js",
2664
- "sha256": "cf0d978a1e9bffb32a854d20a0a88a4daad7e852f12287db15ae1707c0db66a3"
2664
+ "sha256": "a48e13d799185bc95134a23cbe7d9ee91f9dcaf64c1c7c5faa4cf45a4cf94d08"
2665
2665
  },
2666
2666
  {
2667
2667
  "path": "dist/vector-tier.js.map",
2668
- "sha256": "f8db2ecd2284f2d5af15049443aa295c56fa3d67a2240bb4f08b884f36cf41bd"
2668
+ "sha256": "9a74e49879f494f01aec757b4efe0f41245cf20cf1cc4e07123852f6939463cf"
2669
2669
  },
2670
2670
  {
2671
2671
  "path": "dist/workflow-run-dispatch.d.ts",
@@ -2733,7 +2733,7 @@
2733
2733
  },
2734
2734
  {
2735
2735
  "path": "package.json",
2736
- "sha256": "a6f86350222413a151c6d4f73d9c80f4e2d3c21297000e2fe7b0708248d77724"
2736
+ "sha256": "26a1b1c5cd3d01ea854d9fb9ef126fe3cfd6580a52d0a1c7b60f4dffcc280d8d"
2737
2737
  },
2738
2738
  {
2739
2739
  "path": "src/__tests__/golden-baseline.test.ts",
@@ -2741,7 +2741,7 @@
2741
2741
  },
2742
2742
  {
2743
2743
  "path": "src/agentdb-index.ts",
2744
- "sha256": "49c55278320cf79d50463374cb4bd98702381eefc61aa81cf3889f117857f7d0"
2744
+ "sha256": "f3b7a86fc7ec49fc7b47d69a6beb4ace4e193f9a4b63237b257a7cae1879d4f7"
2745
2745
  },
2746
2746
  {
2747
2747
  "path": "src/agentdb-reindex-marker.ts",
@@ -2765,7 +2765,7 @@
2765
2765
  },
2766
2766
  {
2767
2767
  "path": "src/apply-leg.ts",
2768
- "sha256": "15feafe9dedd298f2d8f7815d2a100cedaf4864223affb80f8e8c34317e4b0f6"
2768
+ "sha256": "d0bc07ff16397b8d0d6b26fd72a770553f421902b81e3d5e775e08b4db4710a3"
2769
2769
  },
2770
2770
  {
2771
2771
  "path": "src/apply.ts",
@@ -2997,7 +2997,7 @@
2997
2997
  },
2998
2998
  {
2999
2999
  "path": "src/index.ts",
3000
- "sha256": "307f2d574fd2d7a0f2b8ebe7a36047f0c3d8cade6e8fdda9e10e26d344914912"
3000
+ "sha256": "a2ae53ebaa9993545153419f615db85f7a2d412f61deddb44780773e8ea52be2"
3001
3001
  },
3002
3002
  {
3003
3003
  "path": "src/integration-apply.ts",
@@ -3113,7 +3113,7 @@
3113
3113
  },
3114
3114
  {
3115
3115
  "path": "src/operations.ts",
3116
- "sha256": "fd66a40569fd53cbf0d621643ace1e4f89777e9634bcda24a730e971dc240ccd"
3116
+ "sha256": "9f20a5a9c3e6ff41245612f74f04f62e719744fab2f97ee9d93fcdf4fa52668b"
3117
3117
  },
3118
3118
  {
3119
3119
  "path": "src/package-skill-layouts.ts",
@@ -3161,7 +3161,7 @@
3161
3161
  },
3162
3162
  {
3163
3163
  "path": "src/publish-sibling-drift.ts",
3164
- "sha256": "2bd607ec044e2bca2a7336e10d69cee99db53e6f41b60bfa770711d756dd9116"
3164
+ "sha256": "5a7c2cffce4e62e4e859578b7014020670125e1ea68d4e04f2b1f6256c423b7a"
3165
3165
  },
3166
3166
  {
3167
3167
  "path": "src/publish-signing.ts",
@@ -3217,7 +3217,7 @@
3217
3217
  },
3218
3218
  {
3219
3219
  "path": "src/release.ts",
3220
- "sha256": "b7e248afaadc503642ef3b22eb86817e8ecb12744493c1780065de87772483a4"
3220
+ "sha256": "4e3390606a39f54b2a15db985a6e72a4f34c2ef59765c5124e1d64844d97447c"
3221
3221
  },
3222
3222
  {
3223
3223
  "path": "src/repo-boundary.ts",
@@ -3405,7 +3405,7 @@
3405
3405
  },
3406
3406
  {
3407
3407
  "path": "src/vector-tier.ts",
3408
- "sha256": "f5b5187d2537f2d00c3f248676928d286e715e9984f67491aa1e02eb0f4b1b50"
3408
+ "sha256": "6086c8aabf98d69d9fc7d8b22d88dfbe1588ac1a4e2ddae66a3738e02dc638f2"
3409
3409
  },
3410
3410
  {
3411
3411
  "path": "src/workflow-run-dispatch.ts",
@@ -3425,5 +3425,5 @@
3425
3425
  }
3426
3426
  ]
3427
3427
  },
3428
- "signature": "9lkZG7XpDHs9qtNmKiBJYt3PMKTOAhxXxEU3F4n2uOYQps/u6lY0vb50bdKsxMoZem8/R2qORHxYCU4kN+iYAQ=="
3428
+ "signature": "Qg/pWuzvk2SqP54zlyFPEq6VyAkl6aYu6bQuRgX8C4i/ePjQXMlMQn68zZDP1Fc9jj+vQbf7JJmEw/UjUreXAw=="
3429
3429
  }
package/README.md CHANGED
@@ -604,6 +604,62 @@ instead of only ever checking the plain project path. The daemon also now prints
604
604
  (path N bytes)` and exits non-zero, never a silent "ready" for a socket that was never created
605
605
  (`APPLY_LEG_VERSION` bumped 3→4 for this and the resolver change).
606
606
 
607
+ ### One recall engine for hook and CLI (`hook-recall-hybrid-parity`, ADR-001, `APPLY_LEG_VERSION` 4→5)
608
+
609
+ The daemon's `op: recall` handler used to run its own brute-force cosine loop over the in-memory
610
+ mirror — a SECOND engine, diverging from `dz recall`'s `recallHybrid` (FTS5 lexical + semantic +
611
+ RRF). MEASURED (record 097ca040): 41.8% of taught lessons went unretrieved by either path over 48
612
+ days, and an exact lexical match at cosine 0.39 was silently dropped by the hook's cosine floor.
613
+
614
+ `embedDaemonSource(coreDistDir?)` now takes the SAME `coreDistDir` parameter `recallHookSource`
615
+ already had (default `null`, the hub's own portable marker) and inlines the SAME `loadCoreModule`
616
+ candidate-list pattern the hook uses, loading `index.js` from the resolved `CORE_DIST_DIR` to reach
617
+ `recallHybrid`/`patternRecordId`. `answerRecall(prompt, limit)` — the whole `op: recall` answer —
618
+ tries `hybridRecall` first: `core.recallHybrid(PROJECT, prompt, { limit, mode: 'hook',
619
+ deferExposures: true })`, raced via `Promise.race` against a `HOOK_RECALL_BUDGET_MS` timer (env,
620
+ default 500, always below the hook's own 800 ms socket timeout). On success the reply carries
621
+ `engine: 'hybrid'` and `hits[].score` normalized from the raw RRF sum into `[0,1]`
622
+ (`score / (2/(RRF_K+1))`, `RRF_K=60` — duplicated from `vector-tier.ts`'s own constant since this is
623
+ standalone generated text; `apply-leg-twins.test.ts` does not currently pin the two numerically
624
+ equal, only that both exist as literals — a numeric drift would need to be caught by the parity
625
+ test's own live assertions). On budget overrun / engine error / no resolvable core module, it falls
626
+ straight through to TODAY'S cosine leg (byte-identical) with `engine: 'cosine-fallback'` and a
627
+ `reason`.
628
+
629
+ `HybridRecallMode` in `vector-tier.ts` gained a fourth literal, `'hook'` — ranked identically to
630
+ `'hybrid'` (no semantic-weight change); its only role is to travel end to end for observability. The
631
+ ACTUAL mechanism that keeps a per-prompt recall from moving the lesson-bandit's exposure counters is
632
+ `deferExposures: true` plus never calling the returned `commitExposures(...)` — `recallHybrid`
633
+ already supported deferral for `dz recall --domain`'s own over-fetch-and-truncate case; the daemon is
634
+ simply a second caller of the same contract.
635
+
636
+ `pickEngine` (the one seam `recallHybrid`, `mirrorPatternsToVector`, `teachGuard` etc. all resolve
637
+ their engine through) now routes through `getOrOpenEngine(projectRoot)` instead of calling
638
+ `resolveVectorEngine` directly — a per-process cache keyed by `(projectRoot, mtime of
639
+ .dz/agentdb.db)`, so a long-lived caller (the daemon) pays the `isPackageInstalled`/`probeNativeDep`
640
+ walk once, not once per prompt. A short-lived CLI invocation is unaffected (the cache is populated
641
+ and discarded within one process either way — I-1 parity holds). `getOrOpenEngine`'s second
642
+ parameter is an injectable resolver (default `resolveVectorEngine`) purely for spy-testability — two
643
+ functions in the same ES module cannot be reliably intercepted by `vi.spyOn` when one calls the other
644
+ by its local name.
645
+
646
+ `dz doctor`'s "apply-leg alive (embed daemon)" check now sends one live `op: recall` probe
647
+ (`probeRecallEngine`, `operations.ts`, 1000 ms default — comfortably above the 500 ms production
648
+ budget default) when the socket exists, and appends `(engine: hybrid)` / `(engine: cosine-fallback)`
649
+ to the detail line on a successful reply. A non-listening path (every non-live doctor fixture in this
650
+ repo writes a plain file, never a real socket) fails the probe near-instantly, so every pre-existing
651
+ detail string is untouched.
652
+
653
+ **Honest NFR-1 finding.** MEASURED against the real 743-pattern production store on this machine,
654
+ 100 real prompts from `.dz/recall-usage.jsonl`, under the documented default budget: EVERY reply
655
+ fell back to `cosine-fallback` — `resolveAgentdbEmbedder` (`agentdb-index.ts`) reconstructs the
656
+ transformers pipeline on every call with no cross-call caching (measured standalone: 2–3.6 s/call,
657
+ no warm-up across repeats in one process), so a cold semantic leg routinely exceeds the 500 ms
658
+ budget. The p95/p50/reproducer script live in
659
+ `features/hook-recall-hybrid-parity/07_code_changes/change_manifest.md`. Fixing the embedder's own
660
+ cache is `agentdb-index.ts` work, outside this feature's touched files — named here as a follow-up,
661
+ not silently absorbed into a passing-looking number.
662
+
607
663
  ## Run a plan without the Claude host
608
664
 
609
665
  `runWorkflow` (`workflow-run.ts`) is the PURE scheduler behind `dz workflow run`: it INTERPRETS a
@@ -812,6 +868,28 @@ unchanged) from "the store file itself is unreadable" (corrupt file, permission
812
868
  one `dz: <path> unreadable (<cause>) — falling back to the JSON store` line on stderr per process in
813
869
  the second case, so a broken store no longer looks like plain "fewer lessons".
814
870
 
871
+ ## Embedder cache (`agentdb-index.ts` — `resolveAgentdbEmbedder`)
872
+
873
+ `resolveAgentdbEmbedder(projectRoot)` resolves agentdb's `EmbeddingService` and stands up the
874
+ `@huggingface/transformers` pipeline behind it — MEASURED 2026-09-14 at 2-3.6s per call
875
+ (`features/agentdb-embedder-cache/00_complexity_assessment.md`), because the model+dim for a
876
+ project never changes within one process. It is now cached at module scope, keyed by
877
+ `${agentdbDir}|${model}|${dim}` (so a `DZ_EMBED_MODEL`/`.dz/config.json` change — a different
878
+ `resolveEmbedModel` result — gets its own entry rather than reusing a stale pipeline):
879
+
880
+ - Repeat calls for the same key return the **same object**, not a re-initialized one — MEASURED
881
+ 2026-09-14 (`test/agentdb-embedder-cache.test.ts`, live model): cold call `2117ms`, warm call
882
+ `1ms` (budget: ≤50ms).
883
+ - The **promise** is cached, not the awaited result, so concurrent first callers for the same key
884
+ join one in-flight initialization instead of racing two pipelines (`getAgentdbEmbedderCacheStats()`
885
+ reports `initializations: 1` for two parallel first calls).
886
+ - An `{error}` outcome (or a rejection) evicts its own cache entry immediately, so a failed init
887
+ never "sticks" — the next call retries against the current config.
888
+ - `resetAgentdbEmbedderCache()` clears the cache and the `initializations` counter; it exists for
889
+ tests and future warm-start use only — `vector-tier.ts`/`backlog.ts` call sites are unaffected.
890
+ - `getAgentdbEmbedderCacheStats()` returns `{ entries, initializations }` (`entries` = currently
891
+ cached successful pipelines, `initializations` = pipelines actually started since the last reset).
892
+
815
893
  ## Consistent pre-reindex snapshot + rollback (`agentdb-snapshot.ts`)
816
894
 
817
895
  The pre-reindex snapshot `reindexAgentdbRows` takes before every reindex used to be a bare
@@ -101,16 +101,26 @@ export interface AgentdbSearchResult {
101
101
  readonly hits: AgentdbSearchHit[];
102
102
  readonly error?: string | undefined;
103
103
  }
104
+ type Embedder = {
105
+ embed: (t: string) => Promise<Float32Array>;
106
+ } | {
107
+ error: string;
108
+ };
109
+ /** Test-only (and future warm-start) reset — callers (`vector-tier.ts`, `backlog.ts`) are unaffected. */
110
+ export declare function resetAgentdbEmbedderCache(): void;
111
+ /** `entries` = cached keys right now — a SUCCESSFUL pipeline or an IN-FLIGHT initialization (the promise is
112
+ * cached before it settles, FR-4; a failed one is evicted, FR-3); `initializations` = pipelines actually
113
+ * started since the last reset. (Codex round-1, 2026-09-14: the earlier wording said "successful" only.) */
114
+ export declare function getAgentdbEmbedderCacheStats(): {
115
+ entries: number;
116
+ initializations: number;
117
+ };
104
118
  /**
105
119
  * Resolve agentdb's `EmbeddingService` from the PROJECT (same dynamic-resolution discipline as
106
120
  * {@link indexPatternsToAgentdb}); every dz call site uses the same resolved model so query and row
107
- * vectors stay in the same space.
121
+ * vectors stay in the same space. Cached per process — see {@link embedderCache} above.
108
122
  */
109
- export declare function resolveAgentdbEmbedder(projectRoot: string): Promise<{
110
- embed: (t: string) => Promise<Float32Array>;
111
- } | {
112
- error: string;
113
- }>;
123
+ export declare function resolveAgentdbEmbedder(projectRoot: string): Promise<Embedder>;
114
124
  /**
115
125
  * Cosine similarity in [-1, 1] over two embeddings. Exported (was file-private) so
116
126
  * `harmonizeVectorStore` scores near-duplicate pairs with the IDENTICAL math the semantic search
@@ -246,4 +256,5 @@ export declare function reindexAgentdbRows(projectRoot: string, rows: readonly A
246
256
  /** AM-3: present only when `rollback === 'failed'` — why the restore did not fully complete. */
247
257
  rollbackError?: string;
248
258
  }>;
259
+ export {};
249
260
  //# sourceMappingURL=agentdb-index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agentdb-index.d.ts","sourceRoot":"","sources":["../src/agentdb-index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agentdb-index.d.ts","sourceRoot":"","sources":["../src/agentdb-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH,OAAO,EAAqC,KAAK,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAChH,OAAO,EAAiD,KAAK,cAAc,EAAuB,MAAM,uBAAuB,CAAC;AAehI,iGAAiG;AACjG,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,iDAAiD;AACjD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAaD,mGAAmG;AACnG,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAI/E;AAuBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAiB3H;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,OAAO,CAAC,kBAAkB,CAAC,CAmF7B;AAMD;;;GAGG;AACH;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sCAAuC,CAAC;AAG1E;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,oDAAqD,CAAC;AAWtF,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,kGAAkG;IAClG,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,wGAAwG;AACxG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,EAAE,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAID,KAAK,QAAQ,GAAG;IAAE,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAgBpF,yGAAyG;AACzG,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD;AAED;;4GAE4G;AAC5G,wBAAgB,4BAA4B,IAAI;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAE3F;AA2BD;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CA4BnF;AA2DD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,MAAM,CAYzE;AAaD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAClG,OAAO,CAAC,mBAAmB,CAAC,CAmD9B;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAO,GAC5D,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC,CAyBxD;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B;IAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA6CxC;AAMD,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C;AAcD;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,SAAS,gBAAgB,EAAE,EACjC,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAwE/C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAmCrC;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAO,GAC5D;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA2CrC;AAED,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAuCpC;AAED,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,IAAI,GAAE;IACJ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC;IAC9C;gEAC4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;CACnB,GACL,OAAO,CAAC;IACT,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,2FAA2F;IAC3F,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,iGAAiG;IACjG,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,wFAAwF;IACxF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IACjC,gGAAgG;IAChG,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAyRD"}
@@ -203,27 +203,35 @@ const DZ_TASK_TYPES = DZ_PATTERN_TASK_TYPES;
203
203
  export const DZ_OWNED_TASK_TYPES = ['dz-teach', 'dz-learning', 'dz-backlog'];
204
204
  const DEPS_MISSING = 'agentdb/better-sqlite3 not installed in project (run: dz setup --memory agentdb)';
205
205
  /**
206
- * Resolve agentdb's `EmbeddingService` from the PROJECT (same dynamic-resolution discipline as
207
- * {@link indexPatternsToAgentdb}); every dz call site uses the same resolved model so query and row
208
- * vectors stay in the same space.
206
+ * `agentdb-embedder-cache` (feature): the transformers pipeline behind `EmbeddingService` is
207
+ * expensive to stand up (MEASURED 2026-09-14: 2-3.6s per `resolveAgentdbEmbedder` call — see
208
+ * `features/agentdb-embedder-cache/00_complexity_assessment.md`), yet the resolved model/dim never
209
+ * changes within one process. Keyed by `${agentdbDir}|${model}|${dim}` so a config/env change (a
210
+ * different `resolveEmbedModel` source) gets its own entry (FR-2) rather than reusing a stale
211
+ * pipeline. The PROMISE is cached, not the awaited result (FR-4): concurrent first callers for the
212
+ * same key join the same in-flight initialization instead of racing two pipelines. An `{error}`
213
+ * outcome (or a rejection) evicts its own entry so the next call retries cleanly (FR-3) — a failure
214
+ * must never "stick".
209
215
  */
210
- export async function resolveAgentdbEmbedder(projectRoot) {
211
- let agentdbDir;
212
- try {
213
- const req = createRequire(join(projectRoot, 'package.json'));
214
- agentdbDir = dirname(req.resolve('agentdb'));
215
- }
216
- catch {
217
- return { error: DEPS_MISSING };
218
- }
216
+ const embedderCache = new Map();
217
+ let embedderCacheInitializations = 0;
218
+ /** Test-only (and future warm-start) reset — callers (`vector-tier.ts`, `backlog.ts`) are unaffected. */
219
+ export function resetAgentdbEmbedderCache() {
220
+ embedderCache.clear();
221
+ embedderCacheInitializations = 0;
222
+ }
223
+ /** `entries` = cached keys right now — a SUCCESSFUL pipeline or an IN-FLIGHT initialization (the promise is
224
+ * cached before it settles, FR-4; a failed one is evicted, FR-3); `initializations` = pipelines actually
225
+ * started since the last reset. (Codex round-1, 2026-09-14: the earlier wording said "successful" only.) */
226
+ export function getAgentdbEmbedderCacheStats() {
227
+ return { entries: embedderCache.size, initializations: embedderCacheInitializations };
228
+ }
229
+ async function initAgentdbEmbedder(agentdbDir, model, dim) {
219
230
  try {
220
231
  const { EmbeddingService } = (await import(pathToFileURL(join(agentdbDir, 'controllers', 'EmbeddingService.js')).href));
221
- const model = resolveEmbedModel(projectRoot);
222
- if ('error' in model)
223
- return { error: model.error };
224
232
  const emb = new EmbeddingService({
225
- model: model.model,
226
- dimension: model.dim,
233
+ model,
234
+ dimension: dim,
227
235
  provider: 'transformers',
228
236
  // agentdb >= 3.0.0-alpha.20 refuses UNREGISTERED models without an explicit role policy
229
237
  // (its built-in registry knows all-MiniLM-L6-v2 but not our multilingual variant — grounded
@@ -241,6 +249,42 @@ export async function resolveAgentdbEmbedder(projectRoot) {
241
249
  return { error: `embedder init failed: ${err instanceof Error ? err.message : String(err)}` };
242
250
  }
243
251
  }
252
+ /**
253
+ * Resolve agentdb's `EmbeddingService` from the PROJECT (same dynamic-resolution discipline as
254
+ * {@link indexPatternsToAgentdb}); every dz call site uses the same resolved model so query and row
255
+ * vectors stay in the same space. Cached per process — see {@link embedderCache} above.
256
+ */
257
+ export async function resolveAgentdbEmbedder(projectRoot) {
258
+ let agentdbDir;
259
+ try {
260
+ const req = createRequire(join(projectRoot, 'package.json'));
261
+ agentdbDir = dirname(req.resolve('agentdb'));
262
+ }
263
+ catch {
264
+ return { error: DEPS_MISSING };
265
+ }
266
+ const model = resolveEmbedModel(projectRoot);
267
+ if ('error' in model)
268
+ return { error: model.error };
269
+ const key = `${agentdbDir}|${model.model}|${model.dim}`;
270
+ const hit = embedderCache.get(key);
271
+ if (hit !== undefined)
272
+ return hit;
273
+ embedderCacheInitializations += 1;
274
+ const promise = initAgentdbEmbedder(agentdbDir, model.model, model.dim);
275
+ embedderCache.set(key, promise);
276
+ // FR-3: an init failure must not stick — evict so the next call retries instead of replaying
277
+ // the same {error} forever. `.catch` here only guards a rejection that slips past
278
+ // `initAgentdbEmbedder`'s own try/catch; it never rethrows (this is bookkeeping, not the return path).
279
+ void promise.then((result) => {
280
+ if ('error' in result && embedderCache.get(key) === promise)
281
+ embedderCache.delete(key);
282
+ }, () => {
283
+ if (embedderCache.get(key) === promise)
284
+ embedderCache.delete(key);
285
+ });
286
+ return promise;
287
+ }
244
288
  /** `absent: true` = no store file yet — an EMPTY mirror is a state, not an error (backfill relies on this). */
245
289
  function openReadonly(projectRoot, dbPath) {
246
290
  const dbFile = resolveAgentdbPath(projectRoot, dbPath);