@frankzhang2026/opencode-android-orchestrator 1.0.4 → 1.1.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 (107) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/README.md +79 -18
  3. package/dist/config/queue-policy.d.ts.map +1 -1
  4. package/dist/config/queue-policy.js +1 -2
  5. package/dist/config/queue-policy.js.map +1 -1
  6. package/dist/doctor/index.d.ts.map +1 -1
  7. package/dist/doctor/index.js +14 -3
  8. package/dist/doctor/index.js.map +1 -1
  9. package/dist/doctor/installation.d.ts +1 -1
  10. package/dist/doctor/installation.d.ts.map +1 -1
  11. package/dist/doctor/installation.js +10 -1
  12. package/dist/doctor/installation.js.map +1 -1
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +1 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/installer/adaptive-templates.d.ts +4 -1
  18. package/dist/installer/adaptive-templates.d.ts.map +1 -1
  19. package/dist/installer/adaptive-templates.js +49 -13
  20. package/dist/installer/adaptive-templates.js.map +1 -1
  21. package/dist/installer/android-project.d.ts +3 -1
  22. package/dist/installer/android-project.d.ts.map +1 -1
  23. package/dist/installer/android-project.js.map +1 -1
  24. package/dist/installer/capabilities-script.d.ts +2 -0
  25. package/dist/installer/capabilities-script.d.ts.map +1 -0
  26. package/dist/installer/capabilities-script.js +77 -0
  27. package/dist/installer/capabilities-script.js.map +1 -0
  28. package/dist/installer/gradle-verification.d.ts.map +1 -1
  29. package/dist/installer/gradle-verification.js +13 -6
  30. package/dist/installer/gradle-verification.js.map +1 -1
  31. package/dist/installer/init.d.ts.map +1 -1
  32. package/dist/installer/init.js +2 -1
  33. package/dist/installer/init.js.map +1 -1
  34. package/dist/installer/opencode-config.d.ts +3 -3
  35. package/dist/installer/opencode-config.js +1 -1
  36. package/dist/installer/project-capabilities.d.ts +35 -0
  37. package/dist/installer/project-capabilities.d.ts.map +1 -0
  38. package/dist/installer/project-capabilities.js +82 -0
  39. package/dist/installer/project-capabilities.js.map +1 -0
  40. package/dist/installer/upgrade.d.ts.map +1 -1
  41. package/dist/installer/upgrade.js +9 -1
  42. package/dist/installer/upgrade.js.map +1 -1
  43. package/dist/queue/cli.d.ts.map +1 -1
  44. package/dist/queue/cli.js +32 -5
  45. package/dist/queue/cli.js.map +1 -1
  46. package/dist/queue/executor.d.ts +1 -0
  47. package/dist/queue/executor.d.ts.map +1 -1
  48. package/dist/queue/executor.js +155 -11
  49. package/dist/queue/executor.js.map +1 -1
  50. package/dist/queue/process-ownership.d.ts +12 -0
  51. package/dist/queue/process-ownership.d.ts.map +1 -0
  52. package/dist/queue/process-ownership.js +58 -0
  53. package/dist/queue/process-ownership.js.map +1 -0
  54. package/dist/queue/queue.d.ts +25 -1
  55. package/dist/queue/queue.d.ts.map +1 -1
  56. package/dist/queue/queue.js +152 -11
  57. package/dist/queue/queue.js.map +1 -1
  58. package/dist/queue/service.d.ts.map +1 -1
  59. package/dist/queue/service.js +19 -2
  60. package/dist/queue/service.js.map +1 -1
  61. package/dist/queue/storage.d.ts +3 -1
  62. package/dist/queue/storage.d.ts.map +1 -1
  63. package/dist/queue/storage.js +25 -15
  64. package/dist/queue/storage.js.map +1 -1
  65. package/dist/queue/supervision.d.ts +38 -0
  66. package/dist/queue/supervision.d.ts.map +1 -0
  67. package/dist/queue/supervision.js +247 -0
  68. package/dist/queue/supervision.js.map +1 -0
  69. package/dist/queue/tools.d.ts.map +1 -1
  70. package/dist/queue/tools.js +4 -2
  71. package/dist/queue/tools.js.map +1 -1
  72. package/docs/MIGRATION.md +110 -9
  73. package/docs/QUEUE.md +360 -6
  74. package/docs/SECURITY.md +5 -2
  75. package/docs/TROUBLESHOOTING.md +82 -8
  76. package/package.json +1 -1
  77. package/templates/.opencode/agents/scheduled-coder.md +22 -0
  78. package/templates/.opencode/agents/scheduled-planner.md +73 -2
  79. package/templates/.opencode/skills/scheduled-quality-coder/SKILL.md +34 -2
  80. package/templates/.opencode/skills/scheduled-quality-orchestrator/SKILL.md +65 -4
  81. package/templates/.opencode/skills/scheduled-quality-reviewer/SKILL.md +22 -0
  82. package/templates/AGENTS.md.fragment +10 -4
  83. package/templates/README.md +3 -1
  84. package/templates/automation/config.schema.json +212 -22
  85. package/templates/automation/task-contract.schema.json +617 -21
  86. package/templates/automation/tasks/TASK-TEMPLATE.json.example +31 -3
  87. package/templates/automation/verification/collect.init.gradle +98 -0
  88. package/templates/automation/verification/contract.cjs +93 -0
  89. package/templates/automation/verification/inventory.cjs +433 -0
  90. package/templates/automation/verification/project.cjs +172 -0
  91. package/templates/automation/verification/recovery.cjs +426 -0
  92. package/templates/scripts/automation/acceptance-report.sh +29 -0
  93. package/templates/scripts/automation/claim-task.sh +35 -2
  94. package/templates/scripts/automation/integration-scope-gate.sh +3 -3
  95. package/templates/scripts/automation/lib.sh +167 -17
  96. package/templates/scripts/automation/orchestrate-task.sh +7 -1
  97. package/templates/scripts/automation/preflight.sh +1 -2
  98. package/templates/scripts/automation/quality-gate.sh +10 -1
  99. package/templates/scripts/automation/record-red.sh +182 -32
  100. package/templates/scripts/automation/resume-task.sh +3 -0
  101. package/templates/scripts/automation/scope-gate.sh +4 -4
  102. package/templates/scripts/automation/show-acceptance-review.sh +8 -0
  103. package/templates/scripts/automation/status.sh +38 -0
  104. package/templates/scripts/automation/submit-review.sh +10 -1
  105. package/templates/scripts/automation/validate-contract.sh +56 -3
  106. package/templates/scripts/automation/verify-integration.sh +3 -0
  107. package/templates/scripts/automation/verify-task.sh +17 -0
package/docs/QUEUE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Queue and background execution
2
2
 
3
- Version `1.0.4` stores proposals and approved contracts under
3
+ Version `1.1.0` stores proposals and approved contracts under
4
4
  `<git-common-dir>/automation-runtime/inbox/queue.json`. A contract is runnable
5
5
  only after its full plan, version, digest, target branch and commit policy are
6
6
  approved and durably recorded. Planning reads a fixed `planningHead`, so another
@@ -33,7 +33,7 @@ local commit SHA, authorization source and `pushed: false` (未推送).
33
33
  | `inPlaceExclusive` (new-install default) | `humanApproval` (new-install default) | After acceptance, local integration and directory handoff, or approved abort |
34
34
  | `inPlaceExclusive` | `autoCommit` (configured default or explicitly sealed override) | After build, full tests, Review, local commit/integration and handoff |
35
35
  | `isolatedWorktree` | `humanApproval` | After the worker and its children exit and its result is safely sealed |
36
- | `isolatedWorktree` | `autoCommit` | Rejected; fresh compatible policy approval is required |
36
+ | `isolatedWorktree` | `autoCommit` | V8 must explicitly authorize isolated auto integration; after verified local handoff, or safe sealing and confirmed exit on a pre-commit failure |
37
37
 
38
38
  Both workspaces use one execution slot per Git common directory. A retained
39
39
  isolated candidate keeps its own directory; revalidation and integration must
@@ -82,8 +82,18 @@ opencode-android-orchestrator queue stop .
82
82
  opencode-android-orchestrator queue start .
83
83
  ```
84
84
 
85
- An unsuccessful OpenCode agent process pauses consumption as a shared execution
86
- fault; inspect its log and fix provider/environment failures before clearing it.
85
+ An unsuccessful OpenCode agent process retains its task's logs and stopped
86
+ candidate. Its exit code alone does not establish a shared execution fault.
87
+ In isolated mode, independent tasks can continue after sealing and confirmed
88
+ process exit; dependent tasks still wait for successful local integration.
89
+ Fixed mode continues to hold the directory until approved recovery or abort.
90
+ Unknown ownership, incomplete repository leases and shared scheduler failures
91
+ still block consumption. No automatic environment retry is implied.
92
+
93
+ Reviewer interruption recovery uses the approved queue `resume-review` request
94
+ and the one-argument Shell entry. It rechecks the sealed diff and does not rerun
95
+ Coder. The orchestration step bound supports zero, one or two configured Review
96
+ corrections, including a final budget-exhaustion state check.
87
97
 
88
98
  Pause stops new reservations until explicit resume or a new contract is
89
99
  successfully enqueued. Stop terminates the scheduler while preserving
@@ -124,6 +134,84 @@ It does not run `clean` or rerun all dependency tasks. Coder, Reviewer and local
124
134
  integration perform the configured full suite and build gates. Evidence records
125
135
  fresh-test logs, configured tasks and elapsed seconds.
126
136
 
137
+ The 1.1.0 templates generate task-contract schema V4 with verification
138
+ version 2. npm publication of 1.1.0 is pending; the published 1.0.5 package
139
+ does not include this protocol. Every verification case
140
+ has a stable ID, a one-based acceptance-criterion reference, an evidence source,
141
+ an exact test identity, and a pre-change classification:
142
+
143
+ - `preserve` must pass before and after implementation;
144
+ - `change` must fail before implementation with the approved exception type and
145
+ optional message fragment, then pass afterwards;
146
+ - `observe` may record a previously uncertain boundary, but a failure is
147
+ accepted only when the contract declares its expected cause.
148
+
149
+ Planner declares only the task behavior cases. Before Coder edits any test,
150
+ `claim-task.sh` captures every existing case in the approved focused scope.
151
+ Fully qualified configured Gradle Test paths distinguish modules; overlapping
152
+ filters are combined per task. Each parameter instance must have a distinct,
153
+ stable `(taskPath, className, name)` identity. Ambiguous identities are rejected.
154
+
155
+ The sealed contract explicitly includes:
156
+
157
+ ```json
158
+ "inventory": {
159
+ "mode": "focusedBaseline",
160
+ "existingSkips": "reject",
161
+ "emptyBaseline": "reject"
162
+ }
163
+ ```
164
+
165
+ Use `existingSkips: preserve` only to preserve already skipped regression cases;
166
+ it never permits a new skip or skipped behavior case. Use `emptyBaseline: allow`
167
+ only for an intentionally empty task/filter scope, such as a new test class.
168
+ An empty RED/GREEN is still rejected. Policies apply per task, not only to the
169
+ combined result count. Baseline failures always block before test edits.
170
+
171
+ `record-red.sh TASK-ID` runs the shared collector on unchanged production code.
172
+ It combines the captured regression cases and approved behavior cases into one
173
+ manifest. Missing/extra cases, new skips, ambiguous identities, unexpected
174
+ failures, incomplete events and build failures cannot become RED. GREEN must
175
+ cover the same manifest. No stale XML, cached Test result or discovery dry-run
176
+ is accepted as an actual execution. JUnit XML and Gradle logs are retained with
177
+ the run-bound event stream; the stream and its completion/count records drive
178
+ the decision. See [Gradle Test](https://docs.gradle.org/9.4.1/dsl/org.gradle.api.tasks.testing.Test.html)
179
+ for the underlying execution and listener APIs.
180
+
181
+ Evidence binds the contract, configuration, original execution baseline,
182
+ collector, full test/resource snapshot and attempt files. JVM source sets and
183
+ Android test source providers discover custom inputs without expanding contract
184
+ or agent edit permissions. Symlink, external and generated inputs fail with a
185
+ specific unsupported-input reason. Test and resource inputs freeze after RED.
186
+ The final check also binds GREEN to the verified HEAD and working files.
187
+ Each GREEN invocation first invalidates the previous success in
188
+ `green-verification.json`. Final checks require a PASSED marker bound to the
189
+ same verification run and report digest; failed, interrupted or early-rejected
190
+ reruns cannot reuse an older successful report.
191
+ Human-owned commit-prefix and snapshotted worktree-allowlist files remain outside
192
+ the evidence; changing the exclusion policy invalidates its binding. Such files
193
+ cannot also be test inputs. An isolated candidate can revalidate an advanced
194
+ production baseline, but incoming changes to frozen test inputs block it and
195
+ require a newly approved task, not replacement of the original RED.
196
+
197
+ Failed attempts remain under `inventory-attempts/`; only a complete valid RED
198
+ is sealed. Queue details and `status.sh` expose `baselineInventory`,
199
+ `testManifest`, `greenInventory` and `inventoryStatus` (queue details use the
200
+ hyphenated file names). Status includes the phase, reason code, offending cases
201
+ and next action. Acceptance reports include baseline/RED/GREEN coverage and
202
+ the permitted skips. `processExitCode` is the actual Gradle status; for V4 the
203
+ legacy `red.exitCode: 1` means `approved-case-failure`, because the collector
204
+ allows Test tasks to complete and classifies failures itself. The reviewer must
205
+ still check the semantic origin of the expected failure, beyond type/message.
206
+ Structured errors carry the queue execution ID. Errors from older executions
207
+ or malformed status sidecars do not replace the current script's failure.
208
+
209
+ V1/V2 retain the legacy failure-text command. Existing V3 contracts retain their
210
+ declared-case-only verification. New inventory coverage requires a V4 contract
211
+ and fresh approval, not an in-place rewrite of old evidence. Upgrading templates
212
+ and executor must be done together after the development build is versioned;
213
+ same-version production installations remain verification-only.
214
+
127
215
  ## Baselines and recovery
128
216
 
129
217
  Before execution, changes to contract-relevant files or execution configuration
@@ -153,8 +241,13 @@ exited; a heartbeat timeout alone never steals a live lock. Execution recovery
153
241
  also checks the whole worker process group. If a reservation has no registered
154
242
  worker, stop its recorded launcher before recovering it. Unknown ownership
155
243
  retains the execution slot. `recover` is only for an existing sealed commit
156
- transaction; baseline/Reviewer interruptions use `/resume-task` or
157
- `/resume-review`. Running cancellation uses `/abort-task` and waits for a safe
244
+ transaction; baseline interruptions before `baseline.json` exists may use the
245
+ bounded `/resume-task` route; Reviewer interruptions use `/resume-review`.
246
+ V4 inventory capture happens after `baseline.json` is written, so an interruption
247
+ at that stage cannot use baseline-only resume. Inspect the retained attempt,
248
+ request approved `/abort-task` archival, correct the cause and approve a new task.
249
+ Do not delete or overwrite baseline/RED evidence to make recovery pass.
250
+ Running cancellation uses `/abort-task` and waits for a safe
158
251
  agent boundary before archival through the execution slot. A hung external
159
252
  process must be diagnosed and stopped before ownership recovery can succeed.
160
253
 
@@ -163,3 +256,264 @@ retained unfinished workspace. Inbox, notifications and audit data remain in
163
256
  the Git common directory. Commit-message prefix and worktree-allowlist sidecars
164
257
  remain human-owned. See [Migration](MIGRATION.md), [Troubleshooting](TROUBLESHOOTING.md)
165
258
  and [Security](SECURITY.md) for lifecycle and trust boundaries.
259
+
260
+ ## V5 baseline checkpoint recovery (1.1.0)
261
+
262
+ V4 remains the default contract example. A new V5 contract keeps verification
263
+ version 2 and every V4 inventory/RED/GREEN gate, and additionally requires an
264
+ explicitly approved `recovery` object. Adding it to V4 is rejected. For example:
265
+
266
+ ```json
267
+ {
268
+ "version": 1,
269
+ "scope": "baseline",
270
+ "maxEnvironmentRetries": 2,
271
+ "maxManualRetries": 1,
272
+ "maxSameFailureRetries": 2,
273
+ "maxElapsedMs": 900000,
274
+ "initialDelayMs": 1000,
275
+ "maxDelayMs": 60000
276
+ }
277
+ ```
278
+
279
+ Retry counts must each be 0..3. The elapsed window is 1000..86400000 ms;
280
+ initial/maximum backoff must be 1000..600000 ms with maximum at least initial.
281
+ Backoff grows exponentially with jitter. Zero retries disables that budget.
282
+ The window starts at initial capture and stops new stages/attempts after its
283
+ deadline; it does not forcibly terminate a stalled Gradle or Worker process.
284
+
285
+ The queue runs deterministic capture before Coder starts. Full unit-test
286
+ success seals `baseline-full.json`; successful focused discovery seals
287
+ `baseline-discovery.json`; collection seals `baseline-inventory.json`.
288
+ `baseline.json` is published only after all stages succeed. Recovery reuses
289
+ completed checkpoints without changing their bytes. `baseline-recovery.json`
290
+ retains each attempted stage, command/process logs, input binding, evidence
291
+ hashes, failure category and persistent next-run time. One retry spends one
292
+ budget entry even if it completes multiple stages. RED preparation,
293
+ implementation and Review budgets are independent; capture invokes no models.
294
+
295
+ Only positive network/429 signatures on failed commands authorize automatic
296
+ retry. Test assertion/compilation, authentication and integrity failures take
297
+ precedence over incidental network text. Real historical failures require a
298
+ separate correction/revised task. Unknown failures remain blocked and may use
299
+ `/resume-task` only after fresh approval within the manual retry budget.
300
+ A manual retry has its own budget but shares the elapsed window. There is no
301
+ public `retry-baseline` request; it is reserved for the approved scheduler.
302
+
303
+ Resume requires unchanged contract, execution/target HEAD, repository inputs,
304
+ configuration and recorded toolchain/environment binding. Human-owned files
305
+ excluded by the sealed worktree allowlist remain outside that input snapshot;
306
+ the exclusion policy itself is bound. All retained attempt
307
+ artifacts and checkpoints must still match the queue-sealed ledger. Revocation,
308
+ pause, dependency, process ownership and workspace lease checks still apply.
309
+ Service restarts retain counters and backoff; an ambiguous interrupted RUNNING
310
+ attempt is not automatically replayed. A rejected recovery consumes its wake,
311
+ so corrupted evidence cannot create an automatic retry loop. Successful
312
+ baseline/RED evidence is never replaced. Source or target-branch changes need
313
+ a revised contract. Baseline recovery does not refresh a stale planning head.
314
+
315
+ Inspect `queue status <directory> <key>` evidence `baseline-recovery` and `status.sh` evidence
316
+ `baselineRecovery`; queue item `baselineRecovery.nextRunAt` is the authoritative
317
+ scheduled wake (it can be null after rejection even when retained evidence has
318
+ an old time). Failed isolated tasks retain their workspace; independent tasks
319
+ may continue after process exit and sealing. Fixed-directory tasks still hold
320
+ the directory while waiting. Automatic recovery does not change commit policy.
321
+
322
+ ## V6 Worker safety deadlines (1.1.0)
323
+
324
+ New V6 contracts retain V5 baseline recovery and inventory verification and
325
+ add an explicitly approved execution policy, for example:
326
+
327
+ ```json
328
+ {
329
+ "version": 1,
330
+ "maxRunMs": 1800000,
331
+ "maxStageMs": 600000,
332
+ "terminationGraceMs": 15000
333
+ }
334
+ ```
335
+
336
+ Place this object in `execution`. Run and stage limits are 1000..86400000 ms,
337
+ stage must not exceed run, and TERM grace is 1000..60000 ms. They apply per
338
+ reserved Worker invocation, including resume, Review recovery, integration,
339
+ revalidation and abort; V5's baseline retry count/window still spans its own
340
+ attempts. V4 remains the default example. V1..V5 never gain kill authority by
341
+ upgrading. Normal contract approval covers this policy; no repeated approval
342
+ is needed for an in-policy timeout.
343
+
344
+ The detached supervisor is outside the Worker process group, so a blocked
345
+ Worker event loop cannot disable the deadline. The durable record tracks
346
+ preparation, baseline, coding, review, integration and abort stages. Stage
347
+ changes reset only the stage limit, bounded by the original run deadline.
348
+ Log output and silence do not affect either limit. Wall-clock deadlines include
349
+ sleep; after wake an elapsed deadline triggers termination. A backwards clock
350
+ or unreadable process inventory stops supervision for ownership review.
351
+
352
+ Before TERM and each later KILL, process identity must match a fresh process
353
+ table: a unique inherited run marker or previously witnessed ancestry plus
354
+ PID, start time and process group. Detached descendants retain the marker;
355
+ ordinary Shell descendants are also recorded because macOS may hide inherited
356
+ environments. No signal targets a process name or a whole process group.
357
+ Unknown members, changed identities or unprovable locks preserve the active
358
+ slot and lease with `OWNERSHIP_BLOCKED`. Commands must preserve the ownership
359
+ environment and must not launch persistent external services. Controlled
360
+ Gradle commands use `--no-daemon`; supervised tools also inherit
361
+ `-Dorg.gradle.daemon=false` so shared Gradle daemons are not reused or killed.
362
+
363
+ TERM intent/result and grace start are persisted before escalation. Restarting
364
+ the scheduler keeps its detached supervisor alive; if the supervisor crashes,
365
+ the next scheduler scan reattaches to the same Worker. Run/stage deadlines,
366
+ known identities and TERM grace are retained. An unregistered ambiguous launch
367
+ is not replayed. A dead queue lock can be archived automatically only when its
368
+ recorded owner belongs to this supervised execution or its previous supervisor.
369
+ Lock creation writes and flushes the owner record before publishing an exclusive
370
+ hard link in the same directory. A process killed before publication can leave a
371
+ pending file, but no occupied transaction lock; after publication the complete
372
+ owner remains available for recovery. Older incomplete or unknown lock records
373
+ still require explicit diagnosis. A live or unknown lock is never stolen.
374
+ A machine reboot still requires the
375
+ operator to start the service; this change does not install a system daemon.
376
+
377
+ Two empty ownership snapshots are required before the run can be reconciled.
378
+ On timeout, all attempts and product changes remain. A safely sealed isolated
379
+ candidate becomes BLOCKED, allowing independent tasks to continue; dependent
380
+ tasks keep waiting. Fixed-directory tasks retain their directory. If a local
381
+ commit transaction exists, the task becomes INTEGRATION_BLOCKED and retains
382
+ its lease and transaction; `recover` verifies and integrates that same commit
383
+ without creating another one. Timeout never implies acceptance or authorizes
384
+ new retries. The supervisor does not roll back visible commits.
385
+
386
+ `queue status`, `queue status <directory> <key>` and `status.sh` expose supervision
387
+ state/deadlines. `worker-stop-<runId>.json` records signal intents/results and
388
+ confirmed exit, while `worker-stop-<runId>-blocked.json` preserves ownership
389
+ failures. Raw process environments and the ownership token are not included
390
+ in public status or evidence. `queue stop` stops scheduling, not supervision.
391
+ After an ownership failure, inspect the recorded identities and preserve the
392
+ workspace. `recover-execution` refuses live/unknown descendants and retains
393
+ the interrupted workspace; then use the existing approved recovery/archive
394
+ workflow. Do not clear leases or edit evidence to bypass a refusal.
395
+
396
+
397
+ ## V7 verification environment recovery (1.1.0)
398
+
399
+ V7 adds required `stageRecovery` alongside the V5 `recovery` and V6 `execution`
400
+ policies. The default contract example remains V4; old tasks never acquire new
401
+ retry authority from an installation upgrade.
402
+
403
+ ```json
404
+ {
405
+ "version": 1,
406
+ "maxEnvironmentRetries": 2,
407
+ "maxSameFailureRetries": 1,
408
+ "maxElapsedMs": 900000,
409
+ "initialDelayMs": 1000,
410
+ "maxDelayMs": 60000
411
+ }
412
+ ```
413
+
414
+ Retry limits are 0..3, elapsed time is 1000..86400000 ms, delays are
415
+ 1000..600000 ms with maximum at least initial. RED, GREEN and Reviewer
416
+ verification each share one cumulative budget across calls and correction
417
+ cycles. The phase recovery window starts at its first verification. Successful
418
+ verification resets the consecutive-failure counter, never the retry counter
419
+ or elapsed window. This is not a model-cost or cross-phase task-time budget.
420
+
421
+ Only identified transient network/rate-limit failures of deterministic
422
+ verification may retry. Real assertions, compilation failures, configuration,
423
+ unknown errors, scope/integrity failures and signal termination never grant
424
+ retry authority. RED still requires the approved behavior failure and all
425
+ existing regression checks. Environment retries do not consume preparation
426
+ fixes, implementation gate attempts or Review correction cycles. Review
427
+ verification exhaustion becomes BLOCKED without creating CHANGES_REQUESTED.
428
+ The same model invocation remains responsible for the script result; no model
429
+ call, approval, local commit or integration transaction is automatically replayed.
430
+
431
+ Backoff is exponential with jitter and a persisted next-run time. The bounded
432
+ wait retains the Worker slot; V6 supervision still enforces its deadline and
433
+ covers blocked commands. Scheduler restart leaves that Worker running. Attempts,
434
+ counts and deadlines live under `evidence/<task>/stage-recovery/`. Logs and
435
+ inventory attempts are retained and checked before retries, along with the
436
+ contract, HEAD, working files, configuration, tool environment and sealed
437
+ baseline/RED evidence. New calls never reuse a previous successful verification.
438
+ The queue seals each phase ledger's SHA-256 through the active supervised
439
+ Worker. Rewriting or deleting a ledger cannot reset its counters or backoff;
440
+ unowned checkpoint calls are rejected. Approved product deletions remain part
441
+ of the input snapshot, and restoring a deleted file during backoff invalidates it.
442
+
443
+ Changed inputs or evidence stop the phase. A crashed attempt with no durable
444
+ outcome or an occupied recovery lock also stops; no timeout steals a lock.
445
+ An exhausted phase cannot be reset by re-invoking a command. Preserve evidence
446
+ and use the existing approved archive/revised-contract workflow. This protocol
447
+ does not add automatic recovery of unknown outcomes, provider errors, or retries
448
+ after a Worker termination. `queue status <directory> <key>` and `status.sh`
449
+ expose `stageRecovery`; real Android/provider and physical sleep/reboot tests
450
+ remain separate acceptance work.
451
+
452
+
453
+ ## V8 isolated integration and planning refresh (1.1.0)
454
+
455
+ V8 retains all V7 inventory, baseline recovery, stage recovery and Worker deadline
456
+ policies, and requires `continuity`:
457
+
458
+ ```json
459
+ {
460
+ "version": 1,
461
+ "isolatedAutoIntegration": true,
462
+ "planningRefresh": "completedQueueTasks",
463
+ "planningInputs": [
464
+ "app/src/main/java/example/Feature.kt",
465
+ "app/src/main/java/example/Dependency.kt",
466
+ "app/src/test/java/example/FeatureTest.kt",
467
+ "app/src/test/resources/**"
468
+ ]
469
+ }
470
+ ```
471
+
472
+ Set `isolatedAutoIntegration: true` only with both `workspaceStrategy:
473
+ "isolatedWorktree"` and `commitPolicy: "autoCommit"` in the sealed draft. The
474
+ approval question explicitly grants automatic local integration. Existing
475
+ contracts, including queued fixed-directory auto-commit tasks, do not gain this
476
+ authority from a default policy change. V8 also binds the workspace strategy at
477
+ approval; restore it or approve a revised task after a repository policy change.
478
+ The default example remains V4 and new-install defaults remain human approval.
479
+
480
+ After fresh full tests, build and independent Review, the same repository slot
481
+ verifies and fast-forwards the approved local target. The persisted five-stage
482
+ commit transaction binds the candidate, parent, tree and original authorization.
483
+ No remote operation or fabricated human-acceptance record is produced. Pause
484
+ prevents new reservations; revocation or an abort request prevents starting an
485
+ automatic commit. Target drift, source checkout drift or unsealed changes stop
486
+ integration. This does not authorize an automatic merge, rebase or new model
487
+ attempt. An existing transaction keeps its lease for explicit `recover`, which
488
+ reuses its recorded commit. Before a transaction exists, a failed isolated task
489
+ can be safely sealed and released after process exit, so independent tasks can
490
+ continue; its dependents still wait for actual COMPLETED integration.
491
+
492
+ `planningInputs` declares the files and selectors whose contents informed the
493
+ requirement, interfaces, design and approved test meaning. Include dependencies
494
+ and relevant tests/resources, not just editable files. At draft time the queue
495
+ seals a digest of matched paths, Git blob IDs, modes and selectors at the fixed
496
+ planning HEAD. Empty matches represent absent inputs, so future additions are
497
+ also detected. Symlink and submodule inputs are rejected. The selectors grant
498
+ no edit permission and do not replace `allowedPaths`. An incomplete declaration
499
+ cannot prove semantic independence; Planner must disclose uncertainty and use
500
+ `planningRefresh: "reject"` when dependencies cannot be stated reliably.
501
+
502
+ With `completedQueueTasks`, prepare may advance the execution baseline only if:
503
+
504
+ - Every declared planning input is unchanged, including matched file additions,
505
+ deletions and executable modes.
506
+ - Execution configuration is unchanged. Other completed tasks' sealed plan and
507
+ contract files are exempt; build scripts and verification configuration are not.
508
+ - Every intervening commit forms one linear chain of completed queue integrations
509
+ on the same local target, with matching approval and persisted transaction.
510
+ Unrecorded external commits and merge commits require a revised contract.
511
+
512
+ Changed inputs or denied refresh enter BASELINE_REVIEW before workspace creation
513
+ or model execution. Use `planningRefresh: "reject"` to require reapproval on any
514
+ HEAD advance. Legacy contracts retain their existing allowed-path drift rules.
515
+ The original contract, planning HEAD and input digest remain unchanged; queue
516
+ `planning-baseline` evidence records the actual execution HEAD, prior integrated
517
+ tasks and decision. Prepare and capture a new baseline on that execution HEAD;
518
+ never reuse another task's baseline, RED or Review evidence. Refresh is available
519
+ only before execution, not a way to reset an existing task's retry budgets.
package/docs/SECURITY.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Security model
2
2
 
3
3
  This document describes the security properties of
4
- `@frankzhang2026/opencode-android-orchestrator@1.0.4`. The lifecycle foundation
4
+ `@frankzhang2026/opencode-android-orchestrator@1.1.0`. The lifecycle foundation
5
5
  completed the real OpenCode `1.14.22` and `1.15.13` release matrix in `0.2.0`;
6
6
  `1.0.0` retains that compatibility boundary.
7
7
 
@@ -43,7 +43,10 @@ selections. The configured `humanApproval` policy additionally requires final
43
43
  candidate acceptance. Configured or explicitly selected `autoCommit`
44
44
  authorization is sealed during contract approval and replaces only the final
45
45
  human question; build, actual full unit tests and independent Review remain
46
- mandatory.
46
+ mandatory. Isolated automatic integration additionally requires new V8 authority
47
+ bound to its approved workspace strategy. Planning refresh preserves the original
48
+ approval and is limited to unchanged declared inputs across recorded completed
49
+ queue integrations; it cannot authorize arbitrary target changes.
47
50
 
48
51
  The plugin observes the host's question arguments and completed answer
49
52
  metadata through the common before/after hooks. Its one-use receipt binds
@@ -1,7 +1,8 @@
1
1
  # Troubleshooting
2
2
 
3
3
  Use this guide for
4
- `@frankzhang2026/opencode-android-orchestrator@1.0.4`.
4
+ `@frankzhang2026/opencode-android-orchestrator@1.1.0`. npm publication is
5
+ pending; the pinned Registry commands apply after publication.
5
6
 
6
7
  ## Start with read-only evidence
7
8
 
@@ -11,7 +12,7 @@ From the repository root, capture:
11
12
  git status --short --branch
12
13
  git rev-parse HEAD
13
14
  opencode --version
14
- npx @frankzhang2026/opencode-android-orchestrator@1.0.4 doctor . --json
15
+ npx @frankzhang2026/opencode-android-orchestrator@1.1.0 doctor . --json
15
16
  ```
16
17
 
17
18
  If installation never completed, doctor will correctly report a missing or
@@ -31,6 +32,18 @@ The CLI uses these exit codes:
31
32
  `init`, `upgrade`, and `uninstall` structures successful results; thrown errors
32
33
  remain human-readable on stderr with a stable code such as `[FILE_CONFLICT]`.
33
34
 
35
+ ## Nested Android builds (development)
36
+
37
+ For an installed nested Android build, inspect
38
+ `automation/config.json → androidProject.capabilities.buildRoot`. The wrapper,
39
+ settings and `local.properties` belong in that selected directory. Run managed
40
+ scripts from the Git root; for a manual Gradle command, use the selected build
41
+ directory. In isolated worktrees the Worker resolves the source checkout's SDK
42
+ configuration before starting; ignored `local.properties` is not copied.
43
+ Do not replace the selected directory with a symlink or point it at a sibling
44
+ build. A selection/configuration mismatch requires investigation and a reviewed
45
+ installation change, not a fallback to another wrapper.
46
+
34
47
  ## Company npm Registry override
35
48
 
36
49
  If `npm config get registry` reports an internal Registry and a request fails
@@ -39,9 +52,9 @@ command-scoped override:
39
52
 
40
53
  ```sh
41
54
  npm --registry=https://registry.npmjs.org/ view \
42
- @frankzhang2026/opencode-android-orchestrator@1.0.4 version
55
+ @frankzhang2026/opencode-android-orchestrator@1.1.0 version
43
56
  npx --yes --registry=https://registry.npmjs.org/ \
44
- @frankzhang2026/opencode-android-orchestrator@1.0.4 upgrade . --json
57
+ @frankzhang2026/opencode-android-orchestrator@1.1.0 upgrade . --json
45
58
  ```
46
59
 
47
60
  This leaves the company's saved npm configuration unchanged. Use the option
@@ -71,7 +84,7 @@ Git-backed Superpowers plugin at runtime.
71
84
  | Invalid `--long-command-timeout-ms` | The value is not an integer from `120000` through `7200000`. | Use the `1800000` ms default or pass an intentional bounded value to `init`/`upgrade`; do not edit the generated config directly. |
72
85
  | Android SDK failure | No valid explicit SDK, `ANDROID_HOME`, `ANDROID_SDK_ROOT`, or `local.properties` `sdk.dir` was found. | Configure one real SDK root containing `platforms/` and `build-tools/`. Do not publish `local.properties`. |
73
86
  | Missing `git`, `jq`, `rg`, `shasum`, or Java | Required deterministic command is unavailable on `PATH`. | Install or restore the missing command, record its version, and rerun the read-only checks. |
74
- | `Bundled Orchestrator skill is unavailable` | The installed `1.0.4` package is incomplete, damaged, or loaded from an unsupported partial copy. | Reinstall the exact package, inspect its `resources/third-party/superpowers-v6.2.0/skills/` entries, restart OpenCode, and rerun `opencode debug skill`. Do not add an external Superpowers plugin as a fallback. |
87
+ | `Bundled Orchestrator skill is unavailable` | The installed `1.1.0` package is incomplete, damaged, or loaded from an unsupported partial copy. | Reinstall the exact package, inspect its `resources/third-party/superpowers-v6.2.0/skills/` entries, restart OpenCode, and rerun `opencode debug skill`. Do not add an external Superpowers plugin as a fallback. |
75
88
  | `current process does not own this task queue execution` immediately after Coder start on 1.0.1 | OpenCode created the tool shell in a separate process group, so 1.0.1 rejected a legitimate Worker descendant. | Upgrade to 1.0.2 or later, restart OpenCode, then use the approved resume or abort workflow for the retained task. Do not edit the queue or lease files. |
76
89
  | The exact Superpowers v6.2.0 plugin remains after upgrade | That entry existed in the verified pre-install OpenCode file and is therefore user-owned. | Leave it in place or remove it as a separate reviewed configuration change. Upgrade only removes the old Orchestrator-managed entry. |
77
90
 
@@ -88,7 +101,7 @@ silence of `./gradlew tasks --all --console=plain | rg ...` in a large build.
88
101
  For an existing installation, run:
89
102
 
90
103
  ```sh
91
- npx @frankzhang2026/opencode-android-orchestrator@1.0.4 upgrade . \
104
+ npx @frankzhang2026/opencode-android-orchestrator@1.1.0 upgrade . \
92
105
  --refresh-gradle-discovery
93
106
  ```
94
107
 
@@ -97,7 +110,7 @@ least `1800000` milliseconds. A higher timeout already supplied by the caller
97
110
  is preserved; unrelated Bash commands are unchanged. To configure one hour,
98
111
  run `upgrade . --long-command-timeout-ms 3600000` on a healthy installation.
99
112
  If a command still reports `120000 ms`, confirm that the project manifest and
100
- OpenCode plugin reference are both `1.0.4`, restart the OpenCode session so the
113
+ OpenCode plugin reference are both `1.1.0`, restart the OpenCode session so the
101
114
  plugin reloads, and rerun doctor before attempting recovery.
102
115
 
103
116
  After installation, inspect OpenCode discovery separately:
@@ -251,7 +264,7 @@ session or a missing notification is not evidence that a task never started.
251
264
  | Isolated capacity reached | Integrate or explicitly archive retained workspaces; do not delete failed work simply to advance the queue. |
252
265
  | Execution launch ownership unknown | Stop the recorded launcher, prove it exited, then use `queue recover-execution .`; preserve any partial workspace. |
253
266
  | Dead transaction owner | Inspect the lock record and use explicit `queue recover-lock .`; a live PID or surviving child process blocks takeover. |
254
- | OpenCode process failure | Inspect the current agent log, repair provider/environment access, then clear the fault while idle. Resume alone does not clear it. |
267
+ | OpenCode process failure | Inspect the task's agent log and repair the diagnosed cause. Use the applicable approved recovery or abort route. An agent exit alone does not set a shared fault; fixed mode still retains its workspace, while sealed isolated failures allow independent tasks to continue. |
255
268
  | Local commit already exists but task is blocked | Use `queue recover . TASK-ID`; it reuses the sealed transaction instead of creating another visible commit. |
256
269
  | Target advanced for an isolated candidate | Request `revalidate`, wait for fresh full tests/Review, and confirm the new candidate. |
257
270
  | Upgrade/uninstall reports a retained workspace | Stop scheduling and finish or approve abort before replacing runtime resources. |
@@ -280,3 +293,64 @@ For escalation, provide the command, exit code, stable error code, redacted
280
293
  details, OpenCode version, package version, current branch/HEAD, and the list of
281
294
  affected paths. Share file contents only after applying the guidance in
282
295
  [Security](SECURITY.md).
296
+
297
+ ## 1.1.0 V5 baseline recovery
298
+
299
+ For a V5 task blocked during capture, inspect queue `baselineRecovery` and the
300
+ retained `baseline-recovery` evidence. A non-null future `nextRunAt` means the
301
+ scheduler is backing off inside the approved environment budget; leave the
302
+ attempts intact. A null time with budget/deadline exhaustion stops automatic
303
+ retry. Unknown failures need `/resume-task` approval within the manual budget.
304
+ Assertion, compilation, authentication, historical baseline and integrity
305
+ failures require diagnosis/correction or a revised task, not repeated resume.
306
+
307
+ A changed ledger/checkpoint, execution/target HEAD, source input, configuration
308
+ or bound toolchain prevents reuse. Restore nothing by deleting evidence.
309
+ A RUNNING attempt left by a crash has no durable outcome and cannot be retried
310
+ automatically; account for the entire process group before the existing
311
+ approved abort/archive workflow. V5's elapsed limit does not kill a hung
312
+ process. V4 baseline recovery rules remain unchanged.
313
+
314
+ ## Worker deadlines (V6 development protocol)
315
+
316
+ A deadline stop reports the stage, run/stage deadline, TERM time and any KILL
317
+ escalation. A silent but in-budget compile is allowed to continue. Scheduler
318
+ stop/start does not reset budgets or stop its independent supervisor.
319
+ If the supervisor itself exits, start the scheduler to reattach to its recorded
320
+ Worker. Unknown ownership, PID generation changes, unreadable process tables,
321
+ live/unknown locks and ambiguous launches remain occupied for diagnosis.
322
+
323
+ Once all owned processes have exited, isolated stopped candidates can release
324
+ the execution slot after sealing. An integration interruption preserves the
325
+ commit transaction and lease; use `recover` to complete the existing commit.
326
+ For `OWNERSHIP_BLOCKED`, inspect retained evidence and account for all recorded
327
+ processes before `recover-execution`; it will refuse any live/unknown owner.
328
+ Never use process-name-wide kills or remove a lease to make the queue advance.
329
+
330
+
331
+ ## V7 stage verification failures
332
+
333
+ Inspect `stageRecovery` in task status and `stage-recovery/<phase>.json` in the
334
+ task evidence. WAITING records the persisted backoff; EXHAUSTED means the phase
335
+ budget/window or no-progress bound stopped retries. BLOCKED means inputs,
336
+ evidence or another invariant could not be preserved. Do not edit these records
337
+ or remove locks to get another attempt. Unknown or incomplete process outcomes
338
+ require ownership diagnosis and the existing approved archive/new-contract
339
+ route. A Reviewer environment stop preserves the sealed candidate; it does not
340
+ request a Coder implementation correction or count as approval.
341
+
342
+
343
+ ## V8 continuity stops
344
+
345
+ Inspect queue details `planning-baseline.refresh`: input drift, protected
346
+ configuration drift, disabled refresh and unrecorded target commits each explain
347
+ why preparation stopped. Preserve the original contract and approve a revised
348
+ proposal; do not replace its planning digest or baseline evidence. Restore a
349
+ changed repository workspace strategy or obtain fresh V8 approval.
350
+
351
+ For isolated automatic integration, a changed target or source checkout stops
352
+ before a new commit intent. Preserve the candidate and resolve the drift through
353
+ a revised task. If `commit-transaction.json` already exists, retain its lease and
354
+ use queue `recover` after diagnosis; this reuses the same local commit. It must
355
+ not be discarded to free capacity. Other safely sealed pre-commit failures do
356
+ not stop independent tasks, but dependents continue waiting for integration.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frankzhang2026/opencode-android-orchestrator",
3
- "version": "1.0.4",
3
+ "version": "1.1.0",
4
4
  "description": "Reusable OpenCode orchestration for Android projects",
5
5
  "license": "MIT",
6
6
  "author": "frankzhang2026",
@@ -109,9 +109,31 @@ literally. Do not infer missing requirements and do not ask questions during a
109
109
  non-interactive run. If anything is ambiguous or blocked, stop and report the exact
110
110
  reason; the deterministic scripts own state transitions.
111
111
 
112
+ For schema V4/V5/V6, successful claim must first seal the focused baseline inventory.
113
+ Do not edit tests before claim succeeds. Existing tests join the approved
114
+ behavior cases automatically; keep their coverage and all sealed test/resource
115
+ inputs intact. Use status evidence to inspect missing, newly skipped or extra
116
+ cases and the reported recovery action. An allowed existing skip does not
117
+ authorize any new skipped behavior.
118
+
119
+ For schema V3/V4/V5/V6 tasks, keep production code unchanged while adding the approved
120
+ tests, then call `./scripts/automation/record-red.sh <TASK-ID>` with no model-
121
+ chosen failure text. The script checks every declared case. A familiar exception
122
+ name in a log is not sufficient RED. Fix a test-only preparation error only when
123
+ the contract remains unchanged and its preparation budget allows it; rerun the
124
+ preflight afterwards. Contract contradictions must be blocked with the reported
125
+ case IDs and measured results. Never delete evidence or weaken, skip or reclassify
126
+ a test to pass the preflight.
127
+
112
128
  You may edit only paths allowed both by this agent and by the task contract.
113
129
  Treat `.automation-worktree-allowlist` and the status JSON's
114
130
  `runtime.effectiveWorktreeAllowlist` paths as human-owned local state: never
115
131
  edit, stage, report, or use them as task evidence.
116
132
  Passing tests never grants permission to push, merge, create worktrees, alter
117
133
  automation rules, or declare the task ready for review yourself.
134
+
135
+ For V6 the approved independent supervisor enforces wall-clock deadlines.
136
+ Controlled Gradle entries disable shared-daemon reuse. Never unset Worker
137
+ ownership variables, launch persistent detached services, or bypass controlled
138
+ entries to extend a deadline. If ownership or termination is blocked, preserve
139
+ the candidate and stop; no extra implementation or retry is authorized.