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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/CHANGELOG.md +731 -0
  2. package/dist/akm +94 -196
  3. package/dist/cli/shared.js +6 -2
  4. package/dist/cli.js +22 -9
  5. package/dist/commands/agent/agent-dispatch.js +1 -1
  6. package/dist/commands/command/command-execution.js +24 -62
  7. package/dist/commands/feedback-cli.js +0 -1
  8. package/dist/commands/health/accept-rate.js +2 -2
  9. package/dist/commands/health/checks.js +30 -75
  10. package/dist/commands/health/config-skew.js +38 -0
  11. package/dist/commands/health/egress.js +54 -0
  12. package/dist/commands/health/html-report.js +0 -38
  13. package/dist/commands/health/improve-metrics.js +123 -562
  14. package/dist/commands/health/plugin-staleness.js +53 -3
  15. package/dist/commands/health/renderers.js +12 -4
  16. package/dist/commands/health/report-view-model.js +11 -106
  17. package/dist/commands/health/types-improve.js +4 -19
  18. package/dist/commands/health/windows.js +64 -73
  19. package/dist/commands/health.js +122 -143
  20. package/dist/commands/improve/consolidate/chunking.js +25 -100
  21. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  22. package/dist/commands/improve/consolidate.js +538 -1075
  23. package/dist/commands/improve/content-hash.js +16 -24
  24. package/dist/commands/improve/distill/content-repair.js +18 -100
  25. package/dist/commands/improve/distill-guards.js +20 -81
  26. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  27. package/dist/commands/improve/distill.js +608 -1075
  28. package/dist/commands/improve/eligibility.js +126 -400
  29. package/dist/commands/improve/execution.js +3 -5
  30. package/dist/commands/improve/extract.js +487 -1046
  31. package/dist/commands/improve/feedback-valence.js +0 -25
  32. package/dist/commands/improve/improve-cli.js +29 -166
  33. package/dist/commands/improve/improve-result-file.js +10 -66
  34. package/dist/commands/improve/improve-strategies.js +12 -7
  35. package/dist/commands/improve/improve-usage-report.js +18 -64
  36. package/dist/commands/improve/improve.js +443 -1063
  37. package/dist/commands/improve/ledger.js +114 -0
  38. package/dist/commands/improve/locks.js +2 -8
  39. package/dist/commands/improve/loop-stages.js +459 -1172
  40. package/dist/commands/improve/memory/derived-ref.js +12 -77
  41. package/dist/commands/improve/memory/memory-belief.js +14 -118
  42. package/dist/commands/improve/memory/memory-improve.js +4 -3
  43. package/dist/commands/improve/outcome-loop.js +28 -156
  44. package/dist/commands/improve/planner.js +5 -10
  45. package/dist/commands/improve/preparation.js +851 -2339
  46. package/dist/commands/improve/proactive-maintenance.js +34 -101
  47. package/dist/commands/improve/reflect-noise.js +104 -280
  48. package/dist/commands/improve/reflect.js +621 -1367
  49. package/dist/commands/improve/salience.js +46 -232
  50. package/dist/commands/improve/session-asset.js +19 -100
  51. package/dist/commands/improve/stage.js +323 -0
  52. package/dist/commands/proposal/drain.js +251 -644
  53. package/dist/commands/proposal/proposal-cli.js +3 -18
  54. package/dist/commands/proposal/proposal-types.js +20 -41
  55. package/dist/commands/proposal/proposal.js +1 -2
  56. package/dist/commands/proposal/propose.js +134 -160
  57. package/dist/commands/proposal/repository.js +502 -1487
  58. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  59. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  60. package/dist/commands/proposal/validators/proposals.js +13 -89
  61. package/dist/commands/read/curate.js +63 -413
  62. package/dist/commands/read/search-cli.js +16 -33
  63. package/dist/commands/read/search.js +17 -23
  64. package/dist/commands/read/show.js +2 -13
  65. package/dist/commands/sources/bundle-cli.js +25 -2
  66. package/dist/commands/sources/bundle-config-ops.js +7 -0
  67. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  68. package/dist/commands/sources/info.js +2 -11
  69. package/dist/commands/sources/installed-stashes.js +197 -746
  70. package/dist/commands/sources/schema-repair.js +98 -129
  71. package/dist/commands/sources/source-add.js +62 -12
  72. package/dist/commands/sources/stash-cli.js +1 -1
  73. package/dist/commands/tasks/explain.js +10 -13
  74. package/dist/commands/tasks/tasks-cli.js +9 -8
  75. package/dist/commands/tasks/tasks.js +326 -930
  76. package/dist/commands/tasks/validate.js +42 -21
  77. package/dist/commands/workflow/plan.js +22 -29
  78. package/dist/commands/workflow-cli.js +4 -4
  79. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  80. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  81. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  82. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  83. package/dist/core/adapter/execution-source.js +17 -29
  84. package/dist/core/asset/resolve-ref.js +1 -1
  85. package/dist/core/bundle-id.js +42 -5
  86. package/dist/core/bundle-rename.js +291 -0
  87. package/dist/core/config/config-io.js +1 -2
  88. package/dist/core/config/config-schema.js +1 -33
  89. package/dist/core/config/config-walker.js +1 -1
  90. package/dist/core/config/config.js +163 -68
  91. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  92. package/dist/core/config/schema/embedding.js +20 -5
  93. package/dist/core/config/schema/engines.js +5 -0
  94. package/dist/core/config/schema/execution.js +1 -1
  95. package/dist/core/config/schema/experimental.js +1 -1
  96. package/dist/core/config/schema/improve-processes.js +21 -95
  97. package/dist/core/config/schema/improve.js +4 -42
  98. package/dist/core/config/schema/scheduler.js +12 -12
  99. package/dist/core/config/schema/search.js +6 -22
  100. package/dist/core/env-secret-ref.js +0 -1
  101. package/dist/core/errors.js +8 -9
  102. package/dist/core/file-lock.js +76 -173
  103. package/dist/core/logs-db.js +2 -2
  104. package/dist/core/paths.js +0 -27
  105. package/dist/core/redaction.js +109 -2
  106. package/dist/core/run-lock.js +2 -5
  107. package/dist/core/spawn-env.js +1 -1
  108. package/dist/core/state/migrations.js +108 -61
  109. package/dist/core/state-db-scope.js +2 -4
  110. package/dist/core/state-db.js +126 -692
  111. package/dist/core/type-presentation.js +1 -9
  112. package/dist/core/write-source.js +293 -1012
  113. package/dist/execution/input-contract.js +1 -1
  114. package/dist/execution/resolved-request.js +135 -689
  115. package/dist/execution/source.js +63 -257
  116. package/dist/execution/target-ref.js +1 -1
  117. package/dist/indexer/bundle-identity-guard.js +2 -2
  118. package/dist/indexer/db/graph-db.js +106 -46
  119. package/dist/indexer/ensure-index.js +44 -85
  120. package/dist/indexer/graph/graph-extraction.js +340 -562
  121. package/dist/indexer/graph/graph-related.js +130 -0
  122. package/dist/indexer/index-rebuild-lock.js +3 -11
  123. package/dist/indexer/index-writer-lock.js +8 -17
  124. package/dist/indexer/index-written-assets.js +139 -151
  125. package/dist/indexer/indexer.js +524 -846
  126. package/dist/indexer/materialize-embeddings.js +60 -397
  127. package/dist/indexer/passes/memory-inference.js +81 -90
  128. package/dist/indexer/passes/metadata.js +132 -200
  129. package/dist/indexer/read-preflight.js +0 -7
  130. package/dist/indexer/scan/doc-to-entry.js +1 -3
  131. package/dist/indexer/scan/drain-dir.js +1 -1
  132. package/dist/indexer/search/db-search.js +181 -590
  133. package/dist/indexer/search/fts-query.js +30 -41
  134. package/dist/indexer/search/ranking.js +28 -154
  135. package/dist/indexer/search/search-attribution.js +12 -32
  136. package/dist/indexer/search/search-fields.js +11 -15
  137. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  138. package/dist/indexer/search/search-source.js +1 -4
  139. package/dist/indexer/usage/usage-events.js +2 -7
  140. package/dist/integrations/agent/engine-fallback.js +23 -40
  141. package/dist/integrations/agent/engine-resolution.js +93 -183
  142. package/dist/integrations/agent/execution.js +507 -0
  143. package/dist/integrations/agent/model-map.js +28 -156
  144. package/dist/integrations/agent/request-lowering.js +66 -141
  145. package/dist/integrations/agent/runner-dispatch.js +143 -321
  146. package/dist/integrations/agent/runner.js +54 -14
  147. package/dist/integrations/lockfile.js +53 -101
  148. package/dist/llm/embedders/deterministic.js +2 -3
  149. package/dist/llm/embedders/profile.js +71 -0
  150. package/dist/llm/embedders/remote.js +10 -15
  151. package/dist/llm/graph-extract.js +3 -12
  152. package/dist/llm/index-passes.js +3 -5
  153. package/dist/llm/memory-infer.js +1 -2
  154. package/dist/llm/metadata-enhance.js +1 -2
  155. package/dist/llm/structured-call.js +5 -24
  156. package/dist/output/generic-render.js +23 -11
  157. package/dist/output/html-render.js +13 -10
  158. package/dist/output/render-registry.js +3 -32
  159. package/dist/output/shapes/helpers.js +2 -34
  160. package/dist/output/shapes/passthrough.js +1 -9
  161. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  162. package/dist/output/text/command-format.js +60 -23
  163. package/dist/output/text/helpers.js +1 -1
  164. package/dist/output/text/migrate.js +5 -14
  165. package/dist/output/text/proposal-format.js +1 -2
  166. package/dist/output/text/workflow-format.js +0 -32
  167. package/dist/output/text.js +2 -0
  168. package/dist/registry/factory.js +4 -19
  169. package/dist/registry/network.js +66 -220
  170. package/dist/registry/providers/index.js +0 -2
  171. package/dist/registry/providers/skills-sh.js +3 -14
  172. package/dist/registry/providers/static-index.js +24 -26
  173. package/dist/registry/resolve.js +55 -131
  174. package/dist/scripts/akm-migrate-node.js +43937 -93313
  175. package/dist/scripts/akm-migrate.js +43697 -93071
  176. package/dist/setup/registry-stash-loader.js +4 -13
  177. package/dist/setup/semantic-assets.js +3 -44
  178. package/dist/setup/setup.js +1 -1
  179. package/dist/setup/steps/tasks.js +25 -15
  180. package/dist/sources/provider-factory.js +17 -18
  181. package/dist/sources/providers/filesystem.js +2 -3
  182. package/dist/sources/providers/git-install.js +7 -1
  183. package/dist/sources/providers/git-provider.js +0 -3
  184. package/dist/sources/providers/git-stash.js +0 -17
  185. package/dist/sources/providers/npm.js +2 -4
  186. package/dist/sources/providers/provider-utils.js +5 -10
  187. package/dist/sources/providers/website.js +0 -2
  188. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  189. package/dist/sources/website-url.js +2 -2
  190. package/dist/storage/database.js +9 -35
  191. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  192. package/dist/storage/repositories/index-connection.js +34 -70
  193. package/dist/storage/repositories/index-entries-repository.js +69 -111
  194. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  195. package/dist/storage/repositories/index-entry-schema.js +83 -269
  196. package/dist/storage/repositories/index-fts-repository.js +86 -256
  197. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  198. package/dist/storage/repositories/index-meta-repository.js +6 -4
  199. package/dist/storage/repositories/index-schema.js +192 -220
  200. package/dist/storage/repositories/index-utility-repository.js +8 -29
  201. package/dist/storage/repositories/index-vec-repository.js +133 -414
  202. package/dist/storage/repositories/outcome-repository.js +2 -1
  203. package/dist/storage/repositories/proposals-repository.js +35 -0
  204. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  205. package/dist/storage/repositories/task-history-repository.js +26 -4
  206. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  207. package/dist/storage/sqlite-migrations.js +136 -0
  208. package/dist/storage/sqlite-pragmas.js +11 -9
  209. package/dist/storage/sqlite-transaction.js +170 -0
  210. package/dist/storage/state-db-integrity.js +34 -27
  211. package/dist/tasks/activation-config.js +134 -62
  212. package/dist/tasks/backends/cron.js +129 -277
  213. package/dist/tasks/backends/exec-utils.js +2 -5
  214. package/dist/tasks/backends/launchd.js +125 -745
  215. package/dist/tasks/backends/schtasks.js +101 -620
  216. package/dist/tasks/prepare/prepare-support.js +5 -15
  217. package/dist/tasks/prepare/prepare.js +0 -2
  218. package/dist/tasks/resolve-akm-bin.js +20 -79
  219. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  220. package/dist/tasks/scheduler-binding.js +18 -238
  221. package/dist/tasks/scheduler-invocation.js +52 -52
  222. package/dist/tasks/scheduler-lock.js +53 -0
  223. package/dist/tasks/scheduler-sync.js +361 -751
  224. package/dist/tasks/source/parse-task-source.js +160 -10
  225. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  226. package/dist/tasks/source/task-to-v4.js +2 -2
  227. package/dist/workflows/authoring/authoring.js +3 -12
  228. package/dist/workflows/compile.js +211 -0
  229. package/dist/workflows/concurrency-policy.js +13 -74
  230. package/dist/workflows/exec/child-invocation.js +3 -17
  231. package/dist/workflows/exec/child-workflow.js +32 -141
  232. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  233. package/dist/workflows/exec/environment.js +98 -0
  234. package/dist/workflows/exec/exec-unit.js +33 -140
  235. package/dist/workflows/exec/frozen-judge.js +7 -59
  236. package/dist/workflows/exec/native-executor.js +82 -341
  237. package/dist/workflows/exec/param-secrets.js +29 -47
  238. package/dist/workflows/exec/run-workflow.js +154 -387
  239. package/dist/workflows/exec/scheduler.js +9 -36
  240. package/dist/workflows/exec/step-work.js +127 -430
  241. package/dist/workflows/exec/unit-dispatch.js +11 -63
  242. package/dist/workflows/exec/unit-writer.js +8 -52
  243. package/dist/workflows/exec/worktree.js +39 -273
  244. package/dist/workflows/freeze/child-output-references.js +4 -15
  245. package/dist/workflows/freeze/environment.js +99 -92
  246. package/dist/workflows/freeze/freeze.js +172 -0
  247. package/dist/workflows/freeze/step-values.js +19 -21
  248. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  249. package/dist/workflows/freeze/targets/command.js +10 -33
  250. package/dist/workflows/freeze/targets/script.js +5 -12
  251. package/dist/workflows/freeze/targets/shell.js +3 -6
  252. package/dist/workflows/freeze/targets/task.js +25 -80
  253. package/dist/workflows/freeze/task-bindings.js +20 -67
  254. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  255. package/dist/workflows/ir/params.js +6 -51
  256. package/dist/workflows/ir/plan-hash.js +2 -34
  257. package/dist/workflows/parser.js +140 -43
  258. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  259. package/dist/workflows/renderer.js +36 -69
  260. package/dist/workflows/resource-limits.js +12 -120
  261. package/dist/workflows/runtime/agent-identity.js +8 -40
  262. package/dist/workflows/runtime/run-outputs.js +3 -6
  263. package/dist/workflows/runtime/run-plan.js +316 -0
  264. package/dist/workflows/runtime/runs.js +48 -200
  265. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  266. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  267. package/dist/workflows/validate-summary.js +2 -7
  268. package/docs/integration/bundling-akm.md +49 -42
  269. package/docs/migration/README.md +1 -0
  270. package/docs/migration/release-notes/0.9.17.md +41 -0
  271. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  272. package/docs/reference/cli.md +182 -125
  273. package/docs/reference/configuration.md +49 -56
  274. package/docs/reference/data-and-telemetry.md +19 -20
  275. package/docs/reference/tasks.md +86 -38
  276. package/docs/reference/workflow-schema.md +14 -18
  277. package/docs/reference/workflows.md +6 -9
  278. package/package.json +1 -1
  279. package/schemas/akm-config.json +87 -406
  280. package/dist/commands/health/advisories.js +0 -150
  281. package/dist/commands/health/metrics.js +0 -329
  282. package/dist/commands/health/surfaces.js +0 -102
  283. package/dist/commands/improve/anti-collapse.js +0 -83
  284. package/dist/commands/improve/collapse-detector.js +0 -432
  285. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  286. package/dist/commands/improve/consolidate/merge.js +0 -146
  287. package/dist/commands/improve/distill/promote-memory.js +0 -329
  288. package/dist/commands/improve/distill/quality-gate.js +0 -500
  289. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  290. package/dist/commands/improve/proposal-envelope.js +0 -31
  291. package/dist/commands/improve/run-context.js +0 -123
  292. package/dist/commands/improve/shared.js +0 -21
  293. package/dist/commands/improve/source-identity.js +0 -28
  294. package/dist/commands/improve/triage.js +0 -96
  295. package/dist/commands/proposal/drain-policies.js +0 -151
  296. package/dist/commands/sources/update-transaction.js +0 -220
  297. package/dist/core/action-contributors.js +0 -28
  298. package/dist/core/config/config-version-shim.js +0 -101
  299. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  300. package/dist/core/fs-txn.js +0 -405
  301. package/dist/core/lexical-score.js +0 -25
  302. package/dist/core/maintenance-barrier.js +0 -167
  303. package/dist/execution/executable-identity.js +0 -105
  304. package/dist/execution/guarded-source.js +0 -441
  305. package/dist/indexer/graph/graph-boost.js +0 -427
  306. package/dist/indexer/graph/graph-dedup.js +0 -95
  307. package/dist/indexer/search/name-match.js +0 -35
  308. package/dist/indexer/search/ranking-contributors.js +0 -515
  309. package/dist/indexer/walk/project-context.js +0 -192
  310. package/dist/integrations/agent/execution-cascade.js +0 -566
  311. package/dist/integrations/agent/execution-definitions.js +0 -202
  312. package/dist/integrations/agent/execution-lowering.js +0 -841
  313. package/dist/integrations/agent/execution-preparation.js +0 -98
  314. package/dist/integrations/agent/inline-execution.js +0 -74
  315. package/dist/registry/create-provider-registry.js +0 -29
  316. package/dist/registry/pinned-request-helper.js +0 -247
  317. package/dist/registry/pinned-transport.js +0 -717
  318. package/dist/sources/providers/index.js +0 -14
  319. package/dist/storage/engines/sqlite-migrations.js +0 -271
  320. package/dist/storage/repositories/canaries-repository.js +0 -107
  321. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  322. package/dist/storage/repositories/registry-cache.js +0 -113
  323. package/dist/tasks/scheduler-sync-preview.js +0 -52
  324. package/dist/workflows/freeze/resolve-steps.js +0 -86
  325. package/dist/workflows/freeze/source-freeze.js +0 -64
  326. package/dist/workflows/ir/compile.js +0 -321
  327. package/dist/workflows/ir/environment-v4.js +0 -330
  328. package/dist/workflows/ir/freeze-v4.js +0 -153
  329. package/dist/workflows/ir/schema-v4.js +0 -745
  330. package/dist/workflows/ir/schema.js +0 -354
  331. package/dist/workflows/program/schema.js +0 -78
  332. package/dist/workflows/runtime/checkin.js +0 -57
  333. package/dist/workflows/runtime/plan-classifier.js +0 -196
  334. package/dist/workflows/runtime/unit-checkin.js +0 -45
  335. package/dist/workflows/runtime/unit-phases.js +0 -20
  336. package/dist/workflows/schema.js +0 -4
  337. package/dist/workflows/source-ir/compile.js +0 -200
  338. package/dist/workflows/source-ir/program.js +0 -50
  339. package/dist/workflows/source-ir/result.js +0 -26
  340. package/dist/workflows/source-ir/schema.js +0 -786
  341. package/dist/workflows/source-ir/triggers.js +0 -79
  342. package/dist/workflows/source-ir/uses.js +0 -40
  343. package/dist/workflows/validator.js +0 -60
@@ -25,7 +25,6 @@ import { resolveImproveExecution } from "../improve/execution.js";
25
25
  import { extractCommand } from "../improve/extract-cli.js";
26
26
  import { resolveImproveStrategy } from "../improve/improve-strategies.js";
27
27
  import { drainProposals } from "./drain.js";
28
- import { resolveDrainPolicy } from "./drain-policies.js";
29
28
  import { akmProposalAccept, akmProposalDiff, akmProposalList, akmProposalReject, akmProposalRevert, akmProposalShow, bulkAdjudicateProposals, } from "./proposal.js";
30
29
  import { proposeCommand } from "./propose-cli.js";
31
30
  export function mergeProposalDrainNotices(resolutionNotices, dispatchNotices) {
@@ -323,13 +322,9 @@ const proposalShowCommand = defineJsonCommand({
323
322
  const proposalDrainCommand = defineJsonCommand({
324
323
  meta: {
325
324
  name: "drain",
326
- description: "Drain the standing pending proposal backlog using a deterministic triage policy",
325
+ description: "Drain the pending proposal backlog: accept what a quality judge passed, reject empty diffs, leave the rest for judgment or review",
327
326
  },
328
327
  args: {
329
- policy: {
330
- type: "string",
331
- description: "Built-in preset (personal-stash|conservative|manual) or path to a policy file",
332
- },
333
328
  "dry-run": {
334
329
  type: "boolean",
335
330
  description: "List what would be accepted/rejected/deferred without writing.",
@@ -345,10 +340,6 @@ const proposalDrainCommand = defineJsonCommand({
345
340
  type: "string",
346
341
  description: "Hard per-run accept ceiling. Accepts beyond this are reported as skippedByCap.",
347
342
  },
348
- "max-diff-lines": {
349
- type: "string",
350
- description: "Defer (never promote) accepts whose proposed content exceeds this many lines.",
351
- },
352
343
  "older-than": {
353
344
  type: "string",
354
345
  description: "Only consider proposals created more than this many days ago.",
@@ -365,7 +356,7 @@ const proposalDrainCommand = defineJsonCommand({
365
356
  },
366
357
  strategy: {
367
358
  type: "string",
368
- description: "Read the triage block (policy, applyMode, ceilings, judgment) from this improve strategy.",
359
+ description: "Read the triage block (applyMode, ceilings, judgment) from this improve strategy.",
369
360
  },
370
361
  },
371
362
  async run({ args, rawArgs }) {
@@ -378,20 +369,17 @@ const proposalDrainCommand = defineJsonCommand({
378
369
  // always override config; config supplies defaults for any flag omitted.
379
370
  const selectedStrategy = resolveImproveStrategy(args.strategy, cfg);
380
371
  const triageConfig = selectedStrategy.config.processes?.triage;
381
- const policy = resolveDrainPolicy(args.policy ?? triageConfig?.policy);
382
372
  const dryRun = args["dry-run"] === true;
383
373
  const applyMode = args.promote === true ? "promote" : (triageConfig?.applyMode ?? "queue");
384
374
  const maxAccepts = parsePositiveIntFlag(args["max-accepts"], "--max-accepts") ??
385
375
  triageConfig?.maxAcceptsPerRun ??
386
376
  25;
387
- const maxDiffLines = parsePositiveIntFlag(args["max-diff-lines"], "--max-diff-lines") ??
388
- triageConfig?.maxDiffLines;
389
377
  const rawOlderThan = parsePositiveIntFlag(args["older-than"], "--older-than");
390
378
  const olderThanMs = rawOlderThan !== undefined ? rawOlderThan * 86_400_000 : undefined;
391
379
  // Promotion in promote mode is destructive (commits to git, no batch revert).
392
380
  if (applyMode === "promote" && !dryRun) {
393
381
  const { confirmDestructive } = await import("../../cli/confirm.js");
394
- const confirmed = await confirmDestructive(`Drain and promote matching pending proposals under policy "${policy.name}"? Promotions commit to git and cannot be batch-reverted.`, { yes: args.yes === true });
382
+ const confirmed = await confirmDestructive("Drain and promote judge-passed pending proposals? Promotions commit to git and cannot be batch-reverted.", { yes: args.yes === true });
395
383
  if (!confirmed) {
396
384
  process.stderr.write("Aborted.\n");
397
385
  return;
@@ -444,11 +432,9 @@ const proposalDrainCommand = defineJsonCommand({
444
432
  result = await withLlmStage("drain", () => drainProposals({
445
433
  stashDir,
446
434
  config: cfg,
447
- policy,
448
435
  applyMode,
449
436
  maxAccepts,
450
437
  dryRun,
451
- ...(maxDiffLines !== undefined ? { maxDiffLines } : {}),
452
438
  ...(excludeIds ? { excludeIds } : {}),
453
439
  judgment,
454
440
  }));
@@ -461,7 +447,6 @@ const proposalDrainCommand = defineJsonCommand({
461
447
  output("proposal-drain", {
462
448
  schemaVersion: 1,
463
449
  ok: true,
464
- policy: policy.name,
465
450
  applyMode,
466
451
  dryRun,
467
452
  strategy: selectedStrategy.name,
@@ -1,37 +1,24 @@
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
- // ── Source allow-list (F-4 / #385) ──────────────────────────────────────────
5
4
  /**
6
- * Curated allow-list of valid `source` values for proposals (F-4 / #385).
7
- *
8
- * Rationale (W3C PROV-DM 2013): Provenance records require typed, validated
9
- * sources for meaningful aggregation. Accept-rate-per-source is the core
10
- * self-measurement metric for recursive self-improvement: if reflect proposals
11
- * are accepted at 20% and distill proposals at 60%, that guides resource
12
- * allocation. Free-text typos (`"reflct"`) produce unaggregatable events.
13
- *
14
- * Automated sources (those in {@link AUTOMATED_PROPOSAL_SOURCES}) require a
15
- * `sourceRun` field for full PROV-DM traceability.
5
+ * Valid proposal `source` values (#385): typed sources keep accept-rate per
6
+ * source aggregatable (PROV-DM). An unknown value is accepted with a warning.
16
7
  */
17
8
  export const PROPOSAL_SOURCES = [
18
- // Automated sources — require sourceRun for traceability.
19
9
  "reflect",
20
10
  "distill",
21
11
  "consolidate",
22
12
  "extract",
23
13
  "improve",
24
- // Semi-automated / tool-driven.
25
14
  "feedback",
26
- // Human-initiated / CLI-driven.
27
15
  "propose",
28
16
  "remember",
29
17
  "import",
30
- // Internal / system.
31
18
  "distill_quality_rejected",
32
19
  "schema-repair",
33
20
  ];
34
- /** Automated sources that SHOULD include a `sourceRun` for PROV-DM traceability. */
21
+ /** Automated sources, which should carry a `sourceRun`. */
35
22
  export const AUTOMATED_PROPOSAL_SOURCES = [
36
23
  "reflect",
37
24
  "distill",
@@ -40,38 +27,30 @@ export const AUTOMATED_PROPOSAL_SOURCES = [
40
27
  "improve",
41
28
  "schema-repair",
42
29
  ];
43
- /**
44
- * Check whether a string is a valid {@link ProposalSource}.
45
- * Unknown source values are accepted with a runtime warning rather than a hard
46
- * error, to allow extensions without breaking existing callers.
47
- */
48
30
  export function isValidProposalSource(source) {
49
31
  return PROPOSAL_SOURCES.includes(source);
50
32
  }
51
- /**
52
- * Check whether a source value is an automated source requiring `sourceRun`.
53
- */
54
33
  export function isAutomatedProposalSource(source) {
55
34
  return AUTOMATED_PROPOSAL_SOURCES.includes(source);
56
35
  }
57
- /**
58
- * Gate-decision reason token for a promote refusal caused by the TARGET
59
- * changing after mint — often akm's own bookkeeping, not a merit judgement on
60
- * the proposed content (STALE, R20). The drain stamps this on the auto-reject
61
- * it issues instead of retrying a promote that will fail identically forever;
62
- * {@link isStaleTargetRejection} and the rejection-backoff guard
63
- * (`repository.ts`'s `checkFingerprintAndBackoff`) both key off the exact
64
- * string so they can't drift apart.
65
- */
36
+ /** A promote refused because the target changed after mint (STALE, R20) — not a merit judgement. */
66
37
  export const STALE_TARGET_GATE_REASON = "stale-target";
38
+ export const EXPIRED_GATE_REASON = "expired";
39
+ export const ASSET_MISSING_GATE_REASON = "asset-missing";
40
+ const PROCEDURAL_GATE_REASONS = new Set([
41
+ STALE_TARGET_GATE_REASON,
42
+ EXPIRED_GATE_REASON,
43
+ ASSET_MISSING_GATE_REASON,
44
+ ]);
67
45
  /**
68
- * True for a rejected proposal whose rejection was the drain's stale-target
69
- * auto-reject (STALE, R20), not a judgement on the proposed content. Readers
70
- * that treat a rejection as "this content was refused" — the Reflexion
71
- * "previously rejected" context (`improve/reflect.ts`, `improve/distill.ts`)
72
- * and the accept-rate health metric (`health/accept-rate.ts`) — exclude these
73
- * rows so a procedural refusal doesn't misrepresent content quality.
46
+ * A rejection nobody judged on its content (stale target, expiry, orphan
47
+ * purge). The "previously rejected" prompt context and the accept-rate metric
48
+ * leave these out. Expiries archived before the gate reason existed are known
49
+ * by their review reason.
74
50
  */
75
- export function isStaleTargetRejection(proposal) {
76
- return (proposal.gateDecision?.outcome === "auto-rejected" && proposal.gateDecision.reason === STALE_TARGET_GATE_REASON);
51
+ export function isProceduralRejection(proposal) {
52
+ if (proposal.gateDecision?.outcome === "auto-rejected" && PROCEDURAL_GATE_REASONS.has(proposal.gateDecision.reason)) {
53
+ return true;
54
+ }
55
+ return proposal.review?.reason?.startsWith("expired:") === true;
77
56
  }
@@ -15,7 +15,7 @@ import { resolveStashDir } from "../../core/common.js";
15
15
  import { loadConfig } from "../../core/config/config.js";
16
16
  import { resolveWriteTarget } from "../../core/write-source.js";
17
17
  import { withAssetMutationLease } from "../../indexer/index-writer-lock.js";
18
- import { diffProposal, listProposals, preflightProposalPromotion, promoteProposal, proposalContent, recoverProposalTransactionsForStash, rejectProposalDurably, resolveProposalId, revertProposal, } from "./repository.js";
18
+ import { diffProposal, listProposals, preflightProposalPromotion, promoteProposal, proposalContent, rejectProposalDurably, resolveProposalId, revertProposal, } from "./repository.js";
19
19
  import { validateProposal } from "./validators/proposals.js";
20
20
  // ── Shared helpers ──────────────────────────────────────────────────────────
21
21
  function resolveStash(stashDir) {
@@ -104,7 +104,6 @@ export async function akmProposalReject(options) {
104
104
  const config = options.config ?? loadConfig();
105
105
  const { stashDir: stash } = resolveProposalQueue(options.stashDir, options.queue, config);
106
106
  const proposalId = resolveProposalId(stash, options.id, options.ctx).id;
107
- await recoverProposalTransactionsForStash(stash, config, options.ctx, proposalId);
108
107
  const updated = rejectProposalDurably(stash, proposalId, options.reason, options.ctx, options.gateDecision);
109
108
  return {
110
109
  schemaVersion: 1,
@@ -19,15 +19,16 @@ import { resolveStashDir } from "../../core/common.js";
19
19
  import { generatedContentRejection } from "../../core/content-safety.js";
20
20
  import { UsageError } from "../../core/errors.js";
21
21
  import { appendEvent } from "../../core/events.js";
22
+ import { redactSensitiveText } from "../../core/redaction.js";
22
23
  import { resolveStandardsContext } from "../../core/standards/resolve-standards-context.js";
23
24
  import { warn } from "../../core/warn.js";
24
25
  import { deriveEntryProvenance } from "../../indexer/installations.js";
25
26
  import { fallbackAnnouncement } from "../../integrations/agent/engine-fallback.js";
26
- import { acquireLoweredExecutionDispatchLease, dispatchLoweredExecutionRequest, disposeLoweredExecutionDispatchLease, lowerResolvedExecutionRequest, redactWithLoweredExecutionDispatchLease, } from "../../integrations/agent/execution-lowering.js";
27
- import { prepareInlineExecution } from "../../integrations/agent/inline-execution.js";
27
+ import { buildExecution, resolveExecution } from "../../integrations/agent/execution.js";
28
28
  import { buildProposePrompt, parseAgentProposalPayload } from "../../integrations/agent/prompts.js";
29
+ import { assertRunnerCredentials, collectDispatchSensitiveValues, runExecution, } from "../../integrations/agent/runner-dispatch.js";
29
30
  import { baseFailureFields, enoentHintMessage, isEnoentFailure } from "../agent/agent-support.js";
30
- import { createProposal, isProposalSkipped, resolveProposalQueueTarget, } from "./repository.js";
31
+ import { createProposal, resolveProposalQueueTarget, } from "./repository.js";
31
32
  function failureEnvelope(result, type, name, engine, notices, fallbackReason = "non_zero_exit") {
32
33
  return {
33
34
  ...baseFailureFields(result, fallbackReason),
@@ -41,56 +42,43 @@ function failureEnvelope(result, type, name, engine, notices, fallbackReason = "
41
42
  function noticeFields(notices) {
42
43
  return notices.length > 0 ? { notices } : {};
43
44
  }
44
- /** Materialize required credentials through the real runner boundary, without provider I/O. */
45
- async function preflightProposalDispatch(lowered, runOptions) {
46
- return acquireLoweredExecutionDispatchLease(lowered, {
47
- ...(runOptions.envSource ? { envSource: runOptions.envSource } : {}),
48
- });
49
- }
50
45
  /** Resolve, lower, and dispatch the already-rendered proposal prompt. */
51
46
  async function dispatchProposalPrompt(prompt, config, options, onDispatchReady) {
52
47
  const current = {
53
48
  ...(options.engine !== undefined ? { engine: options.engine } : {}),
54
49
  ...(options.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
55
50
  };
56
- const prepared = prepareInlineExecution({
51
+ const prepared = resolveExecution({
57
52
  content: prompt,
58
53
  config,
59
- invocationKind: "direct",
60
54
  ...(Object.keys(current).length > 0 ? { current } : {}),
61
55
  });
62
56
  const engineName = prepared.request.engine.name;
63
57
  const announcement = fallbackAnnouncement(prepared.fallbackEngineName, engineName);
64
58
  if (announcement)
65
59
  warn(announcement);
66
- const lowered = lowerResolvedExecutionRequest(prepared.request, prepared.config);
60
+ const lowered = buildExecution(prepared.request, prepared.runner);
67
61
  const interactive = !options.runAgentOptions?.spawn;
68
62
  const runOptions = {
69
63
  stdio: interactive ? "interactive" : "captured",
70
64
  parseOutput: "text",
71
65
  ...(options.runAgentOptions ?? {}),
72
66
  };
73
- const lease = await preflightProposalDispatch(lowered, runOptions);
74
- // Materialize/validate every required symbolic credential before the entry
75
- // event opens durable state. Provider/runtime failures still occur after the
76
- // event, preserving the command-attempt observability contract.
77
- try {
78
- onDispatchReady();
79
- options.onDispatchReady?.();
80
- const result = await dispatchLoweredExecutionRequest(lowered, { runOptions, lease });
81
- return {
82
- result,
83
- engineName,
84
- ...(lowered.runner.kind === "llm" ? {} : { engineBin: lowered.runner.profile.bin }),
85
- notices: lowered.notices,
86
- lease,
87
- interactive,
88
- };
89
- }
90
- catch (error) {
91
- disposeLoweredExecutionDispatchLease(lease);
92
- throw error;
93
- }
67
+ // Validate every required symbolic credential before the entry event opens
68
+ // durable state. Provider/runtime failures still occur after the event,
69
+ // preserving the command-attempt observability contract.
70
+ assertRunnerCredentials(lowered.runner, runOptions.envSource);
71
+ onDispatchReady();
72
+ options.onDispatchReady?.();
73
+ const result = await runExecution(lowered, { runOptions });
74
+ return {
75
+ result,
76
+ engineName,
77
+ ...(lowered.runner.kind === "llm" ? {} : { engineBin: lowered.runner.profile.bin }),
78
+ notices: lowered.notices,
79
+ sensitiveValues: collectDispatchSensitiveValues(lowered.runner, {}, runOptions.envSource),
80
+ interactive,
81
+ };
94
82
  }
95
83
  /**
96
84
  * WI-8.5a — the fully-qualified `bundle//conceptId` item_ref for a proposal
@@ -158,153 +146,139 @@ export async function akmPropose(options) {
158
146
  // no synthetic persona, conversation turn, schema, or tool selection is
159
147
  // introduced while it crosses the shared resolved/lowered boundary.
160
148
  const dispatch = await dispatchProposalPrompt(prompt, config, options, () => emitProposeInvoked(target.source, options));
161
- const { result, engineName, notices, lease } = dispatch;
162
- try {
163
- if (!result.ok) {
164
- // B3: ENOENT / not-found gives an actionable hint.
165
- if (isEnoentFailure(result)) {
166
- return {
167
- ...failureEnvelope(result, options.type, options.name, engineName, notices),
168
- error: enoentHintMessage(dispatch.engineBin ?? engineName),
169
- };
170
- }
171
- return failureEnvelope(result, options.type, options.name, engineName, notices);
172
- }
173
- // 5. Resolve the proposal content.
174
- // Path A: opencode wrote the draft file — read it directly (no stdout parse).
175
- // Path B: fallback to stdout JSON parse for non-file-writing agents.
176
- let payload;
177
- if (fs.existsSync(resolvedDraftPath)) {
178
- const draftContent = fs.readFileSync(resolvedDraftPath, "utf8");
179
- fs.unlinkSync(resolvedDraftPath);
180
- payload = {
181
- ref: proposeItemRef(target.source, options.type, options.name),
182
- content: draftContent,
149
+ const { result, engineName, notices, sensitiveValues } = dispatch;
150
+ if (!result.ok) {
151
+ // B3: ENOENT / not-found gives an actionable hint.
152
+ if (isEnoentFailure(result)) {
153
+ return {
154
+ ...failureEnvelope(result, options.type, options.name, engineName, notices),
155
+ error: enoentHintMessage(dispatch.engineBin ?? engineName),
183
156
  };
184
157
  }
185
- else {
186
- // B1: When interactive mode was used and stdout is empty, the agent did not
187
- // write the draft file and stdout was not captured — surface an actionable error.
188
- if (dispatch.interactive && (result.stdout ?? "") === "") {
189
- return {
190
- schemaVersion: 2,
191
- ok: false,
192
- reason: "parse_error",
193
- error: "Agent did not write draft file and stdout was not captured (interactive mode). Check that the agent CLI understood the file-write instruction, or configure a headless profile with stdio: 'captured'.",
194
- type: options.type,
195
- name: options.name,
196
- engine: engineName,
197
- exitCode: result.exitCode,
198
- ...(result.stderr ? { stderr: result.stderr } : {}),
199
- ...noticeFields(notices),
200
- };
201
- }
202
- try {
203
- payload = parseAgentProposalPayload(result.stdout ?? "");
204
- }
205
- catch (err) {
206
- return {
207
- schemaVersion: 2,
208
- ok: false,
209
- reason: "parse_error",
210
- error: err instanceof Error ? err.message : String(err),
211
- type: options.type,
212
- name: options.name,
213
- engine: engineName,
214
- exitCode: result.exitCode,
215
- stdout: result.stdout,
216
- ...(result.stderr ? { stderr: result.stderr } : {}),
217
- ...noticeFields(notices),
218
- };
219
- }
220
- }
221
- const unsafeContent = generatedContentRejection(payload.content, redactWithLoweredExecutionDispatchLease(lease, payload.content));
222
- if (unsafeContent) {
158
+ return failureEnvelope(result, options.type, options.name, engineName, notices);
159
+ }
160
+ // 5. Resolve the proposal content.
161
+ // Path A: opencode wrote the draft file — read it directly (no stdout parse).
162
+ // Path B: fallback to stdout JSON parse for non-file-writing agents.
163
+ let payload;
164
+ if (fs.existsSync(resolvedDraftPath)) {
165
+ const draftContent = fs.readFileSync(resolvedDraftPath, "utf8");
166
+ fs.unlinkSync(resolvedDraftPath);
167
+ payload = {
168
+ ref: proposeItemRef(target.source, options.type, options.name),
169
+ content: draftContent,
170
+ };
171
+ }
172
+ else {
173
+ // B1: When interactive mode was used and stdout is empty, the agent did not
174
+ // write the draft file and stdout was not captured — surface an actionable error.
175
+ if (dispatch.interactive && (result.stdout ?? "") === "") {
223
176
  return {
224
177
  schemaVersion: 2,
225
178
  ok: false,
226
179
  reason: "parse_error",
227
- error: unsafeContent,
180
+ error: "Agent did not write draft file and stdout was not captured (interactive mode). Check that the agent CLI understood the file-write instruction, or configure a headless profile with stdio: 'captured'.",
228
181
  type: options.type,
229
182
  name: options.name,
230
183
  engine: engineName,
231
184
  exitCode: result.exitCode,
185
+ ...(result.stderr ? { stderr: result.stderr } : {}),
232
186
  ...noticeFields(notices),
233
187
  };
234
188
  }
235
- // 6. Insert the proposal. Note: we allow the agent's `ref` to normalise the
236
- // asset name (e.g. path-cleanup), but only after validating that the ref is
237
- // well-formed and the type still matches the requested type.
238
- const expectedRef = proposeItemRef(target.source, options.type, options.name);
239
- let ref = expectedRef;
240
- if (payload.ref) {
241
- let parsedRef;
242
- try {
243
- parsedRef = parseRefInput(payload.ref);
244
- }
245
- catch (err) {
246
- return {
247
- schemaVersion: 2,
248
- ok: false,
249
- reason: "parse_error",
250
- error: err instanceof Error ? err.message : String(err),
251
- type: options.type,
252
- name: options.name,
253
- engine: engineName,
254
- exitCode: result.exitCode,
255
- stdout: result.stdout,
256
- ...(result.stderr ? { stderr: result.stderr } : {}),
257
- ...noticeFields(notices),
258
- };
259
- }
260
- if (parsedRef.type !== options.type) {
261
- return {
262
- schemaVersion: 2,
263
- ok: false,
264
- reason: "parse_error",
265
- error: `Agent returned ref type ${parsedRef.type} but expected ${options.type}`,
266
- type: options.type,
267
- name: options.name,
268
- engine: engineName,
269
- exitCode: result.exitCode,
270
- stdout: result.stdout,
271
- ...(result.stderr ? { stderr: result.stderr } : {}),
272
- ...noticeFields(notices),
273
- };
274
- }
275
- ref = proposeItemRef(target.source, parsedRef.type, parsedRef.name);
189
+ try {
190
+ payload = parseAgentProposalPayload(result.stdout ?? "");
276
191
  }
277
- const createInput = {
278
- ref,
279
- source: "propose",
280
- sourceRun: `propose-${Date.now()}`,
281
- target,
282
- // User-initiated proposals always bypass dedup/cooldown guards — the
283
- // operator is explicitly asking for a new proposal.
284
- force: true,
285
- payload: {
286
- content: payload.content,
287
- ...(payload.frontmatter ? { frontmatter: payload.frontmatter } : {}),
288
- },
289
- };
290
- const proposalResult = createProposal(stash, createInput, options.ctx);
291
- // With force:true, the result is always a Proposal (never skipped).
292
- if (isProposalSkipped(proposalResult)) {
293
- // Should never happen when force:true, but be defensive.
294
- throw new Error(`Unexpected skip in propose command: ${proposalResult.message}`);
192
+ catch (err) {
193
+ return {
194
+ schemaVersion: 2,
195
+ ok: false,
196
+ reason: "parse_error",
197
+ error: err instanceof Error ? err.message : String(err),
198
+ type: options.type,
199
+ name: options.name,
200
+ engine: engineName,
201
+ exitCode: result.exitCode,
202
+ stdout: result.stdout,
203
+ ...(result.stderr ? { stderr: result.stderr } : {}),
204
+ ...noticeFields(notices),
205
+ };
295
206
  }
296
- const proposal = proposalResult;
207
+ }
208
+ const unsafeContent = generatedContentRejection(payload.content, redactSensitiveText(payload.content, sensitiveValues));
209
+ if (unsafeContent) {
297
210
  return {
298
211
  schemaVersion: 2,
299
- ok: true,
300
- proposal,
301
- ref: proposal.ref,
212
+ ok: false,
213
+ reason: "parse_error",
214
+ error: unsafeContent,
215
+ type: options.type,
216
+ name: options.name,
302
217
  engine: engineName,
303
- durationMs: result.durationMs,
218
+ exitCode: result.exitCode,
304
219
  ...noticeFields(notices),
305
220
  };
306
221
  }
307
- finally {
308
- disposeLoweredExecutionDispatchLease(lease);
222
+ // 6. Insert the proposal. Note: we allow the agent's `ref` to normalise the
223
+ // asset name (e.g. path-cleanup), but only after validating that the ref is
224
+ // well-formed and the type still matches the requested type.
225
+ const expectedRef = proposeItemRef(target.source, options.type, options.name);
226
+ let ref = expectedRef;
227
+ if (payload.ref) {
228
+ let parsedRef;
229
+ try {
230
+ parsedRef = parseRefInput(payload.ref);
231
+ }
232
+ catch (err) {
233
+ return {
234
+ schemaVersion: 2,
235
+ ok: false,
236
+ reason: "parse_error",
237
+ error: err instanceof Error ? err.message : String(err),
238
+ type: options.type,
239
+ name: options.name,
240
+ engine: engineName,
241
+ exitCode: result.exitCode,
242
+ stdout: result.stdout,
243
+ ...(result.stderr ? { stderr: result.stderr } : {}),
244
+ ...noticeFields(notices),
245
+ };
246
+ }
247
+ if (parsedRef.type !== options.type) {
248
+ return {
249
+ schemaVersion: 2,
250
+ ok: false,
251
+ reason: "parse_error",
252
+ error: `Agent returned ref type ${parsedRef.type} but expected ${options.type}`,
253
+ type: options.type,
254
+ name: options.name,
255
+ engine: engineName,
256
+ exitCode: result.exitCode,
257
+ stdout: result.stdout,
258
+ ...(result.stderr ? { stderr: result.stderr } : {}),
259
+ ...noticeFields(notices),
260
+ };
261
+ }
262
+ ref = proposeItemRef(target.source, parsedRef.type, parsedRef.name);
309
263
  }
264
+ const createInput = {
265
+ ref,
266
+ source: "propose",
267
+ sourceRun: `propose-${Date.now()}`,
268
+ target,
269
+ payload: {
270
+ content: payload.content,
271
+ ...(payload.frontmatter ? { frontmatter: payload.frontmatter } : {}),
272
+ },
273
+ };
274
+ const proposal = createProposal(stash, createInput, options.ctx);
275
+ return {
276
+ schemaVersion: 2,
277
+ ok: true,
278
+ proposal,
279
+ ref: proposal.ref,
280
+ engine: engineName,
281
+ durationMs: result.durationMs,
282
+ ...noticeFields(notices),
283
+ };
310
284
  }