akm-cli 0.9.31 → 0.10.261001-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. package/CHANGELOG.md +409 -0
  2. package/STABILITY.md +99 -57
  3. package/dist/api-node.mjs +20 -0
  4. package/dist/api.d.ts +23 -0
  5. package/dist/api.js +45 -0
  6. package/dist/assets/hints/cli-hints-full.md +15 -29
  7. package/dist/assets/hints/cli-hints-short.md +2 -2
  8. package/dist/assets/improve-strategies/default.json +3 -3
  9. package/dist/assets/prompts/consolidate-pair.md +9 -7
  10. package/dist/assets/stash-skeleton/README.md +1 -1
  11. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
  12. package/dist/cli/shared.js +31 -48
  13. package/dist/cli/unknown-flags.js +6 -43
  14. package/dist/cli.js +8 -34
  15. package/dist/commands/agent/contribute-cli.js +1 -1
  16. package/dist/commands/completions.js +1 -2
  17. package/dist/commands/config-cli.js +5 -28
  18. package/dist/commands/env/env-cli.js +5 -5
  19. package/dist/commands/env/secret-cli.js +2 -2
  20. package/dist/commands/feedback-cli.js +75 -49
  21. package/dist/commands/health/checks.js +41 -16
  22. package/dist/commands/health/plugin-staleness.js +52 -22
  23. package/dist/commands/improve/autonomy-gate.js +5 -3
  24. package/dist/commands/improve/consolidate/chunking.js +3 -10
  25. package/dist/commands/improve/consolidate/continuity-check.js +4 -4
  26. package/dist/commands/improve/consolidate/pair-pass.js +29 -10
  27. package/dist/commands/improve/consolidate.js +10 -65
  28. package/dist/commands/improve/distill/lesson-update.js +91 -0
  29. package/dist/commands/improve/distill-guards.js +1 -43
  30. package/dist/commands/improve/distill.js +148 -21
  31. package/dist/commands/improve/eligibility.js +14 -1
  32. package/dist/commands/improve/extract-cli.js +1 -1
  33. package/dist/commands/improve/extract-prompt.js +17 -7
  34. package/dist/commands/improve/extract.js +5 -7
  35. package/dist/commands/improve/improve-cli.js +92 -106
  36. package/dist/commands/improve/improve-strategies.js +8 -12
  37. package/dist/commands/improve/improve.js +134 -52
  38. package/dist/commands/improve/loop-stages.js +18 -5
  39. package/dist/commands/improve/planner.js +0 -1
  40. package/dist/commands/improve/preparation.js +40 -99
  41. package/dist/commands/improve/proactive-maintenance.js +2 -2
  42. package/dist/commands/improve/reflect-noise.js +3 -55
  43. package/dist/commands/improve/reflect.js +29 -34
  44. package/dist/commands/improve/retrieval-queries.js +37 -0
  45. package/dist/commands/improve/retrieval-scope.js +2 -2
  46. package/dist/commands/improve/salience.js +2 -9
  47. package/dist/commands/improve/session-asset.js +4 -1
  48. package/dist/commands/improve/stage.js +23 -12
  49. package/dist/commands/lint/index.js +5 -20
  50. package/dist/commands/observability-cli.js +3 -9
  51. package/dist/commands/proposal/drain.js +43 -6
  52. package/dist/commands/proposal/proposal-cli.js +11 -31
  53. package/dist/commands/proposal/repository.js +20 -14
  54. package/dist/commands/proposal/validators/proposal-quality-validators.js +0 -3
  55. package/dist/commands/read/knowledge.js +3 -3
  56. package/dist/commands/read/remember-cli.js +0 -13
  57. package/dist/commands/read/search-cli.js +29 -97
  58. package/dist/commands/read/search.js +0 -11
  59. package/dist/commands/read/show.js +0 -19
  60. package/dist/commands/sources/plugin-upgrade.js +164 -101
  61. package/dist/commands/sources/sources-cli.js +1 -15
  62. package/dist/commands/sources/stash-cli.js +6 -14
  63. package/dist/commands/tasks/tasks-cli.js +4 -115
  64. package/dist/commands/workflow/plan.js +11 -33
  65. package/dist/commands/workflow-cli.js +2 -7
  66. package/dist/core/adapter/adapter-ids.js +1 -2
  67. package/dist/core/adapter/adapters/agent-skills-adapter.js +0 -4
  68. package/dist/core/adapter/adapters/akm-adapter.js +9 -48
  69. package/dist/core/adapter/adapters/akm-lint.js +10 -26
  70. package/dist/core/adapter/adapters/akm-metadata.js +2 -72
  71. package/dist/core/adapter/adapters/akm-task-adapter.js +0 -5
  72. package/dist/core/adapter/adapters/akm-workflow-adapter.js +9 -28
  73. package/dist/core/adapter/adapters/dotenv-adapter.js +1 -20
  74. package/dist/core/adapter/adapters/generic-files-adapter.js +0 -10
  75. package/dist/core/adapter/adapters/llm-wiki-adapter.js +0 -4
  76. package/dist/core/adapter/adapters/tool-dir-shared.js +0 -24
  77. package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -4
  78. package/dist/core/adapter/recognize-match.js +3 -4
  79. package/dist/core/common.js +18 -2
  80. package/dist/core/config/config-schema.js +12 -15
  81. package/dist/core/config/config-types.js +6 -15
  82. package/dist/core/config/config-walker.js +6 -23
  83. package/dist/core/config/config.js +17 -80
  84. package/dist/core/config/engine-semantics.js +7 -3
  85. package/dist/core/config/schema/engines.js +7 -7
  86. package/dist/core/config/schema/improve-processes.js +10 -63
  87. package/dist/core/config/schema/improve.js +2 -21
  88. package/dist/core/config/schema/index-config.js +6 -39
  89. package/dist/core/env-secret-ref.js +2 -45
  90. package/dist/core/errors.js +1 -2
  91. package/dist/core/extra-params.js +2 -86
  92. package/dist/core/file-lock.js +2 -6
  93. package/dist/core/improve-result.js +13 -1
  94. package/dist/core/mutation-target.js +2 -2
  95. package/dist/core/paths.js +4 -0
  96. package/dist/core/recognition-util.js +4 -5
  97. package/dist/core/run-lock.js +1 -1
  98. package/dist/core/subprocess.js +49 -0
  99. package/dist/core/warn.js +21 -4
  100. package/dist/core/write-source.js +3 -3
  101. package/dist/execution/target-ref.js +1 -2
  102. package/dist/indexer/indexer.js +15 -6
  103. package/dist/indexer/passes/memory-inference.js +15 -6
  104. package/dist/indexer/search/db-search.js +49 -36
  105. package/dist/indexer/search/fts-query.js +0 -19
  106. package/dist/indexer/search/ranking.js +29 -1
  107. package/dist/indexer/usage/usage-events.js +21 -16
  108. package/dist/integrations/agent/engine-resolution.js +5 -2
  109. package/dist/integrations/agent/index.js +1 -1
  110. package/dist/integrations/agent/profiles.js +41 -98
  111. package/dist/integrations/agent/request-lowering.js +3 -3
  112. package/dist/integrations/harnesses/aider/index.js +5 -0
  113. package/dist/integrations/harnesses/amazonq/index.js +1 -0
  114. package/dist/integrations/harnesses/claude/config-import.js +2 -3
  115. package/dist/integrations/harnesses/claude/index.js +5 -0
  116. package/dist/integrations/harnesses/codex/index.js +1 -0
  117. package/dist/integrations/harnesses/copilot/index.js +1 -0
  118. package/dist/integrations/harnesses/gemini/index.js +1 -0
  119. package/dist/integrations/harnesses/index.js +18 -39
  120. package/dist/integrations/harnesses/opencode/agent-builder.js +60 -35
  121. package/dist/integrations/harnesses/opencode/config-import.js +121 -52
  122. package/dist/integrations/harnesses/opencode/index.js +22 -0
  123. package/dist/integrations/harnesses/opencode/plugin-layout.js +68 -0
  124. package/dist/integrations/harnesses/opencode/session-log-types.js +12 -0
  125. package/dist/integrations/harnesses/opencode/session-log-v1.js +72 -0
  126. package/dist/integrations/harnesses/opencode/session-log-v2.js +140 -0
  127. package/dist/integrations/harnesses/opencode/session-log.js +104 -115
  128. package/dist/integrations/harnesses/opencode/version.js +98 -0
  129. package/dist/integrations/harnesses/opencode-sdk/{harness.js → index.js} +5 -17
  130. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +105 -206
  131. package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +199 -0
  132. package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +254 -0
  133. package/dist/integrations/harnesses/opencode-sdk/wire.js +66 -0
  134. package/dist/integrations/harnesses/openhands/index.js +1 -0
  135. package/dist/integrations/harnesses/pi/index.js +1 -0
  136. package/dist/integrations/harnesses/shared.js +2 -0
  137. package/dist/integrations/harnesses/types.js +2 -0
  138. package/dist/llm/client.js +41 -11
  139. package/dist/output/cli-hints.js +1 -1
  140. package/dist/output/context.js +10 -19
  141. package/dist/output/format-exempt.js +5 -8
  142. package/dist/output/shapes/helpers.js +1 -22
  143. package/dist/output/shapes/passthrough.js +0 -1
  144. package/dist/output/shapes.js +3 -31
  145. package/dist/output/stdout.js +5 -1
  146. package/dist/output/text/command-format.js +6 -1
  147. package/dist/output/text/workflow-format.js +4 -22
  148. package/dist/scripts/akm-migrate-node.js +15745 -16711
  149. package/dist/scripts/akm-migrate.js +16318 -17280
  150. package/dist/setup/detect.js +10 -4
  151. package/dist/setup/harness-config-import.js +5 -14
  152. package/dist/setup/setup.js +1 -1
  153. package/dist/setup/steps/tasks.js +12 -13
  154. package/dist/sources/providers/git-stash.js +94 -13
  155. package/dist/storage/repositories/index-utility-repository.js +2 -32
  156. package/dist/storage/repositories/index-vec-repository.js +4 -0
  157. package/dist/storage/repositories/task-history-repository.js +0 -5
  158. package/dist/storage/repositories/workflow-runs-repository.js +5 -15
  159. package/dist/tasks/embedded.js +2 -1
  160. package/dist/tasks/run/run-command-task.js +9 -1
  161. package/dist/tasks/run/run-workflow-task.js +4 -3
  162. package/dist/tasks/run/task-history.js +0 -2
  163. package/dist/tasks/run/task-log.js +38 -1
  164. package/dist/tasks/schedule-gates.js +39 -0
  165. package/dist/tasks/scheduler-binding.js +0 -16
  166. package/dist/tasks/scheduler-sync.js +3 -97
  167. package/dist/tasks/source/bounded-document.js +1 -1
  168. package/dist/tasks/source/task-source-v4.js +2 -12
  169. package/dist/tasks/task-run-reserved-flags.js +2 -31
  170. package/dist/workflows/authoring/authoring.js +6 -6
  171. package/dist/workflows/compile.js +8 -65
  172. package/dist/workflows/exec/child-workflow.js +22 -3
  173. package/dist/workflows/exec/native-executor.js +12 -147
  174. package/dist/workflows/exec/run-workflow.js +31 -103
  175. package/dist/workflows/exec/step-work.js +9 -178
  176. package/dist/workflows/exec/unit-dispatch.js +0 -10
  177. package/dist/workflows/freeze/environment.js +3 -44
  178. package/dist/workflows/freeze/freeze.js +8 -41
  179. package/dist/workflows/freeze/targets/child-workflow.js +27 -63
  180. package/dist/workflows/freeze/targets/command.js +2 -16
  181. package/dist/workflows/freeze/targets/shell.js +0 -2
  182. package/dist/workflows/freeze/task-bindings.js +2 -28
  183. package/dist/workflows/ir/params.js +12 -2
  184. package/dist/workflows/parser.js +82 -232
  185. package/dist/workflows/plan.js +1 -1
  186. package/dist/workflows/renderer.js +10 -19
  187. package/dist/workflows/runtime/run-plan.js +11 -53
  188. package/dist/workflows/runtime/runs.js +4 -27
  189. package/dist/workflows/source-files.js +12 -16
  190. package/dist/workflows/source-semantics.js +1 -93
  191. package/docs/README.md +1 -1
  192. package/docs/agents/README.md +3 -3
  193. package/docs/agents/agent-install.md +1 -1
  194. package/docs/architecture/0.10-process-rules.md +827 -0
  195. package/docs/architecture/adapters.md +17 -31
  196. package/docs/architecture/architecture.md +4 -5
  197. package/docs/architecture/improvement.md +115 -76
  198. package/docs/architecture/internals/improve-workflow.md +22 -16
  199. package/docs/architecture/internals/indexing.md +1 -1
  200. package/docs/architecture/internals/search.md +1 -2
  201. package/docs/architecture/internals/storage-locations.md +6 -6
  202. package/docs/architecture/persisted-data-compat.md +13 -4
  203. package/docs/architecture/specs/0.9.0-decisions.md +6 -2
  204. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +2 -2
  205. package/docs/architecture/specs/workflow-format-unification.md +1 -6
  206. package/docs/architecture/testing/manual-testing-checklist.md +21 -30
  207. package/docs/architecture/testing/task-workflow-manual-tests.md +106 -203
  208. package/docs/architecture/testing/testing-workflow.md +1 -1
  209. package/docs/architecture/workflow-engine.md +5 -56
  210. package/docs/guides/author-workflows.md +39 -69
  211. package/docs/guides/bundles.md +3 -1
  212. package/docs/guides/capture-knowledge.md +1 -1
  213. package/docs/guides/claude-code-vs-akm-workflows.md +1 -2
  214. package/docs/guides/discover-and-load.md +4 -4
  215. package/docs/guides/getting-started.md +1 -1
  216. package/docs/guides/improve-the-library.md +10 -9
  217. package/docs/guides/recipes/headless-install.md +2 -2
  218. package/docs/guides/run-workflows.md +1 -1
  219. package/docs/guides/scheduling.md +9 -1
  220. package/docs/guides/use-with-any-agent.md +49 -4
  221. package/docs/integration/bundling-akm.md +7 -6
  222. package/docs/maintainers/curate-workmap.md +1 -2
  223. package/docs/maintainers/release-checklist.md +33 -1
  224. package/docs/migration/README.md +2 -0
  225. package/docs/migration/release-notes/0.10.0.md +201 -0
  226. package/docs/migration/release-notes/README.md +1 -0
  227. package/docs/migration/v0.9-to-v0.10.md +507 -0
  228. package/docs/posts/akm-command-tour.md +3 -3
  229. package/docs/product-surface.md +1 -1
  230. package/docs/reference/README.md +1 -0
  231. package/docs/reference/api.md +65 -0
  232. package/docs/reference/asset-types.md +3 -5
  233. package/docs/reference/bundle-types.md +2 -4
  234. package/docs/reference/cli.md +160 -188
  235. package/docs/reference/configuration.md +101 -20
  236. package/docs/reference/data-and-telemetry.md +2 -2
  237. package/docs/reference/env-and-secrets.md +2 -2
  238. package/docs/reference/supported-formats.md +3 -4
  239. package/docs/reference/tasks.md +12 -19
  240. package/docs/reference/website-sources.md +1 -1
  241. package/docs/reference/workflow-schema.md +89 -317
  242. package/docs/reference/workflows.md +20 -48
  243. package/package.json +12 -2
  244. package/schemas/akm-config.json +2 -243
  245. package/schemas/akm-task.json +2 -3
  246. package/schemas/akm-workflow.json +47 -84
  247. package/dist/assets/improve-strategies/catchup.json +0 -41
  248. package/dist/assets/improve-strategies/proactive-maintenance.json +0 -24
  249. package/dist/assets/improve-strategies/quick.json +0 -17
  250. package/dist/assets/improve-strategies/reflect-distill.json +0 -29
  251. package/dist/assets/improve-strategies/thorough.json +0 -49
  252. package/dist/assets/prompts/retrieval-relevance-judge.md +0 -6
  253. package/dist/assets/tasks/improve/akm-improve-catchup.yml +0 -6
  254. package/dist/assets/tasks/improve/akm-improve-frequent.yml +0 -4
  255. package/dist/assets/tasks/improve/akm-improve-nightly.yml +0 -4
  256. package/dist/cli/retired-commands.js +0 -118
  257. package/dist/commands/improve/retrieval-gate.js +0 -132
  258. package/dist/commands/tasks/validate.js +0 -176
  259. package/dist/core/config/legacy-source-shape-shim.js +0 -117
  260. package/dist/indexer/feedback/utility-policy.js +0 -75
  261. package/dist/integrations/harnesses/ids.js +0 -28
  262. package/dist/tasks/source/task-source-v3-frozen.js +0 -424
  263. package/dist/tasks/source/task-to-v4.js +0 -863
  264. package/dist/workflows/exec/worktree.js +0 -372
  265. package/dist/workflows/freeze/child-output-references.js +0 -83
  266. package/dist/workflows/freeze/identity.js +0 -22
  267. package/dist/workflows/freeze/targets/script.js +0 -50
  268. package/dist/workflows/freeze/targets/task.js +0 -124
  269. package/dist/workflows/github-yaml.js +0 -506
  270. package/dist/workflows/runtime/run-outputs.js +0 -80
@@ -126,10 +126,10 @@ separate cleanup that includes restoring the OS scheduler.
126
126
  | WF-9 | Pre-`irVersion`-5 stored plan is retired | No | Any | Yes | — |
127
127
  | WF-10 | Removed `inherit_env` is rejected | No | Any | Yes | — |
128
128
  | INT-1 | A task that runs a workflow | No | Any | Yes | — |
129
- | INT-2 | A workflow step that targets a task (+ typed input binding) | No | Any | Yes | — |
129
+ | INT-2 | (removed in 0.10: a workflow step that targets a task) | — | — | — | — |
130
130
  | INT-3 | Failure propagation: `task history` vs `workflow status` | No | Any | Yes | — |
131
131
  | INT-4 | Identity across the seam: abandon then re-invoke | No | Any | Yes | — |
132
- | INT-5 | Shipped `improve/*.yml` tasks as a real-world case | No | Any | Yes | — |
132
+ | INT-5 | Shipped `improve/*.yml` tasks as a real-world case (`task explain` only) | No | Any | Yes | — |
133
133
  | DT-1 | `task add` happy path installs a real cron entry | **Yes** | Linux (cron) | Partial | — |
134
134
  | DT-2 | `task add --disabled` writes a disabled binding | **Yes** | Linux (cron) | Partial | — |
135
135
  | DT-3 | `task sync` drift reconciliation (shell-target task) | **Yes** | Linux (cron), VM recommended | No — **UNVERIFIED** | — |
@@ -670,7 +670,7 @@ incorrect.
670
670
  **Why it matters:** child workflows are the headline capability of this
671
671
  release. A parent step composing another workflow must show up correctly in
672
672
  the frozen plan graph before anything runs, and actually drive the child to
673
- completion, folding its exported output back into the parent step's
673
+ completion, folding its last step output back into the parent step's
674
674
  artifact.
675
675
 
676
676
  **Setup:**
@@ -679,7 +679,7 @@ artifact.
679
679
  ```markdown
680
680
  ---
681
681
  type: workflow
682
- description: Child workflow composed by parent.yml (exec-only, no engine required)
682
+ description: Child workflow composed by parent.md (exec-only, no engine required)
683
683
  updated: 2026-01-01
684
684
  tags: [example]
685
685
  params:
@@ -689,9 +689,6 @@ steps:
689
689
  unit:
690
690
  exec:
691
691
  command: ["bash", "-lc", "echo child-said-hello"]
692
- outputs:
693
- message:
694
- from: steps.greet.output
695
692
  ---
696
693
 
697
694
  # Child Workflow
@@ -701,20 +698,22 @@ outputs:
701
698
  Print a fixed greeting.
702
699
  ```
703
700
 
704
- `$AKM_BUNDLE_DIR/workflows/parent.yml` (composition requires a
705
- GitHub-shaped `.yml` parent — Markdown frontmatter has no `uses:` key):
706
- ```yaml
707
- name: Parent composes child
708
- on:
709
- workflow_dispatch: {}
710
- jobs:
711
- main:
712
- runs-on: [self-hosted]
713
- steps:
714
- - id: dispatch
715
- uses: workflows/child
716
- with:
717
- greeting: hello-from-parent
701
+ `$AKM_BUNDLE_DIR/workflows/parent.md` (child workflows are Experimental):
702
+ ```markdown
703
+ ---
704
+ type: workflow
705
+ description: Parent composes child
706
+ steps:
707
+ - id: dispatch
708
+ unit:
709
+ workflow: workflows/child
710
+ with:
711
+ greeting: hello-from-parent
712
+ ---
713
+
714
+ ## dispatch
715
+
716
+ Run the child workflow.
718
717
  ```
719
718
 
720
719
  **Part A — `plan` (no writes, no execution):** `akm workflow plan
@@ -724,17 +723,15 @@ workflows/parent --format json`
724
723
  "child-workflow"`; `.steps[0].inputBindings == [{"name": "greeting", "kind":
725
724
  "literal", "value": "hello-from-parent"}]`; `.steps[0].expansion.via ==
726
725
  "child"`, `.expansion.childRef == "bundle//workflows/child"`,
727
- `.expansion.childVia == "direct"`, `.expansion.childOutputs ==
728
- ["message"]`; `.steps[0].expansion.steps` contains the child's own frozen
726
+ `.steps[0].expansion.steps` contains the child's own frozen
729
727
  graph (one entry, `stepId: "greet"`, `targetKind: "shell"`).
730
728
 
731
729
  **Part B — `run` (actually executes):** `akm workflow run workflows/parent
732
730
  --format json`, then `akm workflow status <run-id> --format json`
733
731
 
734
732
  **Expected result (verified live):** `run` exits `0`, `.run.status ==
735
- "completed"`; `status`'s `.workflow.steps[0].evidence.output == {"message":
736
- "child-said-hello"}` — the child's declared `outputs:` export, promoted as
737
- the parent step's own artifact; `status` has a top-level **`.children`**
733
+ "completed"`; `status`'s `.workflow.steps[0].evidence.output == "child-said-hello"` — the
734
+ child's last step output, promoted as the parent step's own artifact; `status` has a top-level **`.children`**
738
735
  array (not nested under `.workflow`): one entry, `status: "completed"`,
739
736
  `workflowRef: "bundle//workflows/child"`, `spawnedByUnitId:
740
737
  "dispatch:solo"`, `stepId: "dispatch"`.
@@ -1146,16 +1143,20 @@ scheduler writes).
1146
1143
 
1147
1144
  **Setup:**
1148
1145
  ```sh
1149
- cat > "$AKM_BUNDLE_DIR/workflows/leaf.yml" <<'EOF'
1150
- name: Manual test leaf workflow
1151
- on:
1152
- workflow_dispatch:
1153
- jobs:
1154
- main:
1155
- runs-on: [self-hosted]
1156
- steps:
1157
- - id: work
1158
- run: printf leaf-ok
1146
+ cat > "$AKM_BUNDLE_DIR/workflows/leaf.md" <<'EOF'
1147
+ ---
1148
+ type: workflow
1149
+ description: Manual test leaf workflow
1150
+ steps:
1151
+ - id: work
1152
+ unit:
1153
+ exec:
1154
+ command: ["printf", "leaf-ok"]
1155
+ ---
1156
+
1157
+ ## work
1158
+
1159
+ Print leaf-ok.
1159
1160
  EOF
1160
1161
 
1161
1162
  cat > "$AKM_BUNDLE_DIR/tasks/akm-manual-test-wf-task.yml" <<'EOF'
@@ -1193,98 +1194,11 @@ OS scheduler.
1193
1194
  **Cleanup:** `rm -rf "$AKM_SANDBOX"` (no scheduler entries were ever
1194
1195
  created).
1195
1196
 
1196
- ### INT-2 — A workflow step that targets a task (the inverse), including typed input binding
1197
+ ### INT-2 — (removed in 0.10)
1197
1198
 
1198
- **Why it matters:** the reverse composition — the alpha.5
1199
- `FrozenChildWorkflowTarget`/task-bindings machinery. If a workflow step
1200
- `uses: tasks/<ref>` doesn't correctly expand at `plan` time, a published
1201
- workflow's step graph silently diverges from what actually runs.
1202
-
1203
- **Destructive:** No — `workflow plan` performs zero durable writes.
1204
-
1205
- **Setup:** reuses `workflows/leaf.yml` and
1206
- `tasks/akm-manual-test-wf-task.yml` from INT-1, plus:
1207
- ```sh
1208
- cat > "$AKM_BUNDLE_DIR/workflows/task-wrapped.yml" <<'EOF'
1209
- name: Manual test workflow wrapping a task
1210
- on:
1211
- workflow_dispatch:
1212
- jobs:
1213
- main:
1214
- runs-on: [self-hosted]
1215
- steps:
1216
- - id: dispatch
1217
- uses: tasks/akm-manual-test-wf-task
1218
- EOF
1219
- akm index
1220
- ```
1221
-
1222
- **Steps and expected results:**
1223
- 1. `akm workflow plan workflows/task-wrapped --format json` — expected
1224
- (verified live): `.steps[0].stepId == "dispatch"`, `.targetKind ==
1225
- "child-workflow"`, `.expansion.via == "child"`, `.expansion.childVia ==
1226
- "task"`, `.expansion.childTaskRef ==
1227
- "bundle//tasks/akm-manual-test-wf-task"`, `.expansion.childRef ==
1228
- "bundle//workflows/leaf"`, `.expansion.steps[0].stepId == "work"` and
1229
- `.targetKind == "shell"`; exit `0`.
1230
- 2. `akm workflow run workflows/task-wrapped --format json` (this DOES
1231
- publish a run — acceptable, scoped to isolated bundle/state dirs, not
1232
- the OS scheduler), then `akm workflow status <runId> --format json`.
1233
- **Expected result (verified live — this replaces an UNVERIFIED marker
1234
- from an earlier draft of this test):** exit `0`, final `.run.status ==
1235
- "completed"`. Because `leaf.yml` declares no `outputs:` block, the
1236
- parent step's `.workflow.steps[0].evidence.output` is **not** the
1237
- child's step output directly — it is a run pointer: `{"runId":
1238
- "<child-run-uuid>", "status": "completed"}`. The full child summary
1239
- lives in the top-level `.children[0]`: `{"runId": "<same uuid>",
1240
- "workflowRef": "bundle//workflows/leaf", "status": "completed",
1241
- "spawnedByUnitId": "dispatch:solo", "stepId": "dispatch", ...}` — same
1242
- shape as WF-3's `.children` array. (Contrast with WF-3, where the child
1243
- workflow *does* declare `outputs:`, and that gets promoted into the
1244
- parent step's `evidence.output` instead of a bare run pointer.)
1245
-
1246
- **Bonus check — typed input binding across the seam** (exercises the PR's
1247
- "fail-closed input bindings"):
1248
- ```sh
1249
- cat > "$AKM_BUNDLE_DIR/tasks/akm-manual-test-typed-input-task.yml" <<'EOF'
1250
- version: 4
1251
- name: Manual test typed-input task (run target)
1252
- inputs:
1253
- note:
1254
- type: string
1255
- required: true
1256
- run: printf "note=%s" "$AKM_TASK_INPUTS"
1257
- schedule:
1258
- - cron: "0 3 * * *"
1259
- enabled: false
1260
- inputs:
1261
- note: scheduled-default
1262
- EOF
1263
-
1264
- cat > "$AKM_BUNDLE_DIR/workflows/wrap-typed-input-task.yml" <<'EOF'
1265
- name: Manual test workflow binding a literal input into a task step
1266
- on:
1267
- workflow_dispatch:
1268
- jobs:
1269
- main:
1270
- runs-on: [self-hosted]
1271
- steps:
1272
- - id: dispatch
1273
- uses: tasks/akm-manual-test-typed-input-task
1274
- with:
1275
- note: hello-seam
1276
- EOF
1277
- akm index
1278
- akm workflow plan workflows/wrap-typed-input-task --format json
1279
- ```
1280
- **Expected (verified live):** `.steps[0].inputBindings == [{"name":"note","kind":"literal","value":"hello-seam"}]`.
1281
-
1282
- Note: a **required** task input with no `default:` must be given a matching
1283
- `schedule[].inputs.<name>` entry or the task source is rejected outright
1284
- (`TASK_SOURCE_INVALID`) — a task-only rule, not part of the seam, but it
1285
- will trip up anyone building this fixture from scratch.
1286
-
1287
- **Cleanup:** `rm -rf "$AKM_SANDBOX"`.
1199
+ A workflow step that targets a task (`uses: tasks/<ref>`) went with the
1200
+ GitHub-shaped YAML workflow format. A task runs a workflow (INT-1); a workflow
1201
+ step runs a child workflow (WF-3), not a task.
1288
1202
 
1289
1203
  ### INT-3 — Failure propagation: `task history` vs `workflow status`
1290
1204
 
@@ -1297,16 +1211,19 @@ cron failure notification points at), or must they already know to pivot to
1297
1211
 
1298
1212
  **Setup:**
1299
1213
  ```sh
1300
- cat > "$AKM_BUNDLE_DIR/workflows/fail-leaf.yml" <<'EOF'
1301
- name: Manual test failing leaf workflow
1302
- on:
1303
- workflow_dispatch:
1304
- jobs:
1305
- main:
1306
- runs-on: [self-hosted]
1307
- steps:
1308
- - id: boom
1309
- run: exit 1
1214
+ cat > "$AKM_BUNDLE_DIR/workflows/fail-leaf.md" <<'EOF'
1215
+ ---
1216
+ type: workflow
1217
+ steps:
1218
+ - id: boom
1219
+ unit:
1220
+ exec:
1221
+ command: ["sh", "-c", "exit 1"]
1222
+ ---
1223
+
1224
+ ## boom
1225
+
1226
+ Fail.
1310
1227
  EOF
1311
1228
 
1312
1229
  cat > "$AKM_BUNDLE_DIR/tasks/akm-manual-test-fail-task.yml" <<'EOF'
@@ -1360,18 +1277,27 @@ the next scheduled firing must do something predictable.
1360
1277
 
1361
1278
  **Setup:**
1362
1279
  ```sh
1363
- cat > "$AKM_BUNDLE_DIR/workflows/two-step.yml" <<'EOF'
1364
- name: Manual test two-step workflow
1365
- on:
1366
- workflow_dispatch:
1367
- jobs:
1368
- main:
1369
- runs-on: [self-hosted]
1370
- steps:
1371
- - id: first
1372
- run: printf step-one-ok
1373
- - id: second
1374
- run: printf step-two-ok
1280
+ cat > "$AKM_BUNDLE_DIR/workflows/two-step.md" <<'EOF'
1281
+ ---
1282
+ type: workflow
1283
+ steps:
1284
+ - id: first
1285
+ unit:
1286
+ exec:
1287
+ command: ["printf", "step-one-ok"]
1288
+ - id: second
1289
+ unit:
1290
+ exec:
1291
+ command: ["printf", "step-two-ok"]
1292
+ ---
1293
+
1294
+ ## first
1295
+
1296
+ Print step-one-ok.
1297
+
1298
+ ## second
1299
+
1300
+ Print step-two-ok.
1375
1301
  EOF
1376
1302
 
1377
1303
  cat > "$AKM_BUNDLE_DIR/tasks/akm-manual-test-abandon-task.yml" <<'EOF'
@@ -1411,7 +1337,7 @@ starts fresh, never resumes and never errors — a direct consequence of
1411
1337
  attaching to `status = 'active'` rows. One nuance: this auto-attach path is
1412
1338
  also `AND parent_run_id IS NULL`, so it applies to a top-level run a *task*
1413
1339
  starts (INT-1) but not to a run started as a **child** of a parent workflow
1414
- (INT-2) — a child run is only ever driven by its parent. Abandoning a child
1340
+ (WF-3) — a child run is only ever driven by its parent. Abandoning a child
1415
1341
  run's semantics from the *task* side is **UNVERIFIED** — not exercised
1416
1342
  here, plausibly a second interesting gap (a task can only ever directly own
1417
1343
  a top-level run).
@@ -1425,54 +1351,35 @@ examples of tasks that drive akm's own workflows." Testing only synthetic
1425
1351
  fixtures never catches a real schema drift between what `akm task add`
1426
1352
  authors and what these shipped files contain.
1427
1353
 
1428
- **Finding that reshapes this test:** none of the five shipped
1354
+ **Finding that reshapes this test:** none of the shipped
1429
1355
  `src/assets/tasks/improve/*.yml` (or `src/assets/tasks/core/*.yml`) files
1430
1356
  actually target an `akm workflow` asset. Every one is `run: akm <command>
1431
- ...` — a shell target. Verified live for `akm-improve-catchup.yml`:
1357
+ ...` — a shell target. Verified live for `akm-improve-consolidate.yml`:
1432
1358
  `.target == {"kind":"shell"}`. So the literal task→workflow seam (INT-1)
1433
- has **no shipped real-world example** as of alpha.5 — "workflow" in the
1434
- PR/brief is used in the English sense (the `improve` pipeline is a
1435
- multi-step process), not the `akm workflow` asset sense. The direction a
1436
- real shipped task asset DOES exercise unmodified is INT-2's shape — a
1437
- workflow step wrapping a real task via `uses: tasks/`.
1359
+ has **no shipped real-world example** — "workflow" in the PR/brief is used in
1360
+ the English sense (the `improve` pipeline is a multi-step process), not the
1361
+ `akm workflow` asset sense.
1438
1362
 
1439
- **Destructive:** No (`workflow plan` only — zero durable writes).
1363
+ **Destructive:** No (`task explain` only).
1440
1364
 
1441
1365
  **Setup:**
1442
1366
  ```sh
1443
- cp /home/founder3/code/github/itlackey/akm/src/assets/tasks/improve/akm-improve-catchup.yml \
1444
- "$AKM_BUNDLE_DIR/tasks/akm-improve-catchup.yml"
1445
-
1446
- cat > "$AKM_BUNDLE_DIR/workflows/wrap-real-improve-task.yml" <<'EOF'
1447
- name: Manual test workflow wrapping the real shipped improve-catchup task
1448
- on:
1449
- workflow_dispatch:
1450
- jobs:
1451
- main:
1452
- runs-on: [self-hosted]
1453
- steps:
1454
- - id: dispatch
1455
- uses: tasks/akm-improve-catchup
1456
- EOF
1367
+ cp /home/founder3/code/github/itlackey/akm/src/assets/tasks/improve/akm-improve-consolidate.yml \
1368
+ "$AKM_BUNDLE_DIR/tasks/akm-improve-consolidate.yml"
1457
1369
  akm index
1458
1370
  ```
1459
1371
 
1460
1372
  **Steps and expected results (verified live):**
1461
- 1. `akm task explain akm-improve-catchup --format json` → exit `0`,
1462
- `.target.kind == "shell"`, `.description == "Manual recovery —
1463
- consolidation + triage drain (run on demand via \`akm task run
1464
- akm-improve-catchup\`)"`, `.schedule[0] == {"ordinal":0,"cron":"0 4 * * *","enabled":false,"source":"schedule[0].cron","inputs":{}}`
1373
+ 1. `akm task explain akm-improve-consolidate --format json` → exit `0`,
1374
+ `.target.kind == "shell"`, `.description == "Consolidation-only
1375
+ pass (every 4h at :20)"`, `.schedule[0] == {"ordinal":0,"cron":"20 */4 * * *","enabled":false,"source":"schedule[0].cron","inputs":{}}`
1465
1376
  — the real shipped file describes a schedule but cannot activate itself;
1466
1377
  this host's `scheduler.enabled` list does not name it.
1467
- 2. `akm workflow plan workflows/wrap-real-improve-task --format json` →
1468
- `.steps[0].targetKind == "shell"`, `.steps[0].expansion ==
1469
- {"via":"task","taskRef":"tasks/akm-improve-catchup"}`.
1470
1378
 
1471
- **Do not** `workflow run` this composed workflow, and do not `task run
1472
- akm-improve-catchup` directly — both would invoke the real `akm improve
1473
- --strategy catchup` pipeline against a live agent engine, which is slow,
1474
- may require credentials, and is out of scope for a seam test. `workflow
1475
- plan` already proves the seam without executing anything.
1379
+ **Do not** `task run akm-improve-consolidate` directly — it would invoke the
1380
+ real `akm improve --strategy consolidate` pipeline against a live agent
1381
+ engine, which is slow, may require credentials, and is out of scope for a seam
1382
+ test.
1476
1383
 
1477
1384
  **Cleanup:** `rm -rf "$AKM_SANDBOX"`.
1478
1385
 
@@ -1599,16 +1506,20 @@ collision-proof bundle name so the resulting scheduler evidence is easy to
1599
1506
  identify and clean up):
1600
1507
  ```sh
1601
1508
  export SEAM_BUNDLE_NAME="akm-manual-test-seam-$(date +%s)"
1602
- cat > "$AKM_BUNDLE_DIR/workflows/leaf.yml" <<'EOF'
1603
- name: Manual test leaf workflow
1604
- on:
1605
- workflow_dispatch:
1606
- jobs:
1607
- main:
1608
- runs-on: [self-hosted]
1609
- steps:
1610
- - id: work
1611
- run: printf leaf-ok
1509
+ cat > "$AKM_BUNDLE_DIR/workflows/leaf.md" <<'EOF'
1510
+ ---
1511
+ type: workflow
1512
+ description: Manual test leaf workflow
1513
+ steps:
1514
+ - id: work
1515
+ unit:
1516
+ exec:
1517
+ command: ["printf", "leaf-ok"]
1518
+ ---
1519
+
1520
+ ## work
1521
+
1522
+ Print leaf-ok.
1612
1523
  EOF
1613
1524
  cat > "$AKM_BUNDLE_DIR/tasks/akm-manual-test-drift.yml" <<'EOF'
1614
1525
  version: 4
@@ -1781,18 +1692,10 @@ specific corrections from that review:
1781
1692
  correct, still-true finding kept in this document instead is: `akm task
1782
1693
  --help` genuinely has no `remove` subcommand (`add|run|explain|history|
1783
1694
  sync|doctor` only) — confirmed live.
1784
- 2. **INT-2's parent-side child-run evidence shape**, marked `UNVERIFIED` in
1785
- the source draft, was resolved live during review (see INT-2 step 2
1786
- above): for a child dispatched via `uses: tasks/<ref>` where the child
1787
- workflow declares no `outputs:`, the parent step's `evidence.output` is
1788
- a bare `{runId, status}` pointer, while the full child summary is
1789
- carried in the top-level `.children[]` array — the same array shape
1790
- WF-3 already demonstrates for a direct (non-task) child dispatch whose
1791
- child workflow *does* declare `outputs:`.
1792
1695
 
1793
1696
  Live alpha.5 spot-checks performed (in addition to the two above): TASK-3,
1794
1697
  TASK-6, TASK-9, TASK-12, TASK-13, WF-2, WF-5 (incl. `status --units`),
1795
- WF-3/INT-2's `.children` shape, WF-6/#847's original reproduction, WF-9's
1698
+ WF-3's `.children` shape, WF-6/#847's original reproduction, WF-9's
1796
1699
  sqlite table/column names and exact error message, and INT-1 end to end. All
1797
1700
  matched their source draft's claimed exact fields, error codes, and exit codes
1798
1701
  with no further discrepancies found. Stable 0.9.2 changes WF-6 and DT-5 to
@@ -360,7 +360,7 @@ not a side-by-side install. It then runs the CANDIDATE against that home
360
360
  (`migrate status`/`apply`, `bundle list` with every bundle confirmed enabled,
361
361
  `search`/`show`, `task sync` dry-run and real — plain, no `--rebind`, as an
362
362
  upgrading user actually runs it — executing the generated cron command and
363
- confirming it ran the candidate, `task run`, `health`, `improve --plan`), and
363
+ confirming it ran the candidate, `task run`, `health`, `improve --dry-run`), and
364
364
  finally installs a separate untouched copy of the PREVIOUS release and runs
365
365
  it back against the candidate-written home to prove read-back still works.
366
366
  It exists because no other suite drives a real prior release against a real
@@ -9,9 +9,9 @@ exact frontmatter/body syntax that produces the plan, see
9
9
  [Workflow Schema](../reference/workflow-schema.md). For the day-to-day
10
10
  commands that drive a run, see [Running Workflows](../guides/run-workflows.md).
11
11
 
12
- > **`akm workflow run` is Stable, ungated, and the only execution surface.**
13
- > It is the canonical start/resume/execute command; there is no separate
14
- > external-driver protocol.
12
+ > **`akm workflow run` is Experimental (see `STABILITY.md`), ungated, and the only
13
+ > execution surface.** It is the canonical start/resume/execute command; there is
14
+ > no separate external-driver protocol.
15
15
 
16
16
  ## Frozen plans
17
17
 
@@ -81,7 +81,7 @@ existing retry loop, after the parent unit's attempt row is already claimed
81
81
  `running` (so a crash between claiming that row and publishing the child
82
82
  leaves a recoverable `running` parent unit and no orphaned child) and
83
83
  **before** the ordinary post-dispatch journaling (redaction, attempt
84
- finishing, the worktree epilogue), which runs unchanged either way — a
84
+ finishing), which runs unchanged either way — a
85
85
  child-workflow unit is journaled exactly like any other.
86
86
 
87
87
  **The drive contract.** `driveChildWorkflowUnit` validates and resolves the
@@ -127,29 +127,10 @@ preimage already covers everything the child drive depends on — the frozen
127
127
  target carries the child's ref, plan hash, content hash, binding mode, and
128
128
  its entire embedded plan, so any change anywhere in the child changes the
129
129
  parent unit's own input hash transitively. The child run id (minted at
130
- dispatch) and its exported result are unit *outputs*, not inputs, so neither
130
+ dispatch) and its result (the child's last step output) are unit *outputs*, not inputs, so neither
131
131
  belongs in the preimage — adding either would be a hashing-boundary
132
132
  violation, not a fix.
133
133
 
134
- ### Run outputs
135
-
136
- A workflow may declare `outputs:` — a run-level export projected from its
137
- steps' own artifacts once every step has finished (see [Workflow Schema:
138
- Workflow outputs](../reference/workflow-schema.md#workflow-outputs) for the
139
- authoring grammar). Resolution happens inside the same write transaction
140
- that completes the run's final step, immediately after the run's terminal
141
- status is derived: each declared output is resolved from the persisted step
142
- evidence and, if declared, validated against its schema. If resolution or
143
- validation fails for any entry, the **whole completion rolls back** — the
144
- run stays `active`, its final step stays `pending`, and no completion event
145
- is emitted — rather than leaving a run `completed` with missing or invalid
146
- exports. A run with no `outputs:` declaration exports `{runId, status}`
147
- instead, synthesized on read and never persisted. This exported result is
148
- exactly what a parent composing this workflow as a child promotes as the
149
- composing unit's own result on `completed` — the same value, read through
150
- the same function, whether the caller is `akm workflow status` or a parent
151
- unit's dispatch.
152
-
153
134
  ## Resume skips completed units
154
135
 
155
136
  Resume never re-reads config or the asset index, and reads the workflow
@@ -198,38 +179,6 @@ dead is reclaimed at once, so a crashed engine never wedges a run; nothing
198
179
  expires by age and nothing renews. `workflow status` and `list` never take
199
180
  the lock.
200
181
 
201
- ## Worktree isolation
202
-
203
- A file-mutating unit can declare `isolation: worktree` in its `unit:` bag
204
- (agent and sdk runners) — see
205
- [Workflow Schema: Frontmatter keys](../reference/workflow-schema.md#frontmatter-keys).
206
- Each unit attempt gets a fresh **detached git worktree** of the run's base
207
- repository under a run-scoped temp directory; the worktree path is journaled
208
- on the unit row and passed to the harness as its working directory, so
209
- parallel fan-out units can never trample each other's working tree. After the
210
- unit finishes, a clean worktree (`git status --porcelain` empty) is removed
211
- automatically; a dirty one is retained and its path logged, so uncollected
212
- work is never destroyed. Declaring worktree isolation in a non-git directory
213
- fails the step cleanly before anything dispatches.
214
-
215
- > **Warning — outputs matched by `.gitignore` are treated as disposable.** A
216
- > worktree-isolated unit's output survives only if it lands on a
217
- > **collectible path**: a tracked file, or an untracked file your repository
218
- > does **not** `.gitignore`. Anything a unit writes to a `.gitignore`d path —
219
- > build outputs, caches, logs, dependency directories like
220
- > `node_modules`/`dist`, or a scratch file under an ignored directory — is
221
- > **discarded** when its clean worktree is auto-removed. If a unit produces an
222
- > artifact that must survive, write it to a non-ignored path, or report it as
223
- > a result (a structured `output` / free-text result), before the unit
224
- > returns.
225
-
226
- The clean probe deliberately does **not** pass `--ignored`, so "uncollected
227
- work" means tracked or untracked-*unignored* changes only. A worktree whose
228
- only residue is files your repository's own `.gitignore` matches is treated
229
- as clean and removed: those files are disposable by the repo's own
230
- declaration, and retaining a worktree after every package install or build
231
- would blow up disk under the temp root.
232
-
233
182
  ## Concurrency limits
234
183
 
235
184
  Native fan-out (`akm workflow run`) uses the minimum of four limits: the