|
| 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`. |
0 commit comments