@frankzhang2026/opencode-android-orchestrator 0.10.0 → 1.0.1

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 (109) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +48 -51
  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/queue-policy.d.ts +12 -0
  10. package/dist/config/queue-policy.d.ts.map +1 -0
  11. package/dist/config/queue-policy.js +18 -0
  12. package/dist/config/queue-policy.js.map +1 -0
  13. package/dist/config/verification-policy.d.ts +8 -3
  14. package/dist/config/verification-policy.d.ts.map +1 -1
  15. package/dist/config/verification-policy.js +48 -14
  16. package/dist/config/verification-policy.js.map +1 -1
  17. package/dist/doctor/index.d.ts.map +1 -1
  18. package/dist/doctor/index.js +3 -49
  19. package/dist/doctor/index.js.map +1 -1
  20. package/dist/doctor/installation.d.ts.map +1 -1
  21. package/dist/doctor/installation.js +3 -0
  22. package/dist/doctor/installation.js.map +1 -1
  23. package/dist/installer/adaptive-templates.d.ts +3 -1
  24. package/dist/installer/adaptive-templates.d.ts.map +1 -1
  25. package/dist/installer/adaptive-templates.js +2 -0
  26. package/dist/installer/adaptive-templates.js.map +1 -1
  27. package/dist/installer/install-manifest.d.ts +1 -0
  28. package/dist/installer/install-manifest.d.ts.map +1 -1
  29. package/dist/installer/install-manifest.js +6 -1
  30. package/dist/installer/install-manifest.js.map +1 -1
  31. package/dist/installer/opencode-config.d.ts +3 -3
  32. package/dist/installer/opencode-config.d.ts.map +1 -1
  33. package/dist/installer/opencode-config.js +1 -1
  34. package/dist/installer/opencode-config.js.map +1 -1
  35. package/dist/installer/uninstall.d.ts.map +1 -1
  36. package/dist/installer/uninstall.js +5 -0
  37. package/dist/installer/uninstall.js.map +1 -1
  38. package/dist/installer/upgrade.d.ts.map +1 -1
  39. package/dist/installer/upgrade.js +13 -1
  40. package/dist/installer/upgrade.js.map +1 -1
  41. package/dist/plugin/index.d.ts.map +1 -1
  42. package/dist/plugin/index.js +11 -5
  43. package/dist/plugin/index.js.map +1 -1
  44. package/dist/queue/approvals.d.ts +49 -0
  45. package/dist/queue/approvals.d.ts.map +1 -0
  46. package/dist/queue/approvals.js +68 -0
  47. package/dist/queue/approvals.js.map +1 -0
  48. package/dist/queue/cli.d.ts +3 -0
  49. package/dist/queue/cli.d.ts.map +1 -0
  50. package/dist/queue/cli.js +115 -0
  51. package/dist/queue/cli.js.map +1 -0
  52. package/dist/queue/executor.d.ts +24 -0
  53. package/dist/queue/executor.d.ts.map +1 -0
  54. package/dist/queue/executor.js +445 -0
  55. package/dist/queue/executor.js.map +1 -0
  56. package/dist/queue/lifecycle.d.ts +3 -0
  57. package/dist/queue/lifecycle.d.ts.map +1 -0
  58. package/dist/queue/lifecycle.js +24 -0
  59. package/dist/queue/lifecycle.js.map +1 -0
  60. package/dist/queue/queue.d.ts +171 -0
  61. package/dist/queue/queue.d.ts.map +1 -0
  62. package/dist/queue/queue.js +506 -0
  63. package/dist/queue/queue.js.map +1 -0
  64. package/dist/queue/service.d.ts +15 -0
  65. package/dist/queue/service.d.ts.map +1 -0
  66. package/dist/queue/service.js +152 -0
  67. package/dist/queue/service.js.map +1 -0
  68. package/dist/queue/storage.d.ts +32 -0
  69. package/dist/queue/storage.d.ts.map +1 -0
  70. package/dist/queue/storage.js +180 -0
  71. package/dist/queue/storage.js.map +1 -0
  72. package/dist/queue/tools.d.ts +12 -0
  73. package/dist/queue/tools.d.ts.map +1 -0
  74. package/dist/queue/tools.js +155 -0
  75. package/dist/queue/tools.js.map +1 -0
  76. package/docs/MIGRATION.md +32 -11
  77. package/docs/QUEUE.md +151 -0
  78. package/docs/SECURITY.md +38 -31
  79. package/docs/TROUBLESHOOTING.md +34 -11
  80. package/package.json +1 -1
  81. package/templates/.opencode/agents/scheduled-planner.md +64 -131
  82. package/templates/.opencode/commands/abort-task.md +6 -15
  83. package/templates/.opencode/commands/acceptance.md +6 -15
  84. package/templates/.opencode/commands/change.md +3 -1
  85. package/templates/.opencode/commands/resume-review.md +6 -14
  86. package/templates/.opencode/commands/resume-task.md +6 -23
  87. package/templates/.opencode/skills/scheduled-quality-orchestrator/SKILL.md +72 -248
  88. package/templates/AGENTS.md.fragment +8 -0
  89. package/templates/automation/config.json +8 -2
  90. package/templates/automation/config.schema.json +218 -46
  91. package/templates/scripts/automation/abort-task.sh +2 -1
  92. package/templates/scripts/automation/accept-and-integrate.sh +5 -0
  93. package/templates/scripts/automation/acceptance-report.sh +4 -2
  94. package/templates/scripts/automation/approve-and-run.sh +4 -0
  95. package/templates/scripts/automation/begin-review.sh +1 -0
  96. package/templates/scripts/automation/block-task.sh +1 -0
  97. package/templates/scripts/automation/claim-task.sh +1 -0
  98. package/templates/scripts/automation/lib.sh +94 -1
  99. package/templates/scripts/automation/orchestrate-task.sh +11 -0
  100. package/templates/scripts/automation/preflight.sh +14 -4
  101. package/templates/scripts/automation/prepare-contract-review.sh +4 -0
  102. package/templates/scripts/automation/quality-gate.sh +1 -0
  103. package/templates/scripts/automation/record-red.sh +1 -0
  104. package/templates/scripts/automation/resume-review-fix.sh +1 -0
  105. package/templates/scripts/automation/resume-review.sh +1 -0
  106. package/templates/scripts/automation/resume-task.sh +1 -0
  107. package/templates/scripts/automation/scope-gate.sh +10 -2
  108. package/templates/scripts/automation/submit-review.sh +8 -2
  109. package/templates/scripts/automation/verify-task.sh +13 -0
package/docs/MIGRATION.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Migration guide
2
2
 
3
3
  This guide covers migration to
4
- `@frankzhang2026/opencode-android-orchestrator@0.10.0`. Pin the exact version and
4
+ `@frankzhang2026/opencode-android-orchestrator@1.0.1`. Pin the exact version and
5
5
  prove the migration in a disposable clone before changing a long-lived
6
6
  repository.
7
7
 
@@ -9,13 +9,14 @@ repository.
9
9
 
10
10
  | Current state | Correct command after release | Important distinction |
11
11
  | --- | --- | --- |
12
- | No orchestrator files or manifest | `npx @frankzhang2026/opencode-android-orchestrator@0.10.0 init .` | Normal new installation; all runtime-detected Android modules and registered debug verification tasks are discovered automatically. |
12
+ | No orchestrator files or manifest | `npx @frankzhang2026/opencode-android-orchestrator@1.0.1 init .` | Normal new installation; all runtime-detected Android modules and registered debug verification tasks are discovered automatically. |
13
13
  | Published `0.1.0` scaffold only | Remove any project-local `@0.1.0` plugin reference after review, then run `init`. | `0.1.0` did not create a usable managed installation and cannot be upgraded. |
14
- | `0.2.0` through `0.9.0` manifest-managed installation with intact managed/backup content | Run the `0.10.0` `upgrade`; add `--refresh-gradle-discovery` when generated module/task lists are incomplete. | Refresh replaces all derived module metadata, source paths, protected build files, and task allowlists from one Gradle runtime snapshot. Module scope, operator policies, user-owned AGENTS content, and an existing commit-prefix sidecar remain preserved. |
14
+ | `0.2.0` through `0.10.0` manifest-managed installation with intact managed/backup content | Run the `1.0.0` `upgrade`; add `--refresh-gradle-discovery` when generated module/task lists are incomplete. | Refresh replaces all derived module metadata, source paths, protected build files, and task allowlists from one Gradle runtime snapshot. Module scope, operator policies, user-owned AGENTS content, and an existing commit-prefix sidecar remain preserved. |
15
+ | Healthy `1.0.0` installation | Stop the queue service, finish or abort retained workspaces, then run the fixed `1.0.1` `upgrade`. | Pending inbox contracts remain durable. Restart OpenCode so Planner loads the bounded snapshot actions. |
15
16
  | Manually copied V3 files, no `.automation-plugin/manifest.json` | Finish active tasks, preserve historical evidence separately, then run `init`. | Exact files can be reused; differing managed files fail as conflicts. |
16
17
  | Healthy older manifest-managed installation | Run `doctor`, then the fixed target version's `upgrade`. | `upgrade` requires a valid installed manifest and intact original backups. |
17
18
  | Healthy current-version manifest | Run `doctor`; repeated `init` or same-version `upgrade` is verification-only and byte-idempotent. | Do not reinstall or delete the manifest. |
18
- | Damaged manifest, ordinary managed-content drift, or damaged backup content | Stop and investigate. | `init` and `upgrade` intentionally refuse to overwrite this state. AGENTS content outside its managed block and Unix-mode drift are handled by `0.10.0 upgrade`. |
19
+ | Damaged manifest, ordinary managed-content drift, or damaged backup content | Stop and investigate. | `init` and `upgrade` intentionally refuse to overwrite this state. AGENTS content outside its managed block and Unix-mode drift are handled by `1.0.0 upgrade`. |
19
20
 
20
21
  `uninstall` is not an upgrade shortcut. It restores verified pre-install files,
21
22
  removes unchanged plugin-created files, and retains drift for manual review.
@@ -35,7 +36,7 @@ removes unchanged plugin-created files, and retains drift for manual review.
35
36
  support bundle.
36
37
  5. If a managed manifest already exists, the installed version's doctor may be
37
38
  used to collect read-only evidence. A mode warning/failure or an AGENTS
38
- content mismatch does not by itself prevent `0.10.0 upgrade`; the target
39
+ content mismatch does not by itself prevent `1.0.0 upgrade`; the target
39
40
  upgrade performs its own content-safe checks. Do not edit manifest hashes to
40
41
  make doctor pass.
41
42
  6. Prove the migration in a disposable clone or temporary Android fixture
@@ -50,14 +51,14 @@ scaffold, not as an older managed installation.
50
51
  If the project OpenCode configuration contains an exact
51
52
  `@frankzhang2026/opencode-android-orchestrator@0.1.0` entry, save the file and
52
53
  remove only that obsolete entry in a reviewed Git change before running
53
- `0.10.0 init`. The merger deliberately rejects a different version of the same
54
+ `1.0.0 init`. The merger deliberately rejects a different version of the same
54
55
  managed package; it will not silently replace the reference. A global npm
55
56
  installation of `0.1.0` alone does not require project-file cleanup.
56
57
 
57
58
  After release, initialize with the fixed version:
58
59
 
59
60
  ```sh
60
- npx @frankzhang2026/opencode-android-orchestrator@0.10.0 init .
61
+ npx @frankzhang2026/opencode-android-orchestrator@1.0.1 init .
61
62
  ```
62
63
 
63
64
  New installations default to all-module scope, so multiple application modules
@@ -105,7 +106,7 @@ Use the lifecycle command selected by the active manifest:
105
106
 
106
107
  ```sh
107
108
  npx --yes --registry=https://registry.npmjs.org/ \
108
- @frankzhang2026/opencode-android-orchestrator@0.10.0 upgrade . --json
109
+ @frankzhang2026/opencode-android-orchestrator@1.0.1 upgrade . --json
109
110
  ```
110
111
 
111
112
  The command-level Registry option is useful when a company-wide npm Registry
@@ -135,7 +136,7 @@ computed includes dynamically or a company convention plugin applied
135
136
 
136
137
  ```sh
137
138
  npx --yes --registry=https://registry.npmjs.org/ \
138
- @frankzhang2026/opencode-android-orchestrator@0.10.0 upgrade . \
139
+ @frankzhang2026/opencode-android-orchestrator@1.0.1 upgrade . \
139
140
  --refresh-gradle-discovery --json
140
141
  ```
141
142
 
@@ -146,7 +147,7 @@ task report. The resulting module/path/task configuration is written through
146
147
  the normal verified upgrade transaction. Omit the flag when the installed task
147
148
  matrix was intentionally supplied with `--gradle-verification-config` and must
148
149
  remain unchanged. An explicit refresh may be rerun on an already installed
149
- `0.10.0` after the Gradle module graph changes; if its generated resources are
150
+ `1.0.0` after the Gradle module graph changes; if its generated resources are
150
151
  unchanged, the operation remains byte-idempotent.
151
152
 
152
153
  Upgrade also preserves an installed `longCommandTimeoutMs`. Installations from
@@ -194,12 +195,32 @@ The command refuses:
194
195
  Do not repair those conditions by editing the manifest or its hashes. Diagnose
195
196
  the source of drift and use the recorded recovery data.
196
197
 
198
+ ## Moving to the durable 1.0.0 queue
199
+
200
+ Finish or explicitly abort legacy active tasks before upgrading. For an existing
201
+ 1.0.0 installation, stop its background service and complete/abort retained
202
+ workspaces first. The upgrade lock shares queue arbitration so execution cannot
203
+ start while resources are being replaced. Pending inbox contracts remain in the
204
+ Git common directory through upgrade and uninstall; legacy on-disk contracts
205
+ are not silently approved or imported.
206
+
207
+ Schema V6 preserves the selected workspace strategy and defaults missing commit
208
+ policy to `humanApproval`. Old contract approvals never acquire `autoCommit`
209
+ from a changed global default. Queue execution requires full unit tests enabled;
210
+ a migrated `unitTestsEnabled: false` remains preserved but blocks queue
211
+ consumption until the operator enables and commits the setting.
212
+
213
+ Restart OpenCode after upgrading so Planner loads the new bounded intake tools
214
+ and question-receipt hooks. `/change` returns after enqueue; the background
215
+ service owns subsequent execution. Human acceptance and isolated revalidation
216
+ use the queue rather than the old direct Shell commands. See [Queue operation](QUEUE.md).
217
+
197
218
  ## Post-migration verification
198
219
 
199
220
  Run all checks from the detected Git root:
200
221
 
201
222
  ```sh
202
- npx @frankzhang2026/opencode-android-orchestrator@0.10.0 doctor .
223
+ npx @frankzhang2026/opencode-android-orchestrator@1.0.1 doctor .
203
224
  opencode debug config
204
225
  opencode debug skill
205
226
  opencode debug agent scheduled-planner
package/docs/QUEUE.md ADDED
@@ -0,0 +1,151 @@
1
+ # Queue and background execution
2
+
3
+ Version `1.0.1` stores proposals and approved contracts under
4
+ `<git-common-dir>/automation-runtime/inbox/queue.json`. A contract is runnable
5
+ only after its full plan, version, digest, target branch and commit policy are
6
+ approved and durably recorded. Planning reads a fixed `planningHead`, so another
7
+ Coder's active files and branch do not affect the proposal.
8
+
9
+ Planner first receives compact branch and commit metadata. It discovers paths
10
+ through bounded `list` pages and reads exact UTF-8 content through bounded
11
+ `readChunk` pages. Every cursor is tied to the same `planningHead` and query;
12
+ changing the commit, path, prefix or query rejects the cursor.
13
+
14
+ ## Normal use
15
+
16
+ Start OpenCode with `scheduled-planner` and use `/change`. Approve the displayed
17
+ proposal and the returned contract question. After enqueue, Planner returns;
18
+ you can plan and approve B or C while A is executing or awaiting acceptance.
19
+ Only the current task's plan and contract enter its working diff.
20
+
21
+ Defaults are `inPlaceExclusive` and `humanApproval`. Human tasks stop at
22
+ `AWAITING_HUMAN`; `/acceptance TASK-ID` presents the latest review and candidate
23
+ and asks a new question before requesting integration. Automatic tasks must
24
+ explicitly select `autoCommit` in their reviewed contract and proceed from
25
+ `READY_TO_COMMIT` to local commit and integration without a final question.
26
+ They never produce a fabricated human-acceptance record. Completion shows the
27
+ local commit SHA, authorization source and `pushed: false` (未推送).
28
+
29
+ | Workspace policy | Commit policy | When the next independent task may start |
30
+ | --- | --- | --- |
31
+ | `inPlaceExclusive` (default) | `humanApproval` (default) | After acceptance, local integration and directory handoff, or approved abort |
32
+ | `inPlaceExclusive` | Explicitly sealed `autoCommit` | After build, full tests, Review, local commit/integration and handoff |
33
+ | `isolatedWorktree` | `humanApproval` | After the worker and its children exit and its result is safely sealed |
34
+ | `isolatedWorktree` | `autoCommit` | Rejected; fresh compatible policy approval is required |
35
+
36
+ Both workspaces use one execution slot per Git common directory. A retained
37
+ isolated candidate keeps its own directory; revalidation and integration must
38
+ reacquire that same slot. Dependencies wait for `COMPLETED`, which means
39
+ integrated locally. Review approval and commit creation alone do not satisfy a
40
+ dependency. Fixed workspaces remain occupied during failures and human waiting.
41
+
42
+ The worker resolves the Android SDK from `ANDROID_HOME`, `ANDROID_SDK_ROOT`,
43
+ then the source repository's `local.properties` and passes the resolved location
44
+ to its shell and Gradle processes. Isolated worktrees do not copy that local file.
45
+
46
+ ## Service and scheduling
47
+
48
+ The first enqueue starts the package-owned detached service. Closing the
49
+ Planner does not stop it. Enqueue notifications, deadlines, worker completion,
50
+ startup recovery and periodic scans all use the same atomic reservation logic.
51
+ Idle scans do not call a model. No launchd or external Scheduler is registered.
52
+ The machine must be awake; a restarted service scans overdue entries once
53
+ through normal arbitration. Recurring task-template generation is not exposed
54
+ in this release; each approved contract has at most one initial execution.
55
+
56
+ `notBefore` requires an ISO timestamp with an explicit timezone, for example
57
+ `2026-09-14T22:00:00+08:00`. `dependsOn` contains previously approved task IDs.
58
+ Default ordering is FIFO; priority ranges from -100 to 100, higher first, without
59
+ preempting active work. Duplicate approval of a version returns its queue item.
60
+ To revise an unstarted approval, cancel it and approve a new draft version.
61
+ An executing version stays sealed; use a new task ID for later changes.
62
+
63
+ ```sh
64
+ opencode-android-orchestrator queue status .
65
+ opencode-android-orchestrator queue status . TASK-A
66
+ opencode-android-orchestrator queue pause .
67
+ opencode-android-orchestrator queue resume .
68
+ opencode-android-orchestrator queue priority . TASK-B 10
69
+ opencode-android-orchestrator queue cancel . TASK-C
70
+ opencode-android-orchestrator queue stop .
71
+ opencode-android-orchestrator queue start .
72
+ ```
73
+
74
+ An unsuccessful OpenCode agent process pauses consumption as a shared execution
75
+ fault; inspect its log and fix provider/environment failures before clearing it.
76
+
77
+ Pause stops new reservations. Stop terminates the scheduler while preserving
78
+ its active detached worker. Resume does not clear a fault. Notifications are
79
+ persisted until acknowledged, so the original Planner session need not remain
80
+ open. `queue --help` lists direct local-operator commands; interactive agents
81
+ use bounded plugin tools and actual question receipts instead of the CLI.
82
+
83
+ ## Policy, capacity and verification
84
+
85
+ Pause and finish/abort retained workspaces before changing repository mode:
86
+
87
+ ```sh
88
+ opencode-android-orchestrator queue pause .
89
+ opencode-android-orchestrator queue policy . isolatedWorktree humanApproval
90
+ ```
91
+
92
+ Review and commit the changed `automation/config.json` before resuming. The
93
+ queued task fixes its workspace strategy when claimed. Its commit authorization
94
+ remains exactly the approved choice: changing a default cannot grant autoCommit
95
+ to an older task. Direct configuration drift while a workspace is retained
96
+ blocks scheduling; restore the recorded strategy before recovery.
97
+
98
+ Schema V6 queue defaults are `scanIntervalMs: 5000`, `maxWorkspaces: 3` and
99
+ `maxWorkspaceBytes: 21474836480`. Capacity includes retained isolated workspaces,
100
+ including completed directories when automatic cleanup is disabled. Reaching
101
+ count or disk limits pauses new isolated execution while still accepting intake;
102
+ acceptance, recovery and cleanup of existing tasks remain eligible. Occupied or
103
+ failed directories are never deleted simply to free queue capacity.
104
+
105
+ Queued execution requires `unitTestsEnabled: true`. A temporary Gradle init
106
+ script disables up-to-date and output-cache reuse only for Test tasks, records
107
+ actual suite results and rejects missing/skipped-only evidence. The invocation
108
+ uses `--no-configuration-cache`; compilation and build caches remain usable.
109
+ It does not run `clean` or rerun all dependency tasks. Coder, Reviewer and local
110
+ integration perform the configured full suite and build gates. Evidence records
111
+ fresh-test logs, configured tasks and elapsed seconds.
112
+
113
+ ## Baselines and recovery
114
+
115
+ Before execution, changes to contract-relevant files or execution configuration
116
+ since planning require a revised contract and fresh approval. Planning files of
117
+ other completed queue tasks are not treated as execution configuration changes.
118
+ For an isolated waiting candidate whose local target advanced, request
119
+ `revalidate`; it preserves the original evidence, rebases a nonconflicting
120
+ uncommitted candidate in the same worktree, reruns build/full tests/Review and
121
+ produces a new candidate ID. Conflicts or policy changes preserve the workspace
122
+ and block progress. Old final acceptance cannot approve the new candidate.
123
+
124
+ All local commits use a persisted transaction: `INTENT`, `COMMITTED`, `VERIFIED`,
125
+ `INTEGRATED`, `COMPLETED`. Recovery checks the sealed tree, parent, target,
126
+ authorization and local refs before reusing a commit or completing handoff.
127
+ It never force-updates the target or pushes. A fixed directory is reusable only
128
+ after local integration and handoff succeed.
129
+
130
+ ```sh
131
+ opencode-android-orchestrator queue recover-lock .
132
+ opencode-android-orchestrator queue recover-execution .
133
+ opencode-android-orchestrator queue recover . TASK-A
134
+ opencode-android-orchestrator queue clear-fault .
135
+ ```
136
+
137
+ Inspect status and evidence first. Lock recovery proves the recorded owner has
138
+ exited; a heartbeat timeout alone never steals a live lock. Execution recovery
139
+ also checks the whole worker process group. If a reservation has no registered
140
+ worker, stop its recorded launcher before recovering it. Unknown ownership
141
+ retains the execution slot. `recover` is only for an existing sealed commit
142
+ transaction; baseline/Reviewer interruptions use `/resume-task` or
143
+ `/resume-review`. Running cancellation uses `/abort-task` and waits for a safe
144
+ agent boundary before archival through the execution slot. A hung external
145
+ process must be diagnosed and stopped before ownership recovery can succeed.
146
+
147
+ Upgrade and uninstall require the service stopped, no active execution, and no
148
+ retained unfinished workspace. Inbox, notifications and audit data remain in
149
+ the Git common directory. Commit-message prefix and worktree-allowlist sidecars
150
+ remain human-owned. See [Migration](MIGRATION.md), [Troubleshooting](TROUBLESHOOTING.md)
151
+ and [Security](SECURITY.md) for lifecycle and trust boundaries.
package/docs/SECURITY.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Security model
2
2
 
3
3
  This document describes the security properties of
4
- `@frankzhang2026/opencode-android-orchestrator@0.10.0`. The lifecycle foundation
4
+ `@frankzhang2026/opencode-android-orchestrator@1.0.1`. The lifecycle foundation
5
5
  completed the real OpenCode `1.14.22` and `1.15.13` release matrix in `0.2.0`;
6
- `0.10.0` retains that compatibility boundary.
6
+ `1.0.0` retains that compatibility boundary.
7
7
 
8
8
  ## Security goals and non-goals
9
9
 
@@ -38,31 +38,34 @@ perform actions outside the orchestrator's intended scope.
38
38
 
39
39
  ## Human approval boundary
40
40
 
41
- The normal workflow has three fresh OpenCode `question` selections: proposal,
42
- sealed contract, and final result. Direct chat prose, silence, a dismissed
43
- question, or a copied option label is not a normal-path approval. Baseline-only
44
- recovery and exceptional abort each have their own fresh status/question
45
- boundary.
46
-
47
- Approval phrases stored in `automation/config.json` are validation tokens, not
48
- secrets or cryptographic proof. Security depends on the scheduled planner
49
- showing the current review material, the user acting at that boundary, and the
50
- fixed Shell script independently verifying state, hashes, refs, scope, and
51
- leases. Anyone with direct shell and repository write access can invoke or
52
- modify local files; this package does not claim to protect against that actor.
53
-
54
- OpenCode permission prompts are also not semantic workflow approval. They can
55
- be accepted for the remainder of a session and may be auto-approved. For that
56
- reason `0.8.0` exposes only `android_orchestrator_status` and
57
- `android_orchestrator_doctor` as custom tools. State-changing wrappers remain a
58
- NO-GO until a one-use, non-model-forgeable receipt can bind the approval kind,
59
- task, session/message, sealed SHA or branch, time, and nonce.
41
+ Proposal and contract approval always require fresh OpenCode `question`
42
+ selections. The default `humanApproval` policy additionally requires final
43
+ candidate acceptance. Explicit `autoCommit` authorization is sealed during
44
+ contract approval and replaces only the final human question; build, actual
45
+ full unit tests and independent Review remain mandatory.
46
+
47
+ The plugin observes the host's question arguments and completed answer
48
+ metadata through the common before/after hooks. Its one-use receipt binds
49
+ session, consuming message, question call, operation, task/digest and candidate.
50
+ Changed questions, multi-select answers, ordinary chat, copied labels, another
51
+ session and already consumed receipts cannot authorize a tool mutation. A new
52
+ candidate requires a new acceptance question. Receipts expire after 15 minutes
53
+ and are lost on plugin restart; completed enqueue and consumed proof are stored
54
+ in the durable queue. Repeated enqueue cannot create a second execution.
55
+
56
+ The older mutating-wrapper NO-GO decision is superseded only by the bounded
57
+ 1.0.0 queue interfaces and these receipts. Permission prompts still do not grant
58
+ semantic workflow approval. Direct CLI use is a trusted local-operator surface;
59
+ Planner/Coder/Reviewer cannot call arbitrary CLI commands. An actor who can
60
+ modify the package, host hooks, repository or runtime files remains outside
61
+ this enforcement boundary.
60
62
 
61
63
  ## Agent and tool permissions
62
64
 
63
65
  All three installed agents start with `"*": deny` and add exact permissions.
64
- The planner can write only new planning artifacts and invoke the small set of
65
- orchestration scripts. The Coder can edit detected production/test source sets
66
+ The Planner reads committed Git objects through snapshot and writes only
67
+ the independent inbox through authenticated intake tools. It cannot directly
68
+ read/edit the active working files, run Bash or call execution scripts. The Coder can edit detected production/test source sets
66
69
  but not Gradle, OpenCode, automation, or control files. Reviewer edit access is
67
70
  denied. Subagents, Scheduler/job tools, external directories, web access, push,
68
71
  merge/rebase, destructive Git commands, shell composition, and launchd are
@@ -85,7 +88,8 @@ The read-only status tool additionally:
85
88
  Doctor invokes read-only project, dependency, SDK, and installation checks and
86
89
  returns their failures instead of repairing the project.
87
90
 
88
- The compatible `tool.execute.before` hook may only raise the timeout argument
91
+ The compatible `tool.execute.before` hook validates unattended shell commands,
92
+ records approval challenges and may raise the timeout argument
89
93
  for a fixed list of direct managed long-running scripts. Its generated config
90
94
  value is an integer from `120000` through `7200000` milliseconds, defaults to
91
95
  `1800000`, never shortens a larger caller timeout, and does not rewrite the
@@ -130,13 +134,14 @@ while Gradle settings/build files and orchestration resources remain protected.
130
134
  legacy configuration with no scope field as `primary`, preventing an implicit
131
135
  permission expansion.
132
136
 
133
- `unitTestsEnabled`, `lintEnabled`, and `commitMessagePrefixMode` are the
134
- operator-editable fields in the otherwise manifest-managed
137
+ `unitTestsEnabled`, `lintEnabled`, `commitMessagePrefixMode` and bounded
138
+ queue/workspace policies are the operator-editable fields in the otherwise manifest-managed
135
139
  `automation/config.json`. Upgrade authenticates
136
140
  the remaining generated content before preserving those values, and doctor
137
141
  validates the resulting adaptive configuration. Task agents still cannot edit
138
142
  the protected file. Unit tests default on and lint defaults off; disabling unit
139
- verification does not remove the mandatory RED evidence step. Assemble, scope,
143
+ verification blocks queue consumption and does not remove the mandatory RED
144
+ evidence step for legacy non-queue tasks. Assemble, scope,
140
145
  evidence, and required device-test gates are unaffected.
141
146
 
142
147
  When commit prefix mode is `required`, the regular UTF-8 sidecar
@@ -191,14 +196,15 @@ the recorded before/after hashes and Git refs.
191
196
  ## Git and orchestration invariants
192
197
 
193
198
  - The source repository must have an identifiable original branch and baseline
194
- HEAD. Original-branch drift blocks integration.
199
+ HEAD. Fixed-directory branch drift blocks integration; isolated drift
200
+ requires new full verification, independent Review and human acceptance.
195
201
  - The persistent repository lease prevents concurrent orchestrated tasks from
196
202
  sharing a mutable repository workspace.
197
203
  - Planning artifacts remain uncommitted until the verified product change is
198
204
  ready. Successful integration creates exactly one combined local commit.
199
205
  - Scope gates inspect tracked and untracked changes, reject protected paths and
200
206
  obvious test weakening, and bind the accepted result to a diff SHA.
201
- - An approved task snapshots the validated worktree allowlist. Listed local
207
+ - Workspace preparation snapshots the validated worktree allowlist. Listed local
202
208
  changes are excluded consistently from cleanliness, scope, hashes, evidence,
203
209
  archival, and commits; explicit commit pathsets preserve allowlisted staged
204
210
  entries, and rename detection cannot hide an unlisted source path. Changing
@@ -216,8 +222,9 @@ the recorded before/after hashes and Git refs.
216
222
  - Abort rejects out-of-contract/protected paths, archives the diff, and avoids
217
223
  changing the original branch ref.
218
224
 
219
- Git hooks and Git configuration remain part of the host repository's trust
220
- surface. Review them before running a workflow in an untrusted project.
225
+ Queue-controlled Git writes disable hooks and create local commit objects
226
+ from a sealed tree. Git configuration and project-executed code still remain
227
+ part of the host repository's trust surface. Review them before running a workflow in an untrusted project.
221
228
 
222
229
  ## Dependencies and network behavior
223
230
 
@@ -1,7 +1,7 @@
1
1
  # Troubleshooting
2
2
 
3
3
  Use this guide for
4
- `@frankzhang2026/opencode-android-orchestrator@0.10.0`.
4
+ `@frankzhang2026/opencode-android-orchestrator@1.0.1`.
5
5
 
6
6
  ## Start with read-only evidence
7
7
 
@@ -11,7 +11,7 @@ From the repository root, capture:
11
11
  git status --short --branch
12
12
  git rev-parse HEAD
13
13
  opencode --version
14
- npx @frankzhang2026/opencode-android-orchestrator@0.10.0 doctor . --json
14
+ npx @frankzhang2026/opencode-android-orchestrator@1.0.1 doctor . --json
15
15
  ```
16
16
 
17
17
  If installation never completed, doctor will correctly report a missing or
@@ -39,9 +39,9 @@ command-scoped override:
39
39
 
40
40
  ```sh
41
41
  npm --registry=https://registry.npmjs.org/ view \
42
- @frankzhang2026/opencode-android-orchestrator@0.10.0 version
42
+ @frankzhang2026/opencode-android-orchestrator@1.0.1 version
43
43
  npx --yes --registry=https://registry.npmjs.org/ \
44
- @frankzhang2026/opencode-android-orchestrator@0.10.0 upgrade . --json
44
+ @frankzhang2026/opencode-android-orchestrator@1.0.1 upgrade . --json
45
45
  ```
46
46
 
47
47
  This leaves the company's saved npm configuration unchanged. Use the option
@@ -71,7 +71,7 @@ Git-backed Superpowers plugin at runtime.
71
71
  | 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
72
  | 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
73
  | 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 `0.10.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. |
74
+ | `Bundled Orchestrator skill is unavailable` | The installed `1.0.1` 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
75
  | 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. |
76
76
 
77
77
  Version `0.6.0` always passes `--no-configuration-cache` to its temporary
@@ -87,7 +87,7 @@ silence of `./gradlew tasks --all --console=plain | rg ...` in a large build.
87
87
  For an existing installation, run:
88
88
 
89
89
  ```sh
90
- npx @frankzhang2026/opencode-android-orchestrator@0.10.0 upgrade . \
90
+ npx @frankzhang2026/opencode-android-orchestrator@1.0.1 upgrade . \
91
91
  --refresh-gradle-discovery
92
92
  ```
93
93
 
@@ -96,7 +96,7 @@ least `1800000` milliseconds. A higher timeout already supplied by the caller
96
96
  is preserved; unrelated Bash commands are unchanged. To configure one hour,
97
97
  run `upgrade . --long-command-timeout-ms 3600000` on a healthy installation.
98
98
  If a command still reports `120000 ms`, confirm that the project manifest and
99
- OpenCode plugin reference are both `0.10.0`, restart the OpenCode session so the
99
+ OpenCode plugin reference are both `1.0.1`, restart the OpenCode session so the
100
100
  plugin reloads, and rerun doctor before attempting recovery.
101
101
 
102
102
  After installation, inspect OpenCode discovery separately:
@@ -151,7 +151,7 @@ Common fail-closed codes include:
151
151
  | `PLUGIN_VERSION_CONFLICT` | The same managed package identity has another reference/version. | Review and remove or migrate only the obsolete entry; never let init silently replace it. |
152
152
  | `DUPLICATE_PLUGIN` or `DUPLICATE_PROPERTY` | Configuration identity is ambiguous. | Correct the JSON/JSONC structure without discarding unrelated fields or comments. |
153
153
  | `INVALID_JSONC` or `ROOT_NOT_OBJECT` | OpenCode configuration cannot be merged safely. | Repair the user-owned file and validate it before retrying. |
154
- | `AGENTS_BLOCK_CONFLICT` or `AGENTS_MARKERS_INVALID` | During `init`, the bounded block was modified; or a lifecycle command found partial, out-of-order, or duplicate markers. | Keep project-specific instructions outside one valid marker pair. `0.10.0 upgrade` preserves marker-external changes and replaces the old managed block; malformed marker structure still requires manual repair. |
154
+ | `AGENTS_BLOCK_CONFLICT` or `AGENTS_MARKERS_INVALID` | During `init`, the bounded block was modified; or a lifecycle command found partial, out-of-order, or duplicate markers. | Keep project-specific instructions outside one valid marker pair. `1.0.0 upgrade` preserves marker-external changes and replaces the old managed block; malformed marker structure still requires manual repair. |
155
155
  | `FILE_SYMLINK`, `TARGET_SYMLINK`, or `CONFIG_SYMLINK` | A managed target or ancestor is a symbolic link. | Replace it only after understanding ownership and destination. The installer intentionally does not follow it. |
156
156
  | `PLAN_STALE` or `TARGET_MODIFIED` | A file changed between planning and application. | Stop concurrent edits, inspect the diff, and rerun from a stable state. |
157
157
 
@@ -170,8 +170,8 @@ configuration.
170
170
  | --- | --- | --- |
171
171
  | `MANIFEST_MISSING`, `MANIFEST_INVALID`, or `MANIFEST_STATE` | No trustworthy installed manifest is available. | Do not invent a manifest or copy one from another project. Determine whether this is an uninstalled/manual setup or an interrupted transaction. |
172
172
  | `EXISTING_INSTALLATION_DIFFERENT` | `init` found another installed inventory/version. | Use `upgrade` for a healthy older manifest. |
173
- | `EXISTING_INSTALLATION_INVALID` or `INSTALLATION_INVALID` | Manifest, installed files, or required backups failed structural or content validation. In `0.8.0`, this also reported an active manifest whose mode was not exactly `0600`. | Preserve the project and `.automation-plugin/`; use `0.10.0 upgrade` for mode-only drift, and inspect other doctor details or recovery history. |
174
- | `INSTALLED_FILES_MODIFIED` | Upgrade found content/existence drift in an ordinary managed file or missing/modified backup content. | Move intentional customization out of ordinary managed paths or choose manual recovery. `0.10.0` separately merges user-owned `AGENTS.md` content and does not reject mode-only drift. |
173
+ | `EXISTING_INSTALLATION_INVALID` or `INSTALLATION_INVALID` | Manifest, installed files, or required backups failed structural or content validation. In `0.8.0`, this also reported an active manifest whose mode was not exactly `0600`. | Preserve the project and `.automation-plugin/`; use `1.0.0 upgrade` for mode-only drift, and inspect other doctor details or recovery history. |
174
+ | `INSTALLED_FILES_MODIFIED` | Upgrade found content/existence drift in an ordinary managed file or missing/modified backup content. | Move intentional customization out of ordinary managed paths or choose manual recovery. `1.0.0` separately merges user-owned `AGENTS.md` content and does not reject mode-only drift. |
175
175
  | `VERSION_DOWNGRADE_REFUSED` | Target package is older than the installed manifest. | Use a newer fixed package version; never edit the manifest version. |
176
176
  | `UPGRADE_IN_PROGRESS` or `UNINSTALL_IN_PROGRESS` | `.automation-plugin/upgrade.json` or `uninstall.json` records an unfinished transaction. | Inspect the marker and matching recovery directory. Do not delete the marker merely to retry. |
177
177
  | `POST_UPGRADE_VERIFICATION_FAILED` | New resources failed verification. | The implementation attempts a complete old-version rollback; verify the old manifest and inspect upgrade evidence. |
@@ -182,7 +182,7 @@ configuration.
182
182
  Installer control paths are:
183
183
 
184
184
  - active manifest: `.automation-plugin/manifest.json` (new manifests are
185
- written as `0600`; mode-only drift does not block `0.10.0 upgrade`);
185
+ written as `0600`; mode-only drift does not block `1.0.0 upgrade`);
186
186
  - first-install/original backups: `.automation-plugin/backups/<id>/`;
187
187
  - upgrade marker and snapshots: `.automation-plugin/upgrade.json` and
188
188
  `.automation-plugin/upgrades/<id>/`;
@@ -236,6 +236,29 @@ identify the state, workspace, original branch, sealed diff, and evidence.
236
236
  - `TEST_FAILED` or `NEEDS_HUMAN`: inspect the contract and evidence. Do not
237
237
  broaden scope or silently queue the same task again.
238
238
 
239
+ ## Durable queue failures in 1.0.0
240
+
241
+ Start with `opencode-android-orchestrator queue status .` and the task's detailed
242
+ status. The queue and commit transaction are authoritative; an old Planner
243
+ session or a missing notification is not evidence that a task never started.
244
+
245
+ | Symptom | Recovery |
246
+ | --- | --- |
247
+ | Fresh matching question receipt required | Show a new queue review/draft question and select it in the same Planner session; do not paste its approval label into chat. |
248
+ | Waiting for human confirmation or fixed workspace | Accept the current candidate or use the approved abort workflow; further contracts may still be enqueued. |
249
+ | Isolated capacity reached | Integrate or explicitly archive retained workspaces; do not delete failed work simply to advance the queue. |
250
+ | Execution launch ownership unknown | Stop the recorded launcher, prove it exited, then use `queue recover-execution .`; preserve any partial workspace. |
251
+ | Dead transaction owner | Inspect the lock record and use explicit `queue recover-lock .`; a live PID or surviving child process blocks takeover. |
252
+ | OpenCode process failure | Inspect the current agent log, repair provider/environment access, then clear the fault while idle. Resume alone does not clear it. |
253
+ | Local commit already exists but task is blocked | Use `queue recover . TASK-ID`; it reuses the sealed transaction instead of creating another visible commit. |
254
+ | Target advanced for an isolated candidate | Request `revalidate`, wait for fresh full tests/Review, and confirm the new candidate. |
255
+ | Upgrade/uninstall reports a retained workspace | Stop scheduling and finish or approve abort before replacing runtime resources. |
256
+
257
+ The service launches the packaged queue entry with Node.js, independently of the
258
+ OpenCode/Bun executable. Ensure `node` is on the service's inherited `PATH`.
259
+ There is no model polling while idle and no launchd registration. After reboot,
260
+ start the service or enqueue a contract to resume durable scanning.
261
+
239
262
  ## Actions to avoid
240
263
 
241
264
  Never use a troubleshooting shortcut that destroys the evidence needed to
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frankzhang2026/opencode-android-orchestrator",
3
- "version": "0.10.0",
3
+ "version": "1.0.1",
4
4
  "description": "Reusable OpenCode orchestration for Android projects",
5
5
  "license": "MIT",
6
6
  "author": "frankzhang2026",