@frankzhang2026/opencode-android-orchestrator 0.9.0 → 1.0.0

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 (127) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +92 -55
  3. package/dist/cli.js +14 -1
  4. package/dist/cli.js.map +1 -1
  5. package/dist/config/android-sdk.d.ts +10 -0
  6. package/dist/config/android-sdk.d.ts.map +1 -0
  7. package/dist/config/android-sdk.js +50 -0
  8. package/dist/config/android-sdk.js.map +1 -0
  9. package/dist/config/commit-message-prefix.d.ts +31 -0
  10. package/dist/config/commit-message-prefix.d.ts.map +1 -0
  11. package/dist/config/commit-message-prefix.js +155 -0
  12. package/dist/config/commit-message-prefix.js.map +1 -0
  13. package/dist/config/queue-policy.d.ts +12 -0
  14. package/dist/config/queue-policy.d.ts.map +1 -0
  15. package/dist/config/queue-policy.js +18 -0
  16. package/dist/config/queue-policy.js.map +1 -0
  17. package/dist/config/verification-policy.d.ts +10 -3
  18. package/dist/config/verification-policy.d.ts.map +1 -1
  19. package/dist/config/verification-policy.js +66 -13
  20. package/dist/config/verification-policy.js.map +1 -1
  21. package/dist/doctor/index.d.ts.map +1 -1
  22. package/dist/doctor/index.js +3 -49
  23. package/dist/doctor/index.js.map +1 -1
  24. package/dist/doctor/installation.d.ts.map +1 -1
  25. package/dist/doctor/installation.js +81 -0
  26. package/dist/doctor/installation.js.map +1 -1
  27. package/dist/index.d.ts +1 -0
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +1 -0
  30. package/dist/index.js.map +1 -1
  31. package/dist/installer/adaptive-templates.d.ts +8 -2
  32. package/dist/installer/adaptive-templates.d.ts.map +1 -1
  33. package/dist/installer/adaptive-templates.js +10 -0
  34. package/dist/installer/adaptive-templates.js.map +1 -1
  35. package/dist/installer/index.d.ts +1 -0
  36. package/dist/installer/index.d.ts.map +1 -1
  37. package/dist/installer/index.js +1 -0
  38. package/dist/installer/index.js.map +1 -1
  39. package/dist/installer/init.d.ts +4 -1
  40. package/dist/installer/init.d.ts.map +1 -1
  41. package/dist/installer/init.js +60 -9
  42. package/dist/installer/init.js.map +1 -1
  43. package/dist/installer/install-manifest.d.ts +1 -0
  44. package/dist/installer/install-manifest.d.ts.map +1 -1
  45. package/dist/installer/install-manifest.js +6 -1
  46. package/dist/installer/install-manifest.js.map +1 -1
  47. package/dist/installer/opencode-config.d.ts +3 -3
  48. package/dist/installer/opencode-config.js +1 -1
  49. package/dist/installer/uninstall.d.ts.map +1 -1
  50. package/dist/installer/uninstall.js +5 -0
  51. package/dist/installer/uninstall.js.map +1 -1
  52. package/dist/installer/upgrade.d.ts +5 -1
  53. package/dist/installer/upgrade.d.ts.map +1 -1
  54. package/dist/installer/upgrade.js +94 -11
  55. package/dist/installer/upgrade.js.map +1 -1
  56. package/dist/plugin/index.d.ts.map +1 -1
  57. package/dist/plugin/index.js +11 -5
  58. package/dist/plugin/index.js.map +1 -1
  59. package/dist/queue/approvals.d.ts +49 -0
  60. package/dist/queue/approvals.d.ts.map +1 -0
  61. package/dist/queue/approvals.js +68 -0
  62. package/dist/queue/approvals.js.map +1 -0
  63. package/dist/queue/cli.d.ts +3 -0
  64. package/dist/queue/cli.d.ts.map +1 -0
  65. package/dist/queue/cli.js +109 -0
  66. package/dist/queue/cli.js.map +1 -0
  67. package/dist/queue/executor.d.ts +24 -0
  68. package/dist/queue/executor.d.ts.map +1 -0
  69. package/dist/queue/executor.js +445 -0
  70. package/dist/queue/executor.js.map +1 -0
  71. package/dist/queue/lifecycle.d.ts +3 -0
  72. package/dist/queue/lifecycle.d.ts.map +1 -0
  73. package/dist/queue/lifecycle.js +24 -0
  74. package/dist/queue/lifecycle.js.map +1 -0
  75. package/dist/queue/queue.d.ts +154 -0
  76. package/dist/queue/queue.d.ts.map +1 -0
  77. package/dist/queue/queue.js +411 -0
  78. package/dist/queue/queue.js.map +1 -0
  79. package/dist/queue/service.d.ts +15 -0
  80. package/dist/queue/service.d.ts.map +1 -0
  81. package/dist/queue/service.js +152 -0
  82. package/dist/queue/service.js.map +1 -0
  83. package/dist/queue/storage.d.ts +30 -0
  84. package/dist/queue/storage.d.ts.map +1 -0
  85. package/dist/queue/storage.js +171 -0
  86. package/dist/queue/storage.js.map +1 -0
  87. package/dist/queue/tools.d.ts +12 -0
  88. package/dist/queue/tools.d.ts.map +1 -0
  89. package/dist/queue/tools.js +144 -0
  90. package/dist/queue/tools.js.map +1 -0
  91. package/docs/MIGRATION.md +47 -14
  92. package/docs/QUEUE.md +146 -0
  93. package/docs/SECURITY.md +48 -32
  94. package/docs/TROUBLESHOOTING.md +36 -11
  95. package/package.json +1 -1
  96. package/templates/.opencode/agents/scheduled-planner.md +60 -131
  97. package/templates/.opencode/commands/abort-task.md +6 -15
  98. package/templates/.opencode/commands/acceptance.md +6 -15
  99. package/templates/.opencode/commands/change.md +3 -1
  100. package/templates/.opencode/commands/resume-review.md +6 -14
  101. package/templates/.opencode/commands/resume-task.md +6 -23
  102. package/templates/.opencode/skills/scheduled-quality-orchestrator/SKILL.md +69 -248
  103. package/templates/AGENTS.md.fragment +8 -0
  104. package/templates/README.md +9 -1
  105. package/templates/automation/config.json +9 -2
  106. package/templates/automation/config.schema.json +222 -45
  107. package/templates/scripts/automation/abort-task.sh +4 -2
  108. package/templates/scripts/automation/accept-and-integrate.sh +9 -2
  109. package/templates/scripts/automation/acceptance-report.sh +4 -2
  110. package/templates/scripts/automation/approve-and-run.sh +5 -0
  111. package/templates/scripts/automation/begin-review.sh +1 -0
  112. package/templates/scripts/automation/block-task.sh +1 -0
  113. package/templates/scripts/automation/claim-task.sh +1 -0
  114. package/templates/scripts/automation/lib.sh +186 -2
  115. package/templates/scripts/automation/orchestrate-task.sh +12 -0
  116. package/templates/scripts/automation/preflight.sh +25 -4
  117. package/templates/scripts/automation/prepare-contract-review.sh +4 -0
  118. package/templates/scripts/automation/quality-gate.sh +1 -0
  119. package/templates/scripts/automation/record-red.sh +1 -0
  120. package/templates/scripts/automation/resume-review-fix.sh +1 -0
  121. package/templates/scripts/automation/resume-review.sh +1 -0
  122. package/templates/scripts/automation/resume-task.sh +1 -0
  123. package/templates/scripts/automation/scope-gate.sh +10 -2
  124. package/templates/scripts/automation/show-acceptance-review.sh +3 -0
  125. package/templates/scripts/automation/submit-review.sh +8 -2
  126. package/templates/scripts/automation/tests/run-tests.sh +59 -4
  127. package/templates/scripts/automation/verify-task.sh +13 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "urn:frankzhang2026:opencode-android-orchestrator:automation-config:v4",
3
+ "$id": "urn:frankzhang2026:opencode-android-orchestrator:automation-config:v6",
4
4
  "title": "OpenCode task orchestration configuration",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
@@ -11,7 +11,10 @@
11
11
  "pattern": "^(?!/)(?!\\.\\.(?:/|$))(?![A-Za-z]:[\\\\/]).+"
12
12
  },
13
13
  "nullableIdentifier": {
14
- "type": ["string", "null"],
14
+ "type": [
15
+ "string",
16
+ "null"
17
+ ],
15
18
  "minLength": 1
16
19
  },
17
20
  "gradleTask": {
@@ -23,7 +26,9 @@
23
26
  "type": "array",
24
27
  "minItems": 1,
25
28
  "uniqueItems": true,
26
- "items": { "$ref": "#/$defs/gradleTask" }
29
+ "items": {
30
+ "$ref": "#/$defs/gradleTask"
31
+ }
27
32
  }
28
33
  },
29
34
  "required": [
@@ -38,6 +43,7 @@
38
43
  "maxReviewerRestarts",
39
44
  "unitTestsEnabled",
40
45
  "lintEnabled",
46
+ "commitMessagePrefixMode",
41
47
  "longCommandTimeoutMs",
42
48
  "autoCleanupWorktrees",
43
49
  "pushAfterAcceptance",
@@ -45,46 +51,117 @@
45
51
  "requiredSkills",
46
52
  "gradleVerification",
47
53
  "androidProject",
48
- "protectedPaths"
54
+ "protectedPaths",
55
+ "commitPolicy",
56
+ "queue"
49
57
  ],
50
58
  "properties": {
51
- "schemaVersion": { "const": 4 },
52
- "enabled": { "type": "boolean" },
53
- "mode": { "enum": ["shadow", "orchestrated"] },
59
+ "schemaVersion": {
60
+ "const": 6
61
+ },
62
+ "enabled": {
63
+ "type": "boolean"
64
+ },
65
+ "mode": {
66
+ "enum": [
67
+ "shadow",
68
+ "orchestrated"
69
+ ]
70
+ },
54
71
  "workspaceStrategy": {
55
- "enum": ["inPlaceExclusive", "isolatedWorktree"]
56
- },
57
- "originalBranchDriftPolicy": { "const": "block" },
58
- "worktreeBase": { "type": "string" },
59
- "maxFixLoops": { "type": "integer", "minimum": 0, "maximum": 1 },
60
- "maxReviewCycles": { "type": "integer", "minimum": 0, "maximum": 2 },
61
- "maxReviewerRestarts": { "type": "integer", "minimum": 0, "maximum": 3 },
62
- "unitTestsEnabled": { "type": "boolean", "default": true },
63
- "lintEnabled": { "type": "boolean", "default": false },
72
+ "enum": [
73
+ "inPlaceExclusive",
74
+ "isolatedWorktree"
75
+ ]
76
+ },
77
+ "originalBranchDriftPolicy": {
78
+ "const": "block"
79
+ },
80
+ "worktreeBase": {
81
+ "type": "string"
82
+ },
83
+ "maxFixLoops": {
84
+ "type": "integer",
85
+ "minimum": 0,
86
+ "maximum": 1
87
+ },
88
+ "maxReviewCycles": {
89
+ "type": "integer",
90
+ "minimum": 0,
91
+ "maximum": 2
92
+ },
93
+ "maxReviewerRestarts": {
94
+ "type": "integer",
95
+ "minimum": 0,
96
+ "maximum": 3
97
+ },
98
+ "unitTestsEnabled": {
99
+ "type": "boolean",
100
+ "default": true
101
+ },
102
+ "lintEnabled": {
103
+ "type": "boolean",
104
+ "default": false
105
+ },
106
+ "commitMessagePrefixMode": {
107
+ "enum": [
108
+ "required",
109
+ "disabled"
110
+ ],
111
+ "default": "required"
112
+ },
64
113
  "longCommandTimeoutMs": {
65
114
  "type": "integer",
66
115
  "minimum": 120000,
67
116
  "maximum": 7200000
68
117
  },
69
- "autoCleanupWorktrees": { "type": "boolean" },
70
- "pushAfterAcceptance": { "const": false },
118
+ "autoCleanupWorktrees": {
119
+ "type": "boolean"
120
+ },
121
+ "pushAfterAcceptance": {
122
+ "const": false
123
+ },
71
124
  "approvalPhrases": {
72
125
  "type": "object",
73
126
  "additionalProperties": false,
74
- "required": ["proposal", "contract", "acceptance", "abort", "resume"],
127
+ "required": [
128
+ "proposal",
129
+ "contract",
130
+ "acceptance",
131
+ "abort",
132
+ "resume"
133
+ ],
75
134
  "properties": {
76
- "proposal": { "type": "string", "minLength": 4 },
77
- "contract": { "type": "string", "minLength": 4 },
78
- "acceptance": { "type": "string", "minLength": 4 },
79
- "abort": { "type": "string", "minLength": 4 },
80
- "resume": { "type": "string", "minLength": 4 }
135
+ "proposal": {
136
+ "type": "string",
137
+ "minLength": 4
138
+ },
139
+ "contract": {
140
+ "type": "string",
141
+ "minLength": 4
142
+ },
143
+ "acceptance": {
144
+ "type": "string",
145
+ "minLength": 4
146
+ },
147
+ "abort": {
148
+ "type": "string",
149
+ "minLength": 4
150
+ },
151
+ "resume": {
152
+ "type": "string",
153
+ "minLength": 4
154
+ }
81
155
  }
82
156
  },
83
157
  "requiredSkills": {
84
158
  "type": "array",
85
159
  "minItems": 6,
86
160
  "uniqueItems": true,
87
- "items": { "type": "string", "minLength": 1 }
161
+ "items": {
162
+ "type": "string",
163
+ "minLength": 1
164
+ }
88
165
  },
89
166
  "gradleVerification": {
90
167
  "type": "object",
@@ -97,11 +174,21 @@
97
174
  "deviceTestTasks"
98
175
  ],
99
176
  "properties": {
100
- "fullUnitTestTasks": { "$ref": "#/$defs/gradleTaskList" },
101
- "focusedTestTasks": { "$ref": "#/$defs/gradleTaskList" },
102
- "assembleTasks": { "$ref": "#/$defs/gradleTaskList" },
103
- "lintTasks": { "$ref": "#/$defs/gradleTaskList" },
104
- "deviceTestTasks": { "$ref": "#/$defs/gradleTaskList" }
177
+ "fullUnitTestTasks": {
178
+ "$ref": "#/$defs/gradleTaskList"
179
+ },
180
+ "focusedTestTasks": {
181
+ "$ref": "#/$defs/gradleTaskList"
182
+ },
183
+ "assembleTasks": {
184
+ "$ref": "#/$defs/gradleTaskList"
185
+ },
186
+ "lintTasks": {
187
+ "$ref": "#/$defs/gradleTaskList"
188
+ },
189
+ "deviceTestTasks": {
190
+ "$ref": "#/$defs/gradleTaskList"
191
+ }
105
192
  }
106
193
  },
107
194
  "androidProject": {
@@ -117,10 +204,26 @@
117
204
  "testPaths"
118
205
  ],
119
206
  "properties": {
120
- "name": { "type": "string", "minLength": 1 },
121
- "gradleDsl": { "enum": ["kotlin", "groovy", "mixed"] },
122
- "settingsFile": { "$ref": "#/$defs/repositoryPath" },
123
- "moduleScope": { "enum": ["all", "primary"] },
207
+ "name": {
208
+ "type": "string",
209
+ "minLength": 1
210
+ },
211
+ "gradleDsl": {
212
+ "enum": [
213
+ "kotlin",
214
+ "groovy",
215
+ "mixed"
216
+ ]
217
+ },
218
+ "settingsFile": {
219
+ "$ref": "#/$defs/repositoryPath"
220
+ },
221
+ "moduleScope": {
222
+ "enum": [
223
+ "all",
224
+ "primary"
225
+ ]
226
+ },
124
227
  "primaryModule": {
125
228
  "type": "string",
126
229
  "pattern": "^:(?:[A-Za-z0-9_.-]+(?::[A-Za-z0-9_.-]+)*)?$"
@@ -145,9 +248,18 @@
145
248
  "type": "string",
146
249
  "pattern": "^:(?:[A-Za-z0-9_.-]+(?::[A-Za-z0-9_.-]+)*)?$"
147
250
  },
148
- "directory": { "$ref": "#/$defs/repositoryPath" },
149
- "buildFile": { "$ref": "#/$defs/repositoryPath" },
150
- "dsl": { "enum": ["kotlin", "groovy"] },
251
+ "directory": {
252
+ "$ref": "#/$defs/repositoryPath"
253
+ },
254
+ "buildFile": {
255
+ "$ref": "#/$defs/repositoryPath"
256
+ },
257
+ "dsl": {
258
+ "enum": [
259
+ "kotlin",
260
+ "groovy"
261
+ ]
262
+ },
151
263
  "type": {
152
264
  "enum": [
153
265
  "application",
@@ -157,8 +269,12 @@
157
269
  "asset-pack"
158
270
  ]
159
271
  },
160
- "namespace": { "$ref": "#/$defs/nullableIdentifier" },
161
- "applicationId": { "$ref": "#/$defs/nullableIdentifier" }
272
+ "namespace": {
273
+ "$ref": "#/$defs/nullableIdentifier"
274
+ },
275
+ "applicationId": {
276
+ "$ref": "#/$defs/nullableIdentifier"
277
+ }
162
278
  }
163
279
  }
164
280
  },
@@ -168,8 +284,12 @@
168
284
  "uniqueItems": true,
169
285
  "items": {
170
286
  "allOf": [
171
- { "$ref": "#/$defs/repositoryPath" },
172
- { "pattern": "(^|/)src/main/\\*\\*$" }
287
+ {
288
+ "$ref": "#/$defs/repositoryPath"
289
+ },
290
+ {
291
+ "pattern": "(^|/)src/main/\\*\\*$"
292
+ }
173
293
  ]
174
294
  }
175
295
  },
@@ -179,8 +299,12 @@
179
299
  "uniqueItems": true,
180
300
  "items": {
181
301
  "allOf": [
182
- { "$ref": "#/$defs/repositoryPath" },
183
- { "pattern": "(^|/)src/(?:test|androidTest)/\\*\\*$" }
302
+ {
303
+ "$ref": "#/$defs/repositoryPath"
304
+ },
305
+ {
306
+ "pattern": "(^|/)src/(?:test|androidTest)/\\*\\*$"
307
+ }
184
308
  ]
185
309
  }
186
310
  }
@@ -190,7 +314,60 @@
190
314
  "type": "array",
191
315
  "minItems": 1,
192
316
  "uniqueItems": true,
193
- "items": { "$ref": "#/$defs/repositoryPath" }
317
+ "items": {
318
+ "$ref": "#/$defs/repositoryPath"
319
+ }
320
+ },
321
+ "commitPolicy": {
322
+ "enum": [
323
+ "humanApproval",
324
+ "autoCommit"
325
+ ],
326
+ "default": "humanApproval"
327
+ },
328
+ "queue": {
329
+ "type": "object",
330
+ "additionalProperties": false,
331
+ "required": [
332
+ "scanIntervalMs",
333
+ "maxWorkspaces",
334
+ "maxWorkspaceBytes"
335
+ ],
336
+ "properties": {
337
+ "scanIntervalMs": {
338
+ "type": "integer",
339
+ "minimum": 1000,
340
+ "maximum": 60000
341
+ },
342
+ "maxWorkspaces": {
343
+ "type": "integer",
344
+ "minimum": 1,
345
+ "maximum": 32
346
+ },
347
+ "maxWorkspaceBytes": {
348
+ "type": "integer",
349
+ "minimum": 1,
350
+ "default": 21474836480
351
+ }
352
+ }
353
+ }
354
+ },
355
+ "allOf": [
356
+ {
357
+ "if": {
358
+ "properties": {
359
+ "workspaceStrategy": {
360
+ "const": "isolatedWorktree"
361
+ }
362
+ }
363
+ },
364
+ "then": {
365
+ "properties": {
366
+ "commitPolicy": {
367
+ "const": "humanApproval"
368
+ }
369
+ }
370
+ }
194
371
  }
195
- }
372
+ ]
196
373
  }
@@ -13,12 +13,13 @@ if [[ "$#" -ne 2 ]]; then
13
13
  fi
14
14
 
15
15
  automation_validate_task_id "$task_id"
16
+ automation_require_queue_execution "$task_id"
16
17
  automation_require_orchestrated
17
18
  automation_require_approval abort "$approval"
18
19
 
19
20
  current_state="$(automation_read_state "$task_id")"
20
21
  case "$current_state" in
21
- PREPARING|PENDING|CODING|READY_FOR_REVIEW|REVIEWING|CHANGES_REQUESTED|AWAITING_HUMAN|BLOCKED|TEST_FAILED|NEEDS_HUMAN|INTEGRATION_BLOCKED) ;;
22
+ PREPARING|PENDING|CODING|READY_FOR_REVIEW|REVIEWING|CHANGES_REQUESTED|AWAITING_HUMAN|READY_TO_COMMIT|BLOCKED|TEST_FAILED|NEEDS_HUMAN|INTEGRATION_BLOCKED) ;;
22
23
  *) automation_die "cannot abort $task_id from state $current_state" ;;
23
24
  esac
24
25
 
@@ -86,8 +87,9 @@ if [[ -d "$task_root" ]]; then
86
87
  fi
87
88
  done
88
89
  if [[ "$product_path_count" -gt 0 ]]; then
90
+ commit_message="$(automation_commit_message_at "$source_root" "Archive aborted work for $task_id")"
89
91
  git -C "$task_root" add -- "${changed_paths[@]}"
90
- git -C "$task_root" commit --only -m "Archive aborted work for $task_id" -- "${changed_paths[@]}"
92
+ git -C "$task_root" commit --only -m "$commit_message" -- "${changed_paths[@]}"
91
93
  recovery_commit="$(git -C "$task_root" rev-parse HEAD)"
92
94
  else
93
95
  plan_rel="$(jq -er '.planPath' "$origin_file")"
@@ -14,6 +14,11 @@ fi
14
14
 
15
15
  automation_validate_task_id "$task_id"
16
16
  automation_require_orchestrated
17
+ queued_workspace="$(automation_workspace_path "$task_id")"
18
+ if [[ -f "$queued_workspace" && -n "$(jq -r '.queueKey // empty' "$queued_workspace")" ]]; then
19
+ automation_die "queued acceptance must request integration through the repository queue"
20
+ exit 1
21
+ fi
17
22
  automation_require_approval acceptance "$approval"
18
23
  [[ "$(automation_read_state "$task_id")" == "AWAITING_HUMAN" ]] || automation_die "$task_id is not awaiting human acceptance"
19
24
  [[ "$(automation_config_value '.pushAfterAcceptance')" == "false" ]] || automation_die "automatic push is forbidden"
@@ -74,6 +79,7 @@ sealed_diff_sha="$(automation_worktree_diff_sha "$task_root")"
74
79
  )
75
80
  report_file="$evidence_dir/acceptance-report.json"
76
81
  [[ "$(jq -er '.sealedDiffSha256' "$report_file")" == "$sealed_diff_sha" ]] || automation_die "acceptance report is stale"
82
+ automation_read_commit_message_prefix_at "$source_root" >/dev/null
77
83
 
78
84
  automation_acquire_run_lock "$task_id"
79
85
  integration_complete=0
@@ -132,9 +138,10 @@ while IFS= read -r path; do
132
138
  [[ -n "$path" ]] && commit_paths+=("$path")
133
139
  done < <(automation_changed_paths_at "$task_root")
134
140
  [[ "${#commit_paths[@]}" -ge 3 ]] || automation_die "final commit must contain product changes and both planning artifacts"
135
- git -C "$task_root" add -- "${commit_paths[@]}"
136
141
  title="$(jq -er '.title' "$task_root/automation/tasks/$task_id.json")"
137
- git -C "$task_root" commit --only -m "Implement $title ($task_id)" -- "${commit_paths[@]}"
142
+ commit_message="$(automation_commit_message_at "$source_root" "Implement $title ($task_id)")"
143
+ git -C "$task_root" add -- "${commit_paths[@]}"
144
+ git -C "$task_root" commit --only -m "$commit_message" -- "${commit_paths[@]}"
138
145
  product_commit="$(git -C "$task_root" rev-parse HEAD)"
139
146
  automation_worktree_is_clean "$task_root" || automation_die "task root is dirty after the combined task commit"
140
147
  git -C "$task_root" merge-base --is-ancestor "$baseline_head" "$product_commit" || automation_die "combined task commit is not based on the recorded pre-task baseline"
@@ -8,7 +8,8 @@ source "$SCRIPT_DIR/lib.sh"
8
8
  task_id="${1:-}"
9
9
  [[ "$#" -eq 1 ]] || { printf 'Usage: %s TASK-ID\n' "$0" >&2; exit 2; }
10
10
  automation_validate_task_id "$task_id"
11
- [[ "$(automation_read_state "$task_id")" == "AWAITING_HUMAN" ]] || automation_die "$task_id is not AWAITING_HUMAN"
11
+ report_state="$(automation_read_state "$task_id")"
12
+ [[ "$report_state" == "AWAITING_HUMAN" || ( "$report_state" == "READY_TO_COMMIT" && -n "${AUTOMATION_QUEUE_RUN_ID:-}" ) ]] || automation_die "$task_id is not ready for acceptance or authorized local commit"
12
13
 
13
14
  contract="$(automation_contract_path "$task_id")"
14
15
  workspace_file="$(automation_workspace_path "$task_id")"
@@ -60,6 +61,7 @@ automation_worktree_patch_at "$AUTOMATION_ROOT" > "$sealed_diff"
60
61
  report_file="$evidence_dir/acceptance-report.json"
61
62
  jq -n \
62
63
  --arg taskId "$task_id" \
64
+ --arg state "$report_state" \
63
65
  --arg title "$(jq -er '.title' "$contract")" \
64
66
  --arg generatedAt "$(automation_now)" \
65
67
  --arg originalBranch "$original_branch" \
@@ -88,7 +90,7 @@ jq -n \
88
90
  --argjson acceptanceCriteria "$(jq -c '.acceptanceCriteria' "$contract")" \
89
91
  --argjson nonGoals "$(jq -c '.nonGoals' "$contract")" \
90
92
  --argjson targetTests "$(jq -c '.targetTests' "$contract")" \
91
- '{taskId: $taskId, title: $title, state: "AWAITING_HUMAN",
93
+ '{taskId: $taskId, title: $title, state: $state,
92
94
  generatedAt: $generatedAt, originalBranch: $originalBranch,
93
95
  originalHeadBeforeContract: $originalHeadBeforeContract,
94
96
  baselineHead: $baselineHead, originalHeadCurrent: $originalHeadCurrent,
@@ -14,6 +14,10 @@ fi
14
14
 
15
15
  automation_validate_task_id "$task_id"
16
16
  automation_require_orchestrated
17
+ [[ "$(automation_config_value '.schemaVersion')" != "6" ]] || {
18
+ automation_die "contract approval now enqueues through android_orchestrator_intake or the queue enqueue CLI"
19
+ exit 1
20
+ }
17
21
  automation_require_approval contract "$approval"
18
22
  "$SCRIPT_DIR/validate-contract.sh" "$task_id" >/dev/null
19
23
  [[ "$(automation_read_state "$task_id")" == "CONTRACT_REVIEW" ]] || automation_die "$task_id is not awaiting contract review"
@@ -33,6 +37,7 @@ plan="$source_root/$plan_rel"
33
37
  [[ "$(git -C "$source_root" rev-parse HEAD)" == "$original_head" ]] || automation_die "original HEAD changed after contract review began"
34
38
  [[ "$(automation_file_sha256 "$contract")" == "$(jq -er '.contractSha256' "$origin_file")" ]] || automation_die "contract changed after proposal approval"
35
39
  [[ "$(automation_file_sha256 "$plan")" == "$(jq -er '.planSha256' "$origin_file")" ]] || automation_die "plan changed after proposal approval"
40
+ automation_read_commit_message_prefix_at "$source_root" >/dev/null
36
41
 
37
42
  changed_paths=()
38
43
  while IFS= read -r path; do
@@ -8,6 +8,7 @@ source "$SCRIPT_DIR/lib.sh"
8
8
  task_id="${1:-}"
9
9
  [[ "$#" -eq 1 ]] || { printf 'Usage: %s TASK-ID\n' "$0" >&2; exit 2; }
10
10
  automation_validate_task_id "$task_id"
11
+ automation_require_queue_execution "$task_id"
11
12
  [[ "$(automation_read_state "$task_id")" == "READY_FOR_REVIEW" ]] || automation_die "$task_id is not READY_FOR_REVIEW"
12
13
 
13
14
  ready_file="$(automation_evidence_path "$task_id")/ready.json"
@@ -15,6 +15,7 @@ if [[ -z "$task_id" || ${#reason} -lt 12 ]]; then
15
15
  fi
16
16
 
17
17
  automation_validate_task_id "$task_id"
18
+ automation_require_queue_execution "$task_id"
18
19
  current="$(automation_read_state "$task_id")"
19
20
  case "$current" in
20
21
  PENDING|CODING)
@@ -8,6 +8,7 @@ source "$SCRIPT_DIR/lib.sh"
8
8
  task_id="${1:-}"
9
9
  [[ -n "$task_id" ]] || { printf 'Usage: %s TASK-ID\n' "$0" >&2; exit 2; }
10
10
  automation_validate_task_id "$task_id"
11
+ automation_require_queue_execution "$task_id"
11
12
  automation_require_layout
12
13
 
13
14
  [[ "$(automation_read_state "$task_id")" == "PENDING" ]] || automation_die "$task_id is not PENDING"