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.
Files changed (38) hide show
  1. package/.claude-plugin/marketplace.json +18 -0
  2. package/.claude-plugin/plugin.json +22 -0
  3. package/.codex-plugin/plugin.json +29 -0
  4. package/CHANGELOG.md +85 -0
  5. package/LICENSE +21 -0
  6. package/README.md +471 -0
  7. package/dist/lib.mjs +1222 -0
  8. package/dist/pitroom.mjs +3685 -0
  9. package/docs/backends.md +113 -0
  10. package/hooks/hooks.json +28 -0
  11. package/hooks/session-start.mjs +42 -0
  12. package/package.json +60 -0
  13. package/skills/pitroom-brainstorming/SKILL.md +243 -0
  14. package/skills/pitroom-brainstorming/spec-document-reviewer-prompt.md +22 -0
  15. package/skills/pitroom-crew/SKILL.md +80 -0
  16. package/skills/pitroom-debugging/SKILL.md +287 -0
  17. package/skills/pitroom-debugging/condition-based-waiting-example.ts +170 -0
  18. package/skills/pitroom-debugging/condition-based-waiting.md +115 -0
  19. package/skills/pitroom-debugging/defense-in-depth.md +122 -0
  20. package/skills/pitroom-debugging/find-polluter.sh +72 -0
  21. package/skills/pitroom-debugging/root-cause-tracing.md +169 -0
  22. package/skills/pitroom-driven-development/SKILL.md +138 -0
  23. package/skills/pitroom-driven-development/implementer-prompt.md +68 -0
  24. package/skills/pitroom-driven-development/re-review-prompt.md +41 -0
  25. package/skills/pitroom-driven-development/task-reviewer-prompt.md +59 -0
  26. package/skills/pitroom-finishing/SKILL.md +226 -0
  27. package/skills/pitroom-implement/SKILL.md +42 -0
  28. package/skills/pitroom-receiving-review/SKILL.md +209 -0
  29. package/skills/pitroom-research/SKILL.md +35 -0
  30. package/skills/pitroom-review/SKILL.md +47 -0
  31. package/skills/pitroom-review/code-reviewer.md +38 -0
  32. package/skills/pitroom-tdd/SKILL.md +322 -0
  33. package/skills/pitroom-tdd/writing-good-tests.md +198 -0
  34. package/skills/pitroom-verification/SKILL.md +124 -0
  35. package/skills/pitroom-worktrees/SKILL.md +171 -0
  36. package/skills/pitroom-writing-plans/SKILL.md +183 -0
  37. package/skills/pitroom-writing-plans/plan-document-reviewer-prompt.md +23 -0
  38. package/skills/using-pitroom/SKILL.md +66 -0
@@ -0,0 +1,113 @@
1
+ # Worker backends
2
+
3
+ Pitroom's core does everything that must be true for every worker: closed stdin,
4
+ the git guard on `PATH`, recursion guard, timeouts and signals, snapshots and
5
+ isolated copies, exact change tracking, reference verification, receipts and
6
+ the fallback chain. A **backend** only translates between Pitroom and one worker
7
+ CLI. That keeps adapters small (OpenCode is ~150 lines) and makes it impossible
8
+ for a new adapter to skip a safeguard.
9
+
10
+ ```
11
+ src/
12
+ backends/
13
+ types.ts the Backend contract and shared types
14
+ index.ts registry
15
+ opencode/ the reference adapter
16
+ index.ts invocation, failure classification, models, doctor
17
+ events.ts `--format json` stream → ParsedRun
18
+ profiles.ts read / write permission profiles
19
+ core/ lifecycle, process runner, prompt, refs, receipts, report
20
+ vcs/ git snapshots, isolated copies, git guard
21
+ ```
22
+
23
+ ## The contract
24
+
25
+ ```ts
26
+ interface Backend {
27
+ id: string; // "opencode", used in targets: "opencode:provider/model"
28
+ name: string;
29
+ capabilities: {
30
+ readOnly: 'permission-rules' | 'os-sandbox' | 'tool-allowlist' | 'approval-mode';
31
+ resume: 'by-id' | 'none';
32
+ reportsCost: boolean;
33
+ attachFiles: boolean;
34
+ };
35
+ binary(): string; // PITROOM_<ID>_BIN > PATH > known install path
36
+ invocation(req: WorkerRequest): Invocation; // pure
37
+ parse(stdout: string): ParsedRun; // pure, tolerant of a torn last line
38
+ failure(run, stderr, exitCode): Failure | undefined; // kind drives the fallback chain
39
+ defaultModel?(): string | undefined;
40
+ resolveModel?(sessionId: string): string | undefined;
41
+ listModels?(): string[];
42
+ doctor(ctx): DoctorCheck[];
43
+ }
44
+ ```
45
+
46
+ `failure().kind` is `model-unavailable`, `rate-limited`, `auth` or `other`. Anything
47
+ but `other`, when the worker did no work, makes the core try the next target.
48
+
49
+ ## Mapping Pitroom's modes
50
+
51
+ The core decides the mode; the adapter must make the CLI enforce it with the
52
+ CLI's **own** mechanism, and never with flags that switch safety off
53
+ (`--yolo`, `--dangerously-*`, `bypassPermissions`, `danger-full-access`,
54
+ `--auto`): the contract tests reject them.
55
+
56
+ | | read | write / isolate | resume | cost |
57
+ |---|---|---|---|---|
58
+ | **OpenCode v2** (`run --standalone --format json`) | permission profile: edit denied, shell allowlist, `execute` and web off | profile: edits on, history-changing git, bulk deletes and `execute` denied | `--session <id>` | reported |
59
+ | **Codex** (`exec --json --ignore-user-config`) | `-c sandbox_mode="read-only"` (OS sandbox) | `-c sandbox_mode="workspace-write"` (writes only in the working dir, no network), `approval_policy="never"` | `exec resume <id>` | tokens only |
60
+ | **Claude Code** (`-p --output-format stream-json --verbose`) | `--safe-mode --restricted --strict-mcp-config`, `--permission-mode dontAsk`, tools `Read,Grep,Glob` only | same lockdown, tools `+Edit,Write,Bash`, `--disallowedTools Bash(git commit:*)`… | `--resume <id>` | `total_cost_usd` |
61
+ | **Gemini CLI** (soon; `-p -o stream-json`) | `--approval-mode plan` | `auto_edit` + policy engine rules | index/latest only → `resume: 'none'` | tokens only |
62
+
63
+ Whatever the CLI, the core still applies the git guard, closes stdin (Codex and
64
+ Gemini otherwise read piped stdin into the prompt), sets `PWD` to the worker's
65
+ directory, snapshots the tree and verifies references. `--isolate` runs in a
66
+ standalone repository that reads the user's objects through `alternates`
67
+ (not a `git worktree`), so no CLI can map it back to the user's checkout.
68
+
69
+ ## OpenCode v2 notes
70
+
71
+ The OpenCode adapter targets OpenCode v2 (`doctor` fails on v1). What changed from v1, and why the adapter looks the way it does:
72
+
73
+ - **`--standalone` is a safety requirement.** A plain `opencode run` attaches to OpenCode's shared background service, which was started with its own environment. The per-run permission profile (`OPENCODE_CONFIG_CONTENT`), the git guard on `PATH` and `PITROOM_ACTIVE` would then never reach the worker. With `--standalone` each run gets a private server that inherits them; the contract tests assert the flag for every mode.
74
+ - **No `--dir`, and `$PWD` wins.** v2 takes its workspace from `$PWD`, not the process working directory. The core's process runner sets `PWD` to the worker's directory for every CLI; without it a worker started in an isolated copy edited the directory pitroom was launched from (found in a real crew run; the mock now reproduces it and the isolate tests fail without the fix).
75
+ - **Permissions**: v2 calls the shell tool `shell` (v1: `bash`); profiles set both keys to the same rules. The new `execute` tool reaches namespaced tools (browser automation, the OpenCode API itself) and is denied in both modes. `write`/`edit` take `path`.
76
+ - **Events**: `step_finish.tokens` has no `total` (summed from its parts); errors are `{type, message, status}`; a refused tool reports `Permission denied: <tool>`.
77
+ - **Models and sessions**: `debug config` lists config sources (the model is `{providerID, model}`), sessions are exported with `session export`, and model ids accept a `#variant` suffix.
78
+ - **Free tier**: OpenCode Zen free models can answer `403 FreeTierError` ("free tier can only be used from within OpenCode"). It is classified as `auth`, so the fallback chain moves on.
79
+ - **Auto-update**: workers run with `OPENCODE_DISABLE_AUTOUPDATE=1`, so a run never upgrades OpenCode underneath the user.
80
+
81
+ Recorded v2 streams live in `test/fixtures/opencode/{events,failures}/v2-*`; the v1 ones stay as parser regression tests.
82
+
83
+ ## Codex notes
84
+
85
+ - **`--ignore-user-config`.** `~/.codex/config.toml` can define MCP servers, which run outside Codex's sandbox and could have side effects in a read-only run, and profiles that loosen the sandbox. Disabling servers one by one is not reliable (`-c mcp_servers.<name>.enabled=false` breaks on names containing dots or spaces), so workers ignore the file; auth still works. The model is the target's, or Codex's built-in default; `#effort` sets the reasoning effort (`codex:gpt-5.6-sol#low`, `codex:#low`).
86
+ - **Resume takes no `-s`/`-C`**, so the sandbox always goes through `-c sandbox_mode=…`; the tests assert it for new and resumed runs.
87
+ - **Login shells.** Codex runs commands through `zsh -lc`; macOS's `path_helper` and `~/.zprofile` reorder `PATH`, which hides the git-guard shim. The second guard layer (git's own env config: a `reference-transaction` hook and `pushInsteadOf`) holds regardless, for every worker.
88
+ - **Stream**: `item.completed` items of type `error` are warnings (deprecated settings, skills budget), not failures; failures are top-level `error` / `turn.failed`, whose message is a JSON API error. The JSON stream does not name the model, so it is read from the session's rollout file. Cost is not reported.
89
+ - **"Not supported when using Codex with a ChatGPT account"** comes back both for models the account cannot use and for models the installed Codex CLI is too old to know (seen with `gpt-6.1-sol` on 0.146, working on 0.159). It is `model-unavailable`, so the chain moves on, and the message suggests updating Codex.
90
+ - **Node**: `codex` is a Node script (`#!/usr/bin/env node`); Pitroom runs such CLIs on its own Node 18+, since agents' shells often have an older Node first on `PATH`.
91
+
92
+ ## Claude Code notes
93
+
94
+ - **Lockdown** (see the table): `--safe-mode` keeps the user's CLAUDE.md, skills, plugins, hooks and MCP out; `--restricted` removes command-running tools unless listed, confines file tools to the working directory and refuses `bypassPermissions`; `--permission-mode dontAsk` denies anything outside the allowlist instead of prompting. The init event of a real run lists exactly `Glob, Grep, Read` for a read-only worker, no MCP servers, and only Claude Code's built-in plugins.
95
+ - **Not `--bare`**: it disables OAuth, which would break Claude subscriptions.
96
+ - **Argument order**: `--tools`, `--allowedTools` and `--disallowedTools` take lists; non-list options follow them and the prompt comes after `--`, so no list can swallow it.
97
+ - **Errors**: an API error arrives as an assistant message with `is_api_error_message` (e.g. `authentication_failed`, "OAuth session expired"); it is not counted as work, so the fallback chain can move on.
98
+ - **Model**: the init event names it. The user's default is often an Opus-class model; `doctor` warns and suggests `-W claude:haiku`.
99
+
100
+ ## Adding a worker
101
+
102
+ 1. Create `src/backends/<id>/index.ts` exporting a `Backend`; keep CLI knowledge
103
+ (flags, event format, error wording, model listing) in that folder.
104
+ 2. Register it in `src/backends/index.ts` (and drop the id from `PLANNED`).
105
+ 3. Record real fixtures under `test/fixtures/<id>/`:
106
+ - `events/*.jsonl`: stdout of real runs (one read, one write), home paths replaced;
107
+ - `failures/<name>.stdout.jsonl` + `.stderr.log`: e.g. an unknown model;
108
+ - `expected.json`: session id, step count, token total, answer prefix, failure kinds.
109
+ 4. `npm test`: `test/backends.test.mjs` runs the contract suite against every
110
+ registered backend automatically (capabilities, no bypass flags, read ≠ write,
111
+ prompt in argv, optional model/session/files, parsing, failure classification).
112
+ 5. Add an end-to-end mock for the CLI if its behaviour differs materially, and a
113
+ row to the table above and to the README.
@@ -0,0 +1,28 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "matcher": "startup|clear|compact",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.mjs\"",
10
+ "async": false
11
+ }
12
+ ]
13
+ }
14
+ ],
15
+ "PostToolUse": [
16
+ {
17
+ "matcher": "Bash",
18
+ "hooks": [
19
+ {
20
+ "type": "command",
21
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/pitroom.mjs\" hook-card",
22
+ "timeout": 10
23
+ }
24
+ ]
25
+ }
26
+ ]
27
+ }
28
+ }
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ // SessionStart hook: puts the `using-pitroom` skill into the primary agent's
3
+ // context, so it considers delegating before it starts reading and editing, and
4
+ // tells it the exact command to run even if `pitroom` is not on PATH.
5
+ // Dependency-free and fast: it only reads one file.
6
+ import fs from 'node:fs';
7
+ import os from 'node:os';
8
+ import path from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+
11
+ // Inside a Pitroom worker there is nothing to delegate to.
12
+ if (process.env.PITROOM_ACTIVE === '1') process.exit(0);
13
+
14
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
15
+ let skill = '';
16
+ try {
17
+ skill = fs.readFileSync(path.join(root, 'skills', 'using-pitroom', 'SKILL.md'), 'utf8');
18
+ } catch {
19
+ process.exit(0); // broken install: stay silent rather than break the session
20
+ }
21
+ const body = skill.replace(/^---\n[\s\S]*?\n---\n/, '').trim();
22
+ // Fallback when `pitroom` is not on PATH: the installed launcher (it picks a Node 18+),
23
+ // else this Node if it is new enough, else plain `node`.
24
+ const cli = path.join(root, 'dist', 'pitroom.mjs');
25
+ const launcher = path.join(os.homedir(), '.local', 'bin', 'pitroom');
26
+ const nodeOk = Number(process.versions.node.split('.')[0]) >= 18;
27
+ const fallback = fs.existsSync(launcher) ? `"${launcher}"` : `"${nodeOk ? process.execPath : 'node'}" "${cli}"`;
28
+ const command = fs.existsSync(cli) || fs.existsSync(launcher) ? `\`pitroom\`, or if that is not on PATH: \`${fallback}\`` : '`pitroom`';
29
+
30
+ const context = `<pitroom>
31
+ You have Pitroom: a development workflow as skills, and cheap worker agents that read, search, implement and review for you. Run it as ${command}.
32
+ It is optional: use it when it helps or when the user asks for it, otherwise work as you normally would. Below is the 'using-pitroom' skill, a menu of what it offers; load a pitroom-* skill with your Skill tool when you choose to use it.
33
+
34
+ ${body}
35
+ </pitroom>`;
36
+
37
+ // Cursor reads additional_context; Claude Code reads hookSpecificOutput. Emit only one,
38
+ // because Claude Code would otherwise inject the text twice.
39
+ const out = process.env.CURSOR_PLUGIN_ROOT
40
+ ? { additional_context: context }
41
+ : { hookSpecificOutput: { hookEventName: 'SessionStart', additionalContext: context } };
42
+ process.stdout.write(`${JSON.stringify(out)}\n`);
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "pitroom",
3
+ "version": "0.6.0",
4
+ "description": "A free pit crew for your expensive coding agent: the superpowers development workflow, run by cheap workers. Delegate research, fixes, tests, reviews and whole plans from Claude Code, Codex or any agent to OpenCode, Codex or Claude Code workers, with receipts that prove the savings.",
5
+ "type": "module",
6
+ "author": "TahaAtas",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/ATASTECH/pitroom.git"
10
+ },
11
+ "homepage": "https://github.com/ATASTECH/pitroom#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/ATASTECH/pitroom/issues"
14
+ },
15
+ "bin": {
16
+ "pitroom": "dist/pitroom.mjs"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "skills",
21
+ "hooks",
22
+ ".claude-plugin",
23
+ ".codex-plugin",
24
+ "docs/backends.md",
25
+ "README.md",
26
+ "CHANGELOG.md",
27
+ "LICENSE"
28
+ ],
29
+ "engines": {
30
+ "node": ">=18"
31
+ },
32
+ "scripts": {
33
+ "build": "node scripts/build.mjs",
34
+ "typecheck": "tsc --noEmit",
35
+ "test": "npm run build && node --test test/*.test.mjs",
36
+ "prepublishOnly": "npm run typecheck && npm test"
37
+ },
38
+ "keywords": [
39
+ "agent",
40
+ "agent-skills",
41
+ "claude-code",
42
+ "codex",
43
+ "cost",
44
+ "delegation",
45
+ "llm",
46
+ "opencode",
47
+ "subagent",
48
+ "tokens",
49
+ "workflow",
50
+ "code-review",
51
+ "tdd",
52
+ "planning"
53
+ ],
54
+ "license": "MIT",
55
+ "devDependencies": {
56
+ "@types/node": "^22.10.0",
57
+ "esbuild": "^0.25.0",
58
+ "typescript": "^5.7.0"
59
+ }
60
+ }
@@ -0,0 +1,243 @@
1
+ ---
2
+ name: pitroom-brainstorming
3
+ description: Use when you or the user want a feature, component or behaviour change designed before it is built - explores intent, requirements and design with the user and gets approval before implementation.
4
+ ---
5
+
6
+ # Brainstorming Ideas Into Designs
7
+
8
+ Help turn ideas into fully formed designs and specs through natural collaborative dialogue.
9
+
10
+ Start by classifying how much process the request needs, then work
11
+ through your path: understand the context, refine the idea, present a
12
+ design, and get your human partner's approval.
13
+
14
+ <HARD-GATE>
15
+ Do NOT invoke any implementation skill, write any code, scaffold any
16
+ project, or take any implementation action until you have told your
17
+ human partner what you intend and they have approved it. This applies
18
+ to EVERY task on EVERY path below — the ceremony scales with the task;
19
+ the approval gate never does.
20
+ </HARD-GATE>
21
+
22
+ ## Three Paths
23
+
24
+ Before your first question, classify the request and say the
25
+ classification out loud — "this looks bounded, so I'll present a short
26
+ design here rather than write a spec" — so your human partner can
27
+ override it:
28
+
29
+ - **Spike** — a feasibility question ("can we...", "is it possible...",
30
+ "quick and dirty is fine") whose output is an answer, not code you
31
+ keep. Present the question and what you'll try in 2-3 sentences, get
32
+ a nod, then find out as cheaply as correctness allows. No design
33
+ doc, no spec file. Report findings as a recommendation; anything you
34
+ built stays labeled throwaway.
35
+ - **Bounded** — a well-scoped change to code that already exists in
36
+ this repo: a new flag, a small endpoint, a one-file fix.
37
+ Understanding the kind of app is not enough — bounded means the flow
38
+ you are changing is already here to read. If there is no existing
39
+ flow to change, the task is not bounded. Ask the clarifying
40
+ questions that matter, present a short design IN CHAT (a few
41
+ sentences to a few short paragraphs), and STOP. Implementation
42
+ starts only after your human partner says yes to that design — a
43
+ bounded task's approval is as hard a gate as an architectural
44
+ one. No spec file, no implementation plan document.
45
+ - **Architectural** — new projects, new subsystems, changes that
46
+ restructure how components fit together or alter interfaces others
47
+ depend on. Follow the full process: questions, approaches, sectioned
48
+ design, written spec, then the `pitroom-writing-plans` skill.
49
+
50
+ When in doubt between two paths, take the heavier one. The ratchet is
51
+ one-way: hidden complexity discovered mid-task upgrades the path —
52
+ stop, say so, and step up. Nothing downgrades mid-task.
53
+
54
+ ## Anti-Pattern: "Too Simple To Need Approval"
55
+
56
+ Every path ends with your human partner approving your intent before
57
+ implementation. A todo list, a single-function utility, a config
58
+ change — the design may be two sentences in chat, but you MUST present
59
+ it and get approval. "Simple" tasks are where unexamined assumptions
60
+ cause the most wasted work. What scales with simplicity is the
61
+ artifact, never the approval.
62
+
63
+ This gate is for creative work: a feature, a component, a behaviour
64
+ change. A typo, a one-line fix the user spelled out, or a value the
65
+ user named is not creative work; `using-pitroom` leaves those to you
66
+ without this skill.
67
+
68
+ ## Red Flags
69
+
70
+ | Thought | Reality |
71
+ |---------|---------|
72
+ | "This is too simple to need a design" | Simple means a short design, not no design. Two sentences in chat, then approval. |
73
+ | "I'll call it bounded and skip the spec" | Reaching for a label to skip work IS the doubt — take the heavier path. |
74
+ | "It's bounded and the design is obvious — I'll start while they read it" | The gate is the approval, not the design's length. Present, then stop until you hear yes. |
75
+ | "I understand this kind of app, so it's bounded" | Bounded measures the repo, not your familiarity. A new project has no existing flow — it is architectural. |
76
+ | "The spike works, so I'll keep the code" | A spike's output is an answer. Keeping the code is a new request — classify it. |
77
+ | "It grew, but I'm almost done — no need to re-classify" | Hidden complexity upgrades the path mid-task. Stop and say so. |
78
+ | "They approved the spike, so the follow-up change is approved too" | Each task gets its own classification and its own approval. |
79
+
80
+ ## Checklist
81
+
82
+ Classify first, announce the path, then create a task for each item on
83
+ your path and complete them in order.
84
+
85
+ **Spike:**
86
+ 1. **Explore project context** — enough to frame the probe — let workers do the reading (`pitroom-research` for one area, `pitroom-crew` for several) and read their answers, not the files
87
+ 2. **Present question + probe plan** — 2-3 sentences
88
+ 3. **Get approval** — a nod is enough
89
+ 4. **Investigate** — as cheaply as correctness allows
90
+ 5. **Report findings** — a recommendation; label anything built as throwaway
91
+
92
+ **Bounded:**
93
+ 1. **Explore project context** — check files, docs, recent commits — let workers do the reading (`pitroom-research` for one area, `pitroom-crew` for several) and read their answers, not the files
94
+ 2. **Ask clarifying questions** — one at a time, the ones that matter
95
+ 3. **Present short design in chat** — approach, files touched, testing
96
+ 4. **Get approval** — STOP and wait for an explicit yes; presenting the design and starting in the same breath is skipping the gate
97
+ 5. **Implement** — proceed with the normal development workflow (TDD applies); no plan document
98
+
99
+ **Architectural:**
100
+ 1. **Explore project context** — check files, docs, recent commits — let workers do the reading (`pitroom-research` for one area, `pitroom-crew` for several) and read their answers, not the files
101
+ 2. **Ask clarifying questions** — one at a time, understand purpose/constraints/success criteria
102
+ 3. **Propose 2-3 approaches** — with trade-offs and your recommendation
103
+ 4. **Present design** — in sections scaled to their complexity, get user approval after each section
104
+ 5. **Write design doc** — save to `docs/pitroom/specs/YYYY-MM-DD-<topic>-design.md` and commit
105
+ 6. **Spec self-review** — quick inline check for placeholders, contradictions, ambiguity, scope (see below)
106
+ 7. **User reviews written spec** — ask user to review the spec file before proceeding
107
+ 8. **Transition to implementation** — invoke `pitroom-writing-plans` to create implementation plan
108
+
109
+ ## Process Flow
110
+
111
+ ```dot
112
+ digraph brainstorming {
113
+ "Classify: spike / bounded / architectural" [shape=diamond];
114
+ "Present question + probe (2-3 sentences)" [shape=box];
115
+ "Ask clarifying questions (bounded)" [shape=box];
116
+ "Present short design in chat" [shape=box];
117
+ "Human approves?" [shape=diamond];
118
+ "Investigate; report recommendation" [shape=doublecircle];
119
+ "Implement via normal workflow (no plan doc)" [shape=doublecircle];
120
+ "Explore project context" [shape=box];
121
+ "Ask clarifying questions" [shape=box];
122
+ "Propose 2-3 approaches" [shape=box];
123
+ "Present design sections" [shape=box];
124
+ "User approves design?" [shape=diamond];
125
+ "Write design doc" [shape=box];
126
+ "Spec self-review\n(fix inline)" [shape=box];
127
+ "User reviews spec?" [shape=diamond];
128
+ "Invoke pitroom-writing-plans" [shape=doublecircle];
129
+ "Hidden complexity? Upgrade path" [shape=box];
130
+
131
+ "Classify: spike / bounded / architectural" -> "Present question + probe (2-3 sentences)" [label="spike"];
132
+ "Classify: spike / bounded / architectural" -> "Ask clarifying questions (bounded)" [label="bounded"];
133
+ "Classify: spike / bounded / architectural" -> "Explore project context" [label="architectural"];
134
+ "Present question + probe (2-3 sentences)" -> "Human approves?";
135
+ "Ask clarifying questions (bounded)" -> "Present short design in chat";
136
+ "Present short design in chat" -> "Human approves?";
137
+ "Human approves?" -> "Investigate; report recommendation" [label="spike: yes"];
138
+ "Human approves?" -> "Implement via normal workflow (no plan doc)" [label="bounded: yes"];
139
+ "Hidden complexity? Upgrade path" -> "Classify: spike / bounded / architectural";
140
+ "Explore project context" -> "Ask clarifying questions";
141
+ "Ask clarifying questions" -> "Propose 2-3 approaches";
142
+ "Propose 2-3 approaches" -> "Present design sections";
143
+ "Present design sections" -> "User approves design?";
144
+ "User approves design?" -> "Present design sections" [label="no, revise"];
145
+ "User approves design?" -> "Write design doc" [label="yes"];
146
+ "Write design doc" -> "Spec self-review\n(fix inline)";
147
+ "Spec self-review\n(fix inline)" -> "User reviews spec?";
148
+ "User reviews spec?" -> "Write design doc" [label="changes requested"];
149
+ "User reviews spec?" -> "Invoke pitroom-writing-plans" [label="approved"];
150
+ }
151
+ ```
152
+
153
+ **Terminal states are path-bound.** Architectural: the ONLY skill you
154
+ invoke after brainstorming is `pitroom-writing-plans` — never frontend-design,
155
+ mcp-builder, or any other implementation skill. Bounded: after
156
+ approval, implementation proceeds directly through the normal
157
+ development workflow; no plan document. Spike: the terminal state is a
158
+ reported recommendation.
159
+
160
+ ## The Process
161
+
162
+ The subsections below serve the bounded and architectural paths (a
163
+ spike stops at "present the probe, get a nod"). Sections from
164
+ **Exploring approaches** onward are architectural-path depth — for
165
+ bounded work, context plus a few questions plus a short in-chat design
166
+ is the whole process.
167
+
168
+ **Understanding the idea:**
169
+
170
+ - Check out the current project state first (docs, recent commits); for code, ask a worker for a map (`pitroom-research`) instead of reading it yourself
171
+ - Before asking detailed questions, assess scope: if the request describes multiple independent subsystems (e.g., "build a platform with chat, file storage, billing, and analytics"), flag this immediately. Don't spend questions refining details of a project that needs to be decomposed first.
172
+ - If the project is too large for a single spec, help the user decompose into sub-projects: what are the independent pieces, how do they relate, what order should they be built? Then brainstorm the first sub-project through the normal design flow. Each sub-project gets its own spec → plan → implementation cycle.
173
+ - For appropriately-scoped projects, ask questions one at a time to refine the idea
174
+ - Prefer multiple choice questions when possible, but open-ended is fine too
175
+ - Only one question per message - if a topic needs more exploration, break it into multiple questions
176
+ - Focus on understanding: purpose, constraints, success criteria
177
+
178
+ **Exploring approaches:**
179
+
180
+ - Propose 2-3 different approaches with trade-offs
181
+ - Present options conversationally with your recommendation and reasoning
182
+ - Lead with your recommended option and explain why
183
+ - YAGNI ruthlessly - remove unnecessary features from every approach and design
184
+
185
+ **Presenting the design:**
186
+
187
+ - Once you believe you understand what you're building, present the design
188
+ - Scale each section to its complexity: a few sentences if straightforward, up to 200-300 words if nuanced
189
+ - Ask after each section whether it looks right so far
190
+ - Cover: architecture, components, data flow, error handling, testing
191
+ - Be ready to go back and clarify if something doesn't make sense
192
+
193
+ **Design for isolation and clarity:**
194
+
195
+ - Break the system into smaller units that each have one clear purpose, communicate through well-defined interfaces, and can be understood and tested independently
196
+ - For each unit, you should be able to answer: what does it do, how do you use it, and what does it depend on?
197
+ - Can someone understand what a unit does without reading its internals? Can you change the internals without breaking consumers? If not, the boundaries need work.
198
+ - Smaller, well-bounded units are also easier for you to work with - you reason better about code you can hold in context at once, and your edits are more reliable when files are focused. When a file grows large, that's often a signal that it's doing too much.
199
+
200
+ **Working in existing codebases:**
201
+
202
+ - Explore the current structure before proposing changes. Follow existing patterns.
203
+ - Where existing code has problems that affect the work (e.g., a file that's grown too large, unclear boundaries, tangled responsibilities), include targeted improvements as part of the design - the way a good developer improves code they're working in.
204
+ - Don't propose unrelated refactoring. Stay focused on what serves the current goal.
205
+
206
+ ## After the Design (architectural path)
207
+
208
+ **Documentation:**
209
+
210
+ - Write the validated design (spec) to `docs/pitroom/specs/YYYY-MM-DD-<topic>-design.md`
211
+ - (User preferences for spec location override this default)
212
+ - Commit the design document to git
213
+
214
+ **Spec Self-Review:**
215
+ After writing the spec document, look at it with fresh eyes:
216
+
217
+ 1. **Placeholder scan:** Any "TBD", "TODO", incomplete sections, or vague requirements? Fix them.
218
+ 2. **Internal consistency:** Do any sections contradict each other? Does the architecture match the feature descriptions?
219
+ 3. **Scope check:** Is this focused enough for a single implementation plan, or does it need decomposition?
220
+ 4. **Ambiguity check:** Could any requirement be interpreted two different ways? If so, pick one and make it explicit.
221
+
222
+ **Second read (optional, for a long spec):** a read-only worker applies [spec-document-reviewer-prompt.md](spec-document-reviewer-prompt.md):
223
+
224
+ ```bash
225
+ sed "s#{{SPEC_FILE}}#docs/pitroom/specs/<file>.md#" "<this skill's folder>/spec-document-reviewer-prompt.md" > "$TMPDIR/spec-review.md"
226
+ pitroom run --task-file "$TMPDIR/spec-review.md"
227
+ ```
228
+
229
+ Weigh its findings like any review (`pitroom-receiving-review`).
230
+
231
+ Fix any issues inline. No need to re-review — just fix and move on.
232
+
233
+ **User Review Gate:**
234
+ After the spec self-review (and the optional second read), ask the user to review the written spec before proceeding:
235
+
236
+ > "Spec written and committed to `<path>`. Please review it and let me know if you want to make any changes before we start writing out the implementation plan."
237
+
238
+ Wait for the user's response. If they request changes, make them and re-run the spec self-review. Only proceed once the user approves.
239
+
240
+ **Implementation:**
241
+
242
+ - Invoke `pitroom-writing-plans` to create a detailed implementation plan
243
+ - Do NOT invoke any other skill. `pitroom-writing-plans` is the next step.
@@ -0,0 +1,22 @@
1
+ You are a spec document reviewer. Verify that this spec is complete and ready for implementation planning.
2
+
3
+ Spec to review: {{SPEC_FILE}}
4
+
5
+ ## What to check
6
+
7
+ | Category | What to look for |
8
+ |---|---|
9
+ | Completeness | TODOs, placeholders, "TBD", incomplete sections |
10
+ | Consistency | Internal contradictions, conflicting requirements |
11
+ | Clarity | Requirements ambiguous enough to make someone build the wrong thing |
12
+ | Scope | Focused enough for a single plan, not several independent subsystems |
13
+ | YAGNI | Unrequested features, over-engineering |
14
+
15
+ ## Calibration
16
+
17
+ Only flag issues that would cause real problems during implementation planning: a missing section, a contradiction, a requirement that could be read two ways. Wording, style and "some sections are less detailed than others" are not issues. Approve unless there are serious gaps that would lead to a flawed plan.
18
+
19
+ ## Answer
20
+
21
+ SUMMARY: STATUS: APPROVED, or SUMMARY: STATUS: ISSUES FOUND (N)
22
+ In DETAILS: each issue as "[Section]: issue - why it matters for planning", then RECOMMENDATIONS (advisory; they do not block approval).
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: pitroom-crew
3
+ description: Use when facing two or more independent tasks - questions about different areas, unrelated bugs or failing test files, the same mechanical change in separate modules - to run Pitroom workers in parallel, watch them live and merge their results.
4
+ ---
5
+
6
+ # Running a Pitroom crew
7
+
8
+ Several workers at once, each with its own session (and, for changes, its own isolated copy of the project): one worker per independent problem domain. You split the work, watch, and merge.
9
+
10
+ ## When to use
11
+
12
+ - Several questions about different areas of the code.
13
+ - Three or more test files failing with different root causes; subsystems broken independently.
14
+ - The same mechanical change in separate modules.
15
+
16
+ Don't use it when the failures are related (fixing one might fix the others: investigate them together first), when understanding needs the whole system, when you don't yet know what is broken (exploratory debugging: `pitroom-debugging`), or when workers would edit the same files. The tasks of a written plan run through `pitroom-driven-development`, which has its own rules for parallel tasks.
17
+
18
+ ## 1. Split
19
+
20
+ Parts must be **independent**: no part needs another's result, and no two parts edit the same file. Two to five parts is the sweet spot; at most `maxParallel` workers (default 4) run at a time, the rest queue. Keep dependent or judgment-heavy parts for yourself.
21
+
22
+ ## 2. Write focused briefs
23
+
24
+ Each worker sees only its brief, so each brief is:
25
+ 1. **Focused:** one problem domain ("fix agent-tool-abort.test.ts", not "fix all the tests").
26
+ 2. **Self-contained:** the error messages, test names and file paths it needs.
27
+ 3. **Constrained:** what not to change ("do not change production code", "tests only").
28
+ 4. **Specific about the answer:** "the root cause and what you changed", "file:line for each".
29
+
30
+ ```text
31
+ Fix the 3 failing tests in src/agents/agent-tool-abort.test.ts:
32
+ 1. "should abort tool with partial output capture" - expects 'interrupted at' in message
33
+ 2. "should handle mixed completed and aborted tools" - fast tool aborted instead of completed
34
+ 3. "should properly track pendingToolCount" - expects 3 results but gets 0
35
+ These look like timing issues. Find the real cause: replace arbitrary timeouts with
36
+ event-based waiting, or fix the abort implementation. Do NOT just increase timeouts.
37
+ Answer with the root cause and what you changed.
38
+ ```
39
+
40
+ `pitroom-research` and `pitroom-implement` have more brief templates.
41
+
42
+ ## 3. Start
43
+
44
+ ```bash
45
+ pitroom crew -g auth-audit \
46
+ "Map how sessions are created in src/auth; file:line for each step." \
47
+ "List every place that reads the session cookie outside src/auth; file:line." \
48
+ "Which tests cover session expiry? List files and what each asserts."
49
+ ```
50
+
51
+ Read-only by default. For changes add `-i` (each worker edits its own isolated copy): `pitroom crew -i -g lint-fix "Fix the lint errors in src/a" "Fix the lint errors in src/b"`. Never parallel `--write`; Pitroom refuses it.
52
+
53
+ ## 4. Watch
54
+
55
+ Follow the group live without polling:
56
+ - `pitroom watch -g NAME --json`: one JSON line per change (`queued`, `started`, `progress`, `fallback`, `done`/`failed`, then `all-done`). Run it through your host's background or monitor facility so each line reaches you as it happens; it exits by itself when the group is done.
57
+ - No such facility: `pitroom wait -g NAME --timeout 540`, and call it again while it exits with 75.
58
+ - `pitroom status -g NAME`: one table snapshot.
59
+ - Tell the user they can see the same table live with `pitroom watch -g NAME` in a terminal.
60
+
61
+ While workers run, do the parts you kept for yourself.
62
+
63
+ ## 5. Collect, verify and merge
64
+
65
+ ```bash
66
+ pitroom wait -g NAME --brief # one line per worker: state + SUMMARY
67
+ pitroom show <run> # the full report of the ones you need
68
+ ```
69
+
70
+ - Read each summary and understand what changed.
71
+ - Check for conflicts: did two workers touch the same code or contradict each other?
72
+ - Verify what you will rely on (`refs:` lines help), then combine the findings in your own words.
73
+ - For `-i` crews: review each patch (`pitroom review <run>` or `pitroom show <run> --patch`), then `pitroom apply -g NAME`. It applies in order and stops at the first conflict; fix that one with `pitroom run --continue <run> "…"` or by hand, then apply the rest.
74
+ - Run the full test suite yourself afterwards, and spot-check: workers make systematic errors.
75
+
76
+ ## When things go wrong
77
+
78
+ - A worker failed or timed out: retry that part once with a sharper brief, or do it yourself.
79
+ - Rate limits: the fallback chain handles single failures; if many fail, lower `maxParallel` (config or `PITROOM_MAX_PARALLEL`).
80
+ - Stop everything: `pitroom stop -g NAME` (running and queued).