pi-pstack-adapter 0.10.0 → 0.11.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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project are documented here. release-please writes new entries from Conventional Commit PR titles.
4
4
 
5
+ ## [0.11.0](https://github.com/elderfo/pi-pstack-adapter/compare/v0.10.0...v0.11.0) (2026-11-15)
6
+
7
+
8
+ ### Features
9
+
10
+ * **pstack:** certify pstack 0.15.42 ([#35](https://github.com/elderfo/pi-pstack-adapter/issues/35)) ([10fd682](https://github.com/elderfo/pi-pstack-adapter/commit/10fd6827a09376d499cbc82ee3e720871ef7c74e))
11
+
5
12
  ## [0.10.0](https://github.com/elderfo/pi-pstack-adapter/compare/v0.9.0...v0.10.0) (2026-11-05)
6
13
 
7
14
 
package/README.md CHANGED
@@ -9,9 +9,9 @@ Use Cursor's [pstack](https://github.com/cursor/plugins/tree/main/pstack) skills
9
9
 
10
10
  pstack is Cursor's collection of engineering workflows: design reviews (`how`), prose cleanup
11
11
  (`unslop`), test-driven development (`tdd`), parallel fan-out (`swarm`), and the full Poteto Mode
12
- working style. This package downloads a tested pstack release and exposes every workflow as a
13
- Pi skill named `pistack-*`. The upstream files stay unmodified, so you can audit exactly what
14
- the agent reads.
12
+ working style. This package downloads a tested pstack release and gives you every workflow as a
13
+ Pi skill named `pistack-*`. The upstream files stay unmodified, so you can audit what the agent
14
+ reads.
15
15
 
16
16
  ## Quick start
17
17
 
@@ -44,42 +44,7 @@ commands, so keep the `bash` tool active rather than switching to Pi's `powershe
44
44
  `/pistack-status` warns when Bash is missing or the `bash` tool is inactive. Pi inside WSL
45
45
  counts as Linux.
46
46
 
47
- ### Add optional providers for delegating workflows
48
-
49
- Some workflows hand work to subagents or ask you multiple-choice questions. Two providers can run
50
- the subagents:
51
-
52
- - **T3 Code.** When Pi runs inside [T3 Code](https://github.com/pingdotgg/t3code), workflows
53
- delegate through T3's `delegate_task` tool. Each child appears in T3, can run on any provider
54
- and model T3 offers, and can work in its own worktree. You install nothing extra.
55
- - **pi-subagents.** Outside T3 Code, install `pi-subagents`. The upstream agents register as
56
- `pistack-comment-sicko` and `pistack-poteto-agent`.
57
-
58
- For multiple-choice questions, install `pi-ask-user`:
59
-
60
- ```bash
61
- pi install npm:pi-subagents
62
- pi install npm:pi-ask-user
63
- ```
64
-
65
- The adapter uses T3 Code first and falls back to `pi-subagents`. To reverse that order, set
66
- `"delegation": "pi-subagents"` in the adapter config, or set `PISTACK_DELEGATION=pi-subagents`.
67
- Restart Pi or run `/reload` after changing it. `/pistack-status` shows the order and the
68
- provider the session resolved.
69
-
70
- The adapter counts T3's tools, including `task_status` and `orchestrator_capabilities`, only
71
- when T3 Code's own bridge registered them. A tool that another extension or MCP server registers
72
- under the same name is ignored, and `/pistack-check <skill>` names the one tool to delegate with.
73
-
74
- When a delegating workflow starts, the adapter turns on that provider's tool, even if you turned
75
- it off in the tool selector. This happens
76
- whether you run the workflow's `/skill:` command or the agent opens the skill itself. While Poteto
77
- Mode is on, the adapter turns it on for every prompt.
78
-
79
- To find missing providers or executables before you start a workflow, run
80
- `/pistack-check <skill>`.
81
-
82
- ## Install from Git instead of npm
47
+ ### Install from Git instead of npm
83
48
 
84
49
  To track the repository directly, install from GitHub:
85
50
 
@@ -87,8 +52,10 @@ To track the repository directly, install from GitHub:
87
52
  pi install git:github.com/elderfo/pi-pstack-adapter
88
53
  ```
89
54
 
90
- To pin a release, add its tag, for example `git:github.com/elderfo/pi-pstack-adapter@v0.3.0`.
91
- For a pinned npm release, use `npm:pi-pstack-adapter@0.3.0`.
55
+ To pin a release, add a tag from the
56
+ [releases page](https://github.com/elderfo/pi-pstack-adapter/releases), as in
57
+ `git:github.com/elderfo/pi-pstack-adapter@v<version>`. For a pinned npm release, use
58
+ `npm:pi-pstack-adapter@<version>`.
92
59
 
93
60
  ## Run pstack workflows
94
61
 
@@ -106,153 +73,199 @@ Before you run a workflow, check what it needs:
106
73
  /pistack-check how
107
74
  ```
108
75
 
109
- The check reports the workflow's support tier and any missing capabilities or executables.
76
+ The check reports the workflow's support tier and any providers or executables you still need
77
+ to install.
110
78
 
111
79
  The adapter also adds these commands:
112
80
 
113
81
  | Command | What it does |
114
82
  | --- | --- |
115
- | `/pistack-status` | Shows versions, the resolved commit, trust, capabilities, support tiers, and diagnostics. |
83
+ | `/pistack-status` | Shows versions, the pstack commit in use, trust, capabilities, support tiers, and diagnostics. |
116
84
  | `/pistack-check <skill>` | Checks one workflow's requirements. |
117
- | `/pistack-mode on\|off\|status` | Turns Poteto Mode on or off for the current session. |
118
- | `/skill:pistack-setup` | Assigns Pi models to pstack roles or changes the upstream source. |
119
- | `/skill:pistack-status` | Asks the agent to produce the status report. |
85
+ | `/pistack-mode on\|off\|status` | Turns Poteto Mode on or off for every prompt in the current session. |
86
+ | `/skill:pistack-setup` | Assigns Pi models to pstack roles, sets a model filter, or changes the pstack source. |
87
+ | `/skill:pistack-status` | Asks the agent to produce the status report and explain it. |
120
88
 
121
- ## Check how well a workflow is supported
89
+ ### Check how well a workflow is supported
122
90
 
123
91
  `/pistack-status` lists a support tier for each skill:
124
92
 
125
93
  | Tier | Meaning |
126
94
  | --- | --- |
127
95
  | `native` | The skill needs no Pi-specific changes, or the adapter supplies a Pi version. |
128
- | `adapted` | The upstream body works with the host mappings in its wrapper. |
129
- | `dependency-gated` | The workflow needs a capability or executable that may be missing. |
96
+ | `adapted` | The skill works in Pi with the instructions the adapter adds to it. |
97
+ | `dependency-gated` | The workflow needs a provider or executable that may be missing. |
130
98
  | `experimental` | Part of the workflow has no direct Pi equivalent. |
131
- | `unsupported` | Pi cannot provide a required host feature. |
99
+ | `unsupported` | Pi cannot provide a feature the workflow requires. |
132
100
 
133
101
  The [compatibility registry](docs/compatibility.md) lists the tier and requirements of every
134
102
  skill.
135
103
 
104
+ ## Set up workflows that delegate or ask questions
105
+
106
+ Some workflows hand work to subagents or ask you multiple-choice questions. Two providers can run
107
+ the subagents:
108
+
109
+ - **T3 Code.** When Pi runs inside [T3 Code](https://github.com/pingdotgg/t3code), workflows
110
+ delegate through T3's `delegate_task` tool. Each child appears in T3, can run on any provider
111
+ and model T3 offers, and can work in its own worktree. You install nothing extra.
112
+ - **pi-subagents.** Outside T3 Code, install `pi-subagents`. The pstack agents appear as
113
+ `pistack-comment-sicko` and `pistack-poteto-agent`.
114
+
115
+ For multiple-choice questions, install `pi-ask-user`:
116
+
117
+ ```bash
118
+ pi install npm:pi-subagents
119
+ pi install npm:pi-ask-user
120
+ ```
121
+
122
+ When both providers are available, the adapter uses T3 Code. To prefer `pi-subagents`, set
123
+ `"delegation": "pi-subagents"` in the adapter config, or set `PISTACK_DELEGATION=pi-subagents`.
124
+ Restart Pi or run `/reload` after changing it. `/pistack-status` shows the order and the
125
+ provider the session uses.
126
+
127
+ When a delegating workflow starts, the adapter turns on that provider's tool, even if you turned
128
+ it off in the tool selector. While Poteto Mode is on, it turns the tool on for every prompt.
129
+
130
+ The adapter uses T3's tools only when T3 Code itself provides them. It ignores a tool with the
131
+ same name from another extension or MCP server.
132
+
136
133
  ## Choose models for pstack roles
137
134
 
138
135
  pstack assigns work to named model roles such as `feature`, `bug-fix`, and `judgment`. The
139
136
  `general` role covers every other delegate, such as explorers, swarm workers, and ad-hoc helpers.
140
- A role you leave unset uses `general`, and uses the model of the agent that starts it only when
141
- `general` is unset too.
137
+ A role you leave unset uses `general`. When `general` is unset too, the role uses the model of the
138
+ agent that starts it.
142
139
 
143
- To list the models in your Pi installation and assign them to roles, run the setup skill:
140
+ To see the models in your Pi installation and assign them to roles, run the setup skill:
144
141
 
145
142
  ```text
146
143
  /skill:pistack-setup
147
144
  ```
148
145
 
149
- In a noninteractive session, set roles with `PISTACK_MODELS`:
146
+ The setup skill saves your choices in a config file. To set roles in a file or an environment
147
+ variable yourself, see [Set roles without the setup skill](#set-roles-without-the-setup-skill).
150
148
 
151
- ```bash
152
- PISTACK_MODELS='feature=provider/model,bug-fix=provider/other-model' pi
153
- ```
149
+ ### Thinking levels
154
150
 
155
- Add a thinking level to a role with a `:level` suffix. The levels are `off`, `minimal`, `low`,
156
- `medium`, `high`, `xhigh`, and `max`:
151
+ Each role can also have a thinking level: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or
152
+ `max`. The level is a ceiling. A delegate may lower it for routine work but never raises it. A
153
+ role without a level passes none, so the provider uses its own default. If the model does not
154
+ offer the level, Pi limits it to what the model supports. Under T3 Code, T3 may reject the level
155
+ instead. The agent then lowers the level to one the model offers and tells you.
157
156
 
158
- ```bash
159
- PISTACK_MODELS='feature=provider/model:medium,judgment=provider/other-model:high' pi
160
- ```
157
+ A role you leave unset, with `general` unset too, inherits the model and thinking level of the
158
+ agent that starts it. A `strongest-judgment` delegate at `xhigh` would then start every helper at
159
+ `xhigh`. Set `general` to keep helpers at a cheaper level.
161
160
 
162
- Panels such as `arena`'s runners and judge, `architect`'s runners, and `interrogate`'s adversaries
163
- use the panel roles `arena-runners`, `arena-cross-judge-pool`, `architect-runners`, and
164
- `interrogate-reviewers`. A panel holds a list of models, one seat each, separated by spaces.
165
- An `inherit` entry uses the model and thinking of the agent that starts the panel, which is
166
- your session unless a delegate runs the workflow:
161
+ ### Panels
167
162
 
168
- ```bash
169
- PISTACK_MODELS='arena-runners=provider/model:high other-provider/other-model:high' pi
170
- ```
163
+ Some workflows run several models side by side: `arena`'s runners, `architect`'s runners, and
164
+ `interrogate`'s adversaries. Their panel roles are `arena-runners`, `architect-runners`, and
165
+ `interrogate-reviewers`. A panel lists up to eight models, and each one gets a seat. An `inherit`
166
+ seat uses the model and thinking level of the agent that starts the panel, which is your session
167
+ unless a delegate runs the workflow.
168
+
169
+ The `arena-cross-judge-pool` role works differently. `arena`, and `architect` through it, pick
170
+ one judge from this list, the first model from a vendor other than your session's. pstack counts
171
+ Claude Fable and the other Claude models as one vendor. When no entry
172
+ qualifies, `arena` tries `judgment`, then `general`. If neither qualifies, it skips the judge and
173
+ says so. An `inherit` entry never judges.
174
+
175
+ Upstream pstack gives each panel models from several model families. A panel you
176
+ leave unset uses `judgment`, then `general`, so it covers two families only when those roles do.
177
+ The status report warns when a panel's seats all run on one model.
178
+
179
+ ### Pools
171
180
 
172
- Upstream pstack defaults each panel to two model families. A panel you leave unset uses
173
- `judgment`, then `general`, so it covers two families only when those roles do. The status
174
- report warns when a panel's seats all run on one model.
181
+ A role can list up to eight models in order of preference. Each delegation for that role runs on
182
+ the first model that the [model filter](#restrict-which-models-delegation-uses) allows. When a
183
+ task clearly suits another model in the pool, the agent may pick that one instead, and it tells
184
+ you which model it picked and why. It cannot pick a model outside the pool.
175
185
 
176
- ### Give a role a pool of models
186
+ A pool runs one model per task, and a runner panel runs every seat. A pool is also not a retry list.
187
+ When a delegation fails, the agent reports the failure and does not move on to the next model.
177
188
 
178
- An ordinary role can list several models instead of one. The list is a ranking. The agent
179
- delegates by role, passing `pstack:<role>` as the model, and the adapter rewrites the call to the
180
- first model in the ranking that the filter allows, at that entry's thinking level. The agent that
181
- delegates may override the ranking with `pstack:<role>@<provider/model>` when the task clearly
182
- fits another model from the pool better, and it says which model it picked and why. The adapter
183
- blocks an override that is not an allowed entry of the pool. A `:<level>` suffix, as in
184
- `pstack:feature:low`, lowers the thinking level and never raises it above the configured one.
185
- A pool is not a panel: a panel runs one seat per entry, but a pool starts one
186
- child per task. A pool is not a retry list either: when a delegation fails, the agent reports the
187
- failure and does not try the next model. In a config file a pool is a JSON list:
189
+ ### Set roles without the setup skill
190
+
191
+ In a config file, a role takes one model, a pool takes a list, and a panel takes a string of
192
+ seats separated by spaces. Add a thinking level to any model with a `:level` suffix:
188
193
 
189
194
  ```json
190
- { "models": { "feature": ["provider/model-a:high", "provider/model-b:high", "provider/model-c"] } }
195
+ {
196
+ "models": {
197
+ "general": "provider/cheap-model:low",
198
+ "judgment": "provider/strong-model:high",
199
+ "feature": ["provider/model-a:high", "provider/model-b:high", "provider/model-c"],
200
+ "arena-runners": "provider/model-a:high other-provider/model-d:high"
201
+ }
202
+ }
191
203
  ```
192
204
 
193
- The `set_model` action takes the same list in `model`, and its `thinking` applies to each entry
194
- without its own `:level`. Every entry must be a model in your Pi installation, or nothing is
195
- written. In `PISTACK_MODELS`, separate a pool's entries with `|`:
205
+ For a noninteractive session, set the same values in `PISTACK_MODELS`. Separate roles with
206
+ commas and a pool's entries with `|`:
196
207
 
197
208
  ```bash
198
- PISTACK_MODELS='feature=provider/model-a:high|provider/model-b' pi
209
+ PISTACK_MODELS='general=provider/cheap-model:low,feature=provider/model-a:high|provider/model-b' pi
210
+ PISTACK_MODELS='arena-runners=provider/model-a:high other-provider/model-d:high' pi
199
211
  ```
200
212
 
201
- A panel keeps its string of seats. An unset panel's two default seats are delegated as
202
- `pstack:judgment` and `pstack:general`, so each runs once on the first allowed model of its pool,
203
- unless the delegating agent overrides the ranking.
204
-
205
- ### Restrict which models delegation uses
206
-
207
- A model filter limits delegation to some models without changing the role assignments, for
208
- example to run an experiment on one model family only. Ask the agent, or call the
209
- `pstack_adapter` tool's `set_filter` action:
210
-
211
- - `include: ["gpt-*"]` allows only models whose id starts with `gpt-`.
212
- - `exclude: ["*claude*"]` excludes model ids containing `claude`, including Bedrock-style ids.
213
- - `clear: true` removes the filter at that scope.
214
-
215
- A pattern with a `/` matches `provider/model`, and one without matches the model id after the
216
- provider. `*` is the only wildcard, and matching ignores case. A model must match an `include`
217
- pattern when there are any, and must match no `exclude` pattern.
218
-
219
- A filter applies to the current session by default and is not saved. Pass `scope: "user"` or
220
- `scope: "project"` to save it as `modelFilter` in that config file. A saved filter takes effect
221
- at once, and a filter set for the session wins over a saved one until you clear it. The
222
- `model filter` row of `/pistack-status` shows the filter in force and where it came from.
223
- A trusted project's filter replaces the user filter as a whole, including an empty filter.
224
- Empty lists set an unrestricted override; clearing the session filter restores the saved filter.
225
- Wait for `set_filter` to finish before starting delegations, rather than issuing them together.
226
-
227
- Under a filter, the status report and `/pistack-check` mark each pool entry as allowed or
228
- excluded. A role with no allowed entry is blocked: its work is not moved to `general` or to the
229
- session's model. A role that inherits is blocked when the filter excludes the session's model.
230
- A panel seat on an excluded model is blocked, and the other seats still run.
231
-
232
- The adapter also checks every `delegate_task` and `subagent` call in the session, including
233
- calls that no pstack workflow made, and blocks one whose model the filter excludes or that it
234
- cannot check. That includes a call with no model while the session's model is excluded, a model
235
- Pi does not know, a T3 provider other than Pi, a `subagent` child without a model, a `subagent`
236
- workflow script, and a `subagent` action that restarts, refines, steers, or schedules a child,
237
- opens a project session, or configures a watchdog. A T3 target with a named environment is also
238
- blocked because its registry may differ. A blocked call is not retried. These limits apply:
239
-
240
- - A child does not inherit a session filter, so the agent puts it into each brief as an
241
- instruction. A saved filter applies in a child where the adapter loads the same config files.
242
- - Other tools that start agents or processes, such as T3 Code's thread tools or a shell command,
243
- are not checked. The filter does not block a provider or a model inside Pi.
244
- - Changing models with `/model` is not affected.
245
- - The filter is a model-selection guard, not an access-control boundary. The agent can change it
246
- through `set_filter`, but is instructed to keep it unchanged unless the user requests a change.
247
-
248
- Role names are lowercase letters, digits, and hyphens. A model value is printable ASCII with no spaces or markup characters, at most 128 characters. A config entry that breaks these rules stops the adapter at startup with an error that names the file, so fix the key there and restart Pi.
249
-
250
- A role without a level passes none, so the delegation backend applies its own default. A role's
251
- level is a ceiling: a delegate may lower it for routine work but never raises it. A role you leave
252
- unset, with `general` unset too, inherits the model and thinking level of the agent that starts
253
- it. A `strongest-judgment` delegate at `xhigh` would then start every helper at `xhigh`, so set
254
- `general` to keep helpers at a cheaper level. The `pstack_adapter` tool's `set_model` action takes the same
255
- level in its `thinking` parameter. A level the model does not offer is clamped by Pi at run time.
213
+ Role names use lowercase letters, digits, and hyphens. A model value is printable ASCII with no
214
+ spaces or markup characters, at most 128 characters. If an entry breaks these rules, the adapter
215
+ stops at startup with an error that names the file. Fix the entry and restart Pi.
216
+
217
+ ## Restrict which models delegation uses
218
+
219
+ A model filter limits delegation to some models without changing your role assignments, for
220
+ example to run an experiment on one model family. Ask the agent, for example "only delegate to
221
+ GPT models", or run `/skill:pistack-setup`. A filter has two lists of patterns:
222
+
223
+ - `include` lists the models delegation may use. `["gpt-*"]` allows only model ids that start
224
+ with `gpt-`.
225
+ - `exclude` lists the models delegation may not use. `["*claude*"]` blocks every model id that
226
+ contains `claude`, including Bedrock-style ids.
227
+
228
+ A pattern with a `/` matches `provider/model`, and one without matches the part of the id after
229
+ the last `/`. `*` is the only wildcard, and matching ignores case. A model must match an `include`
230
+ pattern when the list has any, and must match no `exclude` pattern.
231
+
232
+ A filter lasts for the current session unless you ask the agent to save it. A saved filter goes
233
+ in your user or project config file as `modelFilter`, for example
234
+ `{ "modelFilter": { "include": ["gpt-*"] } }`, and takes effect at once. A session filter
235
+ overrides a saved one until you clear it. A project's saved filter replaces your user filter
236
+ entirely. The `model filter` row of `/pistack-status` shows the filter in force and where it came
237
+ from.
238
+
239
+ ### What the filter blocks
240
+
241
+ The status report and `/pistack-check` mark each pool entry as allowed or excluded. The adapter
242
+ blocks a role with no allowed entry, and does not move its work to `general` or to your session's
243
+ model. It blocks a role that inherits when the filter excludes your session's model. It blocks a
244
+ panel seat on an excluded model, and the other seats still run.
245
+
246
+ The adapter checks every `delegate_task` and `subagent` call in the session, not only the calls
247
+ pstack workflows make. It blocks a call that would run on an excluded model, and a call it
248
+ cannot check, such as:
249
+
250
+ - a call with no model while the filter excludes your session's model
251
+ - a model Pi does not know
252
+ - a T3 provider other than Pi, or a T3 target that names an environment
253
+ - a `subagent` child without a model, or a `subagent` workflow script
254
+ - a `subagent` action that restarts, refines, steers, or schedules a child, opens a project
255
+ session, or configures a watchdog
256
+
257
+ The agent does not retry a blocked call.
258
+
259
+ ### What the filter does not cover
260
+
261
+ - A child agent does not inherit a session filter. The agent includes the filter in each child's
262
+ instructions instead. A saved filter applies in a child that loads the same config files.
263
+ - The adapter does not check other tools that start agents or processes, such as T3 Code's
264
+ thread tools or a shell command.
265
+ - The filter does not block a provider or a model inside Pi, and it does not affect switching
266
+ models with `/model`.
267
+ - The filter guards model choice. It is not a security boundary. The agent can change it, but its
268
+ instructions say to keep it unless you ask for a change.
256
269
 
257
270
  ## Run Pi noninteractively
258
271
 
@@ -275,13 +288,28 @@ To select a branch, tag, commit, repository, or local checkout, run `/skill:pist
275
288
  adapter asks you to confirm before it changes the source. Restart Pi or run `/reload` afterward.
276
289
 
277
290
  A branch or tag resolves to one commit when you select it. The adapter records that commit and
278
- does not move it on later starts. `/pistack-status` warns when you use a custom repository or a
279
- revision the adapter has not certified.
291
+ does not move it on later starts. The `trust` row of `/pistack-status` tells you how far to trust
292
+ the source:
293
+
294
+ | Trust | Meaning |
295
+ | --- | --- |
296
+ | `tested` | The certified commit from the official repository. |
297
+ | `untested-ref` | A source from the official repository without this release's certified pin. This release has not verified it. |
298
+ | `untested-repo` | A custom repository. Its code runs with your permissions, so review it first. |
299
+ | `local` | A local checkout. Its contents are unverified and can differ between machines. |
280
300
 
281
301
  ## Configuration reference
282
302
 
283
- The setup skill writes user settings to `~/.pi/agent/pi-pstack-adapter.json` and project
284
- settings to `.pi/pi-pstack-adapter.json`. Environment variables override both files:
303
+ The adapter reads settings from these places. A later one overrides an earlier one:
304
+
305
+ 1. Your user config, `~/.pi/agent/pi-pstack-adapter.json`.
306
+ 2. The project config, `.pi/pi-pstack-adapter.json` in the working directory. Pi reads it only
307
+ after you trust the project, and a project cannot change `namespace`.
308
+ 3. Environment variables.
309
+
310
+ The setup skill writes both files. The keys you are most likely to edit are `models`,
311
+ `modelFilter`, and `delegation`. The setup skill also records the pstack source there, so change
312
+ the source through it.
285
313
 
286
314
  | Variable | Effect |
287
315
  | --- | --- |
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.0
1
+ 0.11.0
@@ -4,17 +4,17 @@ Upstream pstack ships a `setup-pstack` skill that writes `~/.cursor/rules/pstack
4
4
  a Cursor-only always-applied rule full of Cursor model slugs. Pi has neither that file nor
5
5
  those models, so this adapter replaces the body with the Pi equivalent.
6
6
 
7
- Four things are configurable. Model roles, the model filter, the upstream source, and the
7
+ You can configure four things: model roles, the model filter, the upstream source, and the
8
8
  delegation order.
9
9
 
10
10
  ## Model roles
11
11
 
12
- pstack skills name a model per role. In Pi those names mean nothing, so each role maps to a
13
- model in your own catalogue. A role you never configure uses the `general` role. When `general` is
12
+ pstack skills name a model per role. Pi has no such models, so each role maps to a
13
+ model in your Pi installation. A role you never configure uses the `general` role. When `general` is
14
14
  unconfigured too, the role inherits the model of whichever agent starts it, which is a working
15
15
  default, not a failure.
16
16
 
17
- Roles used by pstack workflows.
17
+ pstack workflows use these roles.
18
18
 
19
19
  | role | used by |
20
20
  | --- | --- |
@@ -37,11 +37,13 @@ keeps them as panel roles.
37
37
  | `architect-runners` | `architect`'s design candidates |
38
38
  | `interrogate-reviewers` | `interrogate`'s adversaries |
39
39
 
40
- Upstream defaults each panel to two model families, one Claude model and one Grok model. A panel
40
+ Upstream defaults each panel to one Claude Fable, one Claude Opus, and one Gemini model. A panel
41
41
  left unset uses `judgment`, then `general`, so it spans two families only when those roles do.
42
- `arena` takes its judge from the pool only when the model is from a family other than the
43
- session's model, so a pool on the session's family skips the judge. The status report warns when
44
- a panel's seats all land on one model.
42
+ `arena` takes its judge from the pool only when the model is from a vendor other than the
43
+ session model's, and it counts Fable and the other Claude models as one vendor. When no pool entry
44
+ qualifies, it tries `judgment`, then `general`, and skips the judge only when neither does. The
45
+ status report warns when
46
+ a panel's seats all use one model.
45
47
 
46
48
  A panel value lists entries in order. An entry is a model id, optionally with a thinking level,
47
49
  or `inherit` for the model and thinking of the agent that starts the panel, which is the
@@ -59,16 +61,16 @@ configure `general` to stop that. A role's level is a ceiling: delegates may low
59
61
  work, but never raise it. Model choice often affects cost more than thinking level does, so
60
62
  consider a cheaper model for the bulk roles as well.
61
63
 
62
- Steps.
64
+ Follow these steps.
63
65
 
64
66
  1. Call the adapter tool with `action: "models"` to list the provider and model ids this Pi
65
- installation can actually reach. Do not invent ids.
67
+ installation can reach. Do not invent ids.
66
68
  2. Ask the user which model each role should use. Offer the listed ids, and offer
67
69
  `inherit` for any role they do not care about. Use the structured question tool when it is
68
- available; otherwise ask in plain text. Only ids from step 1 are accepted. A user who wants
69
- alternatives for a role gets a pool: a ranked list of models. The adapter runs each delegation
70
- on the first one the model filter allows, unless the delegating agent overrides the ranking
71
- for that task, so ask for the order.
70
+ available; otherwise ask in plain text. The tool accepts only ids from step 1. For a user who
71
+ wants alternatives for a role, offer a pool, which is a ranked list of models. Ask for the
72
+ ranking. The adapter normally picks the first model the filter allows. The delegating agent
73
+ may pick another allowed entry for a particular task.
72
74
  A pool is a set of choices, not a retry list and not a panel, so say that when you offer it.
73
75
  3. Ask for a thinking level. Do not assume the user wants none. Skip this step only when every
74
76
  role is on `inherit`. It applies to every role that got a model in step 2. A role on
@@ -91,8 +93,9 @@ Steps.
91
93
  only when the user says it should differ from its group. Backend default passes no level and
92
94
  leaves the choice to the delegation backend. A Custom user who wants thinking disabled picks
93
95
  `off`.
94
- A model may not offer every level. A level it lacks is clamped when it runs, so say that
95
- instead of asking again. The tool rejects any level other than `off` on a model that has no reasoning support.
96
+ A model may not offer every level. Pi clamps a level it lacks when the role runs. Under T3 Code,
97
+ T3 may reject the level instead, and the delegating agent then lowers it and tells the user.
98
+ Say that instead of asking again. The tool rejects any level other than `off` on a model that has no reasoning support.
96
99
  When it does, set that role with no level and tell the user which role has none.
97
100
  4. For each role, call the adapter tool with `action: "set_model"`, the role, the chosen
98
101
  `provider/model` id, and `thinking` when step 3 picked a level. For a pool, pass `model` as a
@@ -103,7 +106,9 @@ Steps.
103
106
  pass it again.
104
107
  5. Set the panels. Read the `panel roles` table of `action: "status"` and show the user each
105
108
  panel's seats. When a panel's seats share one model, or one family, say so and suggest two
106
- families from step 1, as upstream's defaults do. Never say a family is missing unless the
109
+ families from step 1, as upstream's defaults do. For `arena-cross-judge-pool`, suggest models
110
+ from two vendors, because a Fable and an Opus model are one vendor, so that pool has no eligible
111
+ judge for a Claude session, and arena falls back to `judgment`, then `general`. Never say a family is missing unless the
107
112
  step 1 list shows it. Ask whether to keep each panel or set it. For each panel the user sets,
108
113
  call `set_model` with the panel role and its entries in `model`, separated by commas, for
109
114
  example `model: "provider/model-a, provider/model-b"`. Pass `thinking` for the level of the
@@ -116,8 +121,8 @@ For a scripted environment, set `PISTACK_MODELS` instead, for example
116
121
  `PISTACK_MODELS=feature=anthropic/claude-sonnet-4-5:medium,bug-fix=openai/gpt-5:high`. The
117
122
  optional `:level` suffix sets the thinking level. A pool's entries are separated by `|`, as in
118
123
  `feature=anthropic/claude-sonnet-4-5:high|openai/gpt-5:high`. A panel's entries are separated by spaces, as
119
- in `PISTACK_MODELS='arena-runners=anthropic/claude-sonnet-4-5:high openai/gpt-5:high'`. The environment wins
120
- over both config files, so CI never needs this dialog.
124
+ in `PISTACK_MODELS='arena-runners=anthropic/claude-sonnet-4-5:high openai/gpt-5:high'`. `PISTACK_MODELS` overrides
125
+ both config files, so CI does not need this dialog.
121
126
 
122
127
  ## Model filter
123
128
 
@@ -129,10 +134,11 @@ without rewriting the roles. Call the adapter tool with `action: "set_filter"` a
129
134
  - `clear: true` to remove the filter at that scope.
130
135
 
131
136
  A pattern with `/` matches `provider/model`; one without matches the model id. `*` is the only
132
- wildcard. The filter applies to this session only, unless the user asks to save it: then pass
133
- `scope: "user"` or `scope: "project"`. A session filter wins over a saved one until it is cleared.
134
- A trusted project's filter replaces the user filter as a whole. Empty lists set an unrestricted
135
- override; clearing the session filter restores the saved filter. Wait for `set_filter` to finish
137
+ wildcard. The filter applies to this session only. When the user asks to save it, pass
138
+ `scope: "user"` or `scope: "project"`. A session filter wins over a saved one until you clear it.
139
+ A trusted project's filter replaces the user filter as a whole. Empty `include` and `exclude`
140
+ lists set an override that allows every model. Clearing the session filter restores the saved
141
+ filter. Wait for `set_filter` to finish
136
142
  before issuing delegation calls. Keep the active filter unchanged unless the user requests a change.
137
143
 
138
144
  Read back `action: "status"`. Report the `model filter` row, and any role or panel seat the
@@ -140,34 +146,35 @@ Read back `action: "status"`. Report the `model filter` row, and any role or pan
140
146
  Tell the user the limits: the adapter blocks `delegate_task` and `subagent` calls in this session
141
147
  that the filter does not allow. A child does not inherit a session filter and follows it only as
142
148
  an instruction in its brief. A saved filter applies in a child where the adapter loads the same
143
- config files. Other tools that start agents are not checked. This is a model-selection guard,
149
+ config files. The adapter does not check other tools that start agents. This is a model-selection guard,
144
150
  not an access-control boundary.
145
151
 
146
152
  ## Upstream source
147
153
 
148
154
  By default the adapter uses the pstack revision this release was tested against. Change it only
149
- when you are deliberately testing another revision.
155
+ to test another revision.
150
156
 
151
157
  Call the adapter tool with `action: "set_source"` and one of these.
152
158
 
153
- - `ref` with a branch, tag, or commit. A branch or tag is resolved to a commit once, here, and
154
- recorded. Later sessions keep that commit. The adapter never advances it on its own.
159
+ - `ref` with a branch, tag, or commit. The adapter resolves a branch or tag to a commit once, during
160
+ this call, and records it. Later sessions keep that commit. The adapter never advances it on its own.
155
161
  - `repo` with another repository. This is outside the tested trust boundary.
156
162
  - `localPath` with a directory holding a pstack checkout. Use this when developing pstack itself.
157
163
 
158
164
  The adapter asks the user to confirm every source change itself and refuses without an
159
- interactive session, so a change cannot happen on your say-so alone. Explain the consequence in
165
+ interactive session, so you cannot change the source without the user's confirmation. Explain the consequence in
160
166
  plain words before you call it, and report a refusal as a refusal.
161
167
 
162
- Regeneration happens on the next Pi start. Tell the user to restart Pi, or run `/reload`.
168
+ The adapter regenerates its wrappers on the next Pi start. Tell the user to restart Pi, or run
169
+ `/reload`.
163
170
 
164
171
  ## Delegation order
165
172
 
166
173
  Delegating workflows try T3 Code's `delegate_task` first, then pi-subagents' `subagent`. A user
167
174
  who wants `subagent` first sets `"delegation": "pi-subagents"` in the adapter config file, or
168
175
  `PISTACK_DELEGATION=pi-subagents`. The adapter tool has no action for this. Tell the user which
169
- file to edit: the `config layers` row of the status report lists them. Regeneration happens on
170
- the next Pi start.
176
+ file to edit: the `config layers` row of the status report lists them. The change takes effect
177
+ on the next Pi start.
171
178
 
172
179
  ## Finish
173
180
 
@@ -1,7 +1,7 @@
1
1
  # pstack adapter status
2
2
 
3
- Report what the adapter is actually running, so nobody has to guess whether a pstack workflow
4
- is verified here.
3
+ Report what the adapter is running, so the user can see whether a pstack workflow is verified
4
+ here.
5
5
 
6
6
  1. Call the adapter tool with `action: "status"`.
7
7
  2. Show the user the full report. Do not summarize away the trust line, the resolved commit, or
@@ -15,7 +15,7 @@ To check one workflow before starting it, call the tool with `action: "check"` a
15
15
  name. That reports the capabilities and executables that workflow needs and whether this
16
16
  environment has them, before the workflow does any work.
17
17
 
18
- Support tiers mean this.
18
+ The support tiers mean the following.
19
19
 
20
20
  | tier | meaning |
21
21
  | --- | --- |
@@ -4,7 +4,7 @@ The compatibility registry in `src/registry.ts` assigns one support tier to ever
4
4
  certified pstack revision. Generation reads it, the wrapper frontmatter publishes it, and
5
5
  `/pistack-status` reports it.
6
6
 
7
- Certified revision: pstack `0.15.36` at `c742dd61706fbacc1b95f1a20b7b988cf096ce6c` in
7
+ Certified revision: pstack `0.15.42` at `bf0c7cd80abdbf7fe47b634978a7d1b4071f71a7` in
8
8
  `https://github.com/cursor/plugins`.
9
9
 
10
10
  ## Platforms
@@ -21,6 +21,22 @@ executables in the shell the skills run in, with Pi's `shellCommandPrefix` appli
21
21
  that matters most, because Git Bash adds `/usr/bin` and `/mingw64/bin` to the `PATH` Pi
22
22
  started with. A shell that is missing, inactive, or cannot run a command blocks every workflow.
23
23
 
24
+ pstack `0.15.42` was certified on Linux by the unattended release check. No skill or agent was
25
+ added or removed. Upstream changed its default models to Claude Opus 5.5, Claude Fable 5.2, and
26
+ Gemini 4 Carbon, made Fable its own family, and has arena pick its judge from another vendor,
27
+ where Fable and the other Claude models are one vendor. `how` now spawns one read-only subagent,
28
+ and `why` spawns none: it answers inline from commits and PR discussions, so it loses its
29
+ `delegation` gate and keeps `git` and `gh`. The `how explorer`, `how explainer`,
30
+ `why investigators`, and `why synthesizer` role lines are gone, and the host mapping no longer
31
+ names them. The host mapping gained the new default slugs, Fable and Gemini in the family note,
32
+ and a row saying that poteto-mode's `# defaults: 2` check does not apply to the adapter
33
+ configuration. The statechart scripts changed how they draw edges into nested states and how
34
+ they report a SANY parse failure; they need no new executable, and the `/bin/sh` launcher that
35
+ crashes on native Windows did not change. No tier changed. The release check runs no skill end
36
+ to end, because that would execute new upstream content unattended, so no `0.15.42` skill has
37
+ run in Pi, and `0.15.42` has not been checked on native Windows. The evidence below is from
38
+ `0.15.36` and earlier.
39
+
24
40
  pstack `0.15.36` was certified on Linux. No skill or agent was added or removed. The skills
25
41
  changed only in text, and the Orchestrate playbook's `orch` scripts were deleted; no adapter
26
42
  gate named them. `0.15.36` has not been checked on native Windows. The statechart scripts did
@@ -47,8 +63,8 @@ small Git repository holding a token-bucket rate limiter with two marked bugs.
47
63
  `recall` rises to `dependency-gated`, because the transcript was its only Cursor-specific
48
64
  step. In a fresh session it read the two earlier chats itself, so its fan-out did not run. An
49
65
  earlier fresh run looked in the default session folder, which the sandbox had moved, so the
50
- host mapping now says to find the folder from `$PI_SESSION_FILE` first. `reflect` copied the upstream skill
51
- to a Pi skill location before editing it, but its create-skill route did not run, and
66
+ host mapping now says to find the folder from `$PI_SESSION_FILE` first. `reflect` copied the
67
+ upstream skill to a Pi skill location before editing it, but its create-skill route did not run, and
52
68
  `automate-me` found nothing to draft, so both stay `experimental`.
53
69
  - `poteto-mode`'s Orchestrate playbook ran a two-unit program in a linked worktree. Each unit had
54
70
  an owner on its own branch and worktree, and a verifier from another model family checked the
@@ -223,10 +239,10 @@ Earlier Windows evidence, gathered at pstack `0.15.26` with the same toolchain:
223
239
  - `create-formal-verification-skill` completed in the isolated install without `subagent` or
224
240
  `ask_user`. It generated `.pi/skills/verify-inventory-reservations/SKILL.md` and a dependency-free
225
241
  Node 22 explicit-state verifier that imports the fixture's actual reserve/release functions.
226
- It checked 49 reachable states and 490 transitions for stock 0–3 and five request IDs, caught
242
+ It checked 49 reachable states and 490 transitions for stock from 0 to 3 and five request IDs, caught
227
243
  six mutant copies, then caught a removed retry guard in the actual product file. Restoring
228
- that file restored the passing result and its original hash. This supports `adapted`: the
229
- generated skill path is mapped to Pi. It does not certify TLA+, proof assistants, installation
244
+ that file restored the passing result and its original hash. This supports `adapted`, because
245
+ the host mapping maps the generated skill path to Pi. It does not certify TLA+, proof assistants, installation
230
246
  of other verifiers, unbounded inputs, or real database/async concurrency.
231
247
  - The revised `ketchup` ran read-only in a separate fixture. It listed both supplied product
232
248
  choices (CSV versus JSON and seven versus thirty days of history), drew a Mermaid sequence
@@ -237,8 +253,9 @@ Earlier Windows evidence, gathered at pstack `0.15.26` with the same toolchain:
237
253
  `ketchup`, but still names `uptime` as missing for `benchmark-checklist`. Delegation and
238
254
  structured questions remain unavailable in the isolated install; no delegating tier changed.
239
255
  - A cache inside a Git worktree must own its worktree, Git directory, and common directory before
240
- bootstrap or reuse can change Git state. The Windows run exposed ancestor discovery from an
241
- empty nested cache; this is fixed. Regressions also cover incomplete metadata, a foreign Git
256
+ bootstrap or reuse can change Git state. The Windows run found that Git, started in an
257
+ empty nested cache, discovered the enclosing repository. That is fixed. Regression tests also
258
+ cover incomplete metadata, a foreign Git
242
259
  file, foreign worktree/common directory settings, and short paths, while checking that the
243
260
  enclosing repository's HEAD, config, index, and tracked bytes stay unchanged.
244
261
 
@@ -287,13 +304,13 @@ A session that replaces the `bash` tool with `powershell` cannot run the skills.
287
304
 
288
305
  ## Changing a tier
289
306
 
290
- A tier is a claim about what was verified, so raising one needs evidence, not optimism.
307
+ A tier is a claim about what a run verified, so raising one needs evidence from a run.
291
308
 
292
309
  1. Run the workflow end to end in Pi against the certified revision.
293
310
  2. Record what the workflow produced, not that it started. A `dependency-gated` skill rises to
294
311
  `adapted` only when its delegation or question steps completed against a real provider.
295
312
  3. An `experimental` skill rises only when every Cursor-specific step has a Pi equivalent that
296
- was exercised, not merely described in the host mapping.
313
+ a run exercised, not one the host mapping only describes.
297
314
  4. An `unsupported` skill rises only when the missing host feature exists in Pi.
298
315
  5. Add or update a test that fails if the claim regresses.
299
316
 
@@ -332,7 +349,7 @@ Lowering a tier needs one reproduction of the failure and a note saying what bro
332
349
  | `principle-test-behavior-not-implementation` | `/skill:pistack-principle-test-behavior-not-implementation` | - | - | - |
333
350
  | `principle-type-system-discipline` | `/skill:pistack-principle-type-system-discipline` | - | - | - |
334
351
  | `setup-pstack` | `/skill:pistack-setup` | - | - | The upstream body only writes a Cursor .mdc rule, so the adapter replaces it with a Pi setup workflow. |
335
- | `sharpen` | `/skill:pistack-sharpen` | - | - | Verified end to end in Pi on Linux at pstack 0.15.36: it handed back four short sections and a rewritten prompt for a vague gateway task, left the decisions that were the user's open, and did not start the task. Since pstack 0.15.29 it hands back a rewritten prompt and does not do the task. Its body is prompt-only, with no tool, delegation, or executable, and it runs only when you type it. |
352
+ | `sharpen` | `/skill:pistack-sharpen` | - | - | Verified end to end in Pi on Linux at pstack 0.15.36: it handed back four short sections and a rewritten prompt for a vague gateway task, left the decisions that were the user's open, and did not start the task. Since pstack 0.15.29 it hands back a rewritten prompt and does not do the task. Its body is prompt-only, with no tool, delegation, or executable, and it runs only when you type it. Since pstack 0.15.42 the rewritten prompt asks the agent to prototype any choice an experiment can settle and leaves only product or preference choices to the user. That wording has not been rerun in Pi. |
336
353
  | `tdd` | `/skill:pistack-tdd` | - | - | - |
337
354
  | `technical-writing` | `/skill:pistack-technical-writing` | - | - | - |
338
355
  | `typescript-best-practices` | `/skill:pistack-typescript-best-practices` | - | - | - |
@@ -342,7 +359,7 @@ Lowering a tier needs one reproduction of the failure and a note saying what bro
342
359
 
343
360
  | upstream skill | Pi skill | capabilities | executables | why |
344
361
  | --- | --- | --- | --- | --- |
345
- | `arena` | `/skill:pistack-arena` | `delegation` | `git` | The whole skill is spawning N candidate subagents plus a judge. Since pstack 0.15.36 the judge must come from a model family other than the parent's. The adapter maps the cross-judge pool to the `arena-cross-judge-pool` panel role, which uses `judgment`, then `general` while unset, so when the parent knows its model, the judge runs only when one of its entries is on another family. The status report and `check` warn when that pool is on one model. Otherwise arena skips the judge, picks the base alone, and says so. When the parent does not know its model, arena tries the pool in order anyway and says the family check did not run. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents: two candidates on the `judgment` and `general` roles, then a judge from the family other than the parent's, which scored them. The parent picked a base, took the fixes for two bugs from the other candidate, fixed a third that both shared, and finished with passing tests. It left the candidate worktrees for comparison. |
362
+ | `arena` | `/skill:pistack-arena` | `delegation` | `git` | The whole skill is spawning N candidate subagents plus a judge. Since pstack 0.15.36 the judge must come from a model family other than the parent's, and since pstack 0.15.42 from another vendor, where Fable and the other Claude models are one vendor. Its default runners and pool are now one Fable, one Opus, and one Gemini model. The adapter maps the cross-judge pool to the `arena-cross-judge-pool` panel role, which uses `judgment`, then `general` while unset, so when the parent knows its model, the judge comes from the first pool entry from another vendor. When no entry qualifies, arena tries `judgment`, then `general`, and only when neither is from another vendor does it skip the judge, pick the base alone, and say so. The status report and `check` warn when that pool is on one model. When the parent does not know its model, arena tries the pool in order anyway and says the vendor check did not run. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents: two candidates on the `judgment` and `general` roles, then a judge from the family other than the parent's, which scored them. The parent picked a base, took the fixes for two bugs from the other candidate, fixed a third that both shared, and finished with passing tests. It left the candidate worktrees for comparison. The pstack 0.15.42 vendor rule has not run in Pi. |
346
363
  | `create-formal-verification-skill` | `/skill:pistack-create-formal-verification-skill` | - | - | Manual invocation only; no delegation. It installs or runs the verification tool it chooses and temporarily breaks product code to prove the check. Generated skills belong under `.pi/skills/` in Pi. Verified on a Windows Node finite-state fixture; other toolchains need their own prerequisites. Since pstack 0.15.32, a generated TLA+ check tells the next agent to read its results with statechart, which has its own prerequisites. |
347
364
  | `create-verification-skill` | `/skill:pistack-create-verification-skill` | - | - | Only the generated skill's output path needs remapping to Pi's skill directory. |
348
365
  | `interrogate` | `/skill:pistack-interrogate` | `delegation` | `git` | Multi-model adversarial review is entirely one subagent per configured model. Since pstack 0.15.36 it picks adversaries the way arena picks runners, from the `interrogate reviewers` line, and gives each one its own worktree with the scope's uncommitted changes. Each adversary must prove a finding with a run, and the skill keeps only findings whose command it reruns and sees fail. It reports findings and applies no fixes, but adversaries write and run repro commands, and the skill reruns them, all with your permissions. A worktree is not a sandbox, so read each repro before it reruns, especially on code you do not trust. The rubric, the lead's judgment, and the code-quality lens are gone. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents: two adversaries on the `judgment` and `general` roles, from two model families, each in its own worktree, proved the same two real bugs, and the skill reran both repros before it reported them. It left the adversary worktrees in the temporary folder and named the commands that remove them. |
@@ -358,13 +375,13 @@ Lowering a tier needs one reproduction of the failure and a note saying what bro
358
375
  | `blast-radius` | `/skill:pistack-blast-radius` | - | `git`, `gh` | Needs git and gh to read the diff, commits, and PR before any analysis. |
359
376
  | `correct` | `/skill:pistack-correct` | - | `git` | Mines commit history, then commits fixes and edits lint, CI, and agent instruction files. Run it on a branch you will review. |
360
377
  | `figure-it-out` | `/skill:pistack-figure-it-out` | `delegation` | - | Phase B fan-out and the architect/arena routing require parallel subagents. |
361
- | `how` | `/skill:pistack-how` | `delegation` | - | Every path spawns explorer or explainer subagents; nothing runs inline. |
378
+ | `how` | `/skill:pistack-how` | `delegation` | - | Since pstack 0.15.42 it spawns one read-only subagent that explores and explains in one pass, and nothing runs inline. That path has not run in Pi. |
362
379
  | `maintain-formal-verification-skill` | `/skill:pistack-maintain-formal-verification-skill` | - | `git` | Verified end to end on a Windows Node finite-state fixture at pstack 0.15.28. Manual invocation only; no delegation. It diffs the covered code with git from the verify skill's sync commit, edits only the verification and the verify skill, and temporarily breaks product code to prove an updated check can still fail. In Pi, look for the verify skill under `.pi/skills/`; the verification tool needs its own prerequisites. |
363
380
  | `maintain-verification-skill` | `/skill:pistack-maintain-verification-skill` | `delegation` | - | Source wave launches one read-only subagent per feature file. |
364
381
  | `no-comments` | `/skill:pistack-no-comments` | `delegation` | `git` | Step 1 must spawn the comment-sicko agent; the skill only triages its report. |
365
- | `recall` | `/skill:pistack-recall` | `delegation` | `git`, `gh` | Its core corpus is Cursor's on-disk transcript JSONL. The host mapping points it at this workspace's Pi session files instead. Verified end to end in Pi on Linux at pstack 0.15.36: in a fresh session it found the two earlier chats in the folder that holds `$PI_SESSION_FILE`, read their user messages, checked their claims against git and the code, and rebuilt the threads, problems, and next move. With two chats to read, it read them itself, so it did not fan out to subagents, and that step has not run in Pi. A run before the host mapping said to start from `$PI_SESSION_FILE` looked in the default folder instead, which a custom `PI_CODING_AGENT_DIR` had moved, and found nothing. |
366
- | `teach` | `/skill:pistack-teach` | `delegation` | - | It runs the how and why skills, both of which need subagents. |
367
- | `why` | `/skill:pistack-why` | `delegation` | `git`, `gh` | Default posture spawns one investigator subagent per evidence category plus a synthesizer. |
382
+ | `recall` | `/skill:pistack-recall` | `delegation` | `git`, `gh` | Its core corpus is Cursor's on-disk transcript JSONL. The host mapping points it at this workspace's Pi session files instead. Verified end to end in Pi on Linux at pstack 0.15.36: in a fresh session it found the two earlier chats in the folder that holds `$PI_SESSION_FILE`, read their user messages, checked their claims against git and the code, and rebuilt the threads, problems, and next move. With two chats to read, it read them itself, so it did not fan out to subagents, and that step has not run in Pi. A run before the host mapping said to start from `$PI_SESSION_FILE` looked in the default folder instead, which a custom `PI_CODING_AGENT_DIR` had moved, and found nothing. Since pstack 0.15.42 its shared-record sweep spawns one investigator per source itself instead of reusing why's investigators, and that step has not run in Pi. |
383
+ | `teach` | `/skill:pistack-teach` | `delegation` | - | It runs the how skill, which needs a subagent, and the why skill, which since pstack 0.15.42 runs inline and needs git and gh. Check why's prerequisites too. |
384
+ | `why` | `/skill:pistack-why` | - | `git`, `gh` | Since pstack 0.15.42 it spawns no subagents. It answers inline from the commits and PR discussions behind the target, and from other sources when that trail is thin, so it needs git, and gh for the PR discussions. The inline path has not run in Pi. |
368
385
 
369
386
  ### experimental (7)
370
387
 
@@ -373,9 +390,9 @@ Lowering a tier needs one reproduction of the failure and a note saying what bro
373
390
  | `automate-me` | `/skill:pistack-automate-me` | `delegation`, `structured-question` | `git`, `gh` | Its mining step reads this workspace's transcripts. The host mapping points it at this workspace's Pi session files, which use a different format. Verified end to end in Pi on Linux at pstack 0.15.36: it read only this workspace's sessions, told the parent chat from its subagents' files, found no stated preference there, and changed nothing. The built-in create-skill skill it drafts with has no Pi equivalent, and that step has not run in Pi. |
374
391
  | `ketchup-video` | `/skill:pistack-ketchup-video` | - | - | New in pstack 0.15.32. One end-to-end Pi run on native Windows drew its slides and rendered an mp4 with `ffmpeg` alone, before pstack 0.15.36 added subtitles. Verified end to end in Pi on Linux at pstack 0.15.36: it drew five slides as SVG, rendered a 35-second 1280x720 mp4 with `ffmpeg`, with each subtitle burned into a strip below its slide, and checked frames from the file. Manual invocation only; no delegation or structured question. It follows ketchup, read-only, but shows what happened as a short slide video with no audio, rendered outside the repository, with the waiting calls as text under it. Since pstack 0.15.36 it burns a one-line subtitle into each slide's frames, in a strip below the slide, and measures each slide's hold by matching the rendered frames to the slide. Its body names no renderer, so it needs whatever video tool the session has, such as `ffmpeg`, and Pi has no image generation. Its reply embedded the video as an HTML `video` tag with the file path, and whether a Pi client plays it inline is unverified. When the render fails, it says so in one line and gives only the calls. |
375
392
  | `poteto-help` | `/skill:pistack-poteto-help` | - | - | Its answers describe Cursor setup, the slash menu, and Custom Modes. A request for work runs poteto-mode, which is experimental. It asks a multiple-choice question only when the need is unclear. Its README and guide links resolve under the status report's plugin directory. |
376
- | `poteto-mode` | `/skill:pistack-poteto-mode` | `delegation`, `structured-question` | `git`, `gh` | Sticky-mode hosting plus references to Cursor built-in and plugin skills only partially map to Pi. Since pstack 0.15.36 the Orchestrate playbook calls no scripts, because the `orch` helpers are gone, and watches PRs through event subscriptions only when the harness has them. Pi standalone has none; a T3 Code host can provide them when it exposes `mcp__t3-code__watch_pull_request`. This is a host capability, not a guarantee of either delegation backend. Its Project tracker and Project store, and forking a worker with its built state, have no Pi equivalent; the host mapping says what to do instead. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents and a question tool: Orchestrate ran a two-unit program in a linked worktree, with an owner per unit on its own branch and worktree, a verifier from another model family at the owner's head, and local merges. It kept the tracker and store in a folder it added to the exclude file Git resolved for the worktree, and handed state to new agents instead of messaging old ones. Its other playbooks and sticky mode were not rerun. |
393
+ | `poteto-mode` | `/skill:pistack-poteto-mode` | `delegation`, `structured-question` | `git`, `gh` | Sticky-mode hosting plus references to Cursor built-in and plugin skills only partially map to Pi. Since pstack 0.15.36 the Orchestrate playbook calls no scripts, because the `orch` helpers are gone, and watches PRs through event subscriptions only when the harness has them. Pi standalone has none; a T3 Code host can provide them when it exposes `mcp__t3-code__watch_pull_request`. This is a host capability, not a guarantee of either delegation backend. Its Project tracker and Project store, and forking a worker with its built state, have no Pi equivalent; the host mapping says what to do instead. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents and a question tool: Orchestrate ran a two-unit program in a linked worktree, with an owner per unit on its own branch and worktree, a verifier from another model family at the owner's head, and local merges. It kept the tracker and store in a folder it added to the exclude file Git resolved for the worktree, and handed state to new agents instead of messaging old ones. Its other playbooks and sticky mode were not rerun. Since pstack 0.15.42 it tells the user to rerun setup when the model rule has no `# defaults: 2` line. The host mapping says that check does not apply to the adapter configuration. |
377
394
  | `reflect` | `/skill:pistack-reflect` | `delegation` | - | Its reviewers read the active transcript, and the host mapping points them at the current Pi session file. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents: three reviewers on two model families and a synthesizer read the session file, and the run found a regression the earlier review missed. When told to apply two edits, it copied the upstream skill from the plugin directory to a Pi skill location under a new name and edited only the copy. Its create-skill routing for a new skill is Cursor-specific and has not run in Pi. It never opens a PR or pushes. |
378
- | `statechart` | `/skill:pistack-statechart` | - | `node`, `sh`, `dirname`, `sed` | Lowered from dependency-gated at pstack 0.15.34, because its new scripts crash on native Windows, a certified platform. There, the launcher starts `/bin/sh` by that path to stop TLC's process group, Node cannot start it even when `sh` is on PATH, and with no error handler the run exits 1 with `spawn /bin/sh ENOENT`. It writes no output and leaves an empty hidden staging folder beside the output folder and an empty `statechart-` folder in the temporary folder, so delete those by hand. `/pistack-check` still clears it there, because the gates are found. Use it from Linux, macOS, or WSL. Verified end to end on a Linux checkout fixture at pstack 0.15.34, and again at pstack 0.15.36, where it found the uncapped refill in a token bucket as the shortest path to a broken rule. The Windows end-to-end evidence from pstack 0.15.32 and 0.15.30 describes the scripts it replaced. Manual invocation only; no delegation or structured question. `scripts/statechart` is a POSIX `sh` launcher for TypeScript scripts, and it runs `dirname` and `sed` on every start. It runs the scripts under Node 22.18 to 22.x or Node 23.6 or later, then Bun 1.1.5 or later, then Deno 2.0 or later, and exits with code 127 when none is found. The prerequisite check gates on `node` but cannot check its version. The launcher does: with only an older Node on PATH, it names the versions it needs and exits 127. The command checks a TLA+ spec with TLC and writes `report.md` and TLC output to a new or empty `--out` folder, `SPEC-chart` beside the spec by default, and refuses a folder that is not empty. It also writes `chart.mmd`, except when TLC finds more than 500 states and no rule breaks. It stages its work in a hidden folder beside the output folder and in the system temporary folder, and deletes both. TLC runs from `TLA2TOOLS`, the path to a downloaded `tla2tools.jar`, with the binary in `JAVA` or `java` from PATH. Without `TLA2TOOLS`, it uses TLC 1.7.4 and Java temurin-25 from `mise`, and installs whichever is missing with `mise`, which needs the network. `JAVA` then changes only the binary that runs TLC, and does not skip the `mise` lookup or install of Java. Either `mise` or `TLA2TOOLS` with Java works, so neither is gated, and the script names what is missing when neither is set up. It imports the `--view` module as JavaScript with full process permissions, so review an existing view before you run it. Since pstack 0.15.34 the scripts render no images and do not run `npm`. For an image, the body has the agent install `pele@1.9.0` with `npm` once, outside the repository, which needs `npm` and the network, and render SVG with it. The body does not ask for `--ignore-scripts`, so pass it, and rendering still imports Pele with full process permissions. Run it in a scratch folder outside the repository. Git for Windows bundles `sh`, `dirname`, and `sed`, but not `node`, `mise`, or Java. |
395
+ | `statechart` | `/skill:pistack-statechart` | - | `node`, `sh`, `dirname`, `sed` | Lowered from dependency-gated at pstack 0.15.34, because its new scripts crash on native Windows, a certified platform. There, the launcher starts `/bin/sh` by that path to stop TLC's process group, Node cannot start it even when `sh` is on PATH, and with no error handler the run exits 1 with `spawn /bin/sh ENOENT`. It writes no output and leaves an empty hidden staging folder beside the output folder and an empty `statechart-` folder in the temporary folder, so delete those by hand. `/pistack-check` still clears it there, because the gates are found. Use it from Linux, macOS, or WSL. Verified end to end on a Linux checkout fixture at pstack 0.15.34, and again at pstack 0.15.36, where it found the uncapped refill in a token bucket as the shortest path to a broken rule. The Windows end-to-end evidence from pstack 0.15.32 and 0.15.30 describes the scripts it replaced. Manual invocation only; no delegation or structured question. `scripts/statechart` is a POSIX `sh` launcher for TypeScript scripts, and it runs `dirname` and `sed` on every start. It runs the scripts under Node 22.18 to 22.x or Node 23.6 or later, then Bun 1.1.5 or later, then Deno 2.0 or later, and exits with code 127 when none is found. The prerequisite check gates on `node` but cannot check its version. The launcher does: with only an older Node on PATH, it names the versions it needs and exits 127. The command checks a TLA+ spec with TLC and writes `report.md` and TLC output to a new or empty `--out` folder, `SPEC-chart` beside the spec by default, and refuses a folder that is not empty. It also writes `chart.mmd`, except when TLC finds more than 500 states and no rule breaks. It stages its work in a hidden folder beside the output folder and in the system temporary folder, and deletes both. TLC runs from `TLA2TOOLS`, the path to a downloaded `tla2tools.jar`, with the binary in `JAVA` or `java` from PATH. Without `TLA2TOOLS`, it uses TLC 1.7.4 and Java temurin-25 from `mise`, and installs whichever is missing with `mise`, which needs the network. `JAVA` then changes only the binary that runs TLC, and does not skip the `mise` lookup or install of Java. Either `mise` or `TLA2TOOLS` with Java works, so neither is gated, and the script names what is missing when neither is set up. It imports the `--view` module as JavaScript with full process permissions, so review an existing view before you run it. Since pstack 0.15.34 the scripts render no images and do not run `npm`. For an image, the body has the agent install `pele@1.9.0` with `npm` once, outside the repository, which needs `npm` and the network, and render SVG with it. The body does not ask for `--ignore-scripts`, so pass it, and rendering still imports Pele with full process permissions. Run it in a scratch folder outside the repository. Git for Windows bundles `sh`, `dirname`, and `sed`, but not `node`, `mise`, or Java. At pstack 0.15.42 the Mermaid backend can draw the edges into a nested state as one edge into its parent plus start edges inside it, and a SANY parse failure reruns SANY to print its errors. Those script changes add no executable, leave the `/bin/sh` launcher unchanged, and have not run in Pi. |
379
396
  | `swarm` | `/skill:pistack-swarm` | `delegation` | - | Cloud background workers and cloud_base_branch have no Pi mapping; only local fan-out approximates it. |
380
397
 
381
398
  ### unsupported (1)
@@ -395,8 +412,8 @@ T3 Code's `delegate_task` has no named agents. Generation writes each agent's pr
395
412
  `adapter/agents/<pi-name>.md`, with skill paths relative to that file. The parent begins the
396
413
  child's task by telling it to read that file as its system prompt.
397
414
 
398
- Both agents also register through the `pi-subagents:runtime-agent-register:v1` contract. Without an owner for
399
- that event, the status report says so rather than dropping them silently.
415
+ Both agents also register through the `pi-subagents:runtime-agent-register:v1` contract. When no
416
+ extension handles that event, the status report says the agents did not register.
400
417
 
401
418
  ## Delegation providers
402
419
 
@@ -434,11 +451,10 @@ through `delegate_task`. That run is the evidence the tier rules above require.
434
451
  `setup-pstack` writes a Cursor `.mdc` rule, so the adapter substitutes its own body and
435
452
  publishes it as `/skill:pistack-setup`. Upstream's optional closing offers to run
436
453
  `create-verification-skill` and `create-formal-verification-skill` are left out of the Pi body;
437
- both skills stay available by name. The upstream skill stays represented, and the
454
+ both skills stay available by name. The registry still lists the upstream skill, and the
438
455
  wrapper frontmatter records `pistack-upstream-skill: setup-pstack`.
439
456
 
440
457
  ## Unknown skills
441
458
 
442
459
  A skill present upstream but absent from the registry is generated as `experimental` and reported
443
- in diagnostics. A skill in the registry but absent upstream is reported as removed. Neither case
444
- is silent.
460
+ in diagnostics. A skill in the registry but absent upstream is reported as removed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-pstack-adapter",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Run Cursor's official pstack plugin inside Pi from an unmodified upstream checkout",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/certified.ts CHANGED
@@ -5,9 +5,9 @@
5
5
  export const CERTIFIED = {
6
6
  repo: "https://github.com/cursor/plugins",
7
7
  ref: "main",
8
- commit: "c742dd61706fbacc1b95f1a20b7b988cf096ce6c",
8
+ commit: "bf0c7cd80abdbf7fe47b634978a7d1b4071f71a7",
9
9
  pluginPath: "pstack",
10
- pstackVersion: "0.15.36",
10
+ pstackVersion: "0.15.42",
11
11
  skillCount: 58,
12
12
  agentCount: 2,
13
13
  } as const;
package/src/generate.ts CHANGED
@@ -622,15 +622,16 @@ write no \`Skipped in Pi\` line for it.
622
622
  | \`Grep\`, \`Glob\` | \`rg\` through \`bash\`, or Pi's \`grep\` and \`find\` tools when the session has them. Without \`rg\`, use \`grep -rn\` and \`find\`. |
623
623
  | \`AskUserQuestion\`, \`AskQuestion\` | the \`ask_user\` tool. |
624
624
  | \`TodoWrite\`, \`TaskCreate\`, \`TaskUpdate\`, Open a todolist | no Pi equivalent. Keep an uncommitted \`todo.md\` checklist instead. |
625
- | \`claude-opus-5-5-xhigh\`, \`grok-4.7-xhigh-fast\`, \`gpt-*\`, other Cursor model slugs | the role models configured by \`/skill:${namespace}-setup\`. Pass the role as the model, \`pstack:<role>\`, as [Delegation](#delegation) says, and the adapter picks the role's model and thinking. Call the \`pstack_adapter\` tool with \`action: "status"\` to read the current role table. An effort word in a slug, such as \`-xhigh\` or \`-max\`, is not a model id. The role table's thinking column carries that level, and \`-fast\` has no equivalent. An unconfigured role uses the \`general\` role. When \`general\` is unconfigured too, the adapter lets the child inherit the parent model and thinking. |
625
+ | \`claude-opus-5-5-xhigh\`, \`claude-fable-5-2-max\`, \`gemini-4-carbon-high\`, \`grok-*\`, \`gpt-*\`, other Cursor model slugs | the role models configured by \`/skill:${namespace}-setup\`. Pass the role as the model, \`pstack:<role>\`, as [Delegation](#delegation) says, and the adapter picks the role's model and thinking. Call the \`pstack_adapter\` tool with \`action: "status"\` to read the current role table. An effort word in a slug, such as \`-xhigh\` or \`-max\`, is not a model id. The role table's thinking column carries that level, and \`-fast\` has no equivalent. An unconfigured role uses the \`general\` role. When \`general\` is unconfigured too, the adapter lets the child inherit the parent model and thinking. |
626
626
  | "pick each subagent's reasoning level and fast or standard speed", a role's starting level from the \`/setup-pstack\` budget | the thinking column of the \`model roles\` table is a role's ceiling. When it names a level, you may lower it along \`max\`, \`xhigh\`, \`high\`, \`medium\`, \`low\`, \`minimal\`, \`off\` as the body asks, by ending the role reference with \`:<level>\`, as in \`pstack:feature:low\`. Never raise a role above its configured level, even where the body says to raise it for the hardest work. Send that work to \`strongest-judgment\` at its own level instead. A role whose thinking reads "backend default" keeps that setting, because it has no level to move. An unconfigured role takes the \`general\` role's level as its ceiling, and keeps the parent's setting only when \`general\` is unconfigured too. Fast or standard speed has no Pi equivalent, so leave it out. If the backend rejects the moved level, pass \`pstack:<role>\` with no suffix to use the role's configured level, and say so. |
627
627
  | a role line valued \`auto\` or \`inherit-parent\` | an unconfigured role. Pass \`pstack:<role>\` as for any role. The adapter uses the \`general\` role, and lets the child inherit the parent model only when \`general\` is unconfigured too. |
628
628
  | \`~/.cursor/rules/pstack-models.mdc\` | adapter configuration written by \`/skill:${namespace}-setup\`. |
629
+ | the rule's \`# defaults: 2\` line, a rule without it, telling the user to rerun \`/setup-pstack\` | does not apply. The adapter configuration has no \`# defaults\` line, and an unset role uses the \`general\` role rather than an upstream default slug, so no older setup left stale defaults in it. Do not tell the user to rerun setup for this. |
629
630
  | other \`.cursor/rules/*.mdc\` files, an always-applied rule | Pi reads no rule files. It loads \`AGENTS.md\` or \`CLAUDE.md\` from \`~/.pi/agent/\`, the working directory, and its parent directories into every session, so durable instructions go there. Model roles are the exception, as the row above says. |
630
631
  | role lines \`feature, refactoring\`, \`bug-fix\`, \`perf-issue\`, \`hillclimb\`, \`judgment and prose\`, \`hardest tasks\` | adapter roles \`feature\` or \`refactoring\`, \`bug-fix\`, \`perf-issue\`, \`hillclimb\`, \`judgment\`, and \`strongest-judgment\`. |
631
- | role lines \`how explainer\`, \`why synthesizer\`, \`reflect judgment, divergent, synthesizer\` | adapter role \`judgment\`. |
632
- | role lines \`how explorer\`, \`why investigators\`, \`reflect tooling\`, \`swarm workers\`, and verification | adapter role \`general\`. |
633
- | panel role lines \`arena runners\`, \`arena cross-judge pool\`, \`architect runners\`, \`interrogate reviewers\` | adapter panel roles \`arena-runners\`, \`arena-cross-judge-pool\`, \`architect-runners\`, and \`interrogate-reviewers\`. The \`panel roles\` table of the \`pstack_adapter\` status report lists each panel's seats in order, one per entry, and a seat's thinking is its ceiling, passed by the backend rules in [Delegation](#delegation). A \`model of the agent that starts the panel\` seat comes from an \`inherit\` entry: start it with no \`target\` or \`model\`, so it runs on your own model and thinking even when \`general\` is configured. The \`auto\` and \`inherit-parent\` row does not apply to it. An unset panel uses \`judgment\`, then \`general\`, and those are also the defaults where the body names its own default list or default pool. Families go by the model id after the provider prefix, such as \`claude-*\`, \`gpt-*\`, \`grok-*\`, or \`gemini-*\`, not by the provider, because one provider can serve several families. |
632
+ | role line \`reflect judgment, divergent, synthesizer\` | adapter role \`judgment\`. |
633
+ | role lines \`reflect tooling\`, \`swarm workers\`, and verification | adapter role \`general\`. |
634
+ | panel role lines \`arena runners\`, \`arena cross-judge pool\`, \`architect runners\`, \`interrogate reviewers\` | adapter panel roles \`arena-runners\`, \`arena-cross-judge-pool\`, \`architect-runners\`, and \`interrogate-reviewers\`. The \`panel roles\` table of the \`pstack_adapter\` status report lists each panel's seats in order, one per entry, and a seat's thinking is its ceiling, passed by the backend rules in [Delegation](#delegation). A \`model of the agent that starts the panel\` seat comes from an \`inherit\` entry: on T3, start it with no \`target\`; on pi-subagents, pass your own model as \`model\`, as [Delegation](#delegation) says. It then runs on your own model even when \`general\` is configured. The \`auto\` and \`inherit-parent\` row does not apply to it. An unset panel uses \`judgment\`, then \`general\`, and those are also the defaults where the body names its own default list or default pool. Families and vendors go by the model id after the provider prefix, such as \`claude-fable-*\`, \`claude-*\`, \`gemini-*\`, \`gpt-*\`, or \`grok-*\`, not by the provider, because one provider can serve several families. Apply the body's own family and vendor rules to those ids. |
634
635
  | a panel whose seats all run on one model, or a claim that a model or model family is unavailable | A panel the status report warns about runs on one model because of the adapter configuration. Say that in your reply, name the panel, and name \`/skill:${namespace}-setup\` as the fix. Do not attribute it to which models exist. A \`model of the agent that starts the panel\` seat is your own model, so a panel whose other seats are all on your model is one-model too. Never claim a model or family is unavailable. A model listing is not proof of absence: \`${T3_CAPABILITIES_TOOL}\` filters by \`search\` and omits models beyond its limit, and the \`pstack_adapter\` tool's \`action: "models"\` shows only the session's scoped models when the user scoped some. Say which models the configuration uses instead. |
635
636
  | a delegate no role line names, such as an ad-hoc helper | adapter role \`general\`. |
636
637
  | a Custom Mode, "Use as Mode", or Option+Enter / Alt+Enter on \`/poteto-mode\` | \`/${namespace}-mode on\`, which keeps Poteto Mode active for the Pi session until \`/${namespace}-mode off\`. |
package/src/registry.ts CHANGED
@@ -7,7 +7,7 @@ import type { CapabilityId, RegistryEntry, SupportTier } from "./types.ts";
7
7
  */
8
8
  export const SKILL_REGISTRY: Readonly<Record<string, RegistryEntry>> = {
9
9
  "architect": { tier: "dependency-gated", capabilities: ["delegation"], executables: [], note: "Phase B delegates to arena runners, so it cannot run without parallel subagents." },
10
- "arena": { tier: "adapted", capabilities: ["delegation"], executables: ["git"], note: "The whole skill is spawning N candidate subagents plus a judge. Since pstack 0.15.36 the judge must come from a model family other than the parent's. The adapter maps the cross-judge pool to the `arena-cross-judge-pool` panel role, which uses `judgment`, then `general` while unset, so when the parent knows its model, the judge runs only when one of its entries is on another family. The status report and `check` warn when that pool is on one model. Otherwise arena skips the judge, picks the base alone, and says so. When the parent does not know its model, arena tries the pool in order anyway and says the family check did not run. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents: two candidates on the `judgment` and `general` roles, then a judge from the family other than the parent's, which scored them. The parent picked a base, took the fixes for two bugs from the other candidate, fixed a third that both shared, and finished with passing tests. It left the candidate worktrees for comparison." },
10
+ "arena": { tier: "adapted", capabilities: ["delegation"], executables: ["git"], note: "The whole skill is spawning N candidate subagents plus a judge. Since pstack 0.15.36 the judge must come from a model family other than the parent's, and since pstack 0.15.42 from another vendor, where Fable and the other Claude models are one vendor. Its default runners and pool are now one Fable, one Opus, and one Gemini model. The adapter maps the cross-judge pool to the `arena-cross-judge-pool` panel role, which uses `judgment`, then `general` while unset, so when the parent knows its model, the judge comes from the first pool entry from another vendor. When no entry qualifies, arena tries `judgment`, then `general`, and only when neither is from another vendor does it skip the judge, pick the base alone, and say so. The status report and `check` warn when that pool is on one model. When the parent does not know its model, arena tries the pool in order anyway and says the vendor check did not run. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents: two candidates on the `judgment` and `general` roles, then a judge from the family other than the parent's, which scored them. The parent picked a base, took the fixes for two bugs from the other candidate, fixed a third that both shared, and finished with passing tests. It left the candidate worktrees for comparison. The pstack 0.15.42 vendor rule has not run in Pi." },
11
11
  "automate-me": { tier: "experimental", capabilities: ["delegation", "structured-question"], executables: ["git", "gh"], note: "Its mining step reads this workspace's transcripts. The host mapping points it at this workspace's Pi session files, which use a different format. Verified end to end in Pi on Linux at pstack 0.15.36: it read only this workspace's sessions, told the parent chat from its subagents' files, found no stated preference there, and changed nothing. The built-in create-skill skill it drafts with has no Pi equivalent, and that step has not run in Pi." },
12
12
  "benchmark-checklist": { tier: "dependency-gated", capabilities: [], executables: ["uptime", "nproc"], note: "Its setup step checks load with `uptime` and cores with `nproc`. macOS has no `nproc` without GNU coreutils, and Git Bash on Windows has no `uptime`." },
13
13
  "blast-radius": { tier: "dependency-gated", capabilities: [], executables: ["git", "gh"], note: "Needs git and gh to read the diff, commits, and PR before any analysis." },
@@ -16,7 +16,7 @@ export const SKILL_REGISTRY: Readonly<Record<string, RegistryEntry>> = {
16
16
  "create-formal-verification-skill": { tier: "adapted", capabilities: [], executables: [], note: "Manual invocation only; no delegation. It installs or runs the verification tool it chooses and temporarily breaks product code to prove the check. Generated skills belong under `.pi/skills/` in Pi. Verified on a Windows Node finite-state fixture; other toolchains need their own prerequisites. Since pstack 0.15.32, a generated TLA+ check tells the next agent to read its results with statechart, which has its own prerequisites." },
17
17
  "create-verification-skill": { tier: "adapted", capabilities: [], executables: [], note: "Only the generated skill's output path needs remapping to Pi's skill directory." },
18
18
  "figure-it-out": { tier: "dependency-gated", capabilities: ["delegation"], executables: [], note: "Phase B fan-out and the architect/arena routing require parallel subagents." },
19
- "how": { tier: "dependency-gated", capabilities: ["delegation"], executables: [], note: "Every path spawns explorer or explainer subagents; nothing runs inline." },
19
+ "how": { tier: "dependency-gated", capabilities: ["delegation"], executables: [], note: "Since pstack 0.15.42 it spawns one read-only subagent that explores and explains in one pass, and nothing runs inline. That path has not run in Pi." },
20
20
  "in-your-own-words": { tier: "native", capabilities: [], executables: [] },
21
21
  "interrogate": { tier: "adapted", capabilities: ["delegation"], executables: ["git"], note: "Multi-model adversarial review is entirely one subagent per configured model. Since pstack 0.15.36 it picks adversaries the way arena picks runners, from the `interrogate reviewers` line, and gives each one its own worktree with the scope's uncommitted changes. Each adversary must prove a finding with a run, and the skill keeps only findings whose command it reruns and sees fail. It reports findings and applies no fixes, but adversaries write and run repro commands, and the skill reruns them, all with your permissions. A worktree is not a sandbox, so read each repro before it reruns, especially on code you do not trust. The rubric, the lead's judgment, and the code-quality lens are gone. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents: two adversaries on the `judgment` and `general` roles, from two model families, each in its own worktree, proved the same two real bugs, and the skill reran both repros before it reported them. It left the adversary worktrees in the temporary folder and named the commands that remove them." },
22
22
  "ketchup": { tier: "adapted", capabilities: [], executables: [], note: "Read-only. Pi has no `/visualize` skill or image generation, so its visuals are Mermaid diagrams and screenshots that already exist. It checks PR and CI state only for work the chat touched." },
@@ -26,7 +26,7 @@ export const SKILL_REGISTRY: Readonly<Record<string, RegistryEntry>> = {
26
26
  "make-bot-ui": { tier: "unsupported", capabilities: [], executables: ["curl", "tailscale", "sudo"], note: "Built entirely on Cursor Automations webhook routines and the secret-request card." },
27
27
  "no-comments": { tier: "dependency-gated", capabilities: ["delegation"], executables: ["git"], note: "Step 1 must spawn the comment-sicko agent; the skill only triages its report." },
28
28
  "poteto-help": { tier: "experimental", capabilities: [], executables: [], note: "Its answers describe Cursor setup, the slash menu, and Custom Modes. A request for work runs poteto-mode, which is experimental. It asks a multiple-choice question only when the need is unclear. Its README and guide links resolve under the status report's plugin directory." },
29
- "poteto-mode": { tier: "experimental", capabilities: ["delegation", "structured-question"], executables: ["git", "gh"], note: "Sticky-mode hosting plus references to Cursor built-in and plugin skills only partially map to Pi. Since pstack 0.15.36 the Orchestrate playbook calls no scripts, because the `orch` helpers are gone, and watches PRs through event subscriptions only when the harness has them. Pi standalone has none; a T3 Code host can provide them when it exposes `mcp__t3-code__watch_pull_request`. This is a host capability, not a guarantee of either delegation backend. Its Project tracker and Project store, and forking a worker with its built state, have no Pi equivalent; the host mapping says what to do instead. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents and a question tool: Orchestrate ran a two-unit program in a linked worktree, with an owner per unit on its own branch and worktree, a verifier from another model family at the owner's head, and local merges. It kept the tracker and store in a folder it added to the exclude file Git resolved for the worktree, and handed state to new agents instead of messaging old ones. Its other playbooks and sticky mode were not rerun." },
29
+ "poteto-mode": { tier: "experimental", capabilities: ["delegation", "structured-question"], executables: ["git", "gh"], note: "Sticky-mode hosting plus references to Cursor built-in and plugin skills only partially map to Pi. Since pstack 0.15.36 the Orchestrate playbook calls no scripts, because the `orch` helpers are gone, and watches PRs through event subscriptions only when the harness has them. Pi standalone has none; a T3 Code host can provide them when it exposes `mcp__t3-code__watch_pull_request`. This is a host capability, not a guarantee of either delegation backend. Its Project tracker and Project store, and forking a worker with its built state, have no Pi equivalent; the host mapping says what to do instead. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents and a question tool: Orchestrate ran a two-unit program in a linked worktree, with an owner per unit on its own branch and worktree, a verifier from another model family at the owner's head, and local merges. It kept the tracker and store in a folder it added to the exclude file Git resolved for the worktree, and handed state to new agents instead of messaging old ones. Its other playbooks and sticky mode were not rerun. Since pstack 0.15.42 it tells the user to rerun setup when the model rule has no `# defaults: 2` line. The host mapping says that check does not apply to the adapter configuration." },
30
30
  "principle-attack-the-premise": { tier: "native", capabilities: [], executables: [] },
31
31
  "principle-boundary-discipline": { tier: "native", capabilities: [], executables: [] },
32
32
  "principle-build-the-lever": { tier: "native", capabilities: [], executables: [] },
@@ -51,19 +51,19 @@ export const SKILL_REGISTRY: Readonly<Record<string, RegistryEntry>> = {
51
51
  "principle-subtract-before-you-add": { tier: "native", capabilities: [], executables: [] },
52
52
  "principle-test-behavior-not-implementation": { tier: "native", capabilities: [], executables: [] },
53
53
  "principle-type-system-discipline": { tier: "native", capabilities: [], executables: [] },
54
- "recall": { tier: "dependency-gated", capabilities: ["delegation"], executables: ["git", "gh"], note: "Its core corpus is Cursor's on-disk transcript JSONL. The host mapping points it at this workspace's Pi session files instead. Verified end to end in Pi on Linux at pstack 0.15.36: in a fresh session it found the two earlier chats in the folder that holds `$PI_SESSION_FILE`, read their user messages, checked their claims against git and the code, and rebuilt the threads, problems, and next move. With two chats to read, it read them itself, so it did not fan out to subagents, and that step has not run in Pi. A run before the host mapping said to start from `$PI_SESSION_FILE` looked in the default folder instead, which a custom `PI_CODING_AGENT_DIR` had moved, and found nothing." },
54
+ "recall": { tier: "dependency-gated", capabilities: ["delegation"], executables: ["git", "gh"], note: "Its core corpus is Cursor's on-disk transcript JSONL. The host mapping points it at this workspace's Pi session files instead. Verified end to end in Pi on Linux at pstack 0.15.36: in a fresh session it found the two earlier chats in the folder that holds `$PI_SESSION_FILE`, read their user messages, checked their claims against git and the code, and rebuilt the threads, problems, and next move. With two chats to read, it read them itself, so it did not fan out to subagents, and that step has not run in Pi. A run before the host mapping said to start from `$PI_SESSION_FILE` looked in the default folder instead, which a custom `PI_CODING_AGENT_DIR` had moved, and found nothing. Since pstack 0.15.42 its shared-record sweep spawns one investigator per source itself instead of reusing why's investigators, and that step has not run in Pi." },
55
55
  "reflect": { tier: "experimental", capabilities: ["delegation"], executables: [], note: "Its reviewers read the active transcript, and the host mapping points them at the current Pi session file. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents: three reviewers on two model families and a synthesizer read the session file, and the run found a regression the earlier review missed. When told to apply two edits, it copied the upstream skill from the plugin directory to a Pi skill location under a new name and edited only the copy. Its create-skill routing for a new skill is Cursor-specific and has not run in Pi. It never opens a PR or pushes." },
56
56
  "setup-pstack": { tier: "native", capabilities: [], executables: [], rename: "setup", replacement: "setup.md", note: "The upstream body only writes a Cursor .mdc rule, so the adapter replaces it with a Pi setup workflow." },
57
- "sharpen": { tier: "native", capabilities: [], executables: [], note: "Verified end to end in Pi on Linux at pstack 0.15.36: it handed back four short sections and a rewritten prompt for a vague gateway task, left the decisions that were the user's open, and did not start the task. Since pstack 0.15.29 it hands back a rewritten prompt and does not do the task. Its body is prompt-only, with no tool, delegation, or executable, and it runs only when you type it." },
57
+ "sharpen": { tier: "native", capabilities: [], executables: [], note: "Verified end to end in Pi on Linux at pstack 0.15.36: it handed back four short sections and a rewritten prompt for a vague gateway task, left the decisions that were the user's open, and did not start the task. Since pstack 0.15.29 it hands back a rewritten prompt and does not do the task. Its body is prompt-only, with no tool, delegation, or executable, and it runs only when you type it. Since pstack 0.15.42 the rewritten prompt asks the agent to prototype any choice an experiment can settle and leaves only product or preference choices to the user. That wording has not been rerun in Pi." },
58
58
  "show-me-your-work": { tier: "adapted", capabilities: ["delegation"], executables: [], note: "The mandatory cross-model review of the trail requires spawning a different-family subagent. Verified end to end in Pi on Linux at pstack 0.15.36 with pi-subagents: it kept a decision log the repository ignores, and its reviewer on another model family read the parent's Pi session file and checked each row against it. Its own scripts ran unchanged." },
59
- "statechart": { tier: "experimental", capabilities: [], executables: ["node", "sh", "dirname", "sed"], note: "Lowered from dependency-gated at pstack 0.15.34, because its new scripts crash on native Windows, a certified platform. There, the launcher starts `/bin/sh` by that path to stop TLC's process group, Node cannot start it even when `sh` is on PATH, and with no error handler the run exits 1 with `spawn /bin/sh ENOENT`. It writes no output and leaves an empty hidden staging folder beside the output folder and an empty `statechart-` folder in the temporary folder, so delete those by hand. `/pistack-check` still clears it there, because the gates are found. Use it from Linux, macOS, or WSL. Verified end to end on a Linux checkout fixture at pstack 0.15.34, and again at pstack 0.15.36, where it found the uncapped refill in a token bucket as the shortest path to a broken rule. The Windows end-to-end evidence from pstack 0.15.32 and 0.15.30 describes the scripts it replaced. Manual invocation only; no delegation or structured question. `scripts/statechart` is a POSIX `sh` launcher for TypeScript scripts, and it runs `dirname` and `sed` on every start. It runs the scripts under Node 22.18 to 22.x or Node 23.6 or later, then Bun 1.1.5 or later, then Deno 2.0 or later, and exits with code 127 when none is found. The prerequisite check gates on `node` but cannot check its version. The launcher does: with only an older Node on PATH, it names the versions it needs and exits 127. The command checks a TLA+ spec with TLC and writes `report.md` and TLC output to a new or empty `--out` folder, `SPEC-chart` beside the spec by default, and refuses a folder that is not empty. It also writes `chart.mmd`, except when TLC finds more than 500 states and no rule breaks. It stages its work in a hidden folder beside the output folder and in the system temporary folder, and deletes both. TLC runs from `TLA2TOOLS`, the path to a downloaded `tla2tools.jar`, with the binary in `JAVA` or `java` from PATH. Without `TLA2TOOLS`, it uses TLC 1.7.4 and Java temurin-25 from `mise`, and installs whichever is missing with `mise`, which needs the network. `JAVA` then changes only the binary that runs TLC, and does not skip the `mise` lookup or install of Java. Either `mise` or `TLA2TOOLS` with Java works, so neither is gated, and the script names what is missing when neither is set up. It imports the `--view` module as JavaScript with full process permissions, so review an existing view before you run it. Since pstack 0.15.34 the scripts render no images and do not run `npm`. For an image, the body has the agent install `pele@1.9.0` with `npm` once, outside the repository, which needs `npm` and the network, and render SVG with it. The body does not ask for `--ignore-scripts`, so pass it, and rendering still imports Pele with full process permissions. Run it in a scratch folder outside the repository. Git for Windows bundles `sh`, `dirname`, and `sed`, but not `node`, `mise`, or Java." },
59
+ "statechart": { tier: "experimental", capabilities: [], executables: ["node", "sh", "dirname", "sed"], note: "Lowered from dependency-gated at pstack 0.15.34, because its new scripts crash on native Windows, a certified platform. There, the launcher starts `/bin/sh` by that path to stop TLC's process group, Node cannot start it even when `sh` is on PATH, and with no error handler the run exits 1 with `spawn /bin/sh ENOENT`. It writes no output and leaves an empty hidden staging folder beside the output folder and an empty `statechart-` folder in the temporary folder, so delete those by hand. `/pistack-check` still clears it there, because the gates are found. Use it from Linux, macOS, or WSL. Verified end to end on a Linux checkout fixture at pstack 0.15.34, and again at pstack 0.15.36, where it found the uncapped refill in a token bucket as the shortest path to a broken rule. The Windows end-to-end evidence from pstack 0.15.32 and 0.15.30 describes the scripts it replaced. Manual invocation only; no delegation or structured question. `scripts/statechart` is a POSIX `sh` launcher for TypeScript scripts, and it runs `dirname` and `sed` on every start. It runs the scripts under Node 22.18 to 22.x or Node 23.6 or later, then Bun 1.1.5 or later, then Deno 2.0 or later, and exits with code 127 when none is found. The prerequisite check gates on `node` but cannot check its version. The launcher does: with only an older Node on PATH, it names the versions it needs and exits 127. The command checks a TLA+ spec with TLC and writes `report.md` and TLC output to a new or empty `--out` folder, `SPEC-chart` beside the spec by default, and refuses a folder that is not empty. It also writes `chart.mmd`, except when TLC finds more than 500 states and no rule breaks. It stages its work in a hidden folder beside the output folder and in the system temporary folder, and deletes both. TLC runs from `TLA2TOOLS`, the path to a downloaded `tla2tools.jar`, with the binary in `JAVA` or `java` from PATH. Without `TLA2TOOLS`, it uses TLC 1.7.4 and Java temurin-25 from `mise`, and installs whichever is missing with `mise`, which needs the network. `JAVA` then changes only the binary that runs TLC, and does not skip the `mise` lookup or install of Java. Either `mise` or `TLA2TOOLS` with Java works, so neither is gated, and the script names what is missing when neither is set up. It imports the `--view` module as JavaScript with full process permissions, so review an existing view before you run it. Since pstack 0.15.34 the scripts render no images and do not run `npm`. For an image, the body has the agent install `pele@1.9.0` with `npm` once, outside the repository, which needs `npm` and the network, and render SVG with it. The body does not ask for `--ignore-scripts`, so pass it, and rendering still imports Pele with full process permissions. Run it in a scratch folder outside the repository. Git for Windows bundles `sh`, `dirname`, and `sed`, but not `node`, `mise`, or Java. At pstack 0.15.42 the Mermaid backend can draw the edges into a nested state as one edge into its parent plus start edges inside it, and a SANY parse failure reruns SANY to print its errors. Those script changes add no executable, leave the `/bin/sh` launcher unchanged, and have not run in Pi." },
60
60
  "swarm": { tier: "experimental", capabilities: ["delegation"], executables: [], note: "Cloud background workers and cloud_base_branch have no Pi mapping; only local fan-out approximates it." },
61
61
  "tdd": { tier: "native", capabilities: [], executables: [] },
62
- "teach": { tier: "dependency-gated", capabilities: ["delegation"], executables: [], note: "It runs the how and why skills, both of which need subagents." },
62
+ "teach": { tier: "dependency-gated", capabilities: ["delegation"], executables: [], note: "It runs the how skill, which needs a subagent, and the why skill, which since pstack 0.15.42 runs inline and needs git and gh. Check why's prerequisites too." },
63
63
  "technical-writing": { tier: "native", capabilities: [], executables: [] },
64
64
  "typescript-best-practices": { tier: "native", capabilities: [], executables: [] },
65
65
  "unslop": { tier: "native", capabilities: [], executables: [] },
66
- "why": { tier: "dependency-gated", capabilities: ["delegation"], executables: ["git", "gh"], note: "Default posture spawns one investigator subagent per evidence category plus a synthesizer." },
66
+ "why": { tier: "dependency-gated", capabilities: [], executables: ["git", "gh"], note: "Since pstack 0.15.42 it spawns no subagents. It answers inline from the commits and PR discussions behind the target, and from other sources when that trail is thin, so it needs git, and gh for the PR discussions. The inline path has not run in Pi." },
67
67
  };
68
68
 
69
69
  /** Adapter-owned skills with no upstream counterpart. Keyed by unprefixed generated name. */
@@ -113,7 +113,7 @@ export const MODEL_ROLES: readonly string[] = [
113
113
 
114
114
  /**
115
115
  * Upstream's panel lines, such as `arena runners`, hold a list of models with one seat per entry.
116
- * Upstream defaults each to two model families. A panel left unset here uses the roles in
116
+ * Upstream defaults each to several model families from two vendors. A panel left unset here uses the roles in
117
117
  * `PANEL_DEFAULT_ROLES`, so it spans two families only when those roles do.
118
118
  */
119
119
  export const PANEL_ROLES: readonly string[] = [
package/src/status.ts CHANGED
@@ -216,7 +216,7 @@ function seatModels(seats: readonly PanelSeat[], ranked: boolean): Set<string> |
216
216
  }
217
217
 
218
218
  /**
219
- * Upstream's default panels span two model families. A panel whose seats all land on one model
219
+ * Upstream's default panels span several model families and two vendors. A panel whose seats all land on one model
220
220
  * lost that because of configuration, not because no other model exists, so say so where the
221
221
  * agent reads it. Families are left to the agent, which knows them better than a prefix list.
222
222
  */
@@ -232,11 +232,12 @@ export function panelWarning(panel: ResolvedPanel, config: AdapterConfig, contex
232
232
  ? `its configured entries all name ${named}`
233
233
  : `it is unset, and ${PANEL_DEFAULT_ROLES.map((role) => `\`${role}\``).join(" and ")} both resolve to ${named}`;
234
234
  const ranked = usable.some((seat) => seat.kind === "choice") ? " with the ranked picks, unless the delegating agent overrides the ranking," : ",";
235
- return `Every seat of \`${panel.role}\` runs on ${named}${ranked} because ${cause}, ${pool ? poolEffect(panel, config, model, context) : "so the panel has one model and no second family"}. This comes from the adapter configuration, not from which models are available. Run \`/skill:${config.namespace}-setup\` to put this panel on two model families, as upstream's defaults do.`;
235
+ return `Every seat of \`${panel.role}\` runs on ${named}${ranked} because ${cause}, ${pool ? poolEffect(panel, config, model, context) : "so the panel has one model and no second family"}. This comes from the adapter configuration, not from which models are available. Run \`/skill:${config.namespace}-setup\` to put this panel on models from two vendors, as upstream's defaults do.`;
236
236
  }
237
237
 
238
238
  /**
239
- * Arena's judge is never from the session's family. When no pool entry qualifies, upstream tries
239
+ * Arena's judge is never from the session's vendor, which since pstack 0.15.42 counts Fable and the
240
+ * other Claude models as one. When no pool entry qualifies, upstream tries
240
241
  * its default pool, which here is `judgment`, then `general`, before it skips the judge.
241
242
  */
242
243
  function poolEffect(panel: ResolvedPanel, config: AdapterConfig, model: string | undefined, context: ResolutionContext): string {
@@ -245,7 +246,7 @@ function poolEffect(panel: ResolvedPanel, config: AdapterConfig, model: string |
245
246
  const lead =
246
247
  model === PARENT_MODEL
247
248
  ? "and an `inherit` entry never judges, so arena"
248
- : `so a session on the family of \`${model}\` gets no judge from the pool, and arena`;
249
+ : `so a session on the vendor of \`${model}\` gets no judge from the pool, and arena`;
249
250
  const sameFallback = fallbackModels?.size === 1 && fallbackModels.has(model ?? PARENT_MODEL);
250
251
  return sameFallback
251
252
  ? `${lead} skips the judge`
package/src/vocabulary.ts CHANGED
@@ -33,8 +33,9 @@ export const CURSOR_TERMS: readonly CursorTerm[] = [
33
33
  { key: "`resume`", pattern: /`resume`/ },
34
34
  { key: "`file_attachments`", pattern: /file_attachments/ },
35
35
  { key: "`claude-opus-5-5-xhigh`", pattern: /\bclaude-[a-z]+-\d/ },
36
- { key: "`grok-4.7-xhigh-fast`", pattern: /\bgrok-\d/ },
36
+ { key: "`grok-*`", pattern: /\bgrok-\d/ },
37
37
  { key: "`gpt-*`", pattern: /\bgpt-\d/ },
38
+ { key: "`gemini-4-carbon-high`", pattern: /\bgemini-\d/ },
38
39
  { key: "`inherit-parent`", pattern: /inherit-parent/ },
39
40
  { key: "`~/.cursor/rules/pstack-models.mdc`", pattern: /pstack-models\.mdc/ },
40
41
  { key: "`.cursor/skills/`", pattern: /\.cursor\/skills/ },
@@ -53,6 +54,7 @@ export const CURSOR_TERMS: readonly CursorTerm[] = [
53
54
  { key: "Cursor `/loop`", pattern: /(^|[\s(`])\/loop\b/ },
54
55
  { key: "a skill under `plugins/cache/`", pattern: /plugins\/cache\// },
55
56
  { key: "a Custom Mode", pattern: /Custom Mode/ },
57
+ { key: "`# defaults: 2`", pattern: /# defaults: \d/ },
56
58
  ];
57
59
 
58
60
  /** One upstream Markdown file, named by its skill and its path inside the skill directory. */