akm-cli 0.9.31 → 0.10.26101001-alpha

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 (234) hide show
  1. package/CHANGELOG.md +253 -0
  2. package/STABILITY.md +79 -53
  3. package/dist/api-node.mjs +20 -0
  4. package/dist/api.d.ts +23 -0
  5. package/dist/api.js +45 -0
  6. package/dist/assets/hints/cli-hints-full.md +13 -27
  7. package/dist/assets/hints/cli-hints-short.md +1 -1
  8. package/dist/assets/improve-strategies/default.json +3 -3
  9. package/dist/assets/prompts/consolidate-pair.md +9 -7
  10. package/dist/cli/shared.js +31 -48
  11. package/dist/cli/unknown-flags.js +6 -43
  12. package/dist/cli.js +8 -34
  13. package/dist/commands/agent/contribute-cli.js +1 -1
  14. package/dist/commands/completions.js +1 -2
  15. package/dist/commands/config-cli.js +5 -28
  16. package/dist/commands/env/env-cli.js +5 -5
  17. package/dist/commands/env/secret-cli.js +2 -2
  18. package/dist/commands/health/checks.js +41 -16
  19. package/dist/commands/health/plugin-staleness.js +52 -22
  20. package/dist/commands/improve/autonomy-gate.js +5 -3
  21. package/dist/commands/improve/consolidate/pair-pass.js +7 -1
  22. package/dist/commands/improve/consolidate.js +6 -35
  23. package/dist/commands/improve/distill/lesson-update.js +91 -0
  24. package/dist/commands/improve/distill-guards.js +1 -43
  25. package/dist/commands/improve/distill.js +140 -20
  26. package/dist/commands/improve/extract-cli.js +1 -1
  27. package/dist/commands/improve/improve-cli.js +87 -102
  28. package/dist/commands/improve/improve-strategies.js +8 -12
  29. package/dist/commands/improve/loop-stages.js +0 -1
  30. package/dist/commands/improve/planner.js +0 -1
  31. package/dist/commands/improve/preparation.js +40 -99
  32. package/dist/commands/improve/proactive-maintenance.js +2 -2
  33. package/dist/commands/improve/reflect-noise.js +3 -55
  34. package/dist/commands/improve/reflect.js +3 -8
  35. package/dist/commands/improve/retrieval-scope.js +2 -2
  36. package/dist/commands/improve/salience.js +2 -9
  37. package/dist/commands/improve/stage.js +14 -9
  38. package/dist/commands/lint/index.js +5 -20
  39. package/dist/commands/observability-cli.js +3 -9
  40. package/dist/commands/proposal/drain.js +39 -6
  41. package/dist/commands/proposal/proposal-cli.js +10 -30
  42. package/dist/commands/proposal/repository.js +3 -3
  43. package/dist/commands/read/knowledge.js +3 -3
  44. package/dist/commands/read/remember-cli.js +0 -13
  45. package/dist/commands/read/search-cli.js +29 -97
  46. package/dist/commands/read/search.js +0 -11
  47. package/dist/commands/read/show.js +0 -19
  48. package/dist/commands/sources/plugin-upgrade.js +164 -101
  49. package/dist/commands/sources/sources-cli.js +1 -15
  50. package/dist/commands/sources/stash-cli.js +4 -12
  51. package/dist/commands/tasks/tasks-cli.js +4 -115
  52. package/dist/commands/workflow/plan.js +11 -33
  53. package/dist/commands/workflow-cli.js +2 -7
  54. package/dist/core/adapter/adapter-ids.js +1 -2
  55. package/dist/core/adapter/adapters/agent-skills-adapter.js +0 -4
  56. package/dist/core/adapter/adapters/akm-adapter.js +9 -48
  57. package/dist/core/adapter/adapters/akm-lint.js +10 -26
  58. package/dist/core/adapter/adapters/akm-metadata.js +2 -72
  59. package/dist/core/adapter/adapters/akm-task-adapter.js +0 -5
  60. package/dist/core/adapter/adapters/akm-workflow-adapter.js +9 -28
  61. package/dist/core/adapter/adapters/dotenv-adapter.js +1 -20
  62. package/dist/core/adapter/adapters/generic-files-adapter.js +0 -10
  63. package/dist/core/adapter/adapters/llm-wiki-adapter.js +0 -4
  64. package/dist/core/adapter/adapters/tool-dir-shared.js +0 -24
  65. package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -4
  66. package/dist/core/adapter/recognize-match.js +3 -4
  67. package/dist/core/common.js +18 -2
  68. package/dist/core/config/config-schema.js +12 -15
  69. package/dist/core/config/config-types.js +6 -15
  70. package/dist/core/config/config-walker.js +6 -23
  71. package/dist/core/config/config.js +17 -80
  72. package/dist/core/config/engine-semantics.js +7 -3
  73. package/dist/core/config/schema/engines.js +7 -7
  74. package/dist/core/config/schema/improve-processes.js +8 -61
  75. package/dist/core/config/schema/improve.js +2 -21
  76. package/dist/core/config/schema/index-config.js +6 -39
  77. package/dist/core/env-secret-ref.js +2 -45
  78. package/dist/core/errors.js +1 -2
  79. package/dist/core/extra-params.js +2 -86
  80. package/dist/core/improve-result.js +11 -1
  81. package/dist/core/mutation-target.js +2 -2
  82. package/dist/core/recognition-util.js +4 -5
  83. package/dist/core/warn.js +21 -4
  84. package/dist/core/write-source.js +3 -3
  85. package/dist/execution/target-ref.js +1 -2
  86. package/dist/indexer/search/db-search.js +4 -19
  87. package/dist/indexer/search/fts-query.js +0 -19
  88. package/dist/integrations/agent/engine-resolution.js +5 -2
  89. package/dist/integrations/agent/index.js +1 -1
  90. package/dist/integrations/agent/profiles.js +41 -98
  91. package/dist/integrations/agent/request-lowering.js +3 -3
  92. package/dist/integrations/harnesses/aider/index.js +5 -0
  93. package/dist/integrations/harnesses/amazonq/index.js +1 -0
  94. package/dist/integrations/harnesses/claude/config-import.js +2 -3
  95. package/dist/integrations/harnesses/claude/index.js +5 -0
  96. package/dist/integrations/harnesses/codex/index.js +1 -0
  97. package/dist/integrations/harnesses/copilot/index.js +1 -0
  98. package/dist/integrations/harnesses/gemini/index.js +1 -0
  99. package/dist/integrations/harnesses/index.js +18 -39
  100. package/dist/integrations/harnesses/opencode/agent-builder.js +60 -35
  101. package/dist/integrations/harnesses/opencode/config-import.js +121 -52
  102. package/dist/integrations/harnesses/opencode/index.js +22 -0
  103. package/dist/integrations/harnesses/opencode/plugin-layout.js +68 -0
  104. package/dist/integrations/harnesses/opencode/session-log-types.js +12 -0
  105. package/dist/integrations/harnesses/opencode/session-log-v1.js +72 -0
  106. package/dist/integrations/harnesses/opencode/session-log-v2.js +140 -0
  107. package/dist/integrations/harnesses/opencode/session-log.js +104 -115
  108. package/dist/integrations/harnesses/opencode/version.js +98 -0
  109. package/dist/integrations/harnesses/opencode-sdk/{harness.js → index.js} +5 -17
  110. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +105 -206
  111. package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +199 -0
  112. package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +228 -0
  113. package/dist/integrations/harnesses/opencode-sdk/wire.js +66 -0
  114. package/dist/integrations/harnesses/openhands/index.js +1 -0
  115. package/dist/integrations/harnesses/pi/index.js +1 -0
  116. package/dist/integrations/harnesses/shared.js +2 -0
  117. package/dist/integrations/harnesses/types.js +2 -0
  118. package/dist/llm/client.js +41 -11
  119. package/dist/output/cli-hints.js +1 -1
  120. package/dist/output/context.js +10 -19
  121. package/dist/output/format-exempt.js +5 -8
  122. package/dist/output/shapes/helpers.js +1 -22
  123. package/dist/output/shapes/passthrough.js +0 -1
  124. package/dist/output/shapes.js +3 -31
  125. package/dist/output/stdout.js +5 -1
  126. package/dist/output/text/command-format.js +6 -1
  127. package/dist/output/text/workflow-format.js +4 -22
  128. package/dist/scripts/akm-migrate-node.js +13049 -14013
  129. package/dist/scripts/akm-migrate.js +16316 -17276
  130. package/dist/setup/detect.js +10 -4
  131. package/dist/setup/harness-config-import.js +5 -14
  132. package/dist/setup/setup.js +1 -1
  133. package/dist/setup/steps/tasks.js +12 -13
  134. package/dist/storage/repositories/task-history-repository.js +0 -5
  135. package/dist/storage/repositories/workflow-runs-repository.js +5 -15
  136. package/dist/tasks/embedded.js +2 -1
  137. package/dist/tasks/run/task-history.js +0 -2
  138. package/dist/tasks/schedule-gates.js +39 -0
  139. package/dist/tasks/scheduler-binding.js +0 -16
  140. package/dist/tasks/scheduler-sync.js +3 -97
  141. package/dist/tasks/source/bounded-document.js +1 -1
  142. package/dist/tasks/source/task-source-v4.js +2 -12
  143. package/dist/tasks/task-run-reserved-flags.js +2 -31
  144. package/dist/workflows/authoring/authoring.js +6 -6
  145. package/dist/workflows/compile.js +8 -65
  146. package/dist/workflows/exec/child-workflow.js +22 -3
  147. package/dist/workflows/exec/native-executor.js +12 -147
  148. package/dist/workflows/exec/run-workflow.js +31 -103
  149. package/dist/workflows/exec/step-work.js +9 -178
  150. package/dist/workflows/exec/unit-dispatch.js +0 -10
  151. package/dist/workflows/freeze/environment.js +3 -44
  152. package/dist/workflows/freeze/freeze.js +8 -41
  153. package/dist/workflows/freeze/targets/child-workflow.js +27 -63
  154. package/dist/workflows/freeze/targets/command.js +2 -16
  155. package/dist/workflows/freeze/targets/shell.js +0 -2
  156. package/dist/workflows/freeze/task-bindings.js +2 -28
  157. package/dist/workflows/ir/params.js +12 -2
  158. package/dist/workflows/parser.js +82 -232
  159. package/dist/workflows/plan.js +1 -1
  160. package/dist/workflows/renderer.js +10 -19
  161. package/dist/workflows/runtime/run-plan.js +11 -53
  162. package/dist/workflows/runtime/runs.js +4 -27
  163. package/dist/workflows/source-files.js +12 -16
  164. package/dist/workflows/source-semantics.js +1 -93
  165. package/docs/README.md +1 -1
  166. package/docs/agents/README.md +3 -3
  167. package/docs/agents/agent-install.md +1 -1
  168. package/docs/architecture/adapters.md +17 -31
  169. package/docs/architecture/architecture.md +4 -5
  170. package/docs/architecture/improvement.md +52 -21
  171. package/docs/architecture/internals/improve-workflow.md +15 -8
  172. package/docs/architecture/internals/indexing.md +1 -1
  173. package/docs/architecture/internals/search.md +1 -2
  174. package/docs/architecture/internals/storage-locations.md +5 -5
  175. package/docs/architecture/persisted-data-compat.md +13 -4
  176. package/docs/architecture/specs/0.9.0-decisions.md +6 -2
  177. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +2 -2
  178. package/docs/architecture/specs/workflow-format-unification.md +1 -6
  179. package/docs/architecture/testing/manual-testing-checklist.md +20 -29
  180. package/docs/architecture/testing/task-workflow-manual-tests.md +106 -203
  181. package/docs/architecture/testing/testing-workflow.md +1 -1
  182. package/docs/architecture/workflow-engine.md +5 -56
  183. package/docs/guides/author-workflows.md +39 -69
  184. package/docs/guides/capture-knowledge.md +1 -1
  185. package/docs/guides/claude-code-vs-akm-workflows.md +1 -2
  186. package/docs/guides/discover-and-load.md +4 -4
  187. package/docs/guides/getting-started.md +1 -1
  188. package/docs/guides/improve-the-library.md +7 -7
  189. package/docs/guides/recipes/headless-install.md +2 -2
  190. package/docs/guides/run-workflows.md +1 -1
  191. package/docs/guides/use-with-any-agent.md +49 -4
  192. package/docs/integration/bundling-akm.md +7 -6
  193. package/docs/maintainers/curate-workmap.md +1 -2
  194. package/docs/maintainers/release-checklist.md +30 -1
  195. package/docs/posts/akm-command-tour.md +3 -3
  196. package/docs/product-surface.md +1 -1
  197. package/docs/reference/README.md +1 -0
  198. package/docs/reference/api.md +65 -0
  199. package/docs/reference/asset-types.md +3 -5
  200. package/docs/reference/bundle-types.md +2 -4
  201. package/docs/reference/cli.md +126 -171
  202. package/docs/reference/configuration.md +84 -19
  203. package/docs/reference/data-and-telemetry.md +1 -1
  204. package/docs/reference/env-and-secrets.md +2 -2
  205. package/docs/reference/supported-formats.md +3 -4
  206. package/docs/reference/tasks.md +12 -19
  207. package/docs/reference/website-sources.md +1 -1
  208. package/docs/reference/workflow-schema.md +89 -317
  209. package/docs/reference/workflows.md +20 -48
  210. package/package.json +12 -2
  211. package/schemas/akm-config.json +2 -243
  212. package/schemas/akm-task.json +2 -3
  213. package/schemas/akm-workflow.json +47 -84
  214. package/dist/assets/improve-strategies/catchup.json +0 -41
  215. package/dist/assets/improve-strategies/proactive-maintenance.json +0 -24
  216. package/dist/assets/improve-strategies/quick.json +0 -17
  217. package/dist/assets/improve-strategies/reflect-distill.json +0 -29
  218. package/dist/assets/improve-strategies/thorough.json +0 -49
  219. package/dist/assets/tasks/improve/akm-improve-catchup.yml +0 -6
  220. package/dist/assets/tasks/improve/akm-improve-frequent.yml +0 -4
  221. package/dist/assets/tasks/improve/akm-improve-nightly.yml +0 -4
  222. package/dist/cli/retired-commands.js +0 -118
  223. package/dist/commands/tasks/validate.js +0 -176
  224. package/dist/core/config/legacy-source-shape-shim.js +0 -117
  225. package/dist/integrations/harnesses/ids.js +0 -28
  226. package/dist/tasks/source/task-source-v3-frozen.js +0 -424
  227. package/dist/tasks/source/task-to-v4.js +0 -863
  228. package/dist/workflows/exec/worktree.js +0 -372
  229. package/dist/workflows/freeze/child-output-references.js +0 -83
  230. package/dist/workflows/freeze/identity.js +0 -22
  231. package/dist/workflows/freeze/targets/script.js +0 -50
  232. package/dist/workflows/freeze/targets/task.js +0 -124
  233. package/dist/workflows/github-yaml.js +0 -506
  234. package/dist/workflows/runtime/run-outputs.js +0 -80
@@ -40,15 +40,15 @@ import { getAllEntries } from "../../storage/repositories/index-entries-reposito
40
40
  import { listProposals } from "../proposal/repository.js";
41
41
  import { detectDoubleFrontmatter, isValidDescription } from "../proposal/validators/proposal-quality-validators.js";
42
42
  import { akmSearch } from "../read/search.js";
43
- import { stripFrontmatterBody } from "./content-hash.js";
44
43
  import { autoRepairLessonFrontmatter, autoSwapDescriptionWhenToUse, collectLessonQualityFindings, repairLessonDescriptionTruncation, } from "./distill/content-repair.js";
45
- import { buildClsContext, checkDistillFidelity, DEFAULT_CLS_ADJACENT_COUNT } from "./distill-guards.js";
44
+ import { buildLessonUpdatePrompt, DISTILL_LESSON_UPDATE_JSON_SCHEMA, diffLessonBody, parseLessonUpdate, } from "./distill/lesson-update.js";
45
+ import { buildClsContext, DEFAULT_CLS_ADJACENT_COUNT } from "./distill-guards.js";
46
46
  import { assessMemoryKnowledgePromotionCandidate, deriveKnowledgeRef } from "./distill-promotion-policy.js";
47
47
  import { buildRefVocabulary, scoreEncodingSalience } from "./encoding-salience.js";
48
48
  import { resolveImproveStrategy, resolveProcessEnabled } from "./improve-strategies.js";
49
49
  import { recordLedgerAttempt } from "./ledger.js";
50
50
  import { computeSalience, upsertAssetSalience } from "./salience.js";
51
- import { callStage, mintProposal, noticeSet, rejectedProposalContext, resolveQualityGateJudge, runLessonQualityJudge, stageRunner, } from "./stage.js";
51
+ import { callStage, LESSON_REJECT_MAX_SCORE, mintProposal, noticeSet, rejectedProposalContext, resolveQualityGateJudge, runLessonQualityJudge, stageRunner, } from "./stage.js";
52
52
  /**
53
53
  * Input types distill structurally refuses: a lesson is the distilled form
54
54
  * (distilling one would mint `lessons/lesson-…-lesson`), and env/secret bytes
@@ -361,7 +361,6 @@ export async function akmDistill(options) {
361
361
  eligMeta,
362
362
  asset,
363
363
  vocabulary: loadRefVocabulary(),
364
- outcomeWeightEnabled: config.improve?.salience?.outcomeWeightEnabled !== false,
365
364
  related: options.fetchRelatedFn ?? fetchRelatedAssets,
366
365
  lookup,
367
366
  };
@@ -436,6 +435,12 @@ async function distill(run, targetKind, kind, outputRef, feedbackEvents) {
436
435
  }
437
436
  const none = answeredNone(call.raw);
438
437
  if (none) {
438
+ // The writer may have answered NONE because a lesson already states the rule (the related list says to).
439
+ if (kind === "lesson") {
440
+ const update = await proposeLessonUpdate(run, feedbackLines(feedback), none.reason);
441
+ if (update)
442
+ return update;
443
+ }
439
444
  return skipDistill(run, outputRef, kind, "nothing_reusable", `The writer found no lesson in ${run.inputRef}${none.reason ? `: ${none.reason}` : "."}`);
440
445
  }
441
446
  const assembled = assembleDistilledContent(run, call.raw, kind, outputRef);
@@ -537,6 +542,13 @@ async function judgeAndQueue(run, out) {
537
542
  onNotices: run.notices.add,
538
543
  });
539
544
  if (!verdict.pass) {
545
+ if (out.kind === "lesson" &&
546
+ !out.promotion &&
547
+ (verdict.criteria?.nonRedundancy ?? 5) <= LESSON_REJECT_MAX_SCORE) {
548
+ const update = await proposeLessonUpdate(run, out.feedback ?? [], verdict.reason, related);
549
+ if (update)
550
+ return update;
551
+ }
540
552
  return rejectDistilled(run, out.ref, content, verdict.score, verdict.reason, {
541
553
  ...(verdict.reviewNeeded ? { reviewNeeded: true } : {}),
542
554
  ...(verdict.criteria ? { criteria: verdict.criteria } : {}),
@@ -553,19 +565,6 @@ async function judgeAndQueue(run, out) {
553
565
  frontmatter = data;
554
566
  }
555
567
  else {
556
- // Optional check against the cited source; a contradiction goes to a human.
557
- const fidelity = getImproveProcessConfig("distill", run.profile)?.fidelityCheck ?? {};
558
- if (fidelity.enabled && out.source) {
559
- try {
560
- const verdict = checkDistillFidelity(stripFrontmatterBody(content), [stripFrontmatterBody(out.source)], fidelity);
561
- if (verdict.contradictionDetected) {
562
- return rejectDistilled(run, out.ref, content, 2.0, verdict.reason ?? "Proposal may contradict cited source memories.", { reviewNeeded: true, fidelityContradiction: true });
563
- }
564
- }
565
- catch {
566
- // The fidelity check is supplemental.
567
- }
568
- }
569
568
  // Canonical provenance goes into the content promotion writes.
570
569
  const parsed = parseFrontmatter(content);
571
570
  const xrefs = Array.isArray(parsed.data.xrefs) ? parsed.data.xrefs.map(String) : [];
@@ -622,6 +621,129 @@ async function judgeAndQueue(run, out) {
622
621
  ...swapped,
623
622
  };
624
623
  }
624
+ /**
625
+ * A memory whose lesson repeats a lesson the library holds extends that lesson instead (#1090): the writer returns
626
+ * the lesson's body with the memory's new lines added, and the update is proposed on the lesson's own ref, for a
627
+ * person to review (never staged for the drain). `finding` is what the writer (its NONE reason) or the judge said
628
+ * about the repeat: the related lessons it names are the candidates, or the only related lesson when it names none,
629
+ * so a lesson that merely sits among several near the memory costs no call. Nothing is proposed, and `undefined`
630
+ * returned, when no lesson qualifies, the writer finds the memory adds
631
+ * nothing or contradicts the lesson, the body drops or rewords a line, the judge does not pass the extended lesson,
632
+ * or the lesson changed meanwhile. Needs the quality gate: the judge is what holds the added lines to the memory.
633
+ */
634
+ async function proposeLessonUpdate(run, feedback, finding, related) {
635
+ const memory = run.asset.content ? parseFrontmatter(run.asset.content).content.trim() : "";
636
+ const said = finding.toLowerCase();
637
+ if (!run.runner || !qualityGateEnabled(run) || !memory)
638
+ return undefined;
639
+ const lessons = [];
640
+ for (const asset of related ?? (await run.related(memory.slice(0, 500), RELATED_COUNT))) {
641
+ const parsed = parseRefInput(asset.ref);
642
+ if (parsed.type !== "lesson" || !asset.path || !isWithin(asset.path, run.stash))
643
+ continue;
644
+ try {
645
+ const content = fs.readFileSync(asset.path, "utf8");
646
+ const ref = conceptIdFromTypeName("lesson", parsed.name);
647
+ lessons.push({ ref, path: asset.path, content, body: parseFrontmatter(content).content.trim() });
648
+ }
649
+ catch {
650
+ // A lesson that cannot be read cannot be extended.
651
+ }
652
+ }
653
+ const named = lessons.filter((l) => said.includes(l.ref.toLowerCase()) || said.includes(l.ref.split("/").slice(1).join("/").toLowerCase()));
654
+ const candidates = named.length > 0 ? named : lessons.length === 1 ? lessons : [];
655
+ if (candidates.length === 0)
656
+ return undefined;
657
+ const call = await callStage({
658
+ feature: "distill",
659
+ runner: run.runner,
660
+ system: "Return only valid JSON. No prose.",
661
+ prompt: buildLessonUpdatePrompt(memory, feedback, candidates),
662
+ gate: { config: run.config, enabled: true },
663
+ request: {
664
+ ...(run.options.chat === undefined
665
+ ? { responseSchema: DISTILL_LESSON_UPDATE_JSON_SCHEMA }
666
+ : { chat: run.options.chat }),
667
+ ...(run.options.signal ? { signal: run.options.signal } : {}),
668
+ },
669
+ onNotices: run.notices.add,
670
+ });
671
+ const update = call.ok ? parseLessonUpdate(call.raw, candidates) : null;
672
+ if (!update)
673
+ return undefined;
674
+ const target = update.candidate;
675
+ const { dropped, added } = diffLessonBody(target.body, update.body);
676
+ if (dropped.length > 0) {
677
+ warnVerbose(`[akm] distill update of ${target.ref} dropped or reworded ${dropped.length} line(s); not proposed`);
678
+ return undefined;
679
+ }
680
+ if (added.length === 0)
681
+ return undefined;
682
+ // An edit is judged as the lesson it makes: the existing lesson with the lines added, as one lesson (reusable,
683
+ // grounded in the memory or the lesson), whose added lines must each say something the lesson did not (one call).
684
+ const extended = assembleAsset(parseFrontmatter(target.content).data, update.body);
685
+ const verdict = await runLessonQualityJudge(run.config, extended, memory, run.options.chat, {
686
+ extending: target.body,
687
+ ...(feedback.length > 0 ? { feedback } : {}),
688
+ ...((run.judgeRunner ?? run.runner) ? { llmRunner: run.judgeRunner ?? run.runner } : {}),
689
+ ...(run.options.signal ? { signal: run.options.signal } : {}),
690
+ onNotices: run.notices.add,
691
+ });
692
+ if (!verdict.pass) {
693
+ warnVerbose(`[akm] distill update of ${target.ref} not proposed: ${verdict.reason}`);
694
+ return undefined;
695
+ }
696
+ // The proposal's before-hash is taken at mint: a lesson edited since it was read is not what the writer extended.
697
+ let proposal;
698
+ try {
699
+ if (fs.readFileSync(target.path, "utf8") !== target.content)
700
+ return undefined;
701
+ const existing = parseFrontmatter(target.content);
702
+ const xrefs = Array.isArray(existing.data.xrefs) ? existing.data.xrefs.map(String) : [];
703
+ const frontmatter = { ...existing.data, xrefs: [...new Set([...xrefs, run.inputRef])] };
704
+ proposal = mintProposal(run.stash, run.options.ctx, {
705
+ ref: target.ref,
706
+ source: "distill",
707
+ ...(run.options.sourceRun !== undefined ? { sourceRun: run.options.sourceRun } : {}),
708
+ payload: { content: assembleAsset(frontmatter, update.body), frontmatter },
709
+ ...(verdict.score > 0 ? { confidence: verdict.score / 5 } : {}),
710
+ ...(run.options.eligibilitySource ? { eligibilitySource: run.options.eligibilitySource } : {}),
711
+ attemptedRefs: [run.ledgerRef],
712
+ }, {
713
+ review: {
714
+ reason: "distill-update",
715
+ gate: "quality-gate",
716
+ ...(verdict.criteria ? { scores: verdict.criteria } : {}),
717
+ judgeReason: verdict.reason,
718
+ },
719
+ });
720
+ }
721
+ catch (error) {
722
+ warnVerbose(`[akm] distill update of ${target.ref} not proposed: ${error instanceof Error ? error.message : error}`);
723
+ return undefined;
724
+ }
725
+ emitDistill(run, {
726
+ outcome: "queued",
727
+ proposalRef: target.ref,
728
+ proposalKind: "lesson",
729
+ proposalId: proposal.id,
730
+ updatesExisting: true,
731
+ ...(run.options.sourceRun !== undefined ? { sourceRun: run.options.sourceRun } : {}),
732
+ ...exclusionMeta(run, false),
733
+ });
734
+ return {
735
+ schemaVersion: 1,
736
+ ok: true,
737
+ outcome: "queued",
738
+ inputRef: run.inputRef,
739
+ proposalRef: target.ref,
740
+ proposalKind: "lesson",
741
+ proposalId: proposal.id,
742
+ proposal,
743
+ updatesExisting: true,
744
+ ...exclusionMeta(run, true),
745
+ };
746
+ }
625
747
  function rejectDistilled(run, proposalRef, content, score, reason, meta) {
626
748
  return writeQualityRejection({
627
749
  stash: run.stash,
@@ -863,7 +985,6 @@ function stampInputSalience(run) {
863
985
  type,
864
986
  retrievalFreq: 0,
865
987
  encodingSalience: scored.score,
866
- outcomeWeightEnabled: run.outcomeWeightEnabled,
867
988
  })));
868
989
  }
869
990
  catch {
@@ -887,7 +1008,6 @@ function persistOutputEncodingSalience(run, ref, body) {
887
1008
  type,
888
1009
  retrievalFreq: 0,
889
1010
  encodingSalience: scored.score,
890
- outcomeWeightEnabled: run.outcomeWeightEnabled,
891
1011
  })));
892
1012
  }
893
1013
  catch {
@@ -974,7 +1094,7 @@ async function fetchRelatedAssets(query, n) {
974
1094
  catch {
975
1095
  // best-effort
976
1096
  }
977
- return { ref: h.ref, content };
1097
+ return { ref: h.ref, content, ...(h.path ? { path: h.path } : {}) };
978
1098
  });
979
1099
  }
980
1100
  catch {
@@ -26,7 +26,7 @@ import { akmExtract, resolveStandaloneExtractPlan } from "./extract.js";
26
26
  export const extractCommand = defineJsonCommand({
27
27
  meta: {
28
28
  name: "extract",
29
- description: "Experimental: extract durable insights from native session files (claude, codex, opencode) and queue them as proposals.",
29
+ description: "Extract durable insights from native session files (claude, codex, opencode) and queue them as proposals.",
30
30
  },
31
31
  args: {
32
32
  type: {
@@ -3,16 +3,15 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import path from "node:path";
5
5
  import { defineCommand } from "citty";
6
- import { getParsedInvocation } from "../../cli/invocation.js";
7
- import { getStringArg, parsePositiveIntFlag } from "../../cli/parse-args.js";
8
- import { GLOBAL_OUTPUT_ARGS, output, runWithJsonErrors } from "../../cli/shared.js";
6
+ import { findCittyTopLevelCommandIndex, getStringArg, hasSubcommand, parsePositiveIntFlag } from "../../cli/parse-args.js";
7
+ import { defineJsonCommand, GLOBAL_OUTPUT_ARGS, output, runWithJsonErrors } from "../../cli/shared.js";
9
8
  import { isFullRefInput, parseRefInput } from "../../core/asset/resolve-ref.js";
10
9
  import { loadConfig } from "../../core/config/config.js";
11
10
  import { ConfigError, UsageError } from "../../core/errors.js";
12
11
  import { resolveMutationTarget } from "../../core/mutation-target.js";
13
12
  import { getCacheDir } from "../../core/paths.js";
14
13
  import { redactSensitiveText } from "../../core/redaction.js";
15
- import { clearLogFile, setLogFile, warn } from "../../core/warn.js";
14
+ import { clearLogFile, setLogFile } from "../../core/warn.js";
16
15
  import { resolveWriteTarget } from "../../core/write-source.js";
17
16
  import { DEFAULT_LLM_TIMEOUT_MS } from "../../integrations/agent/config.js";
18
17
  import { defaultWhich } from "../../integrations/agent/detect.js";
@@ -35,37 +34,6 @@ let akmImproveForRun = akmImprove;
35
34
  export function _setAkmImproveForTests(fake) {
36
35
  akmImproveForRun = fake ?? akmImprove;
37
36
  }
38
- /**
39
- * `--auto-accept` (removed in 0.9): citty absorbs it silently, and
40
- * `--auto-accept 90` would leave `90` as the scope — a 0.8-era crontab would
41
- * match nothing and exit 0. Warn, and drop that positional.
42
- */
43
- function resolveScopeAfterRetiredAutoAccept(scopeArg) {
44
- const invocation = getParsedInvocation();
45
- const autoAcceptRaw = invocation.getFlagValue("--auto-accept");
46
- if (autoAcceptRaw === undefined && !invocation.hasFlag("--auto-accept"))
47
- return scopeArg;
48
- warn("[improve] --auto-accept was removed in 0.9 and is ignored; proposals always queue for review. " +
49
- "Replacement: `akm improve && akm proposal drain --promote --yes`, or a `triage` block with " +
50
- 'applyMode: "promote" in your strategy. It becomes a hard error in 0.10.');
51
- if (scopeArg !== undefined && scopeArg === autoAcceptRaw) {
52
- warn(`[improve] ignoring "${scopeArg}" as a scope — it is the removed --auto-accept flag's value.`);
53
- return undefined;
54
- }
55
- return scopeArg;
56
- }
57
- /** `akm improve canary` (removed in 0.9) would otherwise be a type scope matching nothing, exiting 0. */
58
- function rejectRetiredCanaryScope(scopeArg) {
59
- if (scopeArg !== "canary")
60
- return;
61
- throw new UsageError('"akm improve canary" was removed in 0.9; the collapse-detector canary set it managed no longer exists.', "INVALID_FLAG_VALUE");
62
- }
63
- /** `--target` (renamed `--bundle` in 0.9) would otherwise be absorbed and write to the default bundle. */
64
- function rejectRetiredImproveTargetFlag() {
65
- if (!getParsedInvocation().hasFlag("--target"))
66
- return;
67
- throw new UsageError("`akm improve --target` was renamed to `--bundle` in 0.9. Use `--bundle <name>` instead.", "INVALID_FLAG_VALUE");
68
- }
69
37
  /**
70
38
  * `--require-engines` (#957): fail before any side effect when an enabled
71
39
  * process cannot run, naming what each is missing — a scheduled run would
@@ -194,53 +162,91 @@ async function runShowPromptCli(refArg, parsedRef, taskArg, targetArg, resolvedP
194
162
  });
195
163
  }
196
164
  /** `akm improve report` (#944): the per-run LLM usage/routing report ("report" is no asset type). */
197
- function runImproveReportCli(args) {
198
- const runIdArg = getStringArg(args, "run");
199
- const sinceArg = getStringArg(args, "since");
200
- const result = runImproveReportQuery({ runId: runIdArg, since: sinceArg });
201
- output("improve-report", { ok: true, ...result });
202
- }
203
- /** `--run`/`--since` belong to `improve report`; elsewhere citty would silently ignore them. */
204
- function rejectReportOnlyFlags(args) {
205
- const flag = getStringArg(args, "run") !== undefined
206
- ? "--run"
207
- : getStringArg(args, "since") !== undefined
208
- ? "--since"
209
- : undefined;
210
- if (flag === undefined)
211
- return;
212
- throw new UsageError(`\`${flag}\` only applies to \`akm improve report\`. Use \`akm improve report ${flag} <value>\` instead.`, "INVALID_FLAG_VALUE");
213
- }
165
+ const improveReportCommand = defineJsonCommand({
166
+ meta: {
167
+ name: "report",
168
+ description: "Show the LLM usage/routing report for the most recent improve run, one run, or a window of runs.",
169
+ },
170
+ args: {
171
+ run: {
172
+ type: "string",
173
+ description: "Show the report for one specific improve_runs row instead of the most recent run. Mutually exclusive with --since.",
174
+ },
175
+ since: {
176
+ type: "string",
177
+ description: 'Aggregate the report over every real run started since <window> (a duration like "24h"/"7d", or an ISO timestamp) instead of showing one run. Mutually exclusive with --run.',
178
+ },
179
+ },
180
+ run({ args }) {
181
+ const result = runImproveReportQuery({ runId: getStringArg(args, "run"), since: getStringArg(args, "since") });
182
+ output("improve-report", { ok: true, ...result });
183
+ },
184
+ });
214
185
  /**
215
186
  * `akm improve judge`: reflect's quality judge on one revision, read as
216
187
  * `{"source", "candidate", "feedback"}` JSON from stdin, with the engine the
217
188
  * strategy's reflect quality gate names. It writes nothing.
218
189
  */
219
- async function runImproveJudgeCli(strategyName) {
220
- const input = process.stdin.isTTY
221
- ? {}
222
- : JSON.parse((await readStdin()).toString("utf8"));
223
- const { source, candidate, feedback, ref } = input;
224
- if (typeof source !== "string" || typeof candidate !== "string") {
225
- throw new UsageError('`akm improve judge` reads {"source": "...", "candidate": "...", "feedback": "...", "ref": "..."} JSON from stdin.', "MISSING_REQUIRED_ARGUMENT");
226
- }
227
- const config = loadConfig();
228
- const judge = resolveQualityGateJudge(config, resolveImproveStrategy(strategyName, config).config, "reflect");
229
- if (!judge) {
230
- throw new ConfigError("`akm improve judge` judges with the reflect quality gate's engine. Set processes.reflect.qualityGate.engine.", "INVALID_CONFIG_FILE");
231
- }
232
- const notes = typeof feedback === "string" && feedback.trim() !== "" ? [feedback.trim()] : [];
233
- const verdict = await runReflectQualityJudge(config, candidate, source, notes, undefined, {
234
- runnerSelectionFrozen: true,
235
- llmRunner: judge,
236
- ...(typeof ref === "string" && ref ? { ref } : {}),
237
- });
238
- output("improve-judge", { engine: judge.engine, ...verdict });
239
- }
190
+ const improveJudgeCommand = defineJsonCommand({
191
+ meta: {
192
+ name: "judge",
193
+ description: "Run reflect's quality judge on one revision, read as {source, candidate, feedback, ref} JSON from stdin. Writes nothing.",
194
+ },
195
+ args: {
196
+ strategy: {
197
+ type: "string",
198
+ description: "Named improve strategy whose reflect quality gate names the judge engine.",
199
+ },
200
+ },
201
+ async run({ args }) {
202
+ const input = process.stdin.isTTY
203
+ ? {}
204
+ : JSON.parse((await readStdin()).toString("utf8"));
205
+ const { source, candidate, feedback, ref } = input;
206
+ if (typeof source !== "string" || typeof candidate !== "string") {
207
+ throw new UsageError('`akm improve judge` reads {"source": "...", "candidate": "...", "feedback": "...", "ref": "..."} JSON from stdin.', "MISSING_REQUIRED_ARGUMENT");
208
+ }
209
+ const config = loadConfig();
210
+ const judge = resolveQualityGateJudge(config, resolveImproveStrategy(getStringArg(args, "strategy"), config).config, "reflect");
211
+ if (!judge) {
212
+ throw new ConfigError("`akm improve judge` judges with the reflect quality gate's engine. Set processes.reflect.qualityGate.engine.", "INVALID_CONFIG_FILE");
213
+ }
214
+ const notes = typeof feedback === "string" && feedback.trim() !== "" ? [feedback.trim()] : [];
215
+ const verdict = await runReflectQualityJudge(config, candidate, source, notes, undefined, {
216
+ runnerSelectionFrozen: true,
217
+ llmRunner: judge,
218
+ ...(typeof ref === "string" && ref ? { ref } : {}),
219
+ });
220
+ output("improve-judge", { engine: judge.engine, ...verdict });
221
+ },
222
+ });
223
+ /** The subcommands `setup` withheld for this run, restored by `cleanup` (one command runs per process; in-process tests run many). */
224
+ let subCommandsWithheld = false;
225
+ const IMPROVE_SUBCOMMANDS = { report: improveReportCommand, judge: improveJudgeCommand };
240
226
  export const improveCommand = defineCommand({
241
227
  meta: {
242
228
  name: "improve",
243
- description: "Analyze existing AKM assets and generate improvement proposals; also consolidates memories when the selected strategy enables consolidate.",
229
+ description: "Analyze existing AKM assets and generate improvement proposals; also consolidates memories when the selected strategy enables consolidate. `improve report` and `improve judge` are subcommands.",
230
+ },
231
+ subCommands: IMPROVE_SUBCOMMANDS,
232
+ // `improve` takes a scope positional (an asset type or ref), and citty reads
233
+ // the first positional of a command with subcommands as a subcommand name,
234
+ // failing with an unknown command for a scope. So the subcommands stay
235
+ // registered only for an invocation that names one; any other, scope or none,
236
+ // is the improve run itself.
237
+ setup(context) {
238
+ const index = findCittyTopLevelCommandIndex(context.rawArgs, improveCommand.args);
239
+ const token = index >= 0 ? context.rawArgs[index] : undefined;
240
+ if (token !== undefined && token in IMPROVE_SUBCOMMANDS)
241
+ return;
242
+ subCommandsWithheld = true;
243
+ context.cmd.subCommands = undefined;
244
+ },
245
+ cleanup(context) {
246
+ if (!subCommandsWithheld)
247
+ return;
248
+ context.cmd.subCommands = IMPROVE_SUBCOMMANDS;
249
+ subCommandsWithheld = false;
244
250
  },
245
251
  // Declared explicitly: otherwise citty takes `--format`'s value as the scope.
246
252
  args: {
@@ -252,11 +258,6 @@ export const improveCommand = defineCommand({
252
258
  },
253
259
  task: { type: "string", description: "Add extra guidance for this improvement pass" },
254
260
  "dry-run": { type: "boolean", description: "Show planned actions without writing", default: false },
255
- plan: {
256
- type: "boolean",
257
- description: "Alias for --dry-run (#947). Sets the exact same internal flag; use it when previewing resolved process -> engine -> model routing (plan.processes) rather than checking what would write.",
258
- default: false,
259
- },
260
261
  bundle: {
261
262
  type: "string",
262
263
  description: "Bundle to improve and write proposals to (default: defaultWriteTarget, else the working bundle); only its assets are planned",
@@ -268,7 +269,7 @@ export const improveCommand = defineCommand({
268
269
  },
269
270
  "require-feedback-signal": {
270
271
  type: "boolean",
271
- description: "Turn the proactive/high-salience fallback lanes off (they only select and score assets; a rewrite needs negative feedback)",
272
+ description: "Turn the proactive-maintenance lane off for this run, so only assets with recent feedback are planned",
272
273
  default: false,
273
274
  },
274
275
  "json-to-stdout": {
@@ -291,17 +292,9 @@ export const improveCommand = defineCommand({
291
292
  description: "Print the composed reflect prompt for one asset ref and exit — no lock, index write, or engine dispatch (#952). Requires a fully-qualified asset ref as the scope positional (e.g. `akm improve lessons/my-lesson --show-prompt`). JSON/yaml format carries the prompt as a `prompt` field; text format prints it directly.",
292
293
  default: false,
293
294
  },
294
- run: {
295
- type: "string",
296
- description: 'Only with the "report" scope (`akm improve report --run <id>`): show the LLM usage/routing report for one specific improve_runs row instead of the most recent run. Mutually exclusive with --since.',
297
- },
298
- since: {
299
- type: "string",
300
- description: 'Only with the "report" scope (`akm improve report --since <window>`): aggregate the LLM usage/routing report over every real run started since <window> (a duration like "24h"/"7d", or an ISO timestamp) instead of showing one run. Mutually exclusive with --run.',
301
- },
302
295
  strategy: {
303
296
  type: "string",
304
- description: "Named improve strategy from improve.strategies or built-in strategies (catchup, consolidate, default, proactive-maintenance, quick, reflect-distill, thorough). Controls which sub-processes run and which asset types are processed.",
297
+ description: "Named improve strategy from improve.strategies or built-in strategies (consolidate, default). Controls which sub-processes run and which asset types are processed.",
305
298
  },
306
299
  sync: {
307
300
  type: "boolean",
@@ -314,29 +307,21 @@ export const improveCommand = defineCommand({
314
307
  },
315
308
  async run({ args }) {
316
309
  await runWithJsonErrors(async () => {
317
- if (getStringArg(args, "scope") === "report") {
318
- runImproveReportCli(args);
310
+ // citty runs this body after a subcommand it dispatched too.
311
+ if (hasSubcommand(args, new Set(Object.keys(IMPROVE_SUBCOMMANDS))))
319
312
  return;
320
- }
321
- rejectReportOnlyFlags(args);
322
- if (getStringArg(args, "scope") === "judge") {
323
- await runImproveJudgeCli(getStringArg(args, "strategy"));
324
- return;
325
- }
326
- rejectRetiredImproveTargetFlag();
327
313
  const jsonToStdout = args["json-to-stdout"];
328
314
  const targetArg = getStringArg(args, "bundle");
329
315
  const taskArg = getStringArg(args, "task");
330
- // `--plan` is an alias for `--dry-run`; `--show-prompt` is read-only too.
331
- const dryRun = args["dry-run"] || args.plan || args["show-prompt"];
316
+ // `--show-prompt` is read-only too.
317
+ const dryRun = args["dry-run"] || args["show-prompt"];
332
318
  const limitRaw = parsePositiveIntFlag(args.limit ?? undefined);
333
319
  const timeoutMs = parsePositiveIntFlag(args["timeout-ms"], "--timeout-ms");
334
320
  const requireFeedbackSignal = args["require-feedback-signal"];
335
321
  const skipIfLocked = args["skip-if-locked"];
336
322
  const strategyArg = getStringArg(args, "strategy");
337
323
  const effectiveConfig = loadConfig();
338
- const scopeArg = resolveScopeAfterRetiredAutoAccept(getStringArg(args, "scope"));
339
- rejectRetiredCanaryScope(scopeArg);
324
+ const scopeArg = getStringArg(args, "scope");
340
325
  const scopeRef = scopeArg && isFullRefInput(scopeArg) ? parseRefInput(scopeArg) : undefined;
341
326
  const writeTarget = dryRun
342
327
  ? undefined
@@ -1,17 +1,12 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- import catchup from "../../assets/improve-strategies/catchup.json" with { type: "json" };
5
4
  import consolidate from "../../assets/improve-strategies/consolidate.json" with { type: "json" };
6
5
  import defaultStrategy from "../../assets/improve-strategies/default.json" with { type: "json" };
7
- import proactiveMaintenance from "../../assets/improve-strategies/proactive-maintenance.json" with { type: "json" };
8
- import quick from "../../assets/improve-strategies/quick.json" with { type: "json" };
9
- import reflectDistill from "../../assets/improve-strategies/reflect-distill.json" with { type: "json" };
10
- import thorough from "../../assets/improve-strategies/thorough.json" with { type: "json" };
11
6
  import { conceptIdFromTypeName, parseRefInput } from "../../core/asset/resolve-ref.js";
12
7
  import { ImproveProfileConfigSchema } from "../../core/config/config-schema.js";
13
8
  import { deepMergeConfig } from "../../core/config/deep-merge.js";
14
- import { BUILTIN_IMPROVE_STRATEGY_NAMES, IMPROVE_ENGINE_PROCESSES, IMPROVE_PROCESS_NAMES, } from "../../core/config/engine-semantics.js";
9
+ import { BUILTIN_IMPROVE_STRATEGY_NAMES, IMPROVE_ENGINE_PROCESSES, IMPROVE_PROCESS_NAMES, REMOVED_IMPROVE_STRATEGY_NAMES, } from "../../core/config/engine-semantics.js";
15
10
  import { ConfigError } from "../../core/errors.js";
16
11
  import { describeLlmCredentialAvailability, } from "../../integrations/agent/engine-resolution.js";
17
12
  import { runnerLlmConnection } from "../../integrations/agent/runner.js";
@@ -69,12 +64,7 @@ export function isStrategyFilteredForAllPasses(ref, strategy) {
69
64
  }
70
65
  const BUILTIN_STRATEGIES = {
71
66
  default: defaultStrategy,
72
- quick,
73
- thorough,
74
67
  consolidate,
75
- catchup,
76
- "reflect-distill": reflectDistill,
77
- "proactive-maintenance": proactiveMaintenance,
78
68
  };
79
69
  if (BUILTIN_IMPROVE_STRATEGY_NAMES.some((name) => !(name in BUILTIN_STRATEGIES))) {
80
70
  throw new Error("Built-in improve strategy names are out of sync with their assets");
@@ -105,6 +95,11 @@ export function resolveImproveStrategy(name, config) {
105
95
  // shape this refusal exists to reject, not a way around it.
106
96
  "Choose a different strategy. `graph-refresh` cannot be redefined under `improve.strategies` — it always refuses.");
107
97
  }
98
+ if (!(selectedName in BUILTIN_STRATEGIES) &&
99
+ !userStrategies[selectedName] &&
100
+ REMOVED_IMPROVE_STRATEGY_NAMES.includes(selectedName)) {
101
+ throw new ConfigError(`Improve strategy "${selectedName}" was removed in 0.10. Use "default" (or "consolidate"), or define "${selectedName}" under improve.strategies to keep your own version.`, "UNKNOWN_IMPROVE_STRATEGY", `Run \`akm improve --strategy default\`, or add \`improve.strategies.${selectedName}\` to your config; a block of that name is a user-defined strategy that inherits \`default\`.`);
102
+ }
108
103
  if (!(selectedName in BUILTIN_STRATEGIES) && !userStrategies[selectedName]) {
109
104
  const valid = [...new Set([...Object.keys(BUILTIN_STRATEGIES), ...Object.keys(userStrategies)])].sort();
110
105
  throw new ConfigError(`Improve strategy "${selectedName}" not found. Valid strategies: ${valid.join(", ")}.`, "UNKNOWN_IMPROVE_STRATEGY");
@@ -304,7 +299,8 @@ function buildImprovePlan(strategy, config, options) {
304
299
  });
305
300
  }
306
301
  if (engineUnavailable.length > 0 &&
307
- !Object.values(processes).some((process) => process.enabled) &&
302
+ // proactiveMaintenance uses no engine: it is a selector, so it alone does not keep a run alive.
303
+ !IMPROVE_ENGINE_PROCESSES.some((name) => processes[name].enabled) &&
308
304
  (!options.allowAllDisabled || anyEngineNotConfigured)) {
309
305
  const names = engineUnavailable.map((item) => `"${item.process}"`).join(", ");
310
306
  throw new ConfigError(`No improve process can run: ${names} ${engineUnavailable.length === 1 ? "requires" : "require"} an engine that is not configured. Set defaults.llmEngine, or the per-process engine key named for each.`, "LLM_NOT_CONFIGURED");
@@ -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
  : {}),
@@ -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
  },