projecta-rrr 1.18.8 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/bin/install.js +201 -1
  3. package/commands/rrr/complete-milestone.md +43 -2
  4. package/commands/rrr/discuss-phase.md +33 -0
  5. package/commands/rrr/execute-phase.md +145 -9
  6. package/commands/rrr/execute-plan.md +44 -0
  7. package/commands/rrr/mvp.md +52 -2
  8. package/commands/rrr/optimize-cpu.md +238 -0
  9. package/commands/rrr/overnight.md +69 -1
  10. package/commands/rrr/think.md +94 -0
  11. package/commands/rrr/update.md +39 -0
  12. package/docs/OPTIMIZATION_SUMMARY.md +211 -0
  13. package/docs/SEMANTIC_SEARCH_OPTIMIZATION.md +1207 -0
  14. package/hooks/rrr-observation-logger.sh +69 -0
  15. package/hooks/rrr-session-start.sh +60 -0
  16. package/package.json +2 -1
  17. package/rrr/hooks/observation-logger.js +264 -0
  18. package/rrr/hooks/session-start.js +308 -0
  19. package/rrr/lib/mcp/session-search-tool.js +151 -9
  20. package/rrr/lib/memory-store.js +186 -2
  21. package/rrr/lib/scope-classifier.js +148 -0
  22. package/rrr/lib/search/query-cache.js +3 -2
  23. package/rrr/lib/search/storage.js +52 -0
  24. package/rrr/lib/team-coord.js +685 -0
  25. package/rrr/lib/team-executor.js +307 -0
  26. package/rrr/lib/team-ready.md +380 -0
  27. package/rrr/mcp-server/index.js +38 -2
  28. package/rrr/mcp-server/tools/session-search.js +10 -2
  29. package/rrr/scripts/state-compact.js +253 -0
  30. package/rrr/templates/config.json +8 -0
  31. package/rrr/templates/thinking-models/first-principles.md +103 -0
  32. package/rrr/templates/thinking-models/five-whys.md +110 -0
  33. package/rrr/templates/thinking-models/inversion.md +98 -0
  34. package/rrr/templates/thinking-models/pareto.md +103 -0
  35. package/rrr/workflows/resume-project.md +18 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,81 @@ All notable changes to RRR will be documented in this file.
4
4
 
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [1.19.0] - 2026-02-05
8
+
9
+ ### Added
10
+
11
+ - **Auto-Capture Observation Logger** - PostToolUse hook that automatically captures file creates/deletes, test results, git commits, and decision signals to `.planning/observations-YYYY-MM-DD.jsonl` with daily rotation and 1MB limit
12
+ - **Progressive STATE.md Disclosure** - Compact ~30 token state index loaded on session start; full STATE.md only on explicit resume (saves context budget)
13
+ - **SessionStart Auto-Resume Hook** - Handles Claude Code's `source` field (startup/resume/compact/clear) for automatic context restoration
14
+ - **Native Context Window Metrics** - 4-level fallback (HUD state > env var > cached file > estimation) with pressure levels integrated into drift detection
15
+ - **Timeline-Aware Session Queries** - `since`/`until` filters for session search with ISO dates, relative words ("yesterday"), and durations ("3d", "2w")
16
+ - **Complexity-Adaptive Routing** - `/rrr:mvp` auto-detects task complexity (SMALL/MEDIUM/LARGE) and routes to appropriate workflow depth
17
+ - **Configurable Git Branching** - `git_branching` strategy (none/phase/milestone) in config.json with squash-on-complete option
18
+ - **`/rrr:think` Command** - 4 structured thinking models: first-principles, inversion (pre-mortem), pareto (80/20), five-whys (root cause)
19
+ - **TeammateTool / Hidden Swarm Embedding** - File-based team coordination mirroring Claude Code's hidden TeammateTool API with spawnTeam/write/broadcast/cleanup primitives, team-aware executor for wave parallelization, and GA migration path with transport swap
20
+ - **Session Forking Guidance** - Documented session forking as preferred overnight method with fallback to traditional Jarvis
21
+
22
+ ### Changed
23
+
24
+ - `/rrr:mvp` now includes complexity detection preamble before routing
25
+ - `/rrr:execute-phase` supports team coordination for multi-plan waves
26
+ - `/rrr:execute-plan` creates git branches when `git_branching` is configured
27
+ - `/rrr:complete-milestone` handles branch merge and optional squash cleanup
28
+ - `/rrr:discuss-phase` offers optional thinking model integration
29
+ - `/rrr:overnight` uses session forking with 10-min hook timeout
30
+ - Resume workflow uses compact-first progressive disclosure approach
31
+ - Memory store includes context pressure signals in drift detection
32
+
33
+ ## [1.18.10] - 2026-02-03
34
+
35
+ ### Added
36
+
37
+ - **Ferrari-Fast Performance Patch** - Comprehensive optimization implementing all Top 5 research recommendations
38
+ - GrepAI hybrid search configuration (27.5% cost savings, 97% token reduction)
39
+ - MCP process management with V8 heap limits (512MB max) and graceful shutdown
40
+ - LanceDB scalar quantization (4x memory reduction, <1% accuracy loss)
41
+ - Enhanced query caching (1000 queries, 15-minute TTL)
42
+ - Auto-optimization already integrated in v1.18.9 (runs on install for v1.18.9-v1.19.4)
43
+
44
+ ### Changed
45
+
46
+ - Query cache size increased: 500 → 1000 embeddings for higher hit rate
47
+ - Query cache TTL optimized: 30min → 15min for faster refresh cycles
48
+ - MCP server now enforces memory limits to prevent zombie processes
49
+
50
+ ### Performance
51
+
52
+ - Memory usage: ~800MB → ~200MB (4x reduction with quantization)
53
+ - Query cache capacity: 2x increase for better hit rates
54
+ - Token usage: -27.5% through GrepAI compact output
55
+ - MCP process leaks: Prevented via V8 limits and graceful shutdown
56
+
57
+ ### Documentation
58
+
59
+ - Created `.planning/milestones/v1.18/PATCHES.md` with full implementation details
60
+ - Research basis: `docs/SEMANTIC_SEARCH_OPTIMIZATION.md` and `docs/OPTIMIZATION_SUMMARY.md`
61
+
62
+ ## [1.18.9] - 2026-02-03
63
+
64
+ ### Added
65
+
66
+ - **`/rrr:optimize-cpu`** - Keep RRR blazing fast with one command
67
+ - Clean search indexes and caches (regenerable)
68
+ - Kill zombie VS Code processes
69
+ - Kill runaway MCP servers
70
+ - Optimize git repository
71
+ - Show before/after performance metrics
72
+ - Modes: default (safe), --aggressive (deep clean), --check-only (stats only)
73
+ - Run weekly to maintain peak performance
74
+
75
+ - **Auto-optimization on install** - New users automatically get "Ferrari-fast" performance
76
+ - Runs automatically during `npx projecta-rrr` for next 5-6 updates (v1.18.9 - v1.19.4)
77
+ - Cleans search indexes, GrepAI cache, and optimizes git on first install
78
+ - Ensures new users see speed improvements immediately
79
+ - Add `--skip-optimization` flag to skip if needed
80
+ - Part of our commitment to deliver speed improvements to all users
81
+
7
82
  ## [1.18.8] - 2026-02-03
8
83
 
9
84
  ### Fixed
package/bin/install.js CHANGED
@@ -207,6 +207,7 @@ const forceStatusline = args.includes('--force-statusline');
207
207
  const forceNotify = args.includes('--force-notify');
208
208
  const noNotify = args.includes('--no-notify');
209
209
  const hudOnly = args.includes('--hud-only');
210
+ const skipOptimization = args.includes('--skip-optimization');
210
211
 
211
212
  console.log(banner);
212
213
 
@@ -222,6 +223,7 @@ if (hasHelp) {
222
223
  ${cyan}--force-statusline${reset} Replace existing statusline config
223
224
  ${cyan}--force-notify${reset} Replace existing notification hook
224
225
  ${cyan}--no-notify${reset} Skip notification hook installation
226
+ ${cyan}--skip-optimization${reset} Skip automatic performance optimization
225
227
  ${cyan}--hud-only${reset} Install only HUD components (themes + stop hook)
226
228
 
227
229
  ${yellow}Examples:${reset}
@@ -1410,6 +1412,27 @@ function install(isGlobal) {
1410
1412
  });
1411
1413
  console.log(` ${green}✓${reset} Configured cache stats hook`);
1412
1414
  }
1415
+
1416
+ // Configure SessionStart hook for auto-resume context
1417
+ const sessionStartCommand = isGlobal
1418
+ ? '$HOME/.claude/hooks/rrr-session-start.sh'
1419
+ : `${localDirName}/hooks/rrr-session-start.sh`;
1420
+
1421
+ const hasSessionStartHook = settings.hooks.SessionStart.some(entry =>
1422
+ entry.hooks && entry.hooks.some(h => h.command && h.command.includes('rrr-session-start'))
1423
+ );
1424
+
1425
+ if (!hasSessionStartHook && hookFileExists(claudeDir, 'rrr-session-start.sh')) {
1426
+ settings.hooks.SessionStart.push({
1427
+ hooks: [
1428
+ {
1429
+ type: 'command',
1430
+ command: sessionStartCommand
1431
+ }
1432
+ ]
1433
+ });
1434
+ console.log(` ${green}✓${reset} Configured auto-resume hook (SessionStart)`);
1435
+ }
1413
1436
  }
1414
1437
 
1415
1438
  // PATCH-01: Configure PostToolUse hook for drift detection
@@ -1445,6 +1468,37 @@ function install(isGlobal) {
1445
1468
  }
1446
1469
  }
1447
1470
 
1471
+ // Configure PostToolUse hook for observation logger (auto-capture key events)
1472
+ const observationLoggerCommand = isGlobal
1473
+ ? '$HOME/.claude/hooks/rrr-observation-logger.sh'
1474
+ : `${localDirName}/hooks/rrr-observation-logger.sh`;
1475
+
1476
+ if (bashStatus.available && hookFileExists(claudeDir, 'rrr-observation-logger.sh')) {
1477
+ if (!settings.hooks) {
1478
+ settings.hooks = {};
1479
+ }
1480
+ if (!settings.hooks.PostToolUse) {
1481
+ settings.hooks.PostToolUse = [];
1482
+ }
1483
+
1484
+ const hasObservationHook = settings.hooks.PostToolUse.some(entry =>
1485
+ entry.hooks && entry.hooks.some(h => h.command && h.command.includes('rrr-observation-logger'))
1486
+ );
1487
+
1488
+ if (!hasObservationHook) {
1489
+ settings.hooks.PostToolUse.push({
1490
+ matcher: '*',
1491
+ hooks: [
1492
+ {
1493
+ type: 'command',
1494
+ command: observationLoggerCommand
1495
+ }
1496
+ ]
1497
+ });
1498
+ console.log(` ${green}✓${reset} Configured observation logger hook (PostToolUse)`);
1499
+ }
1500
+ }
1501
+
1448
1502
  // Configure UserPromptSubmit hook for intent classification (smart drift detection)
1449
1503
  const classifyIntentCommand = isGlobal
1450
1504
  ? '$HOME/.claude/hooks/rrr-classify-intent.sh'
@@ -1654,6 +1708,13 @@ function install(isGlobal) {
1654
1708
  // Silent fail - context building is optional
1655
1709
  }
1656
1710
  }
1711
+
1712
+ // Run optimization for new users (v1.18.9 - v1.19.4)
1713
+ // This keeps RRR "Ferrari-fast" by cleaning caches and optimizing git
1714
+ // Only runs if: (1) version is in range, (2) --skip-optimization not passed, (3) has package.json
1715
+ if (!skipOptimization && shouldAutoOptimize() && hasProjectPkg) {
1716
+ runOptimization(projectDir);
1717
+ }
1657
1718
  }
1658
1719
 
1659
1720
  return { settingsPath, settings, statuslineCommand, notifyCommand, claudeDir, localDirName, isGlobal, bashAvailable: bashStatus.available };
@@ -1800,6 +1861,136 @@ function printDoctorSummary(claudeDir, settings, localDirName, isGlobal) {
1800
1861
  }
1801
1862
  }
1802
1863
 
1864
+ /**
1865
+ * Check if current version should run auto-optimization
1866
+ * Runs for v1.18.9 through v1.19.4 (next 5-6 updates)
1867
+ */
1868
+ function shouldAutoOptimize() {
1869
+ const currentVersion = pkg.version;
1870
+
1871
+ // Parse version parts
1872
+ const match = currentVersion.match(/^(\d+)\.(\d+)\.(\d+)$/);
1873
+ if (!match) return false;
1874
+
1875
+ const [_, major, minor, patch] = match.map(Number);
1876
+
1877
+ // Enable for v1.18.9 through v1.19.4
1878
+ if (major !== 1) return false;
1879
+ if (minor === 18 && patch >= 9) return true;
1880
+ if (minor === 19 && patch <= 4) return true;
1881
+
1882
+ return false;
1883
+ }
1884
+
1885
+ /**
1886
+ * Run performance optimization on the installed RRR directory
1887
+ * Cleans search indexes, GrepAI cache, and optimizes git
1888
+ */
1889
+ function runOptimization(projectDir) {
1890
+ console.log(`\n ${cyan}Optimizing RRR Performance${reset}\n`);
1891
+
1892
+ try {
1893
+ // Get initial metrics
1894
+ const initialStats = {
1895
+ repoSize: execSync('du -sh . 2>/dev/null || echo "unknown"', {
1896
+ cwd: projectDir,
1897
+ encoding: 'utf8',
1898
+ timeout: 10000
1899
+ }).split('\t')[0].trim()
1900
+ };
1901
+
1902
+ console.log(` ${dim}Current repo size: ${initialStats.repoSize}${reset}`);
1903
+
1904
+ let freedSpace = 0;
1905
+
1906
+ // Clean search indexes (regenerable)
1907
+ const searchIndexDir = path.join(projectDir, '.rrr', 'search');
1908
+ if (fs.existsSync(searchIndexDir)) {
1909
+ try {
1910
+ const beforeSize = execSync(`du -sk "${searchIndexDir}" 2>/dev/null || echo "0"`, {
1911
+ encoding: 'utf8',
1912
+ timeout: 5000
1913
+ }).split('\t')[0];
1914
+
1915
+ fs.rmSync(searchIndexDir, { recursive: true, force: true });
1916
+ console.log(` ${green}✓${reset} Removed search indexes (~${Math.round(parseInt(beforeSize) / 1024)}MB)`);
1917
+ freedSpace += parseInt(beforeSize);
1918
+ } catch (e) {
1919
+ // Silent fail - not critical
1920
+ }
1921
+ }
1922
+
1923
+ // Clean GrepAI cache (regenerable)
1924
+ const grepaiDir = path.join(projectDir, '.grepai');
1925
+ if (fs.existsSync(grepaiDir)) {
1926
+ try {
1927
+ const beforeSize = execSync(`du -sk "${grepaiDir}" 2>/dev/null || echo "0"`, {
1928
+ encoding: 'utf8',
1929
+ timeout: 5000
1930
+ }).split('\t')[0];
1931
+
1932
+ fs.rmSync(grepaiDir, { recursive: true, force: true });
1933
+ console.log(` ${green}✓${reset} Removed GrepAI cache (~${Math.round(parseInt(beforeSize) / 1024)}MB)`);
1934
+ freedSpace += parseInt(beforeSize);
1935
+ } catch (e) {
1936
+ // Silent fail - not critical
1937
+ }
1938
+ }
1939
+
1940
+ // Clean .claude-local duplicates (if not in source repo)
1941
+ const claudeLocalDir = path.join(projectDir, '.claude-local');
1942
+ if (fs.existsSync(claudeLocalDir) && !isRrrSourceRepo()) {
1943
+ try {
1944
+ const beforeSize = execSync(`du -sk "${claudeLocalDir}" 2>/dev/null || echo "0"`, {
1945
+ encoding: 'utf8',
1946
+ timeout: 5000
1947
+ }).split('\t')[0];
1948
+
1949
+ fs.rmSync(claudeLocalDir, { recursive: true, force: true });
1950
+ console.log(` ${green}✓${reset} Removed .claude-local duplicates (~${Math.round(parseInt(beforeSize) / 1024)}MB)`);
1951
+ freedSpace += parseInt(beforeSize);
1952
+ } catch (e) {
1953
+ // Silent fail - not critical
1954
+ }
1955
+ }
1956
+
1957
+ // Optimize git repository
1958
+ try {
1959
+ console.log(` ${dim}Optimizing git repository...${reset}`);
1960
+ execSync('git gc --auto 2>&1', {
1961
+ cwd: projectDir,
1962
+ encoding: 'utf8',
1963
+ stdio: 'pipe',
1964
+ timeout: 30000
1965
+ });
1966
+ console.log(` ${green}✓${reset} Git optimized`);
1967
+ } catch (e) {
1968
+ // Silent fail - git gc is optional
1969
+ }
1970
+
1971
+ // Get final metrics
1972
+ const finalStats = {
1973
+ repoSize: execSync('du -sh . 2>/dev/null || echo "unknown"', {
1974
+ cwd: projectDir,
1975
+ encoding: 'utf8',
1976
+ timeout: 10000
1977
+ }).split('\t')[0].trim()
1978
+ };
1979
+
1980
+ const freedMB = Math.round(freedSpace / 1024);
1981
+ console.log(`\n ${green}Optimization complete!${reset}`);
1982
+ console.log(` ${dim}Final repo size: ${finalStats.repoSize}${reset}`);
1983
+ if (freedMB > 0) {
1984
+ console.log(` ${dim}Freed ~${freedMB}MB of disk space${reset}`);
1985
+ }
1986
+ console.log(` ${dim}Search indexes will rebuild as needed${reset}\n`);
1987
+
1988
+ } catch (e) {
1989
+ // Don't fail install if optimization fails
1990
+ console.log(` ${yellow}⚠${reset} Optimization skipped: ${e.message}\n`);
1991
+ }
1992
+ }
1993
+
1803
1994
  /**
1804
1995
  * Apply statusline and notification config, then print completion message
1805
1996
  */
@@ -1878,9 +2069,18 @@ function finishInstall(settingsPath, settings, statuslineCommand, notifyCommand,
1878
2069
  setupScheduledIndexing();
1879
2070
  }
1880
2071
 
2072
+ // Show optimization note if it ran
2073
+ let optimizationNote = '';
2074
+ if (!skipOptimization && shouldAutoOptimize()) {
2075
+ optimizationNote = `
2076
+ ${green}Performance optimized!${reset} RRR is ready to run at "Ferrari speed".
2077
+ ${dim}(Run ${cyan}/rrr:optimize-cpu${reset} anytime to clean caches and free resources)${reset}
2078
+ `;
2079
+ }
2080
+
1881
2081
  console.log(`
1882
2082
  ${green}Done!${reset}
1883
-
2083
+ ${optimizationNote}
1884
2084
  ${yellow}If you installed from inside Claude Code:${reset}
1885
2085
  Type ${cyan}exit${reset} and restart ${cyan}claude${reset} so it reloads commands.
1886
2086
 
@@ -100,14 +100,55 @@ Output: Milestone archived (roadmap + requirements), PROJECT.md evolved, git tag
100
100
  - Add "Next Milestone Goals" section
101
101
  - Archive previous content in `<details>` (if v1.1+)
102
102
 
103
- 7. **Commit and tag:**
103
+ 7. **Merge branches (if git branching was used):**
104
+
105
+ Check config.json for `git_branching` setting:
106
+
107
+ ```bash
108
+ GIT_BRANCHING=$(node -e "try { const c = require('./.planning/config.json'); console.log(c.git_branching || 'none'); } catch(e) { console.log('none'); }" 2>/dev/null)
109
+ SQUASH=$(node -e "try { const c = require('./.planning/config.json'); console.log(c.squash_on_complete ? 'true' : 'false'); } catch(e) { console.log('false'); }" 2>/dev/null)
110
+ ```
111
+
112
+ **If `git_branching` is `phase` or `milestone`:**
113
+
114
+ a. List all RRR branches:
115
+ ```bash
116
+ git branch --list 'rrr/*'
117
+ ```
118
+
119
+ b. For each RRR branch:
120
+ - Ensure we are on the main/default branch
121
+ - Merge or squash-merge based on `squash_on_complete`:
122
+ ```bash
123
+ DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main")
124
+ git checkout "$DEFAULT_BRANCH"
125
+
126
+ if [ "$SQUASH" = "true" ]; then
127
+ git merge --squash "$BRANCH_NAME"
128
+ git commit -m "feat: merge ${BRANCH_NAME} (squashed)"
129
+ else
130
+ git merge "$BRANCH_NAME" --no-edit
131
+ fi
132
+ ```
133
+
134
+ c. Clean up merged branches:
135
+ ```bash
136
+ git branch -d "$BRANCH_NAME"
137
+ echo "[RRR] Merged and deleted branch: $BRANCH_NAME"
138
+ ```
139
+
140
+ d. Present summary of merged branches to user for confirmation.
141
+
142
+ **If `none`:** Skip this step entirely.
143
+
144
+ 8. **Commit and tag:**
104
145
 
105
146
  - Stage: MILESTONES.md, PROJECT.md, ROADMAP.md, STATE.md, archive files
106
147
  - Commit: `chore: archive v{{version}} milestone`
107
148
  - Tag: `git tag -a v{{version}} -m "[milestone summary]"`
108
149
  - Ask about pushing tag
109
150
 
110
- 8. **Offer next steps:**
151
+ 9. **Offer next steps:**
111
152
  - `/rrr:discuss-milestone` — thinking partner, creates context file
112
153
  - Then `/rrr:new-milestone` — update PROJECT.md with new goals
113
154
 
@@ -62,6 +62,39 @@ Phase number: $ARGUMENTS (required)
62
62
  - Scope expansion (roadmap defines scope)
63
63
  </process>
64
64
 
65
+ <thinking_models>
66
+ **Optional: Apply thinking model during discussion**
67
+
68
+ After step 5 (deep-dive areas) and before step 6 (write CONTEXT.md), offer structured analysis if the discussion revealed complex architectural decisions:
69
+
70
+ ```
71
+ ---
72
+
73
+ Noticed some meaty decisions in this discussion. Want to apply a thinking model?
74
+
75
+ | Model | Good For |
76
+ |-------|----------|
77
+ | `/rrr:think first-principles` | Strip assumptions, rebuild approach |
78
+ | `/rrr:think inversion` | Pre-mortem: what could go wrong? |
79
+ | `/rrr:think pareto` | Cut scope to the essential 20% |
80
+ | `/rrr:think five-whys` | Dig into root cause of a design question |
81
+
82
+ Or skip and proceed to CONTEXT.md.
83
+
84
+ ---
85
+ ```
86
+
87
+ **When to offer:**
88
+ - At least one gray area involved architecture or technology choice
89
+ - Discussion surfaced significant trade-offs
90
+ - User expressed uncertainty about approach
91
+
92
+ **When to skip (just proceed):**
93
+ - All gray areas were UI/UX/content (not architectural)
94
+ - Discussion was quick and clear
95
+ - User has strong opinions already
96
+ </thinking_models>
97
+
65
98
  <success_criteria>
66
99
  - Gray areas identified through intelligent analysis
67
100
  - User chose which areas to discuss
@@ -100,6 +100,50 @@ Phase: $ARGUMENTS
100
100
  **If script not found:**
101
101
  - Log warning, continue without preflight
102
102
 
103
+ 1.7. **Git branching (if configured)**
104
+
105
+ Check config.json for `git_branching` setting:
106
+
107
+ ```bash
108
+ GIT_BRANCHING=$(node -e "try { const c = require('./.planning/config.json'); console.log(c.git_branching || 'none'); } catch(e) { console.log('none'); }" 2>/dev/null)
109
+ ```
110
+
111
+ **If `git_branching` is `phase`:**
112
+ - Create and checkout branch for this phase:
113
+ ```bash
114
+ PHASE_NUM=$ARGUMENTS
115
+ PHASE_SLUG=$(basename "$PHASE_DIR" | sed "s/^${PHASE_NUM}-//")
116
+ BRANCH_NAME="rrr/phase-${PHASE_NUM}-${PHASE_SLUG}"
117
+
118
+ if ! git rev-parse --verify "$BRANCH_NAME" >/dev/null 2>&1; then
119
+ git checkout -b "$BRANCH_NAME"
120
+ echo "[RRR] Created branch: $BRANCH_NAME"
121
+ else
122
+ git checkout "$BRANCH_NAME" 2>/dev/null || echo "[RRR] Already on branch: $BRANCH_NAME"
123
+ fi
124
+ ```
125
+
126
+ **If `git_branching` is `milestone`:**
127
+ - Branch is created at milestone level (by execute-plan or new-milestone)
128
+ - Ensure we are on the milestone branch if it exists
129
+
130
+ **If `none` (default):** No branching, continue on current branch.
131
+
132
+ 1.8. **Team coordination (if configured)**
133
+
134
+ Check config.json for `team_coordination` setting:
135
+
136
+ ```bash
137
+ TEAM_COORD=$(node -e "try { const c = require('./.planning/config.json'); console.log(c.team_coordination !== false ? 'true' : 'false'); } catch(e) { console.log('true'); }" 2>/dev/null)
138
+ ```
139
+
140
+ **If `true` (default):** Team coordination enabled for multi-plan waves.
141
+ - Load team libraries: `rrr/lib/team-coord.js` and `rrr/lib/team-executor.js`
142
+ - Team coordination only activates for waves with 2+ plans
143
+ - Single-plan waves always skip team coordination (zero overhead)
144
+
145
+ **If `false`:** Team coordination disabled. Execute with original hub-and-spoke pattern.
146
+
103
147
  2. **Discover plans**
104
148
  - List all *-PLAN.md files in phase directory
105
149
  - Check which have *-SUMMARY.md (already complete)
@@ -133,11 +177,69 @@ Phase: $ARGUMENTS
133
177
  - If user chooses to skip: Mark plan as skipped, continue to next
134
178
  - If user chooses to continue: Proceed with execution
135
179
 
136
- **5b. Execute plans:**
180
+ **5b. Team setup (if multi-plan wave and team_coordination enabled):**
181
+
182
+ For waves with 2+ plans when `TEAM_COORD=true`:
183
+
184
+ ```javascript
185
+ // Using rrr/lib/team-executor.js
186
+ const team = prepareWaveTeam(phaseNum, waveNum, planIds, planPaths, projectRoot);
187
+ // team is null for single-plan waves (zero overhead)
188
+ ```
189
+
190
+ This creates `.planning/teams/phase-{N}-wave-{W}/` with:
191
+ - `config.json` — team members, status
192
+ - `messages/{agent-id}/` — per-agent inbox dirs
193
+ - `messages/broadcast/` — group messages
194
+ - `state.json` — team lifecycle state
195
+
196
+ Shared file detection: parse each plan's `## Files Modified` section,
197
+ find files appearing in 2+ plans. These require coordination.
198
+
199
+ **5c. Execute plans:**
137
200
  - For each plan, inject `<skills>` block into executor prompt
201
+ - If team exists (multi-plan wave): inject `<team_context>` block with team name, agent ID, peer IDs, shared files
138
202
  - Spawn `rrr-executor` for each plan in wave (parallel Task calls)
139
203
  - Wait for completion (Task blocks)
140
- - Verify SUMMARYs created
204
+
205
+ **5d. Post-wave team analysis (if team exists):**
206
+
207
+ After all executors in wave complete:
208
+
209
+ 1. **Read team messages** (for logging/debugging):
210
+ ```javascript
211
+ const { messages } = collectTeamMessages(team);
212
+ // Log: "[RRR] Wave {W}: {N} team messages exchanged"
213
+ ```
214
+
215
+ 2. **Detect file conflicts** (same file modified by 2+ agents):
216
+ ```javascript
217
+ const conflicts = detectFileConflicts(team, summaryPaths);
218
+ ```
219
+
220
+ 3. **If conflicts detected:** Present conflict resolution UI:
221
+ ```
222
+ ── FILE CONFLICT DETECTED ──────────────────────────
223
+
224
+ File: {file_path}
225
+ Modified by: {agent-1}, {agent-2}
226
+
227
+ {agent-1} changes: {summary from team messages}
228
+ {agent-2} changes: {summary from team messages}
229
+
230
+ ────────────────────────────────────────────────────
231
+ > Select: merge-both / keep-{agent-1} / keep-{agent-2} / manual
232
+ ────────────────────────────────────────────────────
233
+ ```
234
+
235
+ Use AskUserQuestion for conflict resolution if any non-expected conflicts exist.
236
+
237
+ 4. **Cleanup team:**
238
+ ```javascript
239
+ cleanupWaveTeam(team); // Archives to .planning/teams/archived/
240
+ ```
241
+
242
+ 5. **Verify SUMMARYs created**
141
243
  - Proceed to next wave
142
244
 
143
245
  6. **Aggregate results**
@@ -374,22 +476,56 @@ After user runs `/rrr:plan-phase {Z} --gaps`:
374
476
  </offer_next>
375
477
 
376
478
  <wave_execution>
377
- **Parallel spawning:**
479
+ **Parallel spawning with team coordination:**
480
+
481
+ **Step 1: Prepare team (multi-plan waves only)**
482
+
483
+ For waves with 2+ plans when `team_coordination` is enabled:
484
+
485
+ ```javascript
486
+ // From rrr/lib/team-executor.js
487
+ const team = prepareWaveTeam(phaseNum, waveNum, planIds, planPaths, projectRoot);
488
+ // Returns null for single-plan waves (zero overhead)
489
+
490
+ // Build team context for each executor
491
+ const teamBlock = buildTeamPromptBlock(team, planId);
492
+ // Returns '' for null teams
493
+ ```
494
+
495
+ **Step 2: Spawn executors**
378
496
 
379
497
  Spawn all plans in a wave with a single message containing multiple Task calls.
380
- Include the `<skills>` block loaded in step 4 for each plan:
498
+ Include the `<skills>` block loaded in step 4 and `<team_context>` block for each plan:
381
499
 
382
500
  ```
383
- Task(prompt="Execute plan at {plan_01_path}\n\n{skills_01_block}\n\nPlan: @{plan_01_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
384
- Task(prompt="Execute plan at {plan_02_path}\n\n{skills_02_block}\n\nPlan: @{plan_02_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
385
- Task(prompt="Execute plan at {plan_03_path}\n\n{skills_03_block}\n\nPlan: @{plan_03_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
501
+ Task(prompt="Execute plan at {plan_01_path}\n\n{skills_01_block}\n\n{team_context_01}\n\nPlan: @{plan_01_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
502
+ Task(prompt="Execute plan at {plan_02_path}\n\n{skills_02_block}\n\n{team_context_02}\n\nPlan: @{plan_02_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
503
+ Task(prompt="Execute plan at {plan_03_path}\n\n{skills_03_block}\n\n{team_context_03}\n\nPlan: @{plan_03_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
386
504
  ```
387
505
 
388
- Where `{skills_XX_block}` is the `<skills>` content containing skill SKILL.md files specific to that plan.
506
+ Where:
507
+ - `{skills_XX_block}` is the `<skills>` content containing skill SKILL.md files specific to that plan
508
+ - `{team_context_XX}` is the `<team_context>` block from `buildTeamPromptBlock()` (empty for single-plan waves)
509
+
510
+ All executors run in parallel. Task tool blocks until all complete.
511
+
512
+ **Step 3: Post-wave analysis (multi-plan waves only)**
389
513
 
390
- All three run in parallel. Task tool blocks until all complete.
514
+ ```javascript
515
+ // Collect team messages for logging
516
+ const { messages } = collectTeamMessages(team);
517
+ // Log: "[RRR] Wave {W}: {N} team messages exchanged"
518
+
519
+ // Check for file conflicts
520
+ const conflicts = detectFileConflicts(team, summaryPaths);
521
+ // If conflicts: present resolution UI via AskUserQuestion
522
+
523
+ // Archive team
524
+ cleanupWaveTeam(team);
525
+ ```
391
526
 
392
527
  **No polling.** No background agents. No TaskOutput loops.
528
+ **Single-plan waves:** Skip all team logic. Zero overhead. Same as before.
393
529
  </wave_execution>
394
530
 
395
531
  <checkpoint_handling>
@@ -168,6 +168,50 @@ Plan path: $ARGUMENTS
168
168
  - "Review plan first" → display plan summary, ask again
169
169
  - "Cancel" → exit without executing
170
170
 
171
+ 0.7. **Git branching (if configured)**
172
+
173
+ Check config.json for `git_branching` setting:
174
+
175
+ ```bash
176
+ GIT_BRANCHING=$(node -e "try { const c = require('./.planning/config.json'); console.log(c.git_branching || 'none'); } catch(e) { console.log('none'); }" 2>/dev/null)
177
+ ```
178
+
179
+ **If `git_branching` is `phase`:**
180
+ - Extract phase number and slug from plan path
181
+ - Check if branch `rrr/phase-{N}-{slug}` already exists
182
+ - If not: create and checkout the branch
183
+ ```bash
184
+ PHASE_NUM=$(basename "$(dirname "$ARGUMENTS")" | cut -d'-' -f1)
185
+ PHASE_SLUG=$(basename "$(dirname "$ARGUMENTS")" | sed "s/^${PHASE_NUM}-//")
186
+ BRANCH_NAME="rrr/phase-${PHASE_NUM}-${PHASE_SLUG}"
187
+
188
+ if ! git rev-parse --verify "$BRANCH_NAME" >/dev/null 2>&1; then
189
+ git checkout -b "$BRANCH_NAME"
190
+ echo "[RRR] Created branch: $BRANCH_NAME"
191
+ else
192
+ git checkout "$BRANCH_NAME" 2>/dev/null || echo "[RRR] Already on branch: $BRANCH_NAME"
193
+ fi
194
+ ```
195
+
196
+ **If `git_branching` is `milestone`:**
197
+ - Extract milestone version from ROADMAP.md
198
+ - Check if branch `rrr/{version}-{slug}` already exists
199
+ - If not: create and checkout the branch
200
+ ```bash
201
+ MILESTONE_VER=$(grep -E "^## Current Milestone:" .planning/ROADMAP.md 2>/dev/null | sed 's/.*: *\(v[0-9.]*\).*/\1/' || echo "vX.X")
202
+ PHASE_SLUG=$(basename "$(dirname "$ARGUMENTS")" | sed 's/^[0-9]*-//')
203
+ BRANCH_NAME="rrr/${MILESTONE_VER}-${PHASE_SLUG}"
204
+
205
+ if ! git rev-parse --verify "$BRANCH_NAME" >/dev/null 2>&1; then
206
+ git checkout -b "$BRANCH_NAME"
207
+ echo "[RRR] Created branch: $BRANCH_NAME"
208
+ else
209
+ git checkout "$BRANCH_NAME" 2>/dev/null || echo "[RRR] Already on branch: $BRANCH_NAME"
210
+ fi
211
+ ```
212
+
213
+ **If `none` (default):** No branching, continue on current branch.
214
+
171
215
  1. **Validate plan exists**
172
216
  - Confirm file at $ARGUMENTS exists
173
217
  - Error if not found: "Plan not found: {path}"