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

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 (343) hide show
  1. package/CHANGELOG.md +731 -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/proposal/drain.js +251 -644
  53. package/dist/commands/proposal/proposal-cli.js +3 -18
  54. package/dist/commands/proposal/proposal-types.js +20 -41
  55. package/dist/commands/proposal/proposal.js +1 -2
  56. package/dist/commands/proposal/propose.js +134 -160
  57. package/dist/commands/proposal/repository.js +502 -1487
  58. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  59. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  60. package/dist/commands/proposal/validators/proposals.js +13 -89
  61. package/dist/commands/read/curate.js +63 -413
  62. package/dist/commands/read/search-cli.js +16 -33
  63. package/dist/commands/read/search.js +17 -23
  64. package/dist/commands/read/show.js +2 -13
  65. package/dist/commands/sources/bundle-cli.js +25 -2
  66. package/dist/commands/sources/bundle-config-ops.js +7 -0
  67. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  68. package/dist/commands/sources/info.js +2 -11
  69. package/dist/commands/sources/installed-stashes.js +197 -746
  70. package/dist/commands/sources/schema-repair.js +98 -129
  71. package/dist/commands/sources/source-add.js +62 -12
  72. package/dist/commands/sources/stash-cli.js +1 -1
  73. package/dist/commands/tasks/explain.js +10 -13
  74. package/dist/commands/tasks/tasks-cli.js +9 -8
  75. package/dist/commands/tasks/tasks.js +326 -930
  76. package/dist/commands/tasks/validate.js +42 -21
  77. package/dist/commands/workflow/plan.js +22 -29
  78. package/dist/commands/workflow-cli.js +4 -4
  79. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  80. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  81. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  82. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  83. package/dist/core/adapter/execution-source.js +17 -29
  84. package/dist/core/asset/resolve-ref.js +1 -1
  85. package/dist/core/bundle-id.js +42 -5
  86. package/dist/core/bundle-rename.js +291 -0
  87. package/dist/core/config/config-io.js +1 -2
  88. package/dist/core/config/config-schema.js +1 -33
  89. package/dist/core/config/config-walker.js +1 -1
  90. package/dist/core/config/config.js +163 -68
  91. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  92. package/dist/core/config/schema/embedding.js +20 -5
  93. package/dist/core/config/schema/engines.js +5 -0
  94. package/dist/core/config/schema/execution.js +1 -1
  95. package/dist/core/config/schema/experimental.js +1 -1
  96. package/dist/core/config/schema/improve-processes.js +21 -95
  97. package/dist/core/config/schema/improve.js +4 -42
  98. package/dist/core/config/schema/scheduler.js +12 -12
  99. package/dist/core/config/schema/search.js +6 -22
  100. package/dist/core/env-secret-ref.js +0 -1
  101. package/dist/core/errors.js +8 -9
  102. package/dist/core/file-lock.js +76 -173
  103. package/dist/core/logs-db.js +2 -2
  104. package/dist/core/paths.js +0 -27
  105. package/dist/core/redaction.js +109 -2
  106. package/dist/core/run-lock.js +2 -5
  107. package/dist/core/spawn-env.js +1 -1
  108. package/dist/core/state/migrations.js +108 -61
  109. package/dist/core/state-db-scope.js +2 -4
  110. package/dist/core/state-db.js +126 -692
  111. package/dist/core/type-presentation.js +1 -9
  112. package/dist/core/write-source.js +293 -1012
  113. package/dist/execution/input-contract.js +1 -1
  114. package/dist/execution/resolved-request.js +135 -689
  115. package/dist/execution/source.js +63 -257
  116. package/dist/execution/target-ref.js +1 -1
  117. package/dist/indexer/bundle-identity-guard.js +2 -2
  118. package/dist/indexer/db/graph-db.js +106 -46
  119. package/dist/indexer/ensure-index.js +44 -85
  120. package/dist/indexer/graph/graph-extraction.js +340 -562
  121. package/dist/indexer/graph/graph-related.js +130 -0
  122. package/dist/indexer/index-rebuild-lock.js +3 -11
  123. package/dist/indexer/index-writer-lock.js +8 -17
  124. package/dist/indexer/index-written-assets.js +139 -151
  125. package/dist/indexer/indexer.js +524 -846
  126. package/dist/indexer/materialize-embeddings.js +60 -397
  127. package/dist/indexer/passes/memory-inference.js +81 -90
  128. package/dist/indexer/passes/metadata.js +132 -200
  129. package/dist/indexer/read-preflight.js +0 -7
  130. package/dist/indexer/scan/doc-to-entry.js +1 -3
  131. package/dist/indexer/scan/drain-dir.js +1 -1
  132. package/dist/indexer/search/db-search.js +181 -590
  133. package/dist/indexer/search/fts-query.js +30 -41
  134. package/dist/indexer/search/ranking.js +28 -154
  135. package/dist/indexer/search/search-attribution.js +12 -32
  136. package/dist/indexer/search/search-fields.js +11 -15
  137. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  138. package/dist/indexer/search/search-source.js +1 -4
  139. package/dist/indexer/usage/usage-events.js +2 -7
  140. package/dist/integrations/agent/engine-fallback.js +23 -40
  141. package/dist/integrations/agent/engine-resolution.js +93 -183
  142. package/dist/integrations/agent/execution.js +507 -0
  143. package/dist/integrations/agent/model-map.js +28 -156
  144. package/dist/integrations/agent/request-lowering.js +66 -141
  145. package/dist/integrations/agent/runner-dispatch.js +143 -321
  146. package/dist/integrations/agent/runner.js +54 -14
  147. package/dist/integrations/lockfile.js +53 -101
  148. package/dist/llm/embedders/deterministic.js +2 -3
  149. package/dist/llm/embedders/profile.js +71 -0
  150. package/dist/llm/embedders/remote.js +10 -15
  151. package/dist/llm/graph-extract.js +3 -12
  152. package/dist/llm/index-passes.js +3 -5
  153. package/dist/llm/memory-infer.js +1 -2
  154. package/dist/llm/metadata-enhance.js +1 -2
  155. package/dist/llm/structured-call.js +5 -24
  156. package/dist/output/generic-render.js +23 -11
  157. package/dist/output/html-render.js +13 -10
  158. package/dist/output/render-registry.js +3 -32
  159. package/dist/output/shapes/helpers.js +2 -34
  160. package/dist/output/shapes/passthrough.js +1 -9
  161. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  162. package/dist/output/text/command-format.js +60 -23
  163. package/dist/output/text/helpers.js +1 -1
  164. package/dist/output/text/migrate.js +5 -14
  165. package/dist/output/text/proposal-format.js +1 -2
  166. package/dist/output/text/workflow-format.js +0 -32
  167. package/dist/output/text.js +2 -0
  168. package/dist/registry/factory.js +4 -19
  169. package/dist/registry/network.js +66 -220
  170. package/dist/registry/providers/index.js +0 -2
  171. package/dist/registry/providers/skills-sh.js +3 -14
  172. package/dist/registry/providers/static-index.js +24 -26
  173. package/dist/registry/resolve.js +55 -131
  174. package/dist/scripts/akm-migrate-node.js +43937 -93313
  175. package/dist/scripts/akm-migrate.js +43697 -93071
  176. package/dist/setup/registry-stash-loader.js +4 -13
  177. package/dist/setup/semantic-assets.js +3 -44
  178. package/dist/setup/setup.js +1 -1
  179. package/dist/setup/steps/tasks.js +25 -15
  180. package/dist/sources/provider-factory.js +17 -18
  181. package/dist/sources/providers/filesystem.js +2 -3
  182. package/dist/sources/providers/git-install.js +7 -1
  183. package/dist/sources/providers/git-provider.js +0 -3
  184. package/dist/sources/providers/git-stash.js +0 -17
  185. package/dist/sources/providers/npm.js +2 -4
  186. package/dist/sources/providers/provider-utils.js +5 -10
  187. package/dist/sources/providers/website.js +0 -2
  188. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  189. package/dist/sources/website-url.js +2 -2
  190. package/dist/storage/database.js +9 -35
  191. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  192. package/dist/storage/repositories/index-connection.js +34 -70
  193. package/dist/storage/repositories/index-entries-repository.js +69 -111
  194. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  195. package/dist/storage/repositories/index-entry-schema.js +83 -269
  196. package/dist/storage/repositories/index-fts-repository.js +86 -256
  197. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  198. package/dist/storage/repositories/index-meta-repository.js +6 -4
  199. package/dist/storage/repositories/index-schema.js +192 -220
  200. package/dist/storage/repositories/index-utility-repository.js +8 -29
  201. package/dist/storage/repositories/index-vec-repository.js +133 -414
  202. package/dist/storage/repositories/outcome-repository.js +2 -1
  203. package/dist/storage/repositories/proposals-repository.js +35 -0
  204. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  205. package/dist/storage/repositories/task-history-repository.js +26 -4
  206. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  207. package/dist/storage/sqlite-migrations.js +136 -0
  208. package/dist/storage/sqlite-pragmas.js +11 -9
  209. package/dist/storage/sqlite-transaction.js +170 -0
  210. package/dist/storage/state-db-integrity.js +34 -27
  211. package/dist/tasks/activation-config.js +134 -62
  212. package/dist/tasks/backends/cron.js +129 -277
  213. package/dist/tasks/backends/exec-utils.js +2 -5
  214. package/dist/tasks/backends/launchd.js +125 -745
  215. package/dist/tasks/backends/schtasks.js +101 -620
  216. package/dist/tasks/prepare/prepare-support.js +5 -15
  217. package/dist/tasks/prepare/prepare.js +0 -2
  218. package/dist/tasks/resolve-akm-bin.js +20 -79
  219. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  220. package/dist/tasks/scheduler-binding.js +18 -238
  221. package/dist/tasks/scheduler-invocation.js +52 -52
  222. package/dist/tasks/scheduler-lock.js +53 -0
  223. package/dist/tasks/scheduler-sync.js +361 -751
  224. package/dist/tasks/source/parse-task-source.js +160 -10
  225. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  226. package/dist/tasks/source/task-to-v4.js +2 -2
  227. package/dist/workflows/authoring/authoring.js +3 -12
  228. package/dist/workflows/compile.js +211 -0
  229. package/dist/workflows/concurrency-policy.js +13 -74
  230. package/dist/workflows/exec/child-invocation.js +3 -17
  231. package/dist/workflows/exec/child-workflow.js +32 -141
  232. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  233. package/dist/workflows/exec/environment.js +98 -0
  234. package/dist/workflows/exec/exec-unit.js +33 -140
  235. package/dist/workflows/exec/frozen-judge.js +7 -59
  236. package/dist/workflows/exec/native-executor.js +82 -341
  237. package/dist/workflows/exec/param-secrets.js +29 -47
  238. package/dist/workflows/exec/run-workflow.js +154 -387
  239. package/dist/workflows/exec/scheduler.js +9 -36
  240. package/dist/workflows/exec/step-work.js +127 -430
  241. package/dist/workflows/exec/unit-dispatch.js +11 -63
  242. package/dist/workflows/exec/unit-writer.js +8 -52
  243. package/dist/workflows/exec/worktree.js +39 -273
  244. package/dist/workflows/freeze/child-output-references.js +4 -15
  245. package/dist/workflows/freeze/environment.js +99 -92
  246. package/dist/workflows/freeze/freeze.js +172 -0
  247. package/dist/workflows/freeze/step-values.js +19 -21
  248. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  249. package/dist/workflows/freeze/targets/command.js +10 -33
  250. package/dist/workflows/freeze/targets/script.js +5 -12
  251. package/dist/workflows/freeze/targets/shell.js +3 -6
  252. package/dist/workflows/freeze/targets/task.js +25 -80
  253. package/dist/workflows/freeze/task-bindings.js +20 -67
  254. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  255. package/dist/workflows/ir/params.js +6 -51
  256. package/dist/workflows/ir/plan-hash.js +2 -34
  257. package/dist/workflows/parser.js +140 -43
  258. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  259. package/dist/workflows/renderer.js +36 -69
  260. package/dist/workflows/resource-limits.js +12 -120
  261. package/dist/workflows/runtime/agent-identity.js +8 -40
  262. package/dist/workflows/runtime/run-outputs.js +3 -6
  263. package/dist/workflows/runtime/run-plan.js +316 -0
  264. package/dist/workflows/runtime/runs.js +48 -200
  265. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  266. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  267. package/dist/workflows/validate-summary.js +2 -7
  268. package/docs/integration/bundling-akm.md +49 -42
  269. package/docs/migration/README.md +1 -0
  270. package/docs/migration/release-notes/0.9.17.md +41 -0
  271. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  272. package/docs/reference/cli.md +182 -125
  273. package/docs/reference/configuration.md +49 -56
  274. package/docs/reference/data-and-telemetry.md +19 -20
  275. package/docs/reference/tasks.md +86 -38
  276. package/docs/reference/workflow-schema.md +14 -18
  277. package/docs/reference/workflows.md +6 -9
  278. package/package.json +1 -1
  279. package/schemas/akm-config.json +87 -406
  280. package/dist/commands/health/advisories.js +0 -150
  281. package/dist/commands/health/metrics.js +0 -329
  282. package/dist/commands/health/surfaces.js +0 -102
  283. package/dist/commands/improve/anti-collapse.js +0 -83
  284. package/dist/commands/improve/collapse-detector.js +0 -432
  285. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  286. package/dist/commands/improve/consolidate/merge.js +0 -146
  287. package/dist/commands/improve/distill/promote-memory.js +0 -329
  288. package/dist/commands/improve/distill/quality-gate.js +0 -500
  289. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  290. package/dist/commands/improve/proposal-envelope.js +0 -31
  291. package/dist/commands/improve/run-context.js +0 -123
  292. package/dist/commands/improve/shared.js +0 -21
  293. package/dist/commands/improve/source-identity.js +0 -28
  294. package/dist/commands/improve/triage.js +0 -96
  295. package/dist/commands/proposal/drain-policies.js +0 -151
  296. package/dist/commands/sources/update-transaction.js +0 -220
  297. package/dist/core/action-contributors.js +0 -28
  298. package/dist/core/config/config-version-shim.js +0 -101
  299. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  300. package/dist/core/fs-txn.js +0 -405
  301. package/dist/core/lexical-score.js +0 -25
  302. package/dist/core/maintenance-barrier.js +0 -167
  303. package/dist/execution/executable-identity.js +0 -105
  304. package/dist/execution/guarded-source.js +0 -441
  305. package/dist/indexer/graph/graph-boost.js +0 -427
  306. package/dist/indexer/graph/graph-dedup.js +0 -95
  307. package/dist/indexer/search/name-match.js +0 -35
  308. package/dist/indexer/search/ranking-contributors.js +0 -515
  309. package/dist/indexer/walk/project-context.js +0 -192
  310. package/dist/integrations/agent/execution-cascade.js +0 -566
  311. package/dist/integrations/agent/execution-definitions.js +0 -202
  312. package/dist/integrations/agent/execution-lowering.js +0 -841
  313. package/dist/integrations/agent/execution-preparation.js +0 -98
  314. package/dist/integrations/agent/inline-execution.js +0 -74
  315. package/dist/registry/create-provider-registry.js +0 -29
  316. package/dist/registry/pinned-request-helper.js +0 -247
  317. package/dist/registry/pinned-transport.js +0 -717
  318. package/dist/sources/providers/index.js +0 -14
  319. package/dist/storage/engines/sqlite-migrations.js +0 -271
  320. package/dist/storage/repositories/canaries-repository.js +0 -107
  321. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  322. package/dist/storage/repositories/registry-cache.js +0 -113
  323. package/dist/tasks/scheduler-sync-preview.js +0 -52
  324. package/dist/workflows/freeze/resolve-steps.js +0 -86
  325. package/dist/workflows/freeze/source-freeze.js +0 -64
  326. package/dist/workflows/ir/compile.js +0 -321
  327. package/dist/workflows/ir/environment-v4.js +0 -330
  328. package/dist/workflows/ir/freeze-v4.js +0 -153
  329. package/dist/workflows/ir/schema-v4.js +0 -745
  330. package/dist/workflows/ir/schema.js +0 -354
  331. package/dist/workflows/program/schema.js +0 -78
  332. package/dist/workflows/runtime/checkin.js +0 -57
  333. package/dist/workflows/runtime/plan-classifier.js +0 -196
  334. package/dist/workflows/runtime/unit-checkin.js +0 -45
  335. package/dist/workflows/runtime/unit-phases.js +0 -20
  336. package/dist/workflows/schema.js +0 -4
  337. package/dist/workflows/source-ir/compile.js +0 -200
  338. package/dist/workflows/source-ir/program.js +0 -50
  339. package/dist/workflows/source-ir/result.js +0 -26
  340. package/dist/workflows/source-ir/schema.js +0 -786
  341. package/dist/workflows/source-ir/triggers.js +0 -79
  342. package/dist/workflows/source-ir/uses.js +0 -40
  343. package/dist/workflows/validator.js +0 -60
@@ -0,0 +1,323 @@
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
+ import { getImproveProcessConfig } from "../../core/config/config.js";
5
+ import { ConfigError } from "../../core/errors.js";
6
+ import { parseEmbeddedJsonResponse } from "../../core/parse.js";
7
+ import { warn } from "../../core/warn.js";
8
+ import { LlmCallError } from "../../llm/client.js";
9
+ import { callStructured } from "../../llm/structured-call.js";
10
+ import { withLlmStage } from "../../llm/usage-telemetry.js";
11
+ import { isProceduralRejection } from "../proposal/proposal-types.js";
12
+ import { createProposal, listProposalsReadOnly, proposalContentHash, recordGateDecision, } from "../proposal/repository.js";
13
+ import { resolveImproveLlmExecution } from "./execution.js";
14
+ /** Normalize an unknown thrown value to a message. */
15
+ export function errMessage(e) {
16
+ return e instanceof Error ? e.message : String(e);
17
+ }
18
+ /** The lowering notices a stage's dispatches emitted, each once. */
19
+ export function noticeSet(forward) {
20
+ const byKey = new Map();
21
+ const add = (notices) => {
22
+ for (const notice of notices)
23
+ byKey.set(JSON.stringify(notice), notice);
24
+ forward?.(notices);
25
+ };
26
+ const list = () => Object.freeze([...byKey.values()]);
27
+ return { add, list, fields: () => (byKey.size > 0 ? { notices: list() } : {}) };
28
+ }
29
+ /**
30
+ * A stage's LLM runner: the one the improve plan froze for it (an own
31
+ * `llmRunner` key, `null` meaning "none"), else the process engine cascade.
32
+ */
33
+ export function stageRunner(frozen, config, profile, processName, onNotices) {
34
+ if (Object.hasOwn(frozen, "llmRunner"))
35
+ return frozen.llmRunner ?? undefined;
36
+ const resolved = resolveImproveLlmExecution({
37
+ config,
38
+ profile,
39
+ process: getImproveProcessConfig(processName, profile),
40
+ processName,
41
+ });
42
+ if (resolved)
43
+ onNotices?.(resolved.notices);
44
+ return resolved?.runner;
45
+ }
46
+ /**
47
+ * One model call. Provider trouble (transport error, timeout, a disabled
48
+ * feature) comes back as `{ ok: false }`; only a configuration failure throws.
49
+ */
50
+ export async function callStage(call) {
51
+ const messages = [
52
+ ...(call.system ? [{ role: "system", content: call.system }] : []),
53
+ ...(call.history ?? []),
54
+ { role: "user", content: call.prompt },
55
+ ];
56
+ let failure;
57
+ try {
58
+ const raw = await callStructured({
59
+ feature: call.feature,
60
+ ...(call.gate
61
+ ? { akmConfig: call.gate.config, ...(call.gate.enabled !== undefined ? { enabled: call.gate.enabled } : {}) }
62
+ : {}),
63
+ runner: call.runner,
64
+ messages,
65
+ ...(call.request ? { request: call.request } : {}),
66
+ ...(call.onNotices ? { onNotices: call.onNotices } : {}),
67
+ parse: (r) => r ?? "",
68
+ onError: (_cls, err) => {
69
+ failure = { ok: false, reason: "error", error: errMessage(err) };
70
+ return undefined;
71
+ },
72
+ fallback: undefined,
73
+ onFallback: (event) => {
74
+ failure ??= { ok: false, reason: event.reason, ...(event.error ? { error: event.error.message } : {}) };
75
+ },
76
+ });
77
+ return raw === undefined ? (failure ?? { ok: false, reason: "error" }) : { ok: true, raw };
78
+ }
79
+ catch (err) {
80
+ if (err instanceof ConfigError)
81
+ throw err;
82
+ const timedOut = err instanceof LlmCallError && err.code === "timeout";
83
+ return { ok: false, reason: timedOut ? "timeout" : "error", error: errMessage(err) };
84
+ }
85
+ }
86
+ /** Attribute a stage's LLM calls to its process and planned engine (the usage report). */
87
+ const STAGE_LABELS = {
88
+ reflect: "reflect",
89
+ distill: "distill",
90
+ consolidate: "consolidate",
91
+ extract: "session-extraction",
92
+ memoryInference: "memory-inference",
93
+ graphExtraction: "graph-extraction",
94
+ validation: "validation",
95
+ };
96
+ export function attributeStage(plan, process, fn) {
97
+ return withLlmStage(STAGE_LABELS[process], fn, { engine: plan?.processes[process].runner?.engine, process });
98
+ }
99
+ /** How many prior rejected proposals are shown to the model as "don't repeat this". */
100
+ export const MAX_REJECTED_PROPOSALS = 3;
101
+ /**
102
+ * Reflexion context: the newest reviewer rejections for `ref`. Procedural
103
+ * refusals (expiry, stale target, missing asset) are not judgements on the
104
+ * content and are left out. Reads never create state.db.
105
+ */
106
+ export function rejectedProposalContext(stash, ref, ctx) {
107
+ if (!ref)
108
+ return [];
109
+ return listProposalsReadOnly(stash, { ref, status: "rejected", includeArchive: true }, ctx)
110
+ .filter((p) => !isProceduralRejection(p))
111
+ .sort((a, b) => new Date(b.updatedAt ?? 0).getTime() - new Date(a.updatedAt ?? 0).getTime())
112
+ .slice(0, MAX_REJECTED_PROPOSALS)
113
+ .map((p) => ({
114
+ ref: p.ref,
115
+ reason: p.review?.reason ?? "no reason given",
116
+ // `payload.content` is populated on every row, including legacy ones.
117
+ contentPreview: p.payload.content.slice(0, 500),
118
+ }));
119
+ }
120
+ // ── Mint ─────────────────────────────────────────────────────────────────────
121
+ /**
122
+ * Create a stage's proposal. `judged` stamps a `staged` gate decision with the
123
+ * judged content's hash (the triage drain accepts it while the content still
124
+ * matches); `review` leaves it `deferred` for a human (`review_needed` in the
125
+ * improve ledger).
126
+ */
127
+ export function mintProposal(stash, proposalsCtx, input, verdict = {}) {
128
+ const proposal = createProposal(stash, input, proposalsCtx);
129
+ if (verdict.review) {
130
+ return recordGateDecision(stash, proposal.id, { outcome: "deferred", ...verdict.review }, proposalsCtx) ?? proposal;
131
+ }
132
+ return verdict.judged ? stageJudgedProposal(stash, proposal, proposalsCtx) : proposal;
133
+ }
134
+ /**
135
+ * Stamp a proposal the quality judge passed. Best-effort: a failed stamp only
136
+ * means the triage drain judges it again.
137
+ */
138
+ export function stageJudgedProposal(stash, proposal, proposalsCtx) {
139
+ try {
140
+ return (recordGateDecision(stash, proposal.id, {
141
+ outcome: "staged",
142
+ reason: "quality-judge",
143
+ gate: "quality-gate",
144
+ contentHash: proposalContentHash(proposal),
145
+ }, proposalsCtx) ?? proposal);
146
+ }
147
+ catch (error) {
148
+ warn(`[akm] failed to record the quality-judge pass for ${proposal.id}: ${errMessage(error)}`);
149
+ return proposal;
150
+ }
151
+ }
152
+ /** Lesson judge prompt; similar existing lessons let it mark near-duplicates down. */
153
+ export function buildJudgePrompt(lessonContent, sourceContent, similarLessons) {
154
+ const lines = [
155
+ "You are evaluating a proposed lesson asset for an akm knowledge base.",
156
+ "",
157
+ "Score this lesson on each criterion from 1 (poor) to 5 (excellent):",
158
+ "1. NOVELTY: Does the lesson add information not already present in the source asset?",
159
+ "2. NON-REDUNDANCY: Is this lesson meaningfully different from what the source already says?",
160
+ "",
161
+ "Source asset content:",
162
+ "```",
163
+ sourceContent.slice(0, 2000),
164
+ "```",
165
+ ];
166
+ if (similarLessons && similarLessons.length > 0) {
167
+ lines.push("", "Existing similar lessons (top-3 by similarity). Rate lower if the proposed lesson is substantially similar to any of these:");
168
+ for (const sl of similarLessons)
169
+ lines.push(`\nExisting lesson ref: ${sl.ref}`, "```", sl.content.slice(0, 500), "```");
170
+ }
171
+ lines.push("", "Proposed lesson content:", "```", lessonContent.slice(0, 1000), "```", "", 'Return ONLY valid JSON, no prose: {"scores": {"novelty": <1-5 integer>, "nonRedundancy": <1-5 integer>}, "reason": "<one sentence>"}');
172
+ return lines.join("\n");
173
+ }
174
+ function boundedDocument(content, maxChars = 6000) {
175
+ if (content.length <= maxChars)
176
+ return content;
177
+ const half = Math.floor((maxChars - 80) / 2);
178
+ return `${content.slice(0, half)}\n\n[... middle omitted for bounded judge context ...]\n\n${content.slice(-half)}`;
179
+ }
180
+ function buildChangedRegion(sourceContent, candidateContent) {
181
+ const source = sourceContent.split("\n");
182
+ const candidate = candidateContent.split("\n");
183
+ let prefix = 0;
184
+ while (prefix < source.length && prefix < candidate.length && source[prefix] === candidate[prefix])
185
+ prefix++;
186
+ let suffix = 0;
187
+ while (suffix < source.length - prefix &&
188
+ suffix < candidate.length - prefix &&
189
+ source[source.length - 1 - suffix] === candidate[candidate.length - 1 - suffix]) {
190
+ suffix++;
191
+ }
192
+ const removed = source.slice(prefix, source.length - suffix).join("\n");
193
+ const added = candidate.slice(prefix, candidate.length - suffix).join("\n");
194
+ return boundedDocument(`Removed or replaced:\n${removed || "(none)"}\n\nAdded or replacement:\n${added || "(none)"}`);
195
+ }
196
+ /** Judge prompt for an in-place revision (overlap with the source is expected). */
197
+ export function buildReflectJudgePrompt(candidateContent, sourceContent, feedback) {
198
+ return [
199
+ "You are evaluating a proposed revision to an existing akm asset.",
200
+ "",
201
+ "Score this revision on each criterion from 1 (poor) to 5 (excellent):",
202
+ "1. FEEDBACK ALIGNMENT: Does the revision address the supplied feedback or improve retrieval and clarity?",
203
+ "2. PRESERVATION: Does it retain the source's concrete facts, code, commands, examples, and structure without truncation?",
204
+ "3. QUALITY: Is the revision coherent, actionable, complete, and free of unsupported claims?",
205
+ "",
206
+ "Overlap with the source is expected and must not lower the score by itself; this is an in-place revision, not a new lesson.",
207
+ "",
208
+ "Feedback:",
209
+ "```",
210
+ (feedback.length > 0 ? feedback.join("\n") : "No explicit feedback supplied.").slice(0, 1000),
211
+ "```",
212
+ "",
213
+ "Source asset content:",
214
+ "```",
215
+ boundedDocument(sourceContent),
216
+ "```",
217
+ "",
218
+ "Proposed revision:",
219
+ "```",
220
+ boundedDocument(candidateContent),
221
+ "```",
222
+ "",
223
+ "Changed region:",
224
+ "```",
225
+ buildChangedRegion(sourceContent, candidateContent),
226
+ "```",
227
+ "",
228
+ 'Return ONLY valid JSON, no prose: {"scores": {"feedbackAlignment": <1-5 integer>, "preservation": <1-5 integer>, "quality": <1-5 integer>}, "reason": "<one sentence>"}',
229
+ ].join("\n");
230
+ }
231
+ const LESSON_JUDGE_CRITERIA = ["novelty", "nonRedundancy"];
232
+ const REFLECT_JUDGE_CRITERIA = ["feedbackAlignment", "preservation", "quality"];
233
+ /**
234
+ * Read a judge response: the per-criterion shape (averaged here) or the older
235
+ * `{"score"}` shape. Only the expected criteria are read; any missing or
236
+ * out-of-range (1..5) value is a parse failure, extra keys are ignored.
237
+ */
238
+ function parseJudgeResponse(raw, keys) {
239
+ const parsed = parseEmbeddedJsonResponse(raw);
240
+ if (!parsed || typeof parsed.reason !== "string")
241
+ return undefined;
242
+ const reason = parsed.reason;
243
+ const inRange = (value) => typeof value === "number" && Number.isFinite(value) && value >= 1 && value <= 5;
244
+ if (parsed.scores !== undefined) {
245
+ if (typeof parsed.scores !== "object" || parsed.scores === null || Array.isArray(parsed.scores))
246
+ return undefined;
247
+ const scores = parsed.scores;
248
+ const criteria = {};
249
+ for (const key of keys) {
250
+ const value = scores[key];
251
+ if (!inRange(value))
252
+ return undefined;
253
+ criteria[key] = value;
254
+ }
255
+ return { score: Object.values(criteria).reduce((a, b) => a + b, 0) / keys.length, reason, criteria };
256
+ }
257
+ return inRange(parsed.score) ? { score: parsed.score, reason } : undefined;
258
+ }
259
+ function judgeResponseSchema(keys) {
260
+ return {
261
+ type: "object",
262
+ required: ["scores", "reason"],
263
+ additionalProperties: false,
264
+ properties: {
265
+ scores: {
266
+ type: "object",
267
+ required: [...keys],
268
+ additionalProperties: false,
269
+ properties: Object.fromEntries(keys.map((key) => [key, { type: "integer", minimum: 1, maximum: 5 }])),
270
+ },
271
+ reason: { type: "string" },
272
+ },
273
+ };
274
+ }
275
+ /**
276
+ * The quality judge. Fails closed: no runner, an unparseable verdict or a
277
+ * provider failure never passes content. Bands: >= 3.5 pass, 2.5-3.5 review,
278
+ * < 2.5 reject. Temperature is pinned to 0 so verdicts do not flip.
279
+ */
280
+ async function runQualityJudge(feature, config, prompt, keys, chat, options) {
281
+ const resolved = !options.runnerSelectionFrozen && !options.llmRunner
282
+ ? resolveImproveLlmExecution({ config, processName: `${feature}-judge` })
283
+ : null;
284
+ if (resolved)
285
+ options.onNotices?.(resolved.notices);
286
+ const runner = options.llmRunner ?? resolved?.runner;
287
+ if (!runner)
288
+ return { pass: false, score: -1, reason: "no LLM configured — cannot judge, failing closed" };
289
+ const outcome = await callStage({
290
+ feature,
291
+ runner,
292
+ system: "Return only valid JSON. No prose.",
293
+ prompt,
294
+ request: {
295
+ enableThinking: false,
296
+ temperature: 0,
297
+ responseSchema: judgeResponseSchema(keys),
298
+ ...(Object.hasOwn(options, "timeoutMs") ? { timeoutMs: options.timeoutMs } : {}),
299
+ ...(options.signal ? { signal: options.signal } : {}),
300
+ ...(chat ? { chat } : {}),
301
+ },
302
+ ...(options.onNotices ? { onNotices: options.onNotices } : {}),
303
+ });
304
+ if (!outcome.ok) {
305
+ return { pass: false, score: -1, reason: "judge timeout/error — routed to review", reviewNeeded: true };
306
+ }
307
+ const parsed = parseJudgeResponse(outcome.raw, keys);
308
+ if (!parsed)
309
+ return { pass: false, score: -1, reason: "judge parse failed — routed to review", reviewNeeded: true };
310
+ const { score, reason, criteria } = parsed;
311
+ const verdict = score >= 3.5 ? { pass: true } : score >= 2.5 ? { pass: false, reviewNeeded: true } : { pass: false };
312
+ return { ...verdict, score, reason, ...(criteria ? { criteria } : {}) };
313
+ }
314
+ /** Judge a proposed lesson (or knowledge promotion) against its source. */
315
+ export function runLessonQualityJudge(config, lessonContent, sourceContent, chat, options = {}) {
316
+ const prompt = buildJudgePrompt(lessonContent, sourceContent, options.similarLessons);
317
+ return runQualityJudge("lesson_quality_gate", config, prompt, LESSON_JUDGE_CRITERIA, chat, options);
318
+ }
319
+ /** Judge an in-place reflect revision without new-lesson novelty criteria. */
320
+ export function runReflectQualityJudge(config, candidateContent, sourceContent, feedback, chat, options = {}) {
321
+ const prompt = buildReflectJudgePrompt(candidateContent, sourceContent, feedback);
322
+ return runQualityJudge("proposal_quality_gate", config, prompt, REFLECT_JUDGE_CRITERIA, chat, options);
323
+ }