akm-cli 0.9.2-alpha.4 → 0.9.2

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 +493 -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 +265 -52
  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 +77 -14
  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 +24 -7
  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 +3 -2
  127. package/docs/migration/v0.8-to-v0.9.md +13 -11
  128. package/docs/migration/v0.9.0-troubleshooting.md +20 -13
  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 +6 -5
  133. package/docs/reference/supported-formats.md +9 -5
  134. package/docs/reference/tasks.md +338 -75
  135. package/docs/reference/workflow-schema.md +290 -16
  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
@@ -1,31 +1,49 @@
1
1
  # Tasks
2
2
 
3
3
  Task assets are strict, local automation sources. They live at
4
- `<bundle>/tasks/<id>.yml`, use task schema `version: 3`, and can be run directly
5
- or reconciled to cron, launchd, or Windows Task Scheduler with `akm task sync`.
6
- The task file is authored source; scheduler entries are derived OS state.
4
+ `<bundle>/tasks/<id>.yml` and can be run directly or reconciled to cron,
5
+ launchd, or Windows Task Scheduler with `akm task sync`. The task file is
6
+ authored source; scheduler entries are derived OS state.
7
+
8
+ **Task source v4 (`version: 4`) is the only task source grammar this
9
+ release accepts.** A document with `version: 3` or `version: 2` (or any
10
+ other value) fails to load with `UsageError` code
11
+ `TASK_SCHEMA_VERSION_UNSUPPORTED`, naming the migrator. Task source v4 adds
12
+ typed `inputs:` and a single bounded `output:` schema (command targets
13
+ only), and makes scheduling OPTIONAL rather than mandatory. `akm task add`
14
+ authors task source v4 directly.
15
+
16
+ If you have `version: 3` or `version: 2` files on disk (from an earlier
17
+ akm release), see [Migrating to task source v4](#migrating-to-task-source-v4)
18
+ below — `akm migrate apply` converts both generations in one pass. The
19
+ retired v3 grammar itself is documented at the bottom of this page
20
+ ([Task v3 (retired): grammar reference for migration](#task-v3-retired-grammar-reference-for-migration))
21
+ purely so you can read an old file while migrating it; it is not accepted
22
+ by any command in this release.
7
23
 
8
24
  ## Files and schema
9
25
 
10
26
  The only recognized task extension is `.yml`. A `.yaml` near miss is never
11
- indexed, scheduled, or run. Every task must declare `version: 3`; unknown keys
12
- and older versions fail closed. The published [task schema](../../schemas/akm-task.json)
13
- describes the hand-authored contract, while `src/tasks/source-v3.ts` remains the
27
+ indexed, scheduled, or run. Every task must declare `version: 4`; a
28
+ document with no `version:` key, or a `version:` that is not a number,
29
+ fails with `TASK_SOURCE_INVALID` (`must be exactly 4.` / `is required and
30
+ must be exactly 4.`) — a genuinely malformed v4 document, not a legacy one.
31
+ `version: 3` and `version: 2` fail with `TASK_SCHEMA_VERSION_UNSUPPORTED`
32
+ instead (see [Migrating to task source v4](#migrating-to-task-source-v4)).
33
+ The published [task schema](../../schemas/akm-task.json) describes the
34
+ hand-authored contract; `src/tasks/source/task-source-v4.ts` is the
14
35
  authoritative bounded parser.
15
36
 
16
- At the top level a task can use `name`, exactly one executable selector, common
17
- step fields, and exactly one trigger source:
18
-
19
37
  ```yaml
20
- version: 3
38
+ version: 4
21
39
  name: Nightly review
22
40
  uses: workflows/nightly-review
23
- with:
24
- strict: true
25
- akm:
26
- schedule: "0 4 * * *"
27
- enabled: true
28
- timeout: 30m
41
+ inputs:
42
+ strict:
43
+ type: boolean
44
+ default: true
45
+ schedule: "0 4 * * *"
46
+ timeout: 30000
29
47
  ```
30
48
 
31
49
  Task YAML is bounded before expansion: source size, YAML depth, aggregate node
@@ -38,37 +56,38 @@ are rejected rather than normalized.
38
56
  A task selects exactly one of `uses` or `run`; the two fields are mutually
39
57
  exclusive.
40
58
 
41
- `uses` accepts these 0.9.2 target shapes:
59
+ `uses` accepts these target shapes:
42
60
 
43
61
  - `akm/command`, the built-in inline/referenced command action. Its `with`
44
62
  object requires exactly one of `with.ref` or `with.content`; they are
45
63
  mutually exclusive. `with.arguments` is one optional portable string, used
46
- for the single, one-pass `$ARGUMENTS` substitution.
64
+ for the single, one-pass `$ARGUMENTS` substitution. `with:` is legal
65
+ **only** alongside `uses: akm/command` — every other target uses typed
66
+ `inputs:` instead (see [Input flags](#input-flags)).
47
67
  - Asset refs rooted at `commands/`, `workflows/`, or `scripts/`, optionally
48
68
  qualified with a bundle such as `team//commands/review`.
49
- - A revision-qualified GitHub action spelling such as `owner/repo@ref` or
50
- `owner/repo/path@revision`. That syntax is recognized so it cannot be
51
- mistaken for an AKM ref, but remote action acquisition and execution are
52
- unsupported in 0.9.2 and fail before dispatch.
69
+
70
+ A GitHub Action locator (`owner/repo[/path]@ref`, e.g. `actions/checkout@v4`)
71
+ is **not** a recognized `uses:` shape it fails at parse with
72
+ `TASK_SOURCE_INVALID` alongside every other unrecognized target. AKM never
73
+ acquired or executed a remote action in any release; this is the removal of
74
+ a recognized-but-rejected spelling, not a capability that used to work.
53
75
 
54
76
  Agent refs such as `agents/reviewer` are personas and are not executable.
55
77
  Task refs such as `tasks/nightly` are also not executable. Local actions
56
78
  (`./action`) are rejected and Docker actions (`docker://image`) are unsupported.
57
- GitHub expressions are unsupported and rejected before dispatch. Unqualified
58
- remote actions are rejected too.
79
+ GitHub expressions are unsupported and rejected before dispatch.
59
80
 
60
81
  The runtime applies this target-by-target field matrix. Validation is strict;
61
82
  fields are not silently discarded.
62
- For `scripts/` asset refs, `with` is rejected before dispatch.
63
83
 
64
- | Target | `with` | task `env` | Interpreter / execution |
84
+ | Target | `with` / `inputs` | task `env` | Interpreter / execution |
65
85
  |---|---|---|---|
66
- | `run` | Rejected; `with` is legal only with `uses` | Allowed | One authored string through the selected closed host `shell` |
86
+ | `run` | No `with`; declare `inputs:` for typed parameters | Allowed | One authored string through the selected closed host `shell` |
67
87
  | `akm/command` | Required action object: exactly one of `ref` or `content`, plus optional portable `arguments` | Allowed and passed through the command resolver | Shared command authorization and lowering |
68
- | `commands/<name>` | Direct command refs: `with` is rejected; use `akm/command` for portable arguments | Allowed and passed through the command resolver | Shared command authorization and lowering |
69
- | `workflows/<name>` | Of asset refs, workflow refs alone consume `with` as workflow params | A nonempty task `env` is rejected because the durable workflow runtime cannot consume it in 0.9.2 | Fresh durable workflow start |
70
- | `scripts/<name>.<ext>` | Script refs: `with` is rejected | Allowed for the child process | Closed extension-to-interpreter table below |
71
- | `owner/repo[/path]@ref` | Not consumed | Not consumed | Recognized spelling, but remote acquisition is rejected in 0.9.2 |
88
+ | `commands/<name>` | No `with`; declare `inputs:` for typed parameters | Allowed and passed through the command resolver | Shared command authorization and lowering |
89
+ | `workflows/<name>` | Declared `inputs:` become the child run's params | A nonempty task `env` is rejected because the durable workflow runtime cannot consume it | Fresh durable workflow start |
90
+ | `scripts/<name>.<ext>` | No `with`; declare `inputs:` for typed parameters | Allowed for the child process | Closed extension-to-interpreter table below |
72
91
 
73
92
  Script refs use this closed table; any other extension fails before dispatch:
74
93
 
@@ -95,77 +114,281 @@ shell from `uses`. `working-directory` must be a relative, contained path under
95
114
  the task's workspace root. Absolute paths, traversal, dangling links, and
96
115
  symlink escapes fail before execution.
97
116
 
98
- Common resolver fields live under `akm`: `agent`, `engine`, `model`,
99
- `inference`, `outputSchema`, `tools`, `timeout`, `redact`, `maxSteps`, and
100
- `maxRetries`. Environment entries are literal string, number, or boolean
101
- values. Keep credentials out of task source; `redact` contains environment
102
- variable names, never secret values.
103
-
104
- ## Scheduling and triggers
117
+ Every field that used to live under v3's `akm:` options bag is a top-level
118
+ key in task source v4: `agent`, `engine`, `model`, `inference`, `tools`,
119
+ `timeout`, `redact`, `maxSteps`, and `maxRetries`, plus `description`,
120
+ `when_to_use`, and `tags`. Environment entries (`env`) are literal string,
121
+ number, or boolean values. Keep credentials out of task source; `redact`
122
+ contains environment variable names, never secret values.
105
123
 
106
- A task has exactly one scheduling source: either `akm.schedule` or top-level
107
- `on`. The two sources are mutually exclusive.
124
+ ## Scheduling
108
125
 
109
- The compact AKM spelling is:
126
+ Scheduling is **optional**. Omit `schedule:` entirely for a manual-only
127
+ task: the source still parses, still runs with `akm task run`, and
128
+ `akm task sync` silently contributes zero scheduler bindings for it (no OS
129
+ entry, no failure) rather than rejecting the source for missing a trigger.
110
130
 
111
131
  ```yaml
112
- version: 3
132
+ version: 4
133
+ name: Nightly review
113
134
  run: akm improve --strategy default
114
- akm:
115
- schedule: "@daily"
116
- enabled: false
135
+ schedule:
136
+ - cron: "@daily"
137
+ enabled: false
117
138
  ```
118
139
 
119
- The GitHub-shaped local trigger subset accepts schedule entries and an empty
120
- manual trigger:
140
+ A bare string (`schedule: "0 8 * * 1"`) is shorthand for one enabled
141
+ binding with no inputs. A list entry may set its own `enabled` (default
142
+ `true`) and literal `inputs`; those literals are validated against the
143
+ task's `inputs:` declarations both at parse time and again at
144
+ `akm task sync` (once with declared defaults applied), and are
145
+ **delivered** to the scheduled run: `akm task sync` compiles each entry's
146
+ inputs into the scheduler binding's own invocation tail
147
+ (`akm task run <id> --scheduled --<name> <value>…`, names sorted), so the
148
+ fired run receives them exactly as `akm task run <id> --<name> <value>`
149
+ would. Multiple schedule entries create deterministic scheduler bindings
150
+ for the one source task.
151
+
152
+ Task source v4 has **no document-level `enabled` flag** — enablement is
153
+ per schedule binding. Disable one binding by setting its own
154
+ `enabled: false`. `--schedule` is a required flag on every `akm task add`
155
+ invocation, `--disabled` included — not a check specific to `--disabled` —
156
+ so `akm task add --disabled` always has a schedule to write `enabled: false`
157
+ onto and never needs to reject a schedule-less task with "nothing to
158
+ disable."
159
+
160
+ `akm task run <id>` executes a task immediately, including a disabled task.
161
+ `akm task sync` validates the complete desired set before atomically
162
+ reconciling scheduler state. Scheduled invocations re-read the guarded current
163
+ task bytes; workflow targets then create a fresh durable workflow freeze.
164
+
165
+ ## Typed inputs and output
121
166
 
122
167
  ```yaml
123
- version: 3
168
+ version: 4
169
+ name: Review code
170
+ description: Summarize a pull request's changed surface
171
+ inputs:
172
+ scope:
173
+ type: string
174
+ enum: [changed, all]
175
+ default: changed
176
+ strict:
177
+ type: boolean
178
+ default: true
179
+ ticket:
180
+ type: string
181
+ required: true
182
+ output:
183
+ type: object
184
+ properties:
185
+ summary: { type: string }
124
186
  uses: commands/review
125
- on:
126
- schedule:
127
- - cron: "0 6 * * *"
128
- workflow_dispatch: {}
187
+ schedule:
188
+ - cron: "0 8 * * 1"
189
+ enabled: true
190
+ inputs: { scope: all, ticket: OPS-1234 }
191
+ timeout: 45000
192
+ engine: reviewer
193
+ redact: [TOKEN]
129
194
  ```
130
195
 
131
- `workflow_dispatch` accepts no inputs. Service events such as `push` are
132
- rejected and create no watcher or polling daemon. A source with only
133
- `workflow_dispatch` is manual-only and is not installed as a time schedule.
134
- Multiple schedule entries create deterministic scheduler bindings for the one
135
- source task.
196
+ - `inputs:` declares named, typed parameters. Each declaration is a bounded
197
+ JSON Schema (`type`, `enum`, `properties`, `items`, `minimum`/`maximum`,
198
+ `allOf`/`anyOf`/`oneOf`/`not`, and similar keywords an unlisted keyword is
199
+ rejected) plus two keys unique to task source v4: `default` (which must
200
+ itself satisfy the rest of the declaration) and `required: true` (mutually
201
+ exclusive with `default`). Declaration names follow the same identifier
202
+ grammar as workflow parameters, and additionally may not name a flag `akm
203
+ task run` already declares for itself — `bundle`, `format`, `detail`,
204
+ `shape`, `output`, `scheduled`, `quiet`, `verbose`, `help`, `no-quiet`, or
205
+ `no-verbose`. Parsing rejects a colliding name with `TASK_SOURCE_INVALID`
206
+ at declaration time, since `akm task run --<name>`, `akm task explain
207
+ --<name>`, and a `schedule[].inputs` entry would otherwise route the value
208
+ into `akm task run`'s own flag instead of the declared input.
209
+ - **A `required: true` input with no default must be satisfied by every
210
+ schedule binding.** A scheduled run supplies no input flags — the entry's
211
+ own `inputs:` literals plus the declared defaults are the whole value set
212
+ it gets — and a `required: true` input may not carry a `default`, so an
213
+ entry that names no value for one could never run. Parsing rejects that
214
+ contradiction with `TASK_SOURCE_INVALID` at the offending entry's own
215
+ field path (`schedule`, or `schedule[<i>]`), naming the unsatisfied
216
+ input. The rule covers every entry: the `schedule: "<cron>"` string
217
+ shorthand, a list entry with no `inputs:` key, and an entry whose
218
+ `inputs:` mapping is present but incomplete — including one written
219
+ `enabled: false`, so enabling it later can never turn a parsed document
220
+ unrunnable. `akm task sync` keeps its own equivalent check over the
221
+ defaulted values and still rejects the whole desired set before touching
222
+ any scheduler state. Give every schedule entry an explicit value for the
223
+ input, or declare a `default` instead; manual runs are unaffected — a
224
+ task with no `schedule:` stays valid whatever it requires, and `akm task
225
+ run` takes the value from the input's own flag.
226
+ - `output:` is a single bounded JSON Schema, replacing v3's
227
+ `akm.outputSchema`. It is legal only on a command target
228
+ (`uses: commands/<ref>` or `uses: akm/command`), where it is forwarded to
229
+ the prepared invocation as a response-shaping schema. `run:`,
230
+ `uses: scripts/`, and `uses: workflows/` executions have no output-schema
231
+ consumer — a native run's status comes from its exit code alone — so
232
+ declaring `output:` on them fails parsing with `TASK_SOURCE_INVALID`
233
+ instead of silently recording a contract nothing enforces.
234
+ - A task source v4 document **can** be the target of a workflow step's
235
+ `uses: tasks/<ref>` — see the
236
+ [GitHub-shaped YAML subset](workflow-schema.md#github-shaped-yaml-subset)
237
+ for how a workflow step's `with:` binds a v4 task's declared `inputs:`.
238
+
239
+ ### Input flags
240
+
241
+ `akm task run <id>` accepts one exact-name flag per declared `inputs:` entry,
242
+ mirroring `akm workflow run`'s parameter flags:
136
243
 
137
- `akm task run <id>` executes a task immediately, including a disabled task.
138
- `akm task sync` validates the complete desired set before atomically
139
- reconciling scheduler state. Scheduled invocations re-read the guarded current
140
- task bytes; workflow targets then create a fresh durable workflow freeze.
244
+ ```sh
245
+ akm task run review --scope all --strict # doclint:ignore
246
+ ```
247
+
248
+ Flag names are task-specific — they come from that task's own `inputs:`
249
+ declarations — so they are not listed on `akm task run --help` and the
250
+ example above uses one task's actual declared names, not a fixed syntax.
251
+ An undeclared flag fails with `UNKNOWN_FLAG`; a value that does not satisfy
252
+ its declaration, or a missing `required: true` input supplied by neither a
253
+ flag nor a default, fails with `INPUT_BINDING_INVALID` — both exit `2` with
254
+ the usual `{ok:false,error,code}` envelope on stderr.
255
+
256
+ Where the materialized values go next depends on the task's own target, and
257
+ is narrower than it may look: when the target is `uses: workflows/<ref>`,
258
+ the values become the child run's params (the same `with:` → params path a
259
+ workflow step's own composition uses); for every other target — `run:`
260
+ shell, `scripts/<ref>`, `commands/<ref>` — the values are validated and then
261
+ **discarded**. `akm task run`'s own flags never populate an
262
+ `AKM_TASK_INPUTS` environment variable or a `## Task inputs` prompt block.
263
+ Those two surfaces are a *different* delivery path: they exist only when a
264
+ **workflow step** composes this task through `uses: tasks/<ref>` and a
265
+ `with:` binding, resolved fresh for that step's own dispatch — see
266
+ [`with:` on a task-composed step](workflow-schema.md#github-shaped-yaml-subset).
267
+ A scheduled run (`schedule[].inputs`, above) reaches the target through this
268
+ same `akm task run` path, so it inherits the identical rule: delivered as
269
+ params for a `workflows/<ref>` target, otherwise validated and discarded.
270
+ `akm task explain` (below) shows the materialized values regardless of where
271
+ they end up, which is the fastest way to check what a given `akm task run`
272
+ invocation would actually deliver. `akm task add --params` renders
273
+ `--params` values as typed `inputs:` declarations with `default:` values
274
+ (typed from each JSON value's runtime type), not a `with:` bag.
275
+
276
+ ### `akm task explain`
277
+
278
+ `akm task explain <ref> [input flags]` prints a task's source path and
279
+ version, its declared `inputs:` (name, type, `enum`, `required`, `default`),
280
+ the values that would actually be supplied — with provenance
281
+ (`default` | `flag` | `schedule-binding`) — the resolved target kind/ref,
282
+ effective execution settings with field-level provenance, and schedule
283
+ bindings. It is **read-only**: it never spawns anything, writes history, or
284
+ touches the scheduler. A secret-shaped value (a declared default, a supplied
285
+ value, or a schedule binding's literal) prints as `"<redacted>"` with its row
286
+ marked `redacted: true` instead of the real value; an `env:` binding is shown
287
+ as a name/ref only, never its resolved value.
141
288
 
142
- ## Migrating task v2 to v3
289
+ ```sh
290
+ akm task explain review --scope all # doclint:ignore
291
+ ```
143
292
 
144
- Normal execution rejects task v2 and prints the migration hint. Preview the
145
- same fail-closed migration plan that apply consumes:
293
+ `akm task explain`'s default output (no `--format` flag) is the **same raw
294
+ JSON** as `--format json`, byte for byte — there is nothing to lose by
295
+ piping the default form into `jq` or a script. `--format text` is a
296
+ separate renderer: it flattens the same envelope into `dotted.path=value`
297
+ lines (the same convention `akm config list --format text` uses), not a
298
+ copy of the JSON.
299
+
300
+ > A secret-shaped **input default** (as opposed to a supplied value) is
301
+ > redacted the same way, but its accompanying explanation currently reuses
302
+ > workflow-parameter wording that does not quite fit a task input — treat
303
+ > the redaction itself as reliable even where the prose reads oddly.
304
+ > `akm task run --<name> <secret-looking-value>` never echoes the offered
305
+ > value in its error envelope, whether the value fails typed-flag coercion
306
+ > or fails the declared schema (an `enum`/`minimum`/`maximum` mismatch
307
+ > included) — both paths report only the violated constraint.
308
+
309
+ ## Migrating to task source v4
310
+
311
+ `akm migrate status` and `akm migrate apply [--dry-run]` run **both**
312
+ migration generations against your task tree in one pass: task-v2 → task-v3
313
+ first, then task-v3 → task source v4 against the resulting files. Each
314
+ generation keeps its own lock, backup, prevalidation, and rollback — a file
315
+ blocked in the first generation does not stop the second generation from
316
+ converting files that are already `version: 3`.
146
317
 
147
318
  ```sh
148
319
  akm migrate apply --dry-run
149
320
  akm migrate apply
150
321
  ```
151
322
 
152
- The planner reports every input file as `changed`, `skipped`, or `blocked`.
153
- Deterministic prompt, command-ref, workflow-ref, and safe command-string cases
154
- become v3. An argv array or any command whose shell meaning cannot be preserved
155
- is blocked for manual review and remains untouched. Apply validates a complete
156
- v3 replacement before writing and backs up each original immediately before
157
- replacement.
323
+ The planner reports every input file as `changed`, `skipped`, or `blocked`,
324
+ for both generations combined. Resolve every blocked file manually, then
325
+ preview again. Apply validates a complete replacement before writing and
326
+ backs up each original immediately before replacement.
327
+
328
+ Common v3 → v4 blocked reasons and what to do about each:
329
+
330
+ | Reason | Meaning | Fix |
331
+ |---|---|---|
332
+ | `github-action-target-removed` | The task's `uses:` is a GitHub Action locator (`owner/repo[/path]@ref`); that spelling has no task source v4 equivalent. | Rewrite the target as `commands/`, `scripts/`, `workflows/`, or `akm/command` by hand. |
333
+ | `with-on-non-command-target` | A `with:` block is authored on a target other than `uses: akm/command`. | Task-call inputs are declared and bound separately in v4 — author `inputs:` on the task and, if it is a workflow step's own composition, bind them with the step's `with:` instead. |
334
+ | `ambiguous-scheduling-source` | The document declares both `akm.schedule` and `on:`. | Pick one; the migrator will not guess which one wins. |
335
+ | `enabled-false-has-no-schedule-entry` | `akm.enabled: false` with no cron trigger to attach it to (the only trigger is `on.workflow_dispatch`). | Task source v4 has no document-level `enabled` flag — decide whether the task should be scheduled (add a cron) or left manual-only (drop `akm.enabled`), then re-run. |
336
+ | `read-only-source` | The owning source or file is not writable. | Move or re-source the file somewhere writable, or edit it by hand. |
337
+ | `invalid-v3-task` | The v3 document itself is structurally invalid (unknown fields, missing selector, malformed trigger, etc). | Fix the underlying v3 document first — the migrator translates structure, it does not repair it. |
338
+ | `generated-v4-validation-failed` | The converted bytes fail the real task source v4 parser; the detail carries the parse error. | Read the detail — it names the offending field and why v4 refuses it — then fix that field in the v3 file and preview again. |
339
+
340
+ The migrator translates structure, never intent: it never invents an
341
+ `inputs:` declaration on a file's behalf, regardless of how inferable a
342
+ `with:` value's shape looks — declaring `inputs:` (and rewriting a step to
343
+ bind it) is left to the person editing the migrated file by hand.
344
+
345
+ A `changed` file can still carry an informational **notice** alongside its
346
+ converted bytes, for a translation that is faithful but not one-to-one. Each
347
+ notice is reported on that file's own plan entry, and it is the only record of
348
+ a field the migrator resolved by dropping rather than rewriting — read them.
349
+ Two cases produce one today:
350
+
351
+ - **`akm.outputSchema` on a `run:`, `uses: scripts/`, or `uses: workflows/`
352
+ target is dropped, not hoisted to `output:`.** v4 accepts `output:` only on
353
+ a command target (`uses: commands/<ref>` or `uses: akm/command`) — the only
354
+ kinds whose runtime enforces it — and on the other three v3 never enforced
355
+ it either, so nothing enforceable is lost. The file migrates as `changed`
356
+ with a notice naming the dropped field; it is not blocked, and there is
357
+ nothing to edit by hand first. If you *wanted* that schema enforced, move
358
+ the work behind a command target and author `output:` there.
359
+ - **`on.workflow_dispatch` with no `on.schedule` drops silently**, since every
360
+ v4 task is runnable manually with `akm task run` whether or not it has a
361
+ `schedule:`. The migrated document simply has no `schedule:` key.
362
+
363
+ If you only want to run one generation in isolation (for example, your
364
+ tree is already all `version: 3` and you want to preview just the v4 step),
365
+ the frozen migrator's standalone, single-generation entry points remain
366
+ available as a separate executable:
367
+
368
+ ```sh
369
+ akm-migrate task-v4-status
370
+ akm-migrate task-v4-apply --dry-run
371
+ akm-migrate task-v4-apply
372
+ ```
158
373
 
159
- See the [0.9.1 to 0.9.2 migration guide](../migration/v0.9.1-to-v0.9.2.md)
160
- for before/after examples, preserved fields, and recovery guidance.
374
+ See the [0.9.1 to 0.9.2 migration guide](../migration/v0.9.1-to-v0.9.2.md#migrating-task-v3-to-task-source-v4)
375
+ for full before/after examples and recovery guidance.
161
376
 
162
377
  ## Operations
163
378
 
164
379
  - `akm search --type task` and `akm show tasks/<id>` inspect task assets.
165
- - `akm task add` writes a task-v3 source and installs it after validation.
380
+ - `akm task explain <ref>` prints a task's declared inputs, resolved target,
381
+ effective execution settings, and schedule bindings without running
382
+ anything — see [`akm task explain`](#akm-task-explain) above.
383
+ - `akm task add` writes a task source v4 document and installs it after
384
+ validation. `--params` renders typed `inputs:` declarations instead of a
385
+ `with:` bag; `--schedule` is required on every invocation, and
386
+ `--disabled` writes `schedule: [{cron: …, enabled: false}]` instead of a
387
+ document-level flag.
166
388
  - `akm task history` reads durable run history from `state.db`.
167
- - Set `akm.enabled: false` and sync to disable a binding.
168
- - Delete the `.yml` source and sync to remove its derived binding.
389
+ - Disable a binding by editing the source and syncing: set that schedule
390
+ entry's own `enabled: false`.
391
+ - Delete the `.yml` source and sync to remove its derived binding(s).
169
392
  - Use `akm task sync --rebind` only when deliberately changing the captured
170
393
  AKM runtime, then verify with `akm task doctor`.
171
394
 
@@ -174,6 +397,46 @@ identity and AKM fences stale attempts, but an ambiguous process crash can be
174
397
  observed only after the external work has started. Make scheduled side effects
175
398
  idempotent where possible.
176
399
 
400
+ ## Task v3 (retired): grammar reference for migration
401
+
402
+ Nothing in this section is accepted by `src/` in this release — it exists
403
+ only so you can read an already-authored `version: 3` file while deciding
404
+ how to migrate it. The v3 grammar used an `akm:` options bag, an `on:`
405
+ trigger block, and exactly one required scheduling source:
406
+
407
+ ```yaml
408
+ version: 3
409
+ name: Nightly review
410
+ uses: workflows/nightly-review
411
+ with:
412
+ strict: true
413
+ akm:
414
+ schedule: "0 4 * * *"
415
+ enabled: true
416
+ timeout: 30m
417
+ ```
418
+
419
+ or, with the GitHub-shaped local trigger subset:
420
+
421
+ ```yaml
422
+ version: 3
423
+ uses: commands/review
424
+ on:
425
+ schedule:
426
+ - cron: "0 6 * * *"
427
+ workflow_dispatch: {}
428
+ ```
429
+
430
+ `with:` on any `uses:` target carried v3's untyped params bag (workflow
431
+ refs consumed it as run params; command/script refs rejected it outright).
432
+ A GitHub Action locator (`owner/repo[/path]@ref`) was a recognized `uses:`
433
+ shape that was always rejected before dispatch — remote action acquisition
434
+ was never implemented in any akm release. `akm.enabled: false` disabled the
435
+ whole document, not a specific schedule binding.
436
+
437
+ See [Migrating to task source v4](#migrating-to-task-source-v4) above to
438
+ convert a file out of this grammar.
439
+
177
440
  ## See also
178
441
 
179
442
  - [CLI Reference: task](cli.md#task)