akm-cli 0.9.30 → 0.9.31

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 (161) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +10 -10
  3. package/ROADMAP.md +112 -0
  4. package/dist/commands/improve/improve-cli.js +33 -12
  5. package/dist/core/file-lock.js +10 -1
  6. package/dist/llm/client.js +33 -3
  7. package/dist/scripts/akm-migrate-node.js +5 -1
  8. package/dist/scripts/akm-migrate.js +5 -1
  9. package/docs/README.md +42 -41
  10. package/docs/agents/README.md +15 -0
  11. package/docs/agents/agent-install.md +14 -0
  12. package/docs/architecture/README.md +67 -0
  13. package/docs/architecture/adapters.md +272 -0
  14. package/docs/architecture/akm-architecture-decision-history.md +2055 -0
  15. package/docs/architecture/akm-core-principles.md +126 -0
  16. package/docs/architecture/architecture.md +579 -0
  17. package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +550 -0
  18. package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +72 -0
  19. package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +142 -0
  20. package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +189 -0
  21. package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +97 -0
  22. package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +108 -0
  23. package/docs/architecture/decisions/0006-task-source-version-routing.md +124 -0
  24. package/docs/architecture/decisions/0007-workflow-composition-bounds.md +83 -0
  25. package/docs/architecture/decisions/0008-task-binding-normalization.md +88 -0
  26. package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +80 -0
  27. package/docs/architecture/decisions/0010-driver-protocol-cut.md +36 -0
  28. package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +125 -0
  29. package/docs/architecture/decisions/README.md +62 -0
  30. package/docs/architecture/improvement.md +440 -0
  31. package/docs/architecture/internals/classification.md +154 -0
  32. package/docs/architecture/internals/fresh-host-rebuild-runbook.md +40 -0
  33. package/docs/architecture/internals/functional-contract-patterns.md +340 -0
  34. package/docs/architecture/internals/health-advisories.md +110 -0
  35. package/docs/architecture/internals/improve-workflow.md +713 -0
  36. package/docs/architecture/internals/indexing.md +498 -0
  37. package/docs/architecture/internals/registry-network-boundary.md +57 -0
  38. package/docs/architecture/internals/search.md +249 -0
  39. package/docs/architecture/internals/storage-locations.md +943 -0
  40. package/docs/architecture/persisted-data-compat.md +59 -0
  41. package/docs/architecture/reviews/env-secret-access.md +319 -0
  42. package/docs/architecture/runtime-boundary-design.md +153 -0
  43. package/docs/architecture/specs/0.9.0-close-out-plan.md +361 -0
  44. package/docs/architecture/specs/0.9.0-decisions.md +528 -0
  45. package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +745 -0
  46. package/docs/architecture/specs/0.9.0-open-items-register.md +135 -0
  47. package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +740 -0
  48. package/docs/architecture/specs/0.9.0-release-surface-review.md +636 -0
  49. package/docs/architecture/specs/agent-command-engine-model-design.md +513 -0
  50. package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +501 -0
  51. package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +291 -0
  52. package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +2059 -0
  53. package/docs/architecture/specs/di-seams-plan.md +539 -0
  54. package/docs/architecture/specs/driver-protocol-keep-or-cut.md +275 -0
  55. package/docs/architecture/specs/fact-asset-type.md +142 -0
  56. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +634 -0
  57. package/docs/architecture/specs/okf-support.md +148 -0
  58. package/docs/architecture/specs/ref.md +329 -0
  59. package/docs/architecture/specs/reviews/task-workflow-unification/README.md +72 -0
  60. package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +152 -0
  61. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +352 -0
  62. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +300 -0
  63. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +402 -0
  64. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +758 -0
  65. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +645 -0
  66. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +602 -0
  67. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +27 -0
  68. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +27 -0
  69. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +74 -0
  70. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +15 -0
  71. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +132 -0
  72. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +147 -0
  73. package/docs/architecture/specs/stash-conventions-code-spec.md +275 -0
  74. package/docs/architecture/specs/stash-organization-conventions.md +377 -0
  75. package/docs/architecture/specs/task-workflow-format-unification.md +721 -0
  76. package/docs/architecture/specs/workflow-engine-buy-vs-build.md +231 -0
  77. package/docs/architecture/specs/workflow-format-unification.md +437 -0
  78. package/docs/architecture/testing/manual-testing-checklist.md +3420 -0
  79. package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +924 -0
  80. package/docs/architecture/testing/task-workflow-manual-tests.md +1817 -0
  81. package/docs/architecture/testing/testing-workflow.md +446 -0
  82. package/docs/architecture/workflow-engine.md +274 -0
  83. package/docs/guides/README.md +33 -0
  84. package/docs/guides/author-bundles.md +310 -0
  85. package/docs/guides/author-workflows.md +520 -0
  86. package/docs/guides/bundles.md +321 -0
  87. package/docs/guides/capture-knowledge.md +136 -0
  88. package/docs/guides/claude-code-vs-akm-workflows.md +30 -0
  89. package/docs/guides/concepts.md +93 -0
  90. package/docs/guides/discover-and-load.md +158 -0
  91. package/docs/guides/getting-started.md +240 -0
  92. package/docs/guides/improve-the-library.md +246 -0
  93. package/docs/guides/knowledge-management.md +18 -0
  94. package/docs/guides/recipes/headless-install.md +97 -0
  95. package/docs/guides/recipes/website-source.md +28 -0
  96. package/docs/guides/run-workflows.md +279 -0
  97. package/docs/guides/scheduling.md +123 -0
  98. package/docs/guides/use-with-any-agent.md +129 -0
  99. package/docs/guides/wikis.md +81 -0
  100. package/docs/maintainers/README.md +19 -0
  101. package/docs/maintainers/curate-workmap.md +336 -0
  102. package/docs/maintainers/eval.md +3 -0
  103. package/docs/maintainers/local-development.md +108 -0
  104. package/docs/maintainers/release-checklist.md +103 -0
  105. package/docs/migration/README.md +2 -2
  106. package/docs/migration/release-notes/0.0.13.md +1 -1
  107. package/docs/migration/release-notes/0.1.0.md +1 -1
  108. package/docs/migration/release-notes/0.2.0.md +1 -1
  109. package/docs/migration/release-notes/0.3.0.md +1 -1
  110. package/docs/migration/release-notes/0.5.0.md +1 -1
  111. package/docs/migration/release-notes/0.6.0.md +1 -1
  112. package/docs/migration/release-notes/0.7.0.md +1 -1
  113. package/docs/migration/release-notes/0.7.3.md +2 -2
  114. package/docs/migration/release-notes/0.7.4.md +1 -1
  115. package/docs/migration/release-notes/0.7.5.md +1 -1
  116. package/docs/migration/release-notes/0.8.0.md +1 -1
  117. package/docs/migration/release-notes/0.9.0.md +1 -1
  118. package/docs/migration/release-notes/0.9.14.md +1 -1
  119. package/docs/migration/release-notes/0.9.15.md +1 -1
  120. package/docs/migration/release-notes/0.9.16.md +1 -1
  121. package/docs/migration/release-notes/0.9.17.md +1 -1
  122. package/docs/migration/release-notes/0.9.19.md +1 -1
  123. package/docs/migration/release-notes/0.9.2.md +1 -1
  124. package/docs/migration/release-notes/README.md +27 -31
  125. package/docs/migration/v0.5-to-v0.6.md +759 -0
  126. package/docs/migration/v0.8-to-v0.9.md +1 -1
  127. package/docs/plans/0.9.2-agent-command-workflow-plan.md +423 -0
  128. package/docs/posts/README.md +30 -0
  129. package/docs/posts/akm-command-tour.md +495 -0
  130. package/docs/posts/akm-logo-sized.webp +0 -0
  131. package/docs/posts/belief-aware-memory-12.md +139 -0
  132. package/docs/posts/config-v2-lessons-16.md +191 -0
  133. package/docs/posts/improve-loop-autonomous-10.md +225 -0
  134. package/docs/posts/improve-pipeline-debugging-0803.md +179 -0
  135. package/docs/posts/intro-part-01.md +76 -0
  136. package/docs/posts/intro-part-02.md +221 -0
  137. package/docs/posts/intro-part-03.md +190 -0
  138. package/docs/posts/intro-part-04.md +221 -0
  139. package/docs/posts/llm-mode-reflect-13.md +166 -0
  140. package/docs/posts/openpalm-built-on-akm.md +86 -0
  141. package/docs/posts/progressive-disclosure-06.md +129 -0
  142. package/docs/posts/proposal-safety-net-15.md +112 -0
  143. package/docs/posts/release-0.5.0.md +247 -0
  144. package/docs/posts/release-0.6.0.md +117 -0
  145. package/docs/posts/release-0.7.0.md +159 -0
  146. package/docs/posts/release-0.8.0.md +332 -0
  147. package/docs/posts/scattered-skills-05.md +100 -0
  148. package/docs/posts/task-assets-persistent-workflows-11.md +222 -0
  149. package/docs/posts/team-skills-07.md +198 -0
  150. package/docs/posts/wiki-agent-knowledge-08.md +223 -0
  151. package/docs/posts/workflows-vaults-09.md +321 -0
  152. package/docs/product-surface.md +54 -0
  153. package/docs/reference/README.md +1 -2
  154. package/docs/reference/asset-types.md +168 -0
  155. package/docs/reference/cli.md +5 -6
  156. package/docs/reference/env-and-secrets.md +126 -0
  157. package/docs/reference/memory.md +124 -0
  158. package/docs/reference/refs.md +156 -0
  159. package/docs/reference/registry.md +489 -0
  160. package/docs/reference/website-sources.md +141 -0
  161. package/package.json +12 -15
@@ -0,0 +1,721 @@
1
+ # Task / Workflow Unification: One Target Vocabulary, One Prose Rule
2
+
3
+ Status: PROPOSAL v9 — v8 (the post-Opus-review redesign) revised against a
4
+ four-lens Sonnet panel, then re-verified claim-by-claim against the current
5
+ baseline (98 claims checked, 22 corrected; a further 7 corrections from an
6
+ audit of that pass). Review corpus:
7
+ [`reviews/task-workflow-unification/`](./reviews/task-workflow-unification/).
8
+ Baselined on `origin/main` @ `17a0dca`, which merged the 0.9 polish branch
9
+ (`71bb686`). Breaking changes are approved for 0.9.0.
10
+ Date: 2026-08-01
11
+ Related: [`workflow-format-unification.md`](./workflow-format-unification.md),
12
+ [`okf-support.md`](./okf-support.md),
13
+ [`docs/reference/workflows.md`](../../reference/workflows.md)
14
+
15
+ > **2026-08-18 owner clarification:**
16
+ > [Agent, Command, Engine, and Model Resolution](./agent-command-engine-model-design.md)
17
+ > is authoritative wherever this proposal discusses agent personas, command
18
+ > execution, command placeholders, engine/model cascading, tool policy,
19
+ > capability handling, or model aliases. In particular, this proposal's
20
+ > `with:`/named/positional command-template grammar, primary-bundle tool-policy
21
+ > ceiling, static engine-capability declarations, and built-in wildcard alias
22
+ > recommendations are superseded. The owner subsequently settled the 0.9.2
23
+ > source-format direction in the
24
+ > [0.9.2 implementation plan](../../plans/0.9.2-agent-command-workflow-plan.md):
25
+ > task v3 is GitHub-step-shaped, AKM Markdown and GitHub-shaped YAML are peer
26
+ > workflow formats, and both compile through one internal versioned IR. The
27
+ > concrete schemas and examples below are therefore non-normative. The
28
+ > still-compatible concepts — tasks as scheduling wrappers, agents as
29
+ > selectors rather than targets, task composition in workflow steps, live task
30
+ > resolution, and frozen workflow resolution — remain design input.
31
+
32
+ ---
33
+
34
+ ## 1. Grounding — what tasks and workflows are in akm
35
+
36
+ Owner's model; everything below derives from it.
37
+
38
+ 1. **A task is a bundle asset that abstracts over OS-scheduled work** —
39
+ discovered like any asset, *enabled* into a cron/launchd/schtasks entry
40
+ that executes the defined work or dispatches an agent with the task's
41
+ prompt. A platform-agnostic way to share repeatable processes behind one
42
+ CLI.
43
+ 2. **A workflow step is a task** — defined inline or referenced by ref — so
44
+ the same repeatable process is composable without duplicating content or
45
+ config.
46
+ 3. **Fewer concepts, lower cognitive load.** akm is a simple, intuitive
47
+ abstraction layer over the tools and processes autonomous agents use.
48
+
49
+ Not in scope: tasks do not grow `steps:`; workflows do not grow `schedule:`.
50
+ The unit of sharing is the asset, of scheduling the task, of procedure the
51
+ workflow.
52
+
53
+ ## 2. The format (stable since v5–v6, corrections applied)
54
+
55
+ ### 2.1 Targets
56
+
57
+ | Declaration | Work performed |
58
+ |---|---|
59
+ | *(none)* | Agent, prompted with **the nearest prose** — a task's body, or a step's `## <id>` section |
60
+ | `uses: <asset-ref>` | Execute the referenced asset per its subdir-declared type (§2.2) |
61
+ | `run: <shell text>` | Shell, no AI — GitHub-Actions semantics; `sh` on POSIX, `powershell` on Windows, `shell:` override |
62
+
63
+ `uses:` xor `run:` — one schema rule; the double-target error class is
64
+ structurally impossible. No ref-vs-inline sniffing exists.
65
+
66
+ > **The prose rule.** The machine surface names the target; the nearest
67
+ > prose is the instructions. With no target key, the prose *is* the work.
68
+
69
+ ### 2.2 `uses:` — a closed set of four executable types
70
+
71
+ | Ref | Execution | Inputs |
72
+ |---|---|---|
73
+ | `uses: commands/<n>` | Fill the template (§2.4), dispatch an agent | `with:` |
74
+ | `uses: scripts/<n>` | Execute per the script's `run`/`setup`/`cwd` — gated by the execution-activation policy (§5.6) | `env:` |
75
+ | `uses: tasks/<n>` *(steps only)* | Compose the task as this step's work (§2.3) | the task's own, overridable |
76
+ | `uses: workflows/<r>` *(tasks only)* | `runWorkflowSteps()` | `with:` → declared param flags |
77
+
78
+ Any other subdir (including `agents/` — a persona, not work) is an error
79
+ with a targeted hint. **`with:` replaces v5–v7's call-site `params:`** —
80
+ review finding M1 (3/3): `params:` already means *declarations* (name →
81
+ JSON Schema) in workflow frontmatter, and one key carrying declarations,
82
+ run-arguments, placeholder fills, *and* a cascading value was the same
83
+ overload this spec deletes `prompt:` for. GHA's `inputs:`/`with:` split
84
+ exists precisely here, and §2.4/§4 give `with:` exactly one meaning:
85
+ **inputs handed to the referenced asset, never cascaded.**
86
+
87
+ Two `uses:` modes differ in kind, named for authors: `tasks/<n>`
88
+ **composes** — the referenced definition becomes this step's own work —
89
+ while `workflows/<r>` **invokes** — a child run executes and returns.
90
+ `with:` merge on a composition chain (a step referencing a task that
91
+ itself targets a command or workflow) is per-key shallow merge, referencing
92
+ step wins; `with.arguments` is one key, replaced whole. The merged mapping
93
+ feeds the final target: placeholder fill for a command, declared param
94
+ flags for a workflow.
95
+
96
+ ### 2.3 Steps are tasks — composition by reference
97
+
98
+ ```yaml
99
+ steps:
100
+ - id: lint
101
+ uses: tasks/lint-check # the task's target, fields, env, and body
102
+ timeout: 2m # call-site override (one cascade layer nearer)
103
+ - id: fix
104
+ run: bun run fix # inline task: same keys, defined here
105
+ ```
106
+
107
+ - Step keys override the referenced task's keys — the task and the step are
108
+ adjacent cascade layers (§4); `env:` concatenates task-then-step.
109
+ - Trigger keys (`schedule`, `enabled`) are consumed **only** by
110
+ `akm task sync` and, at fire time, the task runner's enabled gate
111
+ (`src/tasks/runner.ts:169` — v7's "sync-only" wording corrected).
112
+ Anywhere else they are no-ops with a lint notice; a referenced task
113
+ cannot double-fire.
114
+ - **Call-site prose is appended at freeze, not at dispatch.** Review
115
+ finding (3/3): there is no "one assembled prompt seam" — prompts are
116
+ built per-unit at dispatch, and the unit hash covers the *frozen
117
+ template*, not the assembled string. So: when the resolved work is
118
+ agent-dispatched, the step's section text is concatenated onto the
119
+ frozen instruction template (blank-line separator, byte-exact) **at
120
+ freeze**, which puts it inside the hash preimage automatically and keeps
121
+ the append ahead of the item/inputs/gate blocks. For shell work the
122
+ section is documentation, ignored at runtime.
123
+ - Refs resolve at freeze (§5.4), so in-flight runs are immune to edits.
124
+ - No nesting: a referenced task targeting `workflows/*` is a compile error
125
+ on a step; a task referencing a task is an error.
126
+
127
+ ### 2.4 Command templates — filled against the real placeholder grammar
128
+
129
+ Review finding M2 (3/3): command placeholders are `$ARGUMENTS` / `$1`–`$9`
130
+ (positional) and `{{name}}` per the advertised grammar
131
+ (`extractParameters`, `src/output/renderers.ts:164-186`); the actual
132
+ filler is `fillPlaceholders()` in
133
+ `src/commands/agent/agent-dispatch.ts:67-72`, which substitutes only
134
+ positional `{{0}}` forms, leniently — a live bug fixed by this work, and
135
+ a second call site the new `with:` contract replaces. Three further
136
+ grammars for the same placeholders exist today and diverge from each
137
+ other: the indexer's recognition sniff `COMMAND_PLACEHOLDER_RE`
138
+ (`src/indexer/walk/matchers.ts:126`, consumed at `:239`) matching only
139
+ `$ARGUMENTS`/`$1`–`$3`; `extractCommandParameters`
140
+ (`src/indexer/passes/metadata.ts:440-461`), a near-clone of the display
141
+ grammar that differs from it in case-sensitivity and digit bounding; and
142
+ a lenient sniff at
143
+ `src/core/adapter/adapters/tool-dir-shared.ts:201-204`.
144
+
145
+ **Convergence is scoped to the fill and display grammars — the two
146
+ recognition sniffs keep their `$`-only forms.** Adding `{{name}}` to
147
+ `COMMAND_PLACEHOLDER_RE` would be a live mis-classification hazard, not a
148
+ cleanup: it returns specificity 18, outranking the directory rules
149
+ (10/15), so any `knowledge/`, `facts/`, or `instructions/` `.md`
150
+ containing a mustache token would be re-typed `command`. The recognition
151
+ gap is narrower than it looks anyway — `classifyByDirectory` /
152
+ `classifyByParentDirHint` (`matchers.ts:43-47`, `:147-156`, `:178-197`)
153
+ already type any `.md` under `commands/` as a command at specificity
154
+ 10/15, beating `classifyBySmartMd`'s `knowledge` (5). The sniff is only
155
+ the fallback for command-shaped `.md` living *outside* `commands/`
156
+ without `tools:`/`agent:` frontmatter. The contract, defined against that
157
+ reality:
158
+
159
+ - `with:` mapping keys fill `{{name}}` placeholders.
160
+ - The reserved key `with.arguments` (string) fills `$ARGUMENTS`, and its
161
+ whitespace-split words fill `$1`–`$9`.
162
+ - An unmatched placeholder or unused `with:` key is a **lint warning and is
163
+ left verbatim** — not a runtime hard error, so imported `$ARGUMENTS`
164
+ commands remain usable as targets.
165
+ - `with.arguments` is reserved: a literal `{{arguments}}` placeholder is
166
+ filled by it too, with a lint warning about the shadowing. Words past
167
+ `$9` remain reachable only through `$ARGUMENTS`.
168
+
169
+ Filling happens at freeze (workflows) / dispatch (tasks), producing the
170
+ prompt string. Bodies remain verbatim — templating stays scoped to the
171
+ command asset type, whose definition is "a template with placeholders."
172
+
173
+ ## 3. The task asset
174
+
175
+ `<bundle>/tasks/<id>.md`: the shared envelope (`$ref
176
+ akm-asset-envelope.json`, OKF v0.2 families included), trigger keys, at
177
+ most one target, and any §4 fields. No `version:` key. **Recognition
178
+ requires frontmatter `type: task`, honored in two subsystems** (R2
179
+ finding: v8 cited only one). At the bundle-adapter layer, the workflow
180
+ adapter is ordered ahead of the task and generic akm adapters in the
181
+ source-root probe list (6th of 11 —
182
+ `src/core/adapter/adapters/index.ts:73-90`; that array is `looksLikeRoot`
183
+ probe order, and only the adapter that claims a root ever calls
184
+ `recognize()` on its files), and inside an akm-workflow bundle it claims
185
+ every `.md` file whose frontmatter does not declare a contrary `type:`
186
+ (`akm-workflow-adapter.ts:67-70`, `:160`). At the per-file
187
+ indexer classifier — the path that actually types `tasks/*.md` during
188
+ normal indexing — `src/indexer/walk/matchers.ts` gains a `type: task`
189
+ branch **ordered before** its existing `"agent" in fm → command` rule
190
+ (`matchers.ts:234-236`), which would otherwise misclassify any task
191
+ carrying an `agent:` selector — including this section's own example.
192
+ Residence is a lint *expectation*, not a recognition signal.
193
+
194
+ ````markdown
195
+ ---
196
+ type: task
197
+ description: Weekly review digest.
198
+ schedule: "0 8 * * 1"
199
+ agent: agents/reviewer
200
+ timeout: 10m
201
+ ---
202
+
203
+ Review the week's completed tasks and summarize action items.
204
+ ````
205
+
206
+ ````markdown
207
+ ---
208
+ type: task
209
+ description: Full nightly quality sweep.
210
+ schedule: "15 2 * * *"
211
+ run: akm improve --strategy thorough --skip-if-locked
212
+ ---
213
+
214
+ # Nightly improve sweep
215
+
216
+ Runbook prose: indexed, shown, never executed.
217
+ ````
218
+
219
+ ````markdown
220
+ ---
221
+ type: task
222
+ schedule: "@daily"
223
+ uses: commands/weekly-review
224
+ with: { scope: team }
225
+ env: [env/prod]
226
+ ---
227
+ ````
228
+
229
+ Lifecycle unchanged: discover via search/show; enable via `enabled:` +
230
+ `task sync`; the OS entry still invokes `akm task run <id>`. Lifecycle
231
+ interactions pinned (review minors): `status: draft` → `sync` never
232
+ installs, regardless of `enabled:`; `status: deprecated` → installs with a
233
+ warning; a previously-installed task that becomes `draft` (or
234
+ `enabled: false`) is uninstalled by the next `sync` — reconciliation is to
235
+ desired state, both directions.
236
+
237
+ Two adapter-policy changes with named mechanisms (panel M13 follow-up):
238
+ the akm adapter's current `type: "task"` special-case — parse as pure
239
+ YAML, `frontmatter: null`, so markdown base checks never fire
240
+ (`akm-adapter.ts:404-412`) — is **removed with the format**, and markdown
241
+ tasks get the full markdown base-check suite; and tasks are declared
242
+ **improve-ineligible**. No such site exists on `BundleAdapter`
243
+ (`src/core/adapter/bundle-adapter.ts:69-121` declares only adapter-level
244
+ optional methods), so v8's "where the adapter already declares per-type
245
+ capabilities" was wrong. Three candidate homes, cheapest first: the
246
+ existing per-type refusal set `DISTILL_REFUSED_INPUT_TYPES`
247
+ (`src/commands/improve/distill.ts:134-142`, already gated at
248
+ `eligibility.ts:380` and documented as driving the planner "for free")
249
+ gains `task`; or the per-type table `TYPE_PRESENTATION`
250
+ (`src/core/type-presentation.ts:74`) gains an eligibility flag; or
251
+ `eligibility.ts` gains an explicit type filter. A task body is an
252
+ executable prompt,
253
+ not curatable knowledge. Lint runs; improve never rewrites it.
254
+
255
+ ## 4. Configuration: two selectors, one value vocabulary, one cascade — built, not "exposed"
256
+
257
+ v7 claimed freeze "already implements" the cascade. Review finding C4
258
+ (3/3): freeze's layer list is exactly `[documentDefaults, unit]`
259
+ (`freeze.ts:50`); `DefaultsSchema` has **no** `model` field and is
260
+ `.passthrough()`, so v7's own worked example is a silent no-op today
261
+ (`config-schema.ts:102-108`); `defaults.llm` is hard-rejected as retired;
262
+ no persona layer exists. What exists is a two-layer resolver whose *shape*
263
+ proves the pattern fits. This section specifies **building** the rest.
264
+
265
+ **Selectors** (nearest wins; each picks a node whose fields join the
266
+ cascade):
267
+
268
+ | Selector | Node | Source |
269
+ |---|---|---|
270
+ | `engine:` | execution node | config `engines.<name>` |
271
+ | `agent:` | persona node | bundle `agents/<name>` |
272
+
273
+ **Value fields** — legal at every layer, merged per-field, nearest wins;
274
+ `env:` concatenates: `model` · `temperature` · `max_tokens` ·
275
+ `extra_params` · `timeout` · `env` · `cwd` · `shell` · `on_error` · `retry`.
276
+
277
+ (`with:` is *not* a value field — it binds to one referenced asset. `params`
278
+ no longer exists as a field name outside workflow declarations. `on_error`/
279
+ `retry` join the vocabulary because `defaults.on_error` already exists at
280
+ document level today — review M12 — making "graph keys are steps-only"
281
+ false for them; they remain meaningless on a task and lint says so. Value
282
+ fields other than `timeout`/`env` on a `uses: workflows/*` task draw the
283
+ same inapplicable-field notice — they configure a unit, and a workflow
284
+ invocation has none.)
285
+
286
+ **Merge classes, stated once** (panel finding: a generic "nearest wins"
287
+ would silently downgrade the existing deep-merge): **scalars** (`model`,
288
+ `temperature`, `max_tokens`, `timeout`, `cwd`, `shell`, `on_error`) —
289
+ nearest wins whole; **mappings** (`extra_params`) — deep-merged along the
290
+ chain, preserving today's `deepMergeConfig` behavior
291
+ (`freeze.ts:211-216`); **lists** (`env`) — concatenated, later wins;
292
+ **`retry`** — replaced whole (half-merging `max`/`on` would be
293
+ incoherent). `with:` merges per-key at its target (§2.2), outside the
294
+ cascade.
295
+
296
+ **Layers, far → near:**
297
+
298
+ ```
299
+ config defaults: → engines.<selected> → agents/<selected> → document defaults: → uses: tasks/<ref> → step/task keys
300
+ ```
301
+
302
+ (`document defaults:` is the workflow frontmatter's `defaults:` block and
303
+ exists only there — a standalone task IS its own call site, so for tasks
304
+ that layer is simply absent, not an implied new task key.)
305
+
306
+ **What must be built (the honest inventory):**
307
+
308
+ 1. `DefaultsSchema` gains the value fields, and stops silently swallowing
309
+ unknown keys (strict with migration-safe notices).
310
+ 2. A **persona snapshot**: the agent asset resolved through the
311
+ provenance ceiling — 07 P1-D, today inline in the show command
312
+ (`src/commands/read/show.ts:433-445`): self-declared `tools:` honored
313
+ ONLY for the operator's **primary bundle**, keyed off primary-bundle
314
+ identity, explicitly *not* the writable bit, failing closed. That
315
+ check is **extracted into a shared persona resolver** consumed by both
316
+ `show` and freeze — a named refactor in §9, since its current home is
317
+ a CLI formatter. The snapshot `{systemPrompt, toolPolicy, model,
318
+ …valueFields}` freezes into the plan; `toolPolicy` is consumed by
319
+ agent-kind engines and draws the standard unconsumed-field notice on
320
+ LLM engines. (This also fixes the live bug where `prompt: agents/x`
321
+ ships raw file bytes *including frontmatter* to the model —
322
+ `runner.ts:592-593`.)
323
+ 3. One cascade module — a new shared module (e.g. `src/core/cascade.ts`;
324
+ there is no `src/exec/` tree today, only `src/workflows/exec/` and
325
+ `src/tasks/`) — the only implementation of layer merge, consumed at
326
+ freeze (workflows) and dispatch (tasks). It
327
+ consolidates the three engine/model resolution sites that exist today
328
+ (`freeze.ts:163-209`, `tasks/runner.ts:479-514`, engine-resolution)
329
+ including their subtly divergent opencode-sdk `llmEngine` fallback
330
+ rules — one implementation, one fallback rule.
331
+ 4. **Capability notices replace both kind-gates.** The task path's hard
332
+ error and freeze's guard — which review M6 showed is *dead code*
333
+ (`freeze.ts:67-73` computes `llm` only for llm engines, then guards
334
+ `kind !== "llm"`), meaning workflows already silently drop these fields
335
+ — are both replaced by one behavior: engines declare the fields they
336
+ consume; an unconsumed field is a lint/freeze **notice**. Strictness
337
+ stays only where the kind is known at authoring time: the engine node's
338
+ own schema (which today is `.passthrough()` + blacklist; it becomes
339
+ genuinely strict as part of this work — review minor).
340
+ 5. Aliases: resolution runs once, after the cascade settles `model`,
341
+ through the existing `resolveModel()` chain. Review M4 (3/3): the
342
+ builtin table has only `claude`/`opencode` columns, so portability to
343
+ LLM endpoints is currently *false* — the builtin entries gain a `"*"`
344
+ column, and an alias that resolves nowhere for the selected platform is
345
+ a freeze/lint notice, not silent pass-through.
346
+ 6. The gate judge (`workflow.judgeEngine`) stays outside the cascade in
347
+ 0.9.0 — frozen separately, as shipped. Noted, not changed.
348
+
349
+ One sentence to teach: *set a field where it should usually apply;
350
+ override it closer when a case differs; the nearest value wins.*
351
+
352
+ ## 5. Execution architecture
353
+
354
+ ### 5.1 One target model, two executors
355
+
356
+ A shared target module resolves every declaration to a typed value:
357
+
358
+ ```
359
+ Target = { kind: agent-prose } # nearest prose is the prompt
360
+ | { kind: command, ref, with } # template fill → agent prompt
361
+ | { kind: script, ref } # script asset, exec
362
+ | { kind: shell, text, shell } # inline run:
363
+ | { kind: workflow, ref, with } # tasks only
364
+ | { kind: task, ref } # steps only; resolves recursively once
365
+ ```
366
+
367
+ Execution is a strategy seam with exactly two implementations:
368
+
369
+ - **AgentUnitExecutor** — today's paths (task runner's `executeRunner()`;
370
+ the orchestrator's journaled `UnitDispatcher`), consuming an assembled
371
+ prompt + frozen engine + persona snapshot.
372
+ - **ShellUnitExecutor** — `Bun.spawn()` for `run:` text and script assets,
373
+ used by both the task runner and the orchestrator.
374
+
375
+ Staging is symmetric and named (panel: the task path's staging was
376
+ unstated): **tasks** run *resolve → execute* — the same resolve stage
377
+ (cascade, persona, targets, templates) with no plan persistence;
378
+ **workflows** run *compile → resolve → freeze → execute* (§5.4). Both
379
+ executors sit behind one interface; each surface wraps results into its
380
+ own recording sink (`task_history`/`logs.db` vs the run journal) — the
381
+ adapter lives at the sink, not inside the executor, which is how the
382
+ `RunnerSpec`-vs-`UnitDispatchRequest` split stays out of the executors'
383
+ type signatures: the resolve stage produces one dispatch plan both
384
+ consume. **ShellUnitExecutor is extracted from the task runner's existing
385
+ hardened command path** (`runManagedSubprocess`, `src/core/subprocess.ts`,
386
+ called at `tasks/runner.ts:277-289`: process-group spawn, SIGTERM→SIGKILL
387
+ kill ladder, injectable spawn/timer seams, `AKM_EVENT_SOURCE` stamping)
388
+ and adopted by the orchestrator — not a new spawn wrapper.
389
+ (`src/tasks/backends/exec-utils.ts` is the scheduler-backend exec seam,
390
+ not part of this path.) Composition is monotemporal by rule: a referenced
391
+ task's fields join the cascade from the copy resolved at freeze, under the
392
+ workflow's config snapshot — a composed task never re-reads config at
393
+ dispatch.
394
+
395
+ Run recording stays split (cron job vs journaled plan) — that boundary is
396
+ real. Everything upstream unifies: target resolution, template filling,
397
+ cascade, alias resolution, env assembly.
398
+
399
+ ### 5.2 Shell units in the IR — v3 → v4, not a non-goal
400
+
401
+ Review C2 (3/3): `IrInvocation.engine` and `UnitDispatchRequest.engine`
402
+ are required, the engine snapshot union is closed, freeze hard-errors with
403
+ no engine, and the IR rejects empty instructions — v7's "no IR changes"
404
+ was false. Owned properly:
405
+
406
+ - `IrInvocation` becomes a discriminated union:
407
+ `{ kind: "agent", engine, … }` | `{ kind: "shell", script, shell, cwd,
408
+ timeoutMs }` (`timeout` is a value field for `run:`, so the shell member
409
+ carries it). Shell members exclude engine/llm fields **structurally** —
410
+ by union-member shape, not by decoder-validated absence.
411
+ - Engine resolution happens **per unit kind**: shell units need no engine,
412
+ so a shell-only workflow freezes on an engine-less machine (the current
413
+ "no engine selected" error narrows to plans containing agent units).
414
+ - Instructions become optional for shell units (parser + IR relaxation —
415
+ review M10; agent units keep the non-empty invariant).
416
+ - Shell units journal as normal `workflow_run_units` rows (status, timing,
417
+ attempts, `failure_reason`; no tokens). Under the external driver
418
+ protocol, shell units are **orchestrator-owned**: `brief` lists them as
419
+ non-claimable and the engine executes them natively — a harness never
420
+ claims shell work.
421
+ - Crash/restart: shell units use the same claim/lease rows as agent
422
+ units; a running shell unit whose lease expires re-dispatches on resume
423
+ under its retry policy. Re-execution idempotency is the author's
424
+ contract — the same contract every cron job already carries — stated in
425
+ the docs, not solvable by the engine.
426
+ - Plan IR version bumps to 4; decoders reject v4 plans in older binaries
427
+ (existing plan-version machinery).
428
+
429
+ ### 5.3 Unit identity — hashVersion 5, preimage stated
430
+
431
+ Review C3 (3/3): hashVersion 4's preimage (`step-work.ts:333-392`) covers
432
+ the frozen template bytes but none of the *other* new inputs — shell text,
433
+ the `uses:` target kind/ref/content hash, and the persona snapshot.
434
+ Without a bump, editing `run:` text, re-pointing a `uses:` ref, or editing
435
+ `agents/<n>` would silently reuse completed journal rows. (Freeze-time
436
+ prose appending, §2.3, already rides in via `template`.) hashVersion 5's
437
+ preimage, explicitly:
438
+
439
+ | Field | Notes |
440
+ |---|---|
441
+ | template instructions | **post** freeze-time prose append (§2.3) and **post** template fill, so `with:` values are covered via the filled bytes |
442
+ | target kind + `uses:` ref + resolved content hash | a re-pointed or edited referenced asset re-dispatches; also the retained provenance for composed steps (the "single-file provenance" minor). Script bytes are **embedded at resolve**, like a command's filled text — execution never re-reads live files, keeping composition monotemporal (§5.1) |
443
+ | persona snapshot hash | system prompt, tool policy, and value fields of the frozen persona — editing `agents/<n>` re-dispatches (panel critical: omitted in v8) |
444
+ | shell text, `shell`, `cwd` | shell units |
445
+ | item / inputs / params / dispatch / invocation / schema | as v4 |
446
+ | env **names** + env **literal values** | see §5.5 — literals are plan content; ref-sourced values stay names-only |
447
+ | isolation, gateFeedback | as v4 |
448
+
449
+ `retry`/`on_error` stay excluded (policy, not input) — unchanged rationale.
450
+
451
+ ### 5.4 Freeze becomes two stages; lint gets a dry freeze
452
+
453
+ Review M11: `uses:` resolution needs asset IO inside a function documented
454
+ pure, and freeze currently has exactly one caller (run start), so every
455
+ composition error would escape lint. Restructure: **compile** (pure) →
456
+ **resolve** (asset loader injected: personas, referenced tasks, command
457
+ templates) → **freeze** (snapshot + hash). `akm lint --type workflows`
458
+ runs compile+resolve with the real loader and no persistence, so dangling
459
+ `uses:` refs, back-door workflow nesting, placeholder mismatches, and
460
+ capability notices all surface at lint time. Composed instructions carry
461
+ the existing 256 KiB cap with a lint warning at 80%.
462
+
463
+ ### 5.5 `env:` — one shape, two provenance classes
464
+
465
+ Format unchanged from v6 (list of env-asset refs and literal mappings,
466
+ later wins, bare-mapping shorthand). Semantics corrected by review M3
467
+ (3/3), which showed "strictly additive" was false at the IR/hash/redaction
468
+ layers. The clean line is **provenance, not shape**:
469
+
470
+ - **Literal entries** are plan content: author-written bytes already
471
+ durable in the source file — frozen into the plan, hashed (§5.3), shown
472
+ by `brief`, **never redacted** (`LOG_LEVEL: debug` must not scrub
473
+ "debug" from every log — the over-redaction finding).
474
+ - **Ref-sourced entries** (`env/<n>` groups, `secrets/<n>` values) are
475
+ runtime-resolved: hashed by **name only**, resolved at dispatch, values
476
+ joined to `sensitiveValues` for redaction, never durable. (Existing
477
+ contract, now stated as the rule.)
478
+ - IR `env` becomes a typed entry list (ref | literal-pair) — an IR v4
479
+ change, not "additive."
480
+ - Env assembly moves per-unit where fan-out requires it: a `map:` step
481
+ with a shell target receives `AKM_ITEM` (JSON) and `AKM_ITEM_INDEX`
482
+ per unit — set as env-object entries on the spawned process (the
483
+ `runManagedSubprocess` `env:` pattern — `src/core/subprocess.ts`, as
484
+ used at `tasks/runner.ts:284`), never spliced into shell text.
485
+ - Literal entries run the existing secret-shape heuristic
486
+ (`param-secrets.ts`'s `detectSecretShapedParams`, built for exactly this
487
+ risk on params): a secret-shaped literal is a lint error pointing at
488
+ `secrets/<n>`.
489
+ - The split is enforced at one place: a single env-assembly resolver (§8
490
+ plumbing) is the only producer of env entries and of their
491
+ `sensitiveValues` contributions, so the literal/ref line cannot
492
+ silently diverge per call site.
493
+
494
+ ### 5.6 Executing scripts inherits the tools: ceiling — no new trust machinery
495
+
496
+ v8 proposed a per-bundle grant key. The panel killed it twice over:
497
+ `activation-policy.ts` documents a standing decision **against new
498
+ persisted trust machinery**, and the claimed precedent — the `tools:`
499
+ provenance ceiling — has **no override at all**. v9 inherits the ceiling
500
+ exactly instead of imitating it loosely:
501
+
502
+ - Shell-class work (a script asset, or the `run:` text of a task) executes
503
+ **only when its defining asset lives in the operator's primary bundle** —
504
+ the same line 07 P1-D draws for self-declared tool grants
505
+ (`show.ts:433-445`): keyed off primary-bundle identity, explicitly *not*
506
+ the writable bit, failing closed.
507
+ - Evaluated in the **resolve stage** (§5.1) — the shared stage both
508
+ surfaces run before any execution — so there is no sync-time/fire-time
509
+ gap and no standing grant for a bundle update to swap content under.
510
+ - Composition chains inherit the rule from the **defining asset's own
511
+ source**: a primary-bundle task that `uses:` a third-party script — or
512
+ composes a third-party task whose target is shell — refuses with an
513
+ error naming the ref and its source. No chain launders provenance.
514
+ - The remedy is an existing verb, not a config bit: `akm clone <ref>`
515
+ copies the asset into the primary bundle, where the operator owns and
516
+ reviews the bytes; the refusal message says exactly that.
517
+ - Scope: this ceiling governs the **new non-AI exec surface only**.
518
+ Agent-dispatched third-party tasks remain governed by the existing
519
+ scheduling gates (setup/sync review, `enabled:`), unchanged.
520
+
521
+ Zero new config, zero persisted trust state. Loosening later (per-bundle
522
+ grants) is an additive future decision that must revisit the
523
+ activation-policy document — deliberately out of 0.9.0 scope.
524
+
525
+ ### 5.7 Shell ergonomics
526
+
527
+ - Bare `akm` in shell/script work resolves to the current installation by
528
+ a **synthesized shim**, not a bare PATH prepend: `resolveAkmInvocation()`
529
+ can return a multi-element launcher invocation (`bun <script>` — the
530
+ case the argv-splice was built for, panel M9 follow-up), so the runner
531
+ writes a platform-appropriate shim (sh script / `.cmd`) invoking the
532
+ exact resolved invocation into the run's temp dir and prepends that dir
533
+ to the child `PATH` (case-insensitive `Path` merge on Windows). Replaces
534
+ the argv rewrite for shell work and covers scripts for free; the task
535
+ runner keeps the argv rewrite only for legacy `.yml` until retirement.
536
+ - `cwd:` under `isolation: worktree` is resolved relative to the worktree
537
+ root; `cwd:` on the LLM runner is a capability notice (review minors).
538
+
539
+ ## 6. GitHub Actions alignment — familiar, not copied
540
+
541
+ Adopted: `uses:`/`run:` pair with mutual exclusion; **`with:` for inputs
542
+ to the referenced thing** (returned to the adopted column by M1);
543
+ step-level keys with no nesting bag; shell semantics with per-OS defaults
544
+ and `shell:`; `env:` bare-mapping shorthand; `cwd:`; `on_error`/`timeout`
545
+ as step keys. Kept akm: typed asset refs (the subdir says what executes —
546
+ GHA's `uses:` is opaque); `params:` reserved for declarations; no step
547
+ `name:`; bundles as the sharing unit.
548
+
549
+ ## 7. Steps flatten to the task shape — with the schema collision fixed
550
+
551
+ The `unit:` bag and `map.unit` are still deleted; targets and value fields
552
+ sit on the step; `map:` keeps `over`/`concurrency`/`reducer`. But v7's
553
+ "duplicate `output` wart" was **wrong** — review C1 (3/3):
554
+ `unit.output` compiles to the per-dispatch structured-result `schema`
555
+ (driving structured retry / `parse_error`) while `step.output` compiles to
556
+ `outputSchema`, the promoted artifact the gate validates
557
+ (`compile.ts:204,229` — verified). Two concepts, two homes:
558
+
559
+ - **`output:`** on a step — the step's **artifact** schema, all step kinds.
560
+ On a unit step it also serves as the dispatch result schema (result *is*
561
+ the artifact).
562
+ - **`map.output:`** — the **per-item** result schema of a map step's units;
563
+ the step's `output:` continues to describe the reduced artifact.
564
+
565
+ ```yaml
566
+ - id: review
567
+ map: { over: steps.intake.output.files, concurrency: 3, output: { type: object } }
568
+ output: { type: array } # what `steps.review.output` resolves to
569
+ ```
570
+
571
+ ## 8. Migration — inside the hardened 0.9.0 cutover
572
+
573
+ Rebuilt against the `71bb686` migrator and review M7 (3/3):
574
+
575
+ - **The converter joins the content-migration step with a vendored,
576
+ frozen copy of the v2 task parser** — the current
577
+ `task-target-ref-migration.ts` imports the *live* parser from `src/`,
578
+ which violates the frozen-migrator principle and breaks the moment the
579
+ live parser is replaced; that gets fixed as part of this work.
580
+ - Mapping: `command: <shell string>` → `run:` verbatim; `command:
581
+ [argv…]` → `run:` with each element shell-escaped **for POSIX `sh`, the
582
+ migrated task recording `shell: sh` explicitly** so the Windows
583
+ `powershell` default never reinterprets the quoting; `prompt: |` →
584
+ body; `prompt: commands/x` → `uses:` + `with:`; `prompt: agents/x` →
585
+ `agent:`; `prompt: ./file.md` → inlined; `workflow:`+`params` →
586
+ `uses: workflows/…` + `with:`; `timeoutMs` → `timeout`;
587
+ `llm.maxTokens`/`llm.temperature`/`llm.extraParams` → flat fields;
588
+ **`name:` → the body's H1** when the converted body has none, else a
589
+ per-task migration notice (never silently dropped);
590
+ `llm.supportsJsonSchema`/`contextLength`/`enableThinking` are
591
+ endpoint-capability facts that belong on the **engine node** — the
592
+ migrator emits a per-task notice naming the value and the config key
593
+ (lossy-with-notice, never silent).
594
+ - Scheduler entries untouched: ids and the `akm task run <id>` ABI do not
595
+ change.
596
+ - **The `.yml` tombstone rule** replaces v7's false "structural" claim
597
+ (refusals key on config/DB shape, not stray files, and placement
598
+ filters by extension — a stray `.yml` today would be invisible or
599
+ wrongly installed): task discovery keeps matching `tasks/*.yml`
600
+ **permanently, as a diagnostic**. In **writable** bundles, `sync`,
601
+ `doctor`, and `lint` hard-error naming the file and the fix; in
602
+ **read-only/third-party** bundles the same diagnostic is a warning —
603
+ the operator cannot edit those files, matching the migrator's existing
604
+ read-only carve-out (`task-target-ref-migration.ts:253-271`). Either
605
+ way a `.yml` is never installed and never silently skipped.
606
+ `<id>.yml` + `<id>.md` colliding on one conceptId is the same named
607
+ error. **Conversion is interruption-safe by ordering**: the migrator
608
+ journals the `.md` write and verifies it before removing the `.yml`,
609
+ and the collision diagnostic special-cases the byte-equivalent
610
+ mid-migration pair (resume completes the removal instead of erroring on
611
+ the migrator's own half-applied state — the panel's crash-window
612
+ finding; the current *backup* model journals whole-DB/config artifacts
613
+ only (`migration-backup.ts:54`), so per-file crash safety lives in the
614
+ content-migration step's own resume ledger —
615
+ `content-migration-report.json`'s `reservedRenames`
616
+ (`config-migrate.ts:518-575`); the `.md`-write-then-`.yml`-delete
617
+ ordering extends that existing ledger rather than introducing per-file
618
+ journaling, costed in §9).
619
+ - Embedded templates convert to `.md`; `listEmbeddedTasks` and `akm
620
+ setup`'s task review move to markdown-aware editing (the current YAML
621
+ round-trip would destroy bodies — review minor).
622
+ - The id-grammar work (subdir ids, scheduler-id `/` → `--` mapping with
623
+ collision lint) lands **in the same migration step, before scheduler
624
+ reconciliation** — sequencing the panel flagged as unstated.
625
+ - The pre-flatten workflow schema (`unit:`, `map.unit`, `defaults.llm`)
626
+ converts in the same step: bag fields lift, `llm` flattens,
627
+ `unit.output` → `map.output` or step `output:` per §7.
628
+
629
+ ## 9. Cost inventory — what this actually changes
630
+
631
+ Honest replacement for v7's §10 (review: "non-goals false ×4").
632
+
633
+ | Surface | Change |
634
+ |---|---|
635
+ | IR | v3 → v4: invocation union, optional instructions (shell), typed env entries, `map.output` |
636
+ | Unit hash | hashVersion 4 → 5 (§5.3 preimage) |
637
+ | Freeze | two-stage (compile/resolve/freeze), per-kind engine resolution, persona snapshot, prose append, capability notices |
638
+ | Dispatch | executor strategy (agent/shell); persona fields reach `UnitDispatchRequest` |
639
+ | Schemas | shared target+value defs; task schema rewritten; workflow schema flattened; `DefaultsSchema` extended and made strict; engine schemas made strict |
640
+ | Parsers | `parseTaskDocument` retired to the migrator (vendored); unified parser gains task recognition; section-required rule relaxed per target kind; the indexer classifier (`matchers.ts`) gains a `type: task` branch ordered ahead of the `"agent" in fm` rule |
641
+ | Adapters | markdown task recognition (`type: task`); the `type: "task"` pure-YAML special-case removed (markdown base checks apply); improve-ineligibility declared per-type (§3 — `DISTILL_REFUSED_INPUT_TYPES` is the cheapest of three homes); akm-task format-family goldens rewritten directly (they carry `specificationGolden: true` / `adapterStatus: NOT IMPLEMENTED`, and `DESIGNATIONS.json` does not cover that tree at all). **DESIGNATIONS re-pointing is mandatory pre-work**: six entries are touched — `cli/c-tasks-family.json` (already `re-baseline`, chunk 9) plus five goldens pinning `tasks/*.yml` paths — `recognition/all-types.json`, `placement/all-types.json`, `minting/oracle.json` (chunk 4), `lint/all-types.json` (chunk 3), `renderer/all-types.json` (chunk 8) — whose `reBaselineChunk` must be re-pointed at this change *before* it lands, per the DESIGNATIONS `$policy` surface-owner rule |
642
+ | Named refactors | 07 P1-D ceiling extracted from `show.ts` into a shared persona resolver; ShellUnitExecutor extracted from the task runner's hardened command path; the three engine/model resolution sites consolidated into the cascade module; the `akm` shim mechanism; per-file create-verify-delete ordering added to the content-migration step's existing `reservedRenames` resume ledger |
643
+ | CLI | `task create`; `task add` retires with `.yml`; capability notices in lint/doctor |
644
+ | Storage | `task_history.target_kind` values widened (additive) |
645
+ | Docs/tests | reference docs, ~10 templates, format-family goldens, parser/freeze/executor suites |
646
+
647
+ Inherited bugs fixed en route: `{{0}}`-only placeholder filling; raw
648
+ frontmatter shipped to models via `prompt: agents/x`; subdir task ids
649
+ indexed but unrunnable (`validateTaskId` rejects `/` — the id grammar
650
+ gains subdir support with the scheduler-id mapping documented); freeze's
651
+ dead llm guard.
652
+
653
+ ## 10. Non-goals (now true)
654
+
655
+ - No new orchestration semantics: `map`/`route`/`gate` behavior, leases,
656
+ check-ins, replay *logic*, and the driver protocol are unchanged (shell
657
+ units are orchestrator-owned under it).
658
+ - No scheduler-backend, `sync`-reconciliation, or `akm task run <id>` ABI
659
+ changes.
660
+ - No change to how command/script/agent/env/secret assets are authored.
661
+ - No multi-file config merging; the cascade layers are config nodes,
662
+ bundle assets, and document/call-site keys.
663
+ - Gate judge selection stays outside the cascade in 0.9.0.
664
+
665
+ ## 11. Findings cross-reference and decision log
666
+
667
+ | Finding (consolidated) | Resolution |
668
+ |---|---|
669
+ | C1 output collision (3/3) | §7 — two schemas, two homes (`output:` / `map.output:`) |
670
+ | C2 shell units unrepresentable (3/3) | §5.2 — IR v4 invocation union, per-kind engine resolution |
671
+ | C3 hash preimage (3/3) | §5.3 — hashVersion 5, preimage table; §2.3 freeze-time append |
672
+ | C4 cascade layers don't exist (3/3) | §4 — "built, not exposed"; build inventory |
673
+ | C5 script execution security (2/3) | §5.6 — the tools: ceiling inherited exactly (primary-bundle only, no override); v8's grant key withdrawn after the panel showed it contradicted activation-policy's no-new-trust-machinery decision |
674
+ | M1 params overload (3/3) | §2.2 — `with:` for inputs; `params:` declarations only; neither cascades |
675
+ | M2 placeholder grammar (3/3) | §2.4 — `with:`/`with.arguments` against the real grammar; lenient + lint |
676
+ | M3 env not additive (3/3) | §5.5 — literal/ref provenance split; IR v4; per-unit env |
677
+ | M4 alias portability (3/3) | §4.5 — `"*"` columns + unresolved-alias notice |
678
+ | M5 agent plumbing + ceiling; false corroboration | §4.2 — persona snapshot via show layer; corroboration claim retracted |
679
+ | M6 dead kind-gate (2/3) | §4.4 — both gates → capability notices |
680
+ | M7 migration overclaims (3/3) | §8 — vendored parser, full mapping, tombstone rule |
681
+ | M8 adapter recognition (2/3) | §3 — `type: task` required |
682
+ | M9 akm-bin rewrite (2/3) | §5.7 — synthesized shim (a bare PATH prepend cannot cover multi-element launcher invocations) |
683
+ | M10 prose invariants (2/3) | §5.2 — per-kind relaxation, costed |
684
+ | M11 lint never freezes (1/3) | §5.4 — dry freeze in lint |
685
+ | M12 `defaults.on_error` (2/3) | §4 — `on_error`/`retry` join the value vocabulary |
686
+ | M13 improve surface (1/3) | §3 — improve excluded from task bodies |
687
+ | Minors | §3 (draft/deprecated), §5.7 (cwd), §8 (embedded/setup, collisions), §9 (bugs fixed, target_kind, goldens) |
688
+
689
+ Decisions 1–14 (rounds 1–6) stand as logged in v7 except where this
690
+ revision supersedes them with review evidence: call-site `params:` →
691
+ `with:` (M1); "expose the cascade" → "build the cascade" (C4); "duplicate
692
+ output" → two-schema design (C1); §10 non-goals → §9 cost inventory
693
+ (C2/C3). v7's remaining question (cascade sign-off) is superseded by this
694
+ section's cross-reference — the cascade shape survived review; its cost
695
+ didn't, and is now stated.
696
+
697
+ **Round 1 Sonnet panel (v8 → v9).** Four independent reviewers (coverage
698
+ audit, architecture, fresh adversarial, security+migration; full reports
699
+ `sonnet-r1-*.md` in the session scratchpad). Panel criticals, all applied:
700
+ the §5.6 grant key contradicted activation-policy's documented
701
+ no-new-trust-machinery decision → replaced by exact ceiling inheritance;
702
+ the v8 hash preimage omitted the persona snapshot → added; `with:` merge
703
+ on composition chains was undefined → §2.2; the tombstone hard-error was
704
+ unactionable on read-only bundles → warning carve-out. Panel majors, all
705
+ applied: task-path staging named (resolve → execute); executor sinks as
706
+ the adapter boundary; ShellUnitExecutor extracted from the task runner's
707
+ hardened path, not rebuilt; monotemporal composition rule; persona
708
+ resolver extraction scoped; merge classes stated (deep-merge preserved
709
+ for `extra_params`); shell invocation carries `timeoutMs`; shell-unit
710
+ crash/lease semantics; toolPolicy under capability notices; improve
711
+ exclusion given a named mechanism; migration crash-window ordering;
712
+ POSIX-pinned migrated quoting; launcher-aware shim. One panel claim was
713
+ verified false and rejected: "the tools: ceiling doesn't exist" — it does
714
+ (`show.ts:433-445`), inline in the show command, which is exactly why §4
715
+ scopes its extraction.
716
+
717
+ Open items: none blocking. Two implementation-time choices are delegated
718
+ to the implementer with defaults: the exact capability-declaration shape
719
+ per engine kind (default: a static field list per kind), and the
720
+ scheduler-id mapping for subdir task ids (default: `/` → `--` with
721
+ collision lint).