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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. package/CHANGELOG.md +760 -0
  2. package/dist/akm +94 -196
  3. package/dist/cli/shared.js +6 -2
  4. package/dist/cli.js +22 -9
  5. package/dist/commands/agent/agent-dispatch.js +1 -1
  6. package/dist/commands/command/command-execution.js +24 -62
  7. package/dist/commands/feedback-cli.js +0 -1
  8. package/dist/commands/health/accept-rate.js +2 -2
  9. package/dist/commands/health/checks.js +30 -75
  10. package/dist/commands/health/config-skew.js +38 -0
  11. package/dist/commands/health/egress.js +54 -0
  12. package/dist/commands/health/html-report.js +0 -38
  13. package/dist/commands/health/improve-metrics.js +123 -562
  14. package/dist/commands/health/plugin-staleness.js +53 -3
  15. package/dist/commands/health/renderers.js +12 -4
  16. package/dist/commands/health/report-view-model.js +11 -106
  17. package/dist/commands/health/types-improve.js +4 -19
  18. package/dist/commands/health/windows.js +64 -73
  19. package/dist/commands/health.js +122 -143
  20. package/dist/commands/improve/consolidate/chunking.js +25 -100
  21. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  22. package/dist/commands/improve/consolidate.js +538 -1075
  23. package/dist/commands/improve/content-hash.js +16 -24
  24. package/dist/commands/improve/distill/content-repair.js +18 -100
  25. package/dist/commands/improve/distill-guards.js +20 -81
  26. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  27. package/dist/commands/improve/distill.js +608 -1075
  28. package/dist/commands/improve/eligibility.js +126 -400
  29. package/dist/commands/improve/execution.js +3 -5
  30. package/dist/commands/improve/extract.js +487 -1046
  31. package/dist/commands/improve/feedback-valence.js +0 -25
  32. package/dist/commands/improve/improve-cli.js +29 -166
  33. package/dist/commands/improve/improve-result-file.js +10 -66
  34. package/dist/commands/improve/improve-strategies.js +12 -7
  35. package/dist/commands/improve/improve-usage-report.js +18 -64
  36. package/dist/commands/improve/improve.js +443 -1063
  37. package/dist/commands/improve/ledger.js +114 -0
  38. package/dist/commands/improve/locks.js +2 -8
  39. package/dist/commands/improve/loop-stages.js +459 -1172
  40. package/dist/commands/improve/memory/derived-ref.js +12 -77
  41. package/dist/commands/improve/memory/memory-belief.js +14 -118
  42. package/dist/commands/improve/memory/memory-improve.js +4 -3
  43. package/dist/commands/improve/outcome-loop.js +28 -156
  44. package/dist/commands/improve/planner.js +5 -10
  45. package/dist/commands/improve/preparation.js +851 -2339
  46. package/dist/commands/improve/proactive-maintenance.js +34 -101
  47. package/dist/commands/improve/reflect-noise.js +104 -280
  48. package/dist/commands/improve/reflect.js +621 -1367
  49. package/dist/commands/improve/salience.js +46 -232
  50. package/dist/commands/improve/session-asset.js +19 -100
  51. package/dist/commands/improve/stage.js +323 -0
  52. package/dist/commands/lint/base-linter.js +19 -5
  53. package/dist/commands/proposal/drain.js +251 -644
  54. package/dist/commands/proposal/proposal-cli.js +3 -18
  55. package/dist/commands/proposal/proposal-types.js +20 -41
  56. package/dist/commands/proposal/proposal.js +1 -2
  57. package/dist/commands/proposal/propose.js +134 -160
  58. package/dist/commands/proposal/repository.js +502 -1487
  59. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  60. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  61. package/dist/commands/proposal/validators/proposals.js +13 -89
  62. package/dist/commands/read/curate.js +63 -413
  63. package/dist/commands/read/search-cli.js +16 -33
  64. package/dist/commands/read/search.js +17 -23
  65. package/dist/commands/read/show.js +2 -13
  66. package/dist/commands/sources/bundle-cli.js +25 -2
  67. package/dist/commands/sources/bundle-config-ops.js +4 -0
  68. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  69. package/dist/commands/sources/info.js +2 -11
  70. package/dist/commands/sources/installed-stashes.js +197 -746
  71. package/dist/commands/sources/schema-repair.js +98 -129
  72. package/dist/commands/sources/source-add.js +62 -12
  73. package/dist/commands/sources/source-manage.js +9 -2
  74. package/dist/commands/sources/stash-cli.js +1 -1
  75. package/dist/commands/tasks/explain.js +10 -13
  76. package/dist/commands/tasks/tasks-cli.js +9 -8
  77. package/dist/commands/tasks/tasks.js +326 -930
  78. package/dist/commands/tasks/validate.js +42 -21
  79. package/dist/commands/workflow/plan.js +22 -29
  80. package/dist/commands/workflow-cli.js +4 -4
  81. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  82. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  83. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  84. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  85. package/dist/core/adapter/execution-source.js +17 -29
  86. package/dist/core/asset/asset-placement.js +4 -13
  87. package/dist/core/asset/resolve-ref.js +1 -1
  88. package/dist/core/bundle-id.js +42 -5
  89. package/dist/core/bundle-rename.js +291 -0
  90. package/dist/core/config/config-io.js +1 -2
  91. package/dist/core/config/config-schema.js +1 -33
  92. package/dist/core/config/config-walker.js +1 -1
  93. package/dist/core/config/config.js +163 -68
  94. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  95. package/dist/core/config/schema/embedding.js +20 -5
  96. package/dist/core/config/schema/engines.js +5 -0
  97. package/dist/core/config/schema/execution.js +1 -1
  98. package/dist/core/config/schema/experimental.js +1 -1
  99. package/dist/core/config/schema/improve-processes.js +21 -95
  100. package/dist/core/config/schema/improve.js +4 -42
  101. package/dist/core/config/schema/scheduler.js +12 -12
  102. package/dist/core/config/schema/search.js +6 -22
  103. package/dist/core/env-secret-ref.js +0 -1
  104. package/dist/core/errors.js +8 -9
  105. package/dist/core/file-lock.js +76 -173
  106. package/dist/core/logs-db.js +2 -2
  107. package/dist/core/paths.js +0 -27
  108. package/dist/core/redaction.js +109 -2
  109. package/dist/core/run-lock.js +2 -5
  110. package/dist/core/spawn-env.js +1 -1
  111. package/dist/core/state/migrations.js +108 -61
  112. package/dist/core/state-db-scope.js +2 -4
  113. package/dist/core/state-db.js +126 -692
  114. package/dist/core/type-presentation.js +1 -9
  115. package/dist/core/write-source.js +293 -1012
  116. package/dist/execution/input-contract.js +1 -1
  117. package/dist/execution/resolved-request.js +135 -689
  118. package/dist/execution/source.js +63 -257
  119. package/dist/execution/target-ref.js +1 -1
  120. package/dist/indexer/bundle-identity-guard.js +2 -2
  121. package/dist/indexer/db/graph-db.js +106 -46
  122. package/dist/indexer/ensure-index.js +44 -85
  123. package/dist/indexer/graph/graph-extraction.js +340 -562
  124. package/dist/indexer/graph/graph-related.js +130 -0
  125. package/dist/indexer/index-rebuild-lock.js +3 -11
  126. package/dist/indexer/index-writer-lock.js +8 -17
  127. package/dist/indexer/index-written-assets.js +139 -151
  128. package/dist/indexer/indexer.js +524 -846
  129. package/dist/indexer/materialize-embeddings.js +60 -397
  130. package/dist/indexer/passes/memory-inference.js +81 -90
  131. package/dist/indexer/passes/metadata.js +132 -200
  132. package/dist/indexer/read-preflight.js +0 -7
  133. package/dist/indexer/scan/doc-to-entry.js +1 -3
  134. package/dist/indexer/scan/drain-dir.js +1 -1
  135. package/dist/indexer/search/db-search.js +181 -590
  136. package/dist/indexer/search/fts-query.js +30 -41
  137. package/dist/indexer/search/ranking.js +28 -154
  138. package/dist/indexer/search/search-attribution.js +12 -32
  139. package/dist/indexer/search/search-fields.js +11 -15
  140. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  141. package/dist/indexer/search/search-source.js +1 -4
  142. package/dist/indexer/usage/usage-events.js +2 -7
  143. package/dist/integrations/agent/engine-fallback.js +23 -40
  144. package/dist/integrations/agent/engine-resolution.js +93 -183
  145. package/dist/integrations/agent/execution.js +507 -0
  146. package/dist/integrations/agent/model-map.js +28 -156
  147. package/dist/integrations/agent/request-lowering.js +66 -141
  148. package/dist/integrations/agent/runner-dispatch.js +143 -321
  149. package/dist/integrations/agent/runner.js +54 -14
  150. package/dist/integrations/lockfile.js +53 -101
  151. package/dist/llm/embedders/deterministic.js +2 -3
  152. package/dist/llm/embedders/profile.js +71 -0
  153. package/dist/llm/embedders/remote.js +10 -15
  154. package/dist/llm/graph-extract.js +3 -12
  155. package/dist/llm/index-passes.js +3 -5
  156. package/dist/llm/memory-infer.js +1 -2
  157. package/dist/llm/metadata-enhance.js +1 -2
  158. package/dist/llm/structured-call.js +5 -24
  159. package/dist/output/generic-render.js +23 -11
  160. package/dist/output/html-render.js +13 -10
  161. package/dist/output/render-registry.js +3 -32
  162. package/dist/output/shapes/helpers.js +2 -34
  163. package/dist/output/shapes/passthrough.js +1 -9
  164. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  165. package/dist/output/text/command-format.js +60 -23
  166. package/dist/output/text/helpers.js +1 -1
  167. package/dist/output/text/migrate.js +5 -14
  168. package/dist/output/text/proposal-format.js +1 -2
  169. package/dist/output/text/workflow-format.js +0 -32
  170. package/dist/output/text.js +2 -0
  171. package/dist/registry/factory.js +4 -19
  172. package/dist/registry/network.js +66 -220
  173. package/dist/registry/providers/index.js +0 -2
  174. package/dist/registry/providers/skills-sh.js +3 -14
  175. package/dist/registry/providers/static-index.js +24 -26
  176. package/dist/registry/resolve.js +55 -131
  177. package/dist/scripts/akm-migrate-node.js +43940 -93320
  178. package/dist/scripts/akm-migrate.js +43700 -93078
  179. package/dist/setup/registry-stash-loader.js +4 -13
  180. package/dist/setup/semantic-assets.js +3 -44
  181. package/dist/setup/setup.js +1 -1
  182. package/dist/setup/steps/tasks.js +25 -15
  183. package/dist/sources/provider-factory.js +17 -18
  184. package/dist/sources/providers/filesystem.js +2 -3
  185. package/dist/sources/providers/git-install.js +7 -1
  186. package/dist/sources/providers/git-provider.js +0 -3
  187. package/dist/sources/providers/git-stash.js +0 -17
  188. package/dist/sources/providers/npm.js +2 -4
  189. package/dist/sources/providers/provider-utils.js +5 -10
  190. package/dist/sources/providers/website.js +0 -2
  191. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  192. package/dist/sources/website-url.js +2 -2
  193. package/dist/storage/database.js +9 -35
  194. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  195. package/dist/storage/repositories/index-connection.js +34 -70
  196. package/dist/storage/repositories/index-entries-repository.js +69 -111
  197. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  198. package/dist/storage/repositories/index-entry-schema.js +83 -269
  199. package/dist/storage/repositories/index-fts-repository.js +86 -256
  200. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  201. package/dist/storage/repositories/index-meta-repository.js +6 -4
  202. package/dist/storage/repositories/index-schema.js +192 -220
  203. package/dist/storage/repositories/index-utility-repository.js +8 -29
  204. package/dist/storage/repositories/index-vec-repository.js +133 -414
  205. package/dist/storage/repositories/outcome-repository.js +2 -1
  206. package/dist/storage/repositories/proposals-repository.js +35 -0
  207. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  208. package/dist/storage/repositories/task-history-repository.js +26 -4
  209. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  210. package/dist/storage/sqlite-migrations.js +136 -0
  211. package/dist/storage/sqlite-pragmas.js +11 -9
  212. package/dist/storage/sqlite-transaction.js +170 -0
  213. package/dist/storage/state-db-integrity.js +34 -27
  214. package/dist/tasks/activation-config.js +134 -62
  215. package/dist/tasks/backends/cron.js +129 -277
  216. package/dist/tasks/backends/exec-utils.js +2 -5
  217. package/dist/tasks/backends/launchd.js +125 -745
  218. package/dist/tasks/backends/schtasks.js +101 -620
  219. package/dist/tasks/prepare/prepare-support.js +5 -15
  220. package/dist/tasks/prepare/prepare.js +0 -2
  221. package/dist/tasks/resolve-akm-bin.js +20 -79
  222. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  223. package/dist/tasks/scheduler-binding.js +18 -238
  224. package/dist/tasks/scheduler-invocation.js +52 -52
  225. package/dist/tasks/scheduler-lock.js +53 -0
  226. package/dist/tasks/scheduler-sync.js +361 -751
  227. package/dist/tasks/source/parse-task-source.js +160 -10
  228. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  229. package/dist/tasks/source/task-to-v4.js +2 -2
  230. package/dist/workflows/authoring/authoring.js +3 -12
  231. package/dist/workflows/compile.js +211 -0
  232. package/dist/workflows/concurrency-policy.js +13 -74
  233. package/dist/workflows/exec/child-invocation.js +3 -17
  234. package/dist/workflows/exec/child-workflow.js +32 -141
  235. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  236. package/dist/workflows/exec/environment.js +98 -0
  237. package/dist/workflows/exec/exec-unit.js +33 -140
  238. package/dist/workflows/exec/frozen-judge.js +7 -59
  239. package/dist/workflows/exec/native-executor.js +82 -341
  240. package/dist/workflows/exec/param-secrets.js +29 -47
  241. package/dist/workflows/exec/run-workflow.js +154 -387
  242. package/dist/workflows/exec/scheduler.js +9 -36
  243. package/dist/workflows/exec/step-work.js +127 -430
  244. package/dist/workflows/exec/unit-dispatch.js +11 -63
  245. package/dist/workflows/exec/unit-writer.js +8 -52
  246. package/dist/workflows/exec/worktree.js +39 -273
  247. package/dist/workflows/freeze/child-output-references.js +4 -15
  248. package/dist/workflows/freeze/environment.js +99 -92
  249. package/dist/workflows/freeze/freeze.js +172 -0
  250. package/dist/workflows/freeze/step-values.js +19 -21
  251. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  252. package/dist/workflows/freeze/targets/command.js +10 -33
  253. package/dist/workflows/freeze/targets/script.js +5 -12
  254. package/dist/workflows/freeze/targets/shell.js +3 -6
  255. package/dist/workflows/freeze/targets/task.js +25 -80
  256. package/dist/workflows/freeze/task-bindings.js +20 -67
  257. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  258. package/dist/workflows/ir/params.js +6 -51
  259. package/dist/workflows/ir/plan-hash.js +2 -34
  260. package/dist/workflows/parser.js +140 -43
  261. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  262. package/dist/workflows/renderer.js +36 -69
  263. package/dist/workflows/resource-limits.js +12 -120
  264. package/dist/workflows/runtime/agent-identity.js +8 -40
  265. package/dist/workflows/runtime/run-outputs.js +3 -6
  266. package/dist/workflows/runtime/run-plan.js +316 -0
  267. package/dist/workflows/runtime/runs.js +48 -200
  268. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  269. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  270. package/dist/workflows/validate-summary.js +2 -7
  271. package/docs/integration/bundling-akm.md +49 -42
  272. package/docs/migration/README.md +1 -0
  273. package/docs/migration/release-notes/0.9.17.md +41 -0
  274. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  275. package/docs/reference/cli.md +182 -125
  276. package/docs/reference/configuration.md +49 -56
  277. package/docs/reference/data-and-telemetry.md +19 -20
  278. package/docs/reference/tasks.md +86 -38
  279. package/docs/reference/workflow-schema.md +14 -18
  280. package/docs/reference/workflows.md +6 -9
  281. package/package.json +1 -1
  282. package/schemas/akm-config.json +87 -406
  283. package/dist/commands/health/advisories.js +0 -150
  284. package/dist/commands/health/metrics.js +0 -329
  285. package/dist/commands/health/surfaces.js +0 -102
  286. package/dist/commands/improve/anti-collapse.js +0 -83
  287. package/dist/commands/improve/collapse-detector.js +0 -432
  288. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  289. package/dist/commands/improve/consolidate/merge.js +0 -146
  290. package/dist/commands/improve/distill/promote-memory.js +0 -329
  291. package/dist/commands/improve/distill/quality-gate.js +0 -500
  292. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  293. package/dist/commands/improve/proposal-envelope.js +0 -31
  294. package/dist/commands/improve/run-context.js +0 -123
  295. package/dist/commands/improve/shared.js +0 -21
  296. package/dist/commands/improve/source-identity.js +0 -28
  297. package/dist/commands/improve/triage.js +0 -96
  298. package/dist/commands/proposal/drain-policies.js +0 -151
  299. package/dist/commands/sources/update-transaction.js +0 -220
  300. package/dist/core/action-contributors.js +0 -28
  301. package/dist/core/config/config-version-shim.js +0 -101
  302. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  303. package/dist/core/fs-txn.js +0 -405
  304. package/dist/core/lexical-score.js +0 -25
  305. package/dist/core/maintenance-barrier.js +0 -167
  306. package/dist/execution/executable-identity.js +0 -105
  307. package/dist/execution/guarded-source.js +0 -441
  308. package/dist/indexer/graph/graph-boost.js +0 -427
  309. package/dist/indexer/graph/graph-dedup.js +0 -95
  310. package/dist/indexer/search/name-match.js +0 -35
  311. package/dist/indexer/search/ranking-contributors.js +0 -515
  312. package/dist/indexer/walk/project-context.js +0 -192
  313. package/dist/integrations/agent/execution-cascade.js +0 -566
  314. package/dist/integrations/agent/execution-definitions.js +0 -202
  315. package/dist/integrations/agent/execution-lowering.js +0 -841
  316. package/dist/integrations/agent/execution-preparation.js +0 -98
  317. package/dist/integrations/agent/inline-execution.js +0 -74
  318. package/dist/registry/create-provider-registry.js +0 -29
  319. package/dist/registry/pinned-request-helper.js +0 -247
  320. package/dist/registry/pinned-transport.js +0 -717
  321. package/dist/sources/providers/index.js +0 -14
  322. package/dist/storage/engines/sqlite-migrations.js +0 -271
  323. package/dist/storage/repositories/canaries-repository.js +0 -107
  324. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  325. package/dist/storage/repositories/registry-cache.js +0 -113
  326. package/dist/tasks/scheduler-sync-preview.js +0 -52
  327. package/dist/workflows/freeze/resolve-steps.js +0 -86
  328. package/dist/workflows/freeze/source-freeze.js +0 -64
  329. package/dist/workflows/ir/compile.js +0 -321
  330. package/dist/workflows/ir/environment-v4.js +0 -330
  331. package/dist/workflows/ir/freeze-v4.js +0 -153
  332. package/dist/workflows/ir/schema-v4.js +0 -745
  333. package/dist/workflows/ir/schema.js +0 -354
  334. package/dist/workflows/program/schema.js +0 -78
  335. package/dist/workflows/runtime/checkin.js +0 -57
  336. package/dist/workflows/runtime/plan-classifier.js +0 -196
  337. package/dist/workflows/runtime/unit-checkin.js +0 -45
  338. package/dist/workflows/runtime/unit-phases.js +0 -20
  339. package/dist/workflows/schema.js +0 -4
  340. package/dist/workflows/source-ir/compile.js +0 -200
  341. package/dist/workflows/source-ir/program.js +0 -50
  342. package/dist/workflows/source-ir/result.js +0 -26
  343. package/dist/workflows/source-ir/schema.js +0 -786
  344. package/dist/workflows/source-ir/triggers.js +0 -79
  345. package/dist/workflows/source-ir/uses.js +0 -40
  346. package/dist/workflows/validator.js +0 -60
@@ -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
  }