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,10 +1,10 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "https://itlackey.github.io/akm/schemas/akm-task.json",
4
- "title": "AKM Task v3",
5
- "description": "Strict task-v3 source document. Exactly one executable selector and exactly one scheduling source are required. GitHub action refs are recognized source syntax but are not executed by AKM 0.9.2.",
4
+ "title": "AKM Task source v4",
5
+ "description": "Task source v4: typed inputs:, a single bounded output: schema, and OPTIONAL scheduling — a document with no schedule: is valid, runnable manually, composable, and is skipped (not rejected) by `akm task sync`. The akm: options bag and the on: trigger block from task v3 are gone (their members are top-level); there is no github-action uses: target; with: is legal only alongside uses: akm/command (use inputs: everywhere else for typed parameters), and output: is legal only on a command target (uses: commands/<ref> or uses: akm/command) — the only kinds whose runtime enforces it. task-v2 and task-v3 sources are converted to this schema by `akm migrate apply` — this document publishes only the version: 4 shape a task source parses to today.",
6
6
  "x-akm-runtimeConstraints": {
7
- "authoritativeParser": "src/tasks/source-v3.ts",
7
+ "authoritativeParser": "src/tasks/source/task-source-v4.ts",
8
8
  "maxSourceUtf8Bytes": 1048576,
9
9
  "maxStringUtf8Bytes": 262144,
10
10
  "maxJsonDepth": 64,
@@ -16,17 +16,30 @@
16
16
  "required": ["version"],
17
17
  "additionalProperties": false,
18
18
  "properties": {
19
- "version": { "const": 3 },
19
+ "version": { "const": 4 },
20
20
  "name": { "type": "string", "maxLength": 262144 },
21
+ "description": { "type": "string", "maxLength": 262144 },
22
+ "when_to_use": { "type": "string", "maxLength": 262144 },
23
+ "tags": {
24
+ "type": "array",
25
+ "maxItems": 1024,
26
+ "items": { "type": "string", "minLength": 1, "maxLength": 262144 }
27
+ },
28
+ "inputs": {
29
+ "type": "object",
30
+ "maxProperties": 128,
31
+ "propertyNames": { "$ref": "#/definitions/taskInputName" },
32
+ "additionalProperties": { "$ref": "#/definitions/inputDeclaration" }
33
+ },
34
+ "output": { "$ref": "#/definitions/outputSchemaDefinition" },
21
35
  "uses": {
22
36
  "oneOf": [
23
37
  { "const": "akm/command" },
24
- { "$ref": "#/definitions/akmExecutableRef" },
25
- { "$ref": "#/definitions/githubActionRef" }
38
+ { "$ref": "#/definitions/akmExecutableRef" }
26
39
  ]
27
40
  },
28
41
  "run": { "$ref": "#/definitions/nonemptyLiteral" },
29
- "with": { "$ref": "#/definitions/jsonObject" },
42
+ "with": { "$ref": "#/definitions/builtinCommandWith" },
30
43
  "env": {
31
44
  "type": "object",
32
45
  "maxProperties": 256,
@@ -46,90 +59,53 @@
46
59
  "maxLength": 262144,
47
60
  "pattern": "^(?![\\\\/])(?![A-Za-z]:[\\\\/])(?!.*(?:^|[\\\\/])\\.\\.(?:[\\\\/]|$))(?!.*[\\\\/]{2})(?!.*[\\\\/]$)[^\\u0000]+$"
48
61
  },
49
- "akm": {
50
- "type": "object",
51
- "additionalProperties": false,
52
- "properties": {
53
- "schedule": { "$ref": "#/definitions/nonemptyLiteral" },
54
- "enabled": { "type": "boolean" },
55
- "description": { "type": "string", "maxLength": 262144 },
56
- "when_to_use": { "type": "string", "maxLength": 262144 },
57
- "tags": {
58
- "type": "array",
59
- "maxItems": 1024,
60
- "items": { "type": "string", "minLength": 1, "maxLength": 262144 }
61
- },
62
- "agent": { "$ref": "#/definitions/nullableSelector" },
63
- "engine": { "$ref": "#/definitions/nullableSelector" },
64
- "model": { "$ref": "#/definitions/nullableSelector" },
65
- "inference": {
66
- "oneOf": [
67
- { "$ref": "#/definitions/jsonObject" },
68
- { "type": "null" }
69
- ]
70
- },
71
- "outputSchema": {
72
- "description": "A JSON Schema accepted by AKM's bounded execution-schema subset, or null. Runtime byte, depth, and node limits are declared by x-akm-runtimeConstraints.",
73
- "oneOf": [
74
- { "$ref": "#/definitions/outputSchemaDefinition" },
75
- { "type": "null" }
76
- ]
77
- },
78
- "tools": {
79
- "oneOf": [
80
- { "type": "string", "maxLength": 262144 },
81
- {
82
- "type": "array",
83
- "maxItems": 1024,
84
- "items": { "type": "string", "maxLength": 262144 }
85
- },
86
- { "$ref": "#/definitions/jsonObject" },
87
- { "type": "null" }
88
- ]
89
- },
90
- "timeout": {
91
- "oneOf": [
92
- { "type": "integer", "minimum": 0, "maximum": 2147483647 },
93
- { "type": "string", "pattern": "^\\d+[mMhHdD]$" },
94
- { "type": "null" }
95
- ]
96
- },
97
- "redact": {
98
- "type": "array",
99
- "maxItems": 32,
100
- "uniqueItems": true,
101
- "items": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" }
102
- },
103
- "maxSteps": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
104
- "maxRetries": { "type": "integer", "minimum": 0, "maximum": 100 }
105
- }
106
- },
107
- "on": {
108
- "type": "object",
109
- "minProperties": 1,
110
- "additionalProperties": false,
111
- "properties": {
112
- "schedule": {
62
+ "schedule": {
63
+ "oneOf": [
64
+ { "$ref": "#/definitions/nonemptyLiteral" },
65
+ {
113
66
  "type": "array",
114
67
  "minItems": 1,
115
68
  "maxItems": 64,
116
- "items": {
117
- "type": "object",
118
- "required": ["cron"],
119
- "additionalProperties": false,
120
- "properties": {
121
- "cron": { "$ref": "#/definitions/nonemptyLiteral" }
122
- }
123
- }
124
- },
125
- "workflow_dispatch": {
126
- "oneOf": [
127
- { "type": "null" },
128
- { "type": "object", "maxProperties": 0, "additionalProperties": false }
129
- ]
69
+ "items": { "$ref": "#/definitions/taskSourceV4ScheduleEntry" }
130
70
  }
131
- }
132
- }
71
+ ]
72
+ },
73
+ "agent": { "$ref": "#/definitions/nullableSelector" },
74
+ "engine": { "$ref": "#/definitions/nullableSelector" },
75
+ "model": { "$ref": "#/definitions/nullableSelector" },
76
+ "inference": {
77
+ "oneOf": [
78
+ { "$ref": "#/definitions/jsonObject" },
79
+ { "type": "null" }
80
+ ]
81
+ },
82
+ "tools": {
83
+ "oneOf": [
84
+ { "type": "string", "maxLength": 262144 },
85
+ {
86
+ "type": "array",
87
+ "maxItems": 1024,
88
+ "items": { "type": "string", "maxLength": 262144 }
89
+ },
90
+ { "$ref": "#/definitions/jsonObject" },
91
+ { "type": "null" }
92
+ ]
93
+ },
94
+ "timeout": {
95
+ "oneOf": [
96
+ { "type": "integer", "minimum": 0, "maximum": 2147483647 },
97
+ { "type": "string", "pattern": "^\\d+[mMhHdD]$" },
98
+ { "type": "null" }
99
+ ]
100
+ },
101
+ "redact": {
102
+ "type": "array",
103
+ "maxItems": 32,
104
+ "uniqueItems": true,
105
+ "items": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" }
106
+ },
107
+ "maxSteps": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
108
+ "maxRetries": { "type": "integer", "minimum": 0, "maximum": 100 }
133
109
  },
134
110
  "oneOf": [
135
111
  {
@@ -148,54 +124,37 @@
148
124
  }
149
125
  },
150
126
  {
151
- "description": "A canonical AKM executable ref or GitHub action ref.",
127
+ "description": "A canonical AKM executable ref (commands/, scripts/, or workflows/). No with: here — declare typed parameters with inputs: instead. output: is legal only on the commands/ arm: a scripts/ or workflows/ execution consumes no output schema, so an authored one would be a silently unenforced contract (src/tasks/source/task-source-v4.ts's targetConsumesOutputSchema).",
152
128
  "required": ["uses"],
153
129
  "properties": {
154
- "uses": {
155
- "oneOf": [
156
- { "$ref": "#/definitions/akmExecutableRef" },
157
- { "$ref": "#/definitions/githubActionRef" }
158
- ]
159
- }
130
+ "uses": { "$ref": "#/definitions/akmExecutableRef" }
160
131
  },
161
132
  "not": {
162
133
  "anyOf": [
163
134
  { "required": ["run"] },
135
+ { "required": ["with"] },
164
136
  { "required": ["shell"] },
165
137
  { "required": ["working-directory"] }
166
138
  ]
167
- }
139
+ },
140
+ "if": {
141
+ "required": ["uses"],
142
+ "properties": { "uses": { "$ref": "#/definitions/akmCommandRef" } }
143
+ },
144
+ "else": { "not": { "required": ["output"] } }
168
145
  },
169
146
  {
170
- "description": "One exact host-shell string.",
147
+ "description": "One exact host-shell string. No output: here — a run: execution decides status from its exit code alone and never enforces an output schema.",
171
148
  "required": ["run"],
172
149
  "not": {
173
150
  "anyOf": [
174
151
  { "required": ["uses"] },
175
- { "required": ["with"] }
152
+ { "required": ["with"] },
153
+ { "required": ["output"] }
176
154
  ]
177
155
  }
178
156
  }
179
157
  ],
180
- "allOf": [
181
- {
182
- "description": "Exactly one scheduling source: akm.schedule or on.",
183
- "oneOf": [
184
- {
185
- "required": ["akm"],
186
- "properties": { "akm": { "required": ["schedule"] } },
187
- "not": { "required": ["on"] }
188
- },
189
- {
190
- "required": ["on"],
191
- "not": {
192
- "required": ["akm"],
193
- "properties": { "akm": { "required": ["schedule"] } }
194
- }
195
- }
196
- ]
197
- }
198
- ],
199
158
  "definitions": {
200
159
  "nonemptyLiteral": {
201
160
  "type": "string",
@@ -214,10 +173,106 @@
214
173
  "maxLength": 262144,
215
174
  "pattern": "^(?:[^\\s:.#/]+//)?(?:commands|workflows|scripts)/(?!\\.{1,2}(?:/|$))[^\\s#\\\\/\\u0000]+(?:/(?!\\.{1,2}(?:/|$))[^\\s#\\\\/\\u0000]+)*$"
216
175
  },
217
- "githubActionRef": {
176
+ "akmCommandRef": {
177
+ "description": "The commands/-only subset of akmExecutableRef — the executable-ref kind whose runtime actually consumes output: (the other consumer, uses: akm/command, is a const, not a ref). Same grammar, with the kind alternation narrowed to commands.",
218
178
  "type": "string",
219
179
  "maxLength": 262144,
220
- "pattern": "^(?!(?:commands|workflows|scripts)/)[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?/(?!\\.{1,2}(?:/|@))[A-Za-z0-9_.-]+(?:/(?!\\.{1,2}(?:/|@))[A-Za-z0-9_.-]+)*@(?![./])(?!.*(?:@|\\.\\.|//|/\\.|\\.(?:/|$)|\\.lock(?:/|$)))[^\\s\\u0000-\\u0020\\u007f~^:?*\\[\\\\/](?:[^\\s\\u0000-\\u0020\\u007f~^:?*\\[\\\\@]*[^\\s\\u0000-\\u0020\\u007f~^:?*\\[\\\\/.@])?$"
180
+ "pattern": "^(?:[^\\s:.#/]+//)?commands/(?!\\.{1,2}(?:/|$))[^\\s#\\\\/\\u0000]+(?:/(?!\\.{1,2}(?:/|$))[^\\s#\\\\/\\u0000]+)*$"
181
+ },
182
+ "taskSourceV4ScheduleEntry": {
183
+ "description": "One schedule: list entry (D2-N5: per-entry enabled defaults true; inputs are validated against inputs: at parse time and delivered to the scheduled run's own invocation, P2b).",
184
+ "type": "object",
185
+ "required": ["cron"],
186
+ "additionalProperties": false,
187
+ "properties": {
188
+ "cron": { "$ref": "#/definitions/nonemptyLiteral" },
189
+ "enabled": { "type": "boolean" },
190
+ "inputs": { "$ref": "#/definitions/taskSourceV4ScheduleInputs" }
191
+ }
192
+ },
193
+ "taskSourceV4ScheduleInputs": {
194
+ "description": "schedule[i].inputs literals: keys are closed to the input-name pattern (the same pattern inputs: declarations use), not the free-form jsonObject shape — the runtime parser additionally rejects any key not present in the document's own inputs: declarations, which static JSON Schema cannot cross-reference here.",
195
+ "type": "object",
196
+ "maxProperties": 128,
197
+ "propertyNames": { "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
198
+ "additionalProperties": { "$ref": "#/definitions/jsonValue" }
199
+ },
200
+ "taskInputName": {
201
+ "description": "One `inputs:` declaration key. Matches the identifier pattern AND excludes every name `akm task run` reserves for its own flags (src/tasks/task-run-reserved-flags.ts's TASK_RUN_RESERVED_FLAG_NAMES — the union of TASK_RUN_VALUE_FLAGS, TASK_RUN_BOOLEAN_FLAGS, and TASK_RUN_SELF_DIAGNOSED_FLAGS) — declaring an input under one of these names is rejected at parse time (TASK_SOURCE_INVALID, parseInputDeclarations) because the CLI would always treat the flag as its own, never as this input's. `no-quiet`/`no-verbose` are citty's negations of the `quiet`/`verbose` booleans and are listed for completeness even though the identifier pattern already excludes any hyphenated name.",
202
+ "type": "string",
203
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
204
+ "not": {
205
+ "enum": [
206
+ "bundle",
207
+ "format",
208
+ "detail",
209
+ "shape",
210
+ "output",
211
+ "scheduled",
212
+ "quiet",
213
+ "verbose",
214
+ "help",
215
+ "no-quiet",
216
+ "no-verbose",
217
+ "target"
218
+ ]
219
+ }
220
+ },
221
+ "inputDeclaration": {
222
+ "description": "One inputs: declaration: a bounded JSON Schema. At the declaration ROOT, required is task source v4's own boolean flag, not JSON Schema's required array; default must itself satisfy the remaining schema; default + required:true together is invalid (D2-N3). Nested schemas (properties/items/allOf/anyOf/oneOf/not) keep ordinary JSON-Schema meaning via outputSchemaDefinition. Closed to exactly this key set — an unlisted keyword (e.g. pattern) is rejected here even though the runtime subset accepts it inside output:, because a task input declaration is intentionally narrower.",
223
+ "type": "object",
224
+ "additionalProperties": false,
225
+ "properties": {
226
+ "type": {
227
+ "oneOf": [
228
+ { "$ref": "#/definitions/outputSchemaTypeName" },
229
+ {
230
+ "type": "array",
231
+ "minItems": 1,
232
+ "maxItems": 1024,
233
+ "items": { "$ref": "#/definitions/outputSchemaTypeName" }
234
+ }
235
+ ]
236
+ },
237
+ "enum": {
238
+ "type": "array",
239
+ "minItems": 1,
240
+ "maxItems": 1024,
241
+ "items": {
242
+ "oneOf": [
243
+ { "type": "string", "maxLength": 262144 },
244
+ { "type": "number" },
245
+ { "type": "boolean" },
246
+ { "type": "null" }
247
+ ]
248
+ }
249
+ },
250
+ "properties": {
251
+ "type": "object",
252
+ "maxProperties": 256,
253
+ "propertyNames": { "maxLength": 262144 },
254
+ "additionalProperties": { "$ref": "#/definitions/outputSchemaDefinition" }
255
+ },
256
+ "required": {
257
+ "description": "Declaration-ROOT required is task source v4's own boolean flag, not a JSON-Schema required array (D2-N3).",
258
+ "type": "boolean"
259
+ },
260
+ "items": { "$ref": "#/definitions/outputSchemaDefinition" },
261
+ "additionalProperties": { "type": "boolean" },
262
+ "minItems": { "type": "integer", "minimum": 0 },
263
+ "maxItems": { "type": "integer", "minimum": 0 },
264
+ "minLength": { "type": "integer", "minimum": 0 },
265
+ "maxLength": { "type": "integer", "minimum": 0 },
266
+ "minimum": { "type": "number" },
267
+ "maximum": { "type": "number" },
268
+ "allOf": { "$ref": "#/definitions/outputSchemaArray" },
269
+ "anyOf": { "$ref": "#/definitions/outputSchemaArray" },
270
+ "oneOf": { "$ref": "#/definitions/outputSchemaArray" },
271
+ "not": { "$ref": "#/definitions/outputSchemaDefinition" },
272
+ "title": { "type": "string", "maxLength": 262144 },
273
+ "description": { "type": "string", "maxLength": 262144 },
274
+ "default": { "$ref": "#/definitions/jsonValue" }
275
+ }
221
276
  },
222
277
  "outputSchemaDefinition": {
223
278
  "type": "object",
@@ -21,6 +21,7 @@
21
21
  "stale_after": { "$ref": "akm-asset-envelope.json#/definitions/stale_after" },
22
22
  "params": {
23
23
  "type": "object",
24
+ "minProperties": 1,
24
25
  "maxProperties": 128,
25
26
  "description": "Run parameters: param name -> JSON Schema declaration. Names must be params.<name>-addressable identifiers.",
26
27
  "propertyNames": {
@@ -30,6 +31,18 @@
30
31
  "$ref": "#/definitions/jsonSchemaObject"
31
32
  }
32
33
  },
34
+ "outputs": {
35
+ "type": "object",
36
+ "minProperties": 1,
37
+ "maxProperties": 64,
38
+ "description": "Named, optionally schema-validated projections of step artifacts, exported when the run completes. Names must be steps.<child>.output.<name>-addressable identifiers. Each entry: { from: steps.<id>.output(.<seg>)*, schema?: <bounded JSON Schema> }. Markdown-frontmatter only.",
39
+ "propertyNames": {
40
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
41
+ },
42
+ "additionalProperties": {
43
+ "$ref": "#/definitions/outputDeclaration"
44
+ }
45
+ },
33
46
  "defaults": {
34
47
  "$ref": "#/definitions/defaults"
35
48
  },
@@ -151,6 +164,21 @@
151
164
  "type": "object",
152
165
  "description": "A JSON Schema declaration. The parser validates it as a schema definition against the runtime's enforced subset (src/core/json-schema.ts checkJsonSchemaDefinition): typo'd type names and keywords outside the subset (e.g. $ref, const, format, patternProperties) are authoring-time errors, not silent no-ops."
153
166
  },
167
+ "outputDeclaration": {
168
+ "type": "object",
169
+ "description": "One outputs: entry: a validated steps.<id>.output(.<seg>)* reference into a step artifact, plus an optional bounded JSON Schema.",
170
+ "required": ["from"],
171
+ "additionalProperties": false,
172
+ "properties": {
173
+ "from": {
174
+ "type": "string",
175
+ "description": "A steps.<id>.output(.<seg>)* reference into a step artifact. Never params.<name> — an output projects a step artifact, never a param."
176
+ },
177
+ "schema": {
178
+ "$ref": "#/definitions/jsonSchemaObject"
179
+ }
180
+ }
181
+ },
154
182
  "retry": {
155
183
  "type": "object",
156
184
  "description": "Bounded retry on transient failures, keyed on the persisted failure_reason taxonomy.",