prodigy 0.4.4

Turn ad-hoc Claude sessions into reproducible development pipelines with parallel AI agents
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
# Git Integration

Prodigy provides deep git integration with worktree isolation, automatic commit tracking, and customizable merge workflows.

## Overview

Git integration features:
- **Worktree isolation**: Each session runs in isolated git worktree
- **Automatic commits**: Track all changes with automatic git commits
- **Commit tracking**: Full audit trail of modifications
- **Smart merging**: Customizable merge workflows with validation
- **Branch tracking**: Intelligent merge target detection

## Worktree Management

Every Prodigy session executes in an isolated git worktree:

```
~/.prodigy/worktrees/{repo_name}/
└── session-{session_id}/   # Isolated worktree for this session
```

### Benefits

- **Isolation**: Main repository remains untouched during execution
- **Parallelism**: Multiple sessions can run concurrently
- **Safety**: Failed workflows don't pollute main repo
- **Debugging**: Worktrees preserve full execution history

### Worktree Lifecycle

```mermaid
stateDiagram-v2
    [*] --> Created: Workflow Start
    Created --> Executing: Commands Run
    Executing --> Modified: Changes Made
    Modified --> Executing: More Commands
    Modified --> Completed: Workflow Done
    Completed --> MergePrompt: User Decision
    MergePrompt --> Merged: Approve Merge
    MergePrompt --> Preserved: Decline Merge
    Merged --> Cleaned: Cleanup Success
    Merged --> Orphaned: Cleanup Failed
    Cleaned --> [*]
    Orphaned --> Cleaned: Manual Cleanup
    Preserved --> [*]: Worktree Kept

    note right of Modified
        Automatic commits
        Full audit trail
    end note

    note right of Orphaned
        Registry created
        Use clean-orphaned
    end note
```

**Figure**: Worktree lifecycle showing creation, execution, merge decision, and cleanup states.

1. **Creation**: Prodigy creates worktree when workflow starts
2. **Execution**: All commands run in worktree context
3. **Changes**: Modifications committed automatically
4. **Completion**: User prompted to merge back to original branch
5. **Cleanup**: Worktree removed after successful merge

### Manual Worktree Management

```bash
# List worktrees
prodigy worktree ls

# Clean completed worktrees
prodigy worktree clean

# Force cleanup
prodigy worktree clean -f

# Clean orphaned worktrees (failed cleanup)
prodigy worktree clean-orphaned <job_id>
```

!!! tip "Worktree Hygiene"
    Regularly clean up completed worktrees with `prodigy worktree clean` to free disk space. Each worktree is a full copy of your repository, so they can accumulate quickly during development.

## Commit Tracking

Prodigy automatically creates commits for trackable changes:

### Automatic Commits

```yaml
# Source: workflows/implement.yml
- claude: "/implement-feature"
  commit_required: true  # Expect git commit from Claude

- shell: "cargo fmt"
  commit_required: true  # Create commit for formatting changes
```

When `commit_required: true` is set, Prodigy validates that a commit was created:

- **Before execution**: Captures HEAD commit SHA
- **After execution**: Compares HEAD to detect new commits
- **Validation failure**: Workflow fails with error "No changes were committed by [command]"
- **Skip validation**: Set `PRODIGY_NO_COMMIT_VALIDATION=true` to bypass (test mode only)

!!! warning "Commit Validation"
    If a command with `commit_required: true` doesn't create a commit, the workflow will fail. This prevents silent failures where expected changes weren't made. Use this for commands that should always modify files (implementations, formatting, etc.).

```rust
// Source: src/cook/workflow/executor.rs:819-824
// Get HEAD before command execution if we need to verify commits
let head_before = if !execution_flags.skip_validation
    && step.commit_required
    && !execution_flags.test_mode
{
    Some(self.get_current_head(&env.working_dir).await?)
} else {
    None
};
```

### Commit Messages

Generated commit messages include:
- Command that created the change
- Workflow context
- Session ID for traceability

## Branch Tracking

Prodigy tracks the original branch for intelligent merging:

### Original Branch Detection

```mermaid
flowchart TD
    Start[Workflow Start] --> Detect{Current<br/>Branch?}
    Detect -->|Named Branch| Capture[Capture Branch Name]
    Detect -->|Detached HEAD| Default[Use Default Branch]

    Capture --> Store[Store in Worktree State]
    Default --> Store

    Store --> Workflow[Execute Workflow]
    Workflow --> Complete[Workflow Complete]

    Complete --> MergeDecision{Merge Target<br/>Exists?}
    MergeDecision -->|Yes| MergeOriginal[Merge to Original Branch]
    MergeDecision -->|No| MergeDefault[Merge to Default Branch]

    style Capture fill:#e8f5e9
    style Default fill:#fff3e0
    style MergeOriginal fill:#e1f5ff
    style MergeDefault fill:#f3e5f5
```

**Figure**: Branch tracking logic showing how Prodigy determines merge target based on workflow start context.

When creating a worktree:
- Captures current branch name (e.g., `feature/ui-improvements`)
- Falls back to default branch for detached HEAD
- Stores in worktree state for session lifetime

### Merge Target Logic

Merge back to the tracked original branch:
```yaml
# User on feature/auth-refactor when starting workflow
# Worktree merges back to feature/auth-refactor (not main!)
```

!!! note "Smart Merge Targeting"
    Prodigy always merges back to the branch you were on when you started the workflow, not to a hardcoded main/master branch. This makes it safe to use on feature branches, release branches, or any development branch.

### Special Cases

- **Feature branches**: Merge back to exact feature branch
- **Detached HEAD**: Falls back to default branch (main/master)
- **Deleted branch**: Falls back to default branch if original deleted
- **Branch rename**: Uses branch name from worktree creation time

## Merge Workflows

Customize the merge process with validation and testing:

```yaml
# Source: workflows/implement.yml
merge:
  commands:
    - shell: "git fetch origin"
    - shell: "git merge origin/main"  # (1)!
    - shell: "cargo test"             # (2)!
    - shell: "cargo clippy"           # (3)!
    - claude: "/prodigy-merge-worktree ${merge.source_branch} ${merge.target_branch}"  # (4)!
  timeout: 600  # (5)!

1. Sync worktree with latest main branch changes before merging
2. Run full test suite to ensure nothing breaks
3. Verify code quality and catch linting issues
4. Execute the actual merge back to original branch
5. Allow 10 minutes for merge operations (adjust for large test suites)
```

!!! tip "Always Pass Both Branch Variables"
    Always use `${merge.source_branch}` and `${merge.target_branch}` when calling `/prodigy-merge-worktree`. This ensures merges go to the branch you started from, not a hardcoded main/master.

### Merge Variables

Available in merge workflows:
- `${merge.worktree}` - Worktree name being merged
- `${merge.source_branch}` - Source branch (worktree branch)
- `${merge.target_branch}` - Target branch (original branch)
- `${merge.session_id}` - Session ID for correlation

### Debugging Merge Operations

Control Claude output visibility during merge operations:

```bash
# Default: Clean output, no Claude streaming
prodigy run workflow.yml

# Verbose: Show Claude JSON streaming output
prodigy run workflow.yml -v

# Force streaming output via environment variable
PRODIGY_CLAUDE_CONSOLE_OUTPUT=true prodigy run workflow.yml
```

!!! tip "Debug Merge Failures"
    Use `-v` flag to see real-time Claude interactions during merge operations. This shows tool invocations, decision-making, and helps diagnose merge conflicts or validation failures.

### Example: Pre-Merge Validation

```yaml
merge:
  commands:
    - shell: "cargo build --release"
    - shell: "cargo test --all"
    - shell: "cargo fmt --check"
    - shell: "cargo clippy -- -D warnings"
    - claude: "/prodigy-merge-worktree ${merge.source_branch} ${merge.target_branch}"
```

### Example: Conflict Resolution

```yaml
merge:
  commands:
    - shell: "git fetch origin"
    - shell: "git merge origin/main --no-commit"
    - claude: "/resolve-conflicts"
      on_failure:
        shell: "git merge --abort"
    - shell: "git add -A"
    - shell: "git commit -m 'Merge main and resolve conflicts'"
    - claude: "/prodigy-merge-worktree ${merge.source_branch} ${merge.target_branch}"
```

## MapReduce Worktree Isolation

In MapReduce workflows, all phases execute in isolated worktrees:

```mermaid
graph TD
    Original[Original Branch<br/>feature/my-feature] --> Parent[Parent Worktree<br/>session-xxx]

    Parent --> Setup[Setup Phase<br/>Executes Here]
    Setup --> Map[Map Phase<br/>Spawn Agents]

    Map --> A1[Agent Worktree 1<br/>agent-1-item-1]
    Map --> A2[Agent Worktree 2<br/>agent-2-item-2]
    Map --> AN[Agent Worktree N<br/>agent-n-item-n]

    A1 -->|Merge Changes| Parent
    A2 -->|Merge Changes| Parent
    AN -->|Merge Changes| Parent

    Parent --> Reduce[Reduce Phase<br/>Executes Here]
    Reduce --> Prompt{User<br/>Approval}

    Prompt -->|Approve| Merge[Merge to Original]
    Prompt -->|Decline| Keep[Keep Worktree]

    Merge --> Original

    style Original fill:#e8f5e9
    style Parent fill:#e1f5ff
    style A1 fill:#fff3e0
    style A2 fill:#fff3e0
    style AN fill:#fff3e0
    style Setup fill:#f3e5f5
    style Reduce fill:#f3e5f5
```

**Figure**: MapReduce worktree hierarchy showing parent worktree for setup/reduce and child worktrees for parallel map agents.

### Isolation Guarantees

1. **Setup phase**: Executes in parent worktree
2. **Map phase**: Each agent runs in child worktree
3. **Reduce phase**: Executes in parent worktree
4. **Final merge**: Parent worktree merges back to original branch

!!! note "Complete Isolation"
    Your main repository remains completely untouched during MapReduce execution. All setup, map, and reduce operations happen in isolated worktrees. Changes only return to your original branch when you explicitly approve the merge.

### Verification

Verify main repository is clean after MapReduce:

```bash
# Check main repo (should be clean)
git status

# Check worktree has changes
cd ~/.prodigy/worktrees/{repo}/session-xxx/
git status
git log
```

## Orphaned Worktree Recovery

Handle cleanup failures gracefully:

### Orphaned Worktree Registry

When cleanup fails, worktree path is registered:
```
~/.prodigy/orphaned_worktrees/{repo_name}/{job_id}.json
```

### Cleanup Command

```bash
# List orphaned worktrees
prodigy worktree clean-orphaned <job_id>

# Dry run
prodigy worktree clean-orphaned <job_id> --dry-run

# Force cleanup
prodigy worktree clean-orphaned <job_id> --force
```

### Common Cleanup Issues

- **Permission denied**: Check directory permissions
- **Disk full**: Free up space before retry
- **Directory busy**: Close editors/processes using worktree
- **Git locks**: Wait for concurrent git operations to complete

!!! warning "Orphaned Worktrees"
    If cleanup fails, worktrees become "orphaned" but agent work is still preserved. Use `prodigy worktree clean-orphaned <job_id>` to safely remove them after resolving the underlying issue (permissions, disk space, etc.).

## Examples

### Feature Branch Workflow

```yaml
# User on feature/authentication
name: implement-auth

- claude: "/implement-auth-module"
  commit_required: true

- shell: "cargo test"
  on_failure:
    claude: "/fix-auth-tests"

# Merge back to feature/authentication (not main!)
merge:
  commands:
    - shell: "cargo test --all"
    - claude: "/prodigy-merge-worktree ${merge.source_branch} ${merge.target_branch}"
```

### Multi-Stage CI with Merge Validation

```yaml
name: comprehensive-ci

- shell: "cargo build"
  commit_required: true

- shell: "cargo test"
  on_failure:
    claude: "/debug-test-failure"
    commit_required: true

- shell: "cargo clippy"
  commit_required: true

merge:
  commands:
    - shell: "git fetch origin"
    - shell: "git merge origin/${merge.target_branch}"
      on_failure:
        claude: "/resolve-merge-conflicts"
    - shell: "cargo test --release"
    - shell: "cargo doc --no-deps"
    - claude: "/prodigy-merge-worktree ${merge.source_branch} ${merge.target_branch}"
  timeout: 900
```