pi-loopflows 0.1.0 → 0.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1 - 2026-06-22
4
+
5
+ - Polish product README and usage guidance for public release.
6
+ - Add bundled `build-review` loopflow for lightweight implementation feedback loops.
7
+ - Add bundled `plan-review` loopflow for plan quality gates before implementation.
8
+ - Expand loopflows skill instructions.
9
+ - Clarify adapter/backend direction for future compatible executors.
10
+
3
11
  ## 0.1.0 - 2026-06-22
4
12
 
5
13
  - Initial release.
package/README.md CHANGED
@@ -1,12 +1,26 @@
1
1
  # pi-loopflows
2
2
 
3
- Deterministic loop workflows for Pi subagents.
3
+ Build deterministic AI workflows out of Pi subagents.
4
4
 
5
- A **loopflow** describes agent work as a process instead of a single prompt: steps, gates, feedback loops, stop conditions, and saved evidence. It lets you connect Pi subagents like building blocks: gather context, plan, build, review, loop back for fixes, and audit the result.
5
+ A **loopflow** is a reusable process for agent work: steps, gates, feedback loops, stop rules, and evidence artifacts. Instead of asking one agent to “do the whole thing”, you describe how specialist agents should cooperate: one agent gathers context, another plans, another builds, another reviews, and a gate decides whether the work moves forward, loops back for fixes, or stops.
6
6
 
7
- ## Why
7
+ `pi-loopflows` ships with a production-ready **Launch Control** loopflow out of the box, and it is also a flexible constructor for your own workflows.
8
8
 
9
- Normal chains are linear. Real work is not. A reviewer may request changes, a builder may need another pass, or a gate may block because evidence is missing. `pi-loopflows` adds that missing control flow while keeping the agents focused on their roles.
9
+ ## Why loopflows
10
+
11
+ Linear chains are useful, but real work is not always linear. A reviewer can request changes. A validator can reject missing evidence. A planner can reveal that the task is blocked. A builder may need several focused passes before the result is safe to accept.
12
+
13
+ Loopflows make that control flow explicit:
14
+
15
+ ```text
16
+ step → step → gate
17
+
18
+ approved → continue
19
+ changes_requested → loop back
20
+ blocked → stop
21
+ ```
22
+
23
+ The philosophy is simple: AI should work through a process, not just produce a confident answer. A loopflow defines who does the work, who checks it, what counts as success, how many attempts are allowed, where evidence is saved, and when the run must stop instead of guessing.
10
24
 
11
25
  ## Install
12
26
 
@@ -14,19 +28,19 @@ Normal chains are linear. Real work is not. A reviewer may request changes, a bu
14
28
  pi install npm:pi-loopflows
15
29
  ```
16
30
 
17
- Or from GitHub:
31
+ `pi-loopflows` uses Pi subagent definitions as its first backend. Install `pi-subagents` if you have not already:
18
32
 
19
33
  ```bash
20
- pi install https://github.com/nik1t7n/pi-loopflows
34
+ pi install npm:pi-subagents
21
35
  ```
22
36
 
23
- Reload Pi after installing:
37
+ Then reload Pi:
24
38
 
25
39
  ```text
26
40
  /reload
27
41
  ```
28
42
 
29
- ## What it adds
43
+ ## What you get
30
44
 
31
45
  ### Tool
32
46
 
@@ -45,9 +59,15 @@ loopflow_run({
45
59
  /loopflow launch-control -- Implement this approved backend plan
46
60
  ```
47
61
 
48
- ### Bundled loopflow
62
+ ### Built-in loopflows
63
+
64
+ - `launch-control` — plan-as-contract implementation loop with builder/reviewer feedback and final audit.
65
+ - `build-review` — small generic build → review → fix loop for scoped implementation tasks.
66
+ - `plan-review` — planning loop that lets a reviewer reject vague or unsafe plans before implementation.
67
+
68
+ ## Built-in: Launch Control
49
69
 
50
- `launch-control`:
70
+ Launch Control is bundled because it is the clearest example of why loopflows exist. It turns a plan into a controlled implementation process:
51
71
 
52
72
  ```text
53
73
  context-builder
@@ -61,19 +81,59 @@ context-builder
61
81
  → final audit
62
82
  ```
63
83
 
84
+ Use it when drift, skipped validation, PR correctness, or multi-step delivery risk matter.
85
+
86
+ Example:
87
+
88
+ ```text
89
+ /loopflow launch-control -- Implement the auth migration plan in docs/auth-plan.md
90
+ ```
91
+
92
+ Launch Control is not hard-coded. It is just a `.loopflow.json` file. You can copy it, change the agents, change the prompts, adjust max iterations, add stricter gates, or create a project-specific version in `.pi/loopflows/`.
93
+
94
+ ## Loopflows as a constructor
95
+
96
+ Think of loopflows as LEGO for agent processes. A loopflow can use any available Pi subagent role:
97
+
98
+ - `context-builder`
99
+ - `scout`
100
+ - `researcher`
101
+ - `planner`
102
+ - `worker`
103
+ - `reviewer`
104
+ - `oracle`
105
+ - your own custom agents
106
+
107
+ You decide:
108
+
109
+ - which agent runs first;
110
+ - what each agent receives;
111
+ - which output is saved;
112
+ - which step is a gate;
113
+ - what statuses mean pass, retry, or stop;
114
+ - how many loop iterations are allowed;
115
+ - where artifacts go;
116
+ - what final audit should prove.
117
+
118
+ Today, the backend runs Pi-compatible subagents. The engine is intentionally built behind an adapter boundary, so future versions can add other compatible backends — Codex CLI, OpenCode, ACP workers, remote agents, or custom executors — without changing the loopflow concept.
119
+
64
120
  ## Loopflow files
65
121
 
66
- Loopflows are JSON files named `*.loopflow.json`.
122
+ Loopflows are JSON files named:
123
+
124
+ ```text
125
+ *.loopflow.json
126
+ ```
67
127
 
68
128
  Discovery locations:
69
129
 
70
- - bundled package `loopflows/`
71
- - user: `~/.pi/agent/loopflows/`
72
- - project: `.pi/loopflows/`
130
+ - bundled package loopflows;
131
+ - user loopflows: `~/.pi/agent/loopflows/`;
132
+ - project loopflows: `.pi/loopflows/`.
73
133
 
74
- Project loopflows can override or add workflows for a repo.
134
+ Project loopflows are the easiest way to customize behavior for one repo.
75
135
 
76
- ## Minimal shape
136
+ ## Minimal example
77
137
 
78
138
  ```json
79
139
  {
@@ -114,14 +174,39 @@ Project loopflows can override or add workflows for a repo.
114
174
 
115
175
  ## Template variables
116
176
 
117
- - `{task}` — original user task
118
- - `{previous}` — previous step output
119
- - `{outputs.stepId}` — output from a named step
120
- - `{outputs.stepId.status}` — parsed gate status
121
- - `{outputs.stepId.json}` — parsed gate JSON
122
- - `{loop.iteration}` — current loop iteration
123
- - `{artifactsDir}` — current run artifact directory
124
- - `{params.name}` — runtime params passed to `loopflow_run`
177
+ - `{task}` — original user task.
178
+ - `{previous}` — previous step output.
179
+ - `{outputs.stepId}` — output from a named step.
180
+ - `{outputs.stepId.output}` — same as above, explicit form.
181
+ - `{outputs.stepId.status}` — parsed gate status.
182
+ - `{outputs.stepId.json}` — parsed gate JSON.
183
+ - `{loop.iteration}` — current loop iteration.
184
+ - `{artifactsDir}` — current run artifact directory.
185
+ - `{params.name}` — runtime params passed to `loopflow_run`.
186
+
187
+ ## Gate contract
188
+
189
+ Gate steps should return JSON. A typical reviewer gate returns:
190
+
191
+ ```json
192
+ {
193
+ "status": "approved",
194
+ "summary": "The implementation satisfies the plan.",
195
+ "findings": [],
196
+ "validation_gaps": [],
197
+ "requires_user_decision": false
198
+ }
199
+ ```
200
+
201
+ Common statuses:
202
+
203
+ - `approved` — move forward.
204
+ - `changes_requested` — loop back for another pass.
205
+ - `blocked` — stop; user or environment action is required.
206
+ - `complete` — final audit passed.
207
+ - `incomplete` — final audit failed.
208
+
209
+ Each loopflow decides which statuses pass, retry, or stop.
125
210
 
126
211
  ## Artifacts
127
212
 
@@ -131,7 +216,7 @@ Every run writes evidence to:
131
216
  <cwd>/.pi/loopflows/runs/<timestamp>-<workflow>/
132
217
  ```
133
218
 
134
- Typical files:
219
+ Typical artifacts:
135
220
 
136
221
  ```text
137
222
  task.md
@@ -144,30 +229,92 @@ final-audit.json
144
229
  summary.md
145
230
  ```
146
231
 
232
+ This makes loopflows inspectable. You can see what each agent claimed, what the gate decided, and why the run stopped or passed.
233
+
234
+ ## Customization patterns
235
+
236
+ ### Make Launch Control stricter
237
+
238
+ Copy the bundled file:
239
+
240
+ ```bash
241
+ mkdir -p .pi/loopflows
242
+ cp ~/.pi/agent/npm/node_modules/pi-loopflows/loopflows/launch-control.loopflow.json \
243
+ .pi/loopflows/launch-control.loopflow.json
244
+ ```
245
+
246
+ Then edit the project copy. Common changes:
247
+
248
+ - increase `maxIterations`;
249
+ - change `reviewer` to a custom security reviewer;
250
+ - add stricter validation language;
251
+ - add a docs or migration audit step;
252
+ - change stop statuses;
253
+ - make the final audit require `complete` only.
254
+
255
+ ### Create a lightweight workflow
256
+
257
+ Use `build-review` for small implementation tasks where full Launch Control is too formal.
258
+
259
+ ```text
260
+ /loopflow build-review -- Add validation to the import endpoint
261
+ ```
262
+
263
+ ### Review a plan before coding
264
+
265
+ Use `plan-review` when you want a plan to be checked before a worker touches files.
266
+
267
+ ```text
268
+ /loopflow plan-review -- Plan the database migration for workspace roles
269
+ ```
270
+
147
271
  ## Backend design
148
272
 
149
- The engine uses an executor adapter boundary:
273
+ The runtime uses an executor adapter boundary:
150
274
 
151
275
  ```ts
152
276
  runAgent(agent, task, options) -> StepResult
153
277
  ```
154
278
 
155
- Current backend: Pi subprocess agents compatible with `pi-subagents` agent definitions.
279
+ Current backend:
156
280
 
157
- Future backends can support Codex CLI, OpenCode, ACP-based workers, remote workers, or other agent runtimes without changing loopflow definitions.
281
+ - Pi subprocess agents compatible with `pi-subagents` agent definitions.
158
282
 
159
- ## Requirements
283
+ Future-compatible backend ideas:
160
284
 
161
- - Pi coding agent
162
- - `pi-subagents` installed for the bundled agent roles:
285
+ - Codex CLI workers;
286
+ - OpenCode workers;
287
+ - ACP-compatible agents;
288
+ - remote worker pools;
289
+ - project-specific executors.
163
290
 
164
- ```bash
165
- pi install npm:pi-subagents
291
+ The point is that loopflows describe the process. The backend decides how each agent is actually executed.
292
+
293
+ ## When to use loopflows vs chains
294
+
295
+ Use normal Pi subagent chains when the process is linear:
296
+
297
+ ```text
298
+ scout → planner → worker
166
299
  ```
167
300
 
301
+ Use loopflows when a step can send work backward or stop the process:
302
+
303
+ ```text
304
+ worker → reviewer → worker → reviewer
305
+ ```
306
+
307
+ If you need a feedback loop, a quality gate, a max iteration limit, or saved evidence, use a loopflow.
308
+
168
309
  ## Status
169
310
 
170
- Early but usable. The core model is intentionally small: steps, loops, gates, artifacts, and adapters.
311
+ `pi-loopflows` is early, but designed as a real product surface rather than a one-off script. The core model is intentionally small:
312
+
313
+ ```text
314
+ steps + loops + gates + artifacts + adapters
315
+ ```
316
+
317
+ That is enough to build useful workflows without turning the extension into a giant orchestration platform.
171
318
 
172
319
  ## License
173
320
 
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "build-review",
3
+ "version": "1.0.0",
4
+ "description": "Generic scoped implementation loop: plan, build, independent review, repeat fixes until approved or blocked.",
5
+ "backend": "pi-subprocess",
6
+ "defaults": {
7
+ "agentScope": "both"
8
+ },
9
+ "steps": [
10
+ {
11
+ "id": "plan",
12
+ "agent": "planner",
13
+ "output": "plan.md",
14
+ "task": "Create a concise implementation plan for this task:\n\n{task}\n\nInclude acceptance criteria, likely files, validation commands, non-goals, and stop conditions. Do not edit files."
15
+ },
16
+ {
17
+ "loop": {
18
+ "id": "build-review",
19
+ "maxIterations": 3,
20
+ "gateStep": "review",
21
+ "passStatuses": ["approved"],
22
+ "retryStatuses": ["changes_requested"],
23
+ "stopStatuses": ["blocked"],
24
+ "onExhausted": "stop",
25
+ "body": [
26
+ {
27
+ "id": "build",
28
+ "agent": "worker",
29
+ "output": "build-{loop.iteration}.md",
30
+ "task": "Implement or fix iteration {loop.iteration}.\n\nTask:\n{task}\n\nPlan:\n{outputs.plan}\n\nPrevious review, if any:\n{outputs.review.output}\n\nIf this is iteration 1, implement the planned change. If this is a later iteration, apply only required reviewer fixes. Use the real project stack. Do not add mocks, demos, fake validation, or hidden fallbacks unless explicitly requested. Run focused validation and report changed files, commands with exit codes, evidence, blockers, and remaining risks."
31
+ },
32
+ {
33
+ "id": "review",
34
+ "agent": "reviewer",
35
+ "output": "review-{loop.iteration}.json",
36
+ "gate": {
37
+ "type": "json-status",
38
+ "passStatuses": ["approved"],
39
+ "retryStatuses": ["changes_requested"],
40
+ "stopStatuses": ["blocked"]
41
+ },
42
+ "task": "Review iteration {loop.iteration}. Do not edit project/source files.\n\nTask:\n{task}\n\nPlan:\n{outputs.plan}\n\nBuilder report:\n{outputs.build.output}\n\nReturn ONLY valid JSON:\n{\n \"status\": \"approved\" | \"changes_requested\" | \"blocked\",\n \"summary\": \"short verdict\",\n \"findings\": [{\"severity\": \"blocker|required|optional\", \"file\": \"path or null\", \"issue\": \"specific issue\", \"required_fix\": \"specific fix or null\"}],\n \"validation_gaps\": [\"gap\"],\n \"requires_user_decision\": false\n}\n\nApprove only if the implementation and evidence satisfy the plan. Request changes for required fixable issues. Block for missing credentials, missing decisions, unsafe scope, or stale plan."
43
+ }
44
+ ]
45
+ }
46
+ }
47
+ ]
48
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "plan-review",
3
+ "version": "1.0.0",
4
+ "description": "Planning loop: gather context, draft a plan, review the plan, and revise until approved or blocked before implementation.",
5
+ "backend": "pi-subprocess",
6
+ "defaults": {
7
+ "agentScope": "both"
8
+ },
9
+ "steps": [
10
+ {
11
+ "id": "context",
12
+ "agent": "context-builder",
13
+ "output": "context.md",
14
+ "task": "Build planning context for this task:\n\n{task}\n\nInspect the repository enough to identify relevant files, constraints, validation commands, risks, and unknowns. Do not edit files."
15
+ },
16
+ {
17
+ "loop": {
18
+ "id": "plan-review",
19
+ "maxIterations": 2,
20
+ "gateStep": "review",
21
+ "passStatuses": ["approved"],
22
+ "retryStatuses": ["changes_requested"],
23
+ "stopStatuses": ["blocked"],
24
+ "onExhausted": "stop",
25
+ "body": [
26
+ {
27
+ "id": "plan",
28
+ "agent": "planner",
29
+ "output": "plan-{loop.iteration}.md",
30
+ "task": "Draft or revise implementation plan iteration {loop.iteration}.\n\nTask:\n{task}\n\nContext:\n{outputs.context}\n\nPrevious review, if any:\n{outputs.review.output}\n\nReturn a practical implementation plan with scope, non-goals, acceptance criteria, likely files, validation commands, risks, and open questions. Do not edit files."
31
+ },
32
+ {
33
+ "id": "review",
34
+ "agent": "reviewer",
35
+ "output": "plan-review-{loop.iteration}.json",
36
+ "gate": {
37
+ "type": "json-status",
38
+ "passStatuses": ["approved"],
39
+ "retryStatuses": ["changes_requested"],
40
+ "stopStatuses": ["blocked"]
41
+ },
42
+ "task": "Review this implementation plan before any code is written. Do not edit files.\n\nTask:\n{task}\n\nContext:\n{outputs.context}\n\nPlan:\n{outputs.plan}\n\nReturn ONLY valid JSON:\n{\n \"status\": \"approved\" | \"changes_requested\" | \"blocked\",\n \"summary\": \"short verdict\",\n \"findings\": [{\"severity\": \"blocker|required|optional\", \"issue\": \"specific issue\", \"required_fix\": \"specific plan change or null\"}],\n \"missing_acceptance_criteria\": [\"criterion\"],\n \"requires_user_decision\": false\n}\n\nApprove only if the plan is specific, scoped, testable, and safe to hand to a worker. Request changes for vague scope, missing validation, or unclear acceptance criteria. Block when user/product decisions or credentials are required."
43
+ }
44
+ ]
45
+ }
46
+ }
47
+ ]
48
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-loopflows",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Deterministic loop workflows for Pi subagents: steps, gates, feedback loops, and artifacts.",
5
5
  "license": "MIT",
6
6
  "author": "Nikita Nosov <20nik.nosov21@gmail.com>",
@@ -26,6 +26,7 @@
26
26
  "extensions",
27
27
  "loopflows",
28
28
  "skills",
29
+ "scripts",
29
30
  "README.md",
30
31
  "LICENSE",
31
32
  "CHANGELOG.md"
@@ -36,8 +37,7 @@
36
37
  ],
37
38
  "skills": [
38
39
  "./skills"
39
- ],
40
- "image": "https://raw.githubusercontent.com/nik1t7n/pi-loopflows/main/assets/pi-loopflows.png"
40
+ ]
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@earendil-works/pi-coding-agent": "*",
@@ -51,6 +51,8 @@
51
51
  },
52
52
  "scripts": {
53
53
  "typecheck": "tsc --noEmit",
54
- "pack:check": "npm pack --dry-run"
54
+ "pack:check": "npm pack --dry-run",
55
+ "validate": "node scripts/validate.mjs",
56
+ "prepublishOnly": "npm run validate && npm run typecheck && npm run pack:check"
55
57
  }
56
58
  }
@@ -0,0 +1,71 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ const root = path.resolve(new URL('..', import.meta.url).pathname);
5
+ const loopflowsDir = path.join(root, 'loopflows');
6
+ const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
7
+
8
+ const errors = [];
9
+
10
+ function assert(condition, message) {
11
+ if (!condition) errors.push(message);
12
+ }
13
+
14
+ assert(pkg.name === 'pi-loopflows', 'package name must be pi-loopflows');
15
+ assert(pkg.keywords?.includes('pi-package'), 'package must include pi-package keyword');
16
+ assert(pkg.pi?.extensions?.includes('./extensions'), 'package pi manifest must expose extensions');
17
+ assert(pkg.pi?.skills?.includes('./skills'), 'package pi manifest must expose skills');
18
+
19
+ const files = fs.readdirSync(loopflowsDir).filter((file) => file.endsWith('.loopflow.json'));
20
+ assert(files.length >= 3, 'expected bundled launch-control, build-review, and plan-review loopflows');
21
+
22
+ for (const file of files) {
23
+ const full = path.join(loopflowsDir, file);
24
+ let wf;
25
+ try {
26
+ wf = JSON.parse(fs.readFileSync(full, 'utf8'));
27
+ } catch (error) {
28
+ errors.push(`${file}: invalid JSON: ${error.message}`);
29
+ continue;
30
+ }
31
+
32
+ assert(typeof wf.name === 'string' && wf.name.length > 0, `${file}: missing name`);
33
+ assert(typeof wf.description === 'string' && wf.description.length > 0, `${file}: missing description`);
34
+ assert(Array.isArray(wf.steps) && wf.steps.length > 0, `${file}: steps must be a non-empty array`);
35
+
36
+ const topLevelIds = new Set();
37
+ for (const [index, node] of wf.steps.entries()) {
38
+ if (node.loop) {
39
+ const loop = node.loop;
40
+ assert(typeof loop.id === 'string' && loop.id.length > 0, `${file}: loop ${index} missing id`);
41
+ assert(Number.isInteger(loop.maxIterations) && loop.maxIterations > 0, `${file}: loop ${loop.id} maxIterations must be positive integer`);
42
+ assert(Array.isArray(loop.body) && loop.body.length > 0, `${file}: loop ${loop.id} body must be non-empty`);
43
+ assert(typeof loop.gateStep === 'string' && loop.gateStep.length > 0, `${file}: loop ${loop.id} missing gateStep`);
44
+ const bodyIds = new Set(loop.body.map((step) => step.id));
45
+ assert(bodyIds.has(loop.gateStep), `${file}: loop ${loop.id} gateStep not present in body`);
46
+ for (const step of loop.body) validateStep(file, step, `loop ${loop.id}`);
47
+ } else {
48
+ validateStep(file, node, `step ${index}`);
49
+ if (node.id) {
50
+ assert(!topLevelIds.has(node.id), `${file}: duplicate top-level step id ${node.id}`);
51
+ topLevelIds.add(node.id);
52
+ }
53
+ }
54
+ }
55
+ }
56
+
57
+ function validateStep(file, step, label) {
58
+ assert(typeof step.id === 'string' && step.id.length > 0, `${file}: ${label} missing id`);
59
+ assert(typeof step.agent === 'string' && step.agent.length > 0, `${file}: ${label} missing agent`);
60
+ assert(typeof step.task === 'string' && step.task.length > 0, `${file}: ${label} missing task`);
61
+ if (step.gate) {
62
+ assert(step.task.includes('JSON') || step.task.includes('json'), `${file}: gate step ${step.id} should explicitly request JSON`);
63
+ }
64
+ }
65
+
66
+ if (errors.length) {
67
+ console.error(errors.map((e) => `- ${e}`).join('\n'));
68
+ process.exit(1);
69
+ }
70
+
71
+ console.log(`Validated ${files.length} loopflows for ${pkg.name}@${pkg.version}`);
@@ -1,19 +1,19 @@
1
1
  ---
2
2
  name: loopflows
3
- description: Use when the user wants deterministic multi-agent workflows, feedback loops between builder/reviewer agents, launch-control style implementation gates, or repeatable Pi subagent processes with max iterations, gates, stop conditions, and artifacts.
3
+ description: Use when the user wants deterministic multi-agent workflows, feedback loops between builder/reviewer agents, launch-control style implementation gates, repeatable Pi subagent processes, or custom workflow construction with max iterations, gates, stop conditions, and artifacts.
4
4
  ---
5
5
 
6
6
  # Loopflows
7
7
 
8
- Use `loopflow_run` for deterministic agent workflows that need real control flow instead of a linear chain.
8
+ Use `loopflow_run` when a task needs process control, not just a linear chain.
9
9
 
10
- Prefer loopflows when work needs:
10
+ A loopflow is a reusable workflow made from subagent steps, gates, and loops. Use it when work should be checked, sent back for fixes, capped by max iterations, or stopped when evidence is missing.
11
11
 
12
- - a builder/reviewer feedback loop;
13
- - explicit pass/retry/stop gates;
14
- - max iteration limits;
15
- - saved evidence artifacts;
16
- - launch-control style plan build review fix → audit flow.
12
+ ## Built-in loopflows
13
+
14
+ - `launch-control` strict plan-as-contract flow: context → plan → build/review loop → final audit.
15
+ - `build-review` lightweight implementation loop for scoped changes.
16
+ - `plan-review` review and revise a plan before implementation starts.
17
17
 
18
18
  ## Commands
19
19
 
@@ -38,3 +38,7 @@ loopflow_run({ workflow: "launch-control", task: "...", maxIterations: 3 })
38
38
  ## Rule of thumb
39
39
 
40
40
  Use `pi-subagents` chains for simple linear handoffs. Use `pi-loopflows` when a gate can send work backward for fixes or stop the run.
41
+
42
+ ## Customization
43
+
44
+ Loopflows are `.loopflow.json` files. Copy bundled workflows into `.pi/loopflows/` to customize them for a project: change agents, prompts, max iterations, pass/retry/stop statuses, or final audit rules.