pitroom 0.6.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.
- package/.claude-plugin/marketplace.json +18 -0
- package/.claude-plugin/plugin.json +22 -0
- package/.codex-plugin/plugin.json +29 -0
- package/CHANGELOG.md +85 -0
- package/LICENSE +21 -0
- package/README.md +471 -0
- package/dist/lib.mjs +1222 -0
- package/dist/pitroom.mjs +3685 -0
- package/docs/backends.md +113 -0
- package/hooks/hooks.json +28 -0
- package/hooks/session-start.mjs +42 -0
- package/package.json +60 -0
- package/skills/pitroom-brainstorming/SKILL.md +243 -0
- package/skills/pitroom-brainstorming/spec-document-reviewer-prompt.md +22 -0
- package/skills/pitroom-crew/SKILL.md +80 -0
- package/skills/pitroom-debugging/SKILL.md +287 -0
- package/skills/pitroom-debugging/condition-based-waiting-example.ts +170 -0
- package/skills/pitroom-debugging/condition-based-waiting.md +115 -0
- package/skills/pitroom-debugging/defense-in-depth.md +122 -0
- package/skills/pitroom-debugging/find-polluter.sh +72 -0
- package/skills/pitroom-debugging/root-cause-tracing.md +169 -0
- package/skills/pitroom-driven-development/SKILL.md +138 -0
- package/skills/pitroom-driven-development/implementer-prompt.md +68 -0
- package/skills/pitroom-driven-development/re-review-prompt.md +41 -0
- package/skills/pitroom-driven-development/task-reviewer-prompt.md +59 -0
- package/skills/pitroom-finishing/SKILL.md +226 -0
- package/skills/pitroom-implement/SKILL.md +42 -0
- package/skills/pitroom-receiving-review/SKILL.md +209 -0
- package/skills/pitroom-research/SKILL.md +35 -0
- package/skills/pitroom-review/SKILL.md +47 -0
- package/skills/pitroom-review/code-reviewer.md +38 -0
- package/skills/pitroom-tdd/SKILL.md +322 -0
- package/skills/pitroom-tdd/writing-good-tests.md +198 -0
- package/skills/pitroom-verification/SKILL.md +124 -0
- package/skills/pitroom-worktrees/SKILL.md +171 -0
- package/skills/pitroom-writing-plans/SKILL.md +183 -0
- package/skills/pitroom-writing-plans/plan-document-reviewer-prompt.md +23 -0
- package/skills/using-pitroom/SKILL.md +66 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Bisection script to find which test creates unwanted files/state
|
|
3
|
+
# Usage: ./find-polluter.sh <file_or_dir_to_check> <test_pattern>
|
|
4
|
+
# Example: ./find-polluter.sh '.git' 'src/**/*.test.ts'
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
if [ $# -ne 2 ]; then
|
|
9
|
+
echo "Usage: $0 <file_to_check> <test_pattern>"
|
|
10
|
+
echo "Example: $0 '.git' 'src/**/*.test.ts'"
|
|
11
|
+
exit 1
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
POLLUTION_CHECK="$1"
|
|
15
|
+
TEST_PATTERN="$2"
|
|
16
|
+
|
|
17
|
+
echo "🔍 Searching for test that creates: $POLLUTION_CHECK"
|
|
18
|
+
echo "Test pattern: $TEST_PATTERN"
|
|
19
|
+
echo ""
|
|
20
|
+
|
|
21
|
+
# Get list of test files (find . emits ./-prefixed paths, so accept the
|
|
22
|
+
# pattern written with or without a leading ./)
|
|
23
|
+
TEST_PATTERN="${TEST_PATTERN#./}"
|
|
24
|
+
# find -path can't match '**/' against zero directory levels, so a pattern
|
|
25
|
+
# like src/**/*.test.ts would skip src/top.test.ts; also try the pattern
|
|
26
|
+
# with '**/' collapsed to cover files directly under the base directory.
|
|
27
|
+
TEST_FILES=$(find . \( -path "./$TEST_PATTERN" -o -path "./${TEST_PATTERN//\*\*\//}" \) | sort -u)
|
|
28
|
+
if [ -z "$TEST_FILES" ]; then
|
|
29
|
+
TOTAL=0
|
|
30
|
+
else
|
|
31
|
+
TOTAL=$(printf '%s\n' "$TEST_FILES" | wc -l | tr -d ' ')
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
echo "Found $TOTAL test files"
|
|
35
|
+
echo ""
|
|
36
|
+
|
|
37
|
+
COUNT=0
|
|
38
|
+
for TEST_FILE in $TEST_FILES; do
|
|
39
|
+
COUNT=$((COUNT + 1))
|
|
40
|
+
|
|
41
|
+
# Skip if pollution already exists
|
|
42
|
+
if [ -e "$POLLUTION_CHECK" ]; then
|
|
43
|
+
echo "⚠️ Pollution already exists before test $COUNT/$TOTAL"
|
|
44
|
+
echo " Skipping: $TEST_FILE"
|
|
45
|
+
continue
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
echo "[$COUNT/$TOTAL] Testing: $TEST_FILE"
|
|
49
|
+
|
|
50
|
+
# Run the test
|
|
51
|
+
npm test "$TEST_FILE" > /dev/null 2>&1 || true
|
|
52
|
+
|
|
53
|
+
# Check if pollution appeared
|
|
54
|
+
if [ -e "$POLLUTION_CHECK" ]; then
|
|
55
|
+
echo ""
|
|
56
|
+
echo "🎯 FOUND POLLUTER!"
|
|
57
|
+
echo " Test: $TEST_FILE"
|
|
58
|
+
echo " Created: $POLLUTION_CHECK"
|
|
59
|
+
echo ""
|
|
60
|
+
echo "Pollution details:"
|
|
61
|
+
ls -la "$POLLUTION_CHECK"
|
|
62
|
+
echo ""
|
|
63
|
+
echo "To investigate:"
|
|
64
|
+
echo " npm test $TEST_FILE # Run just this test"
|
|
65
|
+
echo " cat $TEST_FILE # Review test code"
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
done
|
|
69
|
+
|
|
70
|
+
echo ""
|
|
71
|
+
echo "✅ No polluter found - all tests clean!"
|
|
72
|
+
exit 0
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Root Cause Tracing
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Bugs often manifest deep in the call stack (git init in wrong directory, file created in wrong location, database opened with wrong path). Your instinct is to fix where the error appears, but that's treating a symptom.
|
|
6
|
+
|
|
7
|
+
**Core principle:** Trace backward through the call chain until you find the original trigger, then fix at the source.
|
|
8
|
+
|
|
9
|
+
## When to Use
|
|
10
|
+
|
|
11
|
+
```dot
|
|
12
|
+
digraph when_to_use {
|
|
13
|
+
"Bug appears deep in stack?" [shape=diamond];
|
|
14
|
+
"Can trace backwards?" [shape=diamond];
|
|
15
|
+
"Fix at symptom point" [shape=box];
|
|
16
|
+
"Trace to original trigger" [shape=box];
|
|
17
|
+
"BETTER: Also add defense-in-depth" [shape=box];
|
|
18
|
+
|
|
19
|
+
"Bug appears deep in stack?" -> "Can trace backwards?" [label="yes"];
|
|
20
|
+
"Can trace backwards?" -> "Trace to original trigger" [label="yes"];
|
|
21
|
+
"Can trace backwards?" -> "Fix at symptom point" [label="no - dead end"];
|
|
22
|
+
"Trace to original trigger" -> "BETTER: Also add defense-in-depth";
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Use when:**
|
|
27
|
+
- Error happens deep in execution (not at entry point)
|
|
28
|
+
- Stack trace shows long call chain
|
|
29
|
+
- Unclear where invalid data originated
|
|
30
|
+
- Need to find which test/code triggers the problem
|
|
31
|
+
|
|
32
|
+
## The Tracing Process
|
|
33
|
+
|
|
34
|
+
### 1. Observe the Symptom
|
|
35
|
+
```
|
|
36
|
+
Error: git init failed in ~/project/packages/core
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. Find Immediate Cause
|
|
40
|
+
**What code directly causes this?**
|
|
41
|
+
```typescript
|
|
42
|
+
await execFileAsync('git', ['init'], { cwd: projectDir });
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 3. Ask: What Called This?
|
|
46
|
+
```typescript
|
|
47
|
+
WorktreeManager.createSessionWorktree(projectDir, sessionId)
|
|
48
|
+
→ called by Session.initializeWorkspace()
|
|
49
|
+
→ called by Session.create()
|
|
50
|
+
→ called by test at Project.create()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 4. Keep Tracing Up
|
|
54
|
+
**What value was passed?**
|
|
55
|
+
- `projectDir = ''` (empty string!)
|
|
56
|
+
- Empty string as `cwd` resolves to `process.cwd()`
|
|
57
|
+
- That's the source code directory!
|
|
58
|
+
|
|
59
|
+
### 5. Find Original Trigger
|
|
60
|
+
**Where did empty string come from?**
|
|
61
|
+
```typescript
|
|
62
|
+
const context = setupCoreTest(); // Returns { tempDir: '' }
|
|
63
|
+
Project.create('name', context.tempDir); // Accessed before beforeEach!
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Adding Stack Traces
|
|
67
|
+
|
|
68
|
+
When you can't trace manually, add instrumentation:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// Before the problematic operation
|
|
72
|
+
async function gitInit(directory: string) {
|
|
73
|
+
const stack = new Error().stack;
|
|
74
|
+
console.error('DEBUG git init:', {
|
|
75
|
+
directory,
|
|
76
|
+
cwd: process.cwd(),
|
|
77
|
+
nodeEnv: process.env.NODE_ENV,
|
|
78
|
+
stack,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
await execFileAsync('git', ['init'], { cwd: directory });
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Critical:** Use `console.error()` in tests (not logger - may not show)
|
|
86
|
+
|
|
87
|
+
**Run and capture:**
|
|
88
|
+
```bash
|
|
89
|
+
npm test 2>&1 | grep 'DEBUG git init'
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Analyze stack traces:**
|
|
93
|
+
- Look for test file names
|
|
94
|
+
- Find the line number triggering the call
|
|
95
|
+
- Identify the pattern (same test? same parameter?)
|
|
96
|
+
|
|
97
|
+
## Finding Which Test Causes Pollution
|
|
98
|
+
|
|
99
|
+
If something appears during tests but you don't know which test:
|
|
100
|
+
|
|
101
|
+
Use the bisection script `find-polluter.sh` in this directory:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
./find-polluter.sh '.git' 'src/**/*.test.ts'
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Runs tests one-by-one, stops at first polluter. See script for usage.
|
|
108
|
+
|
|
109
|
+
## Real Example: Empty projectDir
|
|
110
|
+
|
|
111
|
+
**Symptom:** `.git` created in `packages/core/` (source code)
|
|
112
|
+
|
|
113
|
+
**Trace chain:**
|
|
114
|
+
1. `git init` runs in `process.cwd()` ← empty cwd parameter
|
|
115
|
+
2. WorktreeManager called with empty projectDir
|
|
116
|
+
3. Session.create() passed empty string
|
|
117
|
+
4. Test accessed `context.tempDir` before beforeEach
|
|
118
|
+
5. setupCoreTest() returns `{ tempDir: '' }` initially
|
|
119
|
+
|
|
120
|
+
**Root cause:** Top-level variable initialization accessing empty value
|
|
121
|
+
|
|
122
|
+
**Fix:** Made tempDir a getter that throws if accessed before beforeEach
|
|
123
|
+
|
|
124
|
+
**Also added defense-in-depth:**
|
|
125
|
+
- Layer 1: Project.create() validates directory
|
|
126
|
+
- Layer 2: WorkspaceManager validates not empty
|
|
127
|
+
- Layer 3: NODE_ENV guard refuses git init outside tmpdir
|
|
128
|
+
- Layer 4: Stack trace logging before git init
|
|
129
|
+
|
|
130
|
+
## Key Principle
|
|
131
|
+
|
|
132
|
+
```dot
|
|
133
|
+
digraph principle {
|
|
134
|
+
"Found immediate cause" [shape=ellipse];
|
|
135
|
+
"Can trace one level up?" [shape=diamond];
|
|
136
|
+
"Trace backwards" [shape=box];
|
|
137
|
+
"Is this the source?" [shape=diamond];
|
|
138
|
+
"Fix at source" [shape=box];
|
|
139
|
+
"Add validation at each layer" [shape=box];
|
|
140
|
+
"Bug impossible" [shape=doublecircle];
|
|
141
|
+
"NEVER fix just the symptom" [shape=octagon, style=filled, fillcolor=red, fontcolor=white];
|
|
142
|
+
|
|
143
|
+
"Found immediate cause" -> "Can trace one level up?";
|
|
144
|
+
"Can trace one level up?" -> "Trace backwards" [label="yes"];
|
|
145
|
+
"Can trace one level up?" -> "NEVER fix just the symptom" [label="no"];
|
|
146
|
+
"Trace backwards" -> "Is this the source?";
|
|
147
|
+
"Is this the source?" -> "Trace backwards" [label="no - keeps going"];
|
|
148
|
+
"Is this the source?" -> "Fix at source" [label="yes"];
|
|
149
|
+
"Fix at source" -> "Add validation at each layer";
|
|
150
|
+
"Add validation at each layer" -> "Bug impossible";
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**NEVER fix just where the error appears.** Trace back to find the original trigger.
|
|
155
|
+
|
|
156
|
+
## Stack Trace Tips
|
|
157
|
+
|
|
158
|
+
**In tests:** Use `console.error()` not logger - logger may be suppressed
|
|
159
|
+
**Before operation:** Log before the dangerous operation, not after it fails
|
|
160
|
+
**Include context:** Directory, cwd, environment variables, timestamps
|
|
161
|
+
**Capture stack:** `new Error().stack` shows complete call chain
|
|
162
|
+
|
|
163
|
+
## Real-World Impact
|
|
164
|
+
|
|
165
|
+
From debugging session (2025-10-03):
|
|
166
|
+
- Found root cause through 5-level trace
|
|
167
|
+
- Fixed at source (getter validation)
|
|
168
|
+
- Added 4 layers of defense
|
|
169
|
+
- 1847 tests passed, zero pollution
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pitroom-driven-development
|
|
3
|
+
description: Use when executing a written implementation plan - each task goes to a Pitroom worker in an isolated copy, a worker on another model reviews it, and you rule, apply and commit between tasks.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pitroom-Driven Development
|
|
7
|
+
|
|
8
|
+
Execute a plan by giving each task to a fresh implementer worker in an isolated copy, a task review (spec compliance and code quality) by a worker on another model after each, and a whole-branch review at the end. You are the controller: you never write a task's code yourself; you rule on conflicts, apply patches and commit.
|
|
9
|
+
|
|
10
|
+
**Why workers:** each gets exactly its task (Pitroom extracts it from the plan) and none of your conversation. Their tokens are cheap and your context stays free for coordination. A reviewer on a different backend is a second model, not the implementer grading itself.
|
|
11
|
+
|
|
12
|
+
**Core principle:** fresh worker per task + task review on another model + whole-branch review = high quality at worker prices.
|
|
13
|
+
|
|
14
|
+
**Narration:** between tool calls, at most one short line. `pitroom plan status` and the tool results carry the record.
|
|
15
|
+
|
|
16
|
+
**Continuous execution:** do not pause to check in with your human partner between tasks. The only reasons to stop are the four below, or all tasks complete. "Should I continue?" prompts waste their time: they asked you to execute the plan.
|
|
17
|
+
|
|
18
|
+
**Rulings, not stalls.** Conflicts, ambiguities, plan defects, a cap you would have asked to exceed: decide them. The spec is the binding authority, the plan is its argument, and your judgment settles what neither answers. Record every decision with `pitroom plan note PLAN "Task N: Ruling: <what you decided> — <why> — <what it costs if wrong>"` and keep going. A wrong ruling costs rework your human partner can see and undo; a session parked on a question costs their whole day.
|
|
19
|
+
|
|
20
|
+
Four things stop you, and only these: an irreversible or destructive operation; a security-sensitive action; a side effect outside this branch that norms say you ask about first (a merge, a push, a publish); a plan so broken that every path forward is a guess.
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
1. **Branch:** `pitroom-worktrees`. Never implement on main/master without explicit consent.
|
|
25
|
+
2. **Where are we:** `pitroom plan status PLAN`. A task with a `Task N: complete` note is done: never re-dispatch it. A task with runs but no completion note is mid-loop: continue it from its last run and review. After compaction, trust `pitroom plan status` and `git log` over your memory.
|
|
26
|
+
3. **Read the plan once**, and its Spec. Note the Global Constraints. Create a todo per task.
|
|
27
|
+
4. **Pre-flight scan**, before Task 1. Its output is a table, not a verdict: one row for every pair of tasks that share a file or an interface (what one produces against what the other consumes), one row per task on whether its own text agrees with itself (its tests against its code, the files it creates against the files it later touches), and anything the plan mandates that the review rubric treats as a defect (a test that asserts nothing, duplicated logic). Rule on every finding and note the rulings. The table also tells you which tasks are independent (see Parallel tasks).
|
|
28
|
+
5. **Worker setup:** tasks that run the project's tests need its dependencies inside the isolated copy: pass `--link node_modules` (or `.venv`, …) or set `link` in the config.
|
|
29
|
+
|
|
30
|
+
## Tiers
|
|
31
|
+
|
|
32
|
+
Every task names a tier (`**Worker:** cheap|standard|capable`), and `pitroom run --plan` uses it. The config maps tiers to workers (`pitroom config` shows `tiers`); an unconfigured tier falls back to the default worker with a warning. Escalating means the next tier up: cheap → standard → capable. Above capable is you, and you only rule; you do not write the code.
|
|
33
|
+
|
|
34
|
+
## The task loop
|
|
35
|
+
|
|
36
|
+
### 1. Implement
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pitroom run -i --plan PLAN --step N --link node_modules --verify "<the task's test command>" --bg \
|
|
40
|
+
"<optional notes: interfaces or decisions from earlier tasks the brief cannot know, your resolution of an ambiguity>"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Pitroom gives the worker the implementer rules, the plan's context and Global Constraints, and Task N's text; never paste plan text yourself. The run joins the plan's group: follow it with `pitroom watch -g <plan name> --json` or `pitroom wait <run>`.
|
|
44
|
+
|
|
45
|
+
### 2. Handle the status
|
|
46
|
+
|
|
47
|
+
The report starts with `plan: … · STATUS <value>`:
|
|
48
|
+
|
|
49
|
+
- **DONE:** review it (step 3).
|
|
50
|
+
- **DONE_WITH_CONCERNS:** read OPEN ISSUES. Doubts about correctness or scope: resolve them first with `pitroom run --continue <run> "<guidance>"`. Observations: note them and review.
|
|
51
|
+
- **NEEDS_CONTEXT:** `pitroom run --continue <run> "<the missing context>"`.
|
|
52
|
+
- **BLOCKED:** a context problem → `--continue` with context; it needs more reasoning → a fresh run one tier up (`--tier`); too large → split it and note the ruling; the plan is wrong → rule, note, and re-dispatch with the ruling in the notes.
|
|
53
|
+
- **unknown** (no status line): treat it as DONE_WITH_CONCERNS.
|
|
54
|
+
|
|
55
|
+
Never make the same worker retry without changing something. A failing `verify:` line is a finding for the fix loop, not a reason to fix it yourself.
|
|
56
|
+
|
|
57
|
+
### 3. Review
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pitroom review <run>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
A read-only worker on another backend gets one package: the brief, the implementer's report and the diff with context. It returns `SPEC PASS|FAIL`, `QUALITY APPROVED|NEEDS-FIXES` and the issues by severity. Never skip it, and never accept a review that lacks either verdict; the implementer's self-review never replaces it.
|
|
64
|
+
|
|
65
|
+
- Don't pre-judge: never tell a reviewer to ignore something. A finding you think is a false positive enters the loop; you adjudicate at the cap.
|
|
66
|
+
- CANNOT VERIFY items (requirements in unchanged code or across tasks): check each yourself before completing the task. A real gap is a failed spec review.
|
|
67
|
+
|
|
68
|
+
### 4. The fix loop
|
|
69
|
+
|
|
70
|
+
It triggers on SPEC FAIL, any Critical or Important finding, or a CANNOT VERIFY item you confirmed. Minor findings never enter the loop: note them (`pitroom plan note PLAN "Task N: minor (deferred): …"`) for the final review. A finding that conflicts with the plan's text is yours to rule on first (the spec wins), noted before you act.
|
|
71
|
+
|
|
72
|
+
A round is one fix plus one scoped re-review. Five rounds at most per task:
|
|
73
|
+
|
|
74
|
+
- **Rounds 1-3:** `pitroom run --continue <last run> "<the open findings, verbatim>"` (same session, same isolated copy), then `pitroom review <fix run>`. Pitroom sees a fix round and sends only its diff and the previous findings.
|
|
75
|
+
- **Rounds 4-5:** a fresh implementer one tier up: `pitroom run -i --plan PLAN --step N --tier <next> "A prior worker attempted this task <R> times; you own it now. Open findings: …"`, `pitroom discard <old run>`, then `pitroom review <new run>`.
|
|
76
|
+
- After each round: `pitroom plan note PLAN "Task N: fix round R/5 (X addressed, Y open — <one-liners>)"`.
|
|
77
|
+
|
|
78
|
+
Never fix findings yourself: controller fixes skip review.
|
|
79
|
+
|
|
80
|
+
**The breaker.** When round 5 still leaves findings open, stop and adjudicate each one:
|
|
81
|
+
- The reviewer is wrong, or the point is contestable: park it — `Task N: parked — <finding> — Ruling: <why the code stands>`.
|
|
82
|
+
- Real, but nothing downstream builds on it: park it the same way, saying it is real and deferred.
|
|
83
|
+
- Real and load-bearing: rule on the smallest change that unblocks the dependent work, note it, and carry it into the next task's notes. Stop only if every path forward is a guess.
|
|
84
|
+
|
|
85
|
+
Adjudicate only at the cap; every adjudication is a note. A silent discard is forbidden.
|
|
86
|
+
|
|
87
|
+
### 5. Land the task
|
|
88
|
+
|
|
89
|
+
When the review is clean, or every open finding is parked with a ruling at the cap:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pitroom apply <last run> # checked apply; refuses on conflict
|
|
93
|
+
<the task's tests, run by you>
|
|
94
|
+
git add <the task's files> && git commit -m "<the plan's commit message>"
|
|
95
|
+
pitroom plan note PLAN "Task N: complete (<base7>..<head7>, review clean)"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Mark the todo complete and move on. Never start a dependent task before this one is applied: its isolated copy is taken from your tree.
|
|
99
|
+
|
|
100
|
+
## Parallel tasks
|
|
101
|
+
|
|
102
|
+
Tasks the pre-flight table shows as independent (no shared file, no interface between them) may run at once: start each with `pitroom run -i --plan PLAN --step N --bg` (they share the plan's group), watch them with `pitroom watch -g <plan name> --json`, review each, then apply and commit them one at a time in plan order. When `pitroom apply` refuses a patch, look at what conflicts. If only generated files differ (such as a rebuilt `dist/`), apply the rest of the patch and rebuild them. If source hunks conflict, do not drop them: run the task again from the current tree with the conflict in its notes and review that run as usual, or resolve every hunk by hand and review the result with `pitroom review --range` before you commit. Everything that shares a file runs in sequence.
|
|
103
|
+
|
|
104
|
+
## Waiting
|
|
105
|
+
|
|
106
|
+
Never poll with short sleeps, and never sit in one silent, open-ended wait. While workers run, do your own bookkeeping: rulings, reading reports, the next task's notes. When idle, `pitroom wait <run> --timeout 540`; exit 75 means still running: post one line of status and call it again. `pitroom stop <run>` a worker that is clearly stuck, and redo its task.
|
|
107
|
+
|
|
108
|
+
## Final review
|
|
109
|
+
|
|
110
|
+
After the last task:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pitroom review --range "$(git merge-base <base> HEAD)..HEAD" --plan PLAN
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
It runs on the `capable` tier with the whole-branch rubric, and the package carries the plan and your notes, so the reviewer triages the deferred minors and parked findings. If it returns findings: ONE fix run with the complete list, not one run per finding (`pitroom run -i --tier capable --link node_modules "<all findings>"`), exactly one review of that fix (`pitroom review <fix run>`), then apply, test and commit. Adjudicate the residual findings as in the breaker. There is no second fix wave: residual load-bearing findings go to your human partner through `pitroom-finishing`.
|
|
117
|
+
|
|
118
|
+
## Finish
|
|
119
|
+
|
|
120
|
+
Collect every note containing `Ruling:` (`pitroom plan status PLAN` lists them) into your final message under "Rulings I made", in the order you made them, each with what it costs if wrong. The list is exhaustive: it is the only place the decisions you took on your human partner's behalf reach them. Then use `pitroom-finishing`.
|
|
121
|
+
|
|
122
|
+
## Inline execution
|
|
123
|
+
|
|
124
|
+
When Pitroom is unavailable or your human partner chose inline execution: execute the tasks yourself, in order, following each step exactly and running every verification the plan specifies, with `pitroom-tdd` and `pitroom-verification`. Stop and ask when blocked (a missing dependency, a failing test, an unclear instruction); don't guess. Review the branch with `pitroom-review` when Pitroom is available, then use `pitroom-finishing`.
|
|
125
|
+
|
|
126
|
+
## Common rationalizations
|
|
127
|
+
|
|
128
|
+
| Excuse | Reality |
|
|
129
|
+
|---|---|
|
|
130
|
+
| "Close enough on spec compliance" | A spec gap is not done. Fix it, or reach the cap and adjudicate. |
|
|
131
|
+
| "I'll fix it myself, dispatching is overhead" | Controller fixes skip review and fill your context. Continue the worker. |
|
|
132
|
+
| "One more round will converge" | Past the cap, rounds don't converge: the failure is structural. Adjudicate. |
|
|
133
|
+
| "The reviewer will just find something new anyway" | Fix-round reviews see only the fix diff; they cannot wander. |
|
|
134
|
+
| "This finding is obviously wrong, I'll drop it" | You adjudicate only at the cap, and every ruling is a note. |
|
|
135
|
+
| "The fix was small, skip the re-review" | Unreviewed fixes are how regressions land. |
|
|
136
|
+
| "The same model can review its own work" | `pitroom review` picks another backend when one is configured; configure `tiers` if it can't. |
|
|
137
|
+
| "Notes are overhead" | Notes and run records are what survive compaction. Controllers without them re-dispatch finished tasks. |
|
|
138
|
+
| "The worker said the tests pass" | Run them after applying. `pitroom-verification` |
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Implementer brief for `pitroom run -i --plan PLAN --step N`. Pitroom fills the
|
|
3
|
+
placeholders and wraps the result in its worker contract (rules + answer format).
|
|
4
|
+
-->
|
|
5
|
+
You are implementing Task {{STEP}}: {{TITLE}} of the plan {{PLAN_FILE}}.
|
|
6
|
+
|
|
7
|
+
## Your brief
|
|
8
|
+
|
|
9
|
+
This is your requirements document, with the exact values to use verbatim. Other workers handle the plan's other tasks; do only this one.
|
|
10
|
+
|
|
11
|
+
<brief>
|
|
12
|
+
{{BRIEF}}
|
|
13
|
+
</brief>
|
|
14
|
+
|
|
15
|
+
## Notes from the primary agent
|
|
16
|
+
|
|
17
|
+
{{NOTES}}
|
|
18
|
+
|
|
19
|
+
## Your job
|
|
20
|
+
|
|
21
|
+
1. Implement exactly what the task specifies: nothing more (YAGNI), nothing less.
|
|
22
|
+
2. Write the tests the task specifies. When the task says to use TDD: write the failing test, run it and watch it fail for the expected reason, write the minimal code, run it and watch it pass.
|
|
23
|
+
3. While iterating, run the focused test for what you are changing; run the full relevant suite once before you answer.
|
|
24
|
+
4. Self-review (below), fix what you find, then answer.
|
|
25
|
+
|
|
26
|
+
The brief may contain commit steps. You never commit: skip them. The primary agent reviews your diff, applies it and commits.
|
|
27
|
+
|
|
28
|
+
## You work alone
|
|
29
|
+
|
|
30
|
+
Do all of this task's work yourself. Never delegate, never start other agents or `pitroom`, and never ask for a review: a reviewer on another model is already scheduled for your diff.
|
|
31
|
+
|
|
32
|
+
## Code organization
|
|
33
|
+
|
|
34
|
+
- Follow the file structure defined in the plan. Each file has one clear responsibility and a well-defined interface.
|
|
35
|
+
- If a file you create grows beyond the plan's intent, stop and answer DONE_WITH_CONCERNS; do not split files on your own.
|
|
36
|
+
- In existing code, follow the established patterns. Improve code you touch the way a good developer would; do not restructure anything outside your task.
|
|
37
|
+
|
|
38
|
+
## When you are in over your head
|
|
39
|
+
|
|
40
|
+
It is always fine to stop and say "this is too hard for me". Bad work is worse than no work. Answer BLOCKED or NEEDS_CONTEXT when:
|
|
41
|
+
- the task needs an architectural decision with several valid approaches,
|
|
42
|
+
- you need to understand code beyond what was provided and cannot find clarity,
|
|
43
|
+
- you are unsure your approach is correct,
|
|
44
|
+
- the task means restructuring code in ways the plan did not anticipate,
|
|
45
|
+
- you keep reading file after file without making progress.
|
|
46
|
+
|
|
47
|
+
Say specifically what you are stuck on, what you tried and what would unblock you. The primary agent can add context, give the task to a more capable worker, or split it.
|
|
48
|
+
|
|
49
|
+
## Self-review before answering
|
|
50
|
+
|
|
51
|
+
- Completeness: every requirement in the brief implemented? Edge cases?
|
|
52
|
+
- Quality: clear names (what things do, not how), clean and maintainable?
|
|
53
|
+
- Discipline: only what was requested, following the codebase's patterns?
|
|
54
|
+
- Testing: do the tests verify real behaviour, not mocks? Is the test output pristine (no warnings or noise)?
|
|
55
|
+
|
|
56
|
+
Fix what you find before answering.
|
|
57
|
+
|
|
58
|
+
## Answer
|
|
59
|
+
|
|
60
|
+
Start your answer with one status line:
|
|
61
|
+
|
|
62
|
+
STATUS: DONE | DONE_WITH_CONCERNS | NEEDS_CONTEXT | BLOCKED
|
|
63
|
+
|
|
64
|
+
Then the usual answer format. In VERIFICATION give the commands you ran and their results; when the task required TDD add TDD EVIDENCE: the RED command with the relevant failing output (and why that failure was expected), then the GREEN command with the passing output. Put doubts about correctness (DONE_WITH_CONCERNS) and the specifics of BLOCKED or NEEDS_CONTEXT in OPEN ISSUES. Never silently hand over work you are unsure about.
|
|
65
|
+
|
|
66
|
+
## If you are resumed with review findings
|
|
67
|
+
|
|
68
|
+
Fix them, re-run the tests that cover the changed code, and answer again in the same format with a FIX REPORT in DETAILS: each finding, what you changed (file:line), the covering tests, the command and its output. Reviewers do not re-run tests; your answer is the evidence.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Scoped re-review for `pitroom review <fix run>` (a follow-up of a run that was
|
|
3
|
+
already reviewed). Pitroom writes the package and fills {{PACKAGE_FILE}}.
|
|
4
|
+
-->
|
|
5
|
+
You are re-reviewing one task's fix round. A previous review produced findings; the implementer has attempted to fix them. Your job is a verdict on each finding and an inspection of the fix diff, nothing else.
|
|
6
|
+
|
|
7
|
+
## What to read
|
|
8
|
+
|
|
9
|
+
One file holds everything; read it once: {{PACKAGE_FILE}}
|
|
10
|
+
It contains, in order:
|
|
11
|
+
1. BRIEF: the task that was requested.
|
|
12
|
+
2. PREVIOUS FINDINGS: the previous review; its Critical and Important findings and spec gaps are under verification.
|
|
13
|
+
3. FIX REPORT: what the implementer says it changed, with the tests it re-ran.
|
|
14
|
+
4. FIX DIFF: only this fix round's changes, with 10 lines of context.
|
|
15
|
+
|
|
16
|
+
Your working directory contains the code after the fix. You are read-only: do not change files, the index, HEAD or branches.
|
|
17
|
+
|
|
18
|
+
## You work alone
|
|
19
|
+
|
|
20
|
+
Do the whole re-review yourself. Never delegate or start other agents.
|
|
21
|
+
|
|
22
|
+
## Scope
|
|
23
|
+
|
|
24
|
+
Your scope is the previous findings and the fix diff. Give a verdict on every Critical and Important finding and every spec gap. Inspect the fix diff for problems the fix itself introduced. Do not re-review code the fix did not touch: an issue entirely outside the fix diff goes under OUT OF SCOPE and does not block the task; a whole-branch review happens after all tasks.
|
|
25
|
+
|
|
26
|
+
## Tests
|
|
27
|
+
|
|
28
|
+
The fix report is unverified claims: check that it names the covering tests and shows their output, and verify its claims against the diff. Do not re-run the suite. Run a focused test only when the code raises a specific doubt that no existing run answers.
|
|
29
|
+
|
|
30
|
+
## Answer
|
|
31
|
+
|
|
32
|
+
Your SUMMARY is exactly one line:
|
|
33
|
+
SUMMARY: SPEC: PASS|FAIL · QUALITY: APPROVED|NEEDS_FIXES · ISSUES: critical=N important=N minor=N
|
|
34
|
+
|
|
35
|
+
SPEC is PASS only when every finding under verification is ADDRESSED. QUALITY is NEEDS_FIXES when the fix diff introduced any Critical or Important problem. ISSUES counts the findings still open plus the new problems, by severity.
|
|
36
|
+
|
|
37
|
+
In DETAILS, in this order:
|
|
38
|
+
- FINDING VERDICTS: for each finding, in order, the finding in one line, then ADDRESSED or NOT ADDRESSED with file:line evidence. "Attempted" is not addressed: the specific defect must no longer exist.
|
|
39
|
+
- NEW BREAKAGE: problems the fix introduced, with severity and file:line, or "none".
|
|
40
|
+
- OUT OF SCOPE: issues entirely outside the fix diff, or "none".
|
|
41
|
+
A file:line is the project file's path and its line number after the change (from the diff's hunk headers), never a line of the package file. No preamble and no closing summary.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Task review for `pitroom review <run>`. Pitroom writes the review package, fills
|
|
3
|
+
{{PACKAGE_FILE}} and runs this read-only, by default on another worker.
|
|
4
|
+
-->
|
|
5
|
+
You are reviewing one task's implementation: first whether it matches its requirements, then whether it is well built. This is a task-scoped gate, not a merge review; a whole-branch review happens after all tasks.
|
|
6
|
+
|
|
7
|
+
## What to read
|
|
8
|
+
|
|
9
|
+
One file holds everything; read it once: {{PACKAGE_FILE}}
|
|
10
|
+
It contains, in order:
|
|
11
|
+
1. BRIEF: what was requested (for a plan task: the plan's context, its global constraints and the task).
|
|
12
|
+
2. REPORT: what the implementer claims it built, with its test evidence.
|
|
13
|
+
3. DIFF: the change under review, with 10 lines of context.
|
|
14
|
+
|
|
15
|
+
Your working directory contains the code after this change. The diff's context lines are your view of the changed files: open a changed file only when a hunk you must judge is cut off mid-function, and say so. Do not crawl the codebase: look outside the diff only to check a concrete risk you can name (a changed contract, lock order, shared mutable state: then check its call sites), one focused check per named risk, and name both the risk and the check.
|
|
16
|
+
|
|
17
|
+
You are read-only: do not change files, the index, HEAD or branches.
|
|
18
|
+
|
|
19
|
+
## You work alone
|
|
20
|
+
|
|
21
|
+
Do the whole review yourself. Never delegate or start other agents. If the diff is large, review it in passes and say so.
|
|
22
|
+
|
|
23
|
+
## Do not trust the report
|
|
24
|
+
|
|
25
|
+
The report is unverified claims: verify them against the diff. Design rationales in the report ("kept it simple per YAGNI") are the implementer grading its own work; judge the code on its merits. A stated rationale never lowers a finding's severity.
|
|
26
|
+
|
|
27
|
+
## Tests
|
|
28
|
+
|
|
29
|
+
The implementer ran the tests and reported the results. Do not re-run the suite to confirm them. Run a test only when the code raises a specific doubt that no existing run answers, and then only a focused test. Warnings or noise in the reported test output are findings. If the evidence is missing or garbled in the package, report that as a gap; do not regenerate it.
|
|
30
|
+
|
|
31
|
+
## Part 1: Spec compliance
|
|
32
|
+
|
|
33
|
+
Compare the diff with the brief:
|
|
34
|
+
- Missing: requirements skipped, or claimed without being implemented.
|
|
35
|
+
- Extra: features that were not requested, over-engineering.
|
|
36
|
+
- Misunderstood: the right feature built the wrong way, or the wrong problem solved.
|
|
37
|
+
|
|
38
|
+
If the brief lists several files each with its own change, check that every listed file has its hunk; a listed file the diff never touches is Missing. A requirement you cannot verify from this diff (it lives in unchanged code or spans tasks) is a CANNOT VERIFY item, not a reason to search wider.
|
|
39
|
+
|
|
40
|
+
## Part 2: Code quality
|
|
41
|
+
|
|
42
|
+
- Separation of concerns, error handling, DRY without premature abstraction, edge cases.
|
|
43
|
+
- Tests verify real behaviour (not mocks) and cover the task's edge cases.
|
|
44
|
+
- Each file has one clear responsibility; the plan's file structure is followed; the change does not create files that are already large or grow existing files much (pre-existing size is not a finding).
|
|
45
|
+
|
|
46
|
+
Cite file:line for every finding, and for every check you would otherwise answer with a bare "yes". A file:line is the project file's path and its line number after the change (from the diff's hunk headers), never a line of the package file.
|
|
47
|
+
|
|
48
|
+
## Calibration
|
|
49
|
+
|
|
50
|
+
Critical: breaks behaviour, loses data, security. Important: the task cannot be trusted until it is fixed (incorrect or fragile behaviour, a missed requirement, verbatim duplication of logic, swallowed errors, tests that assert nothing). Coverage that could be broader and polish are Minor. If the plan explicitly mandates something this rubric calls a defect, report it as Important and label it plan-mandated: the human decides. Say what was done well before listing issues.
|
|
51
|
+
|
|
52
|
+
## Answer
|
|
53
|
+
|
|
54
|
+
Your SUMMARY is exactly one line:
|
|
55
|
+
SUMMARY: SPEC: PASS|FAIL · QUALITY: APPROVED|NEEDS_FIXES · ISSUES: critical=N important=N minor=N
|
|
56
|
+
|
|
57
|
+
SPEC is FAIL when anything is Missing, Extra or Misunderstood. QUALITY is NEEDS_FIXES when there is any Critical or Important issue.
|
|
58
|
+
|
|
59
|
+
In DETAILS, in this order: SPEC FINDINGS (or "none"), CANNOT VERIFY (what the primary should check, or "none"), STRENGTHS, then CRITICAL, IMPORTANT and MINOR issues, each with file:line, what is wrong, why it matters and how to fix it if not obvious. No preamble and no closing summary.
|