akm-cli 0.9.2-alpha.4 → 0.9.2-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 (143) hide show
  1. package/CHANGELOG.md +463 -0
  2. package/STABILITY.md +23 -5
  3. package/dist/assets/hints/cli-hints-full.md +12 -7
  4. package/dist/assets/tasks/core/extract.yml +3 -5
  5. package/dist/assets/tasks/core/improve.yml +3 -5
  6. package/dist/assets/tasks/core/index-refresh.yml +3 -5
  7. package/dist/assets/tasks/core/sync.yml +3 -5
  8. package/dist/assets/tasks/core/version-check.yml +3 -5
  9. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +3 -5
  10. package/dist/assets/tasks/improve/akm-improve-catchup.yml +6 -6
  11. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +3 -5
  12. package/dist/assets/tasks/improve/akm-improve-frequent.yml +3 -5
  13. package/dist/assets/tasks/improve/akm-improve-nightly.yml +3 -5
  14. package/dist/cli/unknown-flags.js +12 -1
  15. package/dist/cli.js +8 -1
  16. package/dist/commands/command/command-execution.js +23 -2
  17. package/dist/commands/health/improve-metrics.js +38 -0
  18. package/dist/commands/health/windows.js +8 -4
  19. package/dist/commands/health.js +8 -4
  20. package/dist/commands/lint/index.js +1 -1
  21. package/dist/commands/migrate-cli.js +130 -24
  22. package/dist/commands/proposal/validators/proposal-validators.js +7 -2
  23. package/dist/commands/tasks/explain.js +304 -0
  24. package/dist/commands/tasks/tasks-cli.js +185 -3
  25. package/dist/commands/tasks/tasks.js +233 -45
  26. package/dist/commands/workflow/plan.js +159 -0
  27. package/dist/commands/workflow-cli.js +94 -2
  28. package/dist/core/activation-policy.js +2 -12
  29. package/dist/core/adapter/adapters/akm-lint.js +7 -4
  30. package/dist/core/adapter/adapters/akm-metadata.js +26 -14
  31. package/dist/core/adapter/adapters/akm-task-adapter.js +13 -10
  32. package/dist/core/errors.js +45 -0
  33. package/dist/core/json-schema.js +15 -5
  34. package/dist/core/state/migrations.js +57 -0
  35. package/dist/core/state-db.js +16 -14
  36. package/dist/core/subprocess.js +47 -13
  37. package/dist/execution/guarded-source.js +44 -0
  38. package/dist/execution/input-contract.js +250 -0
  39. package/dist/execution/target-ref.js +63 -0
  40. package/dist/indexer/usage/usage-events.js +14 -3
  41. package/dist/integrations/agent/execution-lowering.js +12 -1
  42. package/dist/output/shapes/passthrough.js +2 -0
  43. package/dist/output/text/helpers.js +1 -1
  44. package/dist/output/text/migrate.js +12 -3
  45. package/dist/output/text/workflow-format.js +192 -10
  46. package/dist/output/text/workflow.js +2 -1
  47. package/dist/runtime.js +1 -0
  48. package/dist/scripts/akm-migrate-node.js +11838 -10118
  49. package/dist/scripts/akm-migrate.js +11828 -10117
  50. package/dist/setup/steps/tasks.js +34 -17
  51. package/dist/storage/repositories/task-history-repository.js +5 -1
  52. package/dist/storage/repositories/workflow-runs-repository.js +144 -6
  53. package/dist/tasks/backends/launchd.js +31 -84
  54. package/dist/tasks/embedded.js +13 -7
  55. package/dist/tasks/model/invocation.js +4 -0
  56. package/dist/tasks/prepare/prepare-script-target.js +9 -0
  57. package/dist/tasks/prepare/prepare-support.js +154 -0
  58. package/dist/tasks/prepare/prepare.js +117 -0
  59. package/dist/tasks/prepare/prepared-execution.js +4 -0
  60. package/dist/tasks/prepare/script-capture.js +80 -0
  61. package/dist/tasks/run/attempt-lifecycle.js +165 -0
  62. package/dist/tasks/run/load-task.js +117 -0
  63. package/dist/tasks/run/provenance.js +20 -0
  64. package/dist/tasks/run/run-command-task.js +92 -0
  65. package/dist/tasks/run/run-native-task.js +222 -0
  66. package/dist/tasks/run/run-task.js +99 -0
  67. package/dist/tasks/run/run-workflow-task.js +222 -0
  68. package/dist/tasks/run/task-history.js +134 -0
  69. package/dist/tasks/run/task-log.js +179 -0
  70. package/dist/tasks/run/task-result.js +19 -0
  71. package/dist/tasks/scheduler-binding.js +66 -2
  72. package/dist/tasks/scheduler-invocation.js +63 -3
  73. package/dist/tasks/scheduler-sync.js +55 -12
  74. package/dist/tasks/source/bounded-document.js +455 -0
  75. package/dist/tasks/source/parse-task-source.js +59 -0
  76. package/dist/tasks/source/project-v4.js +62 -0
  77. package/dist/tasks/source/task-input-diagnostics.js +36 -0
  78. package/dist/tasks/source/task-source-v4.js +626 -0
  79. package/dist/tasks/source-v3.js +10 -733
  80. package/dist/tasks/task-run-reserved-flags.js +79 -0
  81. package/dist/workflows/authoring/authoring.js +17 -8
  82. package/dist/workflows/exec/child-invocation.js +34 -0
  83. package/dist/workflows/exec/child-workflow.js +370 -0
  84. package/dist/workflows/exec/exec-unit.js +50 -170
  85. package/dist/workflows/exec/frozen-judge.js +19 -2
  86. package/dist/workflows/exec/native-executor.js +49 -27
  87. package/dist/workflows/exec/param-secrets.js +12 -0
  88. package/dist/workflows/exec/run-workflow.js +48 -59
  89. package/dist/workflows/exec/step-work.js +222 -80
  90. package/dist/workflows/exec/unit-dispatch.js +72 -0
  91. package/dist/workflows/freeze/child-output-references.js +94 -0
  92. package/dist/workflows/freeze/environment.js +174 -0
  93. package/dist/workflows/freeze/identity.js +22 -0
  94. package/dist/workflows/freeze/resolve-steps.js +78 -0
  95. package/dist/workflows/freeze/source-freeze.js +57 -0
  96. package/dist/workflows/freeze/step-values.js +68 -0
  97. package/dist/workflows/freeze/targets/child-workflow.js +206 -0
  98. package/dist/workflows/freeze/targets/command.js +81 -0
  99. package/dist/workflows/freeze/targets/script.js +57 -0
  100. package/dist/workflows/freeze/targets/shell.js +31 -0
  101. package/dist/workflows/freeze/targets/task.js +179 -0
  102. package/dist/workflows/freeze/task-bindings.js +180 -0
  103. package/dist/workflows/ir/compile.js +59 -11
  104. package/dist/workflows/ir/environment-v4.js +3 -3
  105. package/dist/workflows/ir/freeze-v4.js +41 -7
  106. package/dist/workflows/ir/params.js +58 -131
  107. package/dist/workflows/ir/plan-hash.js +3 -3
  108. package/dist/workflows/ir/schema-v4.js +246 -17
  109. package/dist/workflows/parser.js +74 -2
  110. package/dist/workflows/program/schema.js +5 -2
  111. package/dist/workflows/resource-limits.js +20 -0
  112. package/dist/workflows/runtime/plan-classifier.js +19 -5
  113. package/dist/workflows/runtime/run-outputs.js +103 -0
  114. package/dist/workflows/runtime/runs.js +114 -9
  115. package/dist/workflows/runtime/workflow-asset-loader.js +14 -6
  116. package/dist/workflows/source-files.js +5 -5
  117. package/dist/workflows/source-ir/compare.js +17 -0
  118. package/dist/workflows/source-ir/compile.js +7 -3
  119. package/dist/workflows/source-ir/github-yaml.js +64 -17
  120. package/dist/workflows/source-ir/schema.js +69 -21
  121. package/dist/workflows/source-ir/semantics.js +7 -25
  122. package/dist/workflows/source-ir/triggers.js +79 -0
  123. package/dist/workflows/source-ir/uses.js +33 -7
  124. package/docs/migration/README.md +1 -1
  125. package/docs/migration/release-notes/0.9.2.md +87 -11
  126. package/docs/migration/release-notes/README.md +2 -2
  127. package/docs/migration/v0.8-to-v0.9.md +9 -7
  128. package/docs/migration/v0.9.0-troubleshooting.md +14 -7
  129. package/docs/migration/v0.9.1-to-v0.9.2.md +598 -49
  130. package/docs/reference/README.md +1 -1
  131. package/docs/reference/cli.md +140 -46
  132. package/docs/reference/configuration.md +3 -3
  133. package/docs/reference/supported-formats.md +9 -5
  134. package/docs/reference/tasks.md +338 -75
  135. package/docs/reference/workflow-schema.md +281 -8
  136. package/docs/reference/workflows.md +57 -7
  137. package/package.json +1 -1
  138. package/schemas/akm-task.json +173 -118
  139. package/schemas/akm-workflow.json +28 -0
  140. package/dist/tasks/runner.js +0 -941
  141. package/dist/tasks/runtime-v3.js +0 -281
  142. package/dist/workflows/ir/source-freeze-v4.js +0 -506
  143. package/dist/workflows/source-ir/ordering.js +0 -38
package/CHANGELOG.md CHANGED
@@ -6,6 +6,469 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ### Fixed
10
+
11
+ - **Scheduled tasks on Windows ran but recorded no output.** A task fired by
12
+ Task Scheduler logged `exit_code=0` with an empty log: the command really
13
+ ran, but nothing it printed was captured. Captured runs asked for their own
14
+ process group, which is what lets a timeout reap the whole descendant tree
15
+ on macOS/Linux; on Windows that same flag instead means "start with no
16
+ console", and a console host started that way (`powershell.exe`, `cmd.exe`)
17
+ allocates its own console and thereby replaces the pipes it was handed, so
18
+ its output went nowhere. Windows got no reaping benefit in exchange — the
19
+ group kill it enables is a POSIX-only call — so captured Windows runs no
20
+ longer ask for it. A run whose output capture is incomplete for any other
21
+ reason now says so in the task log instead of leaving a silent gap.
22
+ - **A scheduled shell task could fail instantly with exit code 1 on Windows.**
23
+ Two defects on the default Windows task shell (`powershell`): a
24
+ scheduler-fired run restores the PATH captured at install time, which can be
25
+ minimal, and `powershell.exe` is not on it (it lives in a `WindowsPowerShell`
26
+ subdirectory, not `System32`), so the spawn failed outright; and rebinding a
27
+ bare leading `akm` produced a quoted path, which PowerShell parses as a
28
+ string rather than a command to run. Both shells are now resolved to
29
+ absolute paths on Windows, and a rebound invocation carries PowerShell's
30
+ call operator. `cmd`-shell tasks additionally pass their hand-quoted command
31
+ line through verbatim, since `cmd /s /c` does not read a standard argv.
32
+ - **`state.db` could fail to open on macOS** with "this platform has no
33
+ descriptor-backed path." The descriptor-alias optimization used to bind a
34
+ SQLite open to its exact held inode isn't reliably available everywhere —
35
+ Windows never has one, and macOS's `/dev/fd` is a small fixed-size table
36
+ that a process holding higher file-descriptor numbers (as a bundled
37
+ standalone binary routinely does) can miss. The surrounding identity checks
38
+ (dev/ino/uid, re-verified immediately before and after every open) are the
39
+ real protection; a missing alias now falls back to the plain path on any
40
+ platform instead of throwing, matching the fallback Windows already used.
41
+ - The Windows build shipped no embedded template assets, because the
42
+ build-time asset copy anchored its rewrites on forward slashes while the
43
+ glob yields platform-native separators.
44
+
45
+ ## [0.9.2-alpha.5] - 2026-08-28
46
+
47
+ ### Breaking changes & migration
48
+
49
+ - **Durable workflow plans bump to `irVersion` 5.** A stored run frozen
50
+ before this release (`irVersion` 4 or earlier) can no longer `resume`,
51
+ `next`, `complete`, or `run` — those fail closed with `UsageError` code
52
+ `WORKFLOW_IR_VERSION_UNSUPPORTED`, naming the run and pointing at
53
+ `akm workflow abandon`. `akm workflow status`, `akm workflow list`, and
54
+ `akm workflow abandon` keep working on those runs — no data is lost, and
55
+ their step spine is untouched by abandoning. **Before upgrading**, run
56
+ `akm workflow list --active` and either let in-flight runs finish or
57
+ abandon them; after upgrading, recover a blocked run with
58
+ `akm workflow abandon <id>` followed by `akm workflow run <ref>` to start
59
+ fresh from the current authored source. There is no second executor and no
60
+ compatibility replay layer for a pre-`irVersion`-5 plan. The unit and gate
61
+ input-hash prefixes bump alongside it, from `hashVersion` 5 to
62
+ `hashVersion` 7, so that a freshly frozen plan's units are never
63
+ content-addressed the same way an old, no-longer-executable plan's were.
64
+ (`hashVersion` 6 existed only inside this release's own development and
65
+ never shipped in any version — the durable step a released install sees is
66
+ 5 → 7.) The unit preimage also gains one **conditional** field,
67
+ `taskInputs`: the *resolved* values of a task-composing step's input
68
+ bindings, present only for a unit whose frozen target carries
69
+ `inputBindings` — a binding-free unit's preimage keeps exactly the shape it
70
+ had. Hashing the resolved values, not just the frozen binding expression,
71
+ is what makes a resumed run whose upstream step output changed under a
72
+ `{from: "steps.<id>.output"}` binding fail loudly as a replay divergence
73
+ instead of silently reusing the completed unit's stale result.
74
+ See [Migrating from akm 0.9.1 to 0.9.2](docs/migration/v0.9.1-to-v0.9.2.md#workflow-cutover).
75
+ - A workflow step that passes `with:` to a `tasks/<ref>` target whose task
76
+ declares **no** `inputs:` (a `version: 4` task with no `inputs:` key at
77
+ all) is now **rejected** (`UsageError` code
78
+ `COMPOSITION_INVALID`, exit 2) instead of having the authored mapping
79
+ silently dropped at freeze — for any authored shape, including `with: {}`.
80
+ When the target's task source **does** declare `inputs:`, `with:` now
81
+ **binds** them instead: a literal value, or a `{from: "steps.<id>.output…"}`
82
+ reference resolved just before the unit dispatches (the reference grammar
83
+ also accepts `{from: "params.<name>"}`, but a composing step's own
84
+ document can never declare `params:`, so that form is not reachable in
85
+ this release). See [Task input bindings](docs/reference/tasks.md#typed-inputs-and-output)
86
+ for the full grammar. `with:` on `uses: akm/command` is unaffected — it is
87
+ still that builtin's own action-argument bag, never an input binding.
88
+ - **New rejection:** `with:` on a workflow step targeting `uses:
89
+ commands/<ref>` or `uses: scripts/<ref>` is now **rejected**
90
+ (`COMPOSITION_INVALID`, exit 2) instead of being silently discarded at
91
+ freeze — neither target is a binding surface. Remove the `with:` block from
92
+ any such step; a command/script-composing step never accepted its values
93
+ in the first place, so this closes a defect rather than a feature.
94
+ - Composing a task source v4 document from a workflow step's `uses:
95
+ tasks/<ref>`, where the task's own target is a workflow, is no longer
96
+ deferred: it now **freezes and dispatches** normally, the same as a
97
+ direct `uses: workflows/<ref>` step. The prior release's
98
+ `TASK_SOURCE_INVALID` "arrives in a later 0.9.x release" rejection for this
99
+ case is gone.
100
+ - Task-source validation errors raised through the shared `sourceError`
101
+ funnel (field- and semantic-level checks: missing/invalid fields, schedule
102
+ conflicts, and similar) now report code **`TASK_SOURCE_INVALID`** instead of
103
+ `INVALID_FLAG_VALUE`. YAML syntax, size, structure, and expansion failures
104
+ (malformed YAML, oversized source, unsupported YAML constructs, and
105
+ alias/tag/depth/node-count limits) are raised earlier, before that funnel is
106
+ reached — early in this release these still reported `INVALID_FLAG_VALUE`,
107
+ but by 0.9.2's release they report `TASK_SOURCE_INVALID` too (the terminal
108
+ diagnostics ratchet, see the Changed entry below): task-source failures no
109
+ longer split across two codes, so **scripts that were branching on both
110
+ `TASK_SOURCE_INVALID` and `INVALID_FLAG_VALUE` for a task-source error can
111
+ drop the `INVALID_FLAG_VALUE` arm**. Every such error's message prefix is
112
+ `Invalid task source at <path>[:<line>]: …` — not `Invalid task v3 source`,
113
+ since the label no longer names a specific schema generation (task source
114
+ v4 is the only version `src/` accepts by release; see the "Task v3 sources
115
+ no longer parse" entry below). The envelope's `error` message text and exit
116
+ code 2 are unchanged for every task-source error. The envelope's `hint`
117
+ field and the `detail` text `akm lint` and the akm-task adapter report for
118
+ the same failure change from `… Run \`akm <command> --help\` to see
119
+ accepted values.` to `… Fix the task source at the reported path and line,
120
+ then re-run.`
121
+ - **Task-history / JSON-output `target.kind` vocabulary changed.** A prepared
122
+ command (agent/LLM) run now reports `"command"` (formerly the confusingly
123
+ inverted `"prompt"`); the former shared `"command"` string for the native
124
+ arm splits into `"shell"` and `"script"`, now distinguishable in history;
125
+ `"workflow"` and `"unknown"` are unchanged. **Consumers branching on
126
+ `"prompt"` must handle `"command"`** — this affects `akm task run`'s and
127
+ `akm task history`'s JSON output (`result.target.kind` /
128
+ `rows[].target.kind`) and any code reading `task_history.target_kind`
129
+ directly. Rows written by earlier akm versions are read back **mapped** to
130
+ the new vocabulary (legacy `"prompt"` → `{kind:"command", engine}`, legacy
131
+ `"command"` → `{kind:"shell"}`), so `akm task history` output stays uniform
132
+ across vintages. New rows carry a `targetVocab: 2` marker inside their
133
+ `metadata_json`, which akm versions before this one reject as an unknown
134
+ metadata field — a mixed-version fleet must upgrade every `akm` that writes
135
+ task history before an older one reads it.
136
+ - **Task source v4 (`version: 4`) is the task source grammar.** By 0.9.2's
137
+ release, `version: 4` is the *only* version `src/` accepts — see the
138
+ "Task v3 sources no longer parse" entry below for the cutover, the
139
+ `TASK_SCHEMA_VERSION_UNSUPPORTED` rejection, and the migration path. What
140
+ follows describes the v4 grammar itself. Scheduling is **optional**: a
141
+ task source v4 document with no `schedule:` parses, is runnable with
142
+ `akm task run`, and is **skipped** by `akm task sync` (zero bindings, zero
143
+ failures) instead of being rejected for missing a trigger — this is now
144
+ the *only* scheduling grammar; the second syntax task v3 offered
145
+ (`akm.schedule` / a document's top-level `on:`) is retired along with v3
146
+ itself. Task source v4 removes the `akm:` options bag and the `on:`
147
+ trigger block outright;
148
+ every field they carried is a top-level key instead: `akm.description` →
149
+ `description`, `akm.when_to_use` → `when_to_use`, `akm.tags` → `tags`,
150
+ `akm.agent` → `agent`, `akm.engine` → `engine`, `akm.model` → `model`,
151
+ `akm.inference` → `inference`, `akm.outputSchema` → `output`,
152
+ `akm.tools` → `tools`, `akm.timeout` → `timeout`, `akm.redact` →
153
+ `redact`, `akm.maxSteps` → `maxSteps`, `akm.maxRetries` → `maxRetries`,
154
+ `akm.schedule` → top-level `schedule:`, and `akm.enabled` → each
155
+ `schedule:` entry's own `enabled` (v3's single document-level flag
156
+ becomes per-binding in task source v4, defaulting to `true`; the
157
+ document-level `enabled` skip that read it is gone with v3, since a v4
158
+ document has no document-level `enabled` key to read). The GitHub-action
159
+ `uses:` target (`owner/repo@ref`) is removed outright — see the "GitHub
160
+ Action locators are no longer recognized anywhere" entry below.
161
+ `with:` is legal in task source v4 only alongside
162
+ `uses: akm/command`; every other target uses the new typed `inputs:`
163
+ declarations instead of `with:`. A declared `inputs:` name may not collide
164
+ with a flag `akm task run` already declares for itself (`bundle`, `format`,
165
+ `detail`, `shape`, `output`, `scheduled`, `quiet`, `verbose`, `help`,
166
+ `no-quiet`, `no-verbose`) or with `target`, the spelling `akm task`
167
+ retired in 0.9 and still answers with a rename hint in every spelling —
168
+ such a document now fails `TASK_SOURCE_INVALID` at parse time, since the
169
+ colliding name would otherwise route a caller's value into `akm task run`'s
170
+ own flag, or into that rename hint, instead of the declared input. `akm
171
+ task run <id>` now accepts exact-name input flags for a task source v4
172
+ document's declared `inputs:` (an undeclared flag name fails
173
+ `UNKNOWN_FLAG`; a bad value or an unsatisfied `required: true` declaration
174
+ fails `INPUT_BINDING_INVALID`; both exit 2 with the usual JSON error
175
+ envelope).
176
+ Where those materialized values go depends on the task's own target: for
177
+ `uses: workflows/<ref>` they become the child run's params (the existing
178
+ `with:` → params path); for a `run:`, `scripts/<ref>`, or `commands/<ref>`
179
+ target they are validated and then **discarded** — `akm task run`'s own
180
+ flags never populate an `AKM_TASK_INPUTS` environment variable or a
181
+ `## Task inputs` prompt block. Those two surfaces are a separate delivery
182
+ path: they carry a **workflow step's** `with:` binding into a task it
183
+ composes via `uses: tasks/<ref>` (see the `with:`-binding bullet above),
184
+ not `akm task run`'s own CLI flags. `schedule[].inputs` on a `version: 4`
185
+ task source are compiled the same way `akm task run`'s flags are: `akm
186
+ task sync` builds them into the scheduler binding's own invocation tail
187
+ instead of only validating and discarding them, so a scheduled run is
188
+ subject to the identical workflow-target-only delivery rule. `akm task
189
+ add` now authors task source v4 (see the "Task v3 sources no longer
190
+ parse" entry below for the `--params` → typed `inputs:` change). A
191
+ `version: 4` task source is now a valid workflow-step target (see above).
192
+ The published [task schema](schemas/akm-task.json) now publishes only the
193
+ single `version: 4` shape — the `version: 3` arm and its `githubActionRef`
194
+ definition are removed; a `version: 2` or `version: 3` document validates
195
+ against nothing in this schema and is converted by `akm migrate apply`
196
+ instead. **Binding a task's inputs adds nothing to the hash preimage of a
197
+ step that binds none**: a unit whose frozen target carries no
198
+ `inputBindings` has exactly the preimage *shape* it had before this
199
+ feature — no `taskInputs` key at all. Its hash *value* still moves, because
200
+ every unit and gate hash in this release re-versions once (`hashVersion`
201
+ 5 → 7, see the `irVersion` 5 entry above), and no pre-`irVersion`-5 plan can
202
+ execute here to be compared against.
203
+ - **A task's `output:` is legal only with a command target.** `output:`
204
+ alongside `run:`, `uses: scripts/<ref>`, or `uses: workflows/<ref>` now
205
+ fails `TASK_SOURCE_INVALID` (exit 2) at parse instead of being accepted and
206
+ never enforced: those runtimes decide success from the process exit code or
207
+ from a child run's own status and consume no task-level response schema, so
208
+ an authored contract there was silently unenforced. `uses: commands/<ref>`
209
+ and `uses: akm/command` — the targets that forward it as the model's
210
+ response schema — are unchanged. The published
211
+ [task schema](schemas/akm-task.json) enforces the same rule, so an editor
212
+ validating against it no longer green-lights a document `akm task run`
213
+ refuses to load. Migration handles this for you: `akm migrate apply` drops
214
+ an `akm.outputSchema` that sat on one of those three targets (it was inert
215
+ in v3 as well — nothing ever read it there) and reports the drop as a
216
+ notice on that file's plan entry rather than blocking the file.
217
+ - **A `schedule:` entry must be able to satisfy the task's declared
218
+ `inputs:`.** A scheduled firing supplies no input flags, so a task
219
+ declaring a `required: true` input — which may not also carry a
220
+ `default:` — and a `schedule:` entry that names no value for it could only
221
+ ever install a binding that fails at every firing. Such a document now
222
+ fails `TASK_SOURCE_INVALID` (exit 2) at parse, naming the unsatisfied
223
+ input, instead of syncing cleanly and failing once per fire. This covers
224
+ every entry shape: the `schedule: "<cron>"` string shorthand and a list
225
+ entry with no `inputs:` key are held to the same contract as one that
226
+ authors `inputs:`. Give the entry an `inputs:` value for each named input,
227
+ or declare a `default:` on the input instead. Manual-only tasks are
228
+ unaffected — a `required: true` input with no `schedule:` is still valid
229
+ and is supplied per run with `akm task run <id> --<name> <value>`.
230
+ - **`akm workflow create --json` renames its `stashDir` envelope field to
231
+ `bundleDir`.** The success envelope now reads
232
+ `{ok, ref, path, bundleDir}`; the value (the owning bundle's directory) is
233
+ unchanged. Scripts reading `stashDir` off `akm workflow create --json`
234
+ must read `bundleDir`. This was the last `stash`-vocabulary field on a
235
+ 0.9.2 command envelope; the indexer's internal `IndexOptions.stashDir` is
236
+ not a CLI surface and is unchanged.
237
+ - **Task v3 sources no longer parse.** A task document with `version: 3`
238
+ (or `version: 2`) fails with `UsageError` code
239
+ `TASK_SCHEMA_VERSION_UNSUPPORTED` (exit 2) instead of executing — the v3
240
+ parser is gone from `src/`; it survives only vendored inside the
241
+ `akm-migrate` executable, which is how the migrator still reads what it
242
+ converts. Run `akm migrate apply --dry-run`, review every `changed` /
243
+ `skipped` / `blocked` result, then `akm migrate apply` — the command now
244
+ runs **both** generations in one pass: task-v2 → task-v3, then
245
+ task-v3 → task source v4, against the same tree. `akm task add` authors
246
+ task source v4 directly; a task's `--params` becomes typed `inputs:` with
247
+ defaults instead of a `with:` bag. A task's enabled state is now per
248
+ schedule binding (`schedule[].enabled`) rather than a document-level
249
+ `akm.enabled` flag — `akm task add --disabled` writes
250
+ `schedule: [{cron: …, enabled: false}]` instead of a document-level
251
+ `akm.enabled: false`. See
252
+ [Migrating task v3 to task source v4](docs/migration/v0.9.1-to-v0.9.2.md#migrating-task-v3-to-task-source-v4).
253
+ - **GitHub Action locators are no longer recognized anywhere.** A task's
254
+ `uses: owner/repo[/path]@rev` is now a source error at parse
255
+ (`TASK_SOURCE_INVALID`); a workflow step's `uses: owner/repo[/path]@rev`
256
+ now fails with reason `unsupported-uses-target` instead of
257
+ `remote-action-acquisition-out-of-scope`. Nothing acquired or executed a
258
+ remote action in any akm release — this deletes the *recognition* of the
259
+ shape, not a capability that ever worked. The migrator still names the
260
+ target explicitly when it blocks a file
261
+ (`github-action-target-removed`).
262
+ - **Multi-job YAML is rejected at the adapter boundary.** A GitHub-shaped
263
+ workflow document whose `jobs:` map does not contain exactly one job now
264
+ fails at the source adapter with reason `multi-job-unsupported`, surfaced
265
+ from `akm workflow run` (and `akm workflow plan`) as `UsageError` code
266
+ `COMPOSITION_INVALID` (exit 2). Previously such a document parsed and
267
+ ordered its jobs cleanly and was refused only later, in two different
268
+ places, with two different shapes (one thrown error, one `ok: false`
269
+ compile result). Split a multi-job document into separate single-job
270
+ workflows and compose them with a child-workflow step
271
+ (`uses: workflows/<ref>`). Every other workflow-source compile failure now
272
+ reports `UsageError` code `WORKFLOW_SOURCE_INVALID` rather than
273
+ `INVALID_FLAG_VALUE`.
274
+ - **The second task scheduling syntax is removed.** `akm.schedule` and a
275
+ task document's top-level `on:` are gone along with task v3 (see "Task v3
276
+ sources no longer parse" above); task source v4's optional top-level
277
+ `schedule:` is the one canonical scheduling form, and a task with no
278
+ `schedule:` is manual-only and fully composable as a workflow-step
279
+ target.
280
+
281
+ ### Changed
282
+
283
+ - **`INVALID_FLAG_VALUE` is now rare in task or workflow domain failures,
284
+ with two named exceptions.** Every task-source, workflow-source,
285
+ target-classification, and composition failure now reports a
286
+ phase-specific code — `TASK_SOURCE_INVALID`, `TARGET_REF_INVALID`,
287
+ `COMPOSITION_INVALID`, `WORKFLOW_SOURCE_INVALID`, `INPUT_BINDING_INVALID`,
288
+ `TASK_SCHEMA_VERSION_UNSUPPORTED`, or `TASK_TARGET_UNSUPPORTED` — **except**
289
+ a task's workflow-target `env:` composition rejection (a `uses:
290
+ workflows/<ref>` task that also authors `env:`) and a workflow child-ref
291
+ asset-resolution failure (`Workflow source target <ref> was not found.`),
292
+ both deliberately preserved as `INVALID_FLAG_VALUE` so an existing pinned
293
+ test's code and message stay byte-unchanged. The remaining
294
+ `INVALID_FLAG_VALUE` sites in the task/workflow domains (38 total, across
295
+ `src/tasks/**` and `src/workflows/**`) are these two preserved exceptions
296
+ plus scalar CLI-argument parsing (a cron expression, a task id, a workflow
297
+ parameter flag) and one code-allowlist membership entry — genuine
298
+ flag-value validation or a pinned exception, not a re-codable
299
+ task/workflow source or composition failure. **Scripts branching on
300
+ `code` for a task/workflow domain error should switch on the specific
301
+ code above rather than assuming `INVALID_FLAG_VALUE` — except for the two
302
+ named exceptions, which still report `INVALID_FLAG_VALUE`.** Exit codes
303
+ are unchanged (2 for every one of these).
304
+ - **A typed task-input or workflow-param flag no longer echoes the supplied
305
+ value in a validation error.** `akm task run <ref> --<input> <value>`
306
+ against a `type:`-declared input used to report
307
+ `must be <types>; received "<value>"` on a coercion failure, and a value
308
+ that failed its declared `enum:`/`minimum:`/`maximum:` constraint reported
309
+ the value in that message too — both are closed now, since a typed flag
310
+ can carry a credential and this detail lands in stderr envelopes that get
311
+ pasted into CI logs and issue reports. The declared constraint (the
312
+ allowed list or the bound) is still named, since it comes from the
313
+ author's own schema rather than the caller's data. Error and exit codes
314
+ are unchanged.
315
+
316
+ ### Added
317
+
318
+ - **Child workflows.** A workflow step can now compose another workflow —
319
+ directly (`uses: workflows/<ref>`) or through a task source v4 document
320
+ whose own target is a workflow (`uses: tasks/<ref>`) — instead of
321
+ failing to freeze. `with:` on the composing step binds the child's
322
+ declared `params:`. Composition is bounded: depth (8 levels), a
323
+ composition cycle, and aggregate embedded plan bytes (1 MiB total across
324
+ one root freeze) are all checked at **freeze**, before the parent run is
325
+ published, and fail with `UsageError` code `COMPOSITION_INVALID`. The
326
+ child workflow is compiled, validated, and frozen **completely** — its own
327
+ complete plan embedded inside the parent's — before the parent run exists,
328
+ so editing the child's source afterward cannot affect an already-frozen
329
+ parent, and the child's transitive sources join the parent's guarded
330
+ source read set. A composing step's own `env:` is rejected at freeze
331
+ (`UsageError` code `COMPOSITION_INVALID`) rather than silently dropped —
332
+ a child run carries its own frozen environment inside its own plan, so a
333
+ parent-level `env:` on the composing step has nothing to apply to.
334
+ Running a step that composes a child workflow now drives
335
+ the child to completion — see **Child workflows now execute** and
336
+ **Workflow `outputs:`** below. (Correction: an earlier development
337
+ increment of this same 0.9.2 release briefly made an unexecuted composing
338
+ step fail closed with `UsageError` code
339
+ `WORKFLOW_CHILD_EXECUTION_UNSUPPORTED`. That code never reached a release
340
+ and is gone from the shipped 0.9.2 — it is listed here only because a
341
+ 0.9.2 pre-release snapshot may otherwise be the sole place it was seen.)
342
+ See
343
+ [Workflow Schema: Child workflows](docs/reference/workflow-schema.md#child-workflows).
344
+ - **Child workflows now execute.** Running a step whose target is a child
345
+ workflow drives that child inline, in the parent's own process, with the
346
+ same engine `akm workflow run` uses — publication is idempotent, so a
347
+ retried or resumed composing step reuses the same child rather than
348
+ starting a new one. The child's final status maps onto the composing
349
+ step and the parent run: `completed` promotes the child's exported result
350
+ as the step's output and the parent continues; `failed` fails the step
351
+ and the run; `blocked` blocks the step and the run, with recovery notes
352
+ naming the exact sequence — `akm workflow resume <childRunId>`, then
353
+ `akm workflow resume <parentRunId>` and `akm workflow run <parentRunId>`.
354
+ `akm workflow status` on a run that composes children now renders a
355
+ `children:` tree; `akm workflow list` excludes child runs by default
356
+ (`--children` includes them), and a child run id always works directly
357
+ with `status`/`resume`/`abandon`/`run`. See
358
+ [Workflow Schema: Child execution](docs/reference/workflow-schema.md#child-execution)
359
+ and [Running Workflows: Child runs](https://github.com/itlackey/akm/blob/main/docs/guides/run-workflows.md#child-runs).
360
+ - **Workflow `outputs:`.** A workflow may declare a run-level export in its
361
+ Markdown frontmatter — `outputs: {<name>: {from: steps.<id>.output(.<seg>)*,
362
+ schema?}}`, up to 64 entries — resolved once, from persisted step
363
+ evidence, at run completion. An unresolvable reference, a truncated
364
+ step artifact, or a schema violation rolls the completion back
365
+ (`UsageError` code `WORKFLOW_OUTPUT_INVALID`): the run stays `active` and
366
+ its final step stays `pending` rather than completing with missing
367
+ exports. A run with no `outputs:` declaration exports `{runId, status}`
368
+ instead. This is a Markdown-frontmatter-only key — a GitHub-shaped
369
+ workflow's closed root key set has no extension surface for it, the same
370
+ reason it cannot declare `params:` either. See
371
+ [Workflow Schema: Workflow outputs](docs/reference/workflow-schema.md#workflow-outputs).
372
+ - **`akm workflow plan <ref>`** (Evolving) — compiles, resolves, and freezes
373
+ a workflow exactly as starting a run would, then stops: zero durable
374
+ writes, no published run, no event, no lease. Prints the canonical step
375
+ graph, per-step frozen target kinds, task/child expansion, input
376
+ bindings, the source read set, and freeze-time lowering notices —
377
+ secret-free by construction (no resolved reference value, request
378
+ content, script bytes, or credential is ever printed). Defaults to a
379
+ human-readable summary; `--format json` returns the full envelope. See
380
+ [CLI reference: workflow plan](docs/reference/cli.md#workflow-plan).
381
+ - **`akm task explain <ref> [input flags]`** — read-only task introspection.
382
+ Prints the task's source path and version, its declared `inputs:` (with
383
+ defaults — a secret-shaped default prints as `<redacted>`), the supplied
384
+ values with provenance (`default` | `flag` | `schedule-binding`, likewise
385
+ redacted when secret-shaped), the resolved target kind/ref, effective
386
+ execution settings with field-level provenance, and schedule bindings.
387
+ Never spawns anything, writes history, or touches the scheduler; never
388
+ prints an `env:` value, a credential, a prompt body, a `run:` string, or
389
+ `with.content`. It accepts the task's own declared input flags and nothing
390
+ else: `--scheduled` — which `explain` neither declares nor implements —
391
+ fails `UNKNOWN_FLAG` (exit 2) rather than being silently discarded, in
392
+ every spelling (`--scheduled`, `--scheduled=false`, …). See
393
+ [CLI reference: task](docs/reference/cli.md#task).
394
+ - **`AKM_TASK_INPUTS`** — the exec-context environment variable a
395
+ task-composed step's shell/script target receives: canonical JSON of its
396
+ resolved, schema-validated `inputs:` bindings. Present only when the
397
+ bindings are non-empty; subject to the same per-platform size ceiling as
398
+ `AKM_INPUTS` / `AKM_PARAMS`. See
399
+ [Context reaching the command](docs/reference/workflow-schema.md#context-reaching-the-command).
400
+ - **A v3 → task source v4 migrator**: the separate `akm-migrate` executable
401
+ (installed alongside `akm`) gains `task-v4-status` / `task-v4-apply
402
+ [--dry-run]`, a second, independent generation of the same dry-run-first,
403
+ `changed | skipped | blocked` migration planner — options bag flattened to
404
+ top-level keys. A `with:` authored on any target other than
405
+ `uses: akm/command` is `blocked` for manual review, alongside a
406
+ github-action-targeted `uses:` (blocked reason
407
+ `github-action-target-removed`) and anything else ambiguous: the migrator
408
+ translates structure, never intent, so `inputs:` is never invented on a
409
+ file's behalf — declaring it is an authoring decision left to the person
410
+ editing the migrated file. Nothing is overwritten without a backup. A
411
+ `changed` file can carry an informational **notice** for a translation that
412
+ is faithful but not one-to-one — a manual-dispatch-only trigger that v4
413
+ expresses as "no `schedule:`", and an `akm.outputSchema` dropped because v4
414
+ accepts `output:` only with a command target — so read the notices on a
415
+ dry-run plan, not just the outcomes. A v3 document that was never valid in
416
+ the first place (an empty `on:`, or a `workflow_dispatch:` carrying
417
+ `inputs:`) is `blocked` as `invalid-v3-task` rather than being converted
418
+ into runnable v4 bytes. By
419
+ 0.9.2's release this generation runs automatically as the second half of
420
+ `akm migrate status` / `akm migrate apply [--dry-run]` (see "Task v3
421
+ sources no longer parse" above) — `task-v4-status`/`task-v4-apply` remain
422
+ as the standalone, single-generation entry points the frozen migrator
423
+ always exposes. See the
424
+ [0.9.1 to 0.9.2 migration guide](docs/migration/v0.9.1-to-v0.9.2.md#migrating-task-v3-to-task-source-v4).
425
+
426
+ ### Fixed
427
+
428
+ - **A flag value for a parameter or input declaring both `array` and a
429
+ scalar type is no longer forced into an array.** `akm workflow run <ref>
430
+ --<param> <value>` (and, new in this release, `akm task run <id>
431
+ --<input> <value>`) unconditionally grouped a supplied value into an array
432
+ whenever the declaration mentioned `array` at all, so
433
+ `type: ["array", "string"]` with `--x hello` delivered `["hello"]` instead
434
+ of the permitted string, and `type: ["array", "null"]` could never produce
435
+ `null` — silently, since the altered value still satisfied the array
436
+ branch. A single, non-bracketed value now tries the union's scalar
437
+ alternatives first. An `array`-only declaration, the JSON-array shorthand
438
+ (`--x '["a","b"]'`), and grouping a repeated flag are all unchanged.
439
+ - **`akm task <subcommand> --target=<value>` now answers with the 0.9 rename
440
+ hint instead of ignoring the flag.** The retired-spelling check compared
441
+ whole argv tokens, so it caught a bare `--target` but not `--target=team`;
442
+ because `target` is exempt from the generic unknown-flag gate on `task`
443
+ subcommands precisely so that check can answer, the `=`-spelling was
444
+ rejected by nothing at all and the bundle the caller named was silently
445
+ dropped. It now fails with `UsageError` code `INVALID_FLAG_VALUE` (exit 2)
446
+ naming `--bundle`, in every spelling.
447
+ - **The embedded `akm` hint sheet no longer teaches a task format this
448
+ release rejects.** Its "Scheduled Tasks" section still told readers to
449
+ author `version: 3` with `akm.enabled` and `akm.timeout`; it now describes
450
+ task source v4 (`version: 4`, per-entry `schedule[].enabled`, top-level
451
+ `timeout`, typed `inputs:`/`output:`) and points at `akm migrate apply`.
452
+ The `stash`-terminology doc lint now scans the shipped hint assets too, so
453
+ the embedded help cannot drift out of the active-docs vocabulary again.
454
+ - **The macOS native scheduler backend no longer refuses a real
455
+ `launchctl` inventory.** Its loaded-service reader enforced a narrow,
456
+ hand-written grammar over `launchctl print`'s full output and rejected
457
+ the entire read — surfacing as `INVALID_CONFIG_FILE` from every akm
458
+ scheduler command — the moment any line fell outside it, which real
459
+ `launchctl` output on a real Mac routinely does. It now scans for akm's
460
+ own `com.akm.task.*` labels and ignores everything else, which is what
461
+ every caller actually needed. Caught by the gated native-scheduler
462
+ suite's first run against macOS.
463
+ - **The Windows-built package no longer ships without its embedded
464
+ template assets.** The build's asset-copy step matched paths against a
465
+ forward-slash pattern, but path separators on Windows are backslashes,
466
+ so the match silently failed and `dist/assets/` was never populated —
467
+ the packaged npm tarball built on Windows carried no templates at all,
468
+ and any command rendering one (for example `akm health --format html`)
469
+ crashed with `ERR_MODULE_NOT_FOUND`. Also caught by the gated
470
+ native-scheduler suite's first run, this time against Windows.
471
+
9
472
  ## [0.9.2-alpha.4] - 2026-08-26
10
473
 
11
474
  ### Added
package/STABILITY.md CHANGED
@@ -58,6 +58,7 @@ enumeration of the whole `proposal` noun group.
58
58
  | `akm curate` | Stable | |
59
59
  | `akm show` | Stable | |
60
60
  | `akm workflow status` | Stable | |
61
+ | `akm workflow plan` | Evolving | New in 0.9.2; secret-free provenance output; envelope shape may change. |
61
62
  | `akm workflow list` | Stable | |
62
63
  | `akm workflow create` | Stable | |
63
64
  | `akm workflow resume` | Stable | |
@@ -110,6 +111,7 @@ enumeration of the whole `proposal` noun group.
110
111
  | `akm task history` | Evolving | |
111
112
  | `akm task sync` | Evolving | |
112
113
  | `akm task doctor` | Evolving | |
114
+ | `akm task explain` | Evolving | New in 0.9.2; secret-shaped values in provenance output are redacted on a best-effort heuristic basis (not a guarantee). |
113
115
 
114
116
  ## Stable
115
117
 
@@ -254,11 +256,27 @@ CHANGELOG with a migration note.
254
256
  `akm improve && akm proposal drain --promote --yes`, or a `triage` block
255
257
  with `applyMode: "promote"` in your strategy.
256
258
  - **Tasks** — `akm task` subcommand surface (`add | run | sync | doctor |
257
- history`; no alias, no `list`/`remove`/`init`/`enable`/`disable`); strict
258
- version-2 YAML for scheduled tasks. Prompt tasks use named engines and task
259
- history metadata is versioned. Schema additions in patch releases; removals
260
- only at minor. Bare `akm task` is a usage error naming the subcommands
261
- (`akm task doctor` reports scheduler diagnostics).
259
+ history | explain`; no alias, no `list`/`remove`/`init`/`enable`/`disable`);
260
+ task source v4 YAML (typed `inputs:`, optional `schedule:`) is the only
261
+ accepted version task v3 and task v2 sources are converted by
262
+ `akm migrate apply`. Command tasks use named engines and task history
263
+ metadata is versioned. Schema additions in patch releases; removals only at
264
+ minor. Bare `akm task` is a usage error naming the subcommands
265
+ (`akm task doctor` reports scheduler diagnostics). `akm task explain <ref>`
266
+ (new in 0.9.2) and `akm workflow plan <ref>` are both zero-write
267
+ provenance surfaces: they show what a task or workflow would do —
268
+ resolved target, input bindings, child expansion — without starting or
269
+ publishing a run. `akm workflow plan` is secret-free **by construction**
270
+ (the excluded data never reaches the command). `akm task explain`
271
+ instead **redacts** secret-shaped input values on a best-effort
272
+ heuristic basis — a value that doesn't match the heuristic can still
273
+ print unredacted.
274
+ - **Workflow plan** — `akm workflow plan <ref>`, new in 0.9.2: zero-write
275
+ compile+freeze introspection (the canonical step graph, task/child
276
+ expansion, input bindings, and lowering notices for a workflow, without
277
+ starting or publishing a run). The envelope shape may still change; the
278
+ five long-Stable `workflow` verbs (`status`, `list`, `create`, `resume`,
279
+ `abandon`) and `run` are unaffected.
262
280
  - **Events / log** — `akm log` is the event-stream surface (0.9.0: the
263
281
  asset-scoped `akm history` surface, and `log`'s own `tail` subcommand, were
264
282
  both removed; `log` is now a leaf command — the former `list` surface).
@@ -362,16 +362,21 @@ akm task sync --rebind # Also re-pin the scheduler's akm
362
362
  akm task doctor # Scheduler binding + runtime eligibility diagnosis
363
363
  akm task history # Recent run rows (status, timing)
364
364
  akm task run <id> # Run one task immediately (works when disabled)
365
+ akm task explain <ref> # Read-only: declared inputs, target, schedule — spawns nothing
365
366
  akm search --type task # Enumerate task assets (there is no `task list`)
366
367
  ```
367
368
 
368
- Task files use strict task v3 (`version: 3`). To disable one, set
369
- `akm.enabled: false` and run `akm task sync`
370
- (the cron line stays, commented). To remove one, delete the YAML and run
371
- `akm task sync` the scheduler entry is unbound. Per-task `akm.timeout` may
372
- be `null` (disable the invocation timer) or a duration/number overriding the
373
- selected engine invocation timeout. Preview old task-v2 conversion with
374
- `akm migrate apply --dry-run`.
369
+ Task files use task source v4 (`version: 4`). There is no `akm:` options bag
370
+ or `on:` block every control (`schedule`, `timeout`, `engine`, `model`,
371
+ `redact`, `maxSteps`, `maxRetries`, ) is a top-level key now. Typed
372
+ `inputs:` declarations and a bounded `output:` schema work like a
373
+ workflow's (`output:` replaces v3's `akm.outputSchema`). To disable one
374
+ schedule entry, set that entry's `enabled: false` under `schedule:` and run
375
+ `akm task sync` (the cron line stays, commented); to remove one, delete the
376
+ YAML and run `akm task sync` — the scheduler entry is unbound. Top-level
377
+ `timeout:` may be `null` (disable the invocation timer) or a duration/number
378
+ overriding the selected engine invocation timeout. Preview old task-v2/v3
379
+ conversion with `akm migrate apply --dry-run`.
375
380
 
376
381
  ## Agent Dispatch
377
382
 
@@ -1,6 +1,4 @@
1
- version: 3
1
+ version: 4
2
2
  run: akm proposal extract --auto
3
- akm:
4
- schedule: "*/30 * * * *"
5
- enabled: true
6
- description: Opt-in all-harness session extraction every 30 min
3
+ description: Opt-in all-harness session extraction every 30 min
4
+ schedule: "*/30 * * * *"
@@ -1,6 +1,4 @@
1
- version: 3
1
+ version: 4
2
2
  run: akm improve
3
- akm:
4
- schedule: "0 2 * * *"
5
- enabled: true
6
- description: Run improve pipeline nightly
3
+ description: Run improve pipeline nightly
4
+ schedule: "0 2 * * *"
@@ -1,6 +1,4 @@
1
- version: 3
1
+ version: 4
2
2
  run: akm index
3
- akm:
4
- schedule: "0 4 * * *"
5
- enabled: true
6
- description: Nightly incremental index refresh
3
+ description: Nightly incremental index refresh
4
+ schedule: "0 4 * * *"
@@ -1,6 +1,4 @@
1
- version: 3
1
+ version: 4
2
2
  run: akm sync
3
- akm:
4
- schedule: "*/15 * * * *"
5
- enabled: true
6
- description: Sync stash changes to git remote every 15 min
3
+ description: Sync stash changes to git remote every 15 min
4
+ schedule: "*/15 * * * *"
@@ -1,6 +1,4 @@
1
- version: 3
1
+ version: 4
2
2
  run: akm upgrade --check
3
- akm:
4
- schedule: "0 9 * * 1"
5
- enabled: true
6
- description: Weekly check for new akm releases
3
+ description: Weekly check for new akm releases
4
+ schedule: "0 9 * * 1"
@@ -1,6 +1,4 @@
1
- version: 3
1
+ version: 4
2
2
  run: akm improve --strategy graph-refresh --skip-if-locked
3
- akm:
4
- schedule: "10 3 * * 0"
5
- enabled: true
6
- description: Full-corpus graph rebuild (weekly Sunday 3:10am)
3
+ description: Full-corpus graph rebuild (weekly Sunday 3:10am)
4
+ schedule: "10 3 * * 0"
@@ -1,9 +1,9 @@
1
- version: 3
1
+ version: 4
2
2
  run: akm improve --strategy catchup --skip-if-locked
3
- akm:
4
- schedule: "0 4 * * *"
3
+ description: Manual recovery — consolidation + triage drain (run on demand via `akm task run akm-improve-catchup`)
5
4
  # Manual-recovery task: ships disabled (the retired registerDefaultTasks
6
5
  # marked it enableMode: "manual"). `akm task run` works while disabled;
7
- # opting into the schedule is `enabled: true` + `akm task sync`.
8
- enabled: false
9
- description: Manual recovery consolidation + triage drain (run on demand via `akm task run akm-improve-catchup`)
6
+ # opting into the schedule is `schedule[].enabled: true` + `akm task sync`.
7
+ schedule:
8
+ - cron: "0 4 * * *"
9
+ enabled: false
@@ -1,6 +1,4 @@
1
- version: 3
1
+ version: 4
2
2
  run: akm improve --strategy consolidate --skip-if-locked
3
- akm:
4
- schedule: "20 */4 * * *"
5
- enabled: true
6
- description: Consolidation-only pass (every 4h at :20)
3
+ description: Consolidation-only pass (every 4h at :20)
4
+ schedule: "20 */4 * * *"