opencode-swarm 7.116.0 → 7.116.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 (40) hide show
  1. package/.opencode/skills/commit-pr/SKILL.md +60 -579
  2. package/dist/cli/{curator-drift-c0by7063.js → curator-drift-7p2ky1th.js} +2 -2
  3. package/dist/cli/{curator-llm-factory-x96dr0zf.js → curator-llm-factory-9qn52fnv.js} +13 -13
  4. package/dist/cli/{curator-7s5yw6hw.js → curator-yxmtp8py.js} +13 -13
  5. package/dist/cli/{evidence-summary-service-ef6kgtev.js → evidence-summary-service-bwt6drb3.js} +5 -5
  6. package/dist/cli/{gate-evidence-thqt0beq.js → gate-evidence-j2m4cd85.js} +3 -2
  7. package/dist/cli/{guardrail-explain-kwqfkwch.js → guardrail-explain-xvyz2eag.js} +14 -14
  8. package/dist/cli/{hive-promoter-rkkx40qv.js → hive-promoter-ykqc60w1.js} +13 -13
  9. package/dist/cli/{index-bbsaxnj5.js → index-0pfqcjp6.js} +4 -0
  10. package/dist/cli/{index-qgeeyy75.js → index-34g1mv3c.js} +1 -1
  11. package/dist/cli/{index-a6f8b0vn.js → index-5bcrp3bc.js} +1 -1
  12. package/dist/cli/{index-k5ey429j.js → index-5h7d37nf.js} +7 -7
  13. package/dist/cli/{index-me46ffm2.js → index-7kcpkm4y.js} +433 -275
  14. package/dist/cli/{index-81vzywh3.js → index-abjjn4yh.js} +1 -1
  15. package/dist/cli/{index-tvgvb5pa.js → index-efdyjgeh.js} +2 -2
  16. package/dist/cli/{index-jtqkh8jf.js → index-fsrp8wp3.js} +10 -1
  17. package/dist/cli/{index-3yh67t1h.js → index-g4p13g8t.js} +3 -3
  18. package/dist/cli/{index-wh8949ef.js → index-kzj3fp7c.js} +3 -3
  19. package/dist/cli/{index-3b8n3dbd.js → index-p9jf8gt8.js} +14 -14
  20. package/dist/cli/{index-jyetmzcn.js → index-t5f01hnz.js} +3 -3
  21. package/dist/cli/{index-8bvh0qfa.js → index-wegc6xwr.js} +3 -3
  22. package/dist/cli/{index-s385axt1.js → index-wxkf3089.js} +3 -3
  23. package/dist/cli/{index-cnrhj56z.js → index-xdsd2hma.js} +6 -6
  24. package/dist/cli/index.js +13 -13
  25. package/dist/cli/{knowledge-escalator-0bq62d34.js → knowledge-escalator-tthw6c9q.js} +6 -6
  26. package/dist/cli/{knowledge-events-cwwky393.js → knowledge-events-hrbmwxxj.js} +4 -3
  27. package/dist/cli/{knowledge-store-q8x4h82m.js → knowledge-store-5cns5sns.js} +4 -4
  28. package/dist/cli/{knowledge-validator-zr0djm02.js → knowledge-validator-xre0s774.js} +5 -5
  29. package/dist/cli/{pending-delegations-rr9x47rd.js → pending-delegations-9cn17983.js} +2 -2
  30. package/dist/cli/{pr-subscriptions-cny2jz2d.js → pr-subscriptions-8a6jwek2.js} +3 -3
  31. package/dist/cli/{skill-generator-mz267btk.js → skill-generator-22nk6c6a.js} +7 -7
  32. package/dist/commands/close.d.ts +12 -0
  33. package/dist/commands/registry.d.ts +6 -6
  34. package/dist/commands/reset-backup.d.ts +32 -0
  35. package/dist/commands/reset-session.d.ts +2 -0
  36. package/dist/commands/reset.d.ts +9 -0
  37. package/dist/evidence/task-file.d.ts +7 -0
  38. package/dist/index.js +187 -184
  39. package/dist/utils/swarm-artifact-cache.d.ts +13 -0
  40. package/package.json +1 -1
@@ -2,606 +2,87 @@
2
2
  name: commit-pr
3
3
  audience: swarm-plugin
4
4
  description: >
5
- Apply when committing, pushing, opening or updating a PR, writing a pull request,
6
- creating release notes, or closing out remote CI. Enforces the opencode-swarm
7
- invariant audit, release-note fragment workflow, full validation suite, issue
8
- comment requirement, and post-PR lifecycle rules.
5
+ Apply when committing, pushing, opening or updating a pull request, or closing
6
+ out CI. A portable, project-agnostic commit and PR workflow: verify before you
7
+ push, write conventional commits and a clear PR body, and never commit
8
+ generated or secret files.
9
9
  effort: medium
10
10
  ---
11
11
 
12
- # Commit & PR Protocol
12
+ # Commit & PR Protocol (portable)
13
13
 
14
- Follow every step in order. Do not skip steps.
14
+ A project-agnostic workflow for landing a change safely. It makes no assumptions
15
+ about the language, build tool, or hosting provider — discover each project's
16
+ own conventions and follow them. Do every step in order.
15
17
 
16
- ## Step -1 - Mandatory invariant audit
18
+ > If the repository ships its own commit/PR contract (a `CONTRIBUTING.md`, a
19
+ > pull-request template, a contributor-guide file, or a project-specific
20
+ > commit-pr skill), that contract wins over this generic guidance. Read it first.
17
21
 
18
- Before any build, test, push, or PR action, read:
22
+ ## Step 0 Working-tree hygiene
19
23
 
20
- 1. [`../../../AGENTS.md`](../../../AGENTS.md)
21
- 2. [`../../../docs/engineering-invariants.md`](../../../docs/engineering-invariants.md)
24
+ 1. `git status` and `git diff` — know exactly what you are about to commit.
25
+ 2. Confirm you are on a feature branch, not the default branch. If you are on
26
+ `main`/`master`, create a branch first.
27
+ 3. Do not stage generated output, dependency directories, local caches, or
28
+ secrets (build/`dist` output, `node_modules`/`target`/`vendor`, `.env`,
29
+ credentials, keys). If any are tracked or unignored, fix `.gitignore` instead
30
+ of committing them.
22
31
 
23
- For every touched invariant, prepare concrete evidence for the PR body. The PR body must include:
32
+ ## Step 1 Discover the project's checks
24
33
 
25
- ```md
26
- ## Invariant audit
27
- - 1 (plugin init): touched / not touched - <evidence>
28
- - 2 (runtime portability): touched / not touched - <evidence>
29
- - 3 (subprocesses): touched / not touched - <evidence>
30
- - 4 (.swarm containment): touched / not touched - <evidence>
31
- - 5 (plan durability): touched / not touched - <evidence>
32
- - 6 (test_runner safety): touched / not touched - <evidence>
33
- - 7 (test writing): touched / not touched - <evidence>
34
- - 8 (session state): touched / not touched - <evidence>
35
- - 9 (guardrails/retry): touched / not touched - <evidence>
36
- - 10 (chat/system msg): touched / not touched - <evidence>
37
- - 11 (tool registration): touched / not touched - <evidence>
38
- - 12 (release/cache): touched / not touched - <evidence>
39
- ```
34
+ Find the project's own validation commands rather than guessing:
40
35
 
41
- If a touched invariant cannot be proven from source and test output, do not push.
36
+ - A package manifest's script section (e.g. `package.json` `scripts`,
37
+ `Makefile` targets, `pyproject.toml`, `Cargo.toml`, `justfile`, `Taskfile`).
38
+ - CI workflow files under `.github/workflows/` (or the provider's config) —
39
+ these are the checks that must pass to merge.
42
40
 
43
- ### Required validations for touched invariants
41
+ Run the project's build, test, lint, type-check, and format checks — whatever
42
+ exists. Pin tool versions to what the project declares so local results match
43
+ CI. If a check fails, fix the cause; do not weaken, skip, or delete the check.
44
44
 
45
- If invariants 1, 2, or 3 are touched, run all three:
45
+ ## Step 2 Verify before you push
46
46
 
47
- ```bash
48
- bun run build
49
- node scripts/repro-704.mjs
50
- node --input-type=module -e "await import('./dist/index.js'); console.log('dist import OK')"
51
- ```
47
+ Run the discovered checks and confirm they pass. Report the exact commands and
48
+ their results — never claim a check passed without having run it. Passing tests
49
+ mean the change is *plausible*, not automatically *correct*: make sure the change
50
+ actually does what the task intended.
52
51
 
53
- If invariant 3 is touched, audit changed source files for subprocess use:
52
+ ## Step 3 Commit
54
53
 
55
- ```bash
56
- git diff --name-only origin/main..HEAD | xargs -r grep -nE "bunSpawn\(|spawn\(|spawnSync\(" || true
57
- ```
54
+ Write a clear, conventional commit message:
58
55
 
59
- If invariant 11 is touched, run:
56
+ - Title: `<type>(<scope>): <summary>` where `<type>` is one of `feat`, `fix`,
57
+ `perf`, `refactor`, `docs`, `test`, `build`, `ci`, `chore`, `revert`.
58
+ - Keep the title short and imperative; put detail in the body.
59
+ - One logical change per commit where practical.
60
60
 
61
- ```bash
62
- bun --smol test tests/unit/config --timeout 60000
63
- for f in tests/unit/tools/*.test.ts; do bun --smol test "$f" --timeout 30000; done
64
- ```
61
+ ## Step 4 — Push
65
62
 
66
- If invariant 7 is touched, confirm the writing-tests skill was loaded and that new test seams avoid leaking `mock.module`.
63
+ 1. Identify the correct remote. If the repo has several remotes, push to the one
64
+ the PR targets (the upstream you are contributing to), not an unrelated fork.
65
+ 2. `git push -u <remote> <branch>` for a new branch.
66
+ 3. If a push is rejected because you rebased, use `git push --force-with-lease`
67
+ — never a plain, unconditional force push. `--force-with-lease` refuses to
68
+ overwrite commits the remote gained since your last fetch, so it cannot
69
+ silently clobber a teammate's work.
67
70
 
68
- ## Step 0 - Session start hygiene
71
+ ## Step 5 Open or update the PR
69
72
 
70
- Run before publication work:
73
+ Search the repo for a PR template
74
+ (`.github/PULL_REQUEST_TEMPLATE.md` or `.github/PULL_REQUEST_TEMPLATE/`). If one
75
+ exists, fill in its sections. Otherwise write a body with at least:
71
76
 
72
- ```bash
73
- git fetch origin main
74
- rm -f .swarm/evidence/*.json
75
- rm -f .swarm/evidence/pr_body.md
76
- rm -f .swarm/evidence/commit-pr-validation.md
77
- git status --short
78
- ```
77
+ - **Summary** — what changed and why.
78
+ - **Test plan** — the checks you ran and their results.
79
+ - A linking keyword (`Closes #<issue>`) when the PR resolves an issue.
79
80
 
80
- On Windows, prefer temporary save branches over `git stash`. If you must stash, use `git stash push --include-untracked` and verify the stash contents.
81
+ Use a PR title in the same conventional-commit form as your commit.
81
82
 
82
- If this changeset edited any SKILL.md file's wording, also run `file:.swarm/bundled-skills/skill-edit-validation/SKILL.md`'s content-assertion sweep before committing, to catch stale test assertions.
83
+ ## Step 6 Close out CI
83
84
 
84
- ## Step 1 - Commit and PR titles
85
-
86
- Use `<type>(<scope>): <description>` exactly.
87
-
88
- - description is lowercase and does not end with a period
89
- - allowed types: `feat`, `fix`, `perf`, `revert`, `docs`, `chore`, `refactor`, `test`, `ci`, `build`
90
-
91
- Choose the PR title type by the main change:
92
-
93
- - new capability -> `feat`
94
- - bug fix only -> `fix`
95
- - docs or chore only -> non-bump types
96
-
97
- The squash merge commit message must match the PR title exactly.
98
-
99
- > **Note:** The PR title MUST follow `<type>(<scope>): <description>` exactly — CI runs `action-semantic-pull-request` which will fail the `check-title` job if the format is wrong. Do not deviate from this format.
100
-
101
- ## Step 2 - Release note fragment
102
-
103
- Create a pending release fragment and do not calculate a version manually.
104
-
105
- Required file shape:
106
-
107
- ```text
108
- docs/releases/pending/<unique-slug>.md
109
- ```
110
-
111
- The fragment should cover:
112
-
113
- - what changed
114
- - why
115
- - migration steps, if any
116
- - breaking changes, if any
117
- - known caveats
118
-
119
- Bot authors (e.g. `[bot]`, Copilot) and docs/workflow/meta-only changes (no `src/`, `tests/`, `scripts/`, `package.json`, etc.) are exempt from this requirement by CI; all other PRs that touch code must include a fragment.
120
-
121
- Do not manually edit:
122
-
123
- - `package.json` version
124
- - `CHANGELOG.md`
125
- - `.release-please-manifest.json` — exception: reconciliation when the manifest desyncs from actual releases (see below)
126
-
127
- ### Release-please manifest desync
128
-
129
- `.release-please-manifest.json` is the version source of truth for release-please. If it desyncs from the actual published release (e.g., `7.26.0` in manifest but `v7.27.1` on GitHub), release-please will propose a version that goes backwards.
130
-
131
- **Common cause:** An older release PR (e.g., `chore(main): release 7.26.0`) merges after a newer one (`chore(main): release 7.27.1`). Both PRs modify the manifest, so the later one to merge wins — regardless of which version is higher.
132
-
133
- **Detection:** If a release-please PR proposes a version that seems too low, check:
134
- 1. `gh release list --limit 5` — what's the latest published release?
135
- 2. `git show origin/main:.release-please-manifest.json` — what does the manifest say?
136
- 3. If different, the manifest is desynced.
137
-
138
- **Fix:** Open a PR that updates `.release-please-manifest.json` to match the actual latest release (e.g., `"7.27.1"`). Close the incorrect release PR with explanation. After the manifest fix merges, release-please will auto-create a correct release PR.
139
-
140
- ## Step 3 - Mandatory validation suite
141
-
142
- Run the full validation stack before pushing. The exact commands may be narrowed only when the repo contract or current task explicitly justifies it in evidence, not by intuition.
143
-
144
- ### Pre-flight
145
-
146
- `dist/` is generated output and is **not** committed (#1047). Confirm the build still
147
- succeeds and the bundle loads — do not stage `dist/`:
148
-
149
- ```bash
150
- bun run build
151
- node --input-type=module -e "await import('./dist/index.js'); console.log('dist import OK')"
152
- ```
153
-
154
- ### Tier 1 - quality
155
-
156
- Run both linter AND formatter — e.g., `bunx @biomejs/biome@<version> check --write .` or equivalent — because CI quality gates reject code that passes tests but fails style validation. **Pin the tool version** to match the version in `package.json` (`@biomejs/biome`); unversioned `bunx biome` resolves to a different version than the CI gate uses. (the repo script `bun run lint:ci` runs the pinned Biome version; prefer it over invoking `bunx biome` directly).
157
-
158
- ```bash
159
- bun run typecheck
160
- bun run lint:ci
161
- bun run scripts/check-tool-registration.ts
162
- bash scripts/check-mock-cleanup.sh
163
- bash scripts/check-invariants.sh
164
- bash scripts/check-cross-contamination.sh
165
- bash scripts/check-test-clock.sh
166
- ```
167
-
168
- ### Tier 2 - unit tests
169
-
170
- ```bash
171
- bun run test:unit:ci # CI-equivalent unit gate (quarantine ledgers + retry budget)
172
- bun run test:unit:ci <file>... # scoped mode: run only the listed repo-relative test files
173
- ```
174
-
175
- `bun run test:unit:ci` runs `scripts/ci/run-unit-tests-local.ts`, the CI-equivalent unit gate with per-platform quarantine ledgers (`scripts/ci/quarantined-tests.txt`, `quarantined-tests-macos.txt`, `quarantined-tests-windows.txt`) and the retry budget. The full serial run is 45–90 min, so use the scoped mode (`bun run test:unit:ci <file>...`) when the evidence justifies narrowing (e.g. you only touched one module). This closes the gap the hand-rolled loops left (~40% of CI's colocated `src/**` tests were uncovered).
176
-
177
- ### Tier 3 - integration
178
-
179
- ```bash
180
- bun test tests/integration ./test --timeout 120000
181
- ```
182
-
183
- ### Tier 4 - security and adversarial
184
-
185
- ```bash
186
- bun test tests/security --timeout 120000
187
- bun test tests/adversarial --timeout 120000
188
- ```
189
-
190
- ### Tier 5 - smoke
191
-
192
- ```bash
193
- bun test tests/smoke --timeout 120000
194
- ```
195
-
196
- ### Pre-existing failure handling
197
-
198
- If a failure looks unrelated, prove it on clean `origin/main` before carrying it into the PR body:
199
-
200
- ```bash
201
- git worktree add /tmp/repro-check origin/main
202
- cd /tmp/repro-check
203
- bun install --frozen-lockfile
204
- bun run build
205
- bun --smol test <repo-relative-path-to-failing-test> --timeout 120000
206
- cd ..
207
- git worktree remove /tmp/repro-check
208
- ```
209
-
210
- If the failure reproduces on `main`, document it under `## Pre-existing failures`. Do not silently inherit it.
211
-
212
- ### dist/ is generated, not committed
213
-
214
- `dist/` is build output and is git-ignored (#1047); do **not** stage or commit it, and
215
- there is no `dist-check` drift gate. The authoritative artifact check is `package-check`,
216
- which runs `npm pack` and verifies the packed tarball is complete (type declarations,
217
- grammar assets), installs it in a temp project, imports it under Node, and runs the CLI.
218
-
219
- A `package-check` failure is a source / build / `package.json#files` problem — fix the
220
- source or manifest and rebuild; never "commit dist to make CI green." CI builds `dist/`
221
- itself (the `unit`, `package-check`, and `smoke` jobs run `bun run build`), and
222
- release/publish builds from source.
223
-
224
- ## Step 4 - Workflow changes
225
-
226
- If any `.github/workflows/*.yml` file changed, every third-party `uses:` must be pinned to a full 40-character SHA.
227
-
228
- ## Step 5 - History shape
229
-
230
- Before opening a PR, verify no local-only files are staged:
231
-
232
- ```bash
233
- git diff --name-only HEAD origin/main | grep -E '\.(local\.json|vscode|idea)' || true
234
- ```
235
-
236
- Prefer a single clean commit for the branch before initial PR publication. Resolve the canonical remote first (see "Canonical remote resolution" below), then squash/push:
237
-
238
- ```bash
239
- git fetch <canonical-remote> <base-branch>
240
- git log --oneline <canonical-remote>/<base-branch>..HEAD
241
- git reset --soft <canonical-remote>/<base-branch>
242
- git commit -m "type(scope): description"
243
- git push --force-with-lease -u <canonical-remote> <branch-name>
244
- ```
245
-
246
- If a review cycle is already active and inline comments depend on current SHAs, avoid resquashing until threads are resolved.
247
-
248
- If pushing to a PR branch owned by another agent or bot, push to the PR's actual head branch:
249
-
250
- ```powershell
251
- $prBranch = gh pr view <number> --json headRefName --jq '.headRefName'
252
- git fetch <canonical-remote> $prBranch
253
- git push <canonical-remote> "<your-local-branch>:$prBranch" --force-with-lease
254
- ```
255
-
256
- ### Fork PR workflow approval
257
-
258
- If the PR is from a fork (head repository differs from base repository), GitHub requires explicit workflow approval after every push. CI jobs will remain in "waiting" status until approved:
259
-
260
- ```bash
261
- # List pending runs
262
- gh run list --repo <upstream-owner>/<upstream-repo> --branch <branch-name> --limit 5
263
-
264
- # Approve the pending run
265
- gh api -X POST repos/<upstream-owner>/<upstream-repo>/actions/runs/<run-id>/approve
266
- ```
267
-
268
- This requires `actions: write` permission on the base repository. See the `fork-pr-operations` skill for the full protocol including race conditions, permission requirements, and stale CI verification.
269
-
270
- ### Pre-push: Push Protection and Canonical Remote
271
-
272
- Before `git push`, run both checks:
273
-
274
- #### Push protection scan
275
-
276
- GitHub push protection blocks commits containing literal secret patterns. This bit the
277
- first commit of PR #1472 — a test file with a literal `sk_live_*` Stripe fixture
278
- pattern was pushed before the string-concatenation workaround was applied.
279
-
280
- **The primary check (pre-push, after commit exists):**
281
-
282
- ```bash
283
- git log origin/main..HEAD -p | grep -E 'sk_live|ghp_|xox[abprs]-|AKIA|eyJ|AIza' || true
284
- ```
285
-
286
- **The optional pre-commit add-on (staged changes only):**
287
-
288
- ```bash
289
- git diff --cached | grep -E 'sk_live|ghp_|xox[abprs]-|AKIA|eyJ|AIza' || true
290
- ```
291
-
292
- Forbidden patterns: Stripe (`sk_live_*`), GitHub (`ghp_*`), Slack (`xox[abprs]-*`),
293
- AWS (`AKIA*`), JWT (`eyJ*`), Google API (`AIza*`).
294
-
295
- **The fix:** Construct test fixtures via string concatenation rather than literal
296
- patterns. For example:
297
-
298
- ```typescript
299
- // Wrong — triggers push protection:
300
- const stripeKey = 'sk_live_' + '1234567890abcdefghijklmn'
301
-
302
- // Right — split the literal so it never appears verbatim in source:
303
- const stripeKey = 'sk_' + 'live_' + '1234567890abcdefghijklmn'
304
- ```
305
-
306
- > **Note:** This scan is a best-effort heuristic. It will not catch deliberately obfuscated patterns (e.g., base64 or hex encoding, runtime string assembly). For genuinely sensitive keys, use environment variables or a secret store — never commit credentials to source.
307
-
308
- #### Canonical remote resolution
309
-
310
- When a repo has multiple remotes (e.g. `zaxbysauce/opencode-swarm` and
311
- `ZaxbyHub/opencode-swarm`), pushing to the wrong remote causes `gh pr create` to
312
- fail with "No commits between <canonical>:main and <mirror>:<branch>". This happened
313
- on PR #1472.
314
-
315
- **The check:** `git remote -v` before push. Identify the canonical-org remote.
316
-
317
- **The rule:** Push to the canonical-org remote explicitly:
318
-
319
- ```bash
320
- git push -u <canonical-remote> <branch>
321
- ```
322
-
323
- Create the PR against the canonical repo:
324
-
325
- ```bash
326
- gh pr create --repo <canonical-org>/<repo>
327
- ```
328
-
329
- **Heuristic for identifying the canonical remote:** the canonical remote is the one whose URL points to the owning organization (e.g. `github.com/<org>/<repo>.git`), not a personal fork or mirror. When the owning org differs from the local fork's owner, the org-owned remote is canonical. Example: `github.com/ZaxbyHub/opencode-swarm.git` is canonical; `github.com/zaxbysauce/opencode-swarm.git` is a personal fork.
330
-
331
- ## Step 6 - PR creation
332
-
333
- PR body requirements:
334
-
335
- - `Closes #<issue-number>` as the first line when the PR resolves an issue
336
- - `## Summary`
337
- - `## Invariant audit`
338
- - `## Test plan`
339
-
340
- CI enforces both the section ORDER (Summary, then Invariant audit, then Test plan) and that each heading is on its own line with nothing trailing but whitespace (see `.github/workflows/pr-standards.yml`).
341
-
342
- ### Publication-gate evidence
343
-
344
- A repository publication gate (`.github/hooks/pr-publication-gate.json` ->
345
- `scripts/copilot-pr-publication-gate.sh`) may block `gh pr create`, `gh pr edit`,
346
- and `gh pr ready` until publication evidence exists. Before publishing, write:
347
-
348
- - `.swarm/evidence/pr_body.md` — the exact PR body you will publish (must contain
349
- `## Summary`, `## Invariant audit`, and `## Test plan`).
350
- - `.swarm/evidence/commit-pr-validation.md` — the validation commands you ran and
351
- their results.
352
-
353
- These files live under `.swarm/` (runtime state, never committed) and double as the
354
- evidence the gate checks. Keep them current if you edit the PR body or rerun
355
- validation. The CI `pr-standards` check enforces the same body contract server-side.
356
-
357
- PowerShell-safe pattern:
358
-
359
- ```powershell
360
- $body = @"
361
- Closes #<issue-number>
362
-
363
- ## Summary
364
- - <bullet 1>
365
- - <bullet 2>
366
-
367
- ## Invariant audit
368
- - 1 (plugin init): not touched - <evidence>
369
-
370
- ## Test plan
371
- - [ ] <validation item>
372
- "@
373
- $utf8NoBom = New-Object -TypeName System.Text.UTF8Encoding -ArgumentList $false
374
- $prBodyPath = Join-Path ([System.IO.Path]::GetTempPath()) "pr_body.txt"
375
- [System.IO.File]::WriteAllText($prBodyPath, $body, $utf8NoBom)
376
- gh pr create --title "<type>(<scope>): <description>" --body-file $prBodyPath --base main
377
- ```
378
-
379
- ## Step 6a - PR monitoring subscription
380
-
381
- After PR creation, if the project uses PR monitoring (`pr_monitor.enabled: true`
382
- in resolved opencode-swarm config), the new PR must be subscribed for background
383
- monitoring:
384
-
385
- - **Automatic (default):** when `pr_monitor.auto_subscribe_on_pr_create` is
386
- enabled (default `true`), the subscription is created automatically after
387
- `gh pr create` succeeds — no command needed. Verify with `/swarm pr status`
388
- if in doubt.
389
- - **Manual fallback:** when auto-subscribe is disabled or did not fire, run
390
- `/swarm pr subscribe <pr-url>`, which records the subscription and
391
- lazy-starts the polling worker.
392
-
393
- The post-subscription monitoring protocol — event intake, triage
394
- (fix / ask / skip), bounded-retry escalation, and terminal-state behavior —
395
- lives in the swarm-pr-subscribe skill (`../swarm-pr-subscribe/SKILL.md`).
396
-
397
- ## Step 6.5 - Issue comment
398
-
399
- If the PR closes an issue, post a comment on the issue. This is mandatory.
400
-
401
- The issue comment must include:
402
-
403
- 1. the PR link
404
- 2. what changed
405
- 3. how to use it
406
- 4. migration steps or "No migration required"
407
-
408
- PowerShell-safe pattern:
409
-
410
- ````powershell
411
- $comment = @"
412
- Fixed in PR #<pr-number>.
413
-
414
- ## What changed
415
- - <bullet 1>
416
- - <bullet 2>
417
-
418
- ## How to use
419
- ```json
420
- { "config": "example" }
421
- ```
422
-
423
- ## Migration
424
- No migration required.
425
- "@
426
- $utf8NoBom = New-Object -TypeName System.Text.UTF8Encoding -ArgumentList $false
427
- $issueCommentPath = Join-Path ([System.IO.Path]::GetTempPath()) "issue-comment.txt"
428
- [System.IO.File]::WriteAllText($issueCommentPath, $comment, $utf8NoBom)
429
- gh issue comment <issue-number> --body-file $issueCommentPath
430
- ````
431
-
432
- If the PR merged before this was done, post the missing issue comment immediately.
433
-
434
- ## Commit messages
435
-
436
- `git commit -m "..."` with parens, brackets, backticks, or dollar-signs in the message fails on PowerShell because the shell parses them as expressions. Write the commit message to a UTF-8 (no BOM) file first and use `git commit -F <file>`.
437
-
438
- PowerShell-safe pattern:
439
-
440
- ```powershell
441
- $msg = @"
442
- <type>(<scope>): <description>
443
-
444
- <optional body — note this is for the git commit message, NOT the PR body>
445
- "@
446
- $utf8NoBom = New-Object -TypeName System.Text.UTF8Encoding -ArgumentList $false
447
- $commitMsgPath = Join-Path ([System.IO.Path]::GetTempPath()) "commit-msg.txt"
448
- [System.IO.File]::WriteAllText($commitMsgPath, $msg, $utf8NoBom)
449
- git commit -F $commitMsgPath
450
- ```
451
-
452
- Apply this pattern for any commit message containing special characters, multi-paragraph bodies, or code blocks. The plain `git commit -m "..."` form remains fine for short single-line messages with no special characters.
453
-
454
- ## Step 7 - Existing PR follow-up and closeout
455
-
456
- If a PR already exists for the branch:
457
-
458
- 1. do not open a second PR
459
- 2. inspect unresolved PR feedback surfaces before updating or readying the PR: review threads/comments, requested-changes reviews, CI/check failures, mergeability/conflicts, and whether check data belongs to the current head SHA
460
- 3. use `../swarm-pr-feedback/SKILL.md` when feedback needs fixes before closeout
461
- 4. update the existing PR body when summary, invariant evidence, test counts, caveats, or pre-existing failure notes changed
462
- 5. keep the PR draft while follow-up edits are still expected or required checks are still pending
463
- 6. mark the PR ready only after the body is current and required remote checks are green, unless the user explicitly wants it ready earlier
464
- 7. after any follow-up push or force-push, verify the PR head matches the expected commit and that reported checks belong to the current `headRefOid`:
465
-
466
- ```powershell
467
- gh pr view <number> --json headRefOid,body,isDraft,state,mergeable,mergeStateStatus,statusCheckRollup,url
468
- ```
469
-
470
- Useful commands:
471
-
472
- ```powershell
473
- gh pr edit <number> --body-file "$env:TEMP\pr_body.txt"
474
- gh pr ready <number>
475
- gh pr checks <number> --watch --fail-fast
476
- ```
477
-
478
- ### Conflict closeout
479
-
480
- After resolving merge conflicts or syncing a stale branch:
481
-
482
- 1. verify there are no local unmerged paths or conflict markers,
483
- 2. push the conflict-resolution commit,
484
- 3. verify GitHub reports both `mergeable: MERGEABLE` and
485
- `mergeStateStatus: CLEAN`, not merely that local markers are gone, and
486
- 4. keep a conflict/branch-drift item in the PR closure ledger when it affected
487
- the PR.
488
-
489
- If GitHub still reports `DIRTY`, `BLOCKED`, or stale checks after local conflict
490
- resolution, fetch current `origin/main` again and re-evaluate before claiming the
491
- conflict is resolved.
492
-
493
- ### GitHub auto-merge race condition
494
-
495
- With a merge queue enabled, prefer queuing over manual freshness rebases, which
496
- avoids this race entirely. It can still occur if you rebase manually: when `main`
497
- advances while your PR is open, GitHub's PR sync machinery may **automatically push a
498
- merge commit to your branch** in the window between when you fetch and when you push.
499
- This is distinct from a conflict — it is GitHub creating a merge commit on your behalf
500
- without rebuilding generated outputs (lockfiles, etc.).
501
-
502
- Symptoms:
503
- - `git push` is rejected with "fetch first" even though you just fetched
504
- - `git log HEAD..origin/<branch>` shows a commit authored by GitHub/the repo owner with message `Merge branch 'main' into <branch>`
505
- - generated outputs (e.g. lockfiles) on that auto-merge commit are stale because it was not rebuilt
506
-
507
- Recovery:
508
- ```bash
509
- git fetch origin <branch>
510
- git log HEAD..origin/<branch> # confirm it's only the GitHub auto-merge
511
- # Your local commit is correct. Force-push it:
512
- git push origin <branch> --force-with-lease
513
- ```
514
-
515
- After force-pushing, verify the PR head SHA updated and cancel any CI run
516
- targeting the superseded auto-merge SHA to unblock concurrency:
517
-
518
- ```powershell
519
- gh run list --branch <branch> --limit 5 --json databaseId,headSha,status,workflowName
520
- gh run cancel <stale-run-id>
521
- ```
522
-
523
- ### Check closeout
524
-
525
- `gh pr checks --watch --fail-fast` is useful but can lag or flatten matrix and
526
- downstream jobs. When the PR checks view looks stale, missing, or inconsistent,
527
- use the workflow run as the authoritative detail:
528
-
529
- > **MCP environments:** When using GitHub MCP tools instead of `gh`, prefer
530
- > `get_check_runs` over `get_status`. The `get_status` method uses GitHub's
531
- > legacy commit status API: it returns `state: "pending"` even when all GitHub
532
- > Actions jobs are green, because Actions creates check-runs (not legacy
533
- > statuses). `get_check_runs` returns the actual job results.
534
-
535
- ```powershell
536
- gh run view <run-id> --json headSha,status,conclusion,jobs,url
537
- ```
538
-
539
- Keep watching after unit jobs pass; this repository may enqueue integration and
540
- smoke jobs later in the same CI run. Do not call the PR green until the current
541
- `headRefOid` has all required jobs completed successfully.
542
-
543
- If a previous run from an older PR head is still in progress or already failed
544
- and is blocking the current head's workflow through concurrency, inspect it with
545
- `gh run view <run-id> --json headSha,status,conclusion,jobs,url`. Cancel only
546
- obsolete older-head runs that are no longer relevant to the PR head you are
547
- validating, then wait for the current-head checks to complete.
548
-
549
- If you edit the PR body after checks are green, expect PR Standards / title
550
- checks to rerun. Re-check before claiming final green or merge-readiness.
551
-
552
- ### Merge queue (current-base validation)
553
-
554
- Read `file:.swarm/bundled-skills/merge-queue-readiness/SKILL.md` for the full pre-queue merge-group CI simulation protocol.
555
-
556
- When `main` has a GitHub **merge queue** enabled, do not rebase or force-push a PR
557
- *solely because `main` advanced*. Once required checks and review are green, add the
558
- PR to the merge queue; GitHub re-runs the required workflows against the queued
559
- change on top of the latest `main` (and any earlier queued PRs) before merging, so
560
- manual "freshness" rebases are unnecessary.
561
-
562
- Still rebase/force-push when there is a **real** reason: a genuine merge conflict,
563
- a stale review thread that depends on current SHAs, or a correctness issue that only
564
- appears against current `main`. The queue handles up-to-date validation; it does not
565
- resolve conflicts for you.
566
-
567
- Required workflows trigger on both `pull_request` and `merge_group`. PR-only checks
568
- (title/body validation) no-op to success on `merge_group` because the PR already
569
- satisfied them before being queued.
570
-
571
- ## Step 8 - Cancelled jobs and skipped dependents
572
-
573
- If a required GitHub Actions job is `cancelled` and downstream jobs are `skipped`:
574
-
575
- 1. inspect the run:
576
-
577
- ```powershell
578
- gh run view <run-id> --json status,conclusion,jobs,url
579
- ```
580
-
581
- 2. if the cancellation looks like orchestration or infrastructure rather than a code failure, rerun the failed or cancelled jobs:
582
-
583
- ```powershell
584
- gh run rerun <run-id> --failed
585
- ```
586
-
587
- 3. re-check the PR until required jobs are green:
588
-
589
- ```powershell
590
- gh pr checks <number> --watch --fail-fast
591
- ```
592
-
593
- Do not call the PR green or merge-ready while a required job is `cancelled`, `skipped`, `in_progress`, or otherwise non-green unless the user explicitly accepts that state.
594
-
595
- ## Step 9 - Pre-merge checklist
596
-
597
- - [ ] invariant audit is complete and current
598
- - [ ] required build and validation commands ran for touched invariants
599
- - [ ] `test_runner` was not used with broad repo-validation scopes
600
- - [ ] release fragment exists and version files are untouched
601
- - [ ] `dist/` was NOT staged (it is generated output, not committed — #1047)
602
- - [ ] PR body has `Closes`, `## Summary`, `## Invariant audit`, and `## Test plan`
603
- - [ ] if this was review follow-up, the PR body was refreshed to match current evidence
604
- - [ ] if the PR resolves an issue, the issue comment was posted with PR link, what changed, how to use it, and migration notes
605
- - [ ] if any required job was cancelled and dependent jobs skipped, the run was rerun or the non-green state was explicitly accepted by the user
606
- - [ ] for high-risk work (security, isolation, IPC, auth, payments, migrations), an independent adversarial review subagent ran before the final substantive push and all confirmed findings were addressed — if this was not done before pushing, run the review now and force-push a corrected commit before marking the PR ready
607
- - [ ] all required CI checks are green before calling the PR merge-ready
85
+ After the PR is open, watch its checks. If CI fails, read the logs, reproduce
86
+ locally, fix the real cause, and push again. A PR is not done until its required
87
+ checks are green and any review feedback is addressed. Do not merge over failing
88
+ required checks or disable a check to go green.