Skip to content

Commit 0cb116e

Browse files
committed
feat(swarm): close conformance gaps and enforce spec review loop
1 parent 9e65fbe commit 0cb116e

37 files changed

Lines changed: 4957 additions & 74 deletions

‎docs/spec/swarm.md‎

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# Swarm v1 Conformance Specification (Gap Closure)
2+
3+
Status: implemented
4+
Last updated: 2026-03-02
5+
6+
This document defines the conformance requirements needed for the current Swarm
7+
implementation to fully align with `docs/features/swarm.md`.
8+
9+
It records review findings as normative requirements.
10+
Items already implemented in code are listed as baseline and are not redefined
11+
here unless clarification is needed.
12+
13+
## 0. Scope
14+
15+
This spec covers the remaining conformance work for:
16+
17+
- `roboppi swarm` CLI behavior
18+
- coordinator lifecycle and cleanup guarantees
19+
- housekeeping/crash-recovery coverage
20+
- path and output safety rules
21+
- test strategy alignment
22+
23+
Out of scope for this document:
24+
25+
- multi-host swarm support
26+
- nested swarms
27+
- MCP transport delivery (`roboppi swarm mcp`) in v1
28+
29+
## 1. Source Of Truth
30+
31+
Primary design:
32+
33+
- `docs/features/swarm.md`
34+
35+
This document is a conformance addendum and MUST be interpreted together with
36+
that design document.
37+
38+
## 2. Baseline (Already Implemented)
39+
40+
The following are treated as implemented baseline:
41+
42+
- File-backed mailbox/task store with atomic rename-based transitions.
43+
- Core CLI surface:
44+
- `init`
45+
- `members list`
46+
- `message send|broadcast|recv|ack`
47+
- `tasks add|list|claim|complete`
48+
- `housekeep`
49+
- Metadata-only `_events.jsonl` emission for mailbox/tasks.
50+
- Capability wiring of `MAILBOX` / `TASKS` in workflow/daemon/type layers.
51+
- Workflow top-level `swarm:` integration and TUI swarm tab visibility.
52+
53+
This spec focuses only on residual gaps.
54+
55+
## 3. Normative Gap-Closure Requirements
56+
57+
### 3.1 `message recv --wait-ms` MUST be implemented
58+
59+
`roboppi swarm message recv` MUST support:
60+
61+
- `--wait-ms <M>` where `M` is an integer `>= 0`.
62+
63+
Behavior:
64+
65+
- If messages are immediately available, return immediately.
66+
- Otherwise, poll until either:
67+
- at least one message becomes available, or
68+
- elapsed time reaches `wait-ms`.
69+
- On timeout, return success with an empty `messages` array.
70+
- `--wait-ms 0` MUST be equivalent to non-blocking current behavior.
71+
72+
Polling interval MAY use a default constant; it MUST be deterministic and
73+
bounded.
74+
75+
### 3.2 Coordinator shutdown MUST verify completion and apply cleanup policy
76+
77+
Coordinator shutdown MUST satisfy all of:
78+
79+
1. Send `shutdown_request` to all running teammates.
80+
2. Wait for teammate completion and/or explicit `shutdown_ack` evidence within a
81+
bounded timeout.
82+
3. Force-abort only remaining non-settled teammates after timeout.
83+
4. Apply cleanup policy from `team.json.cleanup_policy`:
84+
- if `retain_mailbox=false`, mailbox artifacts are removed at shutdown
85+
- if `retain_tasks=false`, tasks artifacts are removed at shutdown
86+
5. Emit a final metadata-only cleanup event documenting completion and what was
87+
retained/removed.
88+
89+
Cleanup and event emission MUST be best-effort and MUST NOT leave partial
90+
deletions that violate store consistency guarantees.
91+
92+
### 3.3 Task orphan recovery MUST include stale `in_progress` handling
93+
94+
Housekeeping MUST handle stale tasks in `tasks/in_progress/`:
95+
96+
- detect stale tasks via TTL
97+
- move stale tasks to either:
98+
- `pending/` (requeue), or
99+
- `orphaned/` (if introduced)
100+
- update task metadata atomically (`status`, timestamps, ownership fields)
101+
- emit metadata-only event for audit
102+
103+
The operation MUST be idempotent and race-safe under concurrent housekeeping
104+
runs.
105+
106+
### 3.4 CLI output contract MUST be JSON-safe for all failures
107+
108+
For every `roboppi swarm` subcommand failure, including argument/usage errors:
109+
110+
- stdout MUST contain exactly one JSON object:
111+
- `{ "ok": false, "error": "<message>" }`
112+
- exit code MUST be non-zero.
113+
114+
For help output (`-h` / `--help`):
115+
116+
- help text MUST go to stderr
117+
- stdout MUST be empty
118+
- exit code MUST be `0`.
119+
120+
### 3.5 Path safety MUST be explicit for tool-facing path inputs
121+
122+
All tool-facing path inputs MUST be constrained to Swarm-safe boundaries.
123+
124+
Requirements:
125+
126+
- All filesystem mutations for swarm data MUST remain inside
127+
`<context_dir>/_swarm`.
128+
- User-supplied path values (including artifact-like values) MUST reject:
129+
- absolute paths (unless explicitly allowed by command contract)
130+
- `..` traversal
131+
- symlink escape outside allowed roots after resolution.
132+
133+
Validation errors MUST follow the JSON error contract in section 3.4.
134+
135+
### 3.6 Integration testing MUST match section 11 intent
136+
137+
Test suite MUST include at least one supervised integration/AT scenario that:
138+
139+
- runs with supervised mode enabled
140+
- uses `roboppi swarm ...` commands (not only direct store API calls)
141+
- includes two `CUSTOM` workers exchanging messages/tasks
142+
- verifies emitted `swarm_*` exec events and/or `_swarm/*/_events.jsonl`
143+
artifacts
144+
145+
## 4. Capability And Identity Clarifications
146+
147+
### 4.1 `MAILBOX` and `TASKS` separation
148+
149+
`MAILBOX` and `TASKS` MUST remain independently gateable from
150+
`RUN_COMMANDS`.
151+
152+
It is acceptable in v1 that both map to the same restricted `roboppi swarm:*`
153+
surface, but adapters SHOULD evolve toward least-privilege separation by
154+
subcommand group.
155+
156+
### 4.2 Identity anti-spoofing
157+
158+
Current membership validation is mandatory baseline.
159+
160+
Optional per-member token-file verification is a future hardening and is NOT
161+
required for v1 conformance.
162+
163+
## 5. Conformance Checklist
164+
165+
A release is considered conformant to this spec only when all items below are
166+
true:
167+
168+
- [x] 3.1 implemented and covered by unit/AT tests
169+
- `--wait-ms 0`, timeout, and arrival-during-wait AT coverage in `tests/at/swarm-cli.test.ts`
170+
- [x] 3.2 implemented and covered by lifecycle tests
171+
- Shutdown bounded end-to-end: `teammateShutdownWaitMs` deadline + 5s settle cap
172+
- All unsettled teammates force-aborted after deadline (regardless of ack evidence)
173+
- Cleanup trash kept within `_swarm/.trash/` (not `os.tmpdir()`)
174+
- `tests/unit/swarm/coordinator.test.ts` (bounded timeout, abort-only-unsettled, cleanup policy, cleanup event)
175+
- [x] 3.3 implemented and covered by housekeeping tests
176+
- `tests/unit/swarm/housekeeping-tasks.test.ts` (stale detection, metadata rewrite, idempotency, concurrent safety)
177+
- [x] 3.4 implemented and covered by CLI error/help tests
178+
- Unknown subcommand, missing flag, semantic failure AT coverage in `tests/at/swarm-cli.test.ts`
179+
- [x] 3.5 implemented and covered by path-safety tests
180+
- `assertSwarmRootSafe()` + `validateMemberIdPath()` applied to all mutating commands including `init`, `recv`, `ack`, `housekeep`
181+
- `init` validates `--lead` and all `--json-stdin` member IDs via `validateMemberIdPath()`
182+
- Symlink escape + traversal rejection AT in `tests/at/swarm-cli.test.ts` (including `init` subcommand)
183+
- [x] 3.6 implemented and verified in CI test targets
184+
- `tests/at/swarm-supervised-custom.test.ts` uses CLI subprocess calls (not direct store API)
185+
186+
## 6. Compatibility
187+
188+
This specification preserves compatibility with the `version: "1"` swarm
189+
on-disk objects and with the design direction in `docs/features/swarm.md`.

‎examples/swarm-impl-loop.yaml‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ steps:
4545
Read (by exact file path):
4646
- .roboppi-loop/request.md
4747
- docs/features/swarm.md
48+
- docs/spec/swarm.md
4849
- docs/design.md
4950
- src/types/worker-task.ts
5051
- src/worker/adapters/claude-code-adapter.ts
@@ -60,6 +61,8 @@ steps:
6061
- Group by milestones (MVP first; then follow-ups)
6162
- Include file paths and symbols when possible
6263
- Include explicit test tasks (at least: make typecheck, make test-all)
64+
- Add explicit conformance tasks for `docs/spec/swarm.md` section 3.1-3.6 and section 5 checklist.
65+
- If any spec item is partial/missing, add at least one concrete task per gap (code + test).
6366
- Keep scope aligned to .roboppi-loop/request.md
6467
capabilities: [READ, EDIT]
6568
timeout: "25m"
@@ -94,13 +97,15 @@ steps:
9497
Read:
9598
- .roboppi-loop/request.md
9699
- docs/features/swarm.md
100+
- docs/spec/swarm.md
97101
- .roboppi-loop/todo.md
98102
- .roboppi-loop/review.md (if present)
99103
- .roboppi-loop/fix.md (if present)
100104
101105
Task:
102106
- If .roboppi-loop/fix.md exists and is non-empty, apply ONLY those fixes (minimal, targeted changes).
103107
- Otherwise, implement the TODO checklist items (focus on the MVP first).
108+
- Give priority to unresolved MUST items in `docs/spec/swarm.md` section 3.
104109
- Update the TODO checkboxes as you complete items.
105110
- Keep changes focused; avoid drive-by refactors.
106111
@@ -133,7 +138,7 @@ steps:
133138
Task:
134139
1) Run tests:
135140
- make test-all
136-
2) Review the changes against the request + TODO + design doc.
141+
2) Review the changes against the request + TODO + `docs/features/swarm.md` + `docs/spec/swarm.md`.
137142
3) Write/update:
138143
- .roboppi-loop/review.md
139144
- .roboppi-loop/review.verdict (single-line JSON; see Output rules)
@@ -154,6 +159,7 @@ steps:
154159
You must read at least:
155160
- .roboppi-loop/request.md
156161
- docs/features/swarm.md
162+
- docs/spec/swarm.md
157163
- .roboppi-loop/todo.md
158164
- .roboppi-loop/review.base_ref
159165
- .roboppi-loop/review.diff
@@ -162,12 +168,19 @@ steps:
162168
- .roboppi-loop/review.untracked.diff
163169
164170
Format for .roboppi-loop/review.md:
165-
- Sections: Summary, Issues, Verification
171+
- Sections: Summary, Conformance, Issues, Verification
172+
- In Conformance, include `docs/spec/swarm.md` section 3.1-3.6 as:
173+
- status: implemented | partial | missing
174+
- evidence: file paths and symbols
175+
- required fixes (for partial/missing)
166176
167177
Output rules:
168178
- Write .roboppi-loop/review.verdict as a single-line JSON object:
169179
- complete => {"decision":"complete","check_id":"$ROBOPPI_COMPLETION_CHECK_ID"}
170180
- incomplete => {"decision":"incomplete","check_id":"$ROBOPPI_COMPLETION_CHECK_ID"}
181+
- Verdict policy:
182+
- If any MUST requirement in `docs/spec/swarm.md` section 3 is partial or missing, verdict MUST be `incomplete`.
183+
- If all section 3 MUST requirements are implemented and tests pass, verdict MAY be `complete`.
171184
- When FAIL, also include:
172185
- "reasons": ["..."]
173186
- "fingerprints": ["..."]

‎scripts/self-dev/swarm/bootstrap.sh‎

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@ rm -f \
2525

2626
if [ ! -f "${LOOP_DIR}/request.md" ]; then
2727
cat > "${LOOP_DIR}/request.md" <<'EOF'
28-
# Request: Implement Swarm (Agent Teams) for Roboppi
28+
# Request: Swarm Gap Closure (Design + Conformance)
2929
30-
Implement the Swarm feature described in `docs/features/swarm.md`.
30+
Implement/close remaining Swarm gaps so behavior aligns with both:
31+
32+
- `docs/features/swarm.md`
33+
- `docs/spec/swarm.md`
3134
3235
Swarm is a local, file-backed agent team system:
3336
@@ -38,56 +41,56 @@ Swarm is a local, file-backed agent team system:
3841
This is inspired by Claude Code agent teams:
3942
- https://code.claude.com/docs/en/agent-teams
4043
41-
## Scope (v1 / MVP)
44+
## Scope (v1 / MVP + Conformance)
4245
4346
1) Swarm file store (maildir-like)
44-
- Create a file-backed mailbox + task store under `<context_dir>/_swarm/` as
45-
specified in `docs/features/swarm.md`.
46-
- Use atomic operations (`tmp` + `rename`) to avoid corruption under concurrency.
47+
- Keep file-backed mailbox + task store under `<context_dir>/_swarm/`.
48+
- Keep atomic operations (`tmp` + `rename`) for concurrency safety.
4749
4850
2) CLI tools (model-facing)
49-
- Add a `roboppi swarm` CLI group with JSON outputs:
51+
- Keep/extend `roboppi swarm` CLI group:
5052
- `swarm init`
5153
- `swarm members list`
5254
- `swarm message send|broadcast|recv|ack`
5355
- `swarm tasks add|list|claim|complete`
54-
- `swarm housekeep` (requeue stale processing messages)
55-
- All commands MUST print machine-readable JSON to stdout on success.
56-
- Errors should be actionable and MUST NOT print non-JSON to stdout.
57-
58-
3) Capability gating for Claude Code
59-
- Add a new `WorkerCapability` (name: `MAILBOX`) and map it so Claude Code gets
60-
a restricted tool:
61-
- allow `Bash(roboppi swarm:*)` (or equivalent narrow allowlist)
62-
- do NOT grant full `Bash` just for mailbox access
63-
- Update documentation and tests accordingly.
64-
65-
4) Tests
66-
- Add unit tests covering:
67-
- message send -> inbox/new
68-
- recv claim -> processing
69-
- ack -> cur
70-
- broadcast -> N recipients
71-
- task add/claim/complete transitions
72-
- housekeeping (stale processing requeue)
73-
- `make test-all` must pass.
56+
- `swarm housekeep`
57+
- Implement `swarm message recv --wait-ms`.
58+
- Enforce JSON-safe output contract on all failures (including arg/usage errors).
59+
60+
3) Lifecycle and housekeeping closure
61+
- Coordinator shutdown must include deterministic completion checks and cleanup
62+
policy application.
63+
- Housekeeping must cover stale task recovery for `tasks/in_progress/` as
64+
defined by spec.
65+
66+
4) Capability/identity/safety closure
67+
- Keep `MAILBOX` / `TASKS` capability support and gating.
68+
- Keep metadata-only event policy.
69+
- Ensure tool-facing path handling remains traversal-safe.
70+
71+
5) Tests and review quality gate
72+
- Add/extend tests for all spec MUST items.
73+
- `make test-all` should pass in normal local environments.
74+
- Completion review MUST include a conformance audit against
75+
`docs/spec/swarm.md` section 3.1-3.6.
7476
7577
## Constraints
7678
7779
- Keep changes focused; avoid repo-wide refactors.
7880
- Prefer ASCII in new files.
79-
- Validate all paths stay within `<context_dir>/_swarm/` (no traversal).
81+
- Validate paths for swarm mutations stay within `<context_dir>/_swarm/`.
8082
- Bound message/task sizes (e.g. 64KB message body; 256KB task file).
8183
8284
## Acceptance Criteria
8385
84-
- [ ] `docs/features/swarm.md` remains accurate (update if implementation diverges)
85-
- [ ] `roboppi swarm init` creates the expected directory layout + config files
86-
- [ ] `roboppi swarm message send/recv/ack` works end-to-end (file semantics)
87-
- [ ] broadcast delivers to all members
88-
- [ ] `roboppi swarm tasks add/claim/complete` works and is race-safe
89-
- [ ] housekeeping requeues stale `processing/` messages
90-
- [ ] Claude Code capability `MAILBOX` enables only `roboppi swarm:*` bash usage
86+
- [ ] `docs/features/swarm.md` and `docs/spec/swarm.md` are both accurate
87+
- [ ] `docs/spec/swarm.md` section 3.1 (`recv --wait-ms`) is implemented + tested
88+
- [ ] `docs/spec/swarm.md` section 3.2 (shutdown/cleanup policy + final event) is implemented + tested
89+
- [ ] `docs/spec/swarm.md` section 3.3 (stale `in_progress` task recovery) is implemented + tested
90+
- [ ] `docs/spec/swarm.md` section 3.4 (JSON-safe CLI failure output) is implemented + tested
91+
- [ ] `docs/spec/swarm.md` section 3.5 (path safety for tool-facing inputs) is implemented + tested
92+
- [ ] `docs/spec/swarm.md` section 3.6 (supervised integration using `roboppi swarm`) is implemented + tested
93+
- [ ] `make typecheck` passes
9194
- [ ] `make test-all` passes
9295
EOF
9396
fi

0 commit comments

Comments
 (0)