akm-cli 0.9.0-rc.0 → 0.9.0-rc.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 (262) hide show
  1. package/CHANGELOG.md +339 -2
  2. package/SECURITY.md +23 -24
  3. package/dist/assets/help/help-improve.md +10 -10
  4. package/dist/assets/hints/cli-hints-full.md +44 -10
  5. package/dist/assets/hints/cli-hints-short.md +6 -2
  6. package/dist/assets/{profiles → improve-strategies}/default.json +1 -0
  7. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +1 -1
  8. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +2 -3
  9. package/dist/assets/{profiles → improve-strategies}/reflect-distill.json +3 -4
  10. package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
  11. package/dist/assets/stash-skeleton/README.md +28 -0
  12. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +6 -0
  13. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +6 -0
  14. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +12 -1
  15. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +11 -1
  16. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +6 -0
  17. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +9 -0
  18. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +7 -0
  19. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +7 -0
  20. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +6 -0
  21. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +98 -0
  22. package/dist/assets/stash-skeleton/facts/conventions/domains.md +63 -0
  23. package/dist/assets/stash-skeleton/facts/conventions/organization.md +127 -0
  24. package/dist/assets/tasks/core/backup.yml +1 -0
  25. package/dist/assets/tasks/core/extract.yml +1 -0
  26. package/dist/assets/tasks/core/improve.yml +1 -0
  27. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  28. package/dist/assets/tasks/core/sync.yml +1 -0
  29. package/dist/assets/tasks/core/version-check.yml +1 -0
  30. package/dist/assets/tasks/graph-refresh-weekly.yml +4 -4
  31. package/dist/assets/templates/html/health.html +5 -1
  32. package/dist/cli/config-migrate.js +31 -138
  33. package/dist/cli/config-validate.js +10 -8
  34. package/dist/cli.js +48 -14
  35. package/dist/commands/agent/agent-dispatch.js +17 -16
  36. package/dist/commands/agent/agent-support.js +0 -24
  37. package/dist/commands/agent/contribute-cli.js +5 -15
  38. package/dist/commands/backup-cli.js +54 -0
  39. package/dist/commands/config-cli.js +45 -159
  40. package/dist/commands/env/env-binding.js +95 -0
  41. package/dist/commands/env/env-cli.js +8 -65
  42. package/dist/commands/env/secret.js +8 -5
  43. package/dist/commands/health/checks.js +130 -83
  44. package/dist/commands/health/html-report.js +4 -0
  45. package/dist/commands/health/improve-metrics.js +30 -32
  46. package/dist/commands/health/llm-usage.js +19 -19
  47. package/dist/commands/health/md-report.js +4 -0
  48. package/dist/commands/health/metrics.js +2 -1
  49. package/dist/commands/health/surfaces.js +5 -4
  50. package/dist/commands/health.js +1 -1
  51. package/dist/commands/improve/consolidate/chunking.js +2 -2
  52. package/dist/commands/improve/consolidate.js +28 -25
  53. package/dist/commands/improve/distill/promote-memory.js +5 -12
  54. package/dist/commands/improve/distill/quality-gate.js +5 -7
  55. package/dist/commands/improve/distill.js +16 -5
  56. package/dist/commands/improve/eligibility.js +22 -12
  57. package/dist/commands/improve/extract-cli.js +47 -19
  58. package/dist/commands/improve/extract.js +110 -62
  59. package/dist/commands/improve/improve-cli.js +38 -16
  60. package/dist/commands/improve/improve-result-file.js +30 -24
  61. package/dist/commands/improve/improve-strategies.js +137 -0
  62. package/dist/commands/improve/improve.js +60 -30
  63. package/dist/commands/improve/locks.js +66 -45
  64. package/dist/commands/improve/loop-stages.js +75 -33
  65. package/dist/commands/improve/memory/memory-belief.js +79 -7
  66. package/dist/commands/improve/memory/memory-contradiction-detect.js +12 -4
  67. package/dist/commands/improve/preparation.js +71 -73
  68. package/dist/commands/improve/procedural.js +3 -2
  69. package/dist/commands/improve/recombine.js +2 -1
  70. package/dist/commands/improve/reflect.js +119 -214
  71. package/dist/commands/improve/shared.js +11 -5
  72. package/dist/commands/lint/base-linter.js +152 -42
  73. package/dist/commands/mv-cli.js +809 -0
  74. package/dist/commands/proposal/proposal-cli.js +18 -8
  75. package/dist/commands/proposal/propose.js +64 -69
  76. package/dist/commands/read/knowledge.js +436 -4
  77. package/dist/commands/read/remember-cli.js +39 -2
  78. package/dist/commands/read/search-cli.js +6 -1
  79. package/dist/commands/registry-cli.js +29 -14
  80. package/dist/commands/remember.js +2 -0
  81. package/dist/commands/sources/init.js +13 -14
  82. package/dist/commands/sources/migration-help.js +7 -4
  83. package/dist/commands/sources/schema-repair.js +2 -4
  84. package/dist/commands/sources/source-add.js +62 -73
  85. package/dist/commands/sources/source-manage.js +50 -46
  86. package/dist/commands/sources/stash-cli.js +41 -4
  87. package/dist/commands/tasks/default-tasks.js +12 -12
  88. package/dist/commands/tasks/tasks-cli.js +7 -3
  89. package/dist/commands/tasks/tasks.js +113 -18
  90. package/dist/commands/wiki-cli.js +9 -10
  91. package/dist/commands/workflow-cli.js +276 -12
  92. package/dist/core/asset/asset-spec.js +58 -1
  93. package/dist/core/asset/frontmatter.js +12 -2
  94. package/dist/core/common.js +5 -3
  95. package/dist/core/config/config-io.js +28 -17
  96. package/dist/core/config/config-schema.js +379 -66
  97. package/dist/core/config/config-types.js +3 -3
  98. package/dist/core/config/config-version.js +29 -0
  99. package/dist/core/config/config-walker.js +98 -27
  100. package/dist/core/config/config.js +132 -266
  101. package/dist/core/config/deep-merge.js +41 -0
  102. package/dist/core/config/engine-semantics.js +32 -0
  103. package/dist/core/errors.js +2 -2
  104. package/dist/core/extra-params.js +61 -0
  105. package/dist/core/file-lock.js +201 -56
  106. package/dist/core/improve-result.js +178 -0
  107. package/dist/core/json-schema.js +142 -0
  108. package/dist/core/maintenance-barrier.js +119 -0
  109. package/dist/core/migration-backup.js +416 -0
  110. package/dist/core/paths.js +3 -0
  111. package/dist/core/redaction.js +358 -0
  112. package/dist/core/state/migrations.js +17 -2
  113. package/dist/core/state-db.js +44 -1
  114. package/dist/indexer/db/db.js +118 -2
  115. package/dist/indexer/graph/graph-extraction.js +28 -16
  116. package/dist/indexer/index-writer-lock.js +31 -24
  117. package/dist/indexer/index-written-assets.js +15 -6
  118. package/dist/indexer/indexer.js +47 -2
  119. package/dist/indexer/passes/memory-inference.js +10 -6
  120. package/dist/indexer/passes/metadata.js +250 -0
  121. package/dist/indexer/search/db-search.js +111 -44
  122. package/dist/indexer/search/fts-query.js +41 -0
  123. package/dist/indexer/search/ranking-contributors.js +48 -0
  124. package/dist/indexer/search/ranking.js +36 -23
  125. package/dist/indexer/search/search-fields.js +11 -1
  126. package/dist/indexer/walk/matchers.js +39 -0
  127. package/dist/integrations/agent/builder-shared.js +7 -0
  128. package/dist/integrations/agent/builders.js +5 -50
  129. package/dist/integrations/agent/config.js +3 -143
  130. package/dist/integrations/agent/detect.js +17 -2
  131. package/dist/integrations/agent/engine-resolution.js +202 -0
  132. package/dist/integrations/agent/index.js +1 -2
  133. package/dist/integrations/agent/model-aliases.js +16 -2
  134. package/dist/integrations/agent/profiles.js +36 -62
  135. package/dist/integrations/agent/runner-dispatch.js +91 -4
  136. package/dist/integrations/agent/runner.js +76 -207
  137. package/dist/integrations/agent/spawn.js +141 -20
  138. package/dist/integrations/harnesses/aider/agent-builder.js +112 -0
  139. package/dist/integrations/harnesses/aider/index.js +57 -0
  140. package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
  141. package/dist/integrations/harnesses/amazonq/agent-builder.js +152 -0
  142. package/dist/integrations/harnesses/amazonq/index.js +58 -0
  143. package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
  144. package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
  145. package/dist/integrations/harnesses/claude/index.js +25 -25
  146. package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
  147. package/dist/integrations/harnesses/codex/agent-builder.js +136 -0
  148. package/dist/integrations/harnesses/codex/index.js +62 -0
  149. package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
  150. package/dist/integrations/harnesses/copilot/agent-builder.js +121 -0
  151. package/dist/integrations/harnesses/copilot/index.js +59 -0
  152. package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
  153. package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
  154. package/dist/integrations/harnesses/gemini/index.js +59 -0
  155. package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
  156. package/dist/integrations/harnesses/index.js +27 -28
  157. package/dist/integrations/harnesses/opencode/agent-builder.js +2 -3
  158. package/dist/integrations/harnesses/opencode/index.js +15 -22
  159. package/dist/integrations/harnesses/opencode-sdk/harness.js +60 -0
  160. package/dist/integrations/harnesses/opencode-sdk/index.js +8 -32
  161. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
  162. package/dist/integrations/harnesses/openhands/agent-builder.js +125 -0
  163. package/dist/integrations/harnesses/openhands/index.js +57 -0
  164. package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
  165. package/dist/integrations/harnesses/pi/agent-builder.js +103 -0
  166. package/dist/integrations/harnesses/pi/index.js +57 -0
  167. package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
  168. package/dist/integrations/harnesses/types.js +8 -32
  169. package/dist/integrations/lockfile.js +32 -21
  170. package/dist/integrations/session-logs/index.js +24 -11
  171. package/dist/llm/client.js +48 -14
  172. package/dist/llm/feature-gate.js +15 -47
  173. package/dist/llm/graph-extract.js +1 -1
  174. package/dist/llm/index-passes.js +8 -42
  175. package/dist/llm/memory-infer-impl.js +1 -1
  176. package/dist/llm/usage-persist.js +4 -0
  177. package/dist/llm/usage-telemetry.js +35 -5
  178. package/dist/output/renderers.js +3 -2
  179. package/dist/output/shapes/helpers.js +2 -1
  180. package/dist/output/shapes/passthrough.js +6 -0
  181. package/dist/output/text/helpers.js +215 -2
  182. package/dist/output/text/workflow.js +3 -1
  183. package/dist/schemas/akm-config.json +16638 -0
  184. package/dist/schemas/akm-task.json +87 -0
  185. package/dist/schemas/akm-workflow.json +372 -0
  186. package/dist/scripts/migrate-storage.js +10944 -8801
  187. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +9247 -350
  188. package/dist/setup/detected-engines.js +142 -0
  189. package/dist/setup/engine-config.js +89 -0
  190. package/dist/setup/setup.js +236 -132
  191. package/dist/setup/steps/connection.js +61 -32
  192. package/dist/setup/steps/platforms.js +4 -4
  193. package/dist/setup/steps.js +3 -2
  194. package/dist/storage/database.js +13 -1
  195. package/dist/storage/engines/sqlite-migrations.js +1 -0
  196. package/dist/storage/repositories/improve-runs-repository.js +5 -5
  197. package/dist/storage/repositories/task-history-repository.js +78 -0
  198. package/dist/storage/repositories/workflow-runs-repository.js +190 -1
  199. package/dist/tasks/parser.js +138 -52
  200. package/dist/tasks/runner.js +71 -75
  201. package/dist/tasks/schema.js +1 -1
  202. package/dist/tasks/validator.js +11 -6
  203. package/dist/text-import-hook.mjs +1 -1
  204. package/dist/wiki/wiki.js +9 -8
  205. package/dist/workflows/authoring/authoring.js +123 -10
  206. package/dist/workflows/authoring/workflow-program-template.yaml +31 -0
  207. package/dist/workflows/cli.js +4 -0
  208. package/dist/workflows/concurrency-policy.js +15 -0
  209. package/dist/workflows/db.js +200 -13
  210. package/dist/workflows/exec/brief.js +478 -0
  211. package/dist/workflows/exec/frozen-judge.js +47 -0
  212. package/dist/workflows/exec/native-executor.js +1034 -0
  213. package/dist/workflows/exec/param-secrets.js +115 -0
  214. package/dist/workflows/exec/report.js +1355 -0
  215. package/dist/workflows/exec/run-workflow.js +609 -0
  216. package/dist/workflows/exec/scheduler.js +71 -0
  217. package/dist/workflows/exec/step-work.js +1212 -0
  218. package/dist/workflows/exec/unit-writer.js +23 -0
  219. package/dist/workflows/exec/watch.js +116 -0
  220. package/dist/workflows/exec/worktree.js +171 -0
  221. package/dist/workflows/ir/compile.js +375 -0
  222. package/dist/workflows/ir/freeze.js +243 -0
  223. package/dist/workflows/ir/params.js +54 -0
  224. package/dist/workflows/ir/plan-hash.js +68 -0
  225. package/dist/workflows/ir/schema.js +545 -0
  226. package/dist/workflows/parser.js +10 -1
  227. package/dist/workflows/program/expressions.js +369 -0
  228. package/dist/workflows/program/parser.js +869 -0
  229. package/dist/workflows/program/project.js +104 -0
  230. package/dist/workflows/program/schema.js +54 -0
  231. package/dist/workflows/renderer.js +82 -5
  232. package/dist/workflows/resource-limits.js +20 -0
  233. package/dist/workflows/runtime/agent-identity.js +59 -14
  234. package/dist/workflows/runtime/plan-classifier.js +187 -0
  235. package/dist/workflows/runtime/runs.js +246 -69
  236. package/dist/workflows/runtime/unit-checkin.js +45 -0
  237. package/dist/workflows/runtime/workflow-asset-loader.js +42 -1
  238. package/dist/workflows/validate-summary.js +24 -3
  239. package/dist/workflows/validator.js +26 -1
  240. package/docs/data-and-telemetry.md +4 -3
  241. package/docs/migration/release-notes/0.6.0.md +1 -1
  242. package/docs/migration/release-notes/0.7.0.md +5 -4
  243. package/docs/migration/release-notes/0.9.0-beta.60.md +19 -0
  244. package/docs/migration/v0.8-to-v0.9.md +401 -0
  245. package/package.json +4 -2
  246. package/schemas/akm-config.json +16638 -0
  247. package/schemas/akm-task.json +87 -0
  248. package/schemas/akm-workflow.json +372 -0
  249. package/dist/commands/improve/improve-profiles.js +0 -168
  250. package/dist/core/config/config-migration.js +0 -602
  251. package/dist/core/deep-merge.js +0 -38
  252. package/dist/llm/call-ai.js +0 -62
  253. package/dist/setup/legacy-config.js +0 -106
  254. package/docs/README.md +0 -104
  255. /package/dist/assets/{profiles → improve-strategies}/catchup.json +0 -0
  256. /package/dist/assets/{profiles → improve-strategies}/consolidate.json +0 -0
  257. /package/dist/assets/{profiles → improve-strategies}/frequent.json +0 -0
  258. /package/dist/assets/{profiles → improve-strategies}/memory-focus.json +0 -0
  259. /package/dist/assets/{profiles → improve-strategies}/quick.json +0 -0
  260. /package/dist/assets/{profiles → improve-strategies}/recombine-only.json +0 -0
  261. /package/dist/assets/{profiles → improve-strategies}/synthesize.json +0 -0
  262. /package/dist/assets/{profiles → improve-strategies}/thorough.json +0 -0
@@ -0,0 +1,87 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://itlackey.github.io/akm/schemas/akm-task.json",
4
+ "title": "AKM Scheduled Task",
5
+ "description": "Strict version-2 YAML task definition. Exactly one target is required.",
6
+ "type": "object",
7
+ "required": ["version", "schedule"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "version": { "const": 2 },
11
+ "name": { "type": "string" },
12
+ "description": { "type": "string" },
13
+ "when_to_use": { "type": "string" },
14
+ "tags": { "type": "array", "items": { "type": "string", "minLength": 1 } },
15
+ "schedule": { "type": "string", "minLength": 1 },
16
+ "enabled": { "type": "boolean" },
17
+ "workflow": { "type": "string", "minLength": 1 },
18
+ "prompt": { "type": "string", "minLength": 1 },
19
+ "command": {
20
+ "oneOf": [
21
+ { "type": "string", "minLength": 1 },
22
+ { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } }
23
+ ]
24
+ },
25
+ "params": { "type": "object" },
26
+ "engine": { "type": "string", "minLength": 1 },
27
+ "model": { "type": "string", "minLength": 1 },
28
+ "timeoutMs": { "type": ["integer", "null"], "minimum": 1 },
29
+ "llm": { "$ref": "#/definitions/llm" }
30
+ },
31
+ "oneOf": [
32
+ {
33
+ "required": ["workflow"],
34
+ "not": { "anyOf": [{ "required": ["prompt"] }, { "required": ["command"] }, { "required": ["engine"] }, { "required": ["model"] }, { "required": ["timeoutMs"] }, { "required": ["llm"] }] }
35
+ },
36
+ {
37
+ "required": ["prompt"],
38
+ "not": { "anyOf": [{ "required": ["workflow"] }, { "required": ["command"] }, { "required": ["params"] }] }
39
+ },
40
+ {
41
+ "required": ["command"],
42
+ "not": { "anyOf": [{ "required": ["workflow"] }, { "required": ["prompt"] }, { "required": ["params"] }, { "required": ["engine"] }, { "required": ["model"] }, { "required": ["llm"] }] }
43
+ }
44
+ ],
45
+ "definitions": {
46
+ "llm": {
47
+ "type": "object",
48
+ "additionalProperties": false,
49
+ "properties": {
50
+ "temperature": { "type": "number" },
51
+ "maxTokens": { "type": "integer", "minimum": 1 },
52
+ "supportsJsonSchema": { "type": "boolean" },
53
+ "extraParams": { "$ref": "#/definitions/extraParams" },
54
+ "contextLength": { "type": "integer", "minimum": 1 },
55
+ "enableThinking": { "type": "boolean" }
56
+ }
57
+ },
58
+ "extraParams": {
59
+ "type": "object",
60
+ "description": "Provider-specific request fields. Top-level AKM-owned fields are forbidden; credential-shaped keys are forbidden recursively after lowercase/non-alphanumeric normalization.",
61
+ "propertyNames": {
62
+ "not": {
63
+ "enum": ["model", "messages", "temperature", "maxtokens", "responseformat", "stream", "streamoptions", "enablethinking", "authorization", "headers", "apikey", "token", "password", "secret", "cookie", "setcookie"]
64
+ }
65
+ },
66
+ "additionalProperties": { "$ref": "#/definitions/extraParamValue" },
67
+ "x-akm-protectedTopLevelNormalizedKeys": ["model", "messages", "temperature", "maxtokens", "responseformat", "stream", "streamoptions", "enablethinking"],
68
+ "x-akm-recursivelyForbiddenNormalizedKeys": ["authorization", "headers", "apikey", "token", "password", "secret", "cookie", "setcookie"]
69
+ },
70
+ "extraParamValue": {
71
+ "anyOf": [
72
+ { "type": ["string", "number", "boolean", "null"] },
73
+ { "type": "array", "items": { "$ref": "#/definitions/extraParamValue" } },
74
+ {
75
+ "type": "object",
76
+ "propertyNames": {
77
+ "not": {
78
+ "enum": ["authorization", "headers", "apikey", "token", "password", "secret", "cookie", "setcookie"]
79
+ }
80
+ },
81
+ "additionalProperties": { "$ref": "#/definitions/extraParamValue" },
82
+ "x-akm-recursivelyForbiddenNormalizedKeys": ["authorization", "headers", "apikey", "token", "password", "secret", "cookie", "setcookie"]
83
+ }
84
+ ]
85
+ }
86
+ }
87
+ }
@@ -0,0 +1,372 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://itlackey.github.io/akm/schemas/akm-workflow.json",
4
+ "title": "AKM Workflow Program",
5
+ "description": "YAML workflow program for the akm CLI (Agent Knowledge Management). Files live under workflows/ with extension .yaml or .yml. Hand-authored alongside src/workflows/program/schema.ts; the enum vocabularies and patterns here are pinned against the TypeScript constants by tests/workflows/program-parser.test.ts — update both together.",
6
+ "type": "object",
7
+ "required": ["version", "name", "steps"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "version": {
11
+ "const": 2,
12
+ "description": "Workflow program format version. Only 2 is valid."
13
+ },
14
+ "name": {
15
+ "type": "string",
16
+ "minLength": 1,
17
+ "description": "Workflow name."
18
+ },
19
+ "description": {
20
+ "type": "string",
21
+ "description": "Optional human-readable description."
22
+ },
23
+ "params": {
24
+ "type": "object",
25
+ "maxProperties": 128,
26
+ "description": "Run parameters: param name -> JSON Schema declaration. Names must be ${{ params.<name> }}-addressable identifiers.",
27
+ "propertyNames": {
28
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
29
+ },
30
+ "additionalProperties": {
31
+ "$ref": "#/definitions/jsonSchemaObject"
32
+ }
33
+ },
34
+ "defaults": {
35
+ "$ref": "#/definitions/defaults"
36
+ },
37
+ "budget": {
38
+ "$ref": "#/definitions/budget"
39
+ },
40
+ "steps": {
41
+ "type": "array",
42
+ "minItems": 1,
43
+ "maxItems": 256,
44
+ "items": {
45
+ "$ref": "#/definitions/step"
46
+ }
47
+ }
48
+ },
49
+ "definitions": {
50
+ "identifier": {
51
+ "type": "string",
52
+ "pattern": "^[A-Za-z_][A-Za-z0-9_-]*$",
53
+ "description": "Step id: a letter or underscore first, then letters, digits, underscores, or dashes (no dots, no leading digit). This is exactly the ${{ steps.<id>.output }}-addressable grammar; dots are reserved for the .output path separator and the engine's internal <stepId>.gate node id."
54
+ },
55
+ "timeout": {
56
+ "description": "Duration: \"<n>ms\" | \"<n>s\" | \"<n>m\" | \"none\" (bare integers are milliseconds).",
57
+ "oneOf": [
58
+ {
59
+ "type": "string",
60
+ "pattern": "^([0-9]+(ms|s|m)?|none)$"
61
+ },
62
+ {
63
+ "type": "integer",
64
+ "minimum": 1
65
+ }
66
+ ]
67
+ },
68
+ "onError": {
69
+ "description": "Failure policy: fail the step on the first unit failure (default), or record failures and let the gate decide.",
70
+ "enum": ["fail", "continue"]
71
+ },
72
+ "llm": {
73
+ "type": "object",
74
+ "additionalProperties": false,
75
+ "properties": {
76
+ "temperature": { "type": "number" },
77
+ "max_tokens": { "type": "integer", "minimum": 1 },
78
+ "supports_json_schema": { "type": "boolean" },
79
+ "extra_params": { "$ref": "#/definitions/extraParams" },
80
+ "context_length": { "type": "integer", "minimum": 1 },
81
+ "enable_thinking": { "type": "boolean" }
82
+ }
83
+ },
84
+ "extraParams": {
85
+ "type": "object",
86
+ "description": "Provider-specific request fields. Top-level AKM-owned fields are forbidden; credential-shaped keys are forbidden recursively after lowercase/non-alphanumeric normalization.",
87
+ "propertyNames": {
88
+ "not": {
89
+ "enum": ["model", "messages", "temperature", "maxtokens", "responseformat", "stream", "streamoptions", "enablethinking", "authorization", "headers", "apikey", "token", "password", "secret", "cookie", "setcookie"]
90
+ }
91
+ },
92
+ "additionalProperties": { "$ref": "#/definitions/extraParamValue" },
93
+ "x-akm-protectedTopLevelNormalizedKeys": ["model", "messages", "temperature", "maxtokens", "responseformat", "stream", "streamoptions", "enablethinking"],
94
+ "x-akm-recursivelyForbiddenNormalizedKeys": ["authorization", "headers", "apikey", "token", "password", "secret", "cookie", "setcookie"]
95
+ },
96
+ "extraParamValue": {
97
+ "anyOf": [
98
+ { "type": ["string", "number", "boolean", "null"] },
99
+ { "type": "array", "items": { "$ref": "#/definitions/extraParamValue" } },
100
+ {
101
+ "type": "object",
102
+ "propertyNames": {
103
+ "not": {
104
+ "enum": ["authorization", "headers", "apikey", "token", "password", "secret", "cookie", "setcookie"]
105
+ }
106
+ },
107
+ "additionalProperties": { "$ref": "#/definitions/extraParamValue" },
108
+ "x-akm-recursivelyForbiddenNormalizedKeys": ["authorization", "headers", "apikey", "token", "password", "secret", "cookie", "setcookie"]
109
+ }
110
+ ]
111
+ },
112
+ "reducer": {
113
+ "description": "How a map step folds per-item unit results into the step artifact.",
114
+ "enum": ["collect", "vote"]
115
+ },
116
+ "isolation": {
117
+ "description": "Filesystem isolation for file-mutating units (enforcement lands in R2).",
118
+ "enum": ["none", "worktree"]
119
+ },
120
+ "failureReason": {
121
+ "description": "Persisted AgentFailureReason taxonomy (src/integrations/agent/spawn.ts).",
122
+ "enum": [
123
+ "timeout",
124
+ "spawn_failed",
125
+ "non_zero_exit",
126
+ "parse_error",
127
+ "cooldown",
128
+ "llm_rate_limit",
129
+ "llm_content_filter",
130
+ "llm_invalid_json",
131
+ "content_policy_reject",
132
+ "unsupported_type",
133
+ "no_change",
134
+ "aborted"
135
+ ]
136
+ },
137
+ "jsonSchemaObject": {
138
+ "type": "object",
139
+ "description": "A JSON Schema declaration (validated as a schema by the compiler, not here)."
140
+ },
141
+ "retry": {
142
+ "type": "object",
143
+ "description": "Bounded retry on transient failures, keyed on the persisted failure_reason taxonomy.",
144
+ "required": ["max", "on"],
145
+ "additionalProperties": false,
146
+ "properties": {
147
+ "max": {
148
+ "type": "integer",
149
+ "minimum": 0,
150
+ "description": "Maximum retry attempts per unit."
151
+ },
152
+ "on": {
153
+ "type": "array",
154
+ "minItems": 1,
155
+ "items": {
156
+ "$ref": "#/definitions/failureReason"
157
+ }
158
+ }
159
+ }
160
+ },
161
+ "budget": {
162
+ "type": "object",
163
+ "description": "Run-level budget ceilings, enforced by the engine per run (journal-seeded). Hitting a ceiling fails the step hard, regardless of on_error.",
164
+ "additionalProperties": false,
165
+ "properties": {
166
+ "max_tokens": {
167
+ "type": "integer",
168
+ "minimum": 1,
169
+ "description": "Ceiling on total reported token usage across the run (seeded from journaled unit rows)."
170
+ },
171
+ "max_units": {
172
+ "type": "integer",
173
+ "minimum": 1,
174
+ "maximum": 10000,
175
+ "description": "Ceiling on total dispatched units across the run (seeded from journaled unit rows)."
176
+ }
177
+ }
178
+ },
179
+ "defaults": {
180
+ "type": "object",
181
+ "description": "Run-level defaults, overridable per unit.",
182
+ "additionalProperties": false,
183
+ "properties": {
184
+ "engine": {
185
+ "type": "string",
186
+ "minLength": 1
187
+ },
188
+ "model": {
189
+ "type": "string",
190
+ "minLength": 1,
191
+ "description": "Model alias (tier) or exact id; resolved per-harness at dispatch."
192
+ },
193
+ "timeout": {
194
+ "$ref": "#/definitions/timeout"
195
+ },
196
+ "on_error": {
197
+ "$ref": "#/definitions/onError"
198
+ },
199
+ "llm": {
200
+ "$ref": "#/definitions/llm"
201
+ }
202
+ }
203
+ },
204
+ "unit": {
205
+ "type": "object",
206
+ "description": "A single dispatchable unit: instructions plus dispatch overrides.",
207
+ "required": ["instructions"],
208
+ "additionalProperties": false,
209
+ "properties": {
210
+ "engine": {
211
+ "type": "string",
212
+ "minLength": 1,
213
+ "description": "Named engine selected at workflow start."
214
+ },
215
+ "model": {
216
+ "type": "string",
217
+ "minLength": 1
218
+ },
219
+ "llm": {
220
+ "$ref": "#/definitions/llm"
221
+ },
222
+ "timeout": {
223
+ "$ref": "#/definitions/timeout"
224
+ },
225
+ "retry": {
226
+ "$ref": "#/definitions/retry"
227
+ },
228
+ "on_error": {
229
+ "$ref": "#/definitions/onError"
230
+ },
231
+ "instructions": {
232
+ "type": "string",
233
+ "minLength": 1,
234
+ "description": "Instruction template. ${{ … }} expressions are parsed against the closed grammar: params.<name> | steps.<id>.output.<path> | item | item_index."
235
+ },
236
+ "output": {
237
+ "$ref": "#/definitions/jsonSchemaObject"
238
+ },
239
+ "env": {
240
+ "type": "array",
241
+ "items": {
242
+ "type": "string",
243
+ "minLength": 1
244
+ },
245
+ "description": "Env asset refs injected into the dispatched unit env."
246
+ },
247
+ "isolation": {
248
+ "$ref": "#/definitions/isolation"
249
+ }
250
+ }
251
+ },
252
+ "map": {
253
+ "type": "object",
254
+ "description": "Fan the unit template out over an expression-addressed item list.",
255
+ "required": ["over", "unit"],
256
+ "additionalProperties": false,
257
+ "properties": {
258
+ "over": {
259
+ "type": "string",
260
+ "minLength": 1,
261
+ "description": "${{ … }} expression naming the producer of the item list (e.g. ${{ steps.discover.output.files }})."
262
+ },
263
+ "concurrency": {
264
+ "type": "integer",
265
+ "minimum": 1,
266
+ "description": "Max concurrent units for this step; capped by the engine's global limit."
267
+ },
268
+ "reducer": {
269
+ "$ref": "#/definitions/reducer"
270
+ },
271
+ "unit": {
272
+ "$ref": "#/definitions/unit"
273
+ }
274
+ }
275
+ },
276
+ "route": {
277
+ "type": "object",
278
+ "description": "Route on an explicit ${{ … }} input to a LATER step. Targets must come after the routing step.",
279
+ "required": ["input", "when"],
280
+ "additionalProperties": false,
281
+ "properties": {
282
+ "input": {
283
+ "type": "string",
284
+ "minLength": 1,
285
+ "description": "${{ … }} expression naming the value to route on."
286
+ },
287
+ "when": {
288
+ "type": "object",
289
+ "minProperties": 1,
290
+ "maxProperties": 256,
291
+ "description": "Match value -> target step id.",
292
+ "additionalProperties": {
293
+ "$ref": "#/definitions/identifier"
294
+ }
295
+ },
296
+ "default": {
297
+ "$ref": "#/definitions/identifier"
298
+ }
299
+ }
300
+ },
301
+ "gate": {
302
+ "type": "object",
303
+ "description": "Completion gate criteria judged against the step artifact.",
304
+ "required": ["criteria"],
305
+ "additionalProperties": false,
306
+ "properties": {
307
+ "criteria": {
308
+ "type": "array",
309
+ "minItems": 1,
310
+ "items": {
311
+ "type": "string",
312
+ "minLength": 1
313
+ }
314
+ },
315
+ "max_loops": {
316
+ "type": "integer",
317
+ "minimum": 1,
318
+ "description": "Evaluator-optimizer loop bound (execution lands in R2)."
319
+ },
320
+ "required": {
321
+ "type": "boolean",
322
+ "description": "When true, the gate must be judged: if no summary-validation judge is available (offline / misconfigured LLM), the step BLOCKS for a human instead of failing open and silently passing. Absent = fail-open default. The engine's --require-gates flag applies this to every criteria-bearing gate for one invocation."
323
+ }
324
+ }
325
+ },
326
+ "step": {
327
+ "type": "object",
328
+ "description": "One step of the gated spine. Exactly one of unit | map | route.",
329
+ "required": ["id"],
330
+ "additionalProperties": false,
331
+ "properties": {
332
+ "id": {
333
+ "$ref": "#/definitions/identifier"
334
+ },
335
+ "title": {
336
+ "type": "string",
337
+ "minLength": 1
338
+ },
339
+ "unit": {
340
+ "$ref": "#/definitions/unit"
341
+ },
342
+ "map": {
343
+ "$ref": "#/definitions/map"
344
+ },
345
+ "route": {
346
+ "$ref": "#/definitions/route"
347
+ },
348
+ "output": {
349
+ "$ref": "#/definitions/jsonSchemaObject"
350
+ },
351
+ "gate": {
352
+ "$ref": "#/definitions/gate"
353
+ }
354
+ },
355
+ "allOf": [
356
+ {
357
+ "oneOf": [
358
+ {
359
+ "required": ["unit"]
360
+ },
361
+ {
362
+ "required": ["map"]
363
+ },
364
+ {
365
+ "required": ["route"]
366
+ }
367
+ ]
368
+ }
369
+ ]
370
+ }
371
+ }
372
+ }