diff --git a/.devin-plugin/plugin.json b/.devin-plugin/plugin.json index 7e4d8be..9492db2 100644 --- a/.devin-plugin/plugin.json +++ b/.devin-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "pstack", - "version": "0.5.0", + "version": "0.6.1", "description": "Rigorous agent workflows for Devin CLI. Write less, higher quality code.", "homepage": "https://github.com/athul-ramesh/ptstack-devin", "repository": "https://github.com/athul-ramesh/ptstack-devin", diff --git a/README.md b/README.md index 3b0a3f7..7502c04 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,15 @@ Avoid installing two copies with the same plugin name. Devin may source-qualify Ask `/pstack:poteto-help` with a setup or workflow question. This explicit-user skill answers with one suggested prompt and a source link. It does not start a task for a help question. A request to do work follows poteto-mode instead. -Invoke [`/pstack:ketchup`](skills/ketchup/SKILL.md) to catch up on this chat since your last message. It is explicit-user and read-only. It summarizes changes and decisions in under 250 words, with available visuals, options, costs, a recommendation, and what happens without an answer. The CLI uses compact text when no renderer is available. +Invoke [`/pstack:ketchup`](skills/ketchup/SKILL.md) to catch up on this chat since your last message. It is explicit-user and read-only. It summarizes changes and decisions well under 150 words in plain sentences, with small available visuals, options, costs, a recommendation, and what happens without an answer. The CLI uses compact text when no renderer is available. The [usage guide](docs/usage-guide.md) covers prompting, investigation, prototypes before plans, real behavior verification, benchmark evidence, repeated-mistake enforcement, and bounded in-session delivery. The help skill includes [prompting guidance](skills/poteto-help/references/prompting.md) and [copyable recipes](skills/poteto-help/references/recipes.md). +Invoke [`/pstack:sharpen`](skills/sharpen/SKILL.md) before a task to have the agent frame it the way a top expert would, keep one outside check, leave your choices open, and then do the work. It runs only when requested. + Invoke [`/pstack:in-your-own-words`](skills/in-your-own-words/SKILL.md) to hear the goals and problem the agent understood. It runs only when requested and adds no confirmation gate. -This release selectively ports upstream pstack 0.15.23. It adds goal playback, shorter ketchup replies, usable-state verification, a cheap observability proposal after deep debugging, robust Markdown fence checks, and configurable worktree merge bases. Devin dispatch, profile pins, and delivery authority are preserved. See the [port audit](docs/pstack-0.15.23-port-audit.md) for source coverage, exclusions, and evidence limits. Earlier audits cover [0.15.17](docs/pstack-0.15.17-port-audit.md) and [0.15.13](docs/pstack-0.15.13-port-audit.md). +Release 0.6.1 selectively ports upstream pstack 0.15.25; see the [0.15.25 port audit](docs/pstack-0.15.25-port-audit.md). Release 0.6.0 selectively ported upstream pstack 0.15.24; see the [0.15.24 port audit](docs/pstack-0.15.24-port-audit.md). The prior release selectively ported upstream pstack 0.15.23. It adds goal playback, shorter ketchup replies, usable-state verification, a cheap observability proposal after deep debugging, robust Markdown fence checks, and configurable worktree merge bases. Devin dispatch, profile pins, and delivery authority are preserved. See the [port audit](docs/pstack-0.15.23-port-audit.md) for source coverage, exclusions, and evidence limits. Earlier audits cover [0.15.17](docs/pstack-0.15.17-port-audit.md) and [0.15.13](docs/pstack-0.15.13-port-audit.md). ## Features retained from 0.2.0 diff --git a/docs/pstack-0.15.24-port-audit.md b/docs/pstack-0.15.24-port-audit.md new file mode 100644 index 0000000..09a38e4 --- /dev/null +++ b/docs/pstack-0.15.24-port-audit.md @@ -0,0 +1,34 @@ +# Port pstack 0.15.24 to Devin + +Audited on 2026-10-15 against Devin baseline `01bc45a`. Plugin version is 0.6.0, with 37 public skills, 24 internal principle leaves, and 20 playbooks. + +## Source and coverage + +Upstream range: [`dbf4981...1e5c90a`](https://github.com/cursor/plugins/compare/dbf49813a39c1a5389c5e28cb8e4c1c2379e2454...1e5c90a4b6f249917bd21fe361b3a2a7deb741b8) (`pstack/`, 0.15.23 to 0.15.24). The previous audit already covers the 0.15.23 baseline, including #539, #570, #571, #575, #577, #602, and #606, so no earlier prerequisite is missing. + +| Upstream change | Devin disposition | +| --- | --- | +| [#615](https://github.com/cursor/plugins/pull/615) `/sharpen` | Ported as `/pstack:sharpen` with `triggers: [user]`, the documented Devin equivalent of `disable-model-invocation: true`. Help entry and recipe added. | +| [#609](https://github.com/cursor/plugins/pull/609) ketchup rewrite | Ported. Under-150-word budget that counts visual and fallback words, bro voice without its task, two-line action items, unasked irreversible steps, box and label limits. Retains the host-rendering limit and text fallback. Drops `/visualize`, which this port does not ship. | +| [#613](https://github.com/cursor/plugins/pull/613) per-spawn effort and fast-mode rule | Adapted to one statement in poteto-mode Models. Devin `run_subagent` takes a profile, not a model, so there is no per-call reasoning or speed knob. The rule's one-liners in arena, how, why, interrogate, swarm, reflect, recall, and other playbooks are not added. | +| #613 `cursor-grok-*` and `composer-*` family fallbacks | Skipped. Cursor model slugs. This port ships no Cursor slugs. | +| #613 swarm cadence | Adapted in multi-phase-plan. The full audit set runs once at the code-ready SHA, and again only for new behavior, a redesign, or a large diff. Rebases, conflict resolutions, and minor fixes get one fresh-context verifier. | +| #613 orchestrate, shipping, autopilot drop Graphite and prefer Origin | Already satisfied for Graphite. Fork prose and helpers use `gh` only. Origin CLI preference skipped. It is a Cursor forge, not part of the Devin docs. Shipping and autopilot remain cut. The `orch.ts` frontier rewrite is skipped because this port has no orch helper. | +| #613 `worktree-audit.sh` Origin branch | Skipped for the same reason. The `gh` path is unchanged. | +| #613 `watch-pr` GitHub changes | Skipped. This port has no watch-pr helper. | +| [#616](https://github.com/cursor/plugins/pull/616) autopilot catches up with ketchup | Skipped. Autopilot-full and autopilot-stack are cut. | +| [#617](https://github.com/cursor/plugins/pull/617) version bump | Plugin bumped independently to 0.6.0. | +| #613 `/loop 1h` tick and Cursor cloud agent owners | Skipped. Devin `/loop` is not a timer. | + +## Devin compatibility + +| Capability | Evidence | +| --- | --- | +| User-only skills | Documented `triggers` field, default `[user, model]`. [Creating skills](https://docs.devin.ai/cli/extensibility/skills/creating-skills). | +| No per-dispatch model or effort | Documented. "The `run_subagent` tool takes a profile, not a model." [Subagents](https://docs.devin.ai/cli/subagents). | +| Plugin skills and agents | Local CLI and Desktop only. [Plugins](https://docs.devin.ai/cli/extensibility/plugins/overview). | +| `/loop` | Interactive review loop, not a scheduler. [Commands](https://docs.devin.ai/cli/reference/commands). | + +## Verification and limits + +`node --test tests/*.test.mjs` passes. The test suite adds `sharpen` to the user-activation contract. These are static checks. Native 0.6.0 skill registration, slash activation, and visual rendering are untested. diff --git a/docs/pstack-0.15.25-port-audit.md b/docs/pstack-0.15.25-port-audit.md new file mode 100644 index 0000000..a7f7f00 --- /dev/null +++ b/docs/pstack-0.15.25-port-audit.md @@ -0,0 +1,27 @@ +# Port pstack 0.15.25 to Devin + +Audited on 2026-10-16 on top of the open 0.15.24 port branch (`port/pstack-v0.15.24`, PR #8). Plugin version is 0.6.1, with 37 public skills, 24 internal principle leaves, and 20 playbooks. + +## Source and coverage + +Upstream range: [`1e5c90a...99743e9`](https://github.com/cursor/plugins/compare/1e5c90a4b6f249917bd21fe361b3a2a7deb741b8...99743e9c151c8537cbbf1f98bb38f34ef3368453) (`pstack/`, 0.15.24 to 0.15.25 and two follow-ups). + +| Upstream change | Devin disposition | +| --- | --- | +| [#628](https://github.com/cursor/plugins/pull/628) ketchup explains changes with screenshots, videos, and diagrams | Adapted. Ketchup now helps the user understand each change, shows existing screenshots, videos, and diagrams first, sums up in one bullet per ask, lists action items as plain bullets, and puts a choice after the list. Rendered pictures no longer count toward the 150 words; text fallbacks still do. Every picture stays conditional on the Devin host rendering it, and the text fallback is kept, now linking existing captures. `/visualize` stays dropped because this port does not ship it. | +| [#633](https://github.com/cursor/plugins/pull/633) four principles restated as reasoning | Ported verbatim apart from `triggers: [model]` frontmatter: attack-the-premise (test the premise instead of an actor census), fix-root-causes (a guard is a fix only when the state is legitimate), make-operations-idempotent (derive each step from existing state), test-behavior-not-implementation (break-the-behavior and change-the-internals checks). The poteto-mode principle index and `/pstack:correct` step 3 follow. | +| [#634](https://github.com/cursor/plugins/pull/634) cut marginal sections from four skills | Ported. Lead judgment drops its preamble and verdict calibration. Migrate-callers drops its intro, rule bullets, and closing line, as upstream did. Type-system-discipline drops the illegal-states, constructions, cast, exhaustiveness, and partiality bullets, keeping `/pstack:typescript-best-practices`. Swarm drops its opening sentence and the N-is-total-workers step; Devin PanelRun, workspace, model, and evidence sections are untouched. | +| [#614](https://github.com/cursor/plugins/pull/614) version bump | Plugin bumped independently to 0.6.1. | + +## Devin compatibility + +| Capability | Evidence | +| --- | --- | +| Model-triggered principle leaves | Documented `triggers` field. [Creating skills](https://docs.devin.ai/cli/extensibility/skills/creating-skills). | +| Inline screenshots, video, Mermaid | Not documented for the Devin CLI terminal. The changelog documents image attachments as input and Markdown table rendering, not inline image or diagram output. Ketchup therefore keeps every picture conditional on the host and keeps the text fallback. [CLI changelog](https://docs.devin.ai/cli/changelog/stable). | + +The principle and cut changes are prose-only and touch no Devin tool, profile, hook, or helper. + +## Verification and limits + +`node --test tests/*.test.mjs` passes, including a new contract test for the ketchup fallback and the rewritten principles. These are static checks. Native 0.6.1 skill registration and inline visual rendering in Devin are untested. diff --git a/docs/release-notes.md b/docs/release-notes.md index 56d3ee7..a20438d 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,5 +1,9 @@ # Release notes +Plugin `pstack` 0.6.1 selectively ports upstream 0.15.25. Four principles (attack-the-premise, fix-root-causes, make-operations-idempotent, test-behavior-not-implementation) are restated as reasoning instead of rules, and `/pstack:correct` follows the new test rule. Marginal sections are cut from interrogate's lead judgment, migrate-callers, type-system-discipline, and swarm. Ketchup now explains each change, leads with existing screenshots, videos, and diagrams when the host renders them, sums up in bullets, and lists action items as plain bullets. The Devin text fallback is kept. Native activation of 0.6.1 and inline image rendering remain untested. See the [port audit](pstack-0.15.25-port-audit.md). + +Plugin `pstack` 0.6.0 selectively ports upstream 0.15.24. It adds explicit-user `/pstack:sharpen`, rewrites ketchup to a reply well under 150 words with small plain-language visuals, states that Devin dispatch has no per-call effort or speed knob, and runs the full plan audit set once at the code-ready SHA with a single fresh-context verifier for rebases and minor fixes. Native activation of 0.6.0 remains untested. See the [port audit](pstack-0.15.24-port-audit.md). + Plugin `pstack` 0.5.0 selectively ports upstream 0.15.23. It adds explicit-user `/pstack:in-your-own-words`, short ketchup replies with available visuals and a text fallback, usable-state verification, and an observability proposal after deep debugging. Plan validation tracks Markdown fence delimiters. Worktree audits use the remote default or an explicit base and accept merged-PR evidence only for that base. Native activation of 0.5.0 remains untested. See the [port audit](pstack-0.15.23-port-audit.md). Plugin `pstack` 0.4.0 adds explicit-user, read-only `/pstack:ketchup` and ports the prompt reductions from upstream pstack #538 and #539 at 0.15.17. Existing Devin profile pins, dispatch contracts, helpers, hooks, and delivery authority remain intact. Native activation of this release is untested. See the [port audit](pstack-0.15.17-port-audit.md). @@ -10,7 +14,7 @@ Plugin 0.2.0 was verified on local Devin CLI 3000.11.3 (9c803229faa4). Earlier 3 ## Shipped -36 public skills under `/pstack:`. 24 `principle-*` leaves, model-triggered. 20 poteto-mode playbooks. Profiles `pstack:poteto-agent`, `pstack:poteto-agent-{swe,opus,sonnet,codex}`, `pstack:comment-sicko`, and `pstack:panel-{swe,opus,sonnet,codex}`. +37 public skills under `/pstack:`. 24 `principle-*` leaves, model-triggered. 20 poteto-mode playbooks. Profiles `pstack:poteto-agent`, `pstack:poteto-agent-{swe,opus,sonnet,codex}`, `pstack:comment-sicko`, and `pstack:panel-{swe,opus,sonnet,codex}`. SessionStart injects `PSTACK_ROUTE=/pstack:poteto-mode`. diff --git a/skills/correct/SKILL.md b/skills/correct/SKILL.md index d4044d1..d70fcd9 100644 --- a/skills/correct/SKILL.md +++ b/skills/correct/SKILL.md @@ -19,7 +19,7 @@ First, read recent commits, reverts, review comments, agent instruction files, a 1. **Eliminate it with architecture.** Give each piece of state one owner and each task one supported way. Hide internals so the wrong import fails. Replace hand-synced lists with one source of truth. Delete old ways and dead code an agent would copy. 2. **Enforce it with types so the bad state can't be written.** If bad code still compiles, add a lint or CI check whose error names the file, type, or function to use instead. If the pattern is already common, fail only when a change adds more. -3. **Test the behavior.** Fix or delete any test that would still pass if every function it calls returned nothing. +3. **Test the behavior.** Fix or delete any test that still passes when the behavior it checks breaks, or that fails when only the internals change. 4. **Write docs or agent rules last, only for judgment calls.** Nothing fails when an agent skips them. ## Fix and prove diff --git a/skills/interrogate/references/lead-judgment.md b/skills/interrogate/references/lead-judgment.md index ea6262e..3b41346 100644 --- a/skills/interrogate/references/lead-judgment.md +++ b/skills/interrogate/references/lead-judgment.md @@ -1,18 +1,5 @@ # Lead Judgment Framework -You are the lead reviewer. The configured reviewers have produced their findings. Apply pragmatic engineering judgment. Don't aggregate; filter, contextualize, and decide. - -## Why This Step Matters - -Adversarial reviewers are useful because they're aggressive. But aggression without context produces noise. The reviewers only saw a slice of the codebase and a one-paragraph intent statement. They don't know: - -- What was already tried and rejected -- What constraints exist outside the code (timeline, dependencies, migration plans) -- Which parts of the code are temporary scaffolding vs. permanent architecture -- What the next PR in the stack will address - -You have the full conversation context. Use it. - ## Filtering Principles ### Nitpick Gravity @@ -50,9 +37,3 @@ Don't dismiss findings just because they're uncomfortable. The whole point of ad - You read the finding and think "...yeah, actually" Be especially careful about dismissing security findings and correctness bugs. These deserve more scrutiny even when they come from a single model. - -## Verdict Calibration - -A good verdict is useful, not comprehensive. The user should be able to read the "Act On" section, fix those issues, and ship with confidence. If your "Act On" list has more than 5 items, you're probably not filtering hard enough. - -The "Dismissed" section is not busywork. It's a trust mechanism. Showing the user what you rejected and why lets them override your judgment where they disagree. This is more valuable than hiding the rejected findings. diff --git a/skills/ketchup/SKILL.md b/skills/ketchup/SKILL.md index 1fc8c4e..c3a5303 100644 --- a/skills/ketchup/SKILL.md +++ b/skills/ketchup/SKILL.md @@ -1,34 +1,40 @@ --- name: ketchup -description: "Catch the user up on what changed in this chat since their last message, in a short reply with available visuals. Give each action item just enough context to make the call. Use for /pstack:ketchup." +description: "Catch the user up on what changed in this chat since their last message, in a few plain sentences and small available visuals. Give each action item just enough context to make the call. Use for /pstack:ketchup." triggers: - user --- # Ketchup -Catch the user up on what changed in this chat since the last message they wrote before `/pstack:ketchup`. Notifications and subagent results are not their messages. Write in the plain voice of [`/pstack:bro`](../bro/SKILL.md), and skip its restating step. Assume the user remembers their last message and nothing after it. Call each PR, branch, or agent by a name they would know. +Catch the user up on what changed in this chat since the last message they wrote before `/pstack:ketchup`, and help them understand each change, not only where it stands. Notifications and subagent results are not their messages. Assume the user remembers their last message and nothing after it. + +Use [`/pstack:bro`](../bro/SKILL.md)'s voice, not its task: plain words, short sentences, no jargon, like one person catching up another. Say what changed for the user, not how you did it. Say "the tests pass", not "CI is green". Leave out hashes, file paths, commands, build numbers, and test counts unless the user needs one to act. Call each PR, branch, or agent by a name the user would know, not by a label you invented. If a fact needs context to make sense, give the context or leave the fact out. ## Gather what changed -Keep this turn read-only, except for local reply visuals made from facts and artifacts you already have. Do not change repository code or data, start an app or a job, or post anything to make them. Collect your own work since that message, subagent reports, and other messages in this chat. Check the current state of each PR, CI run, or agent this chat touched. Say which are still running and which you could not check. Check each number against its source and disclose corrections. +Keep this turn read-only. Make visuals only from facts and artifacts you already have. Do not change repository code or data, start an app or a job, or post anything to make them. Collect your own work since that message, subagent reports, and other messages in this chat. Check the current state of each PR, CI run, or agent this chat touched. Say which you could not check. Check each number against its source and say so when you correct one. -An action item is a decision or step only the user can take. Include any still waiting on the user, even one raised before their last message. Work you can do yourself is not an action item. +An action item is a decision or step only the user can take, such as a product choice, an approval, an irreversible action, or access you lack. Include any still waiting on the user, even one raised before their last message. Work you can still do yourself is not an action item. Never make up a call to fill the reply. A step the user did not ask for and the work does not need is not an action item, unless it is irreversible and waiting on the user. Give it one action line, no visual, and skip what happens without an answer. ## Write the reply -Keep the text under 250 words. Markdown tables, diagram source, and text fallbacks count as text. Rendered pictures do not. A visual replaces the facts it shows. Do not repeat them in text. Leave out work that changed nothing for the user. +Keep the whole reply well under 150 words, not counting rendered screenshots, videos, or diagrams. Tables and text fallbacks count. When something is easier to grasp as a picture than as sentences, draw it if the host renders it: how a design or system works, a PR stack or dependency chain with each PR's state, a before and after of a fix, or options side by side. Never draw a status list or boxes with nothing connecting them. Never give a fact twice, in text or across visuals. Leave out work that changed nothing for the user. When words run short, cut from what happened before you cut from the action items. + +Open with one sentence that says how many things need the user, or that nothing does. If nothing happened and nothing waits on the user, say so and stop. -Open with the number of action items, or say there are none. If nothing changed and nothing waits on the user, say so and stop. +Then show what happened, pictures first. Embed the existing screenshots and videos the work produced, then any diagram that explains a change, when the host renders them. Then sum up in one short bullet per thing the user asked for: what came of it, and whether it is done, still running, failed, or not checked. Write each line the way you would say it out loud: "Search was slow from a missing index", not "Search review: done". Name any bug found and fixed on the way. Each line must stay true when read alone. Never mark something done that still waits on the user, and leave out anything the action items say. Under the summary, give at most three short lines that change what the user knows or must do. Then name in one line any work left that you can do yourself. -Show each PR, run, or agent this chat touched with its state. Use done, running, failed, or not checked. Use one visual when rendering is available. Then give at most three one-line results that change what the user knows or must do. Keep a result's key number in its line unless the visual shows it. Name remaining agent work in one line. +Then list the action items as plain bullets, never as a diagram or box. Give each two lines, or one for an unasked irreversible step: the decision with your recommendation and why, then what happens if the user does not answer. Ask the call the user owns, such as merge, approve, or pick. A step you would take first goes in your recommendation. So does anything that must happen first, and anything that cannot be undone. Write "unknown" for a part you do not know. Link to existing detail. -Give each action item three lines. State the decision, your recommendation and why, and what happens without an answer. Write "unknown" for a part you do not know. Link to existing detail. Show the current state beside each option with its cost in a visual when possible. Skip that visual for access requests. +Show a choice after the list. If the screenshots above already show its options, write each option's gain and cost under its screenshot instead of drawing a new visual. Otherwise compare the options side by side in a visual when rendering is available, with the current state when there is one. Give every option the work weighed, each with what it gets the user and what it costs. Keep them out of the rest of the text. ## Visuals -Use existing screenshots or video for visible changes. Mark a visible change with no capture "No screenshot yet." Never draw or generate a screen you did not capture, invent numbers, or link an artifact that does not exist. +Keep each visual readable at a glance: at most six boxes, with at most eight words in each. Write labels as plain words a person would say, not tags like "Tests: pass". A fact that needs a sentence belongs in the text, or nowhere. A Markdown table is text, not a picture. + +Embed existing screenshots and video inline for visible changes when the host renders them, not only as links. If a visible change has no capture, mark its summary line "No screenshot yet," and say there what changed on screen. Never draw or generate a screen you did not capture, invent numbers, or link an artifact that does not exist. -For other changes, use a diagram or chart only when the current Devin host exposes a rendering tool or adapter. Mermaid is suitable for states and flows when the host renders it. This plugin provides no chart or image tool and no visual rendering guarantee in the CLI. A Markdown table is text, not a picture. +For other changes, use a diagram only when the current Devin host renders one. Mermaid suits how things connect when the host renders it. This plugin provides no chart or image tool and no visual rendering guarantee in the CLI. -When rendering is unavailable, say so briefly and give the same states, options, costs, and unknowns in compact text within the word limit. Do not invoke an unshipped skill, install a tool, or start a service to satisfy the visual preference. +When rendering is unavailable, say so in a few words, link the existing screenshots and videos, and give the same states, options, costs, and unknowns as compact plain lines within the word limit. Do not invoke an unshipped skill, install a tool, or start a service to satisfy the visual preference. diff --git a/skills/poteto-help/SKILL.md b/skills/poteto-help/SKILL.md index 250eb45..1caf6d4 100644 --- a/skills/poteto-help/SKILL.md +++ b/skills/poteto-help/SKILL.md @@ -52,10 +52,11 @@ The default answer is `/pstack:poteto-mode`, which runs most of the others when |---|---| | Do any non-trivial task with rigor | [`/pstack:poteto-mode`](../poteto-mode/SKILL.md) | | Check that the agent understood the goals and the problem | [`/pstack:in-your-own-words`](../in-your-own-words/SKILL.md) | +| Aim a task higher before starting: more expert, more outcome-focused, not overspecified | [`/pstack:sharpen`](../sharpen/SKILL.md) | | Know how code works now, or where new code should live | [`/pstack:how`](../how/SKILL.md) | | Know why code is shaped this way, or where a number came from | [`/pstack:why`](../why/SKILL.md) | | Understand a change or subsystem, explained plainly | [`/pstack:teach`](../teach/SKILL.md) | -| Catch up on changes since their last message, with a short reply and available visuals | [`/pstack:ketchup`](../ketchup/SKILL.md) | +| Catch up on changes since their last message, in a few plain sentences and small available visuals | [`/pstack:ketchup`](../ketchup/SKILL.md) | | Catch up on their own recent work on a topic | [`/pstack:recall`](../recall/SKILL.md) | | Know what a small diff could break outside itself | [`/pstack:blast-radius`](../blast-radius/SKILL.md) | | Settle types and module shape before code that crosses a function boundary | [`/pstack:architect`](../architect/SKILL.md) | diff --git a/skills/poteto-help/references/recipes.md b/skills/poteto-help/references/recipes.md index 5738848..d583b11 100644 --- a/skills/poteto-help/references/recipes.md +++ b/skills/poteto-help/references/recipes.md @@ -52,3 +52,11 @@ Swap in the real paths, skills, and done checks. Informal wording works. ``` Use this to hear the goals and problem the agent understood. It does not add a confirmation gate to ordinary work. + +## Aim the task higher + +```text +/pstack:sharpen +``` + +The agent frames the task the way a top expert would, keeps one outside check, leaves your choices open, and then does the work. It does not hand back a rewritten prompt. diff --git a/skills/poteto-mode/SKILL.md b/skills/poteto-mode/SKILL.md index 7d71863..73ba2b2 100644 --- a/skills/poteto-mode/SKILL.md +++ b/skills/poteto-mode/SKILL.md @@ -129,4 +129,6 @@ Implementation uses dedicated profiles. Resolve legacy `pstack:panel-` ro - judgment and prose: `pstack:panel-opus` - strongest judgment: `pstack:panel-opus` +Devin dispatch has no per-call reasoning-level or speed parameter, because `run_subagent` takes a profile, not a model. Upstream pstack's per-spawn effort and fast-mode tuning therefore does not apply. Match the model to the job only by choosing among the configured role rows above, never by inventing a profile, editing a pin, or remapping a role at dispatch time. + When an active panel skill requires N perspectives but fewer distinct profiles are available, use N sequential fresh-context `run_subagent` calls on the available registered profiles. One pass is not a panel. Do not claim a model ran without dispatch evidence. diff --git a/skills/poteto-mode/playbooks/multi-phase-plan.md b/skills/poteto-mode/playbooks/multi-phase-plan.md index 1891fe2..ec2daca 100644 --- a/skills/poteto-mode/playbooks/multi-phase-plan.md +++ b/skills/poteto-mode/playbooks/multi-phase-plan.md @@ -12,7 +12,7 @@ **Verification.** Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked (`skills/principle-prove-it-works/SKILL.md`). That sentence is the verification rule. Every verification block opens with it. The live block is mandatory. Drive the real surface with `exec` for CLIs and TUIs, and with the browser mechanism only when Devin exposes one. Declare the actual control path in How to read this. A surface with no available control path is an evidence gap in Appendix C; name the missing adapter and do not claim live verification. -Record the code-ready SHA and run gates and relevant live/performance behavior at that exact revision. Require at least two independent audit passes with distinct focuses, using configured local profiles. Repeated profiles mean separate fresh-context calls; disclose sequential execution and repeat the SHA and focus in every result. Reverify after every patch-changing push. Keep the merge base through fix rounds; rebase again only for merge preparation, a demonstrated trunk conflict, or trunk-caused CI failure. When trunk lacks the feature, prove the added behavior and use an absolute performance budget rather than compare unlike workloads. +Record the code-ready SHA and run gates and relevant live/performance behavior at that exact revision. Require at least two independent audit passes with distinct focuses, using configured local profiles. Repeated profiles mean separate fresh-context calls; disclose sequential execution and repeat the SHA and focus in every result. Run the full audit set once, at the code-ready SHA. Run it again only for new behavior, a redesign, or a large new diff. A rebase, a merge-conflict resolution, or a minor fix gets one fresh-context verifier at the new head. Keep the merge base through fix rounds; rebase again only for merge preparation, a demonstrated trunk conflict, or trunk-caused CI failure. When trunk lacks the feature, prove the added behavior and use an absolute performance budget rather than compare unlike workloads. ````markdown # plan @@ -57,7 +57,7 @@ Tests alone are not sufficient verification. A PR is verified only when its unit ### Verdict, for every PR - [ ] Record the code-ready SHA. At that exact SHA, re-run gates and relevant live/performance checks, then collect two independent fresh-context audits with distinct focuses from configured local profiles. Repeated profiles run sequentially and disclose that fact. Evidence: -- [ ] Clean only when every lane is `PASS`. Findings go back to the owner. Reverify after patch-changing pushes; preserve the merge base through fixes and rebase only for merge preparation, a demonstrated trunk conflict, or trunk-caused CI failure. Evidence: +- [ ] Clean only when every lane is `PASS`. Findings go back to the owner, including a defect a lane filed as a note. After a patch-changing push, run the full audit set again only for new behavior, a redesign, or a large new diff, and otherwise one fresh-context verifier at the new head; preserve the merge base through fixes and rebase only for merge preparation, a demonstrated trunk conflict, or trunk-caused CI failure. Evidence: ## () diff --git a/skills/poteto-mode/references/principles.md b/skills/poteto-mode/references/principles.md index 3f5d83c..cd771d0 100644 --- a/skills/poteto-mode/references/principles.md +++ b/skills/poteto-mode/references/principles.md @@ -7,7 +7,7 @@ Read this catalog only when a live decision needs more than the default engineer - **Laziness Protocol** (`skills/principle-laziness-protocol/SKILL.md`). Refactoring, sizing a diff, or tempted to add abstractions, layers, or signal threading. Bias to deletion and the smallest change that solves the problem. - **Foundational Thinking** (`skills/principle-foundational-thinking/SKILL.md`). Before writing logic. Core types and data structures, scaffold-vs-feature sequencing, what concurrent actors share. - **Redesign from First Principles** (`skills/principle-redesign-from-first-principles/SKILL.md`). Integrating a new requirement into an existing design. Redesign as if it had been foundational from day one. -- **Attack the Premise** (`skills/principle-attack-the-premise/SKILL.md`). Two or more fixes that share one premise have failed the same gate. Take a census of which actors hold the imbalance before the next fix, then question the premise instead of writing another fix that assumes it. +- **Attack the Premise** (`skills/principle-attack-the-premise/SKILL.md`). Two or more fixes that share one premise have failed the same gate. Write the premise down and test it directly before you write another fix that assumes it. - **Subtract Before You Add** (`skills/principle-subtract-before-you-add/SKILL.md`). Sequencing an addition, refactor, or rewrite. Remove dead weight first, then build on the simpler base. - **Minimize Reader Load** (`skills/principle-minimize-reader-load/SKILL.md`). Reviewing or shaping code that's hard to trace. Count layers and hidden state, collapse one-caller wrappers, shrink mutable scope. - **Outcome-Oriented Execution** (`skills/principle-outcome-oriented-execution/SKILL.md`). Planned rewrites and migrations with explicit phase boundaries. Converge on the target architecture. Do not preserve throwaway compatibility states. @@ -29,9 +29,9 @@ Read this catalog only when a live decision needs more than the default engineer - **Explain the Number** (`skills/principle-explain-the-number/SKILL.md`). Before trusting, reporting, or acting on measured latency, throughput, regressions, speedups, or eval results. Validate actual work, spread, and the limiter. - **Prove It Works** (`skills/principle-prove-it-works/SKILL.md`). After a task, before declaring done. Verify against the real artifact, not a proxy or "it compiles". -- **Fix Root Causes** (`skills/principle-fix-root-causes/SKILL.md`). Debugging. Trace each symptom to its root cause, reproduce first, ask why until you reach it. +- **Fix Root Causes** (`skills/principle-fix-root-causes/SKILL.md`). Debugging. Trace each symptom back to the first place the system went wrong and fix it there. A guard is a fix only when the state it handles is legitimate. - **Sequence Work into Verifiable Units** (`skills/principle-sequence-verifiable-units/SKILL.md`). Multi-step work and how you stack commits and PRs. Break work into small units that each end in a check. -- **Test Behavior, Not Implementation** (`skills/principle-test-behavior-not-implementation/SKILL.md`). Writing, changing, or keeping a test. Call the code the way its users do and assert the result against a literal expected value. If the test would still pass when every imported function returns `undefined`, rewrite the assertion or delete the test. +- **Test Behavior, Not Implementation** (`skills/principle-test-behavior-not-implementation/SKILL.md`). Writing, changing, or keeping a test. Assert what the code's users can observe, so the test fails when that behavior breaks and keeps passing when only the internals change. **Delegation** diff --git a/skills/principle-attack-the-premise/SKILL.md b/skills/principle-attack-the-premise/SKILL.md index e72d16f..ff7e901 100644 --- a/skills/principle-attack-the-premise/SKILL.md +++ b/skills/principle-attack-the-premise/SKILL.md @@ -1,6 +1,6 @@ --- name: principle-attack-the-premise -description: "Apply when two or more fixes that share one premise have failed the same gate. Take a census of which actors hold the imbalance before the next fix, then question the premise instead of writing another fix that assumes it." +description: "Apply when two or more fixes that share one premise have failed the same gate. Write the premise down and test it directly before you write another fix that assumes it." triggers: - model --- @@ -9,16 +9,14 @@ triggers: When two or more fixes that share one premise have failed the same gate, suspect the premise, not the fixes. -**Why:** Each failure under a shared premise is evidence about the premise. +**Why:** Each failed fix is evidence against the belief it assumed. A third fix on the same premise spends effort where the evidence already says the cause is not. **Pattern:** - **Write the premise down.** The premise is the one sentence that every failed fix assumed. -- **Take a census before the next fix.** Count the imbalance per actor. The census shows which actors hold the imbalance, not how large it is. Write the census as a rerunnable script per [Build the Lever](../principle-build-the-lever/SKILL.md). -- **Read the skew.** If the same few actors hold most of the imbalance on every run, something assigns them that role. Find what assigns the role. That assignment is the next "why" per [Fix Root Causes](../principle-fix-root-causes/SKILL.md). -- **Remove the asymmetry instead of compensating for it**, per the [Laziness Protocol](../principle-laziness-protocol/SKILL.md). Rotate the role between actors, randomize the assignment, or move the role, so that no actor holds it on every run. A return path, a shared pool, a batched hand-off, or a periodic rebalance leaves the assignment in place and adds work on every run. +- **Test the premise before the next fix.** Find an observation that would come out differently if the premise were false, and make it. Look at how the failures are distributed, not only at how large they are. Make the check rerunnable per [Build the Lever](../principle-build-the-lever/SKILL.md). +- **Follow the evidence.** If it contradicts the premise, the cause is elsewhere. Look for what the failures have in common that the premise did not predict. If it confirms the premise, ask the next "why" per [Fix Root Causes](../principle-fix-root-causes/SKILL.md). The earlier fixes may have treated a consequence instead of the cause. +- **Remove the condition instead of compensating for it**, per the [Laziness Protocol](../principle-laziness-protocol/SKILL.md). If the evidence shows that one part always lands on the losing side, change what puts it there. A mechanism that cleans up after it leaves the cause in place and adds work on every run. -**Stop:** -- Do not start the next fix before the premise is written down and the census exists. -- If the census is even across actors, the premise is not the cause. Look for the cause elsewhere and keep the census as evidence. +**Stop:** Do not start the next fix before the premise is written down and tested. This principle is distinct from [Redesign from First Principles](../principle-redesign-from-first-principles/SKILL.md), which rebuilds a design around a new requirement. It questions a fact the current design assumes. diff --git a/skills/principle-fix-root-causes/SKILL.md b/skills/principle-fix-root-causes/SKILL.md index 626f429..39a834a 100644 --- a/skills/principle-fix-root-causes/SKILL.md +++ b/skills/principle-fix-root-causes/SKILL.md @@ -1,25 +1,22 @@ --- name: principle-fix-root-causes -description: "Apply when debugging. Trace each symptom to its root cause and fix it there; reproduce first, ask why until you reach it, resist nil-check guards that silence crashes." +description: "Apply when debugging. Trace each symptom back to the first place the system went wrong and fix it there. A guard is a fix only when the state it handles is legitimate." triggers: - model --- # Fix Root Causes -When debugging, do not paper over symptoms. Trace every problem to its root cause and fix it there. +When debugging, fix the fault, not the place where it surfaced. The symptom is where a wrong state became visible. The root cause is the first place the system did something it should not do, or failed to handle a state it should handle. -**Why:** Symptom fixes accumulate. Each workaround makes the system harder to reason about, and the real bug remains. Root-cause fixes are slower upfront but reduce total debugging time. +**Why:** A symptom fix hides the evidence and leaves the fault free to surface somewhere else. Each one makes the system harder to reason about, because the code now carries a workaround for a bug that nobody named. **Pattern:** -- Reproduce first (if you can't reproduce it, you can't verify your fix) -- Ask "why" until you hit the root cause -- Resist the urge to add guards (adding a nil check to silence a crash is a symptom fix) -- If a workaround needs a paragraph-long comment to justify it, the code is wrong (fix the code, not the comment) -- Check for the pattern, not just the instance (grep for the same pattern, fix all instances) -- When stuck, instrument. Don't guess (add logging, read the actual error) -- If the deciding fact took a deep dig to find, propose the cheap, always-on signal that would have shown it at first look - -**Restart bugs: suspect state before code** - -Code doesn't change between runs. State does. When something "fails after restart," suspect stale persistent state first: config files, caches, lock files, serialized state. If clearing a state file restores behavior, prioritize state validation as the fix. +- Reproduce first. +- Ask "why" at each step until the answer is a wrong decision in the code, not a consequence of an earlier one. +- When stuck, instrument. Read the actual error and the actual state. Do not guess. +- Ask whether the state that triggered the symptom is legitimate. If the system may be in that state, the code that broke on it is the root cause, and handling the state there is the fix. If the state should never exist, a check where it broke hides the bug. Find what produced the state. Guards, retries, swallowed errors, clamped values, and discarded state are the usual ways to hide a bug. +- When something fails only after a restart, suspect persisted state first: config files, caches, lock files, serialized state. +- Check for the pattern, not just the instance. Find every place with the same fault and fix them all. +- If a workaround needs a paragraph-long comment to justify it, the code is wrong. Fix the code, not the comment. +- If the deciding fact took a deep dig to find, propose the cheap, always-on signal that would have shown it at first look. diff --git a/skills/principle-make-operations-idempotent/SKILL.md b/skills/principle-make-operations-idempotent/SKILL.md index 14c0474..8f0c829 100644 --- a/skills/principle-make-operations-idempotent/SKILL.md +++ b/skills/principle-make-operations-idempotent/SKILL.md @@ -7,15 +7,13 @@ triggers: # Make Operations Idempotent -Design operations so they converge to the correct state regardless of how many times they run or where they start from. Every state-mutating operation should answer: "What happens if this runs twice? What happens if the previous run crashed halfway?" +Design operations so they converge to the correct state regardless of how many times they run or where the previous run stopped. Every state-mutating operation should answer: "What happens if this runs twice? What happens if the previous run crashed halfway?" **Why:** Commands, lifecycle operations, and processing loops run where crashes, restarts, and retries are normal. If partial state changes the next run's outcome, every restart becomes a debugging session. -**The pattern:** -- Convergent startup: scan for existing state, clean stale artifacts, adopt live sessions -- Content-based cleanup: compare by content equivalence, not creation order -- Self-healing locks: use PID-based stale lock detection -- Idempotent scheduling: failed work respawns cleanly, fresh input regenerated after each cycle +**The idea:** derive each step from the state that exists, not from what the previous run meant to do. Read the current state, compare it to the goal, and apply only the difference. A step written this way is safe to repeat, because a repeat finds nothing left to do. + +Anything a run leaves behind, such as a lock, a temporary file, a half-written record, or a claimed job, must be recognizable as stale by the next run. Judge staleness by evidence that stays true wherever the previous run could have stopped, not only in the common case. A marker that the next run cannot judge turns every crash into manual cleanup. For example, write to a temporary path and rename it into place, or compare artifacts by content instead of by creation order. **The test:** 1. What happens if this runs twice in a row? diff --git a/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md b/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md index 60a9b87..10437a6 100644 --- a/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +++ b/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md @@ -7,17 +7,9 @@ triggers: # Migrate Callers Then Delete Legacy APIs -When we decide a new API is the right design, migrate callers and remove the old API in the same refactor wave instead of preserving compatibility layers. - -**Rule:** -- Do not keep legacy API paths alive only because internal callers still exist -- Inventory callers, migrate them, and delete the old API immediately -- Treat temporary adapters as exceptional and time-boxed, not default architecture - Update tests to assert the new contract, and delete tests that only protect pre-refactor implementation details **When this applies:** - No external users depend on backward compatibility - The project can absorb coordinated breaking changes - The new API is part of a simplification or refactor initiative - -Keeping both old and new APIs creates dual-path complexity, slows cleanup, and makes the codebase feel append-only. diff --git a/skills/principle-test-behavior-not-implementation/SKILL.md b/skills/principle-test-behavior-not-implementation/SKILL.md index 1146b57..9cb719c 100644 --- a/skills/principle-test-behavior-not-implementation/SKILL.md +++ b/skills/principle-test-behavior-not-implementation/SKILL.md @@ -1,22 +1,21 @@ --- name: principle-test-behavior-not-implementation -description: "Apply when you write, change, or keep a test. Call the code as its users do and assert the exact result they see. Rewrite or delete a test that would pass if every imported function returned undefined." +description: "Apply when you write, change, or keep a test. Assert what the code's users can observe, so that the test fails when that behavior breaks and keeps passing when only the internals change." triggers: - model --- # Test Behavior, Not Implementation -A test calls the code as its users do and asserts the exact result they see. Rewrite or delete any test that would still pass if every imported function returned `undefined` or a wrong value. +A test is a claim about what the code does for its users: a caller, an end user, or another service. Behavior is what those users can observe through the interface they use. That includes return values, errors, state they can read back, and effects on systems outside the code, such as a request sent, a row written, or a message emitted. Implementation is what they cannot observe: private helpers, internal call order, intermediate data, and which internal collaborator did the work. -These shapes fail that check: +Judge each test against two imagined edits: -- Loose or no assertion: `toBeDefined`, `toBeTruthy`, `not.toThrow`, `toBeGreaterThan(0)`. -- Call or absence only: `toHaveBeenCalled`, `not.toHaveBeenCalled`, `toBeUndefined`, `toEqual([])`. -- Expected value computed by the code under test: `expect(f(a)).toBe(f(a))`. -- Restated constant, config default, table row, or prompt string. -- Assertions on data the test built, with no call to the subject. +- **Break the behavior.** Make the code return a wrong value, skip an effect, or do the effect twice. If the test still passes, it proves nothing. The usual causes are an assertion looser than the contract, an expected value computed by the code under test, a restated constant or prompt string that never runs the code that reads it, and an assertion on data that the test built itself. +- **Change the internals.** Keep every observable result the same and restructure the code underneath. If the test now fails, it is pinned to the implementation. It will need a rewrite on every refactor and still catches no bug. -Fix: call the subject in the test body with one concrete input and assert the literal output or effect. For a mock, assert the payload it received. For an absence, also assert the presence on another input. For a constant, test the mechanism that reads it with one input instead of restating the value. +Keep a test that catches the first edit and survives the second. Rewrite or delete the rest. To write a test that does both, drive the code through its users' interface with a concrete input. Derive the expected value from the requirement, not from a run of the code. Assert what the contract promises, no less and no more. -Keep relation checks across table rows (a key in two tables, a parent that exists) and `*.test-d.ts` type checks. +The contract decides, not the shape of the assertion. When "an empty cart never charges" is the promise, an assertion that the payment client got no call is behavior. Pair it with a case where the charge happens, so that the test shows it can see a call. The payload that a mocked external service receives is behavior, because that service observes it. A call to an internal helper is implementation, because no user can see it. An empty list is the exact answer when no record matches, and a hollow check when the test only needs some result. An exact error message pins wording that no caller reads. The error type that callers branch on is the contract. + +A test can pin an invariant instead of a call, such as a key that must exist in two tables or a compile-time type check. The invariant is the behavior. diff --git a/skills/principle-type-system-discipline/SKILL.md b/skills/principle-type-system-discipline/SKILL.md index 2e569f0..28b25b0 100644 --- a/skills/principle-type-system-discipline/SKILL.md +++ b/skills/principle-type-system-discipline/SKILL.md @@ -1,6 +1,6 @@ --- name: principle-type-system-discipline -description: "Apply when designing types, reviewing a function signature, or writing code in any statically-typed language. Make illegal states unrepresentable, brand semantic primitives, parse external data at boundaries, refuse to lie to the compiler, exhaust variants, derive from authoritative schemas." +description: "Apply when designing types, reviewing a function signature, or writing code in any statically-typed language. Make illegal states unrepresentable, brand semantic primitives, parse external data at boundaries, exhaust variants, derive from authoritative schemas." triggers: - model --- @@ -9,11 +9,6 @@ triggers: Make the compiler reject impossible states, mismatched primitives, and unhandled variants. Prefer defining errors and special cases out of existence over proliferating handlers. For TypeScript syntax, see the `/pstack:typescript-best-practices` skill. -- **Make illegal states unrepresentable.** Model variants as sum types (discriminated unions, enums with payloads, sealed classes), not as a bag of optional fields where contradictory combinations compile. `{ completed: boolean; completedAt?: Date }` admits `completed: true` with no date. Derive the boolean from `completedAt`, or model `{ kind: 'open' } | { kind: 'done'; at: Date }`. If you can write a comment explaining when a combination of fields is valid, split it into a sum type. -- **Types are constructions, not restrictions.** Build the type up from the values you want instead of carving them out of a looser type with checks. A non-empty list is a head plus a rest. A valid time range is a start plus a duration. Choose the shape that cannot build the illegal value and expose the interface callers need on top. - **Brand semantic primitives.** `UserId` and `OrderId` are strings underneath but should not be interchangeable. Give each its own type, such as a branded intersection in TypeScript or a newtype elsewhere. Validate once at creation, trust the type downstream. If two arguments share a primitive type but mean different things, brand them. - **External data is untyped until parsed.** RPC payloads, JSON, IPC messages, CLI args, config files, environment variables, database rows. Have a parse function at every boundary that turns unstructured input into the typed model. The **boundary-discipline** principle skill says where to put validation. -- **Don't lie to the type system.** Casts, unsafe coercions, and assertion functions that bypass the compiler are latent runtime crashes. If the compiler can't prove a fact, prove it (validate, narrow, refine the model) or accept that the cast is a hazard. Trace each `any`, `as`, or `assertNotNull` to the boundary and validate there. -- **Exhaustive matching is the compiler's job.** A match on a sum type must fail compilation when a new variant is added without handling, so the compiler tells the next agent where to add a case. Use your language's idiom: a `never`-typed binding in TypeScript, an unannotated `match` in Rust, `-Wincomplete-patterns` in Haskell, sealed-class match exhaustiveness in Kotlin. - **Derive types from authoritative schemas.** When a protocol buffer, OpenAPI spec, GraphQL schema, database migration, design-token file, or another file owns a shape, derive from it instead of hand-rolling a parallel type. See the **encode-lessons-in-structure** principle skill. -- **Strengthen a type only where partiality appears.** A runtime assertion, null check, or "this should never happen" throw marks the place a type is too weak. Push that check up into the type. Then stop. The type system's job is to track the cases each use site must handle, not to describe the data as precisely as possible. Prefer total functions. `sum` of an empty list is 0, so it takes the plain list. `head` of an empty list has no answer, so it demands the non-empty one. If nothing would otherwise panic, keep the plain type. diff --git a/skills/sharpen/SKILL.md b/skills/sharpen/SKILL.md new file mode 100644 index 0000000..5c7c571 --- /dev/null +++ b/skills/sharpen/SKILL.md @@ -0,0 +1,8 @@ +--- +name: sharpen +description: "Sharpen a task before starting: the expert approach, what the user is really after, and the right level of specification. Use for /pstack:sharpen." +triggers: + - user +--- + +Before starting, ask how a top expert would approach this task (their raw sources, their real methods, an outside check that the result is right), what the user is really after, and whether the task is over- or underspecified. Loosen constraints that don't serve the goal as readily as you add ones that do, and leave choices that are the user's to make open instead of deciding them. Fold in only what makes the work better, not bigger, but always keep one outside check that the result is right, without narrating the framing, then do the work. Don't hand back a rewritten prompt. diff --git a/skills/swarm/SKILL.md b/skills/swarm/SKILL.md index 5613110..590750c 100644 --- a/skills/swarm/SKILL.md +++ b/skills/swarm/SKILL.md @@ -5,8 +5,6 @@ description: "Fan out N parallel workers, drain them, and return one report. Use # Swarm -Fan out N workers. They may cover separate slices, race the same brief, or mix both. The parent waits, aggregates, and returns one report. - Resolve profiles from [`../poteto-mode/references/panel-run.md`](../poteto-mode/references/panel-run.md). Record a `PanelRun` before the first `run_subagent` call. Sequential when the host will not run them together or when distinct profiles are fewer than needed. Say so. Do not claim parallel execution in that mode. ## Start @@ -22,9 +20,8 @@ Open a todolist with one entry per phase. 1. State the done predicate and the artifact or report. 2. Choose the shape. Partition, race, or mix. For a race or mix, declare `first pass`, `rank all`, or `best-of` before spawning. -3. Set N from the user or the shape. N is total workers, not concurrency. -4. Pick the worker profile from `swarm workers` in `$HOME/.config/devin/pstack-models.md`, else the Models default. For a model race, name each arm's profile up front. -5. Give each writer its own root-provisioned output. A verified git worktree, or a separate directory such as `/tmp/swarm-/worker-/`. A branch in the shared checkout is not isolation. +3. Pick the worker profile from `swarm workers` in `$HOME/.config/devin/pstack-models.md`, else the Models default. For a model race, name each arm's profile up front. +4. Give each writer its own root-provisioned output. A verified git worktree, or a separate directory such as `/tmp/swarm-/worker-/`. A branch in the shared checkout is not isolation. ## Phase B: Fan out diff --git a/tests/port-contracts.test.mjs b/tests/port-contracts.test.mjs index 1096545..e51ed7b 100644 --- a/tests/port-contracts.test.mjs +++ b/tests/port-contracts.test.mjs @@ -61,7 +61,7 @@ test('interleaved run documentation assigns boundaries and supersedes history', }); test('portable skills retain user activation and numeric principle model activation', () => { - for (const name of ['correct', 'benchmark-checklist', 'ketchup', 'in-your-own-words']) { + for (const name of ['correct', 'benchmark-checklist', 'ketchup', 'in-your-own-words', 'sharpen']) { const text = read(`skills/${name}/SKILL.md`); assert.match(text, new RegExp(`^name: ${name}$`, 'm')); assert.match(text, /triggers:\n - user/); @@ -116,3 +116,17 @@ test('all implementation and panel pins remain matched and unchanged', () => { } assert.match(read('agents/poteto-agent/AGENT.md'), /^model: gpt-6-1-sol-medium$/m); }); + +test('0.15.25 port keeps ketchup fallback and reasoning-style principles', () => { + const ketchup = read('skills/ketchup/SKILL.md'); + assert.match(ketchup, /help them understand each change/); + assert.match(ketchup, /action items as plain bullets/); + assert.match(ketchup, /When rendering is unavailable/); + assert.doesNotMatch(ketchup, /\/visualize/); + assert.doesNotMatch(read('skills/principle-attack-the-premise/SKILL.md'), /census/); + assert.match(read('skills/principle-fix-root-causes/SKILL.md'), /A guard is a fix only when the state it handles is legitimate/); + assert.doesNotMatch(read('skills/principle-test-behavior-not-implementation/SKILL.md'), /every imported function/); + for (const name of ['principle-attack-the-premise', 'principle-fix-root-causes', 'principle-make-operations-idempotent', 'principle-test-behavior-not-implementation']) { + assert.match(read(`skills/${name}/SKILL.md`), /triggers:\n - model/); + } +});