akm-cli 0.9.17-alpha.3 → 0.9.17-alpha.5

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.
Files changed (346) hide show
  1. package/CHANGELOG.md +760 -0
  2. package/dist/akm +94 -196
  3. package/dist/cli/shared.js +6 -2
  4. package/dist/cli.js +22 -9
  5. package/dist/commands/agent/agent-dispatch.js +1 -1
  6. package/dist/commands/command/command-execution.js +24 -62
  7. package/dist/commands/feedback-cli.js +0 -1
  8. package/dist/commands/health/accept-rate.js +2 -2
  9. package/dist/commands/health/checks.js +30 -75
  10. package/dist/commands/health/config-skew.js +38 -0
  11. package/dist/commands/health/egress.js +54 -0
  12. package/dist/commands/health/html-report.js +0 -38
  13. package/dist/commands/health/improve-metrics.js +123 -562
  14. package/dist/commands/health/plugin-staleness.js +53 -3
  15. package/dist/commands/health/renderers.js +12 -4
  16. package/dist/commands/health/report-view-model.js +11 -106
  17. package/dist/commands/health/types-improve.js +4 -19
  18. package/dist/commands/health/windows.js +64 -73
  19. package/dist/commands/health.js +122 -143
  20. package/dist/commands/improve/consolidate/chunking.js +25 -100
  21. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  22. package/dist/commands/improve/consolidate.js +538 -1075
  23. package/dist/commands/improve/content-hash.js +16 -24
  24. package/dist/commands/improve/distill/content-repair.js +18 -100
  25. package/dist/commands/improve/distill-guards.js +20 -81
  26. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  27. package/dist/commands/improve/distill.js +608 -1075
  28. package/dist/commands/improve/eligibility.js +126 -400
  29. package/dist/commands/improve/execution.js +3 -5
  30. package/dist/commands/improve/extract.js +487 -1046
  31. package/dist/commands/improve/feedback-valence.js +0 -25
  32. package/dist/commands/improve/improve-cli.js +29 -166
  33. package/dist/commands/improve/improve-result-file.js +10 -66
  34. package/dist/commands/improve/improve-strategies.js +12 -7
  35. package/dist/commands/improve/improve-usage-report.js +18 -64
  36. package/dist/commands/improve/improve.js +443 -1063
  37. package/dist/commands/improve/ledger.js +114 -0
  38. package/dist/commands/improve/locks.js +2 -8
  39. package/dist/commands/improve/loop-stages.js +459 -1172
  40. package/dist/commands/improve/memory/derived-ref.js +12 -77
  41. package/dist/commands/improve/memory/memory-belief.js +14 -118
  42. package/dist/commands/improve/memory/memory-improve.js +4 -3
  43. package/dist/commands/improve/outcome-loop.js +28 -156
  44. package/dist/commands/improve/planner.js +5 -10
  45. package/dist/commands/improve/preparation.js +851 -2339
  46. package/dist/commands/improve/proactive-maintenance.js +34 -101
  47. package/dist/commands/improve/reflect-noise.js +104 -280
  48. package/dist/commands/improve/reflect.js +621 -1367
  49. package/dist/commands/improve/salience.js +46 -232
  50. package/dist/commands/improve/session-asset.js +19 -100
  51. package/dist/commands/improve/stage.js +323 -0
  52. package/dist/commands/lint/base-linter.js +19 -5
  53. package/dist/commands/proposal/drain.js +251 -644
  54. package/dist/commands/proposal/proposal-cli.js +3 -18
  55. package/dist/commands/proposal/proposal-types.js +20 -41
  56. package/dist/commands/proposal/proposal.js +1 -2
  57. package/dist/commands/proposal/propose.js +134 -160
  58. package/dist/commands/proposal/repository.js +502 -1487
  59. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  60. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  61. package/dist/commands/proposal/validators/proposals.js +13 -89
  62. package/dist/commands/read/curate.js +63 -413
  63. package/dist/commands/read/search-cli.js +16 -33
  64. package/dist/commands/read/search.js +17 -23
  65. package/dist/commands/read/show.js +2 -13
  66. package/dist/commands/sources/bundle-cli.js +25 -2
  67. package/dist/commands/sources/bundle-config-ops.js +4 -0
  68. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  69. package/dist/commands/sources/info.js +2 -11
  70. package/dist/commands/sources/installed-stashes.js +197 -746
  71. package/dist/commands/sources/schema-repair.js +98 -129
  72. package/dist/commands/sources/source-add.js +62 -12
  73. package/dist/commands/sources/source-manage.js +9 -2
  74. package/dist/commands/sources/stash-cli.js +1 -1
  75. package/dist/commands/tasks/explain.js +10 -13
  76. package/dist/commands/tasks/tasks-cli.js +9 -8
  77. package/dist/commands/tasks/tasks.js +326 -930
  78. package/dist/commands/tasks/validate.js +42 -21
  79. package/dist/commands/workflow/plan.js +22 -29
  80. package/dist/commands/workflow-cli.js +4 -4
  81. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  82. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  83. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  84. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  85. package/dist/core/adapter/execution-source.js +17 -29
  86. package/dist/core/asset/asset-placement.js +4 -13
  87. package/dist/core/asset/resolve-ref.js +1 -1
  88. package/dist/core/bundle-id.js +42 -5
  89. package/dist/core/bundle-rename.js +291 -0
  90. package/dist/core/config/config-io.js +1 -2
  91. package/dist/core/config/config-schema.js +1 -33
  92. package/dist/core/config/config-walker.js +1 -1
  93. package/dist/core/config/config.js +163 -68
  94. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  95. package/dist/core/config/schema/embedding.js +20 -5
  96. package/dist/core/config/schema/engines.js +5 -0
  97. package/dist/core/config/schema/execution.js +1 -1
  98. package/dist/core/config/schema/experimental.js +1 -1
  99. package/dist/core/config/schema/improve-processes.js +21 -95
  100. package/dist/core/config/schema/improve.js +4 -42
  101. package/dist/core/config/schema/scheduler.js +12 -12
  102. package/dist/core/config/schema/search.js +6 -22
  103. package/dist/core/env-secret-ref.js +0 -1
  104. package/dist/core/errors.js +8 -9
  105. package/dist/core/file-lock.js +76 -173
  106. package/dist/core/logs-db.js +2 -2
  107. package/dist/core/paths.js +0 -27
  108. package/dist/core/redaction.js +109 -2
  109. package/dist/core/run-lock.js +2 -5
  110. package/dist/core/spawn-env.js +1 -1
  111. package/dist/core/state/migrations.js +108 -61
  112. package/dist/core/state-db-scope.js +2 -4
  113. package/dist/core/state-db.js +126 -692
  114. package/dist/core/type-presentation.js +1 -9
  115. package/dist/core/write-source.js +293 -1012
  116. package/dist/execution/input-contract.js +1 -1
  117. package/dist/execution/resolved-request.js +135 -689
  118. package/dist/execution/source.js +63 -257
  119. package/dist/execution/target-ref.js +1 -1
  120. package/dist/indexer/bundle-identity-guard.js +2 -2
  121. package/dist/indexer/db/graph-db.js +106 -46
  122. package/dist/indexer/ensure-index.js +44 -85
  123. package/dist/indexer/graph/graph-extraction.js +340 -562
  124. package/dist/indexer/graph/graph-related.js +130 -0
  125. package/dist/indexer/index-rebuild-lock.js +3 -11
  126. package/dist/indexer/index-writer-lock.js +8 -17
  127. package/dist/indexer/index-written-assets.js +139 -151
  128. package/dist/indexer/indexer.js +524 -846
  129. package/dist/indexer/materialize-embeddings.js +60 -397
  130. package/dist/indexer/passes/memory-inference.js +81 -90
  131. package/dist/indexer/passes/metadata.js +132 -200
  132. package/dist/indexer/read-preflight.js +0 -7
  133. package/dist/indexer/scan/doc-to-entry.js +1 -3
  134. package/dist/indexer/scan/drain-dir.js +1 -1
  135. package/dist/indexer/search/db-search.js +181 -590
  136. package/dist/indexer/search/fts-query.js +30 -41
  137. package/dist/indexer/search/ranking.js +28 -154
  138. package/dist/indexer/search/search-attribution.js +12 -32
  139. package/dist/indexer/search/search-fields.js +11 -15
  140. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  141. package/dist/indexer/search/search-source.js +1 -4
  142. package/dist/indexer/usage/usage-events.js +2 -7
  143. package/dist/integrations/agent/engine-fallback.js +23 -40
  144. package/dist/integrations/agent/engine-resolution.js +93 -183
  145. package/dist/integrations/agent/execution.js +507 -0
  146. package/dist/integrations/agent/model-map.js +28 -156
  147. package/dist/integrations/agent/request-lowering.js +66 -141
  148. package/dist/integrations/agent/runner-dispatch.js +143 -321
  149. package/dist/integrations/agent/runner.js +54 -14
  150. package/dist/integrations/lockfile.js +53 -101
  151. package/dist/llm/embedders/deterministic.js +2 -3
  152. package/dist/llm/embedders/profile.js +71 -0
  153. package/dist/llm/embedders/remote.js +10 -15
  154. package/dist/llm/graph-extract.js +3 -12
  155. package/dist/llm/index-passes.js +3 -5
  156. package/dist/llm/memory-infer.js +1 -2
  157. package/dist/llm/metadata-enhance.js +1 -2
  158. package/dist/llm/structured-call.js +5 -24
  159. package/dist/output/generic-render.js +23 -11
  160. package/dist/output/html-render.js +13 -10
  161. package/dist/output/render-registry.js +3 -32
  162. package/dist/output/shapes/helpers.js +2 -34
  163. package/dist/output/shapes/passthrough.js +1 -9
  164. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  165. package/dist/output/text/command-format.js +60 -23
  166. package/dist/output/text/helpers.js +1 -1
  167. package/dist/output/text/migrate.js +5 -14
  168. package/dist/output/text/proposal-format.js +1 -2
  169. package/dist/output/text/workflow-format.js +0 -32
  170. package/dist/output/text.js +2 -0
  171. package/dist/registry/factory.js +4 -19
  172. package/dist/registry/network.js +66 -220
  173. package/dist/registry/providers/index.js +0 -2
  174. package/dist/registry/providers/skills-sh.js +3 -14
  175. package/dist/registry/providers/static-index.js +24 -26
  176. package/dist/registry/resolve.js +55 -131
  177. package/dist/scripts/akm-migrate-node.js +43940 -93320
  178. package/dist/scripts/akm-migrate.js +43700 -93078
  179. package/dist/setup/registry-stash-loader.js +4 -13
  180. package/dist/setup/semantic-assets.js +3 -44
  181. package/dist/setup/setup.js +1 -1
  182. package/dist/setup/steps/tasks.js +25 -15
  183. package/dist/sources/provider-factory.js +17 -18
  184. package/dist/sources/providers/filesystem.js +2 -3
  185. package/dist/sources/providers/git-install.js +7 -1
  186. package/dist/sources/providers/git-provider.js +0 -3
  187. package/dist/sources/providers/git-stash.js +0 -17
  188. package/dist/sources/providers/npm.js +2 -4
  189. package/dist/sources/providers/provider-utils.js +5 -10
  190. package/dist/sources/providers/website.js +0 -2
  191. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  192. package/dist/sources/website-url.js +2 -2
  193. package/dist/storage/database.js +9 -35
  194. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  195. package/dist/storage/repositories/index-connection.js +34 -70
  196. package/dist/storage/repositories/index-entries-repository.js +69 -111
  197. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  198. package/dist/storage/repositories/index-entry-schema.js +83 -269
  199. package/dist/storage/repositories/index-fts-repository.js +86 -256
  200. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  201. package/dist/storage/repositories/index-meta-repository.js +6 -4
  202. package/dist/storage/repositories/index-schema.js +192 -220
  203. package/dist/storage/repositories/index-utility-repository.js +8 -29
  204. package/dist/storage/repositories/index-vec-repository.js +133 -414
  205. package/dist/storage/repositories/outcome-repository.js +2 -1
  206. package/dist/storage/repositories/proposals-repository.js +35 -0
  207. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  208. package/dist/storage/repositories/task-history-repository.js +26 -4
  209. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  210. package/dist/storage/sqlite-migrations.js +136 -0
  211. package/dist/storage/sqlite-pragmas.js +11 -9
  212. package/dist/storage/sqlite-transaction.js +170 -0
  213. package/dist/storage/state-db-integrity.js +34 -27
  214. package/dist/tasks/activation-config.js +134 -62
  215. package/dist/tasks/backends/cron.js +129 -277
  216. package/dist/tasks/backends/exec-utils.js +2 -5
  217. package/dist/tasks/backends/launchd.js +125 -745
  218. package/dist/tasks/backends/schtasks.js +101 -620
  219. package/dist/tasks/prepare/prepare-support.js +5 -15
  220. package/dist/tasks/prepare/prepare.js +0 -2
  221. package/dist/tasks/resolve-akm-bin.js +20 -79
  222. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  223. package/dist/tasks/scheduler-binding.js +18 -238
  224. package/dist/tasks/scheduler-invocation.js +52 -52
  225. package/dist/tasks/scheduler-lock.js +53 -0
  226. package/dist/tasks/scheduler-sync.js +361 -751
  227. package/dist/tasks/source/parse-task-source.js +160 -10
  228. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  229. package/dist/tasks/source/task-to-v4.js +2 -2
  230. package/dist/workflows/authoring/authoring.js +3 -12
  231. package/dist/workflows/compile.js +211 -0
  232. package/dist/workflows/concurrency-policy.js +13 -74
  233. package/dist/workflows/exec/child-invocation.js +3 -17
  234. package/dist/workflows/exec/child-workflow.js +32 -141
  235. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  236. package/dist/workflows/exec/environment.js +98 -0
  237. package/dist/workflows/exec/exec-unit.js +33 -140
  238. package/dist/workflows/exec/frozen-judge.js +7 -59
  239. package/dist/workflows/exec/native-executor.js +82 -341
  240. package/dist/workflows/exec/param-secrets.js +29 -47
  241. package/dist/workflows/exec/run-workflow.js +154 -387
  242. package/dist/workflows/exec/scheduler.js +9 -36
  243. package/dist/workflows/exec/step-work.js +127 -430
  244. package/dist/workflows/exec/unit-dispatch.js +11 -63
  245. package/dist/workflows/exec/unit-writer.js +8 -52
  246. package/dist/workflows/exec/worktree.js +39 -273
  247. package/dist/workflows/freeze/child-output-references.js +4 -15
  248. package/dist/workflows/freeze/environment.js +99 -92
  249. package/dist/workflows/freeze/freeze.js +172 -0
  250. package/dist/workflows/freeze/step-values.js +19 -21
  251. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  252. package/dist/workflows/freeze/targets/command.js +10 -33
  253. package/dist/workflows/freeze/targets/script.js +5 -12
  254. package/dist/workflows/freeze/targets/shell.js +3 -6
  255. package/dist/workflows/freeze/targets/task.js +25 -80
  256. package/dist/workflows/freeze/task-bindings.js +20 -67
  257. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  258. package/dist/workflows/ir/params.js +6 -51
  259. package/dist/workflows/ir/plan-hash.js +2 -34
  260. package/dist/workflows/parser.js +140 -43
  261. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  262. package/dist/workflows/renderer.js +36 -69
  263. package/dist/workflows/resource-limits.js +12 -120
  264. package/dist/workflows/runtime/agent-identity.js +8 -40
  265. package/dist/workflows/runtime/run-outputs.js +3 -6
  266. package/dist/workflows/runtime/run-plan.js +316 -0
  267. package/dist/workflows/runtime/runs.js +48 -200
  268. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  269. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  270. package/dist/workflows/validate-summary.js +2 -7
  271. package/docs/integration/bundling-akm.md +49 -42
  272. package/docs/migration/README.md +1 -0
  273. package/docs/migration/release-notes/0.9.17.md +41 -0
  274. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  275. package/docs/reference/cli.md +182 -125
  276. package/docs/reference/configuration.md +49 -56
  277. package/docs/reference/data-and-telemetry.md +19 -20
  278. package/docs/reference/tasks.md +86 -38
  279. package/docs/reference/workflow-schema.md +14 -18
  280. package/docs/reference/workflows.md +6 -9
  281. package/package.json +1 -1
  282. package/schemas/akm-config.json +87 -406
  283. package/dist/commands/health/advisories.js +0 -150
  284. package/dist/commands/health/metrics.js +0 -329
  285. package/dist/commands/health/surfaces.js +0 -102
  286. package/dist/commands/improve/anti-collapse.js +0 -83
  287. package/dist/commands/improve/collapse-detector.js +0 -432
  288. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  289. package/dist/commands/improve/consolidate/merge.js +0 -146
  290. package/dist/commands/improve/distill/promote-memory.js +0 -329
  291. package/dist/commands/improve/distill/quality-gate.js +0 -500
  292. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  293. package/dist/commands/improve/proposal-envelope.js +0 -31
  294. package/dist/commands/improve/run-context.js +0 -123
  295. package/dist/commands/improve/shared.js +0 -21
  296. package/dist/commands/improve/source-identity.js +0 -28
  297. package/dist/commands/improve/triage.js +0 -96
  298. package/dist/commands/proposal/drain-policies.js +0 -151
  299. package/dist/commands/sources/update-transaction.js +0 -220
  300. package/dist/core/action-contributors.js +0 -28
  301. package/dist/core/config/config-version-shim.js +0 -101
  302. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  303. package/dist/core/fs-txn.js +0 -405
  304. package/dist/core/lexical-score.js +0 -25
  305. package/dist/core/maintenance-barrier.js +0 -167
  306. package/dist/execution/executable-identity.js +0 -105
  307. package/dist/execution/guarded-source.js +0 -441
  308. package/dist/indexer/graph/graph-boost.js +0 -427
  309. package/dist/indexer/graph/graph-dedup.js +0 -95
  310. package/dist/indexer/search/name-match.js +0 -35
  311. package/dist/indexer/search/ranking-contributors.js +0 -515
  312. package/dist/indexer/walk/project-context.js +0 -192
  313. package/dist/integrations/agent/execution-cascade.js +0 -566
  314. package/dist/integrations/agent/execution-definitions.js +0 -202
  315. package/dist/integrations/agent/execution-lowering.js +0 -841
  316. package/dist/integrations/agent/execution-preparation.js +0 -98
  317. package/dist/integrations/agent/inline-execution.js +0 -74
  318. package/dist/registry/create-provider-registry.js +0 -29
  319. package/dist/registry/pinned-request-helper.js +0 -247
  320. package/dist/registry/pinned-transport.js +0 -717
  321. package/dist/sources/providers/index.js +0 -14
  322. package/dist/storage/engines/sqlite-migrations.js +0 -271
  323. package/dist/storage/repositories/canaries-repository.js +0 -107
  324. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  325. package/dist/storage/repositories/registry-cache.js +0 -113
  326. package/dist/tasks/scheduler-sync-preview.js +0 -52
  327. package/dist/workflows/freeze/resolve-steps.js +0 -86
  328. package/dist/workflows/freeze/source-freeze.js +0 -64
  329. package/dist/workflows/ir/compile.js +0 -321
  330. package/dist/workflows/ir/environment-v4.js +0 -330
  331. package/dist/workflows/ir/freeze-v4.js +0 -153
  332. package/dist/workflows/ir/schema-v4.js +0 -745
  333. package/dist/workflows/ir/schema.js +0 -354
  334. package/dist/workflows/program/schema.js +0 -78
  335. package/dist/workflows/runtime/checkin.js +0 -57
  336. package/dist/workflows/runtime/plan-classifier.js +0 -196
  337. package/dist/workflows/runtime/unit-checkin.js +0 -45
  338. package/dist/workflows/runtime/unit-phases.js +0 -20
  339. package/dist/workflows/schema.js +0 -4
  340. package/dist/workflows/source-ir/compile.js +0 -200
  341. package/dist/workflows/source-ir/program.js +0 -50
  342. package/dist/workflows/source-ir/result.js +0 -26
  343. package/dist/workflows/source-ir/schema.js +0 -786
  344. package/dist/workflows/source-ir/triggers.js +0 -79
  345. package/dist/workflows/source-ir/uses.js +0 -40
  346. package/dist/workflows/validator.js +0 -60
@@ -1,329 +0,0 @@
1
- // This Source Code Form is subject to the terms of the Mozilla Public
2
- // License, v. 2.0. If a copy of the MPL was not distributed with this
3
- // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- /**
5
- * Memory→knowledge promotion branch for `akm distill`.
6
- *
7
- * This is an entire second command that used to be inlined inside `akmDistill`:
8
- * when a `memory:*` ref is reinforced enough (per the deterministic stability
9
- * heuristic in `distill-promotion-policy`), distill graduates it into a
10
- * `knowledge:*` proposal instead of a lesson. The branch owns its own LLM
11
- * contradiction-merge (mem0 ADD/UPDATE/NOOP), quality gate, proposal creation,
12
- * and `distill_invoked` event emit.
13
- *
14
- * {@link promoteMemoryToKnowledge} returns the finished {@link AkmDistillResult}
15
- * when the branch fired, or `null` when the ref is not a promotion candidate —
16
- * in which case the caller falls through to the ordinary lesson/knowledge LLM
17
- * path. Logic is byte-identical to the pre-extraction inline code.
18
- */
19
- import fs from "node:fs";
20
- import { parseFrontmatter } from "../../../core/asset/frontmatter.js";
21
- import { ConfigError } from "../../../core/errors.js";
22
- import { appendEvent } from "../../../core/events.js";
23
- import { parseEmbeddedJsonResponse } from "../../../core/parse.js";
24
- import { callStructured } from "../../../llm/structured-call.js";
25
- import { isProposalSkipped } from "../../proposal/repository.js";
26
- import { assessMemoryKnowledgePromotionCandidate } from "../distill-promotion-policy.js";
27
- import { emitProposal } from "../proposal-envelope.js";
28
- import { durableImproveRef } from "../source-identity.js";
29
- import { persistOutputEncodingSalience, runLessonQualityJudge, writeQualityRejection } from "./quality-gate.js";
30
- /** Read-only classification of the deterministic promotion path and destination conflict. */
31
- export async function planMemoryKnowledgePromotion(ctx) {
32
- const durableInputRef = ctx.durableInputRef ?? ctx.inputRef;
33
- const promotion = ctx.targetKind === "lesson"
34
- ? null
35
- : assessMemoryKnowledgePromotionCandidate({
36
- inputRef: durableInputRef,
37
- assetContent: ctx.assetContent,
38
- feedbackEvents: ctx.filteredEvents.map((event) => ({
39
- ...(event.metadata !== undefined ? { metadata: event.metadata } : {}),
40
- })),
41
- });
42
- if (!(promotion?.promote && promotion.content && (ctx.targetKind === "knowledge" || ctx.targetKind === "auto"))) {
43
- return null;
44
- }
45
- const existingKnowledgePath = await ctx.lookup(durableImproveRef(promotion.knowledgeRef));
46
- let existingKnowledgeContent = null;
47
- if (existingKnowledgePath && fs.existsSync(existingKnowledgePath)) {
48
- try {
49
- existingKnowledgeContent = fs.readFileSync(existingKnowledgePath, "utf8");
50
- }
51
- catch {
52
- existingKnowledgeContent = null;
53
- }
54
- }
55
- return { promotion: promotion, existingKnowledgeContent };
56
- }
57
- /**
58
- * PRECHECK (tier3-0917): read-only classification of whether distill would
59
- * promote this memory to knowledge — used by the improve loop's distill
60
- * pre-generation proposal guard (`loop-stages.ts`) to pre-check the SAME ref
61
- * {@link planMemoryKnowledgePromotion} will target at dispatch time
62
- * (knowledgeRef when this resolves `true`, the derived lesson ref
63
- * otherwise), rather than guessing which of the two a guard hit applies to.
64
- * Delegates to {@link planMemoryKnowledgePromotion} itself so the
65
- * classification can never drift from the real dispatch decision — no LLM
66
- * call, no side effect. Every {@link PromoteMemoryContext} field this
67
- * classification does not read (chat, fetchSimilarLessonsFn,
68
- * existingRefVocabulary, …) is a safe placeholder here.
69
- */
70
- export async function wouldPromoteMemoryToKnowledge(args) {
71
- const plan = await planMemoryKnowledgePromotion({
72
- targetKind: "auto",
73
- inputRef: args.inputRef,
74
- durableInputRef: args.durableInputRef,
75
- assetContent: args.assetContent,
76
- filteredEvents: args.feedbackEvents,
77
- config: args.config,
78
- stash: args.stash,
79
- lookup: args.lookup,
80
- fetchSimilarLessonsFn: () => Promise.resolve([]),
81
- existingRefVocabulary: new Set(),
82
- outcomeWeightEnabled: false,
83
- eligMeta: {},
84
- exclusionSetSize: 0,
85
- filteredFeedbackCount: 0,
86
- feedbackFullyFiltered: false,
87
- });
88
- return plan !== null;
89
- }
90
- /** Whether a classified promotion will actually call merge generation and/or the judge. */
91
- export function memoryKnowledgePromotionRequiresDispatch(ctx, plan) {
92
- const hasRunner = Boolean(ctx.llmRunner);
93
- return ((Boolean(plan.existingKnowledgeContent) && hasRunner) ||
94
- (ctx.strategy?.processes?.distill?.qualityGate?.enabled ?? true));
95
- }
96
- /**
97
- * Resolve the knowledge content to propose when a memory promotes to knowledge,
98
- * reconciling it with any existing knowledge file at the destination (D-1 / #369).
99
- *
100
- * When the destination already exists and an LLM is configured, follows the
101
- * mem0 ADD/UPDATE/NOOP pattern (arXiv:2504.19413 §3.2): ADD/UPDATE swap in the
102
- * merged content, NOOP short-circuits with a terminal "skipped" result. Without
103
- * an LLM the existing content is appended as reviewer-reference context so the
104
- * merge can be done by hand. Logic is byte-identical to the prior inline block.
105
- */
106
- async function resolveKnowledgePromotionContent(ctx, plan) {
107
- const durableInputRef = ctx.durableInputRef ?? ctx.inputRef;
108
- const baseContent = plan.promotion.content;
109
- const knowledgeRef = plan.promotion.knowledgeRef;
110
- let resolvedPromotionContent = baseContent;
111
- const existingKnowledgeContent = plan.existingKnowledgeContent;
112
- const runner = ctx.llmRunner;
113
- if (existingKnowledgeContent && runner) {
114
- // Existing content found: call LLM for contradiction-resolution merge.
115
- const mergePrompt = [
116
- "You are merging two versions of a knowledge document.",
117
- "Existing content is already committed; new content comes from a memory distillation run.",
118
- "Choose one of: ADD (combine both), UPDATE (replace existing with new), NOOP (keep existing unchanged).",
119
- 'Return ONLY valid JSON: {"action": "ADD"|"UPDATE"|"NOOP", "content": "<merged markdown if ADD/UPDATE, empty string if NOOP>"}',
120
- "",
121
- "## Existing knowledge content",
122
- "```",
123
- existingKnowledgeContent.slice(0, 3000),
124
- "```",
125
- "",
126
- "## New content from distillation",
127
- "```",
128
- baseContent.slice(0, 3000),
129
- "```",
130
- ].join("\n");
131
- try {
132
- const mergeResponse = await callStructured({
133
- feature: "distill",
134
- runner,
135
- ...(ctx.lease ? { lease: ctx.lease } : {}),
136
- messages: [
137
- { role: "system", content: "Return only valid JSON. No prose." },
138
- { role: "user", content: mergePrompt },
139
- ],
140
- request: {
141
- ...(ctx.signal ? { signal: ctx.signal } : {}),
142
- ...(ctx.chat ? { chat: ctx.chat } : {}),
143
- },
144
- parse: (raw) => raw ?? "",
145
- onError: () => "",
146
- fallback: "",
147
- ...(ctx.onNotices ? { onNotices: ctx.onNotices } : {}),
148
- });
149
- const mergeResult = parseEmbeddedJsonResponse(mergeResponse);
150
- if (mergeResult?.action === "NOOP") {
151
- // Existing content is authoritative — no update needed.
152
- appendEvent({
153
- eventType: "distill_invoked",
154
- // Use item_ref when resolved, otherwise the input conceptId.
155
- ref: ctx.itemRef ?? durableInputRef,
156
- metadata: {
157
- outcome: "skipped",
158
- proposalRef: knowledgeRef,
159
- message: "D-1: LLM resolved destination conflict as NOOP — existing content kept",
160
- ...ctx.eligMeta,
161
- },
162
- }, ctx.eventsCtx);
163
- return {
164
- earlyResult: {
165
- schemaVersion: 1,
166
- ok: true,
167
- outcome: "skipped",
168
- inputRef: ctx.inputRef,
169
- proposalRef: knowledgeRef,
170
- skipReason: "conflict_noop",
171
- message: "Existing knowledge content unchanged (contradiction resolution: NOOP)",
172
- },
173
- };
174
- }
175
- if (mergeResult?.action && (mergeResult.action === "ADD" || mergeResult.action === "UPDATE")) {
176
- if (mergeResult.content?.trim()) {
177
- resolvedPromotionContent = mergeResult.content;
178
- }
179
- }
180
- }
181
- catch (error) {
182
- if (error instanceof ConfigError)
183
- throw error;
184
- // LLM merge failed — fall through with the original promotion content.
185
- // The reviewer will see both versions in the proposal diff.
186
- }
187
- }
188
- else if (existingKnowledgeContent) {
189
- // No LLM configured: include existing content as context in the proposal
190
- // so the reviewer can do the contradiction resolution manually.
191
- resolvedPromotionContent = [
192
- baseContent,
193
- "",
194
- "---",
195
- "<!-- D-1 / #369: Existing knowledge content is shown below for reviewer reference. -->",
196
- "<!-- Review: decide whether to ADD (merge), UPDATE (replace), or NOOP (keep existing). -->",
197
- "",
198
- "## Existing content (for reviewer reference)",
199
- "",
200
- existingKnowledgeContent,
201
- ].join("\n");
202
- }
203
- return { resolvedContent: resolvedPromotionContent };
204
- }
205
- /**
206
- * Run the memory→knowledge promotion branch. Returns the finished distill
207
- * result when promotion fired (all paths terminal), or `null` when the ref is
208
- * not a promotion candidate and the caller should continue to the ordinary
209
- * lesson/knowledge distillation path.
210
- */
211
- export async function promoteMemoryToKnowledge(ctx, planned) {
212
- const { inputRef, assetContent, config, chat, stash, fetchSimilarLessonsFn, existingRefVocabulary, outcomeWeightEnabled, eligMeta, exclusionSetSize, filteredFeedbackCount, feedbackFullyFiltered, } = ctx;
213
- const durableInputRef = ctx.durableInputRef ?? inputRef;
214
- const promotionPlan = planned === undefined ? await planMemoryKnowledgePromotion(ctx) : planned;
215
- if (!promotionPlan)
216
- return null;
217
- const promotion = promotionPlan.promotion;
218
- // D-1 / #369: When the destination knowledge file already exists, route
219
- // through the LLM for contradiction resolution instead of silently
220
- // overwriting. Follows mem0 ADD/UPDATE/DELETE/NOOP pattern (arXiv:2504.19413 §3.2)
221
- // and A-MEM dynamic linking (arXiv:2502.12110).
222
- const merged = await resolveKnowledgePromotionContent(ctx, promotionPlan);
223
- if ("earlyResult" in merged)
224
- return merged.earlyResult;
225
- const resolvedPromotionContent = merged.resolvedContent;
226
- // Apply quality gate to fast-path knowledge promotion (Risk 4 fix).
227
- // D-5 / #388: Three-band system — review_needed band queues to proposal
228
- // queue with review_needed outcome rather than auto-rejecting.
229
- let knowledgeJudgeConfidence;
230
- if (ctx.strategy?.processes?.distill?.qualityGate?.enabled ?? true) {
231
- // D-4 / #390: retrieve top-3 similar lessons for dedup check in judge.
232
- const similarLessons = await fetchSimilarLessonsFn(resolvedPromotionContent.slice(0, 500), 3);
233
- const judgeResult = await runLessonQualityJudge(config, resolvedPromotionContent, assetContent ?? "", chat, {
234
- ...(similarLessons.length > 0 ? { similarLessons } : {}),
235
- ...(ctx.llmRunner ? { llmRunner: ctx.llmRunner } : {}),
236
- ...(ctx.lease ? { lease: ctx.lease } : {}),
237
- ...(ctx.signal ? { signal: ctx.signal } : {}),
238
- ...(ctx.onNotices ? { onNotices: ctx.onNotices } : {}),
239
- });
240
- if (!judgeResult.pass) {
241
- const proposalOpts = {
242
- ...(ctx.proposalsCtx ? { proposalsCtx: ctx.proposalsCtx } : {}),
243
- ...(ctx.sourceRun !== undefined ? { sourceRun: ctx.sourceRun } : {}),
244
- ...(ctx.llmRunner?.connection.model ? { modelId: ctx.llmRunner.connection.model } : {}),
245
- };
246
- if (judgeResult.reviewNeeded) {
247
- // Uncertainty band (2.5–3.5): queue as review_needed instead of rejecting.
248
- return writeQualityRejection(stash, inputRef, promotion.knowledgeRef, resolvedPromotionContent, judgeResult.score, judgeResult.reason, { reviewNeeded: true, ...(judgeResult.criteria ? { criteria: judgeResult.criteria } : {}) }, ctx.eligibilitySource, ctx.eventsCtx, proposalOpts);
249
- }
250
- return writeQualityRejection(stash, inputRef, promotion.knowledgeRef, resolvedPromotionContent, judgeResult.score, judgeResult.reason, judgeResult.criteria ? { criteria: judgeResult.criteria } : {}, ctx.eligibilitySource, ctx.eventsCtx, proposalOpts);
251
- }
252
- // Normalize 1-5 judge score to [0, 1]. Only a real passing verdict reaches
253
- // here (07 P0-2: the judge now fails CLOSED on no-LLM / timeout / parse
254
- // failure, so those return pass:false and early-return above). The score>0
255
- // guard defensively leaves confidence undefined for any non-positive score.
256
- if (judgeResult.score > 0)
257
- knowledgeJudgeConfidence = judgeResult.score / 5;
258
- }
259
- const knowledgeParsed = parseFrontmatter(resolvedPromotionContent);
260
- const proposalResult = emitProposal({ stashDir: stash, proposalsCtx: ctx.proposalsCtx }, {
261
- ref: promotion.knowledgeRef,
262
- source: "distill",
263
- // §23.6 fingerprint model-id term (WI-6.4).
264
- ...(ctx.llmRunner?.connection.model ? { modelId: ctx.llmRunner.connection.model } : {}),
265
- ...(ctx.sourceRun !== undefined ? { sourceRun: ctx.sourceRun } : {}),
266
- payload: {
267
- content: resolvedPromotionContent,
268
- ...(Object.keys(knowledgeParsed.data).length > 0 ? { frontmatter: knowledgeParsed.data } : {}),
269
- },
270
- ...(knowledgeJudgeConfidence !== undefined ? { confidence: knowledgeJudgeConfidence } : {}),
271
- // Attribution tagging: persist the eligibility lane on the proposal.
272
- ...(ctx.eligibilitySource ? { eligibilitySource: ctx.eligibilitySource } : {}),
273
- });
274
- if (isProposalSkipped(proposalResult)) {
275
- appendEvent({
276
- eventType: "distill_invoked",
277
- // Use item_ref when resolved, otherwise the input conceptId.
278
- ref: ctx.itemRef ?? durableInputRef,
279
- metadata: {
280
- outcome: "skipped",
281
- proposalRef: promotion.knowledgeRef,
282
- message: proposalResult.message,
283
- skipReason: proposalResult.reason,
284
- ...eligMeta,
285
- },
286
- }, ctx.eventsCtx);
287
- return {
288
- schemaVersion: 1,
289
- ok: true,
290
- outcome: "skipped",
291
- inputRef,
292
- proposalRef: promotion.knowledgeRef,
293
- skipReason: proposalResult.reason,
294
- message: proposalResult.message,
295
- };
296
- }
297
- const proposal = proposalResult;
298
- // G4: content-score the distilled OUTPUT so it carries a real encoding
299
- // salience (encoding_source='content') from creation.
300
- persistOutputEncodingSalience(durableImproveRef(promotion.knowledgeRef), resolvedPromotionContent, existingRefVocabulary, outcomeWeightEnabled);
301
- appendEvent({
302
- eventType: "distill_invoked",
303
- // Use item_ref when resolved, otherwise the input conceptId.
304
- ref: ctx.itemRef ?? durableInputRef,
305
- metadata: {
306
- outcome: "queued",
307
- proposalRef: promotion.knowledgeRef,
308
- proposalKind: "knowledge",
309
- proposalId: proposal.id,
310
- // R3: judge verdicts are longitudinally queryable, not just a one-shot
311
- // proposal.confidence write (normalized 1–5 score / 5).
312
- ...(knowledgeJudgeConfidence !== undefined ? { judgeConfidence: knowledgeJudgeConfidence } : {}),
313
- ...(ctx.sourceRun !== undefined ? { sourceRun: ctx.sourceRun } : {}),
314
- ...(exclusionSetSize > 0 ? { filteredFeedbackCount } : {}),
315
- ...eligMeta,
316
- },
317
- }, ctx.eventsCtx);
318
- return {
319
- schemaVersion: 1,
320
- ok: true,
321
- outcome: "queued",
322
- inputRef,
323
- proposalRef: promotion.knowledgeRef,
324
- proposalKind: "knowledge",
325
- proposalId: proposal.id,
326
- proposal,
327
- ...(exclusionSetSize > 0 ? { filteredFeedbackCount, feedbackFullyFiltered } : {}),
328
- };
329
- }