@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
package/bin/waves.js ADDED
@@ -0,0 +1,147 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * `momentum waves` — render the wave plan at any scale (Phase 21c,
5
+ * FEAT-028 — ADR-0003).
6
+ *
7
+ * momentum waves phase scale: non-complete phases from
8
+ * overview.md frontmatter (`deps:`, OKF
9
+ * bundle) — legacy index.json fallback
10
+ * momentum waves --tasks [ref] task scale: group waves for a tasks.md —
11
+ * ref = phase id or a tasks.md path;
12
+ * default = the phase bound to the current
13
+ * branch (Rule 15), fallback status.md
14
+ * momentum waves --json machine shape (unstable, internal)
15
+ *
16
+ * Waves feed lanes: wave-1 nodes print suggested `momentum lanes open`
17
+ * commands. Cross-repo (ecosystem) waves stay with `momentum swarm`,
18
+ * which consumes the same engine.
19
+ */
20
+
21
+ const fs = require('fs');
22
+ const path = require('path');
23
+ const { spawnSync } = require('child_process');
24
+
25
+ const MOMENTUM_ROOT = path.resolve(__dirname, '..');
26
+ const { computeWaveLayers } = require(path.join(MOMENTUM_ROOT, 'core', 'waves', 'lib', 'waves'));
27
+ const graphs = require(path.join(MOMENTUM_ROOT, 'core', 'waves', 'lib', 'plan-graph'));
28
+
29
+ function git(cwd, ...args) {
30
+ const res = spawnSync('git', args, { cwd, encoding: 'utf8' });
31
+ return res.status === 0 ? res.stdout.trim() : null;
32
+ }
33
+
34
+ /** Resolve the tasks.md to plan from a ref (phase id, path, or branch binding). */
35
+ function resolveTasksFile(cwd, ref) {
36
+ const root = git(cwd, 'rev-parse', '--show-toplevel');
37
+ if (!root) return { error: 'not inside a git repository' };
38
+ if (ref) {
39
+ const asPath = path.resolve(cwd, ref);
40
+ if (fs.existsSync(asPath) && asPath.endsWith('.md')) return { file: asPath, label: ref };
41
+ const asPhase = path.join(root, 'specs', 'phases', ref, 'tasks.md');
42
+ if (fs.existsSync(asPhase)) return { file: asPhase, label: ref };
43
+ return { error: `cannot resolve '${ref}' to a phase or tasks.md path` };
44
+ }
45
+ // Rule 15 binding: phase-* branch with a matching phase dir.
46
+ const branch = git(cwd, 'symbolic-ref', '--short', 'HEAD');
47
+ if (branch && /^phase-/.test(branch)) {
48
+ const f = path.join(root, 'specs', 'phases', branch, 'tasks.md');
49
+ if (fs.existsSync(f)) return { file: f, label: branch };
50
+ }
51
+ // Fallback: first status.md Active Phase row with an existing dir.
52
+ try {
53
+ const status = fs.readFileSync(path.join(root, 'specs', 'status.md'), 'utf8');
54
+ const section = status.split(/^## Active Phase/m)[1] || '';
55
+ const tokens = [...section.split(/^## /m)[0].matchAll(/`(phase-[A-Za-z0-9._-]+)`/g)].map((m) => m[1]);
56
+ for (const t of tokens) {
57
+ const f = path.join(root, 'specs', 'phases', t, 'tasks.md');
58
+ if (fs.existsSync(f)) return { file: f, label: `${t} (status.md fallback)` };
59
+ }
60
+ } catch { /* no status.md */ }
61
+ return { error: 'no tasks.md resolvable — pass a phase id or path: momentum waves --tasks <ref>' };
62
+ }
63
+
64
+ function render(waves, { json, kind, suggest }) {
65
+ if (json) {
66
+ console.log(JSON.stringify({ unstable: true, kind, waves }, null, 2));
67
+ return;
68
+ }
69
+ if (waves.length === 0) {
70
+ console.log(`no pending ${kind} — nothing to schedule`);
71
+ return;
72
+ }
73
+ for (const w of waves) {
74
+ console.log(`wave ${w.index}: ${w.nodes.join(' ')}`);
75
+ }
76
+ if (suggest && waves[0]) {
77
+ console.log('');
78
+ console.log('wave 1 can start now — open a lane per node:');
79
+ for (const n of waves[0].nodes) {
80
+ console.log(` momentum lanes open ${suggest(n)}`);
81
+ }
82
+ }
83
+ }
84
+
85
+ function runWaves(argv, cwd = process.cwd()) {
86
+ const json = argv.includes('--json');
87
+ const args = argv.filter((a) => a !== '--json');
88
+
89
+ if (args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
90
+ console.log(`momentum waves — wave plan from dependency annotations (one engine, every scale)
91
+
92
+ momentum waves phase scale (overview.md frontmatter "deps"; complete = satisfied)
93
+ momentum waves --tasks [ref] task-group scale ("## Group N — t (deps: G0)" in tasks.md;
94
+ fully-checked groups = satisfied); ref = phase id | path;
95
+ default = the phase bound to your branch (Rule 15)
96
+ --json machine shape (unstable, internal)
97
+
98
+ Waves feed lanes (momentum lanes open …) and land sequentially (momentum
99
+ lanes land). Cross-repo waves: momentum swarm (same engine).`);
100
+ return 0;
101
+ }
102
+
103
+ try {
104
+ if (args[0] === '--tasks') {
105
+ const resolved = resolveTasksFile(cwd, args[1]);
106
+ if (resolved.error) {
107
+ console.error(`✗ ${resolved.error}`);
108
+ return 1;
109
+ }
110
+ const graph = graphs.taskGraph(resolved.file);
111
+ if (!graph || graph.groups.length === 0) {
112
+ console.error(`✗ no "## Group …" headings found in ${resolved.file}`);
113
+ return 1;
114
+ }
115
+ console.log(`task-group waves for ${resolved.label}:`);
116
+ const satisfied = graph.groups.filter((g) => g.satisfied).map((g) => g.id);
117
+ if (satisfied.length) console.log(`(satisfied, dropped: ${satisfied.join(', ')})`);
118
+ const waves = graph.nodes.length
119
+ ? computeWaveLayers(graph.nodes, graph.edges, { label: 'waves --tasks' })
120
+ : [];
121
+ render(waves, { json, kind: 'task groups', suggest: null });
122
+ return 0;
123
+ }
124
+
125
+ const root = git(cwd, 'rev-parse', '--show-toplevel');
126
+ if (!root) {
127
+ console.error('✗ not inside a git repository');
128
+ return 1;
129
+ }
130
+ const graph = graphs.phaseGraph(root);
131
+ if (!graph) {
132
+ console.error('✗ no phase metadata found (specs/phases/*/overview.md frontmatter, or legacy specs/phases/index.json)');
133
+ return 1;
134
+ }
135
+ console.log(`phase waves (non-complete phases; ${graph.source} "deps"):`);
136
+ const waves = graph.nodes.length
137
+ ? computeWaveLayers(graph.nodes, graph.edges, { label: 'waves' })
138
+ : [];
139
+ render(waves, { json, kind: 'phases', suggest: (n) => n });
140
+ return 0;
141
+ } catch (err) {
142
+ console.error(`✗ ${err.message}`);
143
+ return 1;
144
+ }
145
+ }
146
+
147
+ module.exports = { runWaves };
@@ -0,0 +1,112 @@
1
+ # Adapter Capability Matrix
2
+
3
+ > Single source of truth for what each shipped adapter declares it can
4
+ > do. Generated from the `capabilities` block on each adapter's
5
+ > `adapter.js`. Audited automatically by
6
+ > `tests/adapter-capabilities-declared.test.js`.
7
+ >
8
+ > Phase 11 (v0.14.0) unified the declared shape: every capability is
9
+ > now a **uniform boolean**. "Future-planned" or caveated notes live in
10
+ > the adapter's separate `roadmap` block — they no longer pollute the
11
+ > capability values. The orchestration library's
12
+ > `core/orchestration/capability-routing.js` reads this matrix to
13
+ > decide which primitives run in parallel vs sequential per adapter.
14
+
15
+ ## How to read this matrix
16
+
17
+ A capability cell is one of:
18
+ - ✅ — declared `true`
19
+ - ❌ — declared `false`
20
+
21
+ Footnotes (¹, ², …) link to roadmap entries when the declaration has
22
+ forward-looking context (e.g., "planned for a future Codex feature
23
+ drop"). The boolean itself reflects today's truth — never aspirational
24
+ behaviour.
25
+
26
+ If you add a new adapter, fill in **every** column. The audit test
27
+ asserts every adapter declares the full capability surface that
28
+ orchestration code depends on.
29
+
30
+ ## Matrix (as of 2026-07-05, Phase 22 G0 — opencode column added)
31
+
32
+ | Capability | opencode | Claude Code | Codex | Antigravity |
33
+ |---|---|---|---|---|
34
+ | `hooks` | ✅⁵ | ✅ | ✅ | ✅ |
35
+ | `slashCommands` | ✅⁵ | ✅ | ✅ | ❌¹ |
36
+ | `subagents` | ✅⁵ | ✅ | ✅² | ✅ |
37
+ | `parallelSubagents` | ✅⁵ | ✅ | ❌² | ✅ |
38
+ | `sessionStartHook` | ✅⁵ | ✅ | ✅ | ❌³ |
39
+ | `skills` | ✅⁵ | ❌ | ❌⁴ | ❌ |
40
+ | `browser` | ❌ | ❌ | ❌⁴ | ❌ |
41
+ | `computerUse` | ❌ | ❌ | ❌⁴ | ❌ |
42
+ | `artifacts` (adapter-specific) | — | — | — | ✅ |
43
+ | `planningMode` (adapter-specific) | ✅ | — | — | ✅ |
44
+
45
+ ## Phase 17 (v0.20.0) + Phase 17.5 (v0.20.2) + Phase 18 (v0.20.4) — `/swarm` cross-adapter
46
+
47
+ Phase 17 (v0.20.0) delivered the conductor + supervisor architecture,
48
+ files-as-channels coordination, indexing strategies, and intervention
49
+ surface — Claude Code only. Phase 17.5 (v0.20.2) layered five
50
+ portability subcommands (`claim` / `release` / `focus` / `join` /
51
+ `absorb`), lease enforcement at the `manifest.js` write chokepoint, and
52
+ a typed signal protocol. The underlying `core/swarm/` library is
53
+ platform-agnostic.
54
+
55
+ **Phase 18 (v0.20.4)** brings the full 13-subcommand swarm surface to
56
+ Codex and Antigravity via an `adapter.spawn(directive)` contract added
57
+ to every adapter:
58
+
59
+ | Adapter | What ships in Phase 18 |
60
+ |---|---|
61
+ | Codex | `adapter.spawn()` shells `codex --cwd <repoPath> --agent swarm-supervisor`; supervisor TOML at `.codex/agents/swarm-supervisor.toml`; recipe → skill transform produces `.agents/skills/swarm/SKILL.md`; AGENTS.md gains `## Swarm — Lookup Pattern` and `## MCP cwd shim — Codex configuration` sections. |
62
+ | Antigravity | `adapter.spawn()` launches a DETACHED `agy --new-project --dangerously-skip-permissions --print-timeout <bound> -p <boot prompt>` from `repoPath` (real 1.x flags — Phase 22b), logging to `.momentum/swarm-supervisor-<swarm>-w<wave>.log`; workflow at `.agents/workflows/swarm.md` auto-registers as `/swarm`; supervisor skill at `.agents/skills/swarm-supervisor/SKILL.md`; AGENTS.md gains `## Swarm — Lookup Pattern` section. |
63
+
64
+ ### Capability flips — outcome of G4 live VAL evidence
65
+
66
+ Phase 18 G4 live evidence (`specs/phases/phase-18-swarm-parity/evidence/val-001-codex.txt` + `val-002-antigravity.txt`) concluded **neither flip lands**:
67
+
68
+ - **Codex `parallelSubagents`** stays `false`. `codex features list` shows `enable_fanout: under development: false` at codex-cli 0.133.0. Flipping `parallelSubagents` requires `enable_fanout: stable: true` upstream.
69
+ - **Antigravity `sessionStartHook`** stays `false` — but for a NEW reason (Phase 22b, VAL-002 resolved): a literal SessionStart event does not exist on Antigravity's five-event hook surface. The equivalent capability ships via the `momentum-session-context` PreInvocation hook (`ephemeralMessage` injection at `invocationNum 0`, ADR-0006); the flag flips once the injection round-trip is verified live (re-probe blocked by the intermittent agy 1.0.16 hook-runner hang, ENH-054). Evidence: `specs/phases/phase-22b-antigravity-2-adoption/evidence/fact-sheet.md` §5.
70
+
71
+ The swarm subcommand row in the parity matrix flips to `shipped¹⁴` for
72
+ both Codex + Antigravity — the surface is complete; only the two
73
+ capability flags remain `false` pending the listed upstream / operator
74
+ conditions.
75
+
76
+ ### Roadmap footnotes
77
+
78
+ 1. **Antigravity `slashCommands: false`** — chat-driven UI. Orchestration primitives reach Antigravity users via natural-language inference (the main agent picks the primitive from the user's prose) plus the `momentum` CLI floor that works on every adapter.
79
+ 2. **Codex `subagents` / `parallelSubagents`** — Codex declares a subagent surface, but parallel fan-out has not yet been validated by momentum smoke tests. The capability-routing helper treats Codex as sequential for `dispatch` until a future release proves parallel viability in CI. Subagent existence is `true`; parallel fan-out is `false`. Promote `parallelSubagents` to `true` once Codex parallel dispatch is exercised end-to-end.
80
+ 3. **Antigravity `sessionStartHook: false`** — a literal SessionStart event does not exist on Antigravity (five-event surface, Phase 22b/ADR-0006). The banner ships via the `momentum-session-context` PreInvocation hook (`ephemeralMessage` at `invocationNum 0`); AGENTS.md text keeps the fallback hint. Flag flips once the injection round-trip is verified live (ENH-054). `/continue` and `momentum continue` work regardless.
81
+ 4. **Codex `skills` / `browser` / `computerUse`** — declared `false` today; planned for a future Codex feature drop. When Codex ships those features, flip the boolean and remove the corresponding `roadmap` entry in the same PR.
82
+
83
+ 5. **opencode (Phase 22, LIVE-validated 2026-07-05)** — every boolean set from real-runtime evidence against opencode 1.17.13 with real model calls (free tier, zero credentials) — see `specs/phases/phase-22-opencode-adapter/evidence/val-opencode-live.txt`. `parallelSubagents: true` earned via overlapping task-tool timestamps; `skills: true` earned via a live skill-tool load of momentum-orient (**a momentum first — no other adapter has live-validated skills**); `sessionStartHook: true` — earned post-phase (fix/opencode-sessionstart-banner): the banner fired live in a served session once rewired onto the generic `event` bus (a named "session.created" hook key never fires on 1.17.x). Run-mode is deliberately excluded — the event handler hangs `opencode run` (upstream issue candidate) and a session-start banner is meaningless non-interactively.
84
+
85
+ ## ENH-023 and ENH-024 closed (Phase 11 G0)
86
+
87
+ These two open backlog items tracked the type inconsistencies in the
88
+ pre-Phase-11 matrix:
89
+
90
+ - **ENH-023** — `subagents` was bool on Claude Code and Antigravity but
91
+ an explanatory string on Codex.
92
+ - **ENH-024** — `skills` / `browser` / `computerUse` were `false` on
93
+ Claude Code but `'future'` sentinel strings on Codex; Antigravity did
94
+ not declare them at all.
95
+
96
+ Phase 11 Group 0 unified all three adapters around uniform booleans and
97
+ moved every caveat into the `roadmap` field. `tests/
98
+ adapter-capabilities-declared.test.js` now enforces the uniform shape.
99
+
100
+ ## Read this if you are…
101
+
102
+ - **…building an orchestration primitive** (Phase 11 and onward): read
103
+ the boolean cell; if `false`, degrade per the capability-routing
104
+ helper. Surface degraded-mode notes from the adapter's `roadmap`
105
+ block in the user-visible banner so they understand why.
106
+ - **…adding a new adapter**: declare *every* row above on your
107
+ adapter's `capabilities` block as a boolean. Use the `roadmap` block
108
+ for forward-looking notes — never embed them in the capability
109
+ value. The audit test will fail otherwise.
110
+ - **…closing a roadmap entry**: flip the corresponding boolean to
111
+ `true` (or remove if no longer relevant), delete the `roadmap`
112
+ entry, and update this matrix doc in the same PR.
@@ -0,0 +1,170 @@
1
+ # Adapter Parity Matrix (Phase 16 Rework)
2
+
3
+ > Feature × adapter shipping status. Complement to
4
+ > `core/adapter-capabilities.md` (which tracks PRIMITIVES like
5
+ > `hooks: true`).
6
+ >
7
+ > This matrix answers: "is feature X actually shipped on adapter Y via
8
+ > which native idiom, and if degraded, how?" Audited by
9
+ > `tests/adapter-parity-matrix.test.js` — every cell must declare a
10
+ > status. Silent gaps were the failure mode this audit prevents.
11
+ >
12
+ > Introduced in Phase 16 Rework (2026-06-11) — replaces the per-adapter
13
+ > capability-only view with a per-feature native-idiom view.
14
+
15
+ ## Status legend
16
+
17
+ | Status | Meaning |
18
+ |---|---|
19
+ | `shipped` | Feature wired via the platform-native idiom and verified |
20
+ | `shipped-degraded` | Wired but runs in documented degraded mode. Cell's footnote explains |
21
+ | `not-applicable` | Platform's runtime model doesn't surface this feature, by design |
22
+
23
+ If you add a feature OR a new adapter, every (feature, adapter) cell
24
+ must declare a status. The audit test fails on blank cells.
25
+
26
+ ## Conceptual categories
27
+
28
+ Three categories drive the matrix (introduced Phase 16 Rework — see
29
+ overview.md):
30
+
31
+ | Category | What it is | Mental model |
32
+ |---|---|---|
33
+ | **Recipe** | Step-by-step instructions agent FOLLOWS | "Follow this procedure" |
34
+ | **Persona / Skill** | Identity / capability agent LOADS to BECOME | "BE a security reviewer" |
35
+ | **Parallel worker / Subagent** | Spawned sibling that works in parallel | "Go do this concurrently" |
36
+
37
+ ## Matrix
38
+
39
+ ### Recipes (phase + orchestration commands)
40
+
41
+ | Recipe | opencode | Claude Code | Codex | Antigravity |
42
+ |---|---|---|---|---|
43
+ | `/brainstorm-idea` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
44
+ | `/brainstorm-phase` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
45
+ | `/start-project` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
46
+ | `/start-phase` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
47
+ | `/complete-phase` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
48
+ | `/sync-docs` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
49
+ | `/track` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
50
+ | `/review` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
51
+ | `/log` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
52
+ | `/migrate` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
53
+ | `/validate` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
54
+ | `/ecosystem` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
55
+ | `/initiative` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
56
+ | `/session` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
57
+ | `/systematic-debug` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
58
+ | `/scout` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
59
+ | `/dispatch` | shipped¹⁷ | shipped¹ | shipped-degraded⁴ | shipped³ |
60
+ | `/handoff` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
61
+ | `/continue` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
62
+ | `/review-code` | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
63
+ | `/swarm` (Phase 17 + 17.5) | shipped¹⁷ | shipped¹ | shipped¹⁴ | shipped¹⁴ |
64
+ | `/hotfix` (Phase 19) | shipped¹⁷ | shipped¹ | shipped² | shipped³ |
65
+
66
+ ### Personas (skills)
67
+
68
+ | Skill | opencode | Claude Code | Codex | Antigravity |
69
+ |---|---|---|---|---|
70
+ | `momentum-orient` | shipped¹⁷ | not-applicable⁵ | shipped⁶ | shipped⁷ |
71
+ | `momentum-reviewer-security` | shipped-as-subagent¹⁸ | not-applicable⁵ | shipped-as-subagent⁸ | shipped⁷ |
72
+ | `momentum-reviewer-qa` | shipped-as-subagent¹⁸ | not-applicable⁵ | shipped-as-subagent⁸ | shipped⁷ |
73
+ | `momentum-reviewer-architecture` | shipped-as-subagent¹⁸ | not-applicable⁵ | shipped-as-subagent⁸ | shipped⁷ |
74
+
75
+ ### Hooks
76
+
77
+ | Hook | opencode | Claude Code | Codex | Antigravity |
78
+ |---|---|---|---|---|
79
+ | `PreToolUse` (brainstorm-gate) | shipped¹⁹ | shipped⁹ | shipped¹⁰ | shipped¹¹ |
80
+ | `PostToolUse` (history reminder) | shipped¹⁹ | shipped⁹ | shipped¹⁰ | shipped¹¹ |
81
+ | `SessionStart` (handoff banner) | shipped¹⁹ | shipped⁹ | shipped¹⁰ | shipped-as-preinvocation¹¹ |
82
+
83
+ ### Git-lifecycle hooks (Phase 19 — agent-agnostic)
84
+
85
+ | Hook | opencode | Claude Code | Codex | Antigravity |
86
+ |---|---|---|---|---|
87
+ | `commit-msg` (Conventional Commits) | shipped¹⁵ | shipped¹⁵ | shipped¹⁵ | shipped¹⁵ |
88
+ | `pre-push` (merge gate + verify-evidence) | shipped¹⁵ | shipped¹⁵ | shipped¹⁵ | shipped¹⁵ |
89
+
90
+ ### Overlay surfaces
91
+
92
+ | Surface | opencode | Claude Code | Codex | Antigravity |
93
+ |---|---|---|---|---|
94
+ | Primary instruction file (CLAUDE.md / AGENTS.md) | shipped | shipped | shipped | shipped |
95
+ | `commands` overlay | shipped¹⁷ | shipped | shipped | shipped-as-workflows¹² |
96
+ | `agent-rules` overlay | not-applicable¹⁶ | not-applicable¹⁶ | not-applicable¹⁶ | not-applicable¹⁶ |
97
+ | `scripts` overlay (hooks) | shipped | shipped | shipped | shipped |
98
+ | `engines` overlay | shipped | shipped | shipped | shipped |
99
+ | `workflows` overlay (Phase 16) | not-applicable⁵ | not-applicable⁵ | not-applicable⁵ | shipped¹³ |
100
+ | `skills` overlay (Phase 16) | shipped¹⁷ | not-applicable⁵ | shipped⁶ | shipped⁷ |
101
+ | `agents` overlay (Phase 16) | shipped¹⁸ | not-applicable⁵ | shipped⁸ | not-applicable⁵ |
102
+
103
+ ### Ecosystem features
104
+
105
+ | Feature | opencode | Claude Code | Codex | Antigravity |
106
+ |---|---|---|---|---|
107
+ | `momentum init/upgrade` install | shipped | shipped | shipped | shipped |
108
+ | Ecosystem manifest awareness (`ecosystem.json`) | shipped | shipped | shipped | shipped |
109
+ | SessionStart ecosystem banner | shipped¹⁹ | shipped⁹ | shipped¹⁰ | shipped-as-preinvocation¹¹ |
110
+ | Auto session log (PostToolUse) | shipped¹⁹ | shipped⁹ | shipped¹⁰ | shipped¹¹ |
111
+ | Managed `CLAUDE.md` / `AGENTS.md` on `ecosystem init` | shipped | shipped | shipped | shipped |
112
+
113
+ ## Footnotes
114
+
115
+ 1. **Claude Code recipes** — installed as Markdown files at `.claude/commands/<name>.md`. User invokes `/<name>` and Claude Code loads the recipe content as the prompt. Native-idiom.
116
+
117
+ 2. **Codex recipes** — currently installed as Markdown files at `.codex/commands/<name>.md` with a lookup table in `AGENTS.md` ("Recipes Lookup Pattern"). User invokes by name in natural language ("run brainstorm-phase" or "/brainstorm-phase") and the agent finds the matching file. ENH-036 (in-progress) converts each recipe into a native Codex skill at `.agents/skills/<name>/SKILL.md` so they become first-class auto-discovered skills instead of instruction-following text. Custom prompts at `~/.codex/prompts/` are user-scoped only and do not satisfy the repo-shared requirement.
118
+
119
+ 3. **Antigravity recipes** — installed as workflow files at `.agent/workflows/<name>.md` (singular `.agent/` per official docs; gated by Group 4 live smoke — Google's own materials disagree). User types `/<name>` and `agy` auto-registers the workflow as a slash command. YAML frontmatter `--- description: ... ---` optional but recommended for auto-detection.
120
+
121
+ 4. **Codex `/dispatch`** — recipe text instructs natural-language parallel fan-out across multiple subagents (`agents.max_threads = 6` default). Marked `shipped-degraded` until VAL-001 live evidence confirms real-runtime parallel fan-out vs sequential degradation. Capability flip in Group 5.1.
122
+
123
+ 5. **`not-applicable` cells** — the platform's runtime model doesn't surface this overlay or feature. Examples: Claude Code has no per-project skill/agent/workflow file-discovery surface today; Antigravity uses skills (not separate agents/) for personas; Codex uses subagents (not workflows) for parallel work.
124
+
125
+ 6. **Codex skills + momentum-orient** — Codex skills live at `.agents/skills/<name>/SKILL.md` (shared convention with Antigravity; NOT `.codex/skills/`). Momentum installs `momentum-orient` here (Rule-1 orient discipline persona). Marked `shipped` based on vendor doc compliance; live discovery confirmed by VAL-001 in Group 4.
126
+
127
+ 7. **Antigravity skills + reviewers + orient** — installed at `.agents/skills/<name>/SKILL.md` as directories. Each contains SKILL.md with YAML frontmatter (`name`, `description`) + persona body. Loaded by `agy` when the matching skill name is invoked or auto-detected.
128
+
129
+ 8. **Codex reviewer subagents** — installed at `.codex/agents/<name>.toml` (TOML schema with `name`, `description`, `developer_instructions`, `sandbox_mode = "read-only"`). Spawned by natural-language request in the `/review-code` recipe. Codex auto-discovers TOML files in `.codex/agents/` per vendor docs.
130
+
131
+ 9. **Claude Code hooks** — wired via `.claude/settings.json` with matchers `Write|Edit|MultiEdit` for PreToolUse/PostToolUse and no matcher for SessionStart. Hook scripts in `scripts/`. Default-on for users with Claude Code installed.
132
+
133
+ 10. **Codex hooks** — wired via `.codex/hooks.json` with matchers `apply_patch|Bash` for PreToolUse/PostToolUse and no matcher for SessionStart. Per Codex docs (https://developers.openai.com/codex/hooks) the canonical `tool_name` for shell commands is `Bash` — earlier `shell` matcher was a bug (BUG-007, fixed 2026-06-13). Hooks are **enabled by default** in current Codex CLI (`hooks` is `stable: true` in `codex features list`); the first run prompts users to trust each hook via `/hooks`. The legacy `[features] hooks = true` opt-in remains as a fallback.
134
+
135
+ 11. **Antigravity hooks (Phase 22b, verified live)** — vendor named-group `.agents/hooks.json` over the real five events; every hook delegates through `scripts/antigravity-hook-adapter.sh` (ADR-0006), which translates camelCase payloads and emits decision JSON. PreToolUse/PostToolUse fire-verified against agy 1.0.16 (captured payloads under `specs/phases/phase-22b-antigravity-2-adoption/evidence/hook-captures/`). SessionStart does not exist — the handoff/ecosystem banner ships as a PreInvocation `ephemeralMessage` injection at `invocationNum 0` (hence `shipped-as-preinvocation`); AGENTS.md text keeps the fallback hint.
136
+
137
+ 12. **Antigravity `commands` overlay as workflows** — the cross-adapter `core/commands/*.md` content ships to `.agent/workflows/` on Antigravity (recipes become workflows). The destination is shared with the `workflows` overlay key; conflict detection prevents duplicates.
138
+
139
+ 13. **Antigravity `workflows` overlay (Phase 22b, path locked)** — adapter-specific workflows ship to `.agents/workflows/` (canonical root, ADR-0006). Live probe verified slash registration including planted path-matrix markers; agy accepts four root spellings and `.agents/` is the vendor-canonical one. Evidence: `specs/phases/phase-22b-antigravity-2-adoption/evidence/fact-sheet.md` §1/§3.
140
+
141
+ 14. **`/swarm` (Phase 17 v0.20.0 + Phase 17.5 v0.20.2 + Phase 18 v0.20.4)** — Phase 18 v0.20.4 brings full Codex + Antigravity parity to the swarm primitive. Implementation: a platform-agnostic `adapter.spawn(directive)` contract added in Phase 18 G0; Codex dispatch + supervisor TOML + MCP cwd shim documented in G1; Antigravity workflow + supervisor skill + AGENTS.md section in G2; multi-adapter synthetic e2e + Codex/Antigravity install fingerprints in G3. **Capability flips deferred** based on G4 live evidence: Codex `parallelSubagents` stays `false` (gated on `codex features list` showing `enable_fanout: stable: true` — currently `under development`); Antigravity `sessionStartHook` stays `false` (Phase 22b: the event does not exist — see footnote 11; VAL-002 RESOLVED with vendor-runtime evidence). Phase 22b also rewrote the Antigravity spawn onto the real CLI surface: detached `agy --new-project --dangerously-skip-permissions --print-timeout <bound> -p <boot prompt>` from `repoPath` with a per-repo supervisor log (live smoke: BOOT-OK — `specs/phases/phase-22b-antigravity-2-adoption/evidence/spawn-smoke.md`). Codex VAL-001 evidence unchanged at `specs/phases/phase-18-swarm-parity/evidence/val-001-codex.txt`.
142
+
143
+ 15. **Git-lifecycle hooks (Phase 19, FEAT-018/019)** — vendor-neutral, *agent-agnostic* git hooks installed identically for all three adapters: `bin/momentum.js::installGitHooks()` copies `core/git-hooks/*` to the target's `.githooks/` and runs `git config core.hooksPath .githooks` (warn-not-clobber if husky / a custom hooks path exists). `commit-msg` validates Conventional Commits; `pre-push` blocks direct pushes to protected branches without the single-use `.momentum/merge-approved` sentinel and blocks release-tag pushes lacking a non-empty `## Verification Evidence` (Rule 12). Escape hatch: `MOMENTUM_SKIP_HOOKS=1`. These are git hooks, not agent tool-event hooks — the mechanism is identical regardless of agent; the per-column cells exist only for matrix uniformity. Forge-neutral by design (no GitHub/GitLab API); see `core/lifecycle-contract.md`.
144
+
145
+ 16. **`agent-rules` overlay retired (Phase 23 / ADR-0004)** — the condensed `.agent/rules/project.md` file is no longer shipped by any adapter: no agent auto-loaded it, and the full detailed rules (Red Flags + anti-rationalization + Rule 13) now ride each adapter's auto-loaded primary instruction file, generated from the single canonical source at `core/instructions/rules-body.md`. `momentum upgrade` migrates existing installs (pristine → removed; customized → kept + deprecation warning). The `destinations['agent-rules']` contract key stays reserved for future per-adapter rule overlays.
146
+
147
+ 17. **opencode recipes + skills (Phase 22, LIVE-validated)** — recipes install at `.opencode/commands/<name>.md` where each file registers natively as `/<name>` ([opencode commands docs](https://opencode.ai/docs/commands/)); `runInstall` prepends `description` frontmatter for the command picker. Live evidence (G5): `opencode run "/validate"` executed the recipe end-to-end. Momentum skills install at `.opencode/skills/<name>/SKILL.md`; live evidence: the skill tool loaded `momentum-orient` in a real session, and a same-named duplicate on the `.agents/skills/` path (Codex/Antigravity convention) coexisted without error — the `skills` capability boolean is `true`, a momentum first. Full transcript: `specs/phases/phase-22-opencode-adapter/evidence/val-opencode-live.txt`.
148
+
149
+ 18. **opencode agents (Phase 22)** — reviewers + swarm supervisor at `.opencode/agents/<name>.md` (markdown agents, [opencode agents docs](https://opencode.ai/docs/agents/)). The three reviewers declare `mode: subagent` + `permission: edit: deny` (+ read-only bash allowlist) — true sandbox-level read-only, not just prompt-level. Spawn contract: `opencode run --dir <repoPath> --agent swarm-supervisor` (`--dir` pins cwd natively; no MCP shim needed, unlike Codex footnote 14).
150
+
151
+ 19. **opencode momentum plugin (Phase 22 + banner fix, LIVE-validated)** — one self-contained JS plugin at `.opencode/plugins/momentum.js` ([opencode plugins docs](https://opencode.ai/docs/plugins/)) wires the three enforcement hooks; reads the same `.momentum/` sentinels as the other adapters' shell hooks. Live evidence (G5 `val-opencode-live.txt` + `specs/adhoc/fix-opencode-sessionstart-banner/record.md`): the gate blocked a real specs/ edit during `brainstorm-active`; the history reminder stamped after a real write (callID correlation — `tool.execute.after` carries no args); the handoff banner fired in a live served session after being rewired onto the generic `event` bus (a named "session.created" hook key never fires on 1.17.x). Run-mode exclusion by design: the event handler's presence hangs `opencode run` (1.17.13, upstream issue candidate) and a session-start banner is meaningless non-interactively. Remaining degraded cells: ecosystem SessionStart context banner + auto session log not yet wired through the plugin (ENH-058; use `/session` or the `momentum` CLI).
152
+
153
+ ## Read this if you are…
154
+
155
+ - **…asking "is feature X on adapter Y today?"** — find the row, read the cell. Footnote explains how it's shipped (or why not).
156
+ - **…adding a new feature** — add a row; declare every cell. The audit test fails otherwise.
157
+ - **…adding a new adapter** — add a column; declare every cell.
158
+ - **…upgrading a degraded cell to `shipped`** — confirm via live test, flip the cell, drop the footnote in the same PR. Also update `core/adapter-capabilities.md` if the underlying capability boolean changed.
159
+
160
+ ## How the audit test parses this matrix
161
+
162
+ `tests/adapter-parity-matrix.test.js` reads this file and asserts:
163
+
164
+ 1. Every row's cell count matches the column header count.
165
+ 2. Every cell declares a known status: `shipped` / `shipped-degraded` / `not-applicable` / `shipped-as-<other-category>` / `shipped-gated`, optionally with a parenthetical detail and a footnote marker.
166
+ 3. Cells with `shipped-degraded`, `not-applicable`, `shipped-gated`, or `shipped-as-<other>` reference a footnote.
167
+
168
+ Rows in non-table prose are ignored. Tables under any `###` heading
169
+ in this file are audited if their header includes at least one adapter
170
+ display name.
@@ -0,0 +1,98 @@
1
+ Explore any idea through structured dialogue before committing to anything.
2
+
3
+ Use this to think through a concept, technical direction, product decision, or architecture question. **Nothing gets written to disk.** The output is a clear, structured summary you can act on.
4
+
5
+ When you're ready to turn the result into a project, run `/start-project`. To turn a decision into an ADR, run `/log` with `--decision`.
6
+
7
+ ## When to use
8
+
9
+ - You have a vague idea and want to think it through
10
+ - You're weighing technical options and need to reason carefully
11
+ - You want to explore a product direction before committing to building it
12
+ - You're considering a significant architecture or process change
13
+
14
+ ---
15
+
16
+ ## Steps
17
+
18
+ 0. **Enter the brainstorm gate**:
19
+ ```bash
20
+ mkdir -p .momentum && touch .momentum/brainstorm-active
21
+ ```
22
+ While this sentinel exists, the PreToolUse hook (`core/scripts/brainstorm-gate.sh`, wired by Claude Code + Codex + Antigravity) blocks any write-class tool call to `specs/`. This command should not write to disk at all — the sentinel guards against accidental scratch-file leakage (e.g., a stray `specs/decisions/draft.md`).
23
+
24
+ 1. Ask one question at a time to understand the idea:
25
+ - What is the core problem or opportunity?
26
+ - Who is this for? (user, system, team)
27
+ - What are the 2–3 options or directions worth exploring?
28
+ - What constraints matter most? (time, cost, complexity, reversibility)
29
+ - What does success look like?
30
+
31
+ 2. After understanding the idea, reflect back a structured summary **in the chat** (no file):
32
+
33
+ ```
34
+ ## Idea Summary
35
+
36
+ **Problem**: ...
37
+ **Options explored**: ...
38
+ **Key constraints**: ...
39
+ **Recommendation**: ...
40
+ **Open questions**: ...
41
+ ```
42
+
43
+ 3. Ask: "Does this capture it? Anything to refine?"
44
+
45
+ 4. Iterate until the idea is clear.
46
+
47
+ 5. **Exit the brainstorm gate** before any follow-up command:
48
+ ```bash
49
+ rm .momentum/brainstorm-active
50
+ ```
51
+
52
+ 6. Close with one of:
53
+ - "Ready to build this? Run `/start-project` to scaffold it as a project."
54
+ - "Want to explore further before committing? Ask away."
55
+ - "This is a decision, not a project — want to log it as an ADR with `/log --decision`?"
56
+
57
+ ---
58
+
59
+ ## Brainstorm Gate Contract
60
+
61
+ This command runs in two phases: **brainstorm** (conversational, no disk writes) and **commit** (writes files to disk on explicit approval).
62
+
63
+ ### Sentinel-driven enforcement
64
+
65
+ A file `.momentum/brainstorm-active` exists for the lifetime of the brainstorm phase. While it exists, the `brainstorm-gate.sh` PreToolUse hook (shared across Claude Code, Codex, and Antigravity) blocks any write-class tool call whose target lives under `specs/`. The hook is the safety net; the discipline below is the primary contract.
66
+
67
+ For `/brainstorm-idea` specifically, there is no "commit phase" — this command never writes phase or spec files. The gate exists to prevent accidental scratch files from appearing under `specs/` during open-ended exploration. The sentinel is removed when the user picks a direction (or exits the conversation) so the follow-up command (`/start-project`, `/log`, etc.) starts clean.
68
+
69
+ ### Sequence
70
+
71
+ 1. **Enter brainstorm** — `mkdir -p .momentum && touch .momentum/brainstorm-active`
72
+ 2. **Draft in conversation only** — the idea summary lives in chat, not a file. NEVER call `Write`/`Edit`/`MultiEdit` on `specs/` paths during this phase.
73
+ 3. **User picks a direction** — the next step is a different command, not a file write.
74
+ 4. **Exit brainstorm before that command** — `rm .momentum/brainstorm-active`.
75
+
76
+ ### Red flags — STOP and stay in conversation
77
+
78
+ | If you find yourself thinking… | …STOP and stay in conversation |
79
+ |---|---|
80
+ | "I'll save the idea summary to a file so we don't lose it" | The user is the one who decides if it's worth saving. Keep it in chat; let them pick the destination (`/log --decision`, `/start-project`, etc.). |
81
+ | "I'll create `specs/ideas/foo.md` as a scratch file" | This command has no scratch files. The hook will block. |
82
+ | "The brainstorm session is going long; I'll dump notes to disk for safekeeping" | Long conversations are normal; chat is durable. |
83
+
84
+ ### Anti-rationalization counters
85
+
86
+ - "It's just a note, not a real spec" — the hook can't tell a note from a spec; the discipline is consistent across all three brainstorm commands.
87
+ - "The user might forget the conclusion" — summarize in chat; they can copy if they want.
88
+ - "Other commands need this content" — they'll get it from the conversation context.
89
+
90
+ ---
91
+
92
+ ## Key Principles
93
+
94
+ - One question at a time — don't overwhelm
95
+ - No files written during brainstorming — this is thinking, not building
96
+ - The summary is the deliverable — concise, clear, actionable
97
+ - Stay generic — works for software, process, product, or architecture ideas
98
+ - **Brainstorm Gate**: see the contract above. No writes during the session.