From 9693d5c45bbde4481fa1ff08f92a9c8b8e991650 Mon Sep 17 00:00:00 2001 From: joshrichards37 Date: Tue, 15 Sep 2026 10:39:03 +0100 Subject: [PATCH] fix(pstack): kebab-case agent slugs with no spaces Spawn types must match this session's spawn tool enum. A space in the agent name makes lookup fail on some harnesses. Comment Sicko is comment-sicko. Slugs and fallbacks live in poteto-mode/references/harness.md. --- pstack/README.md | 6 +++--- pstack/agents/comment-sicko.md | 2 +- pstack/agents/poteto-agent.md | 2 +- pstack/skills/how/SKILL.md | 16 +++++++------- pstack/skills/interrogate/SKILL.md | 8 +++---- pstack/skills/no-comments/SKILL.md | 2 +- pstack/skills/poteto-mode/SKILL.md | 6 ++++-- .../poteto-mode/playbooks/opening-a-pr.md | 2 +- .../skills/poteto-mode/references/harness.md | 21 +++++++++++++++++++ pstack/skills/reflect/SKILL.md | 6 +++--- pstack/skills/setup-pstack/SKILL.md | 4 ++-- pstack/skills/swarm/SKILL.md | 2 +- pstack/skills/why/SKILL.md | 8 +++---- 13 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 pstack/skills/poteto-mode/references/harness.md diff --git a/pstack/README.md b/pstack/README.md index bc11234c3..08b3d0ae2 100644 --- a/pstack/README.md +++ b/pstack/README.md @@ -185,11 +185,11 @@ automate-me: /automate-me ## the `poteto-agent` and Comment Sicko subagents -pstack also ships a subagent that runs my style end to end. spawn it from a parent agent via [`subagent_type: "poteto-agent"`](./agents/poteto-agent.md). it reads `poteto-mode` in full, including its inline principles index, before doing any work. substituting `generalPurpose` skips that read and drifts. +pstack also ships a subagent that runs my style end to end. spawn it as `poteto-agent`. see [`skills/poteto-mode/references/harness.md`](./skills/poteto-mode/references/harness.md). it reads `poteto-mode` in full, including its inline principles index, before doing any work. substituting the generic type skips that read and drifts. -[`/poteto-mode`](./skills/poteto-mode/SKILL.md) and [`subagent_type: "poteto-agent"`](./agents/poteto-agent.md) route through the same wrapper. +[`/poteto-mode`](./skills/poteto-mode/SKILL.md) and the poteto agent route through the same wrapper. -pstack also ships [Comment Sicko](./agents/comment-sicko.md), a read-only comment reviewer available as `subagent_type: "Comment Sicko"`. usually invoke it through [`/no-comments`](./skills/no-comments/SKILL.md), not directly. +pstack also ships [Comment Sicko](./agents/comment-sicko.md), a read-only comment reviewer available as `comment-sicko`. the slug has no space. usually invoke it through [`/no-comments`](./skills/no-comments/SKILL.md), not directly. ## principles diff --git a/pstack/agents/comment-sicko.md b/pstack/agents/comment-sicko.md index 9a688b8c5..209e3704d 100644 --- a/pstack/agents/comment-sicko.md +++ b/pstack/agents/comment-sicko.md @@ -1,5 +1,5 @@ --- -name: Comment Sicko +name: comment-sicko description: A deranged comment-hater that savors deletion and condemns workaround code. --- diff --git a/pstack/agents/poteto-agent.md b/pstack/agents/poteto-agent.md index 91d53b859..241d607c9 100644 --- a/pstack/agents/poteto-agent.md +++ b/pstack/agents/poteto-agent.md @@ -1,6 +1,6 @@ --- name: poteto-agent -description: Routing target for `/poteto-mode` and any request for poteto's style. Resume an existing `poteto-agent` for the conversation rather than spawning a sibling. Reads the `poteto-mode` skill's `SKILL.md` in full before any work, including its inline Principles index. Substituting `generalPurpose` skips that read and drifts. +description: Routing target for `/poteto-mode` and any request for poteto's style. Resume an existing `poteto-agent` for the conversation rather than spawning a sibling. Reads the `poteto-mode` skill's `SKILL.md` in full before any work, including its inline Principles index. Substituting the generic type skips that read and drifts. is_background: true --- diff --git a/pstack/skills/how/SKILL.md b/pstack/skills/how/SKILL.md index 7d4627c3b..54fa4661c 100644 --- a/pstack/skills/how/SKILL.md +++ b/pstack/skills/how/SKILL.md @@ -21,28 +21,28 @@ When in doubt, take the simple path. Decompose the question into 2 to 4 exploration angles, each a distinct slice of the subsystem. Spawn all explorers in a single message: -- `subagent_type`: `generalPurpose` -- `model`: your configured how-explorer model (default `grok-4.6-fast-xhigh`) +- `subagent_type`: generic slug from [`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md) +- `model`: your configured how-explorer model (a slug this session's spawn tool lists) - `readonly`: `true` Each explorer gets the prompt in `references/explorer-prompt.md` with its angle filled in. Then go to Step 3. ## Step 2b. Direct Explain (simple questions) -Spawn one Task subagent that explores and explains in one pass: +Spawn one explainer that explores and explains in one pass: -- `subagent_type`: `generalPurpose` -- `model`: your configured how-explainer model (default `claude-fable-5-1-thinking-max`) +- `subagent_type`: generic slug from [`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md) +- `model`: your configured how-explainer model (a slug this session's spawn tool lists) - `readonly`: `true` Build its prompt from `references/explainer-prompt.md` without the explorer-findings section. Go to Step 4. ## Step 3. Synthesize (complex questions only) -Once all explorers have returned, spawn one Task subagent to synthesize their findings into one explanation: +Once all explorers have returned, spawn one explainer to synthesize their findings into one explanation: -- `subagent_type`: `generalPurpose` -- `model`: your configured how-explainer model (default `claude-fable-5-1-thinking-max`) +- `subagent_type`: generic slug from [`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md) +- `model`: your configured how-explainer model (a slug this session's spawn tool lists) - `readonly`: `true` Build its prompt from `references/explainer-prompt.md` with every explorer's findings filled in. diff --git a/pstack/skills/interrogate/SKILL.md b/pstack/skills/interrogate/SKILL.md index b59dff74c..a0eeac31b 100644 --- a/pstack/skills/interrogate/SKILL.md +++ b/pstack/skills/interrogate/SKILL.md @@ -33,7 +33,7 @@ Write one clear paragraph. If you're unsure about the intent, ask the user befor ## Step 3, Spawn Reviewers -Launch all reviewers in a single message using the Task tool. Use the `interrogate reviewers` list from `~/.cursor/rules/pstack-models.mdc` when present, one reviewer per entry, extending or shrinking the Reviewer A/B/C/D labels below to the configured entry count. Otherwise use the table defaults. +Launch all reviewers in a single message using this session's spawn tool ([`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md)). Use the `interrogate reviewers` list from `~/.cursor/rules/pstack-models.mdc` when present, one reviewer per entry, extending or shrinking the Reviewer A/B/C/D labels below to the configured entry count. Otherwise use the table defaults. Drop a default row whose slug this session's spawn tool does not list. | Subagent | Default model | |----------|---------------| @@ -43,11 +43,11 @@ Launch all reviewers in a single message using the Task tool. Use the `interroga | Reviewer D | `claude-opus-5-thinking-xhigh` | For each reviewer: -- `subagent_type`: `generalPurpose` -- `model`: the configured `interrogate reviewers` entry, or the table default with no configured line +- `subagent_type`: generic slug from [`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md) +- `model`: the configured `interrogate reviewers` entry, or the table default with no configured line, if this session's spawn tool lists it - `readonly`: `true` -If a model slug is rejected as unresolvable when you try to spawn the subagent, check the valid slugs in the Task tool's error message, pick the closest equivalent (prefer the highest-reasoning tier of the same family), spawn with the valid slug, and open a separate PR to update the configured value or default table. Do not block the review on the slug issue. If the configured value is `inherit-parent` or `auto`, omit `model` instead. Never treat those aliases as broken slugs or enter this fallback for them. +If a model slug is rejected as unresolvable when you try to spawn the subagent, check the valid slugs in the spawn tool's error message, pick the closest equivalent (prefer the highest-reasoning tier of the same family), spawn with the valid slug, and open a separate PR to update the configured value or default table. Do not block the review on the slug issue. If the configured value is `inherit-parent` or `auto`, omit `model` instead. Never treat those aliases as broken slugs or enter this fallback for them. Read `references/reviewer-prompt.md` and fill in the template with: 1. The stated intent diff --git a/pstack/skills/no-comments/SKILL.md b/pstack/skills/no-comments/SKILL.md index 3b3e76295..025dd0732 100644 --- a/pstack/skills/no-comments/SKILL.md +++ b/pstack/skills/no-comments/SKILL.md @@ -16,7 +16,7 @@ Use the caller's files or diff. Otherwise use the current diff against the base ## Steps -1. Spawn `Task` with `subagent_type: "Comment Sicko"`. Pass the scope. Do not restate its rules. +1. Spawn the comments agent from [`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md) (`comment-sicko` / `pstack:comment-sicko`). Pass the scope. Do not restate its rules. If spawn lookup fails, spawn poteto with `agents/comment-sicko.md` as the prompt. 2. Inspect its report and diff. Reject application-code edits, scope escapes, exception-protected deletions, misstated `MUST KILL` reasons, and flags that treat kept intentional code as guilty. Reshape flags on our-code surprises stay actionable. Do not restore those comments. A keep survives only with proof it is about something we cannot change. Audit missed scoped lint and TypeScript suppressions. Correctness or safety suppressions stay actionable `MUST KILL`s. Restore deletions only with exact exceptions and scoped proof. Before accepting thin `IMPORTANT` or `do not remove` kills or keeps, run `/how` or `/why` on their symbol. If a kill is ambiguous, do not restore. If a keep is refuted or still ambiguous, delete it. Revert and rerun one rejected report with the failure named. Reject a second, report it open, and fail `/no-comments`. 3. Fix trivial accepted flags directly by deleting a dead path, dropping a parameter, or using the real API. If any fix needs a shape, run `/architect` once for the accepted set and surrounding code. Stop at the sketch. Architect shapes. Step 4 implements. 4. Implement the smallest root-cause fix in scope. Remove every named workaround. If the root cause is out of scope, land the smallest in-scope fix and report the rest open. The **principle-fix-root-causes** and **principle-redesign-from-first-principles** skills guide intent only. Neither authorizes widening the fence nor fixing instances outside it. Never bolt on symptom guards. diff --git a/pstack/skills/poteto-mode/SKILL.md b/pstack/skills/poteto-mode/SKILL.md index 7559dea02..a3ef6dfae 100644 --- a/pstack/skills/poteto-mode/SKILL.md +++ b/pstack/skills/poteto-mode/SKILL.md @@ -88,9 +88,11 @@ Read the leaf skill in full for any principle you apply. Each entry names when i ## Subagents -**Use `subagent_type: "poteto-agent"` for any subagent you spawn inside a playbook step** (code-writing delegates, ad-hoc helpers). `/poteto-mode` and `poteto-agent` route through the same wrapper. Routed workflow skills (`how`, `why`, `interrogate`, `reflect`, `swarm`) set their own `subagent_type` for diverse-model review. Respect what the skill prescribes, don't override to `poteto-agent`. +Spawn types, spawn tool name, and model slugs live in [`references/harness.md`](references/harness.md). Read it before the first spawn in a session. -**Defaults for every `Task` call.** `run_in_background: true`, agent mode (readonly strips MCP), file pointers not inlined context, explicit model per role (configurable via `/setup-pstack`. Defaults `grok-4.6-fast-xhigh` for code, `claude-fable-5-1-thinking-max` for prose and judgment). Code delegates tier by difficulty. The hardest changes (cross-cutting design, gnarly concurrency, subtle algorithms) go to your strongest judgment model (`claude-fable-5-1-thinking-max`), whether the task needs judgment on vague intent or is a precisely specified sequence of steps to execute to the letter. Trivial mechanical edits go to your fast code model. Per-role lines in the `/setup-pstack` rule override these defaults and the model choices in the routed skills (`how`, `why`, `arena`, `swarm`, `architect`, `interrogate`, `reflect`). A role with no line keeps its default, and a role line of `inherit-parent` or `auto` runs that role on the parent chat model (omit Task `model`). +**Use the poteto slug for any subagent you spawn inside a playbook step** (code-writing delegates, ad-hoc helpers). `/poteto-mode` and `poteto-agent` route through the same wrapper. Routed workflow skills (`how`, `why`, `interrogate`, `reflect`, `swarm`) set their own type for diverse-model review. Respect what the skill prescribes, don't override to poteto. + +**Defaults for every spawn.** `run_in_background: true` / `background: true`, agent mode (readonly strips MCP), file pointers not inlined context, explicit model per role (configurable via `/setup-pstack`). Code delegates tier by difficulty. The hardest changes (cross-cutting design, gnarly concurrency, subtle algorithms) go to your strongest listed judgment model. Trivial mechanical edits go to your fast code model. Per-role lines in the `/setup-pstack` rule override these defaults and the model choices in the routed skills (`how`, `why`, `arena`, `swarm`, `architect`, `interrogate`, `reflect`). A role with no line keeps its default, and a role line of `inherit-parent` or `auto` runs that role on the parent chat model (omit `model`). You own every subagent's work. Review the diff and write your own summary, don't pass through what it said. Interrupt-chained resumes silently drop directives, so fire a fresh subagent with consolidated scope rather than trusting a "done" summary. A second opinion is the same prompt against a different model. Agreement is high-signal. diff --git a/pstack/skills/poteto-mode/playbooks/opening-a-pr.md b/pstack/skills/poteto-mode/playbooks/opening-a-pr.md index a5c65a095..64a476e70 100644 --- a/pstack/skills/poteto-mode/playbooks/opening-a-pr.md +++ b/pstack/skills/poteto-mode/playbooks/opening-a-pr.md @@ -2,7 +2,7 @@ Invoked at the end of every other playbook. -**Worktree.** Work from a git worktree off main. Subagents inherit it. Multiple `Task` calls on the same branch each get their own worktree, or `git fetch && git reset --hard origin/` between them. Dirty branch with unrelated work: patch out, fresh worktree, apply. Snarled worktree: reset from main, redo minimally. +**Worktree.** Work from a git worktree off main. Subagents inherit it. Multiple spawns on the same branch each get their own worktree, or `git fetch && git reset --hard origin/` between them. Dirty branch with unrelated work: patch out, fresh worktree, apply. Snarled worktree: reset from main, redo minimally. Spawn types: [`../references/harness.md`](../references/harness.md). **Commits.** Commit liberally. Rebase into small, ordered commits before opening PRs. Each commit is a future PR: landable, ordered to tell the story. Amend when the fix belongs in a just-made commit. New commit when separable. diff --git a/pstack/skills/poteto-mode/references/harness.md b/pstack/skills/poteto-mode/references/harness.md new file mode 100644 index 000000000..af8bc2d7d --- /dev/null +++ b/pstack/skills/poteto-mode/references/harness.md @@ -0,0 +1,21 @@ +# Spawn harness + +Use this session's spawn tool. Agent type slugs are kebab-case. Never put a space in `subagent_type`. + +## Types + +| Role | Slug | +| --- | --- | +| poteto | `poteto-agent` | +| comments | `comment-sicko` | +| generic | the generic type this session's spawn tool lists | +| explore | `explore` | +| plan | `plan` | + +If the spawn tool lists a plugin prefix, use the prefixed form. + +If lookup fails, retry the unprefixed slug, then the prefixed one. If that fails, spawn `poteto-agent` with the target agent's markdown as the prompt. Do not stop the playbook. + +## Models + +Use `/setup-pstack` slugs. Pass only a slug this session's spawn tool lists. Omit `model` when the role is `inherit-parent` or `auto`. diff --git a/pstack/skills/reflect/SKILL.md b/pstack/skills/reflect/SKILL.md index d00495178..ca159a480 100644 --- a/pstack/skills/reflect/SKILL.md +++ b/pstack/skills/reflect/SKILL.md @@ -28,7 +28,7 @@ For each candidate, read the first JSONL line and check that `message.content[0] ### 2. Spawn three reviewers in parallel -One message, three `Task` calls, `subagent_type: generalPurpose`, explicit `model:` on each, agent mode (`readonly: false`). Reviewers need MCP access for context lookups (tickets, chat threads, observability traces referenced in the transcript). Readonly strips MCPs. +One message, three spawns, generic type from [`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md), explicit `model:` on each, agent mode (`readonly: false`). Reviewers need MCP access for context lookups (tickets, chat threads, observability traces referenced in the transcript). Readonly strips MCPs. | Lens | `model` | Prompt template | |---|---|---| @@ -36,11 +36,11 @@ One message, three `Task` calls, `subagent_type: generalPurpose`, explicit `mode | Tooling | your configured reflect-tooling model (default `gpt-5.6-sol-max`) | `references/tooling-reviewer.md` | | Divergent | your configured reflect-judgment model (default `claude-fable-5-1-thinking-max`) | `references/divergent-reviewer.md` | -Pass each template verbatim, substituting the transcript path or digest where marked. Reviewers return findings in the `Task` response body. +Pass each template verbatim, substituting the transcript path or digest where marked. Reviewers return findings in the spawn response body. ### 3. Synthesize -One `Task` call, `subagent_type: generalPurpose`, using your configured reflect-judgment model (default `claude-fable-5-1-thinking-max`), agent mode (`readonly: false`). The synthesizer's quality check includes spot-verifying citations, which can require MCP access. Readonly strips MCPs. Use `references/synthesizer.md` verbatim, with each reviewer's full output inlined where marked. The synthesizer returns a structured Accepted / Rejected / Backlog list. +One spawn, generic type from [`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md), using your configured reflect-judgment model (a slug this session's spawn tool lists), agent mode (`readonly: false`). The synthesizer's quality check includes spot-verifying citations, which can require MCP access. Readonly strips MCPs. Use `references/synthesizer.md` verbatim, with each reviewer's full output inlined where marked. The synthesizer returns a structured Accepted / Rejected / Backlog list. ### 4. Structural enforcement check diff --git a/pstack/skills/setup-pstack/SKILL.md b/pstack/skills/setup-pstack/SKILL.md index ac9124599..cafc0d993 100644 --- a/pstack/skills/setup-pstack/SKILL.md +++ b/pstack/skills/setup-pstack/SKILL.md @@ -11,7 +11,7 @@ Write `~/.cursor/rules/pstack-models.mdc`, an always-applied rule that sets psta ### 1. Detect available models -Enumerate the model slugs you can pass to a `Task` subagent in this session. That is the dependable source. If Cursor also exposes a models API or CLI that lists the user's entitled models, prefer it for completeness. If you cannot detect any, ask the user to paste the slugs they have access to. Never write a real slug you have not confirmed is available. The aliases `inherit-parent` and `auto` are always valid even though they are not detected slugs. +Enumerate the model slugs you can pass to this session's spawn tool. See [`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md). That is the dependable source. If the harness also exposes a models API or CLI that lists the user's entitled models, prefer it for completeness. If you cannot detect any, ask the user to paste the slugs they have access to. Never write a real slug you have not confirmed is available. The aliases `inherit-parent` and `auto` are always valid even though they are not detected slugs. ### 2. Load current state @@ -44,7 +44,7 @@ description: pstack per-role model choices (overrides skill defaults) alwaysApply: true --- # pstack model configuration. One line per role. Delete a line to fall back to the skill default. -# `inherit-parent` or `auto` as a value: the role runs on the parent chat model (omit Task `model`). Alias entries in a panel list still count toward its fan-out. +# `inherit-parent` or `auto` as a value: the role runs on the parent chat model (omit `model`). Alias entries in a panel list still count toward its fan-out. # budget: unlimited (max) feature, refactoring: grok-4.6-fast-xhigh bug-fix: grok-4.6-fast-xhigh diff --git a/pstack/skills/swarm/SKILL.md b/pstack/skills/swarm/SKILL.md index 5b465d3ba..10443bece 100644 --- a/pstack/skills/swarm/SKILL.md +++ b/pstack/skills/swarm/SKILL.md @@ -27,7 +27,7 @@ Open a todolist with one entry per phase before launching anything. ## Phase B: Fan out -Spawn all N workers in one message with `subagent_type: generalPurpose`, `environment: "cloud"`, `run_in_background: true`, and the configured model. Use `environment: "local"` only when the worker needs access to something on the user's computer. +Spawn all N workers in one message with the generic type from [`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md), `environment: "cloud"` when the spawn tool has it, `run_in_background: true` / `background: true`, and the configured model. Use `environment: "local"` only when the worker needs access to something on the user's computer. Skip `environment` when the spawn tool has no such parameter. When a worker must start from a non-default pushed branch, pass `cloud_base_branch`. diff --git a/pstack/skills/why/SKILL.md b/pstack/skills/why/SKILL.md index 53045ddba..5e3727941 100644 --- a/pstack/skills/why/SKILL.md +++ b/pstack/skills/why/SKILL.md @@ -78,8 +78,8 @@ Aim for a complete **coverage map**, not a minimal one. Document the null, don't Launch all matching investigators in a single message so they run concurrently. Don't ask one agent to cover multiple MCPs. Subagent config (each): -- `subagent_type`: `generalPurpose` -- `model`: your configured why-investigators model (default `grok-4.6-fast-xhigh`) +- `subagent_type`: generic slug from [`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md) +- `model`: your configured why-investigators model (a slug this session's spawn tool lists) - `readonly`: `false` (agent mode). **Do not use readonly/Ask mode.** It strips MCP access, which disables MCP-backed investigators entirely. Investigators still shouldn't write anything. Each investigator gets: @@ -122,8 +122,8 @@ If your scope assessment suggests a single-commit trivial target where the PR de Spawn one synthesizer subagent: -- `subagent_type`: `generalPurpose` -- `model`: your configured why-synthesizer model (default `claude-fable-5-1-thinking-max`) +- `subagent_type`: generic slug from [`../poteto-mode/references/harness.md`](../poteto-mode/references/harness.md) +- `model`: your configured why-synthesizer model (a slug this session's spawn tool lists) - `readonly`: `false` (agent mode). The synthesizer's quality check spot-verifies citations, which can require MCP access. Readonly/Ask mode strips MCPs and defeats that. The synthesizer gets: