akm-cli 0.9.30 → 0.10.261001-beta

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 (384) hide show
  1. package/CHANGELOG.md +438 -0
  2. package/README.md +10 -10
  3. package/ROADMAP.md +112 -0
  4. package/STABILITY.md +99 -57
  5. package/dist/api-node.mjs +20 -0
  6. package/dist/api.d.ts +23 -0
  7. package/dist/api.js +45 -0
  8. package/dist/assets/hints/cli-hints-full.md +15 -29
  9. package/dist/assets/hints/cli-hints-short.md +2 -2
  10. package/dist/assets/improve-strategies/default.json +3 -3
  11. package/dist/assets/prompts/consolidate-pair.md +9 -7
  12. package/dist/assets/stash-skeleton/README.md +1 -1
  13. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
  14. package/dist/cli/shared.js +31 -48
  15. package/dist/cli/unknown-flags.js +6 -43
  16. package/dist/cli.js +8 -34
  17. package/dist/commands/agent/contribute-cli.js +1 -1
  18. package/dist/commands/completions.js +1 -2
  19. package/dist/commands/config-cli.js +5 -28
  20. package/dist/commands/env/env-cli.js +5 -5
  21. package/dist/commands/env/secret-cli.js +2 -2
  22. package/dist/commands/feedback-cli.js +75 -49
  23. package/dist/commands/health/checks.js +41 -16
  24. package/dist/commands/health/plugin-staleness.js +52 -22
  25. package/dist/commands/improve/autonomy-gate.js +5 -3
  26. package/dist/commands/improve/consolidate/chunking.js +3 -10
  27. package/dist/commands/improve/consolidate/continuity-check.js +4 -4
  28. package/dist/commands/improve/consolidate/pair-pass.js +29 -10
  29. package/dist/commands/improve/consolidate.js +10 -65
  30. package/dist/commands/improve/distill/lesson-update.js +91 -0
  31. package/dist/commands/improve/distill-guards.js +1 -43
  32. package/dist/commands/improve/distill.js +148 -21
  33. package/dist/commands/improve/eligibility.js +14 -1
  34. package/dist/commands/improve/extract-cli.js +1 -1
  35. package/dist/commands/improve/extract-prompt.js +17 -7
  36. package/dist/commands/improve/extract.js +5 -7
  37. package/dist/commands/improve/improve-cli.js +125 -118
  38. package/dist/commands/improve/improve-strategies.js +8 -12
  39. package/dist/commands/improve/improve.js +134 -52
  40. package/dist/commands/improve/loop-stages.js +18 -5
  41. package/dist/commands/improve/planner.js +0 -1
  42. package/dist/commands/improve/preparation.js +40 -99
  43. package/dist/commands/improve/proactive-maintenance.js +2 -2
  44. package/dist/commands/improve/reflect-noise.js +3 -55
  45. package/dist/commands/improve/reflect.js +29 -34
  46. package/dist/commands/improve/retrieval-queries.js +37 -0
  47. package/dist/commands/improve/retrieval-scope.js +2 -2
  48. package/dist/commands/improve/salience.js +2 -9
  49. package/dist/commands/improve/session-asset.js +4 -1
  50. package/dist/commands/improve/stage.js +23 -12
  51. package/dist/commands/lint/index.js +5 -20
  52. package/dist/commands/observability-cli.js +3 -9
  53. package/dist/commands/proposal/drain.js +43 -6
  54. package/dist/commands/proposal/proposal-cli.js +11 -31
  55. package/dist/commands/proposal/repository.js +20 -14
  56. package/dist/commands/proposal/validators/proposal-quality-validators.js +0 -3
  57. package/dist/commands/read/knowledge.js +3 -3
  58. package/dist/commands/read/remember-cli.js +0 -13
  59. package/dist/commands/read/search-cli.js +29 -97
  60. package/dist/commands/read/search.js +0 -11
  61. package/dist/commands/read/show.js +0 -19
  62. package/dist/commands/sources/plugin-upgrade.js +164 -101
  63. package/dist/commands/sources/sources-cli.js +1 -15
  64. package/dist/commands/sources/stash-cli.js +6 -14
  65. package/dist/commands/tasks/tasks-cli.js +4 -115
  66. package/dist/commands/workflow/plan.js +11 -33
  67. package/dist/commands/workflow-cli.js +2 -7
  68. package/dist/core/adapter/adapter-ids.js +1 -2
  69. package/dist/core/adapter/adapters/agent-skills-adapter.js +0 -4
  70. package/dist/core/adapter/adapters/akm-adapter.js +9 -48
  71. package/dist/core/adapter/adapters/akm-lint.js +10 -26
  72. package/dist/core/adapter/adapters/akm-metadata.js +2 -72
  73. package/dist/core/adapter/adapters/akm-task-adapter.js +0 -5
  74. package/dist/core/adapter/adapters/akm-workflow-adapter.js +9 -28
  75. package/dist/core/adapter/adapters/dotenv-adapter.js +1 -20
  76. package/dist/core/adapter/adapters/generic-files-adapter.js +0 -10
  77. package/dist/core/adapter/adapters/llm-wiki-adapter.js +0 -4
  78. package/dist/core/adapter/adapters/tool-dir-shared.js +0 -24
  79. package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -4
  80. package/dist/core/adapter/recognize-match.js +3 -4
  81. package/dist/core/common.js +18 -2
  82. package/dist/core/config/config-schema.js +12 -15
  83. package/dist/core/config/config-types.js +6 -15
  84. package/dist/core/config/config-walker.js +6 -23
  85. package/dist/core/config/config.js +17 -80
  86. package/dist/core/config/engine-semantics.js +7 -3
  87. package/dist/core/config/schema/engines.js +7 -7
  88. package/dist/core/config/schema/improve-processes.js +10 -63
  89. package/dist/core/config/schema/improve.js +2 -21
  90. package/dist/core/config/schema/index-config.js +6 -39
  91. package/dist/core/env-secret-ref.js +2 -45
  92. package/dist/core/errors.js +1 -2
  93. package/dist/core/extra-params.js +2 -86
  94. package/dist/core/file-lock.js +12 -7
  95. package/dist/core/improve-result.js +13 -1
  96. package/dist/core/mutation-target.js +2 -2
  97. package/dist/core/paths.js +4 -0
  98. package/dist/core/recognition-util.js +4 -5
  99. package/dist/core/run-lock.js +1 -1
  100. package/dist/core/subprocess.js +49 -0
  101. package/dist/core/warn.js +21 -4
  102. package/dist/core/write-source.js +3 -3
  103. package/dist/execution/target-ref.js +1 -2
  104. package/dist/indexer/indexer.js +15 -6
  105. package/dist/indexer/passes/memory-inference.js +15 -6
  106. package/dist/indexer/search/db-search.js +49 -36
  107. package/dist/indexer/search/fts-query.js +0 -19
  108. package/dist/indexer/search/ranking.js +29 -1
  109. package/dist/indexer/usage/usage-events.js +21 -16
  110. package/dist/integrations/agent/engine-resolution.js +5 -2
  111. package/dist/integrations/agent/index.js +1 -1
  112. package/dist/integrations/agent/profiles.js +41 -98
  113. package/dist/integrations/agent/request-lowering.js +3 -3
  114. package/dist/integrations/harnesses/aider/index.js +5 -0
  115. package/dist/integrations/harnesses/amazonq/index.js +1 -0
  116. package/dist/integrations/harnesses/claude/config-import.js +2 -3
  117. package/dist/integrations/harnesses/claude/index.js +5 -0
  118. package/dist/integrations/harnesses/codex/index.js +1 -0
  119. package/dist/integrations/harnesses/copilot/index.js +1 -0
  120. package/dist/integrations/harnesses/gemini/index.js +1 -0
  121. package/dist/integrations/harnesses/index.js +18 -39
  122. package/dist/integrations/harnesses/opencode/agent-builder.js +60 -35
  123. package/dist/integrations/harnesses/opencode/config-import.js +121 -52
  124. package/dist/integrations/harnesses/opencode/index.js +22 -0
  125. package/dist/integrations/harnesses/opencode/plugin-layout.js +68 -0
  126. package/dist/integrations/harnesses/opencode/session-log-types.js +12 -0
  127. package/dist/integrations/harnesses/opencode/session-log-v1.js +72 -0
  128. package/dist/integrations/harnesses/opencode/session-log-v2.js +140 -0
  129. package/dist/integrations/harnesses/opencode/session-log.js +104 -115
  130. package/dist/integrations/harnesses/opencode/version.js +98 -0
  131. package/dist/integrations/harnesses/opencode-sdk/{harness.js → index.js} +5 -17
  132. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +105 -206
  133. package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +199 -0
  134. package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +254 -0
  135. package/dist/integrations/harnesses/opencode-sdk/wire.js +66 -0
  136. package/dist/integrations/harnesses/openhands/index.js +1 -0
  137. package/dist/integrations/harnesses/pi/index.js +1 -0
  138. package/dist/integrations/harnesses/shared.js +2 -0
  139. package/dist/integrations/harnesses/types.js +2 -0
  140. package/dist/llm/client.js +74 -14
  141. package/dist/output/cli-hints.js +1 -1
  142. package/dist/output/context.js +10 -19
  143. package/dist/output/format-exempt.js +5 -8
  144. package/dist/output/shapes/helpers.js +1 -22
  145. package/dist/output/shapes/passthrough.js +0 -1
  146. package/dist/output/shapes.js +3 -31
  147. package/dist/output/stdout.js +5 -1
  148. package/dist/output/text/command-format.js +6 -1
  149. package/dist/output/text/workflow-format.js +4 -22
  150. package/dist/scripts/akm-migrate-node.js +15769 -16731
  151. package/dist/scripts/akm-migrate.js +16339 -17297
  152. package/dist/setup/detect.js +10 -4
  153. package/dist/setup/harness-config-import.js +5 -14
  154. package/dist/setup/setup.js +1 -1
  155. package/dist/setup/steps/tasks.js +12 -13
  156. package/dist/sources/providers/git-stash.js +94 -13
  157. package/dist/storage/repositories/index-utility-repository.js +2 -32
  158. package/dist/storage/repositories/index-vec-repository.js +4 -0
  159. package/dist/storage/repositories/task-history-repository.js +0 -5
  160. package/dist/storage/repositories/workflow-runs-repository.js +5 -15
  161. package/dist/tasks/embedded.js +2 -1
  162. package/dist/tasks/run/run-command-task.js +9 -1
  163. package/dist/tasks/run/run-workflow-task.js +4 -3
  164. package/dist/tasks/run/task-history.js +0 -2
  165. package/dist/tasks/run/task-log.js +38 -1
  166. package/dist/tasks/schedule-gates.js +39 -0
  167. package/dist/tasks/scheduler-binding.js +0 -16
  168. package/dist/tasks/scheduler-sync.js +3 -97
  169. package/dist/tasks/source/bounded-document.js +1 -1
  170. package/dist/tasks/source/task-source-v4.js +2 -12
  171. package/dist/tasks/task-run-reserved-flags.js +2 -31
  172. package/dist/workflows/authoring/authoring.js +6 -6
  173. package/dist/workflows/compile.js +8 -65
  174. package/dist/workflows/exec/child-workflow.js +22 -3
  175. package/dist/workflows/exec/native-executor.js +12 -147
  176. package/dist/workflows/exec/run-workflow.js +31 -103
  177. package/dist/workflows/exec/step-work.js +9 -178
  178. package/dist/workflows/exec/unit-dispatch.js +0 -10
  179. package/dist/workflows/freeze/environment.js +3 -44
  180. package/dist/workflows/freeze/freeze.js +8 -41
  181. package/dist/workflows/freeze/targets/child-workflow.js +27 -63
  182. package/dist/workflows/freeze/targets/command.js +2 -16
  183. package/dist/workflows/freeze/targets/shell.js +0 -2
  184. package/dist/workflows/freeze/task-bindings.js +2 -28
  185. package/dist/workflows/ir/params.js +12 -2
  186. package/dist/workflows/parser.js +82 -232
  187. package/dist/workflows/plan.js +1 -1
  188. package/dist/workflows/renderer.js +10 -19
  189. package/dist/workflows/runtime/run-plan.js +11 -53
  190. package/dist/workflows/runtime/runs.js +4 -27
  191. package/dist/workflows/source-files.js +12 -16
  192. package/dist/workflows/source-semantics.js +1 -93
  193. package/docs/README.md +43 -42
  194. package/docs/agents/README.md +15 -0
  195. package/docs/agents/agent-install.md +14 -0
  196. package/docs/architecture/0.10-process-rules.md +827 -0
  197. package/docs/architecture/README.md +67 -0
  198. package/docs/architecture/adapters.md +258 -0
  199. package/docs/architecture/akm-architecture-decision-history.md +2055 -0
  200. package/docs/architecture/akm-core-principles.md +126 -0
  201. package/docs/architecture/architecture.md +578 -0
  202. package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +550 -0
  203. package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +72 -0
  204. package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +142 -0
  205. package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +189 -0
  206. package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +97 -0
  207. package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +108 -0
  208. package/docs/architecture/decisions/0006-task-source-version-routing.md +124 -0
  209. package/docs/architecture/decisions/0007-workflow-composition-bounds.md +83 -0
  210. package/docs/architecture/decisions/0008-task-binding-normalization.md +88 -0
  211. package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +80 -0
  212. package/docs/architecture/decisions/0010-driver-protocol-cut.md +36 -0
  213. package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +125 -0
  214. package/docs/architecture/decisions/README.md +62 -0
  215. package/docs/architecture/improvement.md +479 -0
  216. package/docs/architecture/internals/classification.md +154 -0
  217. package/docs/architecture/internals/fresh-host-rebuild-runbook.md +40 -0
  218. package/docs/architecture/internals/functional-contract-patterns.md +340 -0
  219. package/docs/architecture/internals/health-advisories.md +110 -0
  220. package/docs/architecture/internals/improve-workflow.md +719 -0
  221. package/docs/architecture/internals/indexing.md +498 -0
  222. package/docs/architecture/internals/registry-network-boundary.md +57 -0
  223. package/docs/architecture/internals/search.md +248 -0
  224. package/docs/architecture/internals/storage-locations.md +943 -0
  225. package/docs/architecture/persisted-data-compat.md +68 -0
  226. package/docs/architecture/reviews/env-secret-access.md +319 -0
  227. package/docs/architecture/runtime-boundary-design.md +153 -0
  228. package/docs/architecture/specs/0.9.0-close-out-plan.md +361 -0
  229. package/docs/architecture/specs/0.9.0-decisions.md +532 -0
  230. package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +745 -0
  231. package/docs/architecture/specs/0.9.0-open-items-register.md +135 -0
  232. package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +740 -0
  233. package/docs/architecture/specs/0.9.0-release-surface-review.md +636 -0
  234. package/docs/architecture/specs/agent-command-engine-model-design.md +513 -0
  235. package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +501 -0
  236. package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +291 -0
  237. package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +2059 -0
  238. package/docs/architecture/specs/di-seams-plan.md +539 -0
  239. package/docs/architecture/specs/driver-protocol-keep-or-cut.md +275 -0
  240. package/docs/architecture/specs/fact-asset-type.md +142 -0
  241. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +634 -0
  242. package/docs/architecture/specs/okf-support.md +148 -0
  243. package/docs/architecture/specs/ref.md +329 -0
  244. package/docs/architecture/specs/reviews/task-workflow-unification/README.md +72 -0
  245. package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +152 -0
  246. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +352 -0
  247. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +300 -0
  248. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +402 -0
  249. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +758 -0
  250. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +645 -0
  251. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +602 -0
  252. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +27 -0
  253. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +27 -0
  254. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +74 -0
  255. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +15 -0
  256. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +132 -0
  257. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +147 -0
  258. package/docs/architecture/specs/stash-conventions-code-spec.md +275 -0
  259. package/docs/architecture/specs/stash-organization-conventions.md +377 -0
  260. package/docs/architecture/specs/task-workflow-format-unification.md +721 -0
  261. package/docs/architecture/specs/workflow-engine-buy-vs-build.md +231 -0
  262. package/docs/architecture/specs/workflow-format-unification.md +432 -0
  263. package/docs/architecture/testing/manual-testing-checklist.md +3411 -0
  264. package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +924 -0
  265. package/docs/architecture/testing/task-workflow-manual-tests.md +1720 -0
  266. package/docs/architecture/testing/testing-workflow.md +446 -0
  267. package/docs/architecture/workflow-engine.md +223 -0
  268. package/docs/guides/README.md +33 -0
  269. package/docs/guides/author-bundles.md +310 -0
  270. package/docs/guides/author-workflows.md +490 -0
  271. package/docs/guides/bundles.md +323 -0
  272. package/docs/guides/capture-knowledge.md +136 -0
  273. package/docs/guides/claude-code-vs-akm-workflows.md +29 -0
  274. package/docs/guides/concepts.md +93 -0
  275. package/docs/guides/discover-and-load.md +158 -0
  276. package/docs/guides/getting-started.md +240 -0
  277. package/docs/guides/improve-the-library.md +247 -0
  278. package/docs/guides/knowledge-management.md +18 -0
  279. package/docs/guides/recipes/headless-install.md +97 -0
  280. package/docs/guides/recipes/website-source.md +28 -0
  281. package/docs/guides/run-workflows.md +279 -0
  282. package/docs/guides/scheduling.md +131 -0
  283. package/docs/guides/use-with-any-agent.md +174 -0
  284. package/docs/guides/wikis.md +81 -0
  285. package/docs/integration/bundling-akm.md +7 -6
  286. package/docs/maintainers/README.md +19 -0
  287. package/docs/maintainers/curate-workmap.md +335 -0
  288. package/docs/maintainers/eval.md +3 -0
  289. package/docs/maintainers/local-development.md +108 -0
  290. package/docs/maintainers/release-checklist.md +135 -0
  291. package/docs/migration/README.md +4 -2
  292. package/docs/migration/release-notes/0.0.13.md +1 -1
  293. package/docs/migration/release-notes/0.1.0.md +1 -1
  294. package/docs/migration/release-notes/0.10.0.md +201 -0
  295. package/docs/migration/release-notes/0.2.0.md +1 -1
  296. package/docs/migration/release-notes/0.3.0.md +1 -1
  297. package/docs/migration/release-notes/0.5.0.md +1 -1
  298. package/docs/migration/release-notes/0.6.0.md +1 -1
  299. package/docs/migration/release-notes/0.7.0.md +1 -1
  300. package/docs/migration/release-notes/0.7.3.md +2 -2
  301. package/docs/migration/release-notes/0.7.4.md +1 -1
  302. package/docs/migration/release-notes/0.7.5.md +1 -1
  303. package/docs/migration/release-notes/0.8.0.md +1 -1
  304. package/docs/migration/release-notes/0.9.0.md +1 -1
  305. package/docs/migration/release-notes/0.9.14.md +1 -1
  306. package/docs/migration/release-notes/0.9.15.md +1 -1
  307. package/docs/migration/release-notes/0.9.16.md +1 -1
  308. package/docs/migration/release-notes/0.9.17.md +1 -1
  309. package/docs/migration/release-notes/0.9.19.md +1 -1
  310. package/docs/migration/release-notes/0.9.2.md +1 -1
  311. package/docs/migration/release-notes/README.md +28 -31
  312. package/docs/migration/v0.5-to-v0.6.md +759 -0
  313. package/docs/migration/v0.8-to-v0.9.md +1 -1
  314. package/docs/migration/v0.9-to-v0.10.md +507 -0
  315. package/docs/plans/0.9.2-agent-command-workflow-plan.md +423 -0
  316. package/docs/posts/README.md +30 -0
  317. package/docs/posts/akm-command-tour.md +495 -0
  318. package/docs/posts/akm-logo-sized.webp +0 -0
  319. package/docs/posts/belief-aware-memory-12.md +139 -0
  320. package/docs/posts/config-v2-lessons-16.md +191 -0
  321. package/docs/posts/improve-loop-autonomous-10.md +225 -0
  322. package/docs/posts/improve-pipeline-debugging-0803.md +179 -0
  323. package/docs/posts/intro-part-01.md +76 -0
  324. package/docs/posts/intro-part-02.md +221 -0
  325. package/docs/posts/intro-part-03.md +190 -0
  326. package/docs/posts/intro-part-04.md +221 -0
  327. package/docs/posts/llm-mode-reflect-13.md +166 -0
  328. package/docs/posts/openpalm-built-on-akm.md +86 -0
  329. package/docs/posts/progressive-disclosure-06.md +129 -0
  330. package/docs/posts/proposal-safety-net-15.md +112 -0
  331. package/docs/posts/release-0.5.0.md +247 -0
  332. package/docs/posts/release-0.6.0.md +117 -0
  333. package/docs/posts/release-0.7.0.md +159 -0
  334. package/docs/posts/release-0.8.0.md +332 -0
  335. package/docs/posts/scattered-skills-05.md +100 -0
  336. package/docs/posts/task-assets-persistent-workflows-11.md +222 -0
  337. package/docs/posts/team-skills-07.md +198 -0
  338. package/docs/posts/wiki-agent-knowledge-08.md +223 -0
  339. package/docs/posts/workflows-vaults-09.md +321 -0
  340. package/docs/product-surface.md +54 -0
  341. package/docs/reference/README.md +2 -2
  342. package/docs/reference/api.md +65 -0
  343. package/docs/reference/asset-types.md +166 -0
  344. package/docs/reference/bundle-types.md +2 -4
  345. package/docs/reference/cli.md +163 -192
  346. package/docs/reference/configuration.md +101 -20
  347. package/docs/reference/data-and-telemetry.md +2 -2
  348. package/docs/reference/env-and-secrets.md +126 -0
  349. package/docs/reference/memory.md +124 -0
  350. package/docs/reference/refs.md +156 -0
  351. package/docs/reference/registry.md +489 -0
  352. package/docs/reference/supported-formats.md +3 -4
  353. package/docs/reference/tasks.md +12 -19
  354. package/docs/reference/website-sources.md +141 -0
  355. package/docs/reference/workflow-schema.md +89 -317
  356. package/docs/reference/workflows.md +20 -48
  357. package/package.json +23 -16
  358. package/schemas/akm-config.json +2 -243
  359. package/schemas/akm-task.json +2 -3
  360. package/schemas/akm-workflow.json +47 -84
  361. package/dist/assets/improve-strategies/catchup.json +0 -41
  362. package/dist/assets/improve-strategies/proactive-maintenance.json +0 -24
  363. package/dist/assets/improve-strategies/quick.json +0 -17
  364. package/dist/assets/improve-strategies/reflect-distill.json +0 -29
  365. package/dist/assets/improve-strategies/thorough.json +0 -49
  366. package/dist/assets/prompts/retrieval-relevance-judge.md +0 -6
  367. package/dist/assets/tasks/improve/akm-improve-catchup.yml +0 -6
  368. package/dist/assets/tasks/improve/akm-improve-frequent.yml +0 -4
  369. package/dist/assets/tasks/improve/akm-improve-nightly.yml +0 -4
  370. package/dist/cli/retired-commands.js +0 -118
  371. package/dist/commands/improve/retrieval-gate.js +0 -132
  372. package/dist/commands/tasks/validate.js +0 -176
  373. package/dist/core/config/legacy-source-shape-shim.js +0 -117
  374. package/dist/indexer/feedback/utility-policy.js +0 -75
  375. package/dist/integrations/harnesses/ids.js +0 -28
  376. package/dist/tasks/source/task-source-v3-frozen.js +0 -424
  377. package/dist/tasks/source/task-to-v4.js +0 -863
  378. package/dist/workflows/exec/worktree.js +0 -372
  379. package/dist/workflows/freeze/child-output-references.js +0 -83
  380. package/dist/workflows/freeze/identity.js +0 -22
  381. package/dist/workflows/freeze/targets/script.js +0 -50
  382. package/dist/workflows/freeze/targets/task.js +0 -124
  383. package/dist/workflows/github-yaml.js +0 -506
  384. package/dist/workflows/runtime/run-outputs.js +0 -80
@@ -28,7 +28,7 @@ import { resolveEntryContentDir, resolveSourceEntries } from "../../indexer/sear
28
28
  import { collectEngineCredentialValues } from "../../integrations/agent/engine-resolution.js";
29
29
  import { installLlmUsagePersistence } from "../../llm/usage-persist.js";
30
30
  import { withLlmStage } from "../../llm/usage-telemetry.js";
31
- import { isGitBackedStash, listGitChangedPaths, resolveWritableOverride, saveGitStash, } from "../../sources/providers/git.js";
31
+ import { GitStashPushError, isGitBackedStash, listGitChangedPaths, resolveWritableOverride, saveGitStash, } from "../../sources/providers/git.js";
32
32
  import { closeDatabase, openExistingDatabase } from "../../storage/repositories/index-connection.js";
33
33
  import { getEntryCount } from "../../storage/repositories/index-entries-repository.js";
34
34
  import { openSqliteReadSnapshot, SqliteReadSnapshotUnavailableError } from "../../storage/sqlite-read-snapshot.js";
@@ -70,7 +70,8 @@ export function renderSyncCommitMessage(template, result, nowMs) {
70
70
  export const FIRST_ENGINE_RESPONSE_HEARTBEAT_MS = 5_000;
71
71
  /**
72
72
  * Abort the run at the budget; force-exit (0 — budget exhaustion is a normal
73
- * scheduled-task outcome) only if the drain overruns the grace period.
73
+ * scheduled-task outcome) only if the drain overruns the grace period, after
74
+ * `onHardKill` has persisted what the killed run left behind.
74
75
  * Returns an idempotent disposer.
75
76
  */
76
77
  export function armBudgetWatchdog(budgetMs, controller, deps) {
@@ -81,7 +82,15 @@ export function armBudgetWatchdog(budgetMs, controller, deps) {
81
82
  let hardKillTimer;
82
83
  const budgetTimer = setTimeoutFn(() => {
83
84
  controller.abort("improve budget exhausted");
84
- hardKillTimer = setTimeoutFn(() => exitFn(0), hardKillGraceMs);
85
+ hardKillTimer = setTimeoutFn(() => {
86
+ try {
87
+ deps?.onHardKill?.();
88
+ }
89
+ catch {
90
+ // Best-effort: the forced exit must still happen.
91
+ }
92
+ exitFn(0);
93
+ }, hardKillGraceMs);
85
94
  hardKillTimer.unref?.();
86
95
  }, budgetMs);
87
96
  return () => {
@@ -101,6 +110,7 @@ export async function akmImprove(options = {}) {
101
110
  // Set by the usage sink when any engine call terminates, prepass included.
102
111
  let firstEngineResponseSeen = false;
103
112
  let initialGitPaths = new Set();
113
+ let preRunSync;
104
114
  // The write-provenance journal (#652) spans exactly the window this run holds the lock.
105
115
  let journal;
106
116
  const closeJournal = () => {
@@ -155,7 +165,20 @@ export async function akmImprove(options = {}) {
155
165
  });
156
166
  if (!options.dryRun) {
157
167
  const remainingBudget = budgetAbortController.signal.remainingBudgetMs;
158
- clearBudgetTimer = armBudgetWatchdog(Math.max(1, remainingBudget ?? budgetMs), budgetAbortController);
168
+ clearBudgetTimer = armBudgetWatchdog(Math.max(1, remainingBudget ?? budgetMs), budgetAbortController, {
169
+ // The forced exit skips every finally and the CLI catch: leave a terminated
170
+ // run record and bank the files this run wrote (journal is in memory) first.
171
+ // Local commit only — a push to a dead remote must not hang the exit.
172
+ onHardKill: () => {
173
+ try {
174
+ options.onBudgetHardKill?.();
175
+ }
176
+ catch {
177
+ // best-effort
178
+ }
179
+ commitStashBatch({ scope, plannedRefs: collected?.plannedRefs ?? [], runId: options.runId }, { push: false });
180
+ },
181
+ });
159
182
  }
160
183
  try {
161
184
  if (!options.dryRun) {
@@ -174,6 +197,9 @@ export async function akmImprove(options = {}) {
174
197
  });
175
198
  exitBackstop = releaseRunLock;
176
199
  process.on("exit", exitBackstop);
200
+ // Pull in what another host pushed before anything reads the bundle (#1091). This also commits
201
+ // pending managed-path changes, as `akm sync` does, so they are not mistaken for this run's writes.
202
+ preRunSync = syncBeforeRun(setup, eventsCtx);
177
203
  initialGitPaths =
178
204
  syncRepoDir && isGitBackedStash(syncRepoDir) ? new Set(listGitChangedPaths(syncRepoDir)) : new Set();
179
205
  journal = beginWriteProvenance();
@@ -246,6 +272,8 @@ export async function akmImprove(options = {}) {
246
272
  if (writtenPaths.length > 0)
247
273
  result.writtenPaths = writtenPaths;
248
274
  result.sync = commitStashBatch(result);
275
+ if (preRunSync)
276
+ result.preRunSync = preRunSync;
249
277
  return result;
250
278
  }
251
279
  catch (err) {
@@ -654,7 +682,7 @@ function buildResultExecutionPlan(run, preparation, collected, dryRun) {
654
682
  enabled: scope.mode !== "ref" && resolvedPlan.processes.triage.enabled,
655
683
  configuredMode: configuredTriage?.applyMode ?? "queue",
656
684
  mode: improveProfile.processes?.triage?.applyMode ?? "queue",
657
- maxAcceptsPerRun: configuredTriage?.maxAcceptsPerRun ?? 25,
685
+ maxAcceptsPerRun: configuredTriage?.maxAcceptsPerRun ?? 200,
658
686
  },
659
687
  });
660
688
  }
@@ -674,7 +702,7 @@ async function runTriagePrePass(run) {
674
702
  ...(options.target ? { target: options.target } : {}),
675
703
  config: options.config,
676
704
  applyMode: triageConfig?.applyMode ?? "queue",
677
- maxAccepts: triageConfig?.maxAcceptsPerRun ?? 25,
705
+ maxAccepts: triageConfig?.maxAcceptsPerRun ?? 200,
678
706
  dryRun: false,
679
707
  excludeIds: new Set(),
680
708
  judgment: resolvedPlan.triageJudgment,
@@ -712,60 +740,114 @@ export function resolveSyncPathSet(input) {
712
740
  unattributed: changedPaths.filter((p) => !attributed.has(p) && !initialPaths.has(p) && inScope(p)).sort(),
713
741
  };
714
742
  }
743
+ /**
744
+ * One `saveGitStash` call for the run's write-target bundle, shared by the
745
+ * pre-run sync and the auto-sync commit: never throws, records a `stash_synced`
746
+ * event, and returns undefined when the bundle is not git-backed, there is no
747
+ * primary stash, or sync is disabled (`--no-sync` / `sync.enabled: false`).
748
+ * `scopePaths` runs inside the guard; leaving `paths` undefined means what
749
+ * `akm sync` stages (the managed paths).
750
+ */
751
+ function runStashSync(run, eventsCtx, phase, input) {
752
+ const { writeTarget, primaryStashDir, effectiveSync, options, config, improveProfile } = run;
753
+ const repoDir = writeTarget?.source.repoPath ?? primaryStashDir;
754
+ if (!primaryStashDir || !repoDir || effectiveSync.enabled === false || !isGitBackedStash(repoDir)) {
755
+ return undefined;
756
+ }
757
+ const saveGitStashFn = options.saveGitStashFn ?? saveGitStash;
758
+ const writableOverride = writeTarget ? resolveWritable(writeTarget.config) : resolveWritableOverride(config);
759
+ const push = input.push ?? options.sync?.push ?? improveProfile.sync?.push ?? true;
760
+ const record = (metadata) => appendEvent({ eventType: "stash_synced", metadata: { phase, ...metadata } }, eventsCtx);
761
+ try {
762
+ const { paths, unattributed } = input.scopePaths({
763
+ repoDir,
764
+ assetRoot: writeTarget?.source.path ?? primaryStashDir,
765
+ });
766
+ const syncResult = saveGitStashFn(undefined, input.message, writableOverride, {
767
+ push,
768
+ repoDir,
769
+ ...(paths ? { paths } : {}),
770
+ });
771
+ record({
772
+ committed: syncResult.committed,
773
+ pushed: syncResult.pushed,
774
+ skipped: syncResult.skipped,
775
+ reason: syncResult.reason ?? null,
776
+ ...(paths ? { attributed: paths.length, unattributed: unattributed ?? 0 } : {}),
777
+ });
778
+ return {
779
+ committed: syncResult.committed,
780
+ pushed: syncResult.pushed,
781
+ skipped: syncResult.skipped,
782
+ ...(syncResult.reason !== undefined ? { reason: syncResult.reason } : {}),
783
+ };
784
+ }
785
+ catch (syncErr) {
786
+ const reason = errMessage(syncErr);
787
+ warn(`improve: stash sync failed (non-fatal): ${reason}`);
788
+ // A push that failed after the commit landed still left the commit in the repo.
789
+ const committed = syncErr instanceof GitStashPushError;
790
+ record({ committed, pushed: false, skipped: true, reason });
791
+ return { committed, pushed: false, skipped: true, reason };
792
+ }
793
+ }
794
+ /**
795
+ * The pre-run sync (#1091): the same fetch / fast-forward-or-merge / commit /
796
+ * push `akm sync` runs for the write-target bundle, before the index and plan
797
+ * stages so they see what another host pushed. A conflict or fetch failure is
798
+ * a warning, never an abort: the run continues on the local state.
799
+ */
800
+ function syncBeforeRun(run, eventsCtx) {
801
+ const outcome = runStashSync(run, eventsCtx, "pre-run", {
802
+ message: "akm improve pre-run sync",
803
+ scopePaths: ({ repoDir, assetRoot }) => {
804
+ // A bundle whose content sits in a subdirectory of the repo stages only that subdirectory, as
805
+ // `akm sync` does for a content root; a root-level bundle leaves `paths` to the managed-path default.
806
+ const assetPrefix = path.relative(repoDir, assetRoot).replaceAll(path.sep, "/");
807
+ if (!assetPrefix)
808
+ return {};
809
+ return resolveSyncPathSet({
810
+ repoDir,
811
+ assetPrefix,
812
+ changedPaths: listGitChangedPaths(repoDir),
813
+ initialPaths: new Set(),
814
+ writtenPaths: [],
815
+ provenance: false,
816
+ });
817
+ },
818
+ });
819
+ if (outcome?.reason)
820
+ warn(`[improve] pre-run sync: ${outcome.reason}; continuing on the local state`);
821
+ return outcome;
822
+ }
715
823
  /**
716
824
  * The auto-sync commit (#662), used at end of run and from the crash path:
717
825
  * idempotent and never throws. The getters read bindings reassigned after this
718
826
  * factory runs.
719
827
  */
720
828
  function makeCommitStashBatch(deps) {
721
- const { writeTarget, primaryStashDir, effectiveSync, options, config, improveProfile } = deps.run;
722
- return (messageContext) => {
723
- const eventsCtx = deps.getEventsCtx();
829
+ const { effectiveSync } = deps.run;
830
+ return (messageContext, override) => {
724
831
  const writeJournal = deps.getWriteJournal();
725
- const repoDir = writeTarget?.source.repoPath ?? primaryStashDir;
726
- if (!primaryStashDir || !repoDir || effectiveSync.enabled === false || !isGitBackedStash(repoDir)) {
727
- return undefined;
728
- }
729
- const saveGitStashFn = options.saveGitStashFn ?? saveGitStash;
730
- const writableOverride = writeTarget ? resolveWritable(writeTarget.config) : resolveWritableOverride(config);
731
- const push = options.sync?.push ?? improveProfile.sync?.push ?? true;
732
832
  const message = renderSyncCommitMessage(effectiveSync.message ?? "akm improve auto-sync", messageContext, Date.now());
733
- const record = (metadata) => appendEvent({ eventType: "stash_synced", metadata }, eventsCtx);
734
- try {
735
- const assetRoot = writeTarget?.source.path ?? primaryStashDir;
736
- const { paths, unattributed } = resolveSyncPathSet({
737
- repoDir,
738
- assetPrefix: path.relative(repoDir, assetRoot).replaceAll(path.sep, "/"),
739
- changedPaths: listGitChangedPaths(repoDir),
740
- initialPaths: deps.getInitialGitPaths(),
741
- writtenPaths: writeJournal?.writtenPaths() ?? [],
742
- provenance: writeJournal !== undefined,
743
- });
744
- if (unattributed.length > 0) {
745
- warnVerbose(`[improve] auto-sync left ${unattributed.length} path(s) uncommitted — not written by this run: ${unattributed.join(", ")}`);
746
- }
747
- const syncResult = saveGitStashFn(undefined, message, writableOverride, { push, repoDir, paths });
748
- record({
749
- committed: syncResult.committed,
750
- pushed: syncResult.pushed,
751
- skipped: syncResult.skipped,
752
- reason: syncResult.reason ?? null,
753
- attributed: paths.length,
754
- unattributed: unattributed.length,
755
- });
756
- return {
757
- committed: syncResult.committed,
758
- pushed: syncResult.pushed,
759
- skipped: syncResult.skipped,
760
- ...(syncResult.reason !== undefined ? { reason: syncResult.reason } : {}),
761
- };
762
- }
763
- catch (syncErr) {
764
- const reason = errMessage(syncErr);
765
- warn(`improve: stash sync failed (non-fatal): ${reason}`);
766
- record({ committed: false, pushed: false, skipped: true, reason });
767
- return { committed: false, pushed: false, skipped: true, reason };
768
- }
833
+ return runStashSync(deps.run, deps.getEventsCtx(), "end-of-run", {
834
+ message,
835
+ push: override?.push,
836
+ scopePaths: ({ repoDir, assetRoot }) => {
837
+ const { paths, unattributed } = resolveSyncPathSet({
838
+ repoDir,
839
+ assetPrefix: path.relative(repoDir, assetRoot).replaceAll(path.sep, "/"),
840
+ changedPaths: listGitChangedPaths(repoDir),
841
+ initialPaths: deps.getInitialGitPaths(),
842
+ writtenPaths: writeJournal?.writtenPaths() ?? [],
843
+ provenance: writeJournal !== undefined,
844
+ });
845
+ if (unattributed.length > 0) {
846
+ warnVerbose(`[improve] auto-sync left ${unattributed.length} path(s) uncommitted — not written by this run: ${unattributed.join(", ")}`);
847
+ }
848
+ return { paths, unattributed: unattributed.length };
849
+ },
850
+ });
769
851
  };
770
852
  }
771
853
  /**
@@ -22,7 +22,7 @@ import { getLiveRefSnapshot, isRefLiveInSnapshot, } from "../../storage/reposito
22
22
  import { clearAssetOutcomeMissing, countAssetOutcomeMissing, deleteAssetOutcomeMissingBefore, listAssetOutcomeMissingState, stampAssetOutcomeMissing, } from "../../storage/repositories/outcome-repository.js";
23
23
  import { clearAssetSalienceMissing, countAssetSalienceMissing, deleteAssetSalienceMissingBefore, listAssetSalienceMissingState, stampAssetSalienceMissing, } from "../../storage/repositories/salience-repository.js";
24
24
  import { readFreelistInfo, STATE_DB_VACUUMED_EVENT, vacuumIfReclaimable } from "../../storage/state-db-integrity.js";
25
- import { purgeOldTaskLogFiles } from "../../tasks/run/task-log.js";
25
+ import { purgeOldRunLogFiles, purgeOldTaskLogFiles } from "../../tasks/run/task-log.js";
26
26
  import { expireStaleProposals, purgeOrphanProposals } from "../proposal/repository.js";
27
27
  import { checkDeadUrls } from "../url-checker.js";
28
28
  import { isDistillCandidateRef } from "./eligibility.js";
@@ -148,7 +148,6 @@ async function runLoopReflectPass(planned, env, tally) {
148
148
  ...(options.sourceName && primaryStashDir ? { target: { source: options.sourceName, root: primaryStashDir } } : {}),
149
149
  ...(reflectErrors.length > 0 ? { avoidPatterns: [...reflectErrors] } : {}),
150
150
  eventSource: "improve",
151
- lowValueFilter: improveProfile.processes?.reflect?.lowValueFilter?.enabled === true,
152
151
  ...(improveProfile.processes?.reflect?.defectFilter
153
152
  ? { defectFilter: improveProfile.processes.reflect.defectFilter }
154
153
  : {}),
@@ -174,10 +173,18 @@ async function runLoopReflectPass(planned, env, tally) {
174
173
  result,
175
174
  });
176
175
  // A quality rejection recorded itself, and the judge's text is no lesson for
177
- // the next prompt; skips revisit on the `unchanged` cadence.
176
+ // the next prompt; skips revisit on the `unchanged` cadence. A transient
177
+ // failure (transport, parse, timeout, budget abort, crash) is not a verdict
178
+ // on the asset and writes no row, like distill: a `failed` row would advance
179
+ // the ledger cursor and consume the feedback that planned the ref. Only a
180
+ // guard rejection records `failed`.
178
181
  if (!result.ok && reason !== "quality_rejected") {
179
- recordLoopAttempt(planned, env, "reflect", skipped ? "unchanged" : "failed", reason);
180
- if (!skipped) {
182
+ if (skipped)
183
+ recordLoopAttempt(planned, env, "reflect", "unchanged", reason);
184
+ else if (reason === "content_policy_reject")
185
+ recordLoopAttempt(planned, env, "reflect", "failed", reason);
186
+ // A budget abort is no lesson for the next prompt either.
187
+ if (!skipped && reason !== "aborted") {
181
188
  tally.recentErrorPushes.push({
182
189
  originator: "reflect",
183
190
  message: result.error ?? reason ?? "unknown reflect error",
@@ -588,6 +595,12 @@ export function runRetentionPurgePass(ctx) {
588
595
  catch (err) {
589
596
  warnings.push(`task log files purge failed: ${errMessage(err)}`);
590
597
  }
598
+ try {
599
+ report("run_log_files_purged", "run_log_files/_purge", purgeOldRunLogFiles(retentionDays), "improve/index run log file(s)");
600
+ }
601
+ catch (err) {
602
+ warnings.push(`run log files purge failed: ${errMessage(err)}`);
603
+ }
591
604
  return { warnings };
592
605
  }
593
606
  /**
@@ -99,7 +99,6 @@ export function buildImproveExecutionPlan(input) {
99
99
  effective: { ...input.consolidation.effective },
100
100
  gates: {
101
101
  profile: { ...input.consolidation.gates.profile },
102
- minimumPool: { ...input.consolidation.gates.minimumPool },
103
102
  delta: { ...input.consolidation.gates.delta },
104
103
  },
105
104
  },
@@ -9,8 +9,8 @@
9
9
  * Candidate selection reads the improve ledger plus one set of signals: a ref
10
10
  * is eligible for a source when feedback newer than its last attempt landed and
11
11
  * no ledger window holds it, and reflect reads only negative feedback. Refs
12
- * without recent feedback can still be picked by the fallback lanes (proactive
13
- * maintenance, high salience), which only score them; the survivors are ranked
12
+ * without recent feedback can still be picked by the proactive-maintenance
13
+ * lane, which plans them with the rest; the survivors are ranked
14
14
  * by salience, checked on disk and capped. A plan-only run evaluates the same
15
15
  * selectors against read snapshots and writes nothing.
16
16
  */
@@ -35,7 +35,7 @@ import { isAutonomyLaneAllowed } from "./autonomy-gate.js";
35
35
  import { akmConsolidate, inspectConsolidationPool, loadExistingKnowledgeBodyHashes, makeConsolidateResult, } from "./consolidate.js";
36
36
  import { computeSafeChunkSize, DEFAULT_CONTEXT_LENGTH_TOKENS } from "./consolidate/chunking.js";
37
37
  import { contentHash } from "./content-hash.js";
38
- import { assetTypeOf, buildUtilityMap, dedupeRefs, findAssetFilePath, isDistillCandidateRef, isLessonCandidate, resolveImproveScope, withIndexDb, } from "./eligibility.js";
38
+ import { assetTypeOf, buildUtilityMap, dedupeRefs, findAssetFilePath, isDistillCandidateRef, isLessonCandidate, withIndexDb, } from "./eligibility.js";
39
39
  import { akmExtract, countNewExtractCandidates } from "./extract.js";
40
40
  import { computeValenceScore } from "./feedback-valence.js";
41
41
  import { isLedgerBlocked, lastAttemptByRef, ledgerRowFor, loadLedgerSnapshot, stateKey, } from "./ledger.js";
@@ -81,7 +81,7 @@ export function pickDefined(source, keys) {
81
81
  out[key] = source[key];
82
82
  return out;
83
83
  }
84
- export const CONSOLIDATION_CONFIG_KEYS = ["enabled", "minPoolSize", "limit", "maxChunkSize"];
84
+ export const CONSOLIDATION_CONFIG_KEYS = ["enabled", "limit", "maxChunkSize"];
85
85
  /** Emit an aggregate `improve_skipped` row (never one per ref). */
86
86
  export function recordImproveSkip(eventsCtx, ref, metadata) {
87
87
  appendEvent({ eventType: "improve_skipped", ref, metadata }, eventsCtx);
@@ -96,19 +96,13 @@ export function pushRecentError(recentErrors, originator, msg) {
96
96
  }
97
97
  // ── Consolidation ────────────────────────────────────────────────────────────
98
98
  /**
99
- * The consolidation gates and pool, with no model call: the profile toggle,
100
- * `minPoolSize` (not for a named strategy or ref scope, nor once the pool is
101
- * over the 100-memory volume trigger), and the ledger delta (every memory
102
- * judged recently and unchanged since means nothing to do).
99
+ * The consolidation gates and pool, with no model call: the profile toggle
100
+ * and the ledger delta (every memory judged recently and unchanged since
101
+ * means nothing to do).
103
102
  */
104
103
  function planConsolidationPass(args) {
105
- const { options, primaryStashDir, memorySummary, resolvedPlan } = args;
104
+ const { options, primaryStashDir, resolvedPlan } = args;
106
105
  const processConfig = args.improveProfile?.processes?.consolidate;
107
- const volumeTriggered = memorySummary.eligible > 100 && resolvedPlan.processes.consolidate.runner !== null;
108
- const minPoolSize = typeof processConfig?.minPoolSize === "number" ? processConfig.minPoolSize : 0;
109
- const eligiblePoolSize = typeof memorySummary.eligible === "number" ? memorySummary.eligible : 0;
110
- const userNamed = options.strategy !== undefined || resolveImproveScope(options.scope).mode === "ref";
111
- const poolBelowMinSize = !volumeTriggered && !userNamed && minPoolSize > 0 && eligiblePoolSize < minPoolSize;
112
106
  const pool = primaryStashDir
113
107
  ? inspectConsolidationPool({
114
108
  config: options.config,
@@ -127,18 +121,13 @@ function planConsolidationPass(args) {
127
121
  DEFAULT_CONTEXT_LENGTH_TOKENS, 500, processConfig?.maxChunkSize);
128
122
  const profilePassed = processConfig?.enabled !== false;
129
123
  const deltaPassed = pool.candidatePoolSize > 0 || pool.judgedUnchanged === 0;
130
- const wouldRun = profilePassed && !poolBelowMinSize && deltaPassed && pool.candidatePoolSize > 0;
131
- const belowMin = `pool ${eligiblePoolSize} is below minPoolSize ${minPoolSize}`;
124
+ const wouldRun = profilePassed && deltaPassed && pool.candidatePoolSize > 0;
132
125
  const unchanged = "every memory was judged recently and is unchanged since";
133
126
  return {
134
- poolBelowMinSize,
135
- eligiblePoolSize,
136
- minPoolSize,
137
127
  plan: {
138
128
  configured: pickDefined(processConfig, CONSOLIDATION_CONFIG_KEYS),
139
129
  effective: {
140
130
  enabled: profilePassed,
141
- minPoolSize,
142
131
  ...(processConfig?.limit !== undefined ? { limit: processConfig.limit } : {}),
143
132
  chunkSize,
144
133
  },
@@ -149,10 +138,6 @@ function planConsolidationPass(args) {
149
138
  passed: profilePassed,
150
139
  reason: profilePassed ? "consolidation enabled" : "disabled by improve profile",
151
140
  },
152
- minimumPool: {
153
- passed: !poolBelowMinSize,
154
- reason: poolBelowMinSize ? belowMin : `pool satisfies minPoolSize ${minPoolSize}`,
155
- },
156
141
  delta: {
157
142
  passed: deltaPassed,
158
143
  reason: !deltaPassed
@@ -165,13 +150,11 @@ function planConsolidationPass(args) {
165
150
  wouldRun,
166
151
  reason: !profilePassed
167
152
  ? "disabled by improve profile"
168
- : poolBelowMinSize
169
- ? belowMin
170
- : !deltaPassed
171
- ? unchanged
172
- : pool.candidatePoolSize === 0
173
- ? "candidate pool is empty after narrowing"
174
- : "all consolidation gates pass",
153
+ : !deltaPassed
154
+ ? unchanged
155
+ : pool.candidatePoolSize === 0
156
+ ? "candidate pool is empty after narrowing"
157
+ : "all consolidation gates pass",
175
158
  estimatedChunks: wouldRun ? Math.ceil(pool.candidatePoolSize / chunkSize) : 0,
176
159
  },
177
160
  };
@@ -186,14 +169,6 @@ async function runConsolidationPass(args) {
186
169
  if (!planned.plan.gates.profile.passed) {
187
170
  info("[improve] consolidation skipped (disabled by improve profile)");
188
171
  }
189
- else if (planned.poolBelowMinSize) {
190
- recordImproveSkip(eventsCtx, "memories/_consolidation", {
191
- reason: "pool_below_min_size",
192
- poolSize: planned.eligiblePoolSize,
193
- minPoolSize: planned.minPoolSize,
194
- });
195
- info(`[improve] consolidation skipped (pool ${planned.eligiblePoolSize} < minPoolSize ${planned.minPoolSize})`);
196
- }
197
172
  else if (!planned.plan.gates.delta.passed) {
198
173
  recordImproveSkip(eventsCtx, "memories/_consolidation", { reason: "consolidation_no_memory_updates" });
199
174
  info("[improve] consolidation skipped (every memory was judged recently and is unchanged)");
@@ -212,7 +187,6 @@ async function runConsolidationPass(args) {
212
187
  limit: processConfig?.limit,
213
188
  maxChunkSize: processConfig?.maxChunkSize,
214
189
  signal: args.budgetSignal,
215
- p90ChunkSecondsDefault: processConfig?.p90ChunkSecondsDefault,
216
190
  // Its read-only proposal lookups go through the run's own state.db handle.
217
191
  ...(eventsCtx?.db ? { proposalsCtx: { db: eventsCtx.db } } : {}),
218
192
  }));
@@ -671,7 +645,7 @@ export function buildSnapshotManifest(args) {
671
645
  * - distillOnlyRefs: only distill's passes (any signal, a positive or a note
672
646
  * included), on a distill candidate;
673
647
  * - noFeedbackPool: no recent feedback and no reflect window, left to the
674
- * fallback lanes, which only score them;
648
+ * proactive-maintenance lane;
675
649
  * - fullySkippedCount: feedback on record but nothing new, or a live window.
676
650
  * An explicit `--scope <ref>` bypasses every gate.
677
651
  */
@@ -722,12 +696,12 @@ export function partitionBySignalDelta(args) {
722
696
  return out;
723
697
  }
724
698
  /**
725
- * Pick the loop's refs: signal delta, the fallback lanes (unless
726
- * `--require-feedback-signal`; they score, never plan), lane attribution,
727
- * salience, the no-op-dampened ranking, the disk check and the limit.
699
+ * Pick the loop's refs: signal delta, the proactive-maintenance lane (unless
700
+ * `--require-feedback-signal`), lane attribution, salience, the no-op-dampened
701
+ * ranking, the disk check and the limit.
728
702
  */
729
703
  async function selectLoopCandidates(args, postCleanupRefs, validationFailureRefs, actions, persist) {
730
- const { scope, options, primaryStashDir, eventsCtx, improveProfile } = args;
704
+ const { scope, options, primaryStashDir, eventsCtx } = args;
731
705
  const snapshot = buildSnapshotManifest({
732
706
  postCleanupRefs,
733
707
  validationFailureRefs,
@@ -739,9 +713,8 @@ async function selectLoopCandidates(args, postCleanupRefs, validationFailureRefs
739
713
  const processableRefs = [...partition.eligibleRefs, ...partition.distillOnlyRefs];
740
714
  const signalFiltered = processableRefs.filter((c) => snapshot.feedback.get(c.ref)?.hasSignal === true);
741
715
  const signalBearingSet = new Set(signalFiltered.map((r) => r.ref));
742
- // The fallback lanes (proactive, high salience) have no usage evidence of
743
- // their own: they pick only what retrieval returned or new material improve
744
- // never processed (#986). Evaluated once per candidate.
716
+ // The proactive lane has no usage evidence of its own: it picks only what
717
+ // retrieval returned or new material improve never processed (#986). Evaluated once per candidate.
745
718
  const fallbackEligible = postCleanupRefs.filter((c) => !validationFailureRefs.has(c.ref));
746
719
  const allowFallbacks = options.requireFeedbackSignal !== true;
747
720
  const retrievalScope = scope.mode === "ref" || !allowFallbacks
@@ -753,22 +726,20 @@ async function selectLoopCandidates(args, postCleanupRefs, validationFailureRefs
753
726
  ...partition.noFeedbackPool,
754
727
  ]);
755
728
  const noFeedbackCandidates = noFeedbackPool.filter((r) => !unscoped.has(r.ref));
756
- // Only a ref no fallback lane may pick anymore is charged to the retrieval gate.
729
+ // Only a ref the proactive lane may not pick is charged to the retrieval gate.
757
730
  const outOfScope = new Set(noFeedbackPool.filter((r) => unscoped.has(r.ref)).map((r) => r.ref));
758
731
  const retrieval = fetchRetrievalSignals(options, signalFiltered, noFeedbackCandidates, eventsCtx, persist);
759
732
  const proactive = allowFallbacks
760
733
  ? selectProactiveMaintenanceLane(args, noFeedbackCandidates, snapshot, retrieval, persist)
761
734
  : { proactiveRefs: [] };
762
- const highSalienceRefs = allowFallbacks
763
- ? selectHighSalienceLane(options, improveProfile, eventsCtx, noFeedbackCandidates.filter((r) => !proactive.proactiveRefs.some((p) => p.ref === r.ref)), snapshot.lastReflectAttemptAt, persist)
764
- : [];
765
- // An explicit ref scope always acts on its ref; otherwise only feedback plans the loop. The fallback lanes'
766
- // picks are scored with it, never planned: a rewrite needs negative feedback.
767
- const signalAndRetrievalRefs = dedupeRefs([...signalFiltered, ...proactive.proactiveRefs, ...highSalienceRefs]);
768
- const mergedRefs = scope.mode === "ref" ? processableRefs : signalFiltered;
769
- const scoredRefs = scope.mode === "ref" ? processableRefs : signalAndRetrievalRefs;
770
- // Lane attribution: signal-delta, and an explicit ref scope over it.
735
+ // Planned: signal-delta refs plus the proactive lane's picks (whole-stash / type scope); an explicit ref scope
736
+ // acts on its own refs.
737
+ const mergedRefs = scope.mode === "ref" ? processableRefs : dedupeRefs([...signalFiltered, ...proactive.proactiveRefs]);
738
+ // Lane attribution, weakest first so the strongest wins: proactive < signal-delta, and an explicit ref scope
739
+ // over everything.
771
740
  const sourceByRef = new Map();
741
+ for (const r of proactive.proactiveRefs)
742
+ sourceByRef.set(r.ref, "proactive");
772
743
  for (const r of signalFiltered)
773
744
  sourceByRef.set(r.ref, "signal-delta");
774
745
  if (scope.mode === "ref")
@@ -776,7 +747,7 @@ async function selectLoopCandidates(args, postCleanupRefs, validationFailureRefs
776
747
  sourceByRef.set(r.ref, "scope");
777
748
  for (const r of mergedRefs)
778
749
  r.eligibilitySource = sourceByRef.get(r.ref) ?? "unknown";
779
- const salienceMap = scoreSalience(args, scoredRefs, snapshot.feedback, retrieval.retrievalCounts, persist);
750
+ const salienceMap = scoreSalience(args, mergedRefs, snapshot.feedback, retrieval.retrievalCounts, persist);
780
751
  // Rank by salience; a ref skipped as a no-op repeatedly sorts lower (its stored rank is untouched).
781
752
  const noOps = new Map();
782
753
  withRunState(eventsCtx, persist, (db) => {
@@ -795,8 +766,8 @@ async function selectLoopCandidates(args, postCleanupRefs, validationFailureRefs
795
766
  distillOnlyRefs: partition.distillOnlyRefs,
796
767
  limit: options.limit,
797
768
  });
798
- if (signalAndRetrievalRefs.length > 0) {
799
- info(`[improve] ${signalAndRetrievalRefs.length} refs with usage signals (${signalFiltered.length} feedback)`);
769
+ if (mergedRefs.length > 0) {
770
+ info(`[improve] ${mergedRefs.length} refs with usage signals (${signalFiltered.length} feedback)`);
800
771
  }
801
772
  if (validationFailureRefs.size > 0)
802
773
  info(`[improve] ${validationFailureRefs.size} with validation failures excluded`);
@@ -883,11 +854,11 @@ function fetchRetrievalSignals(options, signalFiltered, noFeedbackCandidates, ev
883
854
  return out;
884
855
  }
885
856
  /**
886
- * Proactive maintenance (default off, whole-stash/type runs): pick stable
887
- * assets due for a revisit. The picks are scored and never planned: improve
888
- * does not rewrite on a proactive cadence. The due gate doubles as the
889
- * rotation cooldown: a freshly reflected asset waits `dueDays` before it is
890
- * picked again.
857
+ * Proactive maintenance (default on, whole-stash/type runs): pick stable
858
+ * assets due for a revisit and plan them with the feedback-bearing refs. The
859
+ * cap against a proposal flood: `maxPerRun` limits the picks per run, the due
860
+ * gate admits only an asset not reflected or distilled for `dueDays` (so each
861
+ * comes up at most once per `dueDays`), and reflect's `limit` bounds the run.
891
862
  */
892
863
  function selectProactiveMaintenanceLane(args, candidates, snapshot, retrieval, persist) {
893
864
  if (args.scope.mode === "ref" || !args.resolvedPlan.processes.proactiveMaintenance.enabled) {
@@ -895,7 +866,7 @@ function selectProactiveMaintenanceLane(args, candidates, snapshot, retrieval, p
895
866
  }
896
867
  const pmCfg = args.improveProfile.processes?.proactiveMaintenance;
897
868
  const dueDays = pmCfg?.dueDays ?? DEFAULT_DUE_DAYS;
898
- const maxPerRun = pmCfg?.maxPerRun ?? pmCfg?.limit ?? DEFAULT_MAX_PER_RUN;
869
+ const maxPerRun = pmCfg?.maxPerRun ?? DEFAULT_MAX_PER_RUN;
899
870
  const selection = selectProactiveMaintenanceRefs({
900
871
  candidates,
901
872
  lastReflectTs: snapshot.lastReflectAttemptAt,
@@ -927,7 +898,7 @@ function selectProactiveMaintenanceLane(args, candidates, snapshot, retrieval, p
927
898
  proactiveRefs: selection.selected,
928
899
  proactiveMaintenanceSummary: { ...summary, selectedRefs },
929
900
  proactivePlan: {
930
- configured: pickDefined(pmCfg, ["dueDays", "maxPerRun", "limit"]),
901
+ configured: pickDefined(pmCfg, ["dueDays", "maxPerRun"]),
931
902
  effective: { dueDays, maxPerRun },
932
903
  candidatePool: candidates.length,
933
904
  ...summary,
@@ -935,41 +906,13 @@ function selectProactiveMaintenanceLane(args, candidates, snapshot, retrieval, p
935
906
  },
936
907
  };
937
908
  }
938
- /**
939
- * High salience: zero-feedback refs whose content-derived encoding score (not
940
- * a per-type stub) reaches `salienceThreshold` and that were never reflected,
941
- * top-N by score, capped at 10% of the effective limit. The picks are scored,
942
- * never planned.
943
- */
944
- function selectHighSalienceLane(options, improveProfile, eventsCtx, candidates, lastReflectAttemptAt, persist) {
945
- const threshold = (options.config ?? loadConfig()).improve?.salience?.salienceThreshold ?? 0.75;
946
- const effectiveLimit = options.limit ?? improveProfile?.processes?.reflect?.limit ?? improveProfile.limit ?? 10;
947
- const selected = withRunState(eventsCtx, persist, (db) => candidates
948
- .flatMap((r) => {
949
- const row = getAssetSalience(db, keyOf(r));
950
- return row &&
951
- isContentEncodingRow(row) &&
952
- row.encoding_salience >= threshold &&
953
- !lastReflectAttemptAt.has(r.ref)
954
- ? [{ ref: r, score: row.encoding_salience }]
955
- : [];
956
- })
957
- .sort((a, b) => b.score - a.score)
958
- .slice(0, Math.max(1, Math.floor(effectiveLimit * 0.1)))
959
- .map((q) => q.ref)) ?? [];
960
- if (selected.length > 0) {
961
- info(`[improve] high-salience lane admitted ${selected.length} content-scored ref(s) ` +
962
- `(threshold=${threshold}, requires content-derived encoding_source)`);
963
- }
964
- return selected;
965
- }
966
909
  /**
967
910
  * Score the merged refs: update `asset_outcome` (projected on a plan-only
968
911
  * run), compute each salience vector (keeping a stored content-derived
969
912
  * encoding score), then persist it.
970
913
  */
971
914
  function scoreSalience(args, mergedRefs, feedback, retrievalCounts, persist) {
972
- const { options, eventsCtx } = args;
915
+ const { eventsCtx } = args;
973
916
  const utilityMap = buildUtilityMap(mergedRefs, !persist);
974
917
  const lastUseMsByRef = withIndexDb(!persist, (db) => getLastUseMsByRef(db, mergedRefs)) ?? new Map();
975
918
  const outcomeSalience = updateOutcomeScores({
@@ -982,7 +925,6 @@ function scoreSalience(args, mergedRefs, feedback, retrievalCounts, persist) {
982
925
  eventsCtx,
983
926
  persist,
984
927
  });
985
- const outcomeWeightEnabled = (options.config ?? loadConfig()).improve?.salience?.outcomeWeightEnabled !== false;
986
928
  const storedEncoding = new Map();
987
929
  withRunState(eventsCtx, persist, (db) => {
988
930
  for (const r of mergedRefs) {
@@ -1005,7 +947,6 @@ function scoreSalience(args, mergedRefs, feedback, retrievalCounts, persist) {
1005
947
  outcomeSalience: outcomeSalience.get(r.ref),
1006
948
  sizeBytes: fileSize(r.filePath),
1007
949
  now,
1008
- outcomeWeightEnabled,
1009
950
  }));
1010
951
  }
1011
952
  if (persist) {
@@ -6,8 +6,8 @@ import { computeSalience } from "./salience.js";
6
6
  const DAY_MS = 86_400_000;
7
7
  /** An asset is due when last reflected/distilled more than this many days ago (or never). */
8
8
  export const DEFAULT_DUE_DAYS = 30;
9
- /** Default bound on how many assets the selector surfaces per run. */
10
- export const DEFAULT_MAX_PER_RUN = 25;
9
+ /** Fallback for `maxPerRun`; the same as the shipped `default` strategy. */
10
+ export const DEFAULT_MAX_PER_RUN = 15;
11
11
  /** Size floor for the cost term, so tiny files don't divide by ~0. */
12
12
  const SIZE_FLOOR_BYTES = 200;
13
13
  /**