opencode-swarm-plugin 0.26.1 → 0.27.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.
- package/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +23 -0
- package/README.md +43 -46
- package/bin/swarm.ts +8 -8
- package/dist/compaction-hook.d.ts +57 -0
- package/dist/compaction-hook.d.ts.map +1 -0
- package/dist/hive.d.ts +741 -0
- package/dist/hive.d.ts.map +1 -0
- package/dist/index.d.ts +139 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1353 -350
- package/dist/learning.d.ts +9 -9
- package/dist/plugin.js +1176 -350
- package/dist/schemas/cell-events.d.ts +1352 -0
- package/dist/schemas/{bead-events.d.ts.map → cell-events.d.ts.map} +1 -1
- package/dist/schemas/{bead.d.ts → cell.d.ts} +173 -29
- package/dist/schemas/cell.d.ts.map +1 -0
- package/dist/schemas/index.d.ts +11 -7
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/structured.d.ts +17 -7
- package/dist/structured.d.ts.map +1 -1
- package/dist/swarm-decompose.d.ts +5 -5
- package/dist/swarm-orchestrate.d.ts +16 -2
- package/dist/swarm-orchestrate.d.ts.map +1 -1
- package/dist/swarm-prompts.d.ts +9 -9
- package/dist/swarm-prompts.d.ts.map +1 -1
- package/dist/swarm-review.d.ts +210 -0
- package/dist/swarm-review.d.ts.map +1 -0
- package/dist/swarm-worktree.d.ts +185 -0
- package/dist/swarm-worktree.d.ts.map +1 -0
- package/dist/swarm.d.ts +7 -0
- package/dist/swarm.d.ts.map +1 -1
- package/dist/tool-availability.d.ts +3 -2
- package/dist/tool-availability.d.ts.map +1 -1
- package/docs/analysis-socratic-planner-pattern.md +1 -1
- package/docs/planning/ADR-007-swarm-enhancements-worktree-review.md +168 -0
- package/docs/testing/context-recovery-test.md +2 -2
- package/evals/README.md +2 -2
- package/evals/scorers/index.ts +7 -7
- package/examples/commands/swarm.md +21 -23
- package/examples/plugin-wrapper-template.ts +310 -44
- package/examples/skills/{beads-workflow → hive-workflow}/SKILL.md +40 -40
- package/examples/skills/swarm-coordination/SKILL.md +1 -1
- package/global-skills/swarm-coordination/SKILL.md +14 -14
- package/global-skills/swarm-coordination/references/coordinator-patterns.md +3 -3
- package/package.json +2 -2
- package/src/compaction-hook.ts +161 -0
- package/src/{beads.integration.test.ts → hive.integration.test.ts} +92 -80
- package/src/{beads.ts → hive.ts} +378 -219
- package/src/index.ts +57 -20
- package/src/learning.ts +9 -9
- package/src/output-guardrails.test.ts +4 -4
- package/src/output-guardrails.ts +9 -9
- package/src/planning-guardrails.test.ts +1 -1
- package/src/planning-guardrails.ts +1 -1
- package/src/schemas/{bead-events.test.ts → cell-events.test.ts} +83 -77
- package/src/schemas/cell-events.ts +807 -0
- package/src/schemas/{bead.ts → cell.ts} +95 -41
- package/src/schemas/evaluation.ts +1 -1
- package/src/schemas/index.ts +90 -18
- package/src/schemas/swarm-context.ts +2 -2
- package/src/structured.test.ts +15 -15
- package/src/structured.ts +18 -11
- package/src/swarm-decompose.ts +23 -23
- package/src/swarm-orchestrate.ts +135 -21
- package/src/swarm-prompts.ts +43 -43
- package/src/swarm-review.test.ts +702 -0
- package/src/swarm-review.ts +696 -0
- package/src/swarm-worktree.test.ts +501 -0
- package/src/swarm-worktree.ts +575 -0
- package/src/swarm.integration.test.ts +12 -12
- package/src/tool-availability.ts +36 -3
- package/dist/beads.d.ts +0 -386
- package/dist/beads.d.ts.map +0 -1
- package/dist/schemas/bead-events.d.ts +0 -698
- package/dist/schemas/bead.d.ts.map +0 -1
- package/src/schemas/bead-events.ts +0 -583
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# ADR-007: Swarm Enhancements - Worktree Isolation + Structured Review
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Proposed
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
After reviewing [nexxeln/opencode-config](https://github.com/nexxeln/opencode-config), we identified several patterns that would strengthen our swarm coordination:
|
|
10
|
+
|
|
11
|
+
1. **Git worktree isolation** - Each worker gets a complete isolated copy of the repo
|
|
12
|
+
2. **Structured review loop** - Workers must pass review before completion
|
|
13
|
+
3. **Retry options on abort** - Clean recovery paths when things go wrong
|
|
14
|
+
|
|
15
|
+
Currently our swarm uses:
|
|
16
|
+
- **File reservations** via Swarm Mail for conflict prevention
|
|
17
|
+
- **UBS scan** on completion for bug detection
|
|
18
|
+
- **Manual cleanup** on abort
|
|
19
|
+
|
|
20
|
+
## Decision
|
|
21
|
+
|
|
22
|
+
### 1. Optional Worktree Isolation Mode
|
|
23
|
+
|
|
24
|
+
Add `isolation` parameter to swarm initialization:
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
swarm_init({
|
|
28
|
+
task: "Large refactor across 50 files",
|
|
29
|
+
isolation: "worktree" // or "reservation" (default)
|
|
30
|
+
})
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**When to use worktrees:**
|
|
34
|
+
- Large refactors touching many files
|
|
35
|
+
- High risk of merge conflicts
|
|
36
|
+
- Need complete isolation (different node_modules, etc.)
|
|
37
|
+
|
|
38
|
+
**When to use reservations (default):**
|
|
39
|
+
- Most swarm tasks
|
|
40
|
+
- Quick parallel work
|
|
41
|
+
- Lower overhead
|
|
42
|
+
|
|
43
|
+
**Worktree lifecycle:**
|
|
44
|
+
```
|
|
45
|
+
swarm_worktree_create(task_id) → /path/to/worktree
|
|
46
|
+
↓
|
|
47
|
+
worker does work in worktree
|
|
48
|
+
↓
|
|
49
|
+
swarm_worktree_merge(task_id) → cherry-pick commit to main
|
|
50
|
+
↓
|
|
51
|
+
swarm_worktree_cleanup(task_id) → remove worktree
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**On abort:** Hard reset main to start commit, delete all worktrees.
|
|
55
|
+
|
|
56
|
+
### 2. Structured Review Step
|
|
57
|
+
|
|
58
|
+
The coordinator reviews worker output before marking complete. This replaces the current "trust but verify with UBS" approach.
|
|
59
|
+
|
|
60
|
+
**Review flow:**
|
|
61
|
+
```
|
|
62
|
+
worker completes → coordinator reviews → approved/needs_changes
|
|
63
|
+
↓
|
|
64
|
+
if needs_changes: worker fixes (max 3 attempts)
|
|
65
|
+
↓
|
|
66
|
+
if approved: mark complete
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Review prompt includes:**
|
|
70
|
+
- Epic goal (the big picture)
|
|
71
|
+
- Task requirements
|
|
72
|
+
- What completed tasks this builds on (dependency context)
|
|
73
|
+
- What future tasks depend on this (downstream context)
|
|
74
|
+
- The actual code changes
|
|
75
|
+
|
|
76
|
+
**Why coordinator reviews (not separate reviewer agent):**
|
|
77
|
+
- Coordinator already has full epic context loaded
|
|
78
|
+
- Avoids spawning another agent just for review
|
|
79
|
+
- Keeps the feedback loop tight
|
|
80
|
+
- Coordinator can make judgment calls about "good enough"
|
|
81
|
+
|
|
82
|
+
**Review criteria:**
|
|
83
|
+
1. Does it fulfill the task requirements?
|
|
84
|
+
2. Does it serve the epic goal?
|
|
85
|
+
3. Will downstream tasks be able to use it?
|
|
86
|
+
4. Are there critical bugs? (UBS scan still runs)
|
|
87
|
+
|
|
88
|
+
### 3. Retry Options on Abort
|
|
89
|
+
|
|
90
|
+
When a swarm aborts (user request or failure), provide clear recovery paths:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"retry_options": {
|
|
95
|
+
"same_plan": "/swarm --retry",
|
|
96
|
+
"edit_plan": "/swarm --retry --edit",
|
|
97
|
+
"fresh_start": "/swarm \"original task\""
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**`--retry`**: Resume with same plan, skip completed tasks
|
|
103
|
+
**`--retry --edit`**: Show plan for modification before resuming
|
|
104
|
+
**Fresh start**: Decompose from scratch
|
|
105
|
+
|
|
106
|
+
This requires persisting swarm session state (already have this via Hive cells).
|
|
107
|
+
|
|
108
|
+
## Implementation
|
|
109
|
+
|
|
110
|
+
### Phase 1: Structured Review (Priority)
|
|
111
|
+
1. Add review step to `swarm_complete`
|
|
112
|
+
2. Create review prompt with epic context injection
|
|
113
|
+
3. Handle needs_changes → worker retry loop (max 3)
|
|
114
|
+
4. Keep UBS scan as additional safety net
|
|
115
|
+
|
|
116
|
+
### Phase 2: Worktree Isolation
|
|
117
|
+
1. Add `isolation` mode to `swarm_init`
|
|
118
|
+
2. Implement worktree lifecycle tools
|
|
119
|
+
3. Update worker prompts to work in worktree path
|
|
120
|
+
4. Add cherry-pick merge on completion
|
|
121
|
+
5. Add cleanup on abort
|
|
122
|
+
|
|
123
|
+
### Phase 3: Retry Options
|
|
124
|
+
1. Persist session state for recovery
|
|
125
|
+
2. Add `--retry` and `--retry --edit` flags
|
|
126
|
+
3. Skip completed tasks on retry
|
|
127
|
+
4. Show plan editor for `--edit` mode
|
|
128
|
+
|
|
129
|
+
## Consequences
|
|
130
|
+
|
|
131
|
+
### Positive
|
|
132
|
+
- **Better quality**: Structured review catches issues before integration
|
|
133
|
+
- **Safer large refactors**: Worktree isolation eliminates merge conflicts
|
|
134
|
+
- **Cleaner recovery**: Retry options reduce friction after failures
|
|
135
|
+
- **Coordinator stays in control**: Review keeps human-in-the-loop feel
|
|
136
|
+
|
|
137
|
+
### Negative
|
|
138
|
+
- **More complexity**: Two isolation modes to maintain
|
|
139
|
+
- **Slower completion**: Review step adds latency
|
|
140
|
+
- **Disk usage**: Worktrees consume space (mitigated by cleanup)
|
|
141
|
+
|
|
142
|
+
### Neutral
|
|
143
|
+
- **Credit**: Patterns inspired by nexxeln/opencode-config - should acknowledge in docs
|
|
144
|
+
|
|
145
|
+
## Alternatives Considered
|
|
146
|
+
|
|
147
|
+
### Separate Reviewer Agent
|
|
148
|
+
nexxeln uses a dedicated reviewer subagent. We chose coordinator-as-reviewer because:
|
|
149
|
+
- Avoids context duplication (coordinator already has epic context)
|
|
150
|
+
- Faster feedback loop
|
|
151
|
+
- Coordinator can make "ship it" judgment calls
|
|
152
|
+
|
|
153
|
+
### Staged Changes on Finalize
|
|
154
|
+
nexxeln soft-resets to leave changes staged for user review. We're skipping this because:
|
|
155
|
+
- Our flow already has explicit commit step
|
|
156
|
+
- Hive tracks what changed
|
|
157
|
+
- User can always `git diff` before committing
|
|
158
|
+
|
|
159
|
+
### Always Use Worktrees
|
|
160
|
+
Could simplify by always using worktrees. Rejected because:
|
|
161
|
+
- Overkill for most tasks
|
|
162
|
+
- Slower setup/teardown
|
|
163
|
+
- File reservations work fine for typical parallel work
|
|
164
|
+
|
|
165
|
+
## References
|
|
166
|
+
|
|
167
|
+
- [nexxeln/opencode-config](https://github.com/nexxeln/opencode-config) - Source of inspiration
|
|
168
|
+
- Epic: `bd-lf2p4u-mjaja96b9da` - Swarm Enhancements
|
|
@@ -38,7 +38,7 @@ This test scenario verifies that the swarm coordination system can survive conte
|
|
|
38
38
|
- Epic bead with at least one subtask
|
|
39
39
|
- Example:
|
|
40
40
|
```bash
|
|
41
|
-
|
|
41
|
+
hive_create_epic(
|
|
42
42
|
epic_title: "Test Context Recovery",
|
|
43
43
|
subtasks: [
|
|
44
44
|
{ title: "Modify test files", files: ["test/file1.ts", "test/file2.ts"] }
|
|
@@ -151,7 +151,7 @@ This test scenario verifies that the swarm coordination system can survive conte
|
|
|
151
151
|
```typescript
|
|
152
152
|
// Query the event store directly (if you have access)
|
|
153
153
|
// Or check via beads metadata
|
|
154
|
-
|
|
154
|
+
hive_query(status: "in_progress")
|
|
155
155
|
```
|
|
156
156
|
|
|
157
157
|
**Expected result:**
|
package/evals/README.md
CHANGED
|
@@ -71,13 +71,13 @@ evalite("My decomposition test", {
|
|
|
71
71
|
},
|
|
72
72
|
task: async (input) => {
|
|
73
73
|
// Call your decomposition logic here
|
|
74
|
-
// Should return
|
|
74
|
+
// Should return CellTree JSON as string
|
|
75
75
|
},
|
|
76
76
|
scorers: [subtaskIndependence, coverageCompleteness],
|
|
77
77
|
});
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
##
|
|
80
|
+
## CellTree Format
|
|
81
81
|
|
|
82
82
|
Scorers expect output as JSON string matching:
|
|
83
83
|
|
package/evals/scorers/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createScorer } from "evalite";
|
|
2
|
-
import type {
|
|
2
|
+
import type { CellTree } from "../../src/schemas/index.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Custom scorers for evaluating swarm task decomposition quality
|
|
@@ -18,7 +18,7 @@ export const subtaskIndependence = createScorer({
|
|
|
18
18
|
description: "Checks that no files appear in multiple subtasks",
|
|
19
19
|
scorer: ({ output }) => {
|
|
20
20
|
try {
|
|
21
|
-
const beadTree = JSON.parse(String(output)) as
|
|
21
|
+
const beadTree = JSON.parse(String(output)) as CellTree;
|
|
22
22
|
const fileMap = new Map<string, number>();
|
|
23
23
|
|
|
24
24
|
// Track which files appear in which subtasks
|
|
@@ -48,7 +48,7 @@ export const subtaskIndependence = createScorer({
|
|
|
48
48
|
} catch (error) {
|
|
49
49
|
return {
|
|
50
50
|
score: 0,
|
|
51
|
-
message: `Failed to parse
|
|
51
|
+
message: `Failed to parse CellTree: ${error}`,
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
},
|
|
@@ -82,7 +82,7 @@ export const coverageCompleteness = createScorer({
|
|
|
82
82
|
description: "Checks that subtasks cover the full task scope",
|
|
83
83
|
scorer: ({ output, expected }) => {
|
|
84
84
|
try {
|
|
85
|
-
const beadTree = JSON.parse(String(output)) as
|
|
85
|
+
const beadTree = JSON.parse(String(output)) as CellTree;
|
|
86
86
|
|
|
87
87
|
// If expected files specified, check coverage
|
|
88
88
|
const expectedData = expected as Record<string, unknown> | undefined;
|
|
@@ -127,7 +127,7 @@ export const coverageCompleteness = createScorer({
|
|
|
127
127
|
} catch (error) {
|
|
128
128
|
return {
|
|
129
129
|
score: 0,
|
|
130
|
-
message: `Failed to parse
|
|
130
|
+
message: `Failed to parse CellTree: ${error}`,
|
|
131
131
|
};
|
|
132
132
|
}
|
|
133
133
|
},
|
|
@@ -148,7 +148,7 @@ export const instructionClarity = createScorer({
|
|
|
148
148
|
description: "Checks that subtasks have clear, actionable instructions",
|
|
149
149
|
scorer: ({ output }) => {
|
|
150
150
|
try {
|
|
151
|
-
const beadTree = JSON.parse(String(output)) as
|
|
151
|
+
const beadTree = JSON.parse(String(output)) as CellTree;
|
|
152
152
|
|
|
153
153
|
if (beadTree.subtasks.length === 0) {
|
|
154
154
|
return {
|
|
@@ -193,7 +193,7 @@ export const instructionClarity = createScorer({
|
|
|
193
193
|
} catch (error) {
|
|
194
194
|
return {
|
|
195
195
|
score: 0,
|
|
196
|
-
message: `Failed to parse
|
|
196
|
+
message: `Failed to parse CellTree: ${error}`,
|
|
197
197
|
};
|
|
198
198
|
}
|
|
199
199
|
},
|
|
@@ -42,7 +42,7 @@ Swarm Mail is embedded (no external server needed) and provides:
|
|
|
42
42
|
|
|
43
43
|
- File reservations to prevent conflicts
|
|
44
44
|
- Message passing between agents
|
|
45
|
-
- Thread-based coordination tied to
|
|
45
|
+
- Thread-based coordination tied to cells
|
|
46
46
|
|
|
47
47
|
## Workflow
|
|
48
48
|
|
|
@@ -201,7 +201,7 @@ swarm_plan_interactive(
|
|
|
201
201
|
>
|
|
202
202
|
> **DO NOT decompose inline in the coordinator thread.** This consumes massive context with file reading, CASS queries, and reasoning.
|
|
203
203
|
>
|
|
204
|
-
> **ALWAYS delegate to a `swarm/planner` subagent** that returns only the validated
|
|
204
|
+
> **ALWAYS delegate to a `swarm/planner` subagent** that returns only the validated CellTree JSON.
|
|
205
205
|
|
|
206
206
|
**❌ Don't do this (inline planning):**
|
|
207
207
|
|
|
@@ -215,7 +215,7 @@ swarm_plan_interactive(
|
|
|
215
215
|
|
|
216
216
|
```bash
|
|
217
217
|
# 1. Create planning bead
|
|
218
|
-
|
|
218
|
+
hive_create(title="Plan: <task>", type="task", description="Decompose into subtasks")
|
|
219
219
|
|
|
220
220
|
# 2. Get final prompt from swarm_plan_interactive (when ready_to_decompose=true)
|
|
221
221
|
# final_prompt = <from last swarm_plan_interactive call>
|
|
@@ -225,22 +225,22 @@ Task(
|
|
|
225
225
|
subagent_type="swarm/planner",
|
|
226
226
|
description="Decompose task: <task>",
|
|
227
227
|
prompt="
|
|
228
|
-
You are a swarm planner. Generate a
|
|
228
|
+
You are a swarm planner. Generate a CellTree for this task.
|
|
229
229
|
|
|
230
230
|
<final_prompt from swarm_plan_interactive>
|
|
231
231
|
|
|
232
232
|
## Instructions
|
|
233
233
|
1. Reason about decomposition strategy
|
|
234
|
-
2. Generate
|
|
234
|
+
2. Generate CellTree JSON
|
|
235
235
|
3. Validate with swarm_validate_decomposition
|
|
236
|
-
4. Return ONLY the validated
|
|
236
|
+
4. Return ONLY the validated CellTree JSON (no analysis)
|
|
237
237
|
|
|
238
|
-
Output: Valid
|
|
238
|
+
Output: Valid CellTree JSON only.
|
|
239
239
|
"
|
|
240
240
|
)
|
|
241
241
|
|
|
242
242
|
# 4. Subagent returns validated JSON, parse it
|
|
243
|
-
#
|
|
243
|
+
# cellTree = <result from subagent>
|
|
244
244
|
```
|
|
245
245
|
|
|
246
246
|
**Planning Mode Behavior:**
|
|
@@ -262,25 +262,23 @@ Output: Valid BeadTree JSON only.
|
|
|
262
262
|
### 5. Create Beads
|
|
263
263
|
|
|
264
264
|
```bash
|
|
265
|
-
|
|
265
|
+
hive_create_epic(epic_title="<task>", subtasks=[{title, files, priority}...])
|
|
266
266
|
```
|
|
267
267
|
|
|
268
268
|
Rules:
|
|
269
269
|
|
|
270
|
-
- Each
|
|
270
|
+
- Each cell completable by one agent
|
|
271
271
|
- Independent where possible (parallelizable)
|
|
272
|
-
- 3-7
|
|
272
|
+
- 3-7 cells per swarm
|
|
273
273
|
- No file overlap between subtasks
|
|
274
274
|
|
|
275
|
-
### 6.
|
|
275
|
+
### 6. Spawn Agents (Workers Reserve Their Own Files)
|
|
276
276
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
### 7. Spawn Agents
|
|
277
|
+
> **⚠️ CRITICAL: Coordinator NEVER reserves files.**
|
|
278
|
+
>
|
|
279
|
+
> Workers reserve their own files via `swarmmail_reserve()` as their first action.
|
|
280
|
+
> This is how conflict detection works - reservation = ownership.
|
|
281
|
+
> If coordinator reserves, workers get blocked and swarm stalls.
|
|
284
282
|
|
|
285
283
|
**CRITICAL: Spawn ALL in a SINGLE message with multiple Task calls.**
|
|
286
284
|
|
|
@@ -330,7 +328,7 @@ swarmmail_read_message(message_id=N) # Read specific message
|
|
|
330
328
|
- Worker blocked >5 min → Check inbox, offer guidance
|
|
331
329
|
- File conflict → Mediate, reassign files
|
|
332
330
|
- Worker asking questions → Answer directly
|
|
333
|
-
- Scope creep → Redirect, create new
|
|
331
|
+
- Scope creep → Redirect, create new cell for extras
|
|
334
332
|
|
|
335
333
|
If incompatibilities spotted, broadcast:
|
|
336
334
|
|
|
@@ -343,7 +341,7 @@ swarmmail_send(to=["*"], subject="Coordinator Update", body="<guidance>", import
|
|
|
343
341
|
```bash
|
|
344
342
|
swarm_complete(project_key="$PWD", agent_name="<your-name>", bead_id="<epic-id>", summary="<done>", files_touched=[...])
|
|
345
343
|
swarmmail_release() # Release any remaining reservations
|
|
346
|
-
|
|
344
|
+
hive_sync()
|
|
347
345
|
```
|
|
348
346
|
|
|
349
347
|
### 10. Create PR (unless --to-main)
|
|
@@ -408,9 +406,9 @@ Not: Do Everything Inline → Run Out of Context → Fail
|
|
|
408
406
|
- [ ] **swarmmail_init** called FIRST
|
|
409
407
|
- [ ] Knowledge gathered (semantic-memory, CASS, pdf-brain, skills)
|
|
410
408
|
- [ ] **Planning delegated to swarm/planner subagent** (NOT inline)
|
|
411
|
-
- [ ]
|
|
409
|
+
- [ ] CellTree validated (no file conflicts)
|
|
412
410
|
- [ ] Epic + subtasks created
|
|
413
|
-
- [ ]
|
|
411
|
+
- [ ] **Coordinator did NOT reserve files** (workers do this themselves)
|
|
414
412
|
- [ ] Workers spawned in parallel
|
|
415
413
|
- [ ] Progress monitored via **swarmmail_inbox** (limit=5, no bodies)
|
|
416
414
|
- [ ] PR created (or pushed to main)
|