@hanzlaa/rcode 4.0.0 → 4.1.1

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 (47) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +2 -2
  3. package/cli/doctor.js +17 -0
  4. package/cli/github-sync.js +3 -2
  5. package/cli/index.js +16 -0
  6. package/cli/install.js +1 -0
  7. package/cli/lib/manifest.cjs +13 -0
  8. package/cli/set-mode.js +10 -0
  9. package/cli/set-profile.js +10 -0
  10. package/cli/uninstall.js +100 -39
  11. package/cli/workflow.js +97 -0
  12. package/dist/rcode.js +249 -229
  13. package/package.json +1 -1
  14. package/rcode/bin/lib/config.cjs +3 -2
  15. package/rcode/bin/rcode-tools.cjs +8 -3
  16. package/rcode/skills/SKILLS_INDEX.md +4 -3
  17. package/rcode/skills/actions/1-analysis/rcode-document-project/SKILL.md +6 -0
  18. package/rcode/skills/actions/3-solutioning/rcode-check-implementation-readiness/SKILL.md +6 -0
  19. package/rcode/skills/actions/3-solutioning/rcode-create-architecture/steps/step-01-init.md +1 -1
  20. package/rcode/skills/actions/3-solutioning/rcode-create-architecture/workflow.md +13 -1
  21. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/SKILL.md +166 -0
  22. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/references.md +136 -0
  23. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/rules/backlog-building.md +113 -0
  24. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/rules/composition-with-herdr.md +85 -0
  25. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/rules/integration-branch.md +191 -0
  26. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/rules/merge-strategy.md +113 -0
  27. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/rules/orchestrator-rhythm.md +119 -0
  28. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/rules/wave-design.md +100 -0
  29. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/templates/BACKLOG-template.md +34 -0
  30. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/templates/STATE-template.md +40 -0
  31. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/templates/heartbeat.sh +29 -0
  32. package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/templates/wave-prompt.md +69 -0
  33. package/rcode/skills/actions/4-implementation/rcode-retrospective/workflow.md +61 -246
  34. package/rcode/templates/sprint.md +16 -0
  35. package/rcode/workflows/audit.md +3 -0
  36. package/rcode/workflows/brainstorm.md +1 -1
  37. package/rcode/workflows/council.md +8 -1
  38. package/rcode/workflows/create-architecture.md +5 -1
  39. package/rcode/workflows/create-prd.md +5 -1
  40. package/rcode/workflows/dashboard.md +5 -2
  41. package/rcode/workflows/discuss-phase.md +3 -15
  42. package/rcode/workflows/execute-sprint.md +3 -1
  43. package/rcode/workflows/plan-spawn-planner.md +96 -0
  44. package/rcode/workflows/plan.md +67 -0
  45. package/rcode/workflows/retrospective.md +5 -1
  46. package/rcode/workflows/sprint-planning.md +9 -5
  47. package/server/dashboard.js +2 -2
@@ -0,0 +1,191 @@
1
+ # Campaign Integration Branch
2
+
3
+ The orchestrator maintains its own long-lived parent branch for the campaign. Sub-agents fork from it, merges land on it, master stays untouched until the user explicitly lands the whole campaign.
4
+
5
+ ## Purpose
6
+
7
+ A prior campaign session (2026-05-26) revealed the failure mode this rule prevents:
8
+
9
+ - Sub-agents in Wave-1 forked directly from `master`. They committed.
10
+ - Wave-1 merges landed on `master`.
11
+ - Wave-2 sub-agents forked from `master` again — at a HEAD that already had Wave-1's merges.
12
+ - **But the worktrees were created with `git worktree add ... master` at slightly different times, and some Wave-1 work was still in flight on its own branches.**
13
+ - Wave-2 branches overlapped with Wave-1 branches' files → cross-wave merge conflicts.
14
+ - The orchestrator spent multiple ticks resolving those conflicts instead of shipping new work.
15
+ - Some branches couldn't be auto-merged at all and got queued for a rebase agent, who introduced TSC regressions of its own.
16
+
17
+ The fix: **one campaign integration branch**, serially advanced. Sub-agents always fork from the integration branch's CURRENT TIP (not a snapshot, not master). When a wave's merges land on the integration branch, the next wave's sub-agents inherit them automatically.
18
+
19
+ ## Rules
20
+
21
+ ### Naming
22
+
23
+ | Branch | When to use |
24
+ |---|---|
25
+ | `campaign-integration` | Default for unnamed campaigns. |
26
+ | `campaign-<topic>` | When the campaign has a coherent theme (e.g. `campaign-crm-cleanup`, `campaign-q2-tech-debt`). |
27
+ | `campaign-<topic>-<wave>` | Don't use. The integration branch is one branch across all waves. Per-wave naming defeats the purpose. |
28
+
29
+ Sub-agent branches stay named `campaign-<area>` and live as short-lived feature branches that merge into the integration branch.
30
+
31
+ ### Lifecycle
32
+
33
+ ```
34
+ master ┐
35
+ ├─ campaign-integration (branch) │ <-- orchestrator stays here
36
+ │ ├─ campaign-area-1 │ <-- sub-agent Wave 1
37
+ │ ├─ campaign-area-2 │
38
+ │ ├─ campaign-area-3 │
39
+ │ │
40
+ │ │ <-- Wave 1 merged into campaign-integration
41
+ │ │
42
+ │ ├─ campaign-area-4 │ <-- Wave 2 forks from updated integration
43
+ │ ├─ campaign-area-5 │
44
+ │ │
45
+ │ │ <-- Wave 2 merged
46
+ │ │
47
+ │ └─ (continues...) │
48
+ │ │
49
+ └─ (Phase 3: integration → master)│
50
+ ```
51
+
52
+ ### Pre-flight (Phase 0)
53
+
54
+ ```bash
55
+ git checkout master && git pull origin master # start fresh
56
+ git checkout -b campaign-integration master
57
+ git push -u origin campaign-integration # OPTIONAL — only the integration branch may be auto-pushed
58
+ ```
59
+
60
+ The integration branch can be auto-pushed because:
61
+ - It is **not master** — pushing it does not affect production.
62
+ - It enables PR-style review via GitHub.
63
+ - It survives orchestrator crashes (work lives on origin).
64
+
65
+ If the user says "no push of anything ever" — respect that. Don't push the integration branch either.
66
+
67
+ ### Sub-agent worktree creation
68
+
69
+ ```bash
70
+ # WRONG — direct fork from master, cross-wave conflict risk
71
+ git worktree add ../sm-worktrees/camp-<area> -b campaign-<area> master
72
+
73
+ # RIGHT — fork from integration branch
74
+ git worktree add ../sm-worktrees/camp-<area> -b campaign-<area> campaign-integration
75
+ ```
76
+
77
+ ### Merging during a wave (Phase 2)
78
+
79
+ ```bash
80
+ # orchestrator's main worktree is checked out on campaign-integration
81
+ git merge campaign-<area> --no-edit
82
+ NEW_TSC=$(pnpm tsc --noEmit 2>&1 | grep -c "error TS")
83
+ if [ "$NEW_TSC" -gt "$INTEGRATION_BASELINE_TSC" ]; then
84
+ git reset --hard HEAD~1 # back out of integration branch, NOT master
85
+ fi
86
+ ```
87
+
88
+ Master never enters the picture during merges. The TSC gate compares against the integration branch's recorded baseline, not master's.
89
+
90
+ ### Sync from master during long campaigns
91
+
92
+ If the campaign runs for hours and other work lands on master from outside, periodically pull master into the integration branch:
93
+
94
+ ```bash
95
+ # orchestrator on campaign-integration
96
+ git fetch origin
97
+ git merge origin/master --no-edit # fast-forward when possible, conflict-resolve when not
98
+ ```
99
+
100
+ Do this between waves, NEVER mid-wave (would disrupt in-flight sub-agents whose branches were forked from the older integration tip).
101
+
102
+ ### Landing (Phase 3)
103
+
104
+ When BACKLOG.md is empty and all sub-agent branches have merged into the integration branch:
105
+
106
+ ```bash
107
+ git checkout campaign-integration
108
+ git diff master..campaign-integration --stat # show user the change set
109
+ git log master..campaign-integration --oneline # show user the commit list
110
+ ```
111
+
112
+ Then **ask the user**:
113
+
114
+ ```
115
+ Campaign-integration is N commits ahead of master.
116
+ How do you want to land it?
117
+ (a) Open a PR: gh pr create --base master --head campaign-integration
118
+ (b) Merge to master locally (--no-ff for a clean merge commit)
119
+ (c) Squash-merge to master (one tidy commit, history compressed)
120
+ (d) Leave campaign-integration as-is — I'll review later
121
+ ```
122
+
123
+ Do NOT default to any of these. Wait for the user's answer.
124
+
125
+ ## Examples
126
+
127
+ ### Three-wave campaign with integration branch
128
+
129
+ ```
130
+ T+0: git checkout -b campaign-integration master # Phase 0
131
+ T+1: wave 1: 4 sub-agents fork from campaign-integration
132
+ T+15m: wave 1 merges land on campaign-integration (NOT master)
133
+ T+15m: wave 2: 4 sub-agents fork from updated campaign-integration
134
+ ↑ inherits wave 1's work automatically
135
+ T+30m: wave 2 merges land on campaign-integration
136
+ T+30m: wave 3: 4 sub-agents fork from updated campaign-integration
137
+ T+45m: wave 3 merges land
138
+ T+45m: BACKLOG empty. Ask user how to land. (PR / merge / squash / leave)
139
+ ```
140
+
141
+ Cross-wave conflicts disappear because every sub-agent sees the previous waves' merged work.
142
+
143
+ ### Sync from master mid-campaign (rare)
144
+
145
+ ```
146
+ T+0h: Start campaign-integration from master.
147
+ T+2h: Wave 1, 2 done on integration branch.
148
+ T+2h: Notice another team merged "fix(auth): X" to master.
149
+ T+2h: Between waves: orchestrator on campaign-integration runs
150
+ `git merge origin/master --no-edit` → fast-forward succeeds.
151
+ T+2h: Wave 3 forks from now-up-to-date integration branch.
152
+ ```
153
+
154
+ ## Anti-Patterns
155
+
156
+ ### Forking sub-agents from master directly
157
+
158
+ **Problem**: Cross-wave conflicts pile up — sibling branches stomp on the same files because they both fork from the same parent without seeing each other's work.
159
+ **Instead**: Sub-agents always fork from `campaign-integration`.
160
+
161
+ ### Treating the integration branch as just-another-branch and merging it to master mid-campaign
162
+
163
+ **Problem**: Defeats the isolation. If you ship integration → master on every wave, you're back to the old direct-on-master pattern.
164
+ **Instead**: Merge integration → master only once, at Phase 3, with explicit user consent.
165
+
166
+ ### Per-wave integration branches (`campaign-wave1-integration`, `campaign-wave2-integration`)
167
+
168
+ **Problem**: Now you have to merge the wave integrations together at the end — adds a layer of merge work for no benefit. The whole point of integration is one durable line.
169
+ **Instead**: One integration branch, serially advanced across all waves.
170
+
171
+ ### Skipping the Phase-3 "how do you want to land it" question
172
+
173
+ **Problem**: Auto-merging integration → master at campaign end repeats the no-consent-push mistake at the local level.
174
+ **Instead**: Always ask. Present PR / merge / squash / leave as explicit options.
175
+
176
+ ### Pushing campaign-integration without checking first
177
+
178
+ **Problem**: User may have a "no push" preference that covers ALL refs, not just master.
179
+ **Instead**: For the very first push of the integration branch, ask once. Subsequent pushes of the same branch can use that answer.
180
+
181
+ ## Related
182
+
183
+ - `orchestrator-rhythm.md` — heartbeat continues while integration branch has open waves
184
+ - `wave-design.md` — wave size still 3-5; integration branch doesn't change wave structure
185
+ - `merge-strategy.md` — TSC gate is now against integration baseline, not master
186
+ - `backlog-building.md` — BACKLOG and STATE files live on the integration branch
187
+ - `composition-with-herdr.md` — herdr panes still own per-sub-agent worktrees; orchestrator owns the integration branch's main worktree
188
+
189
+ ## Changelog
190
+
191
+ - 2026-05-26: Initial. Codified from the session that revealed cross-wave conflict explosions — the orchestrator was merging sub-agent branches into master directly, which forced parallel waves to fight over the same files. The integration-branch pattern eliminates that.
@@ -0,0 +1,113 @@
1
+ # Merge Strategy + TSC Gate
2
+
3
+ How to merge wave output **into the campaign integration branch** without regressing. Master is never touched during the campaign — see `integration-branch.md`.
4
+
5
+ ## Purpose
6
+ Parallel branches stomp on shared files. Merging requires a discipline: smallest first, TSC at every step, abort on first sign of trouble.
7
+
8
+ ## Rules
9
+
10
+ ### Order: smallest first
11
+ Sort campaign branches by `git rev-list --count campaign-integration..<branch>` ascending. Merge the smallest one first.
12
+ - Validates the merge flow on low-risk content.
13
+ - Lets big branches rebase on top of small ones (less conflict per merge step).
14
+
15
+ ### TSC baseline gate
16
+ Before any wave:
17
+ ```bash
18
+ TSC_BASELINE=$(pnpm tsc --noEmit 2>&1 | grep -c "error TS")
19
+ ```
20
+ After every merge:
21
+ ```bash
22
+ TSC_NEW=$(pnpm tsc --noEmit 2>&1 | grep -c "error TS")
23
+ if [ "$TSC_NEW" -gt "$TSC_BASELINE" ]; then
24
+ echo "Regression on this merge — reverting"
25
+ git reset --hard HEAD~1
26
+ fi
27
+ ```
28
+ **Never compound regressions across waves.**
29
+
30
+ ### Conflict resolution (delegates to herdr-orchestration)
31
+ - Content conflicts: read both sides, keep the **more-complete superset side**, remove markers, syntax-check, stage, commit. (See herdr-orchestration rules.)
32
+ - AA conflicts (add/add): peek both versions; if nearly identical, keep the canonical owner's version. The "owner" is the branch whose audit doc claimed the feature.
33
+ - Unable to resolve safely: `git merge --abort`, mark the branch as `[needs-rebase]` in STATE.md, queue for next wave's resolution pass.
34
+
35
+ ### Push policy
36
+ **During the campaign**: NEVER `git push origin campaign-integration`. The orchestrator is on the integration branch, not master.
37
+
38
+ Pushing the integration branch itself is permitted (it's not master, it's isolated), but ASK ONCE at Phase 0:
39
+ ```bash
40
+ git push -u origin campaign-integration 2>&1 | tail -3
41
+ ```
42
+ Once that question is answered yes, the orchestrator may push the integration branch silently after each wave merge (helpful for PR previews and survival across restarts).
43
+
44
+ **At Phase 3 only**: ask the user how to land the campaign. Options: PR, local merge to master, squash, or leave. Push master ONLY if they say "yes, merge and push to master" — explicit, never inferred. Never rely on `git push 2>/dev/null || true` patterns (they swallow auth failures and diverge silently).
45
+
46
+ ### Worktree cleanup
47
+ After a branch is merged AND pushed:
48
+ ```bash
49
+ git worktree remove --force ../sm-worktrees/camp-<area>
50
+ git branch -d campaign-<area>
51
+ ```
52
+ Frees space and keeps `git worktree list` readable.
53
+
54
+ ## Examples
55
+
56
+ ### Single-wave merge sweep
57
+
58
+ ```bash
59
+ for B in $(git branch --format="%(refname:short)" | grep "^campaign-"); do
60
+ C=$(git rev-list --count master..$B 2>/dev/null)
61
+ [ "$C" = "0" ] && continue
62
+ echo "=== merging $B ($C commits) ==="
63
+ if git merge "$B" --no-edit 2>&1 | tail -5 | grep -q "CONFLICT"; then
64
+ echo "CONFLICT — aborting and queueing $B for resolution"
65
+ git merge --abort
66
+ echo "$B" >> .planning/campaign/NEEDS-REBASE.md
67
+ else
68
+ NEW=$(pnpm tsc --noEmit 2>&1 | grep -c "error TS")
69
+ if [ "$NEW" -gt "$TSC_BASELINE" ]; then
70
+ echo "TSC regressed ($TSC_BASELINE → $NEW) — reverting $B"
71
+ git reset --hard HEAD~1
72
+ fi
73
+ fi
74
+ done
75
+ git push origin campaign-integration
76
+ ```
77
+
78
+ ### Aborted merge handling
79
+
80
+ When a conflict aborts:
81
+ 1. The branch stays alive — work isn't lost.
82
+ 2. The orchestrator's next turn dispatches a single rebase agent specifically for `NEEDS-REBASE.md` items.
83
+ 3. After rebase, retry merge.
84
+
85
+ ## Anti-Patterns
86
+
87
+ ### Auto-resolving conflicts with `-X theirs` or `-X ours`
88
+
89
+ **Problem**: Strategy options pick a whole side, discarding the other branch's work without inspection.
90
+ **Instead**: Read both sides; superset rule; if uncertain, abort and queue.
91
+
92
+ ### Merging while sub-agents are still active on overlapping files
93
+
94
+ **Problem**: Sub-agent's later commit invalidates the merge you just made.
95
+ **Instead**: Only merge branches whose status is `idle`/`done`. `working` branches stay queued.
96
+
97
+ ### Skipping the TSC check
98
+
99
+ **Problem**: A type error silently lands on master, next wave forks from broken master, regression compounds.
100
+ **Instead**: TSC after every merge. Revert immediately on regression.
101
+
102
+ ### Force-pushing master to "fix" a regression
103
+
104
+ **Problem**: Destroys local work, can lose unpushed wave output.
105
+ **Instead**: `git reset --hard HEAD~1` (no force-push) to undo a bad local merge before pushing.
106
+
107
+ ## Related
108
+ - `orchestrator-rhythm.md` — merges happen during heartbeat ticks, not in the middle of dispatch
109
+ - `wave-design.md` — wave composition determines conflict surface area
110
+ - `composition-with-herdr.md` — herdr conflict-resolution superset rule
111
+
112
+ ## Changelog
113
+ - 2026-05-26: Initial.
@@ -0,0 +1,119 @@
1
+ # Orchestrator Rhythm + Heartbeat
2
+
3
+ The orchestrator must never go silent while sub-agents are still working.
4
+
5
+ ## Purpose
6
+ A long-running campaign hits two failure modes that this rule prevents:
7
+ 1. **Silent assistant**: orchestrator answers a question, then never wakes back up — sub-agents finish, their commits sit unmerged.
8
+ 2. **Polling waste**: orchestrator wakes too often (every 60s), burning cache misses and tokens.
9
+
10
+ ## Rules
11
+
12
+ ### Heartbeat sources — IMPORTANT distinctions
13
+
14
+ **`ScheduleWakeup` only fires when `/loop` mode is active.** Outside `/loop`, it is effectively a no-op — the harness will NOT re-invoke the assistant after the delay. The assistant must verify this before relying on it.
15
+
16
+ **To actually auto-wake the orchestrator during a campaign, pick ONE of these:**
17
+
18
+ 1. **`/loop` mode (RECOMMENDED for long campaigns)** — User invokes `/loop` at the start of the campaign. After that, the assistant's `ScheduleWakeup` calls actually fire and re-invoke autonomously. The user can ctrl-c the loop at any time. This is the only built-in path to true autonomous re-invocation.
19
+
20
+ 2. **`/schedule` (cron-based)** — User creates a scheduled routine that pings the assistant at fixed intervals (e.g. every 15 min). Survives session restarts. Requires Anthropic's scheduled-agents feature. Best for multi-hour campaigns where the user closes the terminal.
21
+
22
+ 3. **Manual pinging** — User types `<<autonomous-loop-dynamic>>` (or just "check status") each time they want progress. Most honest default if `/loop` and `/schedule` aren't available. The orchestrator should be honest with the user that nothing auto-fires.
23
+
24
+ 4. **Bash heartbeat file** — Only an EXTERNAL liveness signal. `touch .planning/campaign/HEARTBEAT` every 30s in a background bash loop. **This does NOT wake the assistant** — it only tells an external watcher (you, a monitor script) that the campaign hasn't crashed. Useful as a secondary check, never as the primary heartbeat.
25
+
26
+ ### Be honest at campaign start
27
+
28
+ At Phase 0, the orchestrator MUST clarify with the user which heartbeat path is in effect:
29
+
30
+ ```
31
+ Heartbeat options for this campaign:
32
+ (a) Wrap the campaign in /loop so auto-wakeup actually fires (recommended for >1h work)
33
+ (b) Use /schedule to ping every N minutes (best for multi-hour, can-close-terminal campaigns)
34
+ (c) Manual mode — you ping me with "check status" whenever you want progress
35
+
36
+ Which would you like? (a/b/c)
37
+ ```
38
+
39
+ If the user picks (c) or skips: NEVER claim "Scheduling 20-min wakeup" in chat — that's a lie. Say instead: "12 agents detached and running. Ping me back with 'check status' when you want me to merge results."
40
+
41
+ ### Cadence by phase (only relevant under /loop or /schedule)
42
+
43
+ | Phase | Heartbeat interval | Rationale |
44
+ |---|---|---|
45
+ | Phase 1 (wave just dispatched) | 720s | Sub-agents need 10-15 min to produce a commit |
46
+ | Phase 2 (multiple waves running) | 540-720s | Slightly tighter — more chances to merge |
47
+ | Phase 3 (draining last waves) | 270s | Sub-agents finishing close to each other; don't miss the last |
48
+ | Idle (waiting on stuck pane) | 1200s | Sub-agent stuck — give it room or surface it |
49
+
50
+ ### Cadence by phase
51
+
52
+ | Phase | Heartbeat interval | Rationale |
53
+ |---|---|---|
54
+ | Phase 1 (wave just dispatched) | 720s | Sub-agents need 10-15 min to produce a commit |
55
+ | Phase 2 (multiple waves running) | 540-720s | Slightly tighter — more chances to merge |
56
+ | Phase 3 (draining last waves) | 270s | Sub-agents finishing close to each other; don't miss the last |
57
+ | Idle (waiting on stuck pane) | 1200s | Sub-agent stuck — give it room or surface it |
58
+
59
+ ### Stop conditions
60
+ The heartbeat should stop ONLY when ALL three are true:
61
+ - Every herdr pane is `idle` or `done`
62
+ - Every campaign branch has been merged or marked rejected
63
+ - `.planning/campaign/BACKLOG.md` is empty (or only contains items marked `[skip]`)
64
+
65
+ ## Examples
66
+
67
+ ### End-of-turn pattern (every campaign turn)
68
+
69
+ ```
70
+ ScheduleWakeup(
71
+ delaySeconds=720,
72
+ reason="Wave-3 in flight; expect commits within 10 min then merge + dispatch wave-4",
73
+ prompt="<<autonomous-loop-dynamic>>"
74
+ )
75
+ ```
76
+
77
+ ### Heartbeat bash template
78
+
79
+ ```bash
80
+ #!/bin/bash
81
+ # Run with: bash heartbeat.sh & echo $! > .planning/campaign/HEARTBEAT.pid
82
+ HEARTBEAT=.planning/campaign/HEARTBEAT
83
+ while true; do
84
+ date -u +%FT%TZ > "$HEARTBEAT"
85
+ sleep 30
86
+ done
87
+ ```
88
+
89
+ ### Resuming after auto-compact
90
+
91
+ If the orchestrator hits auto-compact mid-campaign, the first turn after must:
92
+ 1. Read `.planning/campaign/STATE.md` — figure out which wave is in flight.
93
+ 2. Run `herdr pane list` — find which panes are still working.
94
+ 3. Run `git branch | grep campaign-` + `git rev-list --count master..<each>` — find unmerged commits.
95
+ 4. Resume from Phase 2 of the workflow. Do not redispatch waves that are already in flight.
96
+
97
+ ## Anti-Patterns
98
+
99
+ ### Polling every 60s
100
+
101
+ **Problem**: Wakeup interval shorter than 270s burns the Anthropic prompt cache repeatedly without any real work happening (sub-agents need minutes between commits).
102
+ **Instead**: 540-720s default. Drop to 270s only when wrapping the last wave.
103
+
104
+ ### Bash `sleep && check` loop instead of ScheduleWakeup
105
+
106
+ **Problem**: A blocking `sleep` in the assistant's own session ties up the conversation slot. The harness blocks long leading sleeps anyway.
107
+ **Instead**: Use ScheduleWakeup. The bash heartbeat is for a SEPARATE background process, not for sleeping in the assistant's bash.
108
+
109
+ ### Ending a turn without scheduling wakeup while sub-agents are working
110
+
111
+ **Problem**: Orchestrator returns control to user, user doesn't reply, sub-agents complete, no one merges, work rots.
112
+ **Instead**: Last action of every campaign turn = `ScheduleWakeup`. Non-negotiable.
113
+
114
+ ## Related
115
+ - `wave-design.md` — how wave size affects cadence
116
+ - `composition-with-herdr.md` — herdr pane status states (`working`/`idle`/`done`) drive the loop exit
117
+
118
+ ## Changelog
119
+ - 2026-05-26: Initial. Codified from session that shipped 200+ commits across ~12 waves.
@@ -0,0 +1,100 @@
1
+ # Wave Design
2
+
3
+ How to size, split, and sequence campaign waves.
4
+
5
+ ## Purpose
6
+ A campaign with too few agents underuses parallelism; too many causes merge conflicts and stalls. This rule encodes the sizing + sequencing that worked across long sessions.
7
+
8
+ ## Rules
9
+
10
+ ### Wave size
11
+ - **Default: 4 agents per wave.** 2x2 herdr grid, easy to monitor visually.
12
+ - **Minimum: 3.** Below 3 the orchestrator overhead isn't justified — just do the work directly.
13
+ - **Maximum: 5.** Above 5 the merge stage becomes painful and TSC regressions compound across simultaneous changes.
14
+ - **Sequential or concurrent waves?** Concurrent only if you have >8 distinct unrelated areas AND the merge bookkeeping is automated. Default is sequential: dispatch wave → merge → dispatch wave.
15
+
16
+ ### Wave scope rules
17
+ Each agent in a wave must:
18
+ - Own a **distinct audit area** (no two agents touching the same file domain).
19
+ - Have a **clear stop signal** — fix 3-5 items, then return. No "keep going until I say stop".
20
+ - Be **diagnose-then-fix**, not "rewrite this area".
21
+
22
+ Cross-agent overlap risks (use these to vet wave composition):
23
+
24
+ | If wave includes both… | Conflict risk | Mitigation |
25
+ |---|---|---|
26
+ | `lead-types` + `call-update-flow` | Both touch `leadService.js`/`callService.js` | Run sequentially, not concurrent |
27
+ | `crm-pipeline` + `deals-pipeline-forecast` | Both touch deal stage logic | Split: one schema, one UI |
28
+ | `email-system` + `email-sequences` | Both touch templating | Run sequentially |
29
+ | `oauth-callbacks` + `integrations-developer` | Both touch OAuth handlers | Different providers per agent |
30
+
31
+ ### Item picking heuristics
32
+
33
+ For each backlog item, score before assigning to a wave:
34
+
35
+ | Criterion | Good for wave | Bad for wave |
36
+ |---|---|---|
37
+ | Blast radius | 1-5 files | 20+ files |
38
+ | Has Prisma schema change | OK with migration | Not OK without migration |
39
+ | Cross-cuts auth/RBAC | Solo agent | Avoid |
40
+ | Touches WebSocket/realtime | Solo agent | Avoid |
41
+ | Pure UI/CSS | Great parallel target | — |
42
+ | Pure backend logic in one service | Great parallel target | — |
43
+
44
+ ### Wave duration
45
+ - Target: 10-15 min per wave.
46
+ - Past 25 min: peek at all panes, identify stuck agents, decide kill-or-wait.
47
+ - Hard stop: 45 min. If a wave hasn't produced commits in 45 min, something is wrong — abort and re-dispatch.
48
+
49
+ ## Examples
50
+
51
+ ### Good wave-1 composition (from real session)
52
+ ```
53
+ camp-crm-pipeline ← AUDIT-CRM-pipeline P1/P2
54
+ camp-crm-reporting ← AUDIT-CRM-reporting P1/P2
55
+ camp-deals-forecast ← AUDIT-deals-pipeline-forecast P1
56
+ camp-crm-activity ← AUDIT-CRM-activity P1
57
+ ```
58
+ Distinct services, distinct schema tables, no overlap.
59
+
60
+ ### Bad wave composition
61
+ ```
62
+ camp-leads-A ← leadService refactor
63
+ camp-leads-B ← leadService bug fixes
64
+ camp-leads-C ← leadService new feature
65
+ camp-leads-D ← leadService perf
66
+ ```
67
+ All four touch `leadService.js` — merge will be a conflict bloodbath.
68
+
69
+ ### Phased waves (when items naturally depend on each other)
70
+ ```
71
+ Wave 1: schema additions (lead-types schema, conversation schema)
72
+ Wave 2: backend wiring on top of Wave 1's schema
73
+ Wave 3: UI on top of Wave 2's API
74
+ ```
75
+ Each phase merges before the next dispatches.
76
+
77
+ ## Anti-Patterns
78
+
79
+ ### Dispatching all backlog items at once
80
+
81
+ **Problem**: 17 audit docs × 4 items = 68 simultaneous agents. Herdr can't manage that; merge stage becomes O(N²).
82
+ **Instead**: 4 agents at a time, 17 waves over the campaign.
83
+
84
+ ### Reusing a worktree across waves
85
+
86
+ **Problem**: Worktree state lingers — uncommitted files, stale `node_modules` symlink, half-merged branch.
87
+ **Instead**: Fresh worktree per wave-agent. Tear down after merge.
88
+
89
+ ### Wave with no audit doc backing
90
+
91
+ **Problem**: Agent invents work that wasn't asked for; commits get rejected.
92
+ **Instead**: Every wave-agent prompt must reference a specific audit doc with specific item numbers.
93
+
94
+ ## Related
95
+ - `backlog-building.md` — what feeds wave selection
96
+ - `merge-strategy.md` — what happens after a wave completes
97
+ - `composition-with-herdr.md` — herdr 2x2 pane grid
98
+
99
+ ## Changelog
100
+ - 2026-05-26: Initial.
@@ -0,0 +1,34 @@
1
+ # CAMPAIGN BACKLOG
2
+
3
+ Generated: <ISO-TIMESTAMP>
4
+ Repo: <REPO-NAME>
5
+ Baseline TSC errors: <COUNT>
6
+ Source: `<AUDIT-DOC-DIRECTORY>` + `grep TODO/FIXME/HACK` in `<SCAN-DIRS>`
7
+
8
+ ## Open items
9
+
10
+ <!-- One bullet per atomic, mergeable unit of work. Order = priority. -->
11
+
12
+ - [ ] **<area-1>** (P1): <short description>. Source: `<audit-doc>:<line>`
13
+ - [ ] **<area-1>** (P2): <short description>. Source: `<audit-doc>:<line>`
14
+ - [ ] **<area-2>** (P1): <short description>. Source: `<audit-doc>:<line>`
15
+ - [ ] **<area-2>** (P2): <short description>. Source: `<audit-doc>:<line>`
16
+ - …
17
+
18
+ ## In flight
19
+
20
+ <!-- Updated by orchestrator at every wave dispatch. -->
21
+
22
+ - [~] **<area>**: assigned to pane <pane-id>, branch `<branch>`, started <iso-time>, wave <N>
23
+
24
+ ## Shipped
25
+
26
+ <!-- Updated by orchestrator at every merge. -->
27
+
28
+ - [x] **<area>**: commit `<sha>`, wave <N>, merged <iso-time>, push <iso-time>
29
+
30
+ ## Skipped / blocked
31
+
32
+ <!-- Items the campaign deliberately did NOT do. Always include reason. -->
33
+
34
+ - [skip] **<area>**: <reason>. Re-evaluate after <blocker> is resolved.
@@ -0,0 +1,40 @@
1
+ # CAMPAIGN STATE
2
+
3
+ Last update: <ISO-TIMESTAMP>
4
+ Heartbeat: `.planning/campaign/HEARTBEAT` (file mtime should be < 60s old while campaign is live)
5
+ Heartbeat PID: see `.planning/campaign/HEARTBEAT.pid`
6
+
7
+ ## TSC drift over time
8
+
9
+ | Time (UTC) | Wave | TSC errors | Delta vs baseline |
10
+ |---|---|---|---|
11
+ | <iso> (campaign start) | 0 (baseline) | <count> | 0 |
12
+ | <iso> | 1 | <count> | +/-N |
13
+ | <iso> | 2 | <count> | +/-N |
14
+
15
+ ## Wave history
16
+
17
+ ### Wave 1 — <one-line theme>
18
+ - Dispatched: <iso>
19
+ - Agents: 4 (pane labels: <Pane1, Pane2, Pane3, Pane4>)
20
+ - Branches: `<branch-1>`, `<branch-2>`, `<branch-3>`, `<branch-4>`
21
+ - Outcome:
22
+ - merged: `<branch-1>` (3 commits), `<branch-2>` (5 commits), `<branch-3>` (2 commits)
23
+ - rebase needed: `<branch-4>` (conflict on shared file)
24
+ - Pushed to origin: <iso>
25
+ - Cumulative commits: <count>
26
+
27
+ ### Wave 2 — <one-line theme>
28
+ - …
29
+
30
+ ## Active panes
31
+
32
+ | Pane | Label | Branch | Status | Last commit at |
33
+ |---|---|---|---|---|
34
+ | `<pane-id>` | <label> | `<branch>` | working/idle/done | <iso> |
35
+
36
+ ## Open questions / blockers
37
+
38
+ <!-- Things the orchestrator surfaces to the human at next opportunity. -->
39
+
40
+ - <blocker description>
@@ -0,0 +1,29 @@
1
+ #!/bin/bash
2
+ # Background heartbeat for the autonomous fix campaign.
3
+ #
4
+ # Run: bash heartbeat.sh & echo $! > .planning/campaign/HEARTBEAT.pid
5
+ # Kill: kill $(cat .planning/campaign/HEARTBEAT.pid) && rm .planning/campaign/HEARTBEAT.pid
6
+ #
7
+ # Touches .planning/campaign/HEARTBEAT every 30s with an ISO-8601 UTC timestamp.
8
+ # External watchers can monitor mtime to see the campaign is alive.
9
+ #
10
+ # This is the SECONDARY heartbeat. The PRIMARY heartbeat is ScheduleWakeup inside
11
+ # the assistant session — without ScheduleWakeup the assistant goes silent regardless
12
+ # of this bash loop.
13
+
14
+ set -euo pipefail
15
+
16
+ HEARTBEAT_DIR="${HEARTBEAT_DIR:-.planning/campaign}"
17
+ mkdir -p "$HEARTBEAT_DIR"
18
+
19
+ HEARTBEAT_FILE="$HEARTBEAT_DIR/HEARTBEAT"
20
+ INTERVAL="${HEARTBEAT_INTERVAL:-30}"
21
+
22
+ echo "[heartbeat] starting — writes to $HEARTBEAT_FILE every ${INTERVAL}s" >&2
23
+
24
+ trap 'echo "[heartbeat] received SIGTERM, exiting" >&2; exit 0' TERM INT
25
+
26
+ while true; do
27
+ date -u +%FT%TZ > "$HEARTBEAT_FILE"
28
+ sleep "$INTERVAL"
29
+ done