opencode-swarm 7.110.2 → 7.111.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,8 @@ description: Batch collection and fix protocol for CI failures. Triggered when a
6
6
  # CI Failure Batching
7
7
 
8
8
  ## Trigger
9
- When ANY CI check fails on the PR (pr-monitor surfaces `pr.ci.failed`).
9
+ When the PR monitor surfaces `pr.ci.failed`. The event is batched after the
10
+ check set is complete and includes all known failed checks in `failedChecks`.
10
11
 
11
12
  ## Protocol
12
13
  1. **DO NOT immediately fix the first failure.** Check if other jobs are still running:
@@ -29,11 +30,7 @@ Example from session #1685:
29
30
  - Without batching: 6 pushes (format → stale-assertion-1 → stale-assertion-2 → integration → merge-group → clean)
30
31
  - With batching: 2 pushes (collect all → fix all → push once → clean)
31
32
 
32
- ## Pr-monitor workaround
33
- The pr-monitor fires `pr.ci.failed` per-check. When the first event arrives:
34
- 1. Check `gh pr checks` — are other jobs still running?
35
- 2. If yes: WAIT for completion
36
- 3. If no: the single failure IS the only failure — proceed normally
37
-
38
- ## Root cause
39
- The pr-monitor should batch-fire after the CI run completes (issue #1746 item 7). This playbook is the manual protocol.
33
+ ## Pr-monitor expectation
34
+ The pr-monitor should fire one `pr.ci.failed` event for the completed failing
35
+ check set, not one event per check. Still verify with `gh pr checks` before
36
+ fixing, because GitHub can append late merge-group or matrix jobs.
@@ -1,24 +1,38 @@
1
1
  ---
2
2
  name: gate-attribution
3
- description: Per-task gate dispatch protocol. Documents the single-taskId attribution rule and parallel-lane optimization for reviewer/test_engineer gates.
3
+ description: Per-task gate dispatch protocol. Documents single-task attribution plus parseable set-dispatch reviewer/test_engineer rows.
4
4
  ---
5
5
 
6
6
  # Gate Attribution
7
7
 
8
8
  ## The rule
9
- The gate tracker attributes reviewer/test_engineer dispatches PER TASK (single taskId in the prompt). Set-dispatches covering multiple tasks do NOT count per-task, even with per-task verdicts.
9
+ The gate tracker attributes reviewer/test_engineer dispatches PER TASK. A
10
+ single-task prompt still attributes by `task_id` / `taskId` / unambiguous prompt
11
+ task ID. A set-dispatch can also count per-task when the reviewer/test_engineer
12
+ output includes parseable per-task rows:
13
+
14
+ ```
15
+ [REVIEWED] | task-2.1 | APPROVED | ...
16
+ [REVIEWED] | 2.2 | PASS | ...
17
+ ```
18
+
19
+ Rows with `task-X.Y` are normalized to `X.Y`; unsafe or non-plan IDs are ignored.
20
+ Only passing verdicts (`APPROVED`, `PASS`, or `PASSED`) create gate evidence.
21
+ Rows such as `NEEDS_REVISION` are reviewed rows but do not satisfy the gate. If
22
+ no reviewed rows are parseable, attribution falls back to the single-task rule.
10
23
 
11
24
  ## Protocol
12
- 1. **For each task requiring a gate:** Dispatch a separate reviewer and/or test_engineer with exactly ONE taskId
13
- 2. **Minimize overhead via parallel dispatch:**
25
+ 1. **For unrelated or high-risk tasks:** Dispatch separate reviewer and/or test_engineer lanes with exactly ONE taskId.
26
+ 2. **For a true set-dispatch:** Require one `[REVIEWED] | task-id | verdict | ...` row per task in the returned output. Only passing verdict rows count.
27
+ 3. **Minimize overhead via parallel dispatch when set-dispatch is not appropriate:**
14
28
  ```
15
29
  dispatch_lanes_async with:
16
30
  - common_prompt: shared verification context
17
31
  - lanes: one lane per task, each with a single taskId
18
32
  - max_concurrent: up to 3
19
33
  ```
20
- 3. **Collect + attribute:** Each lane result auto-attributes to its taskId
21
- 4. **Do NOT batch:** Even for identical reviews, dispatch separately
34
+ 4. **Collect + attribute:** Single-task lanes auto-attribute to their taskId; set-dispatch rows auto-attribute per parsed row.
35
+ 5. **Do NOT rely on prose summaries:** A batched dispatch without parseable rows is ambiguous and does not count per-task.
22
36
 
23
37
  ## Optimization for trivial tasks
24
38
  For pure ceremony gates (1-line doc fix):
@@ -28,4 +42,7 @@ taskId: X.Y
28
42
  ```
29
43
 
30
44
  ## Why this exists
31
- The gate tracker (`src/hooks/delegation-gate.ts`) keys delegation chains by `sessionID`, and task attribution resolves exactly ONE taskId per dispatch (`args.task_id ?? args.taskId`). Ambiguous multi-task prompts fail closed (resolve to null) rather than attributing to any task — so a set-dispatch covering multiple tasks does not count per-task even with per-task verdicts. Tracked in issue #1746 item 6.
45
+ The gate tracker (`src/hooks/delegation-gate.ts`) keys delegation chains by
46
+ `sessionID`. Ambiguous multi-task prompts still fail closed, but parseable
47
+ `[REVIEWED] | task-id | ...` rows provide explicit per-task attribution for
48
+ set-dispatches. Tracked in issue #1746 item 6.
@@ -10,21 +10,33 @@ Before adding the PR to the merge queue (or before the final push if the repo us
10
10
 
11
11
  ## Protocol
12
12
  1. **Fetch latest main:** `git fetch origin main`
13
- 2. **Create a temporary simulation worktree (do NOT mutate the PR branch).** Use a project-relative path UNDER the swarm worktree base so the path is portable across OSes and its later removal is permitted by the worktree guardrail (paths outside `.swarm-worktrees/` are blocked). Do NOT hardcode `/tmp` — it does not exist on Windows.
13
+ 2. **Run the simulation command (preferred):**
14
+ ```
15
+ /swarm ci-simulate --base origin/main --head <pr-branch>
16
+ ```
17
+ By default this runs fixed local CI gates: `bun run typecheck`,
18
+ `bun run lint:ci`, `bun run build`, `bun run test:unit:ci`,
19
+ integration/security/smoke tests, and `bun run drift:check`.
20
+ `test:unit:ci` runs unit tests per file with the repo's quarantine filters
21
+ and retry budget, matching CI's mock-isolation semantics. The command creates
22
+ a temporary detached worktree under `.swarm/ci-simulate`, merges the PR branch
23
+ or current worktree commit, runs the gate sequence, removes the worktree, and
24
+ prunes metadata. It does not accept arbitrary shell commands.
25
+ 3. **Manual fallback:** If the command is unavailable, create a temporary simulation worktree (do NOT mutate the PR branch). Use a project-relative path UNDER the swarm worktree base so the path is portable across OSes and its later removal is permitted by the worktree guardrail (paths outside `.swarm-worktrees/` are blocked). Do NOT hardcode `/tmp` — it does not exist on Windows.
14
26
  ```
15
27
  git worktree add .swarm-worktrees/merge-sim origin/main
16
28
  cd .swarm-worktrees/merge-sim
17
29
  git merge <pr-branch> --no-edit
18
30
  ```
19
- 3. **Run integration + unit tests against the merged result:**
31
+ 4. **Run integration + unit tests against the merged result:**
20
32
  ```
21
33
  bun test tests/integration --timeout 120000
22
34
  bun test tests/unit --timeout 120000
23
35
  ```
24
36
  (Use per-file loops for hot modules per AGENTS.md invariant 6)
25
- 4. **If failures:** Fix on the PR branch, re-push, re-simulate. Always run the cleanup step (5) before re-simulating or on any exit path — do not leave the simulation worktree behind.
26
- 5. **Cleanup (run on EVERY exit path, including failure):** `git worktree remove --force .swarm-worktrees/merge-sim`. If the remove is guardrail-blocked or fails, delete the directory directly and run `git worktree prune`.
27
- 6. **Only after simulation passes,** add PR to the merge queue.
37
+ 5. **If failures:** Fix on the PR branch, re-push, re-simulate. Always run the cleanup step (6) before re-simulating or on any exit path — do not leave the simulation worktree behind.
38
+ 6. **Cleanup for manual fallback (run on EVERY exit path, including failure):** `git worktree remove --force .swarm-worktrees/merge-sim`. If the remove is guardrail-blocked or fails, delete the directory directly and run `git worktree prune`.
39
+ 7. **Only after simulation passes,** add PR to the merge queue.
28
40
 
29
41
  ## Why this matters
30
42
  PR-branch CI and merge-group CI test DIFFERENT things:
@@ -33,5 +45,7 @@ PR-branch CI and merge-group CI test DIFFERENT things:
33
45
 
34
46
  Integration tests that pass on the PR branch may fail in merge-group context due to test interactions exposed by the merged result.
35
47
 
36
- ## Root cause
37
- A `swarm ci-simulate` command would automate this (issue #1746 item 5). This playbook is the manual protocol.
48
+ ## Automation
49
+ `/swarm ci-simulate` automates the merge-result worktree, merge, command run,
50
+ worktree removal, and metadata prune. Use the manual protocol only when the
51
+ command is unavailable or the repo needs bespoke setup.
@@ -19,11 +19,18 @@ After editing ANY `.md` file under `.opencode/skills/`, `.claude/skills/`, or `.
19
19
  - Does the assertion still hold against the new content?
20
20
  - Is it checking a substring containing the old phrase?
21
21
  - Is it checking for the ABSENCE of a word the new wording introduces? (e.g., `not.toContain('skip')` catches "this check is skipped")
22
- 4. **Update stale assertions in the same changeset.** Do NOT defer to CI.
23
- 5. **Preserve behavioral intent:** When updating, preserve what the assertion TESTS (e.g., "the plan skill has a spec-absent branch"), not just the string match.
22
+ 4. **Prefer the semantic registry:** If the assertion is checking skill behavior
23
+ rather than an exact contract string, move it behind
24
+ `tests/helpers/skill-content-registry.ts` (or add a concept there) and assert
25
+ the named concept from the test.
26
+ 5. **Update stale assertions in the same changeset.** Do NOT defer to CI.
27
+ 6. **Preserve behavioral intent:** When updating, preserve what the assertion TESTS (e.g., "the plan skill has a spec-absent branch"), not just the string match.
24
28
 
25
29
  ## Constraint
26
30
  Do NOT rubber-stamp brittle assertions. If an assertion tests implementation detail rather than behavioral intent, flag it for refactoring to a semantic check.
27
31
 
28
32
  ## Root cause
29
- A skill-content test registry would auto-adjust (issue #1746 item 3). This playbook is the manual safety net.
33
+ Skill-content tests should assert named semantic concepts where possible. The
34
+ registry in `tests/helpers/skill-content-registry.ts` is the preferred safety
35
+ net for recurring skill wording checks; use the manual grep sweep for exact
36
+ contract strings and any tests not yet migrated.
@@ -9,16 +9,12 @@ description: Protocol for cleaning parallel-coder worktree lanes before retry. T
9
9
  Before re-dispatching a coder for a task that already has a lane (any prior dispatch status).
10
10
 
11
11
  ## Protocol
12
- 1. **Ownership check do this FIRST, before any deletion.** Confirm the lane is not owned by another ACTIVE session: read `.swarm/session/state.json` and verify no other session's `delegationChains` reference `<session>/<task>`. If another active session owns it, STOP — surface the conflict and do not delete.
13
- 2. **Check for existing lane branch:** `git branch --list "swarm/lane/<session>/<task>"`
14
- 3. **If branch exists:**
15
- - Verify 0-commits-ahead: `git log --oneline HEAD..swarm/lane/<session>/<task>` empty = safe
16
- - Delete: `git branch -d swarm/lane/<session>/<task>` (use `-D` only if `-d` fails AND the commits are confirmed unneeded)
17
- - Under full-auto, `-D` is deny-pattern-blocked use `-d`
18
- 4. **Remove the per-lane worktree directory.** Target the SPECIFIC lane `.swarm-worktrees/<session>/<task>`, NOT the session parent (the parent holds sibling lanes). Prefer `git worktree remove .swarm-worktrees/<session>/<task>` — this is permitted because the path is under the `.swarm-worktrees/` base. A bare `rm -rf` / `Remove-Item -Recurse -Force` on `.swarm-worktrees/` is deny-pattern-blocked by the guardrail, so do not use it here.
19
- 5. **Prune:** `git worktree prune`
20
- 6. **Verify:** `git branch --list "swarm/lane/<session>/<task>"` returns empty
21
- 7. Only after cleanup, proceed to `declare_scope` + coder dispatch
12
+ 1. **Prefer built-in provisioning cleanup.** Re-dispatch normally through the standard coder/worktree path. Provisioning pre-cleans stale same-lane worktrees/branches when ownership is safe and the existing lane is clean.
13
+ 2. **If provisioning blocks:** Treat the error as signal. Dirty lanes, lanes active in another worktree, and lanes owned by another active session must be surfaced to the user instead of deleted.
14
+ 3. **If manual cleanup is explicitly required:** Do the ownership check FIRST. Confirm the lane is not owned by another ACTIVE session: read `.swarm/session/state.json` and verify no other session's `delegationChains` reference `<session>/<task>`. If another active session owns it, STOP.
15
+ 4. **Remove only the specific lane.** Target `.swarm-worktrees/<session>/<task>`, never the session parent. Prefer `git worktree remove .swarm-worktrees/<session>/<task>` and then `git worktree prune`.
16
+ 5. **Delete only confirmed stale branches.** `git branch -d swarm/lane/<session>/<task>` is allowed after confirming the branch is not checked out and contains no needed commits. Use force deletion only with explicit human approval.
17
+ 6. **Verify:** `git branch --list "swarm/lane/<session>/<task>"` returns empty before retrying.
22
18
 
23
19
  ## Root cause
24
- The provisioning code should auto-clean after coder completion/denial/cancellation (tracked in issue #1746 item 1). This playbook is the temporary protocol.
20
+ Stale same-lane worktrees and branches used to require manual cleanup before retry. Provisioning now handles the safe clean/stale cases automatically and fails closed for dirty, active, or cross-session-owned lanes.
@@ -14,7 +14,7 @@ import {
14
14
  resolveWorktreeBaseDir,
15
15
  shortenWorktreePath,
16
16
  writeLaneProfileToDiskReal
17
- } from "./index-dm35e55e.js";
17
+ } from "./index-dnbca696.js";
18
18
  import"./index-5e4e2hvv.js";
19
19
  import"./index-p0arc26j.js";
20
20
  import"./index-zgwm4ryv.js";
@@ -12,7 +12,7 @@ import {
12
12
  runCuratorInit,
13
13
  runCuratorPhase,
14
14
  writeCuratorSummary
15
- } from "./index-smk3st51.js";
15
+ } from "./index-7xfh4k71.js";
16
16
  import"./index-53z1afgh.js";
17
17
  import"./index-c8s9a3zh.js";
18
18
  import"./index-xddysq89.js";
@@ -32,7 +32,7 @@ import"./index-jt58s751.js";
32
32
  import"./index-wvrj16f0.js";
33
33
  import"./index-q1exe2b3.js";
34
34
  import"./index-vzzt3ygr.js";
35
- import"./index-dm35e55e.js";
35
+ import"./index-dnbca696.js";
36
36
  import"./index-r3j3458j.js";
37
37
  import"./index-jtqkh8jf.js";
38
38
  import"./index-5e4e2hvv.js";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  createCuratorLLMDelegate
4
- } from "./index-smk3st51.js";
4
+ } from "./index-7xfh4k71.js";
5
5
  import"./index-53z1afgh.js";
6
6
  import"./index-c8s9a3zh.js";
7
7
  import"./index-xddysq89.js";
@@ -21,7 +21,7 @@ import"./index-jt58s751.js";
21
21
  import"./index-wvrj16f0.js";
22
22
  import"./index-q1exe2b3.js";
23
23
  import"./index-vzzt3ygr.js";
24
- import"./index-dm35e55e.js";
24
+ import"./index-dnbca696.js";
25
25
  import"./index-r3j3458j.js";
26
26
  import"./index-jtqkh8jf.js";
27
27
  import"./index-5e4e2hvv.js";
@@ -1,8 +1,8 @@
1
1
  // @bun
2
2
  import {
3
3
  handleGuardrailExplain
4
- } from "./index-4k3gh2nz.js";
5
- import"./index-smk3st51.js";
4
+ } from "./index-9ptp9kky.js";
5
+ import"./index-7xfh4k71.js";
6
6
  import"./index-53z1afgh.js";
7
7
  import"./index-c8s9a3zh.js";
8
8
  import"./index-xddysq89.js";
@@ -22,7 +22,7 @@ import"./index-jt58s751.js";
22
22
  import"./index-wvrj16f0.js";
23
23
  import"./index-q1exe2b3.js";
24
24
  import"./index-vzzt3ygr.js";
25
- import"./index-dm35e55e.js";
25
+ import"./index-dnbca696.js";
26
26
  import"./index-r3j3458j.js";
27
27
  import"./index-jtqkh8jf.js";
28
28
  import"./index-5e4e2hvv.js";
@@ -5,7 +5,7 @@ import {
5
5
  isHiveEligible,
6
6
  promoteFromSwarm,
7
7
  promoteToHive
8
- } from "./index-smk3st51.js";
8
+ } from "./index-7xfh4k71.js";
9
9
  import"./index-53z1afgh.js";
10
10
  import"./index-c8s9a3zh.js";
11
11
  import"./index-xddysq89.js";
@@ -25,7 +25,7 @@ import"./index-jt58s751.js";
25
25
  import"./index-wvrj16f0.js";
26
26
  import"./index-q1exe2b3.js";
27
27
  import"./index-vzzt3ygr.js";
28
- import"./index-dm35e55e.js";
28
+ import"./index-dnbca696.js";
29
29
  import"./index-r3j3458j.js";
30
30
  import"./index-jtqkh8jf.js";
31
31
  import"./index-5e4e2hvv.js";