@tianhai/pi-workflow-kit 1.3.0 → 1.5.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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  AI coding agents tend to skip design and jump straight into implementation, producing over-engineered or misaligned code. **pi-workflow-kit** solves this by hard-blocking write operations during brainstorm and planning phases — the agent *literally cannot modify your source files* until you approve the design.
6
6
 
7
- [pi](https://github.com/badlogic/pi-mono) package. Zero configuration required.
7
+ [pi](https://github.com/badlogic/pi-mono) package. Skills are portable; the workflow guard and `/pwk-setup` command are Pi integrations.
8
8
 
9
9
  ## Install
10
10
 
@@ -12,7 +12,13 @@ AI coding agents tend to skip design and jump straight into implementation, prod
12
12
  pi install npm:@tianhai/pi-workflow-kit
13
13
  ```
14
14
 
15
- No setup needed skills and guards activate automatically after install.
15
+ For Pi delegation providers that discover project agents, install the canonical PWK roles before starting a gated workflow:
16
+
17
+ ```text
18
+ /pwk-setup
19
+ ```
20
+
21
+ This creates the five role definitions under `.agents/agents/`. It does not install or configure a provider. Existing customized files are preserved; use `/pwk-setup --force` only when you explicitly want to replace differing role files. Run setup before `/skill:pwk-brainstorming`; the command is refused during brainstorm and plan phases.
16
22
 
17
23
  **Want to try before committing?**
18
24
 
@@ -20,13 +26,19 @@ No setup needed — skills and guards activate automatically after install.
20
26
  pi -e npm:@tianhai/pi-workflow-kit
21
27
  ```
22
28
 
23
- **Optional — parallel code review.** The feature-level review can run four specialized reviewers in parallel over the whole feature diff via the `subagent` tool. Install [`pi-subagents`](https://pi.dev/packages/pi-subagents) to enable it:
29
+ **Optional — delegated recon and review.** The skills request logical capabilities rather than a specific agent tool. If the host has no safe compatible provider, they perform recon and review inline. In Pi, [`@tintinweb/pi-subagents`](https://github.com/tintinweb/pi-subagents) is one compatible provider:
24
30
 
25
31
  ```bash
26
- pi install npm:pi-subagents
32
+ pi install npm:@tintinweb/pi-subagents
27
33
  ```
28
34
 
29
- The four reviewers (`pwk-spec-reviewer`, `pwk-tracing-reviewer`, `pwk-smell-reviewer`, `pwk-hazard-reviewer`) ship with this kit as **package agents** — `pi-subagents` discovers them automatically, no extra setup. Without `pi-subagents`, `pwk-executing-tasks` falls back to inline `/skill:pwk-code-review`.
35
+ After `/pwk-setup`, Tintinweb can discover the five named roles from `.agents/agents/`; recon can also use its built-in read-only `Explore` agent. No running subagents need to be pre-created. Other Pi extensions require the documented capabilities or a separate adapter; arbitrary extensions are not automatically compatible.
36
+
37
+ ### Using the roles on other hosts
38
+
39
+ The five role files define portable logical roles, not a required provider API. Claude Code can map them to its native read-only task/subagent mechanism, but must enforce its own permissions or hooks because the Pi workflow guard does not transfer outside Pi. A different Pi extension can use the same roles when it provides the documented capabilities or an adapter; otherwise PWK performs recon and review inline.
40
+
41
+ See [`docs/provider-delegation-contract.md`](docs/provider-delegation-contract.md) for the normalized capability and outcome contract. The core kit does not install a provider, require `@tintinweb/pi-subagents`, or provide automatic compatibility with every Pi subagent extension.
30
42
 
31
43
  ## What You Get
32
44
 
@@ -58,10 +70,10 @@ A **design doc is one PR**; a **requirement is one testable slice within it**. A
58
70
 
59
71
  | Phase | Trigger | What Happens |
60
72
  |-------|---------|--------------|
61
- | **Brainstorm** | `/skill:pwk-brainstorming` | Explore approaches, produce a design doc with a `## Requirements` list |
73
+ | **Brainstorm** | `/skill:pwk-brainstorming` | Explore approaches, produce a design doc with a `## Requirements` list. On non-trivial topics, requests the logical `codebase-recon` capability; if unavailable or unsafe, performs the `pwk-recon-scout` role inline. |
62
74
  | **Plan** | `/skill:pwk-writing-plans` | Turn each requirement into **acceptance criteria + integration tests** — a behavioral spec (no implementation code) |
63
75
  | **Execute** | `/skill:pwk-executing-tasks` | Write the feature E2E (red) → **checkpoint: feature-spec** → implement requirements → **checkpoint: feature-complete** → feature review |
64
- | **Code review** | `/skill:pwk-code-review` | Feature-level (default) or per-requirement: code tracing, spec alignment, code smells (applies fixes), production hazard check |
76
+ | **Code review** | `/skill:pwk-code-review` | Feature-level (default) or per-requirement: code tracing, spec alignment, code smells (applies fixes), production hazard check. Delegated review uses four logical roles when a safe provider is available; otherwise it runs inline. |
65
77
  | **Finalize** | `/skill:pwk-finalizing` | Delete consumed plan docs, update README/CHANGELOG, create PR |
66
78
  | **Diagnose** | `/skill:pwk-diagnose` | Debugging loop: reproduce → hypothesise → instrument → fix → cleanup. **Exits the gated phase** (debugging writes tests/instrumentation) |
67
79
  | **Status** | `/skill:pwk-status` | Read-only overview of all active design topics — phase + progress. Use when resuming or juggling several designs in parallel worktrees. Not a pipeline phase; **does not exit the gated phase**. |
@@ -177,11 +189,12 @@ pi-workflow-kit/
177
189
  │ ├── pwk-finalizing/SKILL.md
178
190
  │ ├── pwk-status/SKILL.md
179
191
  │ └── pwk-diagnose/SKILL.md
180
- ├── agents/ # package agents for parallel code-review (discovered by pi-subagents)
192
+ ├── agents/ # canonical role contracts; /pwk-setup copies them to .agents/agents/
181
193
  ├── docs/
182
194
  │ ├── developer-usage-guide.md
183
195
  │ ├── workflow-phases.md
184
196
  │ ├── oversight-model.md
197
+ │ ├── provider-delegation-contract.md
185
198
  │ ├── lessons.md
186
199
  │ ├── adr/ # permanent architectural decisions (never archived)
187
200
  │ └── plans/ # active design/plan/progress docs (deleted after finalization)
@@ -7,7 +7,11 @@ systemPromptMode: replace
7
7
 
8
8
  # PWK Hazard Reviewer
9
9
 
10
- You are a production-hazards reviewer. Execute the task instructions below faithfully using read-only tools (`read`, `grep`, `find`, `bash`). **Report findings only — do NOT modify files.** Flag hazards and non-trivial issues for the main agent / human to decide.
10
+ You are a production-hazards reviewer. Execute the task instructions below faithfully using the host’s read-only tools. **Report findings only — do not modify files.** Flag hazards and non-trivial issues for the main agent or human to decide.
11
+
12
+ ## Authority boundary
13
+
14
+ The host must enforce read-only execution. Do not create, modify, delete, move, or copy files, and do not run commands that mutate system or repository state.
11
15
 
12
16
  ## Checklist — audit each changed file
13
17
 
@@ -21,4 +25,6 @@ For each item below, write `[SAFE]` (1-line justification) or `[TRIGGERED]` (con
21
25
  6. **Unrestricted uploads / temp flooding** — uploads to local temp without limits or `finally` cleanup
22
26
  7. **Silent swallowing loops** — background workers catching/suppressing exceptions without logging/back-off
23
27
 
24
- Also check the design doc's `## Production-risk areas`, if any.
28
+ Also check the design docs `## Production-risk areas`, if any.
29
+
30
+ Include file and line evidence for each finding. If there are no findings, report `No findings` explicitly.
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: pwk-recon-scout
3
+ description: Codebase recon scout — maps how a repo handles a topic before design. Produces a 5-section observation report (no recommendations, no design opinion). Read-only reporter.
4
+ tools: read, grep, find, ls, bash
5
+ systemPromptMode: replace
6
+ ---
7
+
8
+ # PWK Recon Scout
9
+
10
+ You are a codebase recon scout requested during brainstorming before design work. Your job is to map how a repository handles a topic today so the main agent can design against prior art instead of loading the relevant files into its own context.
11
+
12
+ **You are observations only.** No design recommendations, no preferred-approach opinion, no code beyond one-line excerpts. Every claim must cite a `file:line` so the main agent can drill in if it needs to.
13
+
14
+ ## Authority boundary
15
+
16
+ You are a read-only reporter. The host must enforce the requested read-only boundary; do not create, modify, delete, move, or copy files, and do not run commands that mutate system or repository state.
17
+
18
+ ## Inputs
19
+
20
+ The host provides three things:
21
+
22
+ - a `<topic>` (one short phrase, the new feature or change)
23
+ - a one-line `<intent>` (what the new thing does, in plain words)
24
+ - the repository root
25
+
26
+ If any of these is missing, ask for it before proceeding.
27
+
28
+ ## Output — the 5-section codebase map
29
+
30
+ Return a single markdown report with these five sections, in this order. Each section is a short bulleted list (5-10 bullets is the sweet spot; fewer is fine, more is a smell that you did not stay narrow).
31
+
32
+ ### Relevant files
33
+
34
+ Paths that matter for the topic, each with a one-line role. Group by subdirectory if the repo has clear layering; otherwise a flat list is fine.
35
+
36
+ ### Existing patterns
37
+
38
+ How the codebase does similar work today. Cite the file:line for the pattern. Include 2-4 patterns — the new design will compose with these, so the main agent needs to know what conventions are non-negotiable.
39
+
40
+ ### Call sites
41
+
42
+ Where the new behavior would plug in, or which existing wiring it would change. Distinguish **read-side call sites** (consumers of the current behavior) from **write-side call sites** (the functions or entry points that would need updating).
43
+
44
+ ### Test layout
45
+
46
+ Where similar tests live, what harness they use (vitest, jest, go test, etc.), and one or two example test names to mimic. If the codebase has a custom fixture that is painful to build, call it out here so the main agent does not discover it during the planning phase.
47
+
48
+ ### Gotchas
49
+
50
+ Anything that bit a previous change, in this layer of the code or in the topic area specifically. A migrations folder that must run in order, a feature flag that gates the new path, a known deadlock with another subsystem, an environment variable that has to be set, a CI hook that runs before tests. The point is to surface landmines before the planning phase.
51
+
52
+ End with `Scout: complete` when the five sections are present. If the host cannot complete the report, return `Scout: unavailable` with the reason instead of inventing observations.
53
+
54
+ ## Hard rules
55
+
56
+ - **Cite a file:line per claim.** No assertions without a citation. The main agent treats your report as a map, not a summary.
57
+ - **Observations only.** No `I recommend`, no `the right approach is`, no `consider doing X`. If you have an opinion, surface it as a neutral fact: e.g. `the codebase has three different error formats` is fine; `the codebase should standardize on one` is not.
58
+ - **Stay narrow.** If the topic is `add OAuth2 login`, do not also report on the entire auth subsystem. Cover the call sites and patterns the new feature will actually touch.
59
+ - **Do not paste code blocks longer than five lines.** One-line excerpts are fine for context. Anything longer means the main agent should read the file itself.
60
+ - **Time-box.** If after 10 tool calls the topic has no prior art in the repo, report that and stop. An empty codebase map is a useful signal: the topic is greenfield.
61
+
62
+ ## When you finish
63
+
64
+ Return the report as your final message. The main agent reads it into its context and uses it as the grounding context for approach exploration and design presentation.
65
+
66
+ ## Failure modes
67
+
68
+ - If no compatible read-only delegation worker is available, the main agent performs this role inline.
69
+ - If the role cannot complete, return `Scout: unavailable` with the reason rather than returning an empty or invented report.
@@ -7,11 +7,21 @@ systemPromptMode: replace
7
7
 
8
8
  # PWK Smell Reviewer
9
9
 
10
- You are a code-smell reviewer. Execute the task instructions below faithfully using read-only tools (`read`, `grep`, `find`, `bash`). **Report findings only — do NOT modify files.** Flag only: smells that require large refactors risky to the requirement; everything else is for the main agent to fix.
10
+ You are a code-smell reviewer. Execute the task instructions below faithfully using the host’s read-only tools. **Report findings only — do not modify files.** Flag only smells that require large refactors risky to the requirement; everything else is for the main agent to fix.
11
+
12
+ ## Authority boundary
13
+
14
+ The host must enforce read-only execution. Do not create, modify, delete, move, or copy files, and do not run commands that mutate system or repository state.
15
+
16
+ ## Review scope
17
+
18
+ Review the changed code and affected files against the assigned requirement and feature scope.
11
19
 
12
20
  ## Checklist — report what you find
13
21
 
14
22
  - Shallow modules (interface nearly as complex as implementation)
15
23
  - Duplication
16
- - Missing seams / premature abstraction
17
- - Poor naming, magic values, dead code
24
+ - Missing seams or premature abstraction
25
+ - Poor naming, magic values, dead code
26
+
27
+ Include file and line evidence for each finding. If there are no findings, report `No findings` explicitly.
@@ -7,8 +7,12 @@ systemPromptMode: replace
7
7
 
8
8
  # PWK Spec Reviewer
9
9
 
10
- You are a spec-alignment reviewer. Execute the task instructions below faithfully using read-only tools (`read`, `grep`, `find`, `bash`). **Report findings only — do NOT modify files.**
10
+ You are a spec-alignment reviewer. Execute the task instructions below faithfully using the host’s read-only tools. **Report findings only — do not modify files.**
11
+
12
+ ## Authority boundary
13
+
14
+ The host must enforce read-only execution. Do not create, modify, delete, move, or copy files, and do not run commands that mutate system or repository state.
11
15
 
12
16
  ## Checklist
13
17
 
14
- For each acceptance criterion, point to the code and the test that satisfy it. A criterion with no covering code or no test is a **gap**. Code that does more than the criteria specify is **scope creep** — flag it.
18
+ For each acceptance criterion, point to the code and the test that satisfy it. A criterion with no covering code or no test is a **gap**. Code that does more than the criteria specify is **scope creep** — flag it. Include the relevant file and line for each finding. If there are no findings, report `No findings` explicitly.
@@ -7,8 +7,12 @@ systemPromptMode: replace
7
7
 
8
8
  # PWK Trace Reviewer
9
9
 
10
- You are a code-tracing reviewer. Execute the task instructions below faithfully using read-only tools (`read`, `grep`, `find`, `bash`). **Report findings only — do NOT modify files.**
10
+ You are a code-tracing reviewer. Execute the task instructions below faithfully using the host’s read-only tools. **Report findings only — do not modify files.**
11
+
12
+ ## Authority boundary
13
+
14
+ The host must enforce read-only execution. Do not create, modify, delete, move, or copy files, and do not run commands that mutate system or repository state.
11
15
 
12
16
  ## Checklist
13
17
 
14
- Trace the new/changed code paths end-to-end against the integration tests. For each path: does data flow correctly from entry to the asserted outcome? Note any branch the tests don't exercise, any dead branch, any path where the trace breaks.
18
+ Trace the new or changed code paths end-to-end against the integration tests. For each path, determine whether data flows correctly from entry to the asserted outcome. Note any branch the tests do not exercise, any dead branch, or any path where the trace breaks. Include file and line evidence. If there are no findings, report `No findings` explicitly.
@@ -1,6 +1,6 @@
1
1
  # Developer Usage Guide
2
2
 
3
- How to install and use `pi-workflow-kit` with the Pi coding agent.
3
+ How to install and use `pi-workflow-kit` with Pi, and how its workflow roles map to other agent hosts.
4
4
 
5
5
  ## What you get
6
6
 
@@ -40,11 +40,19 @@ You control each phase by invoking the skill. A design doc is one PR; a requirem
40
40
 
41
41
  ### 1. Brainstorm
42
42
 
43
+ Before entering the gated phase in Pi, optionally install the canonical role definitions:
44
+
45
+ ```
46
+ /pwk-setup
47
+ ```
48
+
49
+ The command creates `.agents/agents/` and installs the five PWK roles. It preserves differing files unless `--force` is supplied and is refused during brainstorm and plan phases. It does not install a delegation provider.
50
+
43
51
  ```
44
52
  /skill:pwk-brainstorming
45
53
  ```
46
54
 
47
- Explore the idea through collaborative dialogue. The agent reads code, asks questions, proposes approaches, and presents the design for your review.
55
+ Explore the idea through collaborative dialogue. The agent reads code, asks questions, proposes approaches, and presents the design for your review. On non-trivial topics with prior art, the skill requests the logical `codebase-recon` capability using the `pwk-recon-scout` role. A compatible host may dispatch that role in a fresh, bounded, read-only worker; otherwise the skill reports `Scout: unavailable` and performs the same five-section recon inline.
48
56
 
49
57
  Outcome: `docs/plans/YYYY-MM-DD-<topic>-design.md` — descriptive, opening with a `## Requirements` list. For a too-big requirement, may start an **umbrella** (writes a status-free overview + the first part's design doc). ADRs go to `docs/adr/` (permanent).
50
58
 
@@ -68,13 +76,11 @@ Implement via the **feature-gate flow** with full autonomy: write the feature-ac
68
76
 
69
77
  ### 4. Code review (feature level)
70
78
 
71
- The `pwk-executing-tasks` skill invokes the `subagent` tool automatically at the feature-level review (programmatic, not user-driven). Four specialized reviewers launch in parallel over the whole feature diff — each from a different dimension (spec gaps & scope creep, end-to-end code tracing, code smells, production hazards). A per-requirement review runs the same way for a tagged requirement. The reviewers ship as **package agents** (`agents/pwk-*.md`, declared via the `pi-subagents.agents` manifest key) and are discovered natively by the optional **`pi-subagents`** package — no copy step. All report findings only; no agent edits files or produces commits. The main agent collects results, applies smell fixes itself, runs integration tests after each fix, then updates progress to `✅ done`.
79
+ The `pwk-executing-tasks` skill requests the `parallel-review` capability for four logical roles over the whole feature diff: spec alignment, code tracing, code smells, and production hazards. The roles are independent, fresh-context, read-only reporters; the main agent collects their results, applies smell fixes itself, runs the tests, and flags other findings for the human.
72
80
 
73
- *Fallback:* if `pi-subagents` is not installed (so the `subagent` tool is unavailable), the skill falls back to inline `/skill:pwk-code-review` as before. Install it to enable parallel review:
81
+ In Pi, `/pwk-setup` installs the canonical role definitions into `.agents/agents/`, where compatible providers such as `@tintinweb/pi-subagents` can discover them. Tintinweb may run the roles through its native `Agent` mechanism or map recon to its built-in read-only `Explore` type. The core kit does not require Tintinweb or any other provider.
74
82
 
75
- ```bash
76
- pi install npm:pi-subagents
77
- ```
83
+ *Fallback:* if no host/provider can guarantee the requested capabilities, the skill performs the missing recon or review work inline. Other Pi extensions are supported only when they expose the documented capabilities or have a separate adapter; arbitrary extensions are not automatically compatible. See `docs/provider-delegation-contract.md` for the integration contract.
78
84
 
79
85
  ### 5. Finalize
80
86
 
@@ -102,7 +108,7 @@ A read-only overview of all active design topics — which phase each is in and
102
108
 
103
109
  ## What the extension does
104
110
 
105
- The `workflow-guard` extension watches `write`/`edit` and `bash` tool calls:
111
+ The `workflow-guard` extension registers `/pwk-setup` and watches `write`/`edit` and `bash` tool calls:
106
112
 
107
113
  - **During brainstorm and writing-plans**: blocks writes outside `docs/plans/`, and blocks destructive bash via a simple common-blacklist (a command is allowed unless it matches a destructive pattern). A short phase reminder is shown once when the gated phase begins so the model self-restricts.
108
114
  - **During executing-tasks, code-review, finalizing, diagnose**: no restrictions.
@@ -121,5 +127,5 @@ Plans specify *what* (acceptance criteria + integration tests); the executor wri
121
127
  - Start with brainstorming for anything non-trivial.
122
128
  - The plan is a behavioral spec, not an implementation recipe — let the executor choose how.
123
129
  - The feature-gate flow has two checkpoints by default (feature-spec + feature-complete): use them to steer the E2E spec and the finished implementation.
124
- - **Right-size each requirement at plan time** with the `### Checkpoints` (`none`/`full`/`spec`, default `none`) and `### Review` (`skip`/`parallel`/`inline`, default `skip`) tags — per-requirement ceremony is opt-in. The always-on feature-level `### Feature review` covers the whole diff. `spec` keeps the cheap spec-correctness gate and drops the complete checkpoint (covered by review), so it requires at least `inline` review. A trivial fix can also use the brainstorming trivial fast-path (one-turn brainstorm, minimal design doc).
130
+ - **Right-size each requirement at plan time** with the `### Checkpoints` (`none`/`full`/`spec`, default `none`) and `### Review` (`skip`/`parallel`/`inline`, default `skip`) tags — per-requirement ceremony is opt-in. The always-on feature-level `### Feature review` covers the whole diff. `spec` keeps the cheap spec-correctness gate and drops the complete checkpoint (covered by review), so it requires at least `inline` review. A trivial fix can also use the brainstorming trivial fast-path (one-turn brainstorm, minimal design doc). Production-risk requirements are auto-tagged `### Review: parallel` by `pwk-writing-plans`; the human can override or downgrade before plan approval.
125
131
  - Put all plan artifacts under `docs/plans/`; ADRs under `docs/adr/`.
@@ -6,10 +6,10 @@
6
6
 
7
7
  Skills teach the agent the workflow. There are 5 pipeline skills:
8
8
 
9
- - **pwk-brainstorming** — explore ideas, produce a descriptive design doc that opens with a `## Requirements` list. For a requirement too big for one design doc, may start an **umbrella** (multiple design docs under one status-free overview, shipping as one PR)
9
+ - **pwk-brainstorming** — explore ideas, produce a descriptive design doc that opens with a `## Requirements` list. For a requirement too big for one design doc, may start an **umbrella** (multiple design docs under one status-free overview, shipping as one PR). On non-trivial topics, requests the logical `codebase-recon` capability and falls back to the `pwk-recon-scout` role inline when unavailable or unsafe.
10
10
  - **pwk-writing-plans** — turn each requirement into acceptance criteria + integration-test cases (a behavioral spec, no implementation code)
11
11
  - **pwk-executing-tasks** — feature-gate flow: write the feature E2E first, implement the requirements, then one feature-level review; two mandatory checkpoints at the feature level, per-requirement ceremony opt-in
12
- - **pwk-code-review** — the inline reviewer (code tracing, spec alignment, code smells, production hazards). During `pwk-executing-tasks`, the **feature-level review** (the default) runs **four specialized reviewers in parallel** over the whole feature diff via the `subagent` tool, each from a fresh context (spec gaps & scope creep, tracing, smells, hazards); a per-requirement review runs the same way for a tagged requirement. These ship as package agents (`agents/pwk-*.md`) discovered natively by the optional **`pi-subagents`** package; all report findings only fixes are applied by the executing-tasks main agent. Falls back to inline `/skill:pwk-code-review` when `pi-subagents` is not installed.
12
+ - **pwk-code-review** — the inline reviewer (code tracing, spec alignment, code smells, production hazards). During `pwk-executing-tasks`, the feature-level review requests the `parallel-review` capability for four logical fresh-context, read-only roles; successful reports are retained and missing roles are retried or completed inline. It falls back to inline review when no safe compatible provider exists. The canonical provider contract is documented in `docs/provider-delegation-contract.md`.
13
13
  - **pwk-finalizing** — dispose consumed plan docs (archive or delete; for an umbrella, the overview + every part), curate lessons, update docs, create PR or merge
14
14
 
15
15
  Plus 2 on-demand skills:
@@ -21,7 +21,7 @@ They explain *what* to do and *when* to do it. Phase control is manual — you i
21
21
 
22
22
  ## Extension
23
23
 
24
- The `workflow-guard` extension enforces one rule:
24
+ The `workflow-guard` extension registers the Pi-only `/pwk-setup` command and enforces one workflow rule:
25
25
 
26
26
  > During brainstorm and plan phases, `write` and `edit` are **hard-blocked** outside `docs/plans/`.
27
27
 
@@ -29,7 +29,7 @@ The agent can still use `read` and `bash` for investigation. During those gated
29
29
 
30
30
  During executing-tasks, code-review, finalizing, **and diagnose**, nothing is restricted (diagnosis needs to write failing tests and debug instrumentation, so it exits the gate). `pwk-status` stays inside the gate.
31
31
 
32
- Reviewer-agent checklists live only in `agents/pwk-*-reviewer.md` (single source of truth); `pwk-executing-tasks` passes each reviewer just the requirement scope + diff and names the agent.
32
+ Canonical role contracts live in `agents/pwk-*.md` (single source of truth) and can be installed into `.agents/agents/` with `/pwk-setup`. `pwk-executing-tasks` requests logical review roles through the host’s delegation capabilities and passes each role just the requirement scope + diff.
33
33
 
34
34
  Phases follow the skill you invoke — there is no message-keyword unlock. Invoking `/skill:pwk-executing-tasks`, `pwk-finalizing`, `pwk-code-review`, or `pwk-diagnose` exits the gated phase (those skills write source); `pwk-status` deliberately does **not** (read-only orientation). `/pwk-guard on|off|auto` manually overrides the guard.
35
35
 
@@ -0,0 +1,112 @@
1
+ # Provider Delegation Contract
2
+
3
+ This document defines the provider-neutral contract for running PWK roles outside the main agent. It is an integration contract for host adapters and extensions. The workflow skills describe the same behavior in portable language; they do not require this document’s TypeScript notation or any specific transport.
4
+
5
+ ## Logical operations
6
+
7
+ A provider may support either operation independently:
8
+
9
+ - `codebase-recon` — run one `pwk-recon-scout` role and return its five-section observation map.
10
+ - `feature-review` — run the requested review roles over one feature scope and return one outcome per role.
11
+
12
+ The logical role name is not the provider’s concrete agent type. A provider may map `pwk-recon-scout` to a safe built-in explorer, a custom agent definition, or a host-native read-only task.
13
+
14
+ ## Required capabilities
15
+
16
+ A provider advertises capabilities independently from its name:
17
+
18
+ | Capability | Meaning |
19
+ |---|---|
20
+ | `codebase-recon` | Can run one fresh, read-only recon worker and collect its report. |
21
+ | `named-role-dispatch` | Can map each requested logical role to an appropriate worker. |
22
+ | `parallel-review` | Can run independent review roles concurrently when requested. |
23
+ | `result-collection` | Returns one distinguishable outcome for every requested role. |
24
+ | `read-only-enforcement` | Prevents delegated workers from writing files or running destructive commands. |
25
+ | `fresh-context` | Starts each requested worker without reusing an unrelated prior conversation. |
26
+ | `bounded-execution` | Applies a timeout, turn limit, or equivalent resource bound. |
27
+
28
+ A provider must not claim `read-only-enforcement` when it only adds a prompt instruction. Providers may support `codebase-recon` without supporting `parallel-review`.
29
+
30
+ ## Request shape
31
+
32
+ The following TypeScript is illustrative. Implementations may use Pi events, tool calls, CLI processes, native task APIs, or another transport. A reference implementation of the outcome normalization lives in `extensions/workflow-guard.ts` (`assessDelegationCoverage`), exported as a pure helper so future adapters and tests share one definition of complete coverage.
33
+
34
+ ```ts
35
+ type DelegationOperation = 'codebase-recon' | 'feature-review';
36
+ type DelegationRole =
37
+ | 'pwk-recon-scout'
38
+ | 'pwk-spec-reviewer'
39
+ | 'pwk-tracing-reviewer'
40
+ | 'pwk-smell-reviewer'
41
+ | 'pwk-hazard-reviewer';
42
+
43
+ type DelegationRequest = {
44
+ operation: DelegationOperation;
45
+ roles: DelegationRole[];
46
+ prompt: string;
47
+ cwd: string;
48
+ constraints: {
49
+ readOnly: true;
50
+ freshContext: true;
51
+ parallel: boolean;
52
+ bounded: true;
53
+ };
54
+ };
55
+ ```
56
+
57
+ The provider must preserve the logical roles and the repository root when translating a request. `parallel: true` requests concurrency; it does not permit unbounded concurrency. If the provider cannot satisfy a requested constraint, it must reject the delegated operation so the host can use inline fallback.
58
+
59
+ ## Normalized outcome shape
60
+
61
+ ```ts
62
+ type DelegationStatus = 'completed' | 'failed' | 'timed-out' | 'skipped';
63
+
64
+ type DelegationResult = {
65
+ role: DelegationRole;
66
+ status: DelegationStatus;
67
+ report?: string;
68
+ error?: string;
69
+ provider?: string;
70
+ runId?: string;
71
+ };
72
+ ```
73
+
74
+ Rules:
75
+
76
+ - `role` is required and must identify one requested logical role.
77
+ - `completed` requires a non-empty `report` that follows the role contract.
78
+ - `failed` and `timed-out` require an `error` or equivalent failure explanation.
79
+ - `skipped` is explicit and is not equivalent to completion.
80
+ - `provider` identifies the adapter or host that produced the outcome when known.
81
+ - `runId` is an opaque provider-local identifier when available; consumers must not interpret its format.
82
+ - A multi-role operation is complete only when every requested role has a completed result or an explicit fallback result approved by the workflow.
83
+
84
+ An empty report is not a successful result. A missing role is not silently discarded.
85
+
86
+ ## Fallback protocol
87
+
88
+ If no provider satisfies the requested capabilities, the host performs the role inline using the same logical contract. For recon, it reports:
89
+
90
+ ```text
91
+ Scout: unavailable — inline recon used.
92
+ ```
93
+
94
+ For feature review, successful delegated reports remain usable. A failed or timed-out role is retried or performed inline. The host does not report a complete review while a required role has neither a delegated result nor an inline result.
95
+
96
+ ## Provider discovery and selection
97
+
98
+ Provider discovery and transport are host-specific. A future Pi adapter may use a capability registry, an event-bus handshake, a shared extension RPC, or explicit configuration. The core PWK package does not assume that all Pi extensions are discoverable or that a package name identifies a compatible provider.
99
+
100
+ If multiple providers are available, selection must be deterministic. A host may use explicit configuration or a documented priority order. It must not select a provider based only on extension load order when that changes safety or result semantics.
101
+
102
+ ## Role setup and provider loading
103
+
104
+ The Pi-only `/pwk-setup` command copies the canonical role definitions into `.agents/agents/`. This makes named roles available to providers that discover the shared directory, including `@tintinweb/pi-subagents`. Setup creates role definitions; it does not install or configure a provider.
105
+
106
+ Providers may cache role definitions. Hosts should tell the user when `/reload` or a new session is needed. Setup must not reload a session implicitly.
107
+
108
+ ## Safety boundary
109
+
110
+ The provider is responsible for enforcing any capability it advertises. The role prompt is defense in depth, not a security boundary. The Pi workflow guard protects the main Pi session’s brainstorm and plan phases; it does not automatically protect Claude Code or another host, and it does not replace delegated-worker tool restrictions.
111
+
112
+ The `/pwk-setup` installer itself is hardened in depth: it opens the target with `O_NOFOLLOW` and does every subsequent check, read, and write through that one descriptor (`fstat` regular-file check, content comparison, and post-write verification), so nothing swapped in on the path afterward can affect what is read or written. On platforms where `O_NOFOLLOW` is unavailable, a symlink swapped in before the initial open remains a narrow advisory window; setup is a user-invoked development command, not a security boundary.
@@ -32,7 +32,7 @@ Write boundary: only `docs/plans/` is writable. Source files are hard-blocked.
32
32
  - Reads the design doc's `## Requirements`; for each, derives **acceptance criteria + integration-test cases** (a behavioral spec, no implementation code), lists requirements in build order (dependencies positioned earlier), and challenges the design when `## Production-risk areas` is present.
33
33
  - For an umbrella part, reads the `*-overview.md` to plan one slice (composing with earlier parts' code) and reuses the existing feature branch instead of creating a new one.
34
34
  - Derives a **`## Feature acceptance` section** in the plan from the design's Feature acceptance — the **primary enforced spec**, an end-to-end test the executor gates on first. If the design has none, stops and asks the human to brainstorm one.
35
- - Tags the plan: per-requirement `### Checkpoints`/`### Review` default to `none`/`skip` (opt-in), plus an always-on feature-level `### Feature review`. Flags only requirements with complex logic, the main part of the feature, or production-risk.
35
+ - Tags the plan: per-requirement `### Checkpoints`/`### Review` default to `none`/`skip` (opt-in), plus an always-on feature-level `### Feature review`. Flags only requirements with complex logic, the main part of the feature, or production-risk. Requirements with `### Production-risk notes` are auto-tagged `### Review: parallel` (see `pwk-writing-plans` for the rule).
36
36
  - Produce `docs/plans/YYYY-MM-DD-<topic>-implementation.md`.
37
37
 
38
38
  Write boundary: only `docs/plans/` is writable.
@@ -43,7 +43,7 @@ Write boundary: only `docs/plans/` is writable.
43
43
  /skill:pwk-executing-tasks
44
44
  ```
45
45
 
46
- - **Feature-gate flow:** write the feature-acceptance E2E test (red) → **⏸ checkpoint: feature-spec** (human confirms the E2E proves the feature) → implement the requirements back-to-back with full autonomy (the executor chooses structure/signatures/internals) → **⏸ checkpoint: feature-complete** (full suite + feature E2E green) → **feature review** (four parallel reviewers over the whole feature diff via the `subagent` tool; falls back to inline `/skill:pwk-code-review` when `pi-subagents` is absent — see [code-review](#code-review)).
46
+ - **Feature-gate flow:** write the feature-acceptance E2E test (red) → **⏸ checkpoint: feature-spec** (human confirms the E2E proves the feature) → implement the requirements back-to-back with full autonomy (the executor chooses structure/signatures/internals) → **⏸ checkpoint: feature-complete** (full suite + feature E2E green) → **feature review** (request the `parallel-review` capability for four logical read-only roles when the host supports it; otherwise run `/skill:pwk-code-review` inline — see [code-review](#code-review)).
47
47
  - Per-requirement checkpoints/reviews are **opt-in** — they fire only for requirements the plan tags (default off); see [Proportionality](#proportionality).
48
48
  - **Regression check after each commit** — run the full existing suite to catch cross-requirement regressions immediately. The feature E2E stays red until the last requirement and is gated only at `feature-complete` (the old integration gate folds into it).
49
49
  - Progress tracked in `docs/plans/*-progress.md` (feature phase + requirement checklist).
@@ -68,7 +68,7 @@ Flag a requirement for a checkpoint when it has complex logic or is the main par
68
68
 
69
69
  The **inline reviewer**: code tracing, spec alignment (vs acceptance criteria), code smells (applies fixes), production hazard check. Unlocked — may modify code to fix smells.
70
70
 
71
- **Not a phase you drive manually.** During `pwk-executing-tasks`, the **feature-level review** (the default) runs **four specialized reviewers in parallel** over the whole feature diff via the `subagent` tool (spec, tracing, smell, hazard — each fresh-context, read-only reporters); a per-requirement review runs the same way for a tagged requirement. This skill is the **fallback** when [`pi-subagents`](https://pi.dev/packages/pi-subagents) is not installed. You can also invoke `/skill:pwk-code-review` standalone for an ad-hoc review of any diff.
71
+ **Not a phase you drive manually.** During `pwk-executing-tasks`, the feature-level review requests four logical roles (`pwk-spec-reviewer`, `pwk-tracing-reviewer`, `pwk-smell-reviewer`, `pwk-hazard-reviewer`) through the host’s `parallel-review` capability. Roles are fresh-context, read-only reporters; successful reports are retained and failed roles are retried or completed inline. If no compatible provider is available, the whole review runs inline. In Pi, `/pwk-setup` installs the canonical role definitions into `.agents/agents/`; [`@tintinweb/pi-subagents`](https://github.com/tintinweb/pi-subagents) is one compatible provider. See `docs/provider-delegation-contract.md` for the provider contract. You can also invoke `/skill:pwk-code-review` standalone for an ad-hoc review of any diff.
72
72
 
73
73
  No write restrictions.
74
74
 
@@ -1,4 +1,17 @@
1
- import { resolve } from "node:path";
1
+ import {
2
+ closeSync,
3
+ constants,
4
+ fstatSync,
5
+ ftruncateSync,
6
+ lstatSync,
7
+ mkdirSync,
8
+ openSync,
9
+ readFileSync,
10
+ readSync,
11
+ writeSync,
12
+ } from "node:fs";
13
+ import { dirname, join, resolve } from "node:path";
14
+ import { fileURLToPath } from "node:url";
2
15
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
16
 
4
17
  /**
@@ -12,6 +25,192 @@ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
12
25
 
13
26
  type Phase = "brainstorm" | "plan" | null;
14
27
 
28
+ type DelegationStatus = "completed" | "failed" | "timed-out" | "skipped";
29
+
30
+ export interface DelegationOutcome {
31
+ role: string;
32
+ status: DelegationStatus;
33
+ report?: string;
34
+ error?: string;
35
+ provider?: string;
36
+ runId?: string;
37
+ }
38
+
39
+ export interface DelegationCoverage {
40
+ complete: boolean;
41
+ missing: string[];
42
+ retainedReports: string[];
43
+ }
44
+
45
+ /** Summarize role outcomes without treating failed or empty outcomes as coverage. */
46
+ export function assessDelegationCoverage(
47
+ requiredRoles: readonly string[],
48
+ outcomes: readonly DelegationOutcome[],
49
+ ): DelegationCoverage {
50
+ const completedReports = new Map<string, string>();
51
+ for (const outcome of outcomes) {
52
+ if (outcome.status === "completed" && outcome.report) {
53
+ completedReports.set(outcome.role, outcome.report);
54
+ }
55
+ }
56
+
57
+ const missing = requiredRoles.filter((role) => !completedReports.has(role));
58
+ return {
59
+ complete: missing.length === 0,
60
+ missing,
61
+ retainedReports: [...completedReports.values()],
62
+ };
63
+ }
64
+
65
+ export const ROLE_NAMES = [
66
+ "pwk-recon-scout",
67
+ "pwk-spec-reviewer",
68
+ "pwk-tracing-reviewer",
69
+ "pwk-smell-reviewer",
70
+ "pwk-hazard-reviewer",
71
+ ] as const;
72
+
73
+ const CANONICAL_AGENTS_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..", "agents");
74
+
75
+ function setupUsageError(): Error {
76
+ return new Error("Usage: /pwk-setup [--force]");
77
+ }
78
+
79
+ function parseSetupArgs(args: string): { force: boolean } {
80
+ const normalized = args.trim();
81
+ if (!normalized) return { force: false };
82
+ if (normalized === "--force") return { force: true };
83
+ throw setupUsageError();
84
+ }
85
+
86
+ function ensureDirectory(path: string): void {
87
+ const stats = statNoFollow(path);
88
+ if (!stats) {
89
+ mkdirSync(path);
90
+ return;
91
+ }
92
+ if (stats.isSymbolicLink()) throw new Error(`Refusing symlink destination: ${path}`);
93
+ if (!stats.isDirectory()) throw new Error(`Destination is not a directory: ${path}`);
94
+ }
95
+
96
+ /** lstat without following symlinks; null when the path does not exist. */
97
+ function statNoFollow(path: string): ReturnType<typeof lstatSync> | null {
98
+ try {
99
+ return lstatSync(path);
100
+ } catch (error) {
101
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
102
+ return null;
103
+ }
104
+ }
105
+
106
+ /** Read exactly `size` bytes from `fd` starting at position 0, regardless of the fd's cursor. */
107
+ function readAllFromFd(fd: number, size: number): string {
108
+ const buffer = Buffer.alloc(size);
109
+ let offset = 0;
110
+ while (offset < size) {
111
+ const bytesRead = readSync(fd, buffer, offset, size - offset, offset);
112
+ if (bytesRead === 0) break;
113
+ offset += bytesRead;
114
+ }
115
+ return buffer.toString("utf8");
116
+ }
117
+
118
+ /** Write `content` to `fd` at position 0 (truncating first) and verify by reading the same fd back. */
119
+ function overwriteFd(fd: number, content: string, path: string): void {
120
+ ftruncateSync(fd, 0);
121
+ const buffer = Buffer.from(content, "utf8");
122
+ writeSync(fd, buffer, 0, buffer.length, 0);
123
+ if (readAllFromFd(fd, buffer.length) !== content) throw new Error(`Verification failed after writing: ${path}`);
124
+ }
125
+
126
+ function writeNewFile(path: string, content: string): void {
127
+ const noFollow = constants.O_NOFOLLOW ?? 0;
128
+ const flags = constants.O_RDWR | noFollow | constants.O_CREAT | constants.O_EXCL;
129
+ const fd = openSync(path, flags, 0o644);
130
+ try {
131
+ overwriteFd(fd, content, path);
132
+ } finally {
133
+ closeSync(fd);
134
+ }
135
+ }
136
+
137
+ function installRoleFiles(cwd: string, force: boolean): { installed: string[]; skipped: string[] } {
138
+ const projectAgentsDir = join(cwd, ".agents");
139
+ const targetDir = join(projectAgentsDir, "agents");
140
+ ensureDirectory(projectAgentsDir);
141
+ ensureDirectory(targetDir);
142
+
143
+ const installed: string[] = [];
144
+ const skipped: string[] = [];
145
+ const failures: string[] = [];
146
+ const noFollow = constants.O_NOFOLLOW ?? 0;
147
+
148
+ for (const roleName of ROLE_NAMES) {
149
+ const sourcePath = join(CANONICAL_AGENTS_DIR, `${roleName}.md`);
150
+ const targetPath = join(targetDir, `${roleName}.md`);
151
+
152
+ try {
153
+ // Read inside the try: one broken canonical source becomes a per-role failure
154
+ // instead of aborting the whole install and hiding other roles' results.
155
+ const content = readFileSync(sourcePath, "utf8");
156
+
157
+ // Open the existing target (if any) once and do every check/read/write through
158
+ // that single fd — the fd names one fixed inode, so nothing swapped in on the
159
+ // path between checks (TOCTOU) can affect what gets read or written.
160
+ let fd: number | null;
161
+ try {
162
+ fd = openSync(targetPath, constants.O_RDWR | noFollow);
163
+ } catch (error) {
164
+ const err = error as NodeJS.ErrnoException;
165
+ if (err.code === "ENOENT") {
166
+ fd = null;
167
+ } else if (err.code === "ELOOP") {
168
+ throw new Error(`Refusing symlink destination: ${targetPath}`);
169
+ } else {
170
+ throw error;
171
+ }
172
+ }
173
+
174
+ if (fd === null) {
175
+ writeNewFile(targetPath, content);
176
+ installed.push(roleName);
177
+ continue;
178
+ }
179
+
180
+ try {
181
+ const stats = fstatSync(fd);
182
+ if (!stats.isFile()) throw new Error(`Refusing non-regular destination: ${targetPath}`);
183
+
184
+ const existing = readAllFromFd(fd, stats.size);
185
+ if (existing === content) {
186
+ skipped.push(roleName);
187
+ continue;
188
+ }
189
+ if (!force) {
190
+ failures.push(`${targetPath}: conflict (use /pwk-setup --force to replace it)`);
191
+ continue;
192
+ }
193
+
194
+ overwriteFd(fd, content, targetPath);
195
+ installed.push(roleName);
196
+ } finally {
197
+ closeSync(fd);
198
+ }
199
+ } catch (error) {
200
+ failures.push(`${targetPath}: ${error instanceof Error ? error.message : String(error)}`);
201
+ }
202
+ }
203
+
204
+ if (failures.length > 0) {
205
+ const partial =
206
+ installed.length + skipped.length > 0
207
+ ? ` (${installed.length} installed, ${skipped.length} skipped before failure — installation is partial)`
208
+ : "";
209
+ throw new Error(`PWK setup incomplete${partial}:\n${failures.join("\n")}`);
210
+ }
211
+ return { installed, skipped };
212
+ }
213
+
15
214
  // Destructive commands blocked in brainstorm/plan phases (simple common blacklist)
16
215
  const DESTRUCTIVE_PATTERNS = [
17
216
  /\brm\b/i,
@@ -181,6 +380,16 @@ function enforceLabel(): string {
181
380
  return guardOverride === "on" ? "GUARD ON" : phase ? phase.toUpperCase() : "";
182
381
  }
183
382
 
383
+ /**
384
+ * Is `/pwk-setup` blocked right now? Deliberately NOT `enforceActive()`: setup must
385
+ * refuse during a gated phase even when the tool-call guard is manually disabled
386
+ * (`/pwk-guard off`), since its own banner promises writes stay confined to
387
+ * docs/plans/ for the whole gated phase, override or not.
388
+ */
389
+ function setupBlocked(): boolean {
390
+ return phase !== null || guardOverride === "on";
391
+ }
392
+
184
393
  export default function (pi: ExtensionAPI) {
185
394
  pi.on("session_start", () => {
186
395
  phase = null;
@@ -188,6 +397,40 @@ export default function (pi: ExtensionAPI) {
188
397
  guardOverride = null;
189
398
  });
190
399
 
400
+ // --- Project role setup -------------------------------------------------
401
+ // This command writes through Node rather than the write tool, so it enforces
402
+ // the gated-phase boundary itself instead of relying on tool_call interception.
403
+ pi.registerCommand("pwk-setup", {
404
+ description: "Install PWK role agents into .agents/agents/",
405
+ handler: async (args, ctx) => {
406
+ // Refuse whenever the session is read-only in fact: gated phase (even with the
407
+ // tool-call guard manually disabled — the design mandates that) or the manual
408
+ // read-only lock, whose banner promises "writes only under docs/plans/".
409
+ if (setupBlocked()) {
410
+ const scope =
411
+ guardOverride === "on"
412
+ ? "the manual read-only lock (/pwk-guard on)"
413
+ : `${(phase as string).toUpperCase()} phase`;
414
+ const message = `Cannot run /pwk-setup during ${scope}. Run it before entering the gated workflow or after leaving it (guard auto/off).`;
415
+ ctx.ui.notify(message, "warning");
416
+ throw new Error(message);
417
+ }
418
+
419
+ const { force } = parseSetupArgs(args ?? "");
420
+ try {
421
+ const result = installRoleFiles(ctx.cwd, force);
422
+ const parts = [`PWK setup complete: ${result.installed.length} installed`];
423
+ if (result.skipped.length > 0) parts.push(`${result.skipped.length} skipped`);
424
+ if (force) parts.push("forced conflicts replaced");
425
+ ctx.ui.notify(`${parts.join(", ")}. Providers may require /reload to discover updated roles.`, "info");
426
+ } catch (error) {
427
+ const message = error instanceof Error ? error.message : String(error);
428
+ ctx.ui.notify(message, "error");
429
+ throw error;
430
+ }
431
+ },
432
+ });
433
+
191
434
  // --- Manual override (escape hatch) -----------------------------------
192
435
  // Phases are driven by `/skill:` commands; `/pwk-guard` lets the user pin the
193
436
  // guard regardless of phase. `/pwk-guard auto` returns control to skill transitions.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tianhai/pi-workflow-kit",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "Enforce structured brainstorm→plan→execute→finalize workflow with TDD discipline in AI coding agents",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -32,6 +32,7 @@
32
32
  "docs/developer-usage-guide.md",
33
33
  "docs/workflow-phases.md",
34
34
  "docs/oversight-model.md",
35
+ "docs/provider-delegation-contract.md",
35
36
  "LICENSE",
36
37
  "README.md"
37
38
  ],
@@ -11,7 +11,7 @@ Read-only exploration of source code; every file you create or edit goes under `
11
11
 
12
12
  Classify the change at the start.
13
13
 
14
- - **Trivial** — typo or obvious bugfix with no open design questions, config/version bump, single-function change, or anything the human flags as trivial. Skip steps 3–5; write a **minimal** design doc in one turn (one-line context, a `## Requirements` list with the single requirement, optional `## Production-risk areas` line), and hand off to `/skill:pwk-writing-plans`. The guard still enforces read-only — trivial compresses the phase to one turn, it doesn't skip it.
14
+ - **Trivial** — typo or obvious bugfix with no open design questions, config/version bump, single-function change, or anything the human flags as trivial. Skip steps 3–7; write a **minimal** design doc in one turn (one-line context, a `## Requirements` list with the single requirement, optional `## Production-risk areas` line), and hand off to `/skill:pwk-writing-plans`. The guard still enforces read-only — trivial compresses the phase to one turn, it doesn't skip it.
15
15
  - **Non-trivial** — open design questions, multiple approaches, cross-module impact, or new behavior. Run the full process below.
16
16
 
17
17
  When unsure, ask: "This looks trivial — fast-path it, or full brainstorm?" Default to full.
@@ -54,11 +54,12 @@ The whole umbrella is one branch and one PR: `pwk-writing-plans` creates the bra
54
54
  1. **Check git state** — `git status` + `git log --oneline -5`. Uncommitted work? Ask the user what to do first.
55
55
  2. **Discovery** *(skip in a brand-new repo with no `docs/plans/`)* — glob `docs/plans/*-design.md` and `*-overview.md`; report in-flight topics and any active umbrella. If the new idea continues an existing topic, ask whether to extend it or start fresh. Part of an umbrella? An existing `*-overview.md` means the split is already decided — read it for the roster and design this part's `-design.md` against it (see [Umbrella](#umbrella)).
56
56
  3. **Understand the idea** — read only enough code/docs/commits to ground the design. **Check `docs/lessons.md`** — known constraints may shape it. Ask questions one at a time, prefer multiple choice. Once you can articulate what/why/constraints, present a short summary and ask: "Should I proceed, or is there more?" The human decides when to move on.
57
- 4. **Explore approaches** — propose 2–3, leading with your recommendation. Sketch the concrete interface (types, signatures, example caller) for each so the comparison is grounded in code, not abstractions.
58
- 5. **Present the design** in one pass, organized into sections (architecture, components, data flow, error handling, testing) the human comments on any section; re-present only revised sections.
57
+ 4. **(skipped on trivial changes)** **Codebase recon** for non-trivial topics with prior art, request the host’s `codebase-recon` capability using the logical `pwk-recon-scout` role. Require a fresh-context, read-only, bounded worker and pass the topic, one-line intent, and repo root. Use the returned 5-section codebase map (Relevant files, Existing patterns, Call sites, Test layout, Gotchas) as the grounding context for the next two steps instead of reading those files inline. The scout is observations only — no design recommendations. Skip this step on trivial changes (typo, version bump, single-function edit per the proportionality rule). If no compatible capability is available or the provider cannot enforce the requested constraints, report `Scout: unavailable` and do the same recon inline, preserving the five-section map and `file:line` citations; do not silently omit recon.
58
+ 5. **Explore approaches** propose 2–3, leading with your recommendation. Sketch the concrete interface (types, signatures, example caller) for each so the comparison is grounded in code, not abstractions.
59
+ 6. **Present the design** in one pass, organized into sections (architecture, components, data flow, error handling, testing) — the human comments on any section; re-present only revised sections.
59
60
 
60
61
  Identified a significant architectural decision? Offer an ADR in `docs/adr/`. Only when all three hold: **hard to reverse**, **surprising without context**, **a real trade-off**. Format: title + 1–3 sentences of context/decision/why. ADRs are permanent institutional memory — they stay out of archive/rotation forever. (Guard note: `docs/adr/` is outside the writable `docs/plans/`; write it only after the user approves and unlocks.)
61
- 6. **Write the design doc** — `docs/plans/YYYY-MM-DD-<topic>-design.md`, descriptive (not a task list). **Open with `## Requirements`** — one testable behavior each; `pwk-writing-plans` derives acceptance criteria and tests from these. Then: problem, approaches considered, architecture, components, data flow, error handling, testing.
62
+ 7. **Write the design doc** — `docs/plans/YYYY-MM-DD-<topic>-design.md`, descriptive (not a task list). **Open with `## Requirements`** — one testable behavior each; `pwk-writing-plans` derives acceptance criteria and tests from these. Then: problem, approaches considered, architecture, components, data flow, error handling, testing.
62
63
 
63
64
  Touches a production-risk area (DB schema/migrations, auth, external APIs, concurrency/batch, uploads/large data flows, Redis/caching/queues)? Add a brief `## Production-risk areas` — `pwk-writing-plans` carries it into the plan and `pwk-code-review` audits it per requirement.
64
65
 
@@ -7,7 +7,7 @@ description: "Implement a plan via the feature-gate flow: write the feature-acce
7
7
 
8
8
  Implement the plan from `docs/plans/*-implementation.md` via the **feature-gate flow**. The plan is a behavioral spec (acceptance criteria + integration tests) — you choose structure, signatures, internals; the criteria define *what*, you decide *how*.
9
9
 
10
- The feature-acceptance E2E test is the primary enforced gate. The flow is always on: write the E2E first (red), implement the requirements back-to-back, then run one feature-level review over the whole diff. Per-requirement checkpoints and reviews are **opt-in** — they fire only for requirements the plan tags (default off); the feature gate covers everything else.
10
+ The feature-acceptance E2E test is the primary enforced gate and the primary enforced spec for the feature. The flow is always on: write the E2E first (red), implement the requirements back-to-back, then run one feature-level review over the whole diff. Per-requirement checkpoints and reviews are **opt-in** — they fire only for requirements the plan tags (default off); the feature gate covers everything else.
11
11
 
12
12
  ## Before you start
13
13
 
@@ -93,25 +93,10 @@ The old "integration gate" is gone — the feature E2E at `feature-complete` *is
93
93
 
94
94
  After `feature-complete` is approved, run **one** review over the **whole feature diff**, driven by the plan's feature-level `### Feature review` tag. This is the single thorough review — per-requirement reviews, if any, only saw slices in isolation.
95
95
 
96
- - **`parallel`** (default) — four fresh-context reviewers via the `subagent` tool. Gather scope (the plan's acceptance criteria + Feature acceptance, `git log --oneline && git diff <merge-base>...HEAD`) and invoke:
96
+ - **`parallel`** (default) — request the host’s `parallel-review` capability for four fresh-context, read-only logical roles: `pwk-spec-reviewer`, `pwk-tracing-reviewer`, `pwk-smell-reviewer`, and `pwk-hazard-reviewer`. Gather scope (the plan's acceptance criteria + Feature acceptance, `git log --oneline && git diff <merge-base>...HEAD`) and provide it to every role. Require independent execution and one collected outcome per role. The reviewer role contracts live in `agents/pwk-*-reviewer.md`; do not duplicate their checklists in the workflow instructions. Reviewers are read-only reporters; you apply smell fixes yourself (full suite + E2E must stay green, commit) and flag trace/spec/hazard findings as follow-ups for the human.
97
97
 
98
- ```json
99
- {
100
- "tasks": [
101
- {"agent": "pwk-spec-reviewer", "task": "<scope + whole diff here>"},
102
- {"agent": "pwk-tracing-reviewer", "task": "<scope + whole diff here>"},
103
- {"agent": "pwk-smell-reviewer", "task": "<scope + whole diff here>"},
104
- {"agent": "pwk-hazard-reviewer", "task": "<scope + whole diff here>"}
105
- ],
106
- "agentScope": "both",
107
- "cwd": "<repo-root>"
108
- }
109
- ```
110
-
111
- The reviewer checklists live only in `agents/pwk-*-reviewer.md` — don't restate them in the task strings (duplication guarantees drift). Reviewers are read-only reporters; you apply smell fixes yourself (full suite + E2E must stay green, commit) and flag trace/spec/hazard findings as follow-ups for the human.
112
-
113
- - **`inline`** — run `/skill:pwk-code-review` over the whole diff as a single pass.
114
- - **Fallback** — subagent tool unavailable or errors → run `/skill:pwk-code-review` inline instead.
98
+ - **`inline`** — perform `/skill:pwk-code-review` over the whole diff as a single pass.
99
+ - **Fallback** — if the host has no compatible parallel-review capability, cannot prove the requested read-only/fresh-context/bounded constraints, or delegation fails, perform the missing review work inline. Retain successful delegated reports and do not mark the feature fully reviewed while a required role is missing.
115
100
 
116
101
  On success, set `Feature phase: done`.
117
102
 
@@ -120,7 +105,7 @@ On success, set `Feature phase: done`.
120
105
  The plan tags each requirement and the feature level:
121
106
 
122
107
  - **`### Checkpoints: none | full | spec`** — per-requirement human stops. `none` (default) = no per-requirement stop; `full` = tests + complete; `spec` = tests only.
123
- - **`### Review: skip | parallel | inline`** — per-requirement review. `skip` (default) = none; `parallel` = four reviewers; `inline` = one `pwk-code-review` pass.
108
+ - **`### Review: skip | parallel | inline`** — per-requirement review. `skip` (default) = none; `parallel` = four reviewers; `inline` = one `pwk-code-review` pass. The auto-tag default for requirements with non-empty `### Production-risk notes` is `parallel` (see `pwk-writing-plans` for the rule).
124
109
  - **`### Feature review: parallel | inline`** — the one whole-feature review (always present). Default `parallel`; `inline` for small features.
125
110
 
126
111
  ## User override commands
@@ -23,10 +23,11 @@ Your writes go into `docs/plans/` and nowhere else. Source code and configuratio
23
23
  - **Integration tests** — test name + what each asserts. This is the spec the executor writes tests from.
24
24
  - **Meaningful tests** — write acceptance criteria and tests as observable behavior: (1) **Test observable behavior** — assert on what the feature produces or changes (a return value, persisted/updated data, an emitted event, an HTTP response) through its public interface; these assertions keep passing as the implementation changes. (2) **Write a per-slice test when the slice has its own observable behavior** — when a slice is pure config or a trivial extraction, the feature E2E covers it and a per-slice test is unnecessary.
25
25
  - **`### Checkpoints: none | full | spec`** — how many human stops. `none` = no per-requirement stop (default — the feature gate covers it); `full` = tests + complete stops; `spec` = tests stop only. Flag a requirement `full` or `spec` when it contains complex logic or is the main part of the feature — where a human look at the slice is worth the stop.
26
- - **`### Review: skip | parallel | inline`** — `skip` = no per-requirement review (default — the feature-level review covers it); `parallel` = four reviewers via subagent; `inline` = one `pwk-code-review` pass. Flag a requirement for `parallel` or `inline` when it touches production-risk areas.
26
+ - **`### Review: skip | parallel | inline`** — `skip` = no per-requirement review (default — the feature-level review covers it); `parallel` = four reviewers via delegated parallel roles; `inline` = one `pwk-code-review` pass. The auto-tag bullet below is the single source of truth for risky-requirement tagging.
27
27
  - **`### Feature review: parallel | inline`** — one review over the **whole feature diff**, always present (the single thorough pass). `parallel` (default — thoroughness lives here, since it is the only review in the common case); `inline` for small features.
28
28
  - Tag every requirement — missing tags default to `none` / `skip`. **`spec` requires at least `inline` review** — dropping the complete checkpoint is only safe when review covers implementation quality; never combine `spec` with `Review: skip` (use `Checkpoints: none` instead).
29
29
  - **Production-risk notes** — carry forward the design's `## Production-risk areas`, if any.
30
+ - **Auto-tag risky requirements with `### Review: parallel`** — when a requirement has a non-empty `### Production-risk notes` section, emit `### Review: parallel` as the default. Requirements without risk notes keep the existing default (`### Review: skip`). The tag is silently applied; the human can override or downgrade it to `inline` or `skip` during plan review before approval, and `pwk-executing-tasks` honors the edited value. This is the one source of truth for the auto-tag rule — `pwk-executing-tasks` and the docs link to it here, they do not restate the rule.
30
31
  - **Challenge the design first** *(if production-risk areas exist)* — stress-test the design against the flagged risks before writing criteria. If a risk invalidates a design choice, stop and return to `/skill:pwk-brainstorming` rather than planning around a flawed design.
31
32
  - **Ordering** — dependencies come **earlier** in the list; the executor runs in listed order with no dependency graph. Aim for vertical slices that merge cleanly on their own.
32
33