@limina-labs/momentum 0.30.2

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 (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +214 -0
  3. package/adapters/antigravity/adapter.js +196 -0
  4. package/adapters/antigravity/hooks.json +39 -0
  5. package/adapters/antigravity/instructions/AGENTS.md +638 -0
  6. package/adapters/antigravity/instructions/header.md +3 -0
  7. package/adapters/antigravity/instructions/surfaces.md +153 -0
  8. package/adapters/antigravity/instructions/vars.json +1 -0
  9. package/adapters/antigravity/scripts/antigravity-hook-adapter.sh +147 -0
  10. package/adapters/antigravity/skills/momentum-orient/SKILL.md +29 -0
  11. package/adapters/antigravity/skills/momentum-reviewer-architecture/SKILL.md +39 -0
  12. package/adapters/antigravity/skills/momentum-reviewer-qa/SKILL.md +38 -0
  13. package/adapters/antigravity/skills/momentum-reviewer-security/SKILL.md +42 -0
  14. package/adapters/antigravity/skills/swarm-supervisor/SKILL.md +75 -0
  15. package/adapters/antigravity/workflows/continue.md +39 -0
  16. package/adapters/antigravity/workflows/dispatch.md +49 -0
  17. package/adapters/antigravity/workflows/handoff.md +38 -0
  18. package/adapters/antigravity/workflows/review-code.md +84 -0
  19. package/adapters/antigravity/workflows/scout.md +42 -0
  20. package/adapters/antigravity/workflows/swarm.md +203 -0
  21. package/adapters/claude-code/adapter.js +148 -0
  22. package/adapters/claude-code/commands/continue.md +82 -0
  23. package/adapters/claude-code/commands/dispatch.md +154 -0
  24. package/adapters/claude-code/commands/handoff.md +85 -0
  25. package/adapters/claude-code/commands/review-code.md +194 -0
  26. package/adapters/claude-code/commands/scout.md +119 -0
  27. package/adapters/claude-code/commands/swarm.md +242 -0
  28. package/adapters/claude-code/instructions/header.md +3 -0
  29. package/adapters/claude-code/instructions/vars.json +1 -0
  30. package/adapters/claude-code/settings.json +36 -0
  31. package/adapters/codex/adapter.js +225 -0
  32. package/adapters/codex/agents/momentum-reviewer-architecture.toml +57 -0
  33. package/adapters/codex/agents/momentum-reviewer-qa.toml +52 -0
  34. package/adapters/codex/agents/momentum-reviewer-security.toml +57 -0
  35. package/adapters/codex/agents/swarm-supervisor.toml +76 -0
  36. package/adapters/codex/commands/continue.md +40 -0
  37. package/adapters/codex/commands/dispatch.md +111 -0
  38. package/adapters/codex/commands/handoff.md +57 -0
  39. package/adapters/codex/commands/scout.md +90 -0
  40. package/adapters/codex/commands/swarm.md +334 -0
  41. package/adapters/codex/hooks.json +36 -0
  42. package/adapters/codex/instructions/AGENTS.md +691 -0
  43. package/adapters/codex/instructions/header.md +3 -0
  44. package/adapters/codex/instructions/surfaces.md +206 -0
  45. package/adapters/codex/instructions/vars.json +1 -0
  46. package/adapters/codex/skills/momentum-orient/SKILL.md +29 -0
  47. package/adapters/opencode/adapter.js +224 -0
  48. package/adapters/opencode/agents/momentum-reviewer-architecture.md +54 -0
  49. package/adapters/opencode/agents/momentum-reviewer-qa.md +48 -0
  50. package/adapters/opencode/agents/momentum-reviewer-security.md +48 -0
  51. package/adapters/opencode/agents/swarm-supervisor.md +51 -0
  52. package/adapters/opencode/commands/continue.md +40 -0
  53. package/adapters/opencode/commands/dispatch.md +111 -0
  54. package/adapters/opencode/commands/handoff.md +57 -0
  55. package/adapters/opencode/commands/review-code.md +194 -0
  56. package/adapters/opencode/commands/scout.md +90 -0
  57. package/adapters/opencode/commands/swarm.md +334 -0
  58. package/adapters/opencode/instructions/AGENTS.md +604 -0
  59. package/adapters/opencode/instructions/header.md +3 -0
  60. package/adapters/opencode/instructions/surfaces.md +119 -0
  61. package/adapters/opencode/instructions/vars.json +1 -0
  62. package/adapters/opencode/plugins/momentum.js +219 -0
  63. package/adapters/opencode/skills/momentum-lanes/SKILL.md +30 -0
  64. package/adapters/opencode/skills/momentum-orient/SKILL.md +29 -0
  65. package/adapters/opencode/skills/momentum-track/SKILL.md +28 -0
  66. package/adapters/opencode/skills/momentum-validate/SKILL.md +31 -0
  67. package/bin/antigravity.js +112 -0
  68. package/bin/ecosystem.js +1302 -0
  69. package/bin/lanes.js +300 -0
  70. package/bin/momentum.js +1857 -0
  71. package/bin/okf.js +72 -0
  72. package/bin/orchestration-commands.js +305 -0
  73. package/bin/state-commands.js +218 -0
  74. package/bin/swarm.js +1104 -0
  75. package/bin/waves.js +147 -0
  76. package/core/adapter-capabilities.md +112 -0
  77. package/core/adapter-parity-matrix.md +170 -0
  78. package/core/commands/brainstorm-idea.md +98 -0
  79. package/core/commands/brainstorm-phase.md +129 -0
  80. package/core/commands/complete-phase.md +130 -0
  81. package/core/commands/ecosystem.md +161 -0
  82. package/core/commands/hotfix.md +64 -0
  83. package/core/commands/initiative.md +119 -0
  84. package/core/commands/lanes.md +94 -0
  85. package/core/commands/log.md +45 -0
  86. package/core/commands/migrate.md +70 -0
  87. package/core/commands/review.md +31 -0
  88. package/core/commands/session.md +79 -0
  89. package/core/commands/start-phase.md +161 -0
  90. package/core/commands/start-project.md +142 -0
  91. package/core/commands/sync-docs.md +81 -0
  92. package/core/commands/systematic-debug.md +46 -0
  93. package/core/commands/track.md +54 -0
  94. package/core/commands/validate.md +96 -0
  95. package/core/ecosystem/layout.md +128 -0
  96. package/core/ecosystem/lib/index.js +245 -0
  97. package/core/ecosystem/lib/initiative.js +258 -0
  98. package/core/ecosystem/lib/pointer.js +198 -0
  99. package/core/ecosystem/lib/state.js +295 -0
  100. package/core/ecosystem/schema/ecosystem.schema.json +85 -0
  101. package/core/ecosystem/schema/initiative.schema.json +61 -0
  102. package/core/ecosystem/scripts/session-append.sh +167 -0
  103. package/core/ecosystem/templates/ecosystem-agents.md +79 -0
  104. package/core/ecosystem/templates/ecosystem-claude.md +79 -0
  105. package/core/ecosystem/templates/ecosystem-settings-claude.json +14 -0
  106. package/core/ecosystem/templates/initiative-template.md +50 -0
  107. package/core/engines/subagent-dispatch.md +80 -0
  108. package/core/git-hooks/commit-msg +14 -0
  109. package/core/git-hooks/contract.js +176 -0
  110. package/core/git-hooks/pre-push +15 -0
  111. package/core/git-hooks/run-check.js +160 -0
  112. package/core/instructions/legacy-project-md-hashes.json +12 -0
  113. package/core/instructions/navigation.md +14 -0
  114. package/core/instructions/rules-body.md +454 -0
  115. package/core/lanes/lib/board.js +161 -0
  116. package/core/lanes/lib/land.js +301 -0
  117. package/core/lanes/lib/signals.js +207 -0
  118. package/core/lanes/lib/state.js +325 -0
  119. package/core/lib/frontmatter.js +163 -0
  120. package/core/lib/okf-migrate.js +374 -0
  121. package/core/lib/okf-types.js +61 -0
  122. package/core/lifecycle-contract.md +59 -0
  123. package/core/orchestration/capability-routing.js +120 -0
  124. package/core/orchestration/continue.js +102 -0
  125. package/core/orchestration/dispatch.js +366 -0
  126. package/core/orchestration/events.js +197 -0
  127. package/core/orchestration/handoff.js +317 -0
  128. package/core/orchestration/index.js +50 -0
  129. package/core/orchestration/run-artifact.js +93 -0
  130. package/core/orchestration/scout.js +327 -0
  131. package/core/orchestration/session-log.js +123 -0
  132. package/core/orchestration/tracking.js +180 -0
  133. package/core/orchestration/types.js +131 -0
  134. package/core/scripts/brainstorm-gate.sh +157 -0
  135. package/core/scripts/check-history-reminder.sh +110 -0
  136. package/core/scripts/sessionstart-handoff.sh +180 -0
  137. package/core/specs-templates/CLAUDE.md +484 -0
  138. package/core/specs-templates/README.md +32 -0
  139. package/core/specs-templates/specs/README.md +30 -0
  140. package/core/specs-templates/specs/adhoc/README.md +31 -0
  141. package/core/specs-templates/specs/adhoc/_TEMPLATE.md +29 -0
  142. package/core/specs-templates/specs/architecture/ecosystem.md +214 -0
  143. package/core/specs-templates/specs/backlog/backlog.md +46 -0
  144. package/core/specs-templates/specs/backlog/details/.gitkeep +0 -0
  145. package/core/specs-templates/specs/changelog/.gitkeep +0 -0
  146. package/core/specs-templates/specs/decisions/0000-template.md +33 -0
  147. package/core/specs-templates/specs/decisions/README.md +29 -0
  148. package/core/specs-templates/specs/decisions/impact-map.md +14 -0
  149. package/core/specs-templates/specs/decisions/index.md +4 -0
  150. package/core/specs-templates/specs/index.md +16 -0
  151. package/core/specs-templates/specs/phases/README.md +41 -0
  152. package/core/specs-templates/specs/phases/index.md +6 -0
  153. package/core/specs-templates/specs/planning/roadmap.md +23 -0
  154. package/core/specs-templates/specs/status.md +70 -0
  155. package/core/specs-templates/specs/vision/principles.md +16 -0
  156. package/core/specs-templates/specs/vision/project-charter.md +35 -0
  157. package/core/specs-templates/specs/vision/success-criteria.md +19 -0
  158. package/core/swarm/absorb.js +294 -0
  159. package/core/swarm/conductor.js +499 -0
  160. package/core/swarm/focus.js +151 -0
  161. package/core/swarm/inbox.js +222 -0
  162. package/core/swarm/join.js +138 -0
  163. package/core/swarm/lib/board.js +178 -0
  164. package/core/swarm/lib/brief.js +157 -0
  165. package/core/swarm/lib/git-sha-cache.js +71 -0
  166. package/core/swarm/lib/incremental-log.js +117 -0
  167. package/core/swarm/lib/manifest.js +578 -0
  168. package/core/swarm/lib/pre-merge.js +112 -0
  169. package/core/swarm/lib/saga.js +146 -0
  170. package/core/swarm/lib/sessions.js +83 -0
  171. package/core/swarm/lib/tokens.js +255 -0
  172. package/core/swarm/lib/wave-ordering.js +55 -0
  173. package/core/swarm/schema/board.schema.json +54 -0
  174. package/core/swarm/schema/contract.schema.json +56 -0
  175. package/core/swarm/schema/dispatch-run.schema.json +70 -0
  176. package/core/swarm/schema/manifest.schema.json +234 -0
  177. package/core/swarm/schema/signal.schema.json +61 -0
  178. package/core/swarm/signals.js +296 -0
  179. package/core/swarm/supervise.md +81 -0
  180. package/core/waves/lib/plan-graph.js +175 -0
  181. package/core/waves/lib/waves.js +83 -0
  182. package/package.json +46 -0
@@ -0,0 +1,242 @@
1
+ Swarm — sustained parallel multi-project feature delivery (Phase 17, v0.20.0).
2
+
3
+ A **swarm** is a declared cross-repo work unit driven from ONE user session. The user's session becomes the **conductor**. The conductor spawns one **supervisor** subagent per impacted repo, each pinned to that repo's working directory with its own fresh context. Each supervisor runs momentum's normal `/start-phase` → implement → `/sync-docs` → `/complete-phase` loop INSIDE its repo. The conductor coordinates waves (computed from `ecosystem.json` dependency edges), surfaces inbox decisions, broadcasts cross-cutting concerns, and synthesizes per-repo retrospectives at fan-in.
4
+
5
+ > v0.20.0 ships Claude Code only. Codex + Antigravity parity is Phase 18.
6
+
7
+ ## Architecture
8
+
9
+ | Layer | Owns | Reads |
10
+ |---|---|---|
11
+ | Conductor (this user session) | `<eco>/swarms/<id>/manifest.json` + `board.json` + `contracts/` + `inbox/` + `signals/` + `changes/` | Per-supervisor `dispatch-run-<id>.json` (status) |
12
+ | Supervisor (per repo, background) | `<repo>/specs/phases/phase-N-<slug>/*` + `<repo>/.momentum/runs/dispatch-run-<id>.json` | Its phase brief + contract + history.md tail |
13
+
14
+ Agents are stateless across turns; **state lives in files**. A swarm survives session boundaries the same way a phase does — every state-changing action writes to disk; `/swarm resume` reconstitutes from disk.
15
+
16
+ ## When to use
17
+
18
+ - A feature spans **two or more momentum-installed repos** AND has dependency ordering (frontend depends on backend depends on shared-types).
19
+ - The user wants ONE session driving the whole feature, not three serial sessions.
20
+ - An initiative exists or is about to exist at `<eco>/initiatives/<slug>.md`.
21
+
22
+ Do NOT use `/swarm` for:
23
+ - Read-only cross-repo audits — use `/dispatch`.
24
+ - Single-repo phases — use `/start-phase` directly.
25
+ - Pure context transfer — use `/handoff`.
26
+
27
+ ## Subcommands
28
+
29
+ The slash command form mirrors the CLI: `/swarm <sub> [args]`. The CLI floor is `momentum swarm <sub> [args]` — pick whichever door fits the moment. Both produce the same on-disk artifacts.
30
+
31
+ ---
32
+
33
+ ### `/swarm start <slug> --initiative <slug> --repos r1,r2,... --phase <phase-slug> [--mode checkpoint|autopilot]`
34
+
35
+ Plan + spawn Wave 1.
36
+
37
+ **Step 1 — Present the plan and ask for approval.**
38
+
39
+ Compute the wave plan in-process (no spawn yet) by calling the CLI floor in dry-run:
40
+
41
+ ```bash
42
+ momentum swarm start <slug> --initiative <slug> --repos r1,r2,... --phase <phase-slug> --mode <mode> --json
43
+ ```
44
+
45
+ Read the JSON. Render the wave plan to the user:
46
+
47
+ ```
48
+ ▸ Swarm <NNNN-slug> — planned (not yet spawning)
49
+ Initiative: <slug>
50
+ Mode: <mode>
51
+ Waves:
52
+ Wave 1: <r1>, <r2>
53
+ Wave 2: <r3>
54
+ Wave 3: <r4>
55
+ Token budget: 300k per supervisor (override with /swarm budget)
56
+ Lease: 24h per repo, renewed each turn
57
+
58
+ Proceed?
59
+ ```
60
+
61
+ WAIT for user approval. If `mode = autopilot`, plan approval is the only checkpoint until completion. If `mode = checkpoint`, you'll also pause between waves.
62
+
63
+ **Step 2 — Spawn Wave 1 supervisors (foreground synthesis, background sessions).**
64
+
65
+ After approval, spawn one Claude Code background session per Wave 1 repo. The CLI does this when invoked with `--spawn`:
66
+
67
+ ```bash
68
+ momentum swarm start <slug> --initiative <slug> --repos ... --phase <phase-slug> --mode <mode> --spawn
69
+ ```
70
+
71
+ If `claude --bg` is not available in this env, the CLI surfaces the spawn directives and exits — degrade by reporting the directives to the user (they can launch sessions manually) and continue with conductor polling on the existing manifest.
72
+
73
+ **Step 3 — Begin the conductor poll loop.**
74
+
75
+ See `/swarm status` (next subcommand). On every conductor turn:
76
+
77
+ 1. Read `<eco>/swarms/<id>/board.json` (≈3KB).
78
+ 2. Read `<eco>/swarms/<id>/inbox/INDEX.md`.
79
+ 3. If `inbox_count > 0`, surface each pending item; resolve interactively.
80
+ 4. If a supervisor reports `done: true` for the active wave's last repo, run the wave checkpoint flow (see `/swarm verify` — Phase 17 G2).
81
+
82
+ ---
83
+
84
+ ### `/swarm status <swarm-id>`
85
+
86
+ Render the materialized board cache. Read-only — no manifest mutation. Strategy A from the indexing design: conductor reads ONLY `board.json` (~3KB).
87
+
88
+ ```bash
89
+ momentum swarm status <swarm-id>
90
+ ```
91
+
92
+ Default output is a rendered ANSI table. Pass `--json` for machine-readable.
93
+
94
+ Surface:
95
+ - Per-repo: wave, status, tasks N/M, tokens used/budget, commits, current task.
96
+ - `inbox_count` warning at the bottom if > 0.
97
+ - Recent activity tail (last 10 audit events).
98
+
99
+ When inboxes are pending, prompt: "Run `/swarm verify <id>` to surface the questions, or `/swarm tell <id> <repo> '...'` to push context to a specific supervisor."
100
+
101
+ ---
102
+
103
+ ### `/swarm claim <swarm-id> <repo> [--session <id>] [--lease-hours 24]`
104
+
105
+ > Phase 17.5 / v0.20.2 — multi-session ownership primitive.
106
+
107
+ Claim ownership of `<repo>` inside `<swarm-id>` for the current session. The conductor library uses this whenever a session needs authority to write to a repo's manifest entry — `/swarm focus`, `/swarm join`, and a co-conductor taking a wave all compose `claim` under the hood.
108
+
109
+ ```bash
110
+ momentum swarm claim <swarm-id> <repo> [--session <id>] [--lease-hours 24]
111
+ ```
112
+
113
+ Claim succeeds when:
114
+ - the repo is `_unclaimed` or `_focusing` (sentinel — anyone may claim), OR
115
+ - the current owner's `lease_expires_at` is in the past (takeover; audit logs both `claim` and `lease-takeover`).
116
+
117
+ Claim is rejected when the current owner's lease is still valid; the CLI writes a `claim-request` signal so the existing owner sees the request on their next conductor poll. Exit code 1 on rejection.
118
+
119
+ On success the manifest sets `owner = <session>`, refreshes `lease_renewed_at`, and sets `lease_expires_at = now + <lease-hours>`. The board cache is refreshed.
120
+
121
+ ---
122
+
123
+ ### `/swarm focus <swarm-id> <repo> [--session <id>] [--expires-min 60]`
124
+
125
+ > Phase 17.5 / v0.20.2 — split one repo off the swarm into a side-session.
126
+
127
+ Issue a single-use focus token for `<repo>` and hand control to a second Claude Code session. Use when one repo needs sustained one-on-one attention without halting the rest of the swarm. The original conductor keeps every other repo; the new side-session takes `<repo>` and drives its phase to completion. Reunite via `/swarm absorb`.
128
+
129
+ ```bash
130
+ momentum swarm focus <swarm-id> <repo> [--session <id>] [--expires-min 60]
131
+ ```
132
+
133
+ Behavior:
134
+ 1. Asserts the caller currently owns `<repo>` (rejected with exit 1 if not).
135
+ 2. Issues an opaque focus token at `<eco>/swarms/<id>/tokens/<token>.json` (single-use, 1-hour default expiry).
136
+ 3. Flips `repos[<repo>].owner` to the `_focusing` sentinel — anyone with the token may claim.
137
+ 4. Writes a `focus-request` signal carrying the token + repo.
138
+ 5. Audit-logs `focus`.
139
+ 6. Prints a spawn directive — run `claude --bg --cwd <eco>` in a second terminal, then inside that session call `momentum swarm join <swarm-id> --token <token>`.
140
+
141
+ The token is single-use: consuming it (via `/swarm join --token`) deletes the file and atomically flips ownership to the receiver. If the token expires before consumption, run `/swarm claim <repo>` against the FOCUSING sentinel to recover.
142
+
143
+ ---
144
+
145
+ ### `/swarm join <swarm-id> [--token <token>] [--claim <repo>] [--session <id>]`
146
+
147
+ > Phase 17.5 / v0.20.2 — register a session with an existing swarm.
148
+
149
+ Attach the current session to `<swarm-id>` as a co-conductor. Adds the session to `sessions[]` (idempotent — touch on re-join), auto-renews any repos the session already owns, and optionally consumes a transfer token or claims a specific repo.
150
+
151
+ ```bash
152
+ momentum swarm join <swarm-id> [--token <token>] [--claim <repo>] [--session <id>]
153
+ ```
154
+
155
+ Three shapes:
156
+
157
+ | Form | Result |
158
+ |---|---|
159
+ | `join <id>` | Registration only. Adds the session; renews any owned leases. |
160
+ | `join <id> --token <token>` | Consumes the token. If `kind=focus`, claims the token's `target_repo` automatically. If `kind=join`, registers only (equivalent to plain join). |
161
+ | `join <id> --claim <repo>` | Explicit claim — bound by the same lease rules as `/swarm claim`. Exits 1 if rejected. |
162
+
163
+ Exit codes:
164
+ - 0 on success.
165
+ - 1 if the swarm doesn't exist, the token is missing/expired, or the claim is rejected (`EOWNERSHIP`).
166
+
167
+ Audit log gets a `join` entry detailing the route — `registration only` / `via token kind=…` / `with --claim …`.
168
+
169
+ ---
170
+
171
+ ### `/swarm absorb <target-swarm-id> <source-swarm-id> [--yes] [--session <id>]`
172
+
173
+ > Phase 17.5 / v0.20.2 — converge two swarms back into one.
174
+
175
+ Merge `<source-swarm-id>` into `<target-swarm-id>` (the caller's swarm). Use to reunite after a `/swarm focus` split, or to absorb work from a peer swarm that's now done.
176
+
177
+ ```bash
178
+ momentum swarm absorb <target-swarm-id> <source-swarm-id> [--yes] [--session <id>]
179
+ ```
180
+
181
+ Behavior:
182
+ 1. Loads both manifests. If either is missing → exit 1.
183
+ 2. Detects contract conflicts: for every shared `surface` in both swarms' `contracts`, the `owner` must match and the `content_hash` (when present) must match. Mismatches abort cleanly — both swarms left untouched — with a printed diff for each conflict.
184
+ 3. Without `--yes`, prints a dry-run plan (repos to add, overlap, contract status) and exits 0 without writing. Re-run with `--yes` to proceed.
185
+ 4. On commit:
186
+ - `repos`: union; target wins on overlap (so a repo already in flight in target is not regressed by source's state)
187
+ - `waves`: recomputed via the wave-ordering library over the union of repos, against `ecosystem.json` dependencies
188
+ - `sessions[]`: union by `session_id` (earliest `first_seen`, latest `last_seen`)
189
+ - `contracts`: union; target's version kept on overlap (we verified compatibility above)
190
+ - `audit[]`: concat + sort by timestamp; append an `absorb` entry
191
+ - `inbox/`: source's pending items copied into target with bumped ids
192
+ 5. Archives the source swarm directory to `<eco>/swarms/.absorbed/<source-id>/`. Forensics preserved.
193
+ 6. Refreshes target's `board.json`.
194
+
195
+ JSON output (`--json`) returns `{ absorbed, into, reposAdded, reposOverlapped, inboxMoved, archivedTo }`.
196
+
197
+ ---
198
+
199
+ ### `/swarm release <swarm-id> <repo> [--session <id>]`
200
+
201
+ > Phase 17.5 / v0.20.2 — multi-session ownership primitive.
202
+
203
+ Release the current session's ownership of `<repo>`. Sets `owner = _unclaimed`, clears the lease, and audit-logs `release`. Idempotent — releasing an already-unclaimed repo is a no-op.
204
+
205
+ ```bash
206
+ momentum swarm release <swarm-id> <repo> [--session <id>]
207
+ ```
208
+
209
+ Only the current owner may release. Attempting to release a repo you don't own exits 1 (you'd need `/swarm claim` against an expired lease, or the owner to release first).
210
+
211
+ ---
212
+
213
+ ### `/swarm cancel <swarm-id> [--reason "<text>"]`
214
+
215
+ Graceful halt. Halts every supervisor, marks the swarm `cancelled` in the manifest, preserves all artifacts for forensics.
216
+
217
+ ```bash
218
+ momentum swarm cancel <swarm-id> --reason "<text>"
219
+ ```
220
+
221
+ **Confirm with the user before running.** Cancel is reversible only via `/swarm resume` re-attaching to a frozen state — you cannot un-cancel a wave that was mid-flight if commits have been pushed and force-overwrites would be needed.
222
+
223
+ After cancel:
224
+ 1. All queued/running/blocked repos move to `cancelled`.
225
+ 2. All queued/running waves move to `cancelled`.
226
+ 3. Branches remain — supervisors do NOT force-push or delete.
227
+ 4. Audit log gains a `cancel` entry with the reason.
228
+
229
+ ---
230
+
231
+ ## Tracking contract
232
+
233
+ - **Auto every time:** `manifest.json` writes via the conductor library; `board.json` regenerated on each write.
234
+ - **Auto only when meaningful:** `[SWARM]` entry in each supervisor's repo `history.md` after wave completion; `[NOTE]` in the originating session log on wave transitions.
235
+ - **Never:** silent overwrites of supervisor branches. Cancel preserves; resume reconstitutes.
236
+
237
+ ## Errors
238
+
239
+ - Ecosystem root not found → suggest `--ecosystem <path>` or running from inside an ecosystem.
240
+ - Repo arg not a member → list valid members and abort.
241
+ - Initiative does not exist → suggest `momentum ecosystem initiative create <slug>` and abort.
242
+ - `claude --bg` not on PATH → degrade to dry-run + manual spawn instructions.
@@ -0,0 +1,3 @@
1
+ # Project Rules: <Project Name>
2
+
3
+ > Claude Code configuration for this project.
@@ -0,0 +1 @@
1
+ { "TASK_TOOL": "the built-in **TodoWrite** tool", "TASK_TOOL_NAME": "TodoWrite" }
@@ -0,0 +1,36 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "Write|Edit|MultiEdit",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "bash scripts/brainstorm-gate.sh"
10
+ }
11
+ ]
12
+ }
13
+ ],
14
+ "PostToolUse": [
15
+ {
16
+ "matcher": "Edit|Write",
17
+ "hooks": [
18
+ {
19
+ "type": "command",
20
+ "command": "bash scripts/check-history-reminder.sh"
21
+ }
22
+ ]
23
+ }
24
+ ],
25
+ "SessionStart": [
26
+ {
27
+ "hooks": [
28
+ {
29
+ "type": "command",
30
+ "command": "bash scripts/sessionstart-handoff.sh"
31
+ }
32
+ ]
33
+ }
34
+ ]
35
+ }
36
+ }
@@ -0,0 +1,225 @@
1
+ 'use strict';
2
+
3
+ // Codex adapter for momentum.
4
+ //
5
+ // Codex uses AGENTS.md as its primary repository instruction surface. Generic
6
+ // momentum command recipes install into .codex/commands/ via the standard
7
+ // overlay, then are transformed in `runInstall` into native Codex skills at
8
+ // .agents/skills/<name>/SKILL.md so each recipe becomes a first-class
9
+ // auto-discoverable skill (per https://developers.openai.com/codex/skills).
10
+ // The .codex/commands/ directory is removed post-transform — skills are the
11
+ // canonical surface, not lookup fragments.
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const { spawnSync } = require('child_process');
16
+
17
+ module.exports = {
18
+ displayName: 'Codex',
19
+
20
+ destinations: {
21
+ commands: ['.codex', 'commands'],
22
+ 'agent-rules': ['.agent', 'rules'],
23
+ scripts: ['scripts'],
24
+ engines: ['.agent', 'engines'],
25
+ // Phase 16 Rework: native Codex surfaces.
26
+ // Skills live at .agents/skills/ (shared with Antigravity; NOT .codex/skills/)
27
+ // Subagents live at .codex/agents/ (TOML files)
28
+ // workflows declared but unused on Codex (no native workflow surface)
29
+ workflows: ['.codex', 'workflows'],
30
+ skills: ['.agents', 'skills'],
31
+ agents: ['.codex', 'agents'],
32
+ },
33
+
34
+ primaryInstruction: {
35
+ source: ['instructions', 'AGENTS.md'],
36
+ destination: ['AGENTS.md'],
37
+ label: 'AGENTS.md',
38
+ markerAware: true,
39
+ },
40
+
41
+ configFiles: [
42
+ {
43
+ source: ['hooks.json'],
44
+ destination: ['.codex', 'hooks.json'],
45
+ label: '.codex/hooks.json',
46
+ },
47
+ ],
48
+
49
+ capabilities: {
50
+ hooks: true,
51
+ slashCommands: true,
52
+ subagents: true,
53
+ parallelSubagents: false,
54
+ sessionStartHook: true,
55
+ skills: true,
56
+ browser: true,
57
+ computerUse: true,
58
+ },
59
+
60
+ roadmap: {
61
+ subagents:
62
+ 'Codex declares a subagent surface; parallel-fanout not yet validated by momentum smoke tests. ' +
63
+ 'capability-routing treats this as sequential until proven.',
64
+ parallelSubagents:
65
+ 'Promote to true once dispatch parallel mode is exercised against Codex in CI (VAL-001).',
66
+ },
67
+
68
+ runInstall(targetDir, adapterDir, helpers) {
69
+ const { copyFile, fileExists, recordManaged, dryRun } = helpers;
70
+
71
+ console.log('→ Configuring Codex hooks...');
72
+ const hooksDest = path.join(targetDir, '.codex', 'hooks.json');
73
+ if (recordManaged) recordManaged(hooksDest); // managed regardless of write
74
+ if (!fileExists(hooksDest)) {
75
+ copyFile(path.join(adapterDir, 'hooks.json'), hooksDest);
76
+ } else {
77
+ console.log(' ⚠️ .codex/hooks.json already exists.');
78
+ console.log(` Merge hooks manually from: ${path.join(adapterDir, 'hooks.json')}`);
79
+ }
80
+
81
+ console.log('→ Transforming recipes into native Codex skills...');
82
+ if (dryRun) console.log(' ✋ would generate skills at .agents/skills/ from recipes');
83
+ else transformCommandsIntoSkills(targetDir, recordManaged);
84
+ },
85
+
86
+ runUpgrade(targetDir, adapterDir, helpers) {
87
+ const { copyFile, fileExists, recordManaged, dryRun } = helpers;
88
+
89
+ console.log('→ Upgrading Codex hooks...');
90
+ const src = path.join(adapterDir, 'hooks.json');
91
+ const dest = path.join(targetDir, '.codex', 'hooks.json');
92
+ if (recordManaged) recordManaged(dest); // managed even when identical-skip
93
+
94
+ if (fileExists(dest)) {
95
+ const srcContent = fs.readFileSync(src, 'utf8');
96
+ const destContent = fs.readFileSync(dest, 'utf8');
97
+ if (srcContent !== destContent) {
98
+ if (dryRun) {
99
+ console.log(' ✋ would upgrade: .codex/hooks.json');
100
+ } else {
101
+ fs.copyFileSync(dest, dest + '.bak');
102
+ copyFile(src, dest);
103
+ console.log(' ↑ upgraded: .codex/hooks.json (original saved as .bak)');
104
+ }
105
+ }
106
+ } else {
107
+ copyFile(src, dest);
108
+ console.log(` ${dryRun ? '✋ would add: ' : '+ added: '} .codex/hooks.json`);
109
+ }
110
+
111
+ console.log('→ Re-generating Codex skills from recipes...');
112
+ if (dryRun) console.log(' ✋ would re-generate skills at .agents/skills/ from recipes');
113
+ else transformCommandsIntoSkills(targetDir, recordManaged);
114
+ },
115
+
116
+ // Phase 18 G1 — adapter.spawn(directive) for Codex.
117
+ // Shells `codex --cwd <repoPath>` with the supervisor TOML as the
118
+ // subagent declaration. The MCP cwd shim (see AGENTS.md → "## MCP
119
+ // cwd shim — Codex configuration") keeps file ops inside the
120
+ // pinned cwd. See `bin/momentum.js` for the directive contract.
121
+ spawn(directive) {
122
+ if (!directive || directive.platform !== 'codex') {
123
+ return {
124
+ repoId: directive && directive.repoId,
125
+ status: -1,
126
+ detail: `non-codex platform: ${directive && directive.platform}`,
127
+ };
128
+ }
129
+ const codexBin = process.env.CODEX_BIN || 'codex';
130
+ const args = ['--cwd', directive.repoPath, '--agent', 'swarm-supervisor'];
131
+ const prompt = [
132
+ `You are a swarm supervisor. Recipe: ${directive.recipePath}`,
133
+ `Read the recipe and the brief at specs/phases/${directive.phaseSlug}/overview.md.`,
134
+ `Your repo: ${directive.repoId}. Your swarm: ${directive.swarmId} wave ${directive.wave}.`,
135
+ `Begin the boot sequence.`,
136
+ ].join('\n');
137
+ const r = spawnSync(codexBin, args, {
138
+ input: prompt,
139
+ env: Object.assign({}, process.env, directive.env),
140
+ encoding: 'utf8',
141
+ timeout: 5000,
142
+ });
143
+ return {
144
+ repoId: directive.repoId,
145
+ status: r.status == null ? -1 : r.status,
146
+ detail: (r.error && r.error.message) || (r.stderr || '').slice(0, 200),
147
+ };
148
+ },
149
+ };
150
+
151
+ // ─── Recipes → Skills transform (ENH-036) ────────────────────────────────────
152
+ //
153
+ // Per https://developers.openai.com/codex/skills the canonical project-scope
154
+ // skill surface is $REPO_ROOT/.agents/skills/<name>/SKILL.md with YAML
155
+ // frontmatter declaring `name` + `description`. Each momentum recipe becomes
156
+ // one such skill so Codex auto-discovers and dispatches them natively (rather
157
+ // than the AGENTS.md-lookup-then-follow-instructions pattern that shipped in
158
+ // v0.19.0).
159
+ function transformCommandsIntoSkills(targetDir, recordManaged) {
160
+ const commandsDir = path.join(targetDir, '.codex', 'commands');
161
+ const skillsRoot = path.join(targetDir, '.agents', 'skills');
162
+ if (!fs.existsSync(commandsDir)) {
163
+ console.log(' (no .codex/commands/ to transform — skipping)');
164
+ return;
165
+ }
166
+ fs.mkdirSync(skillsRoot, { recursive: true });
167
+
168
+ let count = 0;
169
+ for (const file of fs.readdirSync(commandsDir)) {
170
+ if (!file.endsWith('.md')) continue;
171
+ const name = file.replace(/\.md$/, '');
172
+ const body = fs.readFileSync(path.join(commandsDir, file), 'utf8');
173
+ const description = extractRecipeDescription(body, name);
174
+
175
+ const skillDir = path.join(skillsRoot, name);
176
+ fs.mkdirSync(skillDir, { recursive: true });
177
+ const skillBody = renderSkillMarkdown(name, description, body);
178
+ const skillPath = path.join(skillDir, 'SKILL.md');
179
+ fs.writeFileSync(skillPath, skillBody);
180
+ // Generated skills are momentum-managed — record them so they appear in
181
+ // the lock file and a dropped recipe's skill is orphan-cleaned (Phase 20).
182
+ if (recordManaged) recordManaged(skillPath);
183
+ count++;
184
+ }
185
+
186
+ // Remove the lookup-fragment directory — skills are now the canonical
187
+ // surface. Keep .codex/agents/ + .codex/hooks.json + .codex/swarm/ etc.
188
+ fs.rmSync(commandsDir, { recursive: true, force: true });
189
+ console.log(` + ${count} skill(s) generated at .agents/skills/ from recipes`);
190
+ console.log(' - .codex/commands/ removed (skills replace lookup fragments)');
191
+ }
192
+
193
+ // Extract the first non-heading, non-blank line of the recipe as the skill
194
+ // description. Recipes follow a consistent house-style where line 1 is a
195
+ // one-sentence "what it does" — well suited to Codex's "describe when to
196
+ // trigger" requirement.
197
+ function extractRecipeDescription(body, name) {
198
+ for (const line of body.split('\n')) {
199
+ const trimmed = line.trim();
200
+ if (!trimmed) continue;
201
+ if (trimmed.startsWith('#')) continue;
202
+ // Strip wrapping markdown emphasis if present.
203
+ return trimmed
204
+ .replace(/^[*_]+|[*_]+$/g, '')
205
+ .replace(/\s+/g, ' ')
206
+ .trim();
207
+ }
208
+ return `Run the momentum ${name} recipe.`;
209
+ }
210
+
211
+ function renderSkillMarkdown(name, description, recipeBody) {
212
+ // YAML frontmatter must escape colons / newlines. The description is one
213
+ // line by construction (extractRecipeDescription guarantees this), so a
214
+ // simple double-quoted string is safe — but we still escape embedded
215
+ // double-quotes and backslashes.
216
+ const safeDescription = description.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
217
+ return [
218
+ '---',
219
+ `name: ${name}`,
220
+ `description: "${safeDescription} Activates when the user invokes /${name} or asks momentum to run the ${name} recipe."`,
221
+ '---',
222
+ '',
223
+ recipeBody.endsWith('\n') ? recipeBody : recipeBody + '\n',
224
+ ].join('\n');
225
+ }
@@ -0,0 +1,57 @@
1
+ # momentum reviewer — Architecture lens (Codex)
2
+ #
3
+ # Installed by momentum init/upgrade --agent codex into .codex/agents/.
4
+
5
+ name = "momentum-reviewer-architecture"
6
+
7
+ description = """
8
+ Review a code diff for architectural fit, rule compliance, and pattern
9
+ consistency. Returns Critical/Important/Minor findings ONLY — does not
10
+ modify code, does not refactor. Dispatched by the review-code recipe.
11
+ """
12
+
13
+ developer_instructions = """
14
+ You are an architecture-focused code reviewer dispatched by the momentum
15
+ toolkit. You will receive a code diff and the project's full rules
16
+ (AGENTS.md — the complete rulebook).
17
+
18
+ YOUR LENS: architectural fit, rule compliance, pattern consistency.
19
+
20
+ For each change, ask:
21
+ - Does it violate any of the 12 autonomous rules (orient first, update
22
+ tracking, auto-track discoveries, pre-phase bug check, phase boundary
23
+ awareness, git lifecycle, plan before implementing, record history,
24
+ doc sync protocol, architecture stability, evaluator discipline,
25
+ verify before claim)?
26
+ - Does it match the patterns established elsewhere in the codebase?
27
+ Read 2-3 nearby files for convention.
28
+ - Does it create hidden coupling, a leaky abstraction, or an
29
+ adapter/contract violation? (For momentum specifically: every
30
+ capability declaration uniform-boolean; overlay subdirs use the
31
+ destinations contract; adapter-specific code stays in adapters/,
32
+ generic in core/.)
33
+ - Is it documented where rules say it should be (history.md entry, ADR
34
+ for decisional changes, backlog entry for discovered issues)?
35
+ - Does the commit message convention match (feat / fix / docs / etc.)?
36
+
37
+ Output format — return EXACTLY this structure:
38
+
39
+ ```
40
+ ## Architecture review
41
+
42
+ ### Critical
43
+ - [finding] (file:line) — [why it's critical]
44
+
45
+ ### Important
46
+ - [finding] (file:line) — [explanation]
47
+
48
+ ### Minor
49
+ - [finding] (file:line) — [explanation]
50
+ ```
51
+
52
+ If no findings at a severity level, write "(none)". Do NOT speculate
53
+ beyond what the diff shows. Do NOT refactor yourself — flag the
54
+ issue. Do NOT modify any files.
55
+ """
56
+
57
+ sandbox_mode = "read-only"
@@ -0,0 +1,52 @@
1
+ # momentum reviewer — QA lens (Codex)
2
+ #
3
+ # Installed by momentum init/upgrade --agent codex into .codex/agents/.
4
+
5
+ name = "momentum-reviewer-qa"
6
+
7
+ description = """
8
+ Review a code diff for test coverage, edge cases, and regression risk.
9
+ Returns Critical/Important/Minor findings ONLY — does not modify code,
10
+ does not write tests. Dispatched by the review-code recipe on the
11
+ current branch's pending changes.
12
+ """
13
+
14
+ developer_instructions = """
15
+ You are a QA-focused code reviewer dispatched by the momentum toolkit.
16
+ You will receive a code diff and a project-rules excerpt (especially
17
+ Rule 12 — Verify Before Claim).
18
+
19
+ YOUR LENS: test coverage, edge cases, regression risk.
20
+
21
+ For each meaningful behavior change in the diff, ask:
22
+ - Is there a test that exercises it? If yes, does it test the happy
23
+ path AND at least one edge case?
24
+ - What edge cases are uncovered? Consider: empty input, large input,
25
+ concurrent access, error paths, network/IO failures, malformed data,
26
+ Unicode / non-ASCII, very long strings, off-by-one boundaries.
27
+ - Could this change break an existing test or production path? Look
28
+ for callers of any modified function.
29
+ - Does the change add a verification command, or rely on "should work
30
+ now" — Rule 12 territory.
31
+
32
+ Output format — return EXACTLY this structure:
33
+
34
+ ```
35
+ ## QA review
36
+
37
+ ### Critical
38
+ - [finding] (file:line) — [why it's critical]
39
+
40
+ ### Important
41
+ - [finding] (file:line) — [explanation]
42
+
43
+ ### Minor
44
+ - [finding] (file:line) — [explanation]
45
+ ```
46
+
47
+ If no findings at a severity level, write "(none)". Do NOT speculate
48
+ beyond what the diff shows. Do NOT write tests yourself — flag the
49
+ gap. Do NOT modify any files.
50
+ """
51
+
52
+ sandbox_mode = "read-only"
@@ -0,0 +1,57 @@
1
+ # momentum reviewer — Security lens (Codex)
2
+ #
3
+ # Installed by `momentum init/upgrade --agent codex` into .codex/agents/.
4
+ # Discovered automatically by Codex from .codex/agents/*.toml per vendor docs.
5
+ # Spawned by natural language ("review the diff for security" or
6
+ # "run momentum-reviewer-security"), typically as one of three parallel
7
+ # subagents from the /review-code recipe.
8
+
9
+ name = "momentum-reviewer-security"
10
+
11
+ description = """
12
+ Review a code diff through a security lens (OWASP Top 10, STRIDE threat
13
+ categories). Returns Critical/Important/Minor findings ONLY — does not
14
+ modify code, does not propose fixes. Dispatched by the review-code recipe
15
+ on the current branch's pending changes.
16
+ """
17
+
18
+ developer_instructions = """
19
+ You are a security-focused code reviewer dispatched by the momentum
20
+ toolkit. You will receive a code diff and a project-rules excerpt.
21
+
22
+ YOUR LENS: OWASP Top 10 + STRIDE threat categories.
23
+
24
+ Things to look for:
25
+ - Hard-coded secrets, credentials, API keys
26
+ - SQL/NoSQL injection vectors, unparameterized queries
27
+ - XSS / SSRF / CSRF surfaces in any user-controlled input path
28
+ - Authentication / authorization gaps in newly added endpoints
29
+ - Insecure deserialization, prototype pollution
30
+ - Logging of sensitive data (PII, tokens)
31
+ - Race conditions / TOCTOU in security-relevant code paths
32
+ - Cryptographic anti-patterns (weak algorithms, fixed IVs, MD5/SHA1
33
+ for security, broken random sources)
34
+ - Dependency additions of known-vulnerable packages
35
+
36
+ Output format — return EXACTLY this structure:
37
+
38
+ ```
39
+ ## Security review
40
+
41
+ ### Critical
42
+ - [finding] (file:line) — [why it's critical]
43
+
44
+ ### Important
45
+ - [finding] (file:line) — [explanation]
46
+
47
+ ### Minor
48
+ - [finding] (file:line) — [explanation]
49
+ ```
50
+
51
+ If no findings at a severity level, write "(none)". Do NOT speculate
52
+ beyond what the diff shows. Do NOT propose code fixes — flag only.
53
+ Do NOT modify any files. Do NOT run any code-modifying commands.
54
+ """
55
+
56
+ # Read-only sandbox — reviewers cannot modify the codebase.
57
+ sandbox_mode = "read-only"