@jterrats/open-orchestra 1.0.8 → 1.0.10

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 (188) hide show
  1. package/AGENTS.md +15 -2
  2. package/CLAUDE.md +16 -2
  3. package/dist/acceptance-criteria-quality.d.ts +12 -0
  4. package/dist/acceptance-criteria-quality.js +137 -0
  5. package/dist/acceptance-criteria-quality.js.map +1 -0
  6. package/dist/architecture-debt-inventory.d.ts +31 -0
  7. package/dist/architecture-debt-inventory.js +200 -0
  8. package/dist/architecture-debt-inventory.js.map +1 -0
  9. package/dist/architecture-debt-report.d.ts +2 -0
  10. package/dist/architecture-debt-report.js +28 -0
  11. package/dist/architecture-debt-report.js.map +1 -0
  12. package/dist/autonomous-phase-lifecycle.d.ts +5 -1
  13. package/dist/autonomous-phase-lifecycle.js +87 -17
  14. package/dist/autonomous-phase-lifecycle.js.map +1 -1
  15. package/dist/autonomous-run-store.js +2 -2
  16. package/dist/autonomous-run-store.js.map +1 -1
  17. package/dist/benchmark.js +2 -1
  18. package/dist/benchmark.js.map +1 -1
  19. package/dist/clarification.js +2 -1
  20. package/dist/clarification.js.map +1 -1
  21. package/dist/cli-payloads.d.ts +4 -0
  22. package/dist/cli-payloads.js +24 -0
  23. package/dist/cli-payloads.js.map +1 -0
  24. package/dist/collaboration-flows.d.ts +1 -2
  25. package/dist/command-manifest.js +18 -5
  26. package/dist/command-manifest.js.map +1 -1
  27. package/dist/command-routes-integrations.js +2 -1
  28. package/dist/command-routes-integrations.js.map +1 -1
  29. package/dist/command-routes.js +3 -1
  30. package/dist/command-routes.js.map +1 -1
  31. package/dist/command-utils.d.ts +1 -2
  32. package/dist/command-utils.js.map +1 -1
  33. package/dist/commands.d.ts +2 -2
  34. package/dist/commands.js +17 -4
  35. package/dist/commands.js.map +1 -1
  36. package/dist/constants.js +1 -0
  37. package/dist/constants.js.map +1 -1
  38. package/dist/cursor-canvas.js +21 -1
  39. package/dist/cursor-canvas.js.map +1 -1
  40. package/dist/cursor-mdc.d.ts +10 -0
  41. package/dist/cursor-mdc.js +37 -0
  42. package/dist/cursor-mdc.js.map +1 -0
  43. package/dist/fs-utils.js +2 -1
  44. package/dist/fs-utils.js.map +1 -1
  45. package/dist/generated-guidance-health.d.ts +33 -0
  46. package/dist/generated-guidance-health.js +125 -0
  47. package/dist/generated-guidance-health.js.map +1 -0
  48. package/dist/github.js +22 -7
  49. package/dist/github.js.map +1 -1
  50. package/dist/health-checks.js +2 -51
  51. package/dist/health-checks.js.map +1 -1
  52. package/dist/id-utils.d.ts +3 -0
  53. package/dist/id-utils.js +11 -0
  54. package/dist/id-utils.js.map +1 -0
  55. package/dist/instruction-blocks.js +20 -5
  56. package/dist/instruction-blocks.js.map +1 -1
  57. package/dist/mcp-oauth-proxy.js +5 -5
  58. package/dist/mcp-oauth-proxy.js.map +1 -1
  59. package/dist/memory-status.js +31 -5
  60. package/dist/memory-status.js.map +1 -1
  61. package/dist/memory.js +31 -7
  62. package/dist/memory.js.map +1 -1
  63. package/dist/metrics-commands.js +69 -17
  64. package/dist/metrics-commands.js.map +1 -1
  65. package/dist/notifications.js +12 -2
  66. package/dist/notifications.js.map +1 -1
  67. package/dist/phase-deterministic-output.d.ts +4 -0
  68. package/dist/phase-deterministic-output.js +62 -0
  69. package/dist/phase-deterministic-output.js.map +1 -0
  70. package/dist/phase-executor.js +9 -172
  71. package/dist/phase-executor.js.map +1 -1
  72. package/dist/phase-playbooks.js +17 -0
  73. package/dist/phase-playbooks.js.map +1 -1
  74. package/dist/provider-utils.js +11 -1
  75. package/dist/provider-utils.js.map +1 -1
  76. package/dist/qa-e2e-artifacts.d.ts +7 -0
  77. package/dist/qa-e2e-artifacts.js +225 -0
  78. package/dist/qa-e2e-artifacts.js.map +1 -0
  79. package/dist/quality-contracts.d.ts +83 -0
  80. package/dist/quality-contracts.js +463 -0
  81. package/dist/quality-contracts.js.map +1 -0
  82. package/dist/refresh-generated.js +81 -28
  83. package/dist/refresh-generated.js.map +1 -1
  84. package/dist/runtime-bootstrap.js +26 -2
  85. package/dist/runtime-bootstrap.js.map +1 -1
  86. package/dist/runtime-commands.d.ts +2 -0
  87. package/dist/runtime-commands.js +190 -1
  88. package/dist/runtime-commands.js.map +1 -1
  89. package/dist/runtime-context-manifest.d.ts +27 -0
  90. package/dist/runtime-context-manifest.js +151 -0
  91. package/dist/runtime-context-manifest.js.map +1 -0
  92. package/dist/runtime-execution-renderer.d.ts +3 -1
  93. package/dist/runtime-execution-renderer.js +7 -1
  94. package/dist/runtime-execution-renderer.js.map +1 -1
  95. package/dist/runtime-execution.d.ts +2 -1
  96. package/dist/runtime-execution.js +191 -2
  97. package/dist/runtime-execution.js.map +1 -1
  98. package/dist/runtime-guardrails.js +5 -1
  99. package/dist/runtime-guardrails.js.map +1 -1
  100. package/dist/runtime-lifecycle-watch-adapters.d.ts +4 -0
  101. package/dist/runtime-lifecycle-watch-adapters.js +87 -0
  102. package/dist/runtime-lifecycle-watch-adapters.js.map +1 -0
  103. package/dist/runtime-lifecycle-watch.d.ts +85 -0
  104. package/dist/runtime-lifecycle-watch.js +312 -0
  105. package/dist/runtime-lifecycle-watch.js.map +1 -0
  106. package/dist/runtime-parent-action-dispatch.d.ts +30 -0
  107. package/dist/runtime-parent-action-dispatch.js +114 -0
  108. package/dist/runtime-parent-action-dispatch.js.map +1 -0
  109. package/dist/runtime-parent-action-eligibility.d.ts +12 -0
  110. package/dist/runtime-parent-action-eligibility.js +131 -0
  111. package/dist/runtime-parent-action-eligibility.js.map +1 -0
  112. package/dist/runtime-parent-actions.d.ts +7 -2
  113. package/dist/runtime-parent-actions.js +145 -1
  114. package/dist/runtime-parent-actions.js.map +1 -1
  115. package/dist/runtime-spawn-bridge.js +21 -1
  116. package/dist/runtime-spawn-bridge.js.map +1 -1
  117. package/dist/skills-validation.js +1 -2
  118. package/dist/skills-validation.js.map +1 -1
  119. package/dist/sonar-commands.d.ts +1 -0
  120. package/dist/sonar-commands.js +36 -0
  121. package/dist/sonar-commands.js.map +1 -1
  122. package/dist/sonar-insights.d.ts +13 -0
  123. package/dist/sonar-insights.js +32 -53
  124. package/dist/sonar-insights.js.map +1 -1
  125. package/dist/sonar-payload-normalizers.d.ts +16 -0
  126. package/dist/sonar-payload-normalizers.js +67 -0
  127. package/dist/sonar-payload-normalizers.js.map +1 -0
  128. package/dist/sonar-preflight.d.ts +26 -0
  129. package/dist/sonar-preflight.js +111 -0
  130. package/dist/sonar-preflight.js.map +1 -0
  131. package/dist/sonar-redaction.d.ts +1 -0
  132. package/dist/sonar-redaction.js +13 -0
  133. package/dist/sonar-redaction.js.map +1 -0
  134. package/dist/subagent-protocol.js.map +1 -1
  135. package/dist/task-graph-commands.js +8 -1
  136. package/dist/task-graph-commands.js.map +1 -1
  137. package/dist/telemetry-redaction.js +31 -2
  138. package/dist/telemetry-redaction.js.map +1 -1
  139. package/dist/types/model-config.d.ts +6 -0
  140. package/dist/types/runtime.d.ts +49 -2
  141. package/dist/types/tasks.d.ts +12 -0
  142. package/dist/types.d.ts +1 -1
  143. package/dist/types.js.map +1 -1
  144. package/dist/web-api.js +8 -0
  145. package/dist/web-api.js.map +1 -1
  146. package/dist/web-artifacts.js +8 -3
  147. package/dist/web-artifacts.js.map +1 -1
  148. package/dist/web-console/assets/index-DA8Fs4r7.js +11 -0
  149. package/dist/web-console/index.html +1 -1
  150. package/dist/workflow-background-subagents.js +8 -4
  151. package/dist/workflow-background-subagents.js.map +1 -1
  152. package/dist/workflow-handoff-assessment.d.ts +3 -0
  153. package/dist/workflow-handoff-assessment.js +246 -0
  154. package/dist/workflow-handoff-assessment.js.map +1 -0
  155. package/dist/workflow-handoff-contract.d.ts +32 -0
  156. package/dist/workflow-handoff-contract.js +123 -0
  157. package/dist/workflow-handoff-contract.js.map +1 -0
  158. package/dist/workflow-phase-transition.d.ts +16 -0
  159. package/dist/workflow-phase-transition.js +76 -0
  160. package/dist/workflow-phase-transition.js.map +1 -0
  161. package/dist/workflow-run-commands.js +79 -18
  162. package/dist/workflow-run-commands.js.map +1 -1
  163. package/dist/workflow-services.js +62 -28
  164. package/dist/workflow-services.js.map +1 -1
  165. package/dist/workspace-init-artifacts.d.ts +9 -0
  166. package/dist/workspace-init-artifacts.js +28 -0
  167. package/dist/workspace-init-artifacts.js.map +1 -1
  168. package/dist/workspace-runtime-bootstrap.d.ts +3 -1
  169. package/dist/workspace-runtime-bootstrap.js +8 -3
  170. package/dist/workspace-runtime-bootstrap.js.map +1 -1
  171. package/dist/workspace.d.ts +5 -2
  172. package/dist/workspace.js +46 -16
  173. package/dist/workspace.js.map +1 -1
  174. package/docs/adoption-guide.md +12 -0
  175. package/docs/architecture-debt-inventory.md +25 -0
  176. package/docs/autonomous-workflow.md +10 -2
  177. package/docs/claude-adapter-qa-matrix.md +56 -0
  178. package/docs/e2e-test-batteries.md +34 -23
  179. package/docs/orchestra-mvp.md +21 -0
  180. package/docs/release-test-matrix.md +22 -0
  181. package/docs/runtime-adapters.md +155 -15
  182. package/docs/sonar-quality-gates.md +240 -11
  183. package/package.json +5 -1
  184. package/rules/delivery-quality-gates.mdc +8 -0
  185. package/rules/devops-tooling.mdc +1 -0
  186. package/rules/security-guardrails.mdc +3 -0
  187. package/rules/testing-discipline.mdc +9 -0
  188. package/dist/web-console/assets/index-CgSKcay8.js +0 -11
@@ -22,10 +22,13 @@ Required GitHub secret when the GitHub Actions workflow is enabled:
22
22
 
23
23
  - `SONAR_TOKEN`: token for SonarQube Cloud or SonarQube Server.
24
24
 
25
- Optional GitHub secret:
25
+ Optional GitHub secrets:
26
26
 
27
27
  - `SONAR_HOST_URL`: required for self-hosted SonarQube Server. Leave unset for
28
28
  SonarQube Cloud, or set `http://localhost:9000` only for local commands.
29
+ - `CF_ACCESS_CLIENT_ID` and `CF_ACCESS_CLIENT_SECRET`: Cloudflare Access service
30
+ token credentials for GitHub-hosted runners that must reach a private
31
+ self-hosted SonarQube URL protected by Zero Trust.
29
32
 
30
33
  Optional GitHub variables:
31
34
 
@@ -37,6 +40,12 @@ Optional GitHub variables:
37
40
  `workflow_dispatch`.
38
41
  - `SONAR_QUALITY_GATE_WAIT`: set to `true` to fail the workflow when the remote
39
42
  quality gate fails.
43
+ - `SONAR_RUNNER`: set to `self-hosted` to run the Sonar workflow on a local
44
+ runner that can reach the shared SonarQube runtime directly. When this is set,
45
+ the workflow uses `http://localhost:9001` by default and skips Cloudflare
46
+ Access service-token checks.
47
+ - `SONAR_LOCAL_HOST_URL`: optional override for self-hosted runner mode when the
48
+ runner reaches SonarQube through a different local-only URL.
40
49
 
41
50
  The workflow skips analysis when `SONAR_TOKEN` is not configured. This keeps
42
51
  forks and offline development usable. For private repositories, keep
@@ -53,31 +62,240 @@ gate status. If the scanner can upload analysis but the wait step fails with
53
62
  `Project not found`, update the `SONAR_TOKEN` permissions or keep
54
63
  `SONAR_QUALITY_GATE_WAIT` unset until the token can read the project.
55
64
 
65
+ Before scanner execution, CI runs:
66
+
67
+ ```bash
68
+ node bin/orchestra.js sonar preflight \
69
+ --provider "$SONAR_PROVIDER_RESOLVED" \
70
+ --project-key jterrats_open-orchestra \
71
+ --organization jterrats \
72
+ --host-url "$SONAR_HOST_URL_RESOLVED" \
73
+ --branch "$BRANCH_NAME"
74
+ ```
75
+
76
+ The preflight validates token authentication, project visibility, quality gate
77
+ API access, issue API access, and security hotspot API access. It redacts the
78
+ token, host URL, and Cloudflare Access service token values from diagnostic
79
+ output. `hotspots` is a warning when unavailable because some Sonar tokens can
80
+ analyze and read issues while hotspot review permissions are managed separately.
81
+
82
+ Common remediation:
83
+
84
+ - `auth-invalid`: regenerate `SONAR_TOKEN`; do not paste header names or
85
+ prefixes into the secret value.
86
+ - `project-not-found`: verify the project key and organization, then grant the
87
+ token user Browse access on the project.
88
+ - `permission-denied`: grant Execute Analysis for scanner upload and Browse/API
89
+ access for evidence import. Use a user token when hotspot APIs must be read.
90
+ - `cloudflare-challenge`: use the Cloudflare Access service token proxy, a
91
+ self-hosted runner with local `SONAR_LOCAL_HOST_URL`, or an Access policy that
92
+ explicitly allows the CI service token without an interactive challenge.
93
+
56
94
  ## Local SonarQube
57
95
 
58
- Open Orchestra includes `docker-compose.sonar.yml` for local SonarQube
59
- dogfooding:
96
+ Open Orchestra does not own the long-lived local SonarQube containers. The
97
+ shared laptop/VPS runtime lives in `~/dev/sonarqube_jeterrats_dev` so multiple
98
+ projects can use the same SonarQube server without tying its lifecycle to this
99
+ repository.
100
+
101
+ ```bash
102
+ cd ~/dev/sonarqube_jeterrats_dev
103
+ docker compose up -d
104
+ ```
105
+
106
+ The shared runtime binds SonarQube to `127.0.0.1:${SONAR_PORT:-9001}` by
107
+ default, persists data in Docker volumes, and routes
108
+ `sonarqube.jterrats.dev` through the Cloudflare Tunnel named
109
+ `open-orchestra-sonar-local`.
110
+ The local database password is a rotated strong value stored only in the shared
111
+ infra `.env` file with owner-only file permissions; do not reset it to the
112
+ default `sonar` password.
113
+
114
+ ```bash
115
+ cd ~/dev/sonarqube_jeterrats_dev
116
+ docker compose ps
117
+ docker compose logs -f sonarqube
118
+ docker compose logs -f cloudflared
119
+ ```
120
+
121
+ This repository keeps only project-specific assets: `sonar-project.properties`,
122
+ scanner scripts, import commands, and release evidence. That separation avoids
123
+ one project accidentally stopping, deleting, changing ports, or rotating
124
+ credentials for every other project using the same SonarQube server.
125
+
126
+ Open `http://localhost:9001`, complete the SonarQube first-run setup if needed,
127
+ create the `jterrats_open-orchestra` project key, and generate a project token.
128
+ The scanner and `orchestra sonar import` both authenticate with the token as
129
+ SonarQube Basic auth (`<token>:`), so the token must be valid for analysis and
130
+ API reads on the target project. Then run scanner/import commands against the
131
+ local or tunnel host. Example local scan:
60
132
 
61
133
  ```bash
62
- docker compose -f docker-compose.sonar.yml up -d
134
+ SONAR_HOST_URL=http://localhost:9001 SONAR_TOKEN=<local-token> npm run sonar:scan:local
63
135
  ```
64
136
 
65
- Open `http://localhost:9000`, complete the SonarQube first-run setup, create a
66
- project key, and generate a project token. Then run scanner/import commands
67
- against the local host. Example import after analysis is available:
137
+ Example import after analysis is available:
68
138
 
69
139
  ```bash
70
140
  SONAR_TOKEN=<local-token> node bin/orchestra.js sonar import \
71
141
  --provider sonarqube-local \
72
- --host-url http://localhost:9000 \
73
- --project-key open-orchestra \
142
+ --host-url http://localhost:9001 \
143
+ --project-key jterrats_open-orchestra \
74
144
  --branch main \
75
145
  --task GH-368-LOCAL-SONARQUBE-PROVIDER \
76
146
  --json
77
147
  ```
78
148
 
79
- HTTP is accepted only for `sonarqube-local` on localhost. Self-hosted and cloud
80
- hosts must use HTTPS.
149
+ HTTP is accepted only for `sonarqube-local` on localhost. Shared tunnel and
150
+ cloud hosts must use HTTPS.
151
+
152
+ ### Private Cloudflare Access
153
+
154
+ Do not expose SonarQube as a public DNS-only origin. If remote access is needed,
155
+ use Cloudflare Tunnel with Cloudflare Access so `sonarqube.jterrats.dev` is an
156
+ authenticated private entry point, not an open public service.
157
+
158
+ Minimum Cloudflare setup:
159
+
160
+ - Create a tunnel for this laptop or temporary VPS. The current tunnel name is
161
+ `open-orchestra-sonar-local`.
162
+ - Route `sonarqube.jterrats.dev` to the Sonar service behind the tunnel. The DNS
163
+ record is a proxied CNAME to
164
+ `6fb60222-1427-4ca1-bf11-9e19375d39ff.cfargotunnel.com`.
165
+ - Protect the hostname with a Cloudflare Access self-hosted application.
166
+ - Restrict Access to named users, groups, or a short-lived maintainer policy.
167
+ - Require MFA at the identity provider when possible.
168
+ - Keep SonarQube itself authenticated; Cloudflare Access is an outer gate, not a
169
+ replacement for Sonar users and tokens.
170
+
171
+ When the tunnel hostname is active, CI can use
172
+ `SONAR_HOST_URL=https://sonarqube.jterrats.dev` only if the runner has an
173
+ approved Access path. For GitHub-hosted runners, create a Cloudflare Access
174
+ service token, add a Service Auth policy scoped to the SonarQube application,
175
+ and configure `CF_ACCESS_CLIENT_ID` plus `CF_ACCESS_CLIENT_SECRET` as GitHub
176
+ secrets. The workflow starts an ephemeral localhost proxy that injects those
177
+ headers for SonarScanner and Orchestra import calls; browser login remains
178
+ required for human access. The proxy readiness check validates SonarQube through
179
+ the configured `SONAR_TOKEN` so private SonarQube instances that require
180
+ authentication do not fail on anonymous health endpoints.
181
+
182
+ If the Access service token secrets are not configured, the workflow keeps the
183
+ normal direct Sonar URL behavior. Use local analysis evidence or a self-hosted
184
+ runner when GitHub-hosted runners cannot access the private endpoint.
185
+
186
+ ### Self-Hosted Runner Mode
187
+
188
+ For private local SonarQube on a laptop or low-cost VPS, prefer a self-hosted
189
+ GitHub Actions runner over exposing the analyzer path through Cloudflare Access.
190
+ Configure the repository or organization variable:
191
+
192
+ ```bash
193
+ gh variable set SONAR_RUNNER --repo jterratsdev/open-orchestra --body self-hosted
194
+ ```
195
+
196
+ Register the runner with dedicated labels so only the Sonar job can claim it.
197
+ Do not include OS-specific labels in the workflow unless the Sonar runtime truly
198
+ depends on that operating system; this keeps the same CI definition usable from
199
+ a macOS laptop today and a Linux host later.
200
+
201
+ ```text
202
+ self-hosted
203
+ sonar
204
+ local-sonar
205
+ ```
206
+
207
+ For the current laptop setup, use the macOS ARM64 runner package and configure
208
+ the runner with `--labels sonar,local-sonar`. GitHub automatically adds the
209
+ platform labels such as `self-hosted`, `macOS`, and `ARM64`.
210
+
211
+ Current macOS ARM64 bootstrap:
212
+
213
+ ```bash
214
+ mkdir -p ~/dev/actions-runner-open-orchestra-sonar
215
+ cd ~/dev/actions-runner-open-orchestra-sonar
216
+ curl -L -o actions-runner-osx-arm64.tar.gz <github-runner-osx-arm64-download-url>
217
+ tar xzf actions-runner-osx-arm64.tar.gz
218
+ ./config.sh --url https://github.com/jterratsdev/open-orchestra --labels sonar,local-sonar --name open-orchestra-sonar-macos-arm64
219
+ ./run.sh
220
+ ```
221
+
222
+ Future Linux runner bootstrap should use the Linux package that matches the host
223
+ architecture, the same `sonar,local-sonar` labels, and a dedicated service
224
+ account. Do not reuse a broad organization runner for Sonar unless the runner
225
+ already has least-privilege filesystem, Docker, and network access.
226
+
227
+ Service lifecycle:
228
+
229
+ ```bash
230
+ cd ~/dev/actions-runner-open-orchestra-sonar
231
+ ./svc.sh install
232
+ ./svc.sh start
233
+ ./svc.sh status
234
+ ./svc.sh stop
235
+ ```
236
+
237
+ Use `./run.sh` for interactive local troubleshooting. Use `svc.sh` only after
238
+ the runner can start, claim a Sonar workflow job, and reach SonarQube locally.
239
+
240
+ Keep the shared SonarQube stack running locally:
241
+
242
+ ```bash
243
+ cd ~/dev/sonarqube_jterrats_dev
244
+ docker compose up -d
245
+ ```
246
+
247
+ When `SONAR_RUNNER=self-hosted`, the workflow resolves SonarQube to
248
+ `http://localhost:9001` unless `SONAR_LOCAL_HOST_URL` is set. This intentionally
249
+ ignores `SONAR_HOST_URL`, so organization-level Cloudflare tunnel secrets do not
250
+ pull local machine analysis back through Zero Trust. Cloudflare Access remains
251
+ available for human remote browser usage and for GitHub-hosted runner access to
252
+ private SonarQube only. The CI scan uses
253
+ `continue-on-error` on the scanner step so Orchestra can still import and upload
254
+ Sonar evidence when the quality gate fails; a final workflow step re-fails the
255
+ job after evidence is captured.
256
+
257
+ If the runner itself runs inside a container, `localhost` points at the runner
258
+ container. In that case either run the runner process on the host, attach the
259
+ runner container to the SonarQube Docker network, or set `SONAR_LOCAL_HOST_URL`
260
+ to the host/network address that reaches SonarQube without Cloudflare.
261
+
262
+ ### Self-Hosted Runner Health Check
263
+
264
+ Before relying on CI, validate the local runner and SonarQube path from the same
265
+ machine that runs the GitHub Actions runner:
266
+
267
+ ```bash
268
+ gh variable list --repo jterratsdev/open-orchestra
269
+ gh api repos/jterratsdev/open-orchestra/actions/runners --jq '.runners[] | {name, status, busy, labels: [.labels[].name]}'
270
+ npm run sonar:preflight:local
271
+ ```
272
+
273
+ Expected result:
274
+
275
+ - `SONAR_RUNNER` is `self-hosted`.
276
+ - A runner is `online` with `self-hosted`, `sonar`, and `local-sonar` labels.
277
+ - Sonar authentication returns `{"valid":true}`.
278
+ - `npm run sonar:preflight:local` passes `auth`, `project`, `qualityGate`, and
279
+ `issues`; `hotspots` may warn when the token lacks hotspot read access.
280
+
281
+ If the runner is online but jobs stay queued, verify the workflow labels match
282
+ the runner labels exactly. If Sonar preflight fails, fix the token/project
283
+ permissions before rerunning the workflow.
284
+
285
+ ### Current Workflow Warning Triage
286
+
287
+ - Node 20 action warning: non-blocking today. Track upstream action upgrades and
288
+ update actions when GitHub publishes Node 24-compatible major versions.
289
+ - GPG keyserver warning from the Sonar scanner action: non-blocking when scanner
290
+ setup and analysis complete. Prefer self-hosted runner network allowlisting or
291
+ a pinned scanner cache before treating it as release-blocking.
292
+ - Cache or tar warnings: non-blocking unless scanner dependencies fail to
293
+ restore and analysis cannot start. Rebuild the runner cache or rerun the job
294
+ before changing project code.
295
+
296
+ These warnings should be captured as CI annotations, but they do not override a
297
+ passing Sonar workflow unless the scanner, import, or final quality gate step
298
+ fails.
81
299
 
82
300
  Sonar reads TypeScript through `tsconfig.sonar.json`, a standalone analyzer
83
301
  config that mirrors the build compiler options but lowers only the analyzer
@@ -117,6 +335,17 @@ Recommended minimum quality gate for new code:
117
335
  - Coverage reported from `coverage/lcov.info` for source files on every Sonar
118
336
  run.
119
337
 
338
+ The Orchestra Sonar import stores unresolved issues and Sonar security hotspots
339
+ in the uploaded `sonar-insights` artifact. When the gate fails only on
340
+ `new_security_hotspots_reviewed`, review the hotspot list in SonarQube, mark
341
+ each hotspot as safe, fixed, or accepted with rationale, then rerun the Sonar
342
+ workflow. Do not bypass this gate from code unless the Product Owner explicitly
343
+ accepts the security risk.
344
+ If the artifact includes `securityHotspotsUnavailableReason`, the configured
345
+ `SONAR_TOKEN` can read the quality gate and issues but cannot read the hotspots
346
+ API. Grant the token Browse plus security hotspot review/read permissions in
347
+ SonarQube before using the artifact as release evidence.
348
+
120
349
  ## Coverage Publishing
121
350
 
122
351
  The Sonar workflow runs `npm run test:coverage` before analysis. That command
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jterrats/open-orchestra",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  "extensions/vscode-open-orchestra",
@@ -18,16 +18,20 @@
18
18
  "test:e2e": "npm run build && npm run site:build && playwright test",
19
19
  "test:e2e:init": "node --test e2e/init-onboarding.test.js",
20
20
  "test:e2e:runtime": "node --test e2e/runtime-manual-queue.test.js",
21
+ "test:e2e:runtime:ollama": "npm run build && node --test e2e/runtime-ollama-provider.test.js",
21
22
  "lint": "eslint . && prettier --check \"{bin,e2e,scripts,test,src}/**/*.js\" \"{site,web-console}/src/**/*.{css,js,jsx}\" \"{site,web-console}/*.{html,js,json}\" \"extensions/**/*.{cjs,json,md}\" \"src/**/*.ts\" \"*.{js,json}\"",
22
23
  "format": "prettier --write \"{bin,e2e,scripts,test,src}/**/*.js\" \"{site,web-console}/src/**/*.{css,js,jsx}\" \"{site,web-console}/*.{html,js,json}\" \"extensions/**/*.{cjs,json,md}\" \"src/**/*.ts\" \"*.{js,json}\"",
23
24
  "secret-scan": "node scripts/secret-scan.js",
24
25
  "security:audit": "node scripts/security-audit.js",
26
+ "architecture:inventory": "npm run build && node scripts/architecture-debt-inventory.js",
25
27
  "duplicates": "jscpd --config .jscpd.json",
26
28
  "validate:workflow": "node scripts/validate-workflow.js",
27
29
  "release:matrix": "node scripts/release-test-matrix.js",
28
30
  "performance:bench": "npm run build && node scripts/performance-benchmark.js",
29
31
  "precommit": "npm run lint && npm run typecheck && npm run secret-scan && npm run security:audit && npm test && npm run validate:workflow",
30
32
  "prepack": "npm run build",
33
+ "sonar:preflight:local": "node bin/orchestra.js sonar preflight --provider sonarqube-local --project-key jterrats_open-orchestra --host-url ${SONAR_HOST_URL:-http://localhost:9001}",
34
+ "sonar:scan:local": "sonar-scanner -Dsonar.host.url=${SONAR_HOST_URL:-http://localhost:9001}",
31
35
  "hooks:install": "git config core.hooksPath .githooks",
32
36
  "build:web": "npm run build:web:legacy && npm run build:web:react",
33
37
  "build:web:legacy": "esbuild src/web-console-client.js --bundle --format=esm --platform=browser --target=es2022 --outfile=dist/assets/web-console.js",
@@ -18,7 +18,13 @@ Development work is not complete when code compiles. Every implementation must m
18
18
  ## QA Gate
19
19
 
20
20
  - QA receives the Developer handoff before release approval.
21
+ - Workflow gate approval is not a status shortcut. `po→architect` can be approved only when the issue/task has user-validated scope, non-goals, assumptions, priority, acceptance criteria, and sizing context. `qa→release` can be approved only after real implementation evidence, QA findings, BA/PO acceptance, and Architect review when technical contracts changed.
22
+ - Generated handoffs with `Acceptance Criteria: none` are incomplete for release purposes. Pull the criteria from the linked GitHub issue or Orchestra task, record a review finding, and block release until the criteria/evidence gap is fixed or explicitly risk-accepted by the Product Owner.
21
23
  - QA must produce a test plan covering acceptance criteria, regression areas, edge cases, data setup, and environment assumptions.
24
+ - QA must block test planning when acceptance criteria are fragmented, non-verifiable, or only role/phase headings. Return those findings to PO/BA before release evidence is generated.
25
+ - QA plans must include an AC-to-evidence matrix with expected observable result, actual result, artifact/command, and pass/fail/deferred status for each acceptance criterion.
26
+ - QA must validate that the planned tests exercise the actual risk, not a weaker surrogate. For scope/split, handoff, workflow, runtime, queueing, failback, or release-gate bugs, the test data must create the condition that should trigger the guardrail.
27
+ - QA must block when the plan substitutes a weaker surface for the requested behavior, such as browser smoke for workflow/CLI behavior, command execution without stdout/files/events checks, or API response checks without receiver-side effects for integrations.
22
28
  - QA must execute or explicitly defer each test case with a reason.
23
29
  - QA findings must include severity, reproduction steps, expected result, actual result, and evidence.
24
30
  - QA execution must be reviewable through a sprint-review-style evidence demo before release approval. Analyst/BA compares the executed evidence against the GitHub issue, user story, acceptance criteria, and Orchestra task; Architect reviews whether the tests cover architecture contracts, boundaries, integrations, data flow, and risk areas.
@@ -29,6 +35,8 @@ Development work is not complete when code compiles. Every implementation must m
29
35
 
30
36
  - QA and Developer must identify which manual checks should become automated tests.
31
37
  - Prefer Playwright for browser-based E2E, smoke, and regression flows.
38
+ - Automation for every product surface must use isolated deterministic fixtures: web, mobile, desktop, CLI, API, integrations, workflow/runtime, installer, data, and generated-artifact flows. Use the configured E2E fixture path, sandbox org, emulator, container, device farm, or test environment when the user/project provides one; otherwise default local disposable fixtures to `/tmp`.
39
+ - Automation must assert state transitions and final artifacts. For workflow-style systems, assert the automaton path: valid transition, blocked transition, loop/return transition, resume, and final release transition when applicable. For UI/mobile/API/integration systems, assert the user-visible state, device/responsive behavior, API contract, receiver-side side effect, persisted data, async job/event, or external sandbox state that proves the acceptance criterion.
32
40
  - Use Page Object pattern for Playwright suites. Selectors belong in page objects or stable test helpers, not scattered through test bodies.
33
41
  - Automated tests must be deterministic and avoid real network, clock, or randomness unless controlled by fixtures, mocks, or seeded data.
34
42
 
@@ -30,6 +30,7 @@ DevOps decisions must cover deployability, scalability, downtime strategy, obser
30
30
  - Prefer managed services when they reduce operational risk without creating unacceptable lock-in or cost exposure.
31
31
  - Record tool choices and major operational trade-offs in an ADR when they affect long-term operations.
32
32
  - CI/CD, IaC, runbooks, and operational scripts that repeat command matrices, provider lists, environment maps, or resource collections must load the `collection-standards` skill.
33
+ - Local Docker stacks must publish ports on `127.0.0.1` unless the task explicitly requires LAN/public access and Security has accepted the risk. Databases, caches, queues, admin UIs, metrics backends, and Docker socket access are private by default.
33
34
 
34
35
  ## Scalability
35
36
  - Define expected traffic, data volume, concurrency, growth assumptions, and bottlenecks.
@@ -35,3 +35,6 @@ These are non-negotiable. Violations must be fixed before code review.
35
35
 
36
36
  - For databases, encryption, IaC, environment segregation, secrets management, scalability, and vulnerability management, see **infra-data-encryption.mdc**.
37
37
  - Production networked services must consider TLS 1.2+, certificate management, HSTS where applicable, secure cookies, least privilege, and secret rotation.
38
+ - Local Docker Compose, dev servers, databases, caches, observability tools, and admin UIs must bind published ports to `127.0.0.1` by default.
39
+ - Binding to `0.0.0.0`, `[::]`, or a LAN interface is a security exception. It needs a linked task, explicit rationale, no default credentials, and a time-bounded review.
40
+ - Never expose Redis, Postgres, admin consoles, Docker socket, or internal APIs on public/LAN interfaces unless Security approves the exact use case and compensating controls.
@@ -40,6 +40,11 @@ alwaysApply: true
40
40
  - Use the Page Object pattern for UI tests. Selectors live in page objects, not test bodies.
41
41
  - Tag tests by speed/scope (`@smoke`, `@regression`) so CI can run fast feedback loops.
42
42
  - Capture evidence for E2E failures with traces, screenshots, or videos when supported by the framework.
43
+ - E2E tests for any product surface must run against isolated disposable fixtures: web apps, mobile apps, desktop apps, CLI, APIs, integrations, workflows, runtimes, installers, file-system flows, data pipelines, and generated artifacts. Use the user/project-configured E2E fixture path, device farm, sandbox org, emulator, container, or test environment when one is explicitly provided; otherwise default local disposable fixtures to `/tmp`. Each test creates its own users/data/project/tasks/roles/acceptance criteria/expected artifacts as applicable; never rely on the developer's current repo state as the tested product state.
44
+ - QA must choose fixture data that reproduces the risk being validated. If the acceptance criterion is about oversized stories, split decisions, phase returns, queueing, or specialist roles, the E2E must create an oversized/cross-cutting task with enough paths, roles, acceptance criteria, and risk signals to force that behavior.
45
+ - Every E2E must assert the resulting state, not only that the action executed. Validate UI-visible state, navigation, accessibility, device/responsive behavior, API contracts, receiver-side integration state, database/mock records, files, events, handoff contents, stdout/stderr, exit code, push notifications, background jobs, generated artifacts, or release-readiness output as applicable.
46
+ - For workflow automata, E2E must validate state transitions and loops: allowed transition, blocked transition, return-to-dev/architect/BA when findings fail, and resume behavior after the corrective state is satisfied.
47
+ - Include negative and edge scenarios when they are the reason for the change. A happy-path smoke is insufficient for bugs involving guardrails, split detection, security boundaries, QA failback, or release blocking.
43
48
  - QA, SDET, Developer, BA, Architect, and Release work that produces or reviews evidence must load the `qa-evidence-pack` skill when it involves acceptance criteria coverage, Playwright/browser artifacts, CLI stdout/stderr, API contracts, integration side effects, screenshots, visual diffs, or annotated defect evidence.
44
49
  - Keep large screenshots, videos, traces, logs, API payloads, and visual diffs as files. Summarize them in a compact evidence report so agents do not consume context with raw artifacts.
45
50
 
@@ -47,6 +52,10 @@ alwaysApply: true
47
52
 
48
53
  - Developer must provide QA with test commands run, pass/fail results, covered scenarios, and known gaps.
49
54
  - QA must produce a test plan before release approval and map every acceptance criterion to automated, manual, contract/mock, or deferred evidence.
55
+ - QA must reject fragmented acceptance criteria before planning tests. Role names, phase names, headings, and partial clauses are not executable criteria and must return to PO/BA for rewrite.
56
+ - QA plans must include an AC-to-evidence matrix with: acceptance criterion, test type, fixture/setup, command or artifact, expected observable result, actual result, and pass/fail/deferred status.
57
+ - QA must challenge weak tests before approving: if the test fixture is too small to exercise the bug, uses only the happy path, does not create the expected failure/return condition, or does not inspect the artifact/state that proves the acceptance criterion, QA must block or request changes.
58
+ - QA must reject weaker surrogate tests. Validate the affected product surface directly: workflow/CLI/API/integration/generated artifact/mobile/desktop/data behavior cannot be approved only by a generic browser smoke or command-executed check.
50
59
  - QA evidence must validate observable outcomes, not only execution. CLI checks assert exit code, stdout/stderr, files, events, or final state; browser checks assert visible user-facing state; API checks assert response contract and side effects; integration checks assert sandbox/mock/contract/webhook/event/log outcomes or defer with owner and rationale.
51
60
  - Evidence summaries or metadata must name the covered acceptance criterion or explicitly state that all acceptance criteria are covered. Smoke and regression checks are useful but do not count as acceptance coverage unless they map to an acceptance criterion.
52
61
  - Visual/UI/diagram defect evidence must include source or expected image when available, actual screenshot/render, diff image when practical, and an annotated screenshot for ambiguous failures. Use red boxes for broken bounds/overlap, orange arrows for wrong connectors or flow, yellow translucent areas for excess spacing, blue guide lines for alignment, and short defect labels.