From 1a25398746d8290f79c37f6b6ae5ae3dc2a2312e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 17 Oct 2026 03:18:13 +0000 Subject: [PATCH 1/2] port upstream pstack skill cuts from #634 The 0.15.25 baseline already matches cursor/plugins e5136d8. Apply the #634 cuts to the four skills, keeping the existing Devin frontmatter and swarm wording. Leave versions at 0.15.25. Co-authored-by: Kaitian Xie --- .../interrogate/references/lead-judgment.md | 19 ------------------- .../SKILL.md | 8 -------- .../principle-type-system-discipline/SKILL.md | 7 +------ skills/swarm/SKILL.md | 5 ----- 4 files changed, 1 insertion(+), 38 deletions(-) diff --git a/skills/interrogate/references/lead-judgment.md b/skills/interrogate/references/lead-judgment.md index 5ce5260..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/principle-migrate-callers-then-delete-legacy-apis/SKILL.md b/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md index 91ec0c5..0837c45 100644 --- a/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +++ b/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md @@ -6,17 +6,9 @@ triggers: [user] # 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 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-type-system-discipline/SKILL.md b/skills/principle-type-system-discipline/SKILL.md index e2ea52c..17ad098 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: [user] --- @@ -8,11 +8,6 @@ triggers: [user] 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 `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/swarm/SKILL.md b/skills/swarm/SKILL.md index 59eccde..05cc28c 100644 --- a/skills/swarm/SKILL.md +++ b/skills/swarm/SKILL.md @@ -6,8 +6,6 @@ triggers: [user] # Swarm -Fan out N parallel cloud workers. They may cover separate slices, race the same brief, or mix both. The parent waits, aggregates, and returns one report. - ## Start Open a todolist with one entry per phase before launching anything. @@ -21,7 +19,6 @@ Open a todolist with one entry per phase before launching anything. 1. State the done predicate and the artifact or report the swarm must return. 2. Choose the shape. Partition into slices, race N workers on identical briefs, or mix both. For a race or mixed shape, declare `first pass`, `rank all`, or `best-of` before spawning. -3. Set N from the user or derive it from the shape. N is total workers, not the cloud concurrency limit. 4. Pick the worker model from the `swarm workers` line in `~/.devin/rules/pstack-models.md`. If the rule or that line is missing, use `swe-2-high`. Map the value to the workers' `profile`: a real slug `M` becomes `pstack-M`; `auto` or `inherit-parent` uses `subagent_general`, so the workers run on the parent model. Create a missing `pstack-M` profile per `/pstack:setup-pstack`. If a pinned slug is rejected at spawn, use the default and say so. If it rejects the default, use the closest valid slug of the same family `devin models list` reports. For a model race, name each arm's model up front. Pick each subagent's reasoning level and fast or standard speed for the job, per the Subagents section of the **poteto-mode** skill. 5. Give each worker its own writable output when it writes. When workers verify or measure commits, each brief names the exact SHAs. A measurement brief also names the method (sample count, what one sample is, order). The worker records both in its result. @@ -39,8 +36,6 @@ If a worker drops out, proceed with N-1 and note it. Read the terminal results. Drop a result that does not record the SHAs and method its brief names, and respawn that worker once. After a second miss, record a gap. A gap does not count as a pass. For coverage, every required slice needs a result. For a race, apply the selection rule declared up front. Use first pass, rank all, or best-of. Do not paste raw worker dumps. -Keep a compact result table, one-line evidenced issues, and explicit gaps or dropouts. - ## Phase D: Report Return one consolidated in-chat report with the table, issue one-liners, gaps or dropouts, and the race rule when used. From 2605879c093151de0dd7596b1f30e9decaa3b433 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 18 Oct 2026 01:26:34 +0000 Subject: [PATCH 2/2] port upstream pstack through 019a6a2 Apply the #700 brand type guard and rename poteto-mode to its folder. Apply the #704 guide edits on top of the existing Devin wording. Leave versions at 0.15.25. Co-authored-by: Kaitian Xie --- docs/guide/02-poteto-mode.md | 2 +- docs/guide/03-understand.md | 6 +++--- docs/guide/04-design.md | 2 +- docs/guide/05-build-and-clean.md | 4 ++-- docs/guide/06-verify-and-ship.md | 8 ++++---- docs/guide/07-overnight.md | 2 +- docs/guide/08-principles.md | 2 +- docs/guide/09-make-it-yours.md | 6 +++--- docs/guide/10-recipes-and-pitfalls.md | 4 ++-- skills/poteto-mode/SKILL.md | 2 +- skills/typescript-best-practices/SKILL.md | 2 +- skills/typescript-best-practices/references/patterns.md | 8 ++++++-- 12 files changed, 26 insertions(+), 22 deletions(-) diff --git a/docs/guide/02-poteto-mode.md b/docs/guide/02-poteto-mode.md index ecccfdf..c21069b 100644 --- a/docs/guide/02-poteto-mode.md +++ b/docs/guide/02-poteto-mode.md @@ -25,7 +25,7 @@ flowchart TD J --> K ``` -The diagram shows the common routes. There are also playbooks for hillclimbing a metric, diagnosing runtime symptoms and captured traces, prototypes, visual parity, authoring and evaluating skills, autonomous runs, babysitting a PR or stack to merge-ready, shipping a verified stack, running a PR queue on autopilot, orchestrating project-scale programs, session pickup, pausing safely, multi-phase plans, and worktree cleanup. The [playbook directory](../../skills/poteto-mode/playbooks/) has the full set. +The diagram shows the common routes. There are also playbooks for hillclimbing a metric, diagnosing runtime symptoms and captured traces, prototypes, visual parity, authoring and evaluating skills, autonomous runs, babysitting a PR or stack to merge-ready, shipping a verified stack, running a PR queue or a stack on autopilot, orchestrating project-scale programs, session pickup, pausing safely, multi-phase plans, and worktree cleanup. The [playbook directory](../../skills/poteto-mode/playbooks/) has the full set. ## Say the goal, not the ceremony diff --git a/docs/guide/03-understand.md b/docs/guide/03-understand.md index b57f130..dfc4dc1 100644 --- a/docs/guide/03-understand.md +++ b/docs/guide/03-understand.md @@ -30,9 +30,9 @@ Ask the question you actually have. [`/pstack:how`](../../skills/how/SKILL.md) r /pstack:why was the retry limit set to five? does the reason still hold? ``` -[`/pstack:why`](../../skills/why/SKILL.md) works like a detective on a cold case. It starts from source control, then queries whatever evidence categories your MCPs expose, such as the issue tracker, long-form docs, team chat, observability, error tracking, and analytics, all in parallel. The report cites everything, separates direct evidence from inference, and says "appears to" when the record is thin. A null result gets reported too, because "nobody wrote down why" is itself an answer. +[`/pstack:why`](../../skills/why/SKILL.md) starts from source control, then queries whatever evidence categories your MCPs expose, such as the issue tracker, long-form docs, team chat, observability, error tracking, and analytics, all in parallel. The report cites everything, separates direct evidence from inference, and says "appears to" when the record is thin. A null result gets reported too, because "nobody wrote down why" is itself an answer. -The two compose naturally. `do why first then how` is a perfectly good prompt when you suspect the history explains the mess. +The two compose naturally. `do why first then how` is a good prompt when you suspect the history explains the mess. ## Actually understand it with `/pstack:teach` @@ -40,7 +40,7 @@ The two compose naturally. `do why first then how` is a perfectly good prompt wh /pstack:teach me how this PR changes retries. convince me it fixes the cause and not the symptom. ``` -[`/pstack:teach`](../../skills/teach/SKILL.md) is for when a summary isn't enough. It runs `/pstack:how` and `/pstack:why`, for a small change maybe just one of them, and weaves the findings into a plain explanation that builds up diagram by diagram. The "convince me" framing is worth stealing. It turns the explanation into an argument you can poke at instead of a tour. +[`/pstack:teach`](../../skills/teach/SKILL.md) is for when a summary isn't enough. It runs `/pstack:how` and `/pstack:why`, for a small change maybe just one of them, and weaves the findings into a plain explanation that builds up diagram by diagram. The "convince me" framing is worth reusing. It turns the explanation into an argument you can test instead of a tour. It works on the agent's own choices too: diff --git a/docs/guide/04-design.md b/docs/guide/04-design.md index c5dc9be..6c271cb 100644 --- a/docs/guide/04-design.md +++ b/docs/guide/04-design.md @@ -2,7 +2,7 @@ One attempt at a hard design locks in the first shape the model thought of. `/pstack:architect` settles types and boundaries before implementation. `/pstack:arena` runs several attempts at the same brief and merges the best parts. `/pstack:interrogate` has other models try to break the result. When the job is coverage rather than design synthesis, `/pstack:swarm` fans out slices or races and aggregates their results. -The two most common design mistakes are taking the agent's first design and polishing a plan that no code has tested. This page fixes both. You plan through code: prototypes answer the open questions, a README or tutorial sets the target, and the written plan comes last. +The two most common design mistakes are taking the agent's first design and polishing a plan that no code has tested. This page fixes both. You plan through code. Prototypes answer the open questions, a README or tutorial sets the target, and the written plan comes last. ![Three robots draft competing bridge models at their own tables under /pstack:architect, /pstack:arena, and /pstack:interrogate panels, while a judge robot with a clipboard inspects skeptically.](./images/design.jpg) diff --git a/docs/guide/05-build-and-clean.md b/docs/guide/05-build-and-clean.md index 59538a5..6053b80 100644 --- a/docs/guide/05-build-and-clean.md +++ b/docs/guide/05-build-and-clean.md @@ -1,6 +1,6 @@ # Build the change and clean the diff -The build playbooks share one discipline. Say what you observed, let the playbook demand the evidence. This page shows what to put in the prompt for each common build task, then the cleanup habit that keeps diffs reviewable. +The build playbooks share one discipline. Say what you observed, and let the playbook demand the evidence. This page shows what to put in the prompt for each common build task, then the cleanup habit that keeps diffs reviewable. ## Prompt each build playbook with what you know @@ -22,7 +22,7 @@ A refactoring prompt pins behavior before structure moves: /pstack:poteto-mode move parsing into one module, zero behavior change. record the current output first and prove it's unchanged after. ``` -A perf prompt states the measurement, not a vibe: +A perf prompt states the measurement, not an impression: ```text /pstack:poteto-mode startup takes 1.8s on this fixture. trace it, fix the measured cause, show me before and after. diff --git a/docs/guide/06-verify-and-ship.md b/docs/guide/06-verify-and-ship.md index ef9c6a9..877c03f 100644 --- a/docs/guide/06-verify-and-ship.md +++ b/docs/guide/06-verify-and-ship.md @@ -14,7 +14,7 @@ Put what done means in the first prompt, in whatever words fit: /pstack:poteto-mode add json output to this command. text output stays byte-identical, the json parses, both run against the sample project. show me the evidence. ``` -Now the agent has three checks it can run, not a mood to satisfy. When the reply comes back, it should carry the exact commands and outputs. If a check couldn't run, a good reply says "inconclusive", and you should treat a confident reply without evidence as a red flag. +Now the agent has three checks it can run, not a mood to satisfy. When the reply comes back, it should carry the exact commands and outputs. If a check couldn't run, a good reply says "inconclusive". A confident reply without evidence is a warning sign. Match the check to the change: @@ -26,7 +26,7 @@ Match the check to the change: Ask for the proof as an artifact you can inspect yourself: the failing test and then the passing one, a before-and-after video, the trace, the screenshot. If the fix already merged, ask for the same check again on main. An artifact beats a plausible explanation, because you can challenge it without replaying the whole run. -For a small diff you don't fully trust, [`/pstack:blast-radius`](../../skills/blast-radius/SKILL.md) finds what it could break elsewhere. It picks the one fact the change is safe because of and proves it by running code instead of writing an essay about it. +For a small diff you don't fully trust, [`/pstack:blast-radius`](../../skills/blast-radius/SKILL.md) finds what it could break elsewhere. It finds the one fact that makes the change safe and proves that fact by running code, not by arguing for it. ## Vet a measured number with `/pstack:benchmark-checklist` @@ -85,13 +85,13 @@ While you're there, make the dev setup repeatable too: seeded data, test users, ## Keep the verification skill honest -Apps change and feature maps rot. Run this at least once a day, ideally from a scheduled automation so nobody has to remember: +Apps change, and feature maps go out of date. Run this at least once a day, ideally from a scheduled automation so nobody has to remember: ```text /pstack:maintain-verification-skill ``` -[`/pstack:maintain-verification-skill`](../../skills/maintain-verification-skill/SKILL.md) audits the generated skill: one read-only source reader per feature in parallel, then one live pass that drives every mapped feature. It ends in exactly one of three outcomes. `clean` means full coverage and nothing to ship. `changed` means one PR of proven corrections, confined to the verification skill's own directory. `blocked` names the blocker. It never edits product code. If the live pass catches a product regression, it reports the regression instead of papering over it in docs. +[`/pstack:maintain-verification-skill`](../../skills/maintain-verification-skill/SKILL.md) audits the generated skill: one read-only source reader per feature in parallel, then one live pass that drives every mapped feature. It ends in exactly one of three outcomes. `clean` means full coverage and nothing to ship. `changed` means one PR of proven corrections, confined to the verification skill's own directory. `blocked` names the blocker. It never edits product code. If the live pass catches a product regression, it reports the regression instead of hiding it with a doc edit. ## Open the PR diff --git a/docs/guide/07-overnight.md b/docs/guide/07-overnight.md index 0b438af..da92f95 100644 --- a/docs/guide/07-overnight.md +++ b/docs/guide/07-overnight.md @@ -71,7 +71,7 @@ Before the skill hands back its summary, it spawns a reviewer on a different mod The contract above drives one task to one finish condition. Some nights hold more, a queue of independent changes or a whole program. Three playbooks scale the same trust up. -[Autopilot-full](../../skills/poteto-mode/playbooks/autopilot-full.md) runs a queue of independent PRs to merged. Each PR gets one owner agent that carries it from build through merge, and no owner merges on its own verdict. A swarm of fresh verifiers starts a round at the owner's code-ready head and again at every later push that changes the patch. Only a clean verdict on the patch that merges authorizes the merge: +[Autopilot-full](../../skills/poteto-mode/playbooks/autopilot-full.md) runs a queue of independent PRs to merged. Each PR gets one owner agent that carries it from build through merge, and no owner merges on its own verdict. A swarm of fresh verifiers checks the owner's code-ready head. A later rebase or minor fix gets one fresh verifier, and only new behavior or a large new diff calls the full swarm again. Only a clean verdict on the patch that merges authorizes the merge: ```text /pstack:poteto-mode full autopilot on this queue. each item is independent. i want them merged by morning. diff --git a/docs/guide/08-principles.md b/docs/guide/08-principles.md index 53982a7..0f1e355 100644 --- a/docs/guide/08-principles.md +++ b/docs/guide/08-principles.md @@ -24,7 +24,7 @@ Say two parallel attempts are about to write to the same branch: separate before serializing shared state. give each attempt its own worktree, no locks. ``` -Each phrase lands because the rule behind it is specific. The agent still has to say, in its reply, which decision the rule changed. A principle citation with no decision behind it is the tell that it name-dropped instead of applying. +Each phrase lands because the rule behind it is specific. The agent still has to say, in its reply, which decision the rule changed. A principle citation with no decision behind it means the agent named the rule without applying it. ## The 24, briefly diff --git a/docs/guide/09-make-it-yours.md b/docs/guide/09-make-it-yours.md index b0e9165..d78b8f1 100644 --- a/docs/guide/09-make-it-yours.md +++ b/docs/guide/09-make-it-yours.md @@ -1,6 +1,6 @@ # Make it yours -poteto-mode is one person's style. The machinery underneath, playbooks, routing, model roles, works just as well wearing yours. This page covers generating a personal mode, capturing lessons from a session, fixing the repo so agents stop repeating mistakes, authoring a focused skill, and testing a skill change before you trust it. +poteto-mode is one person's style. The playbooks, routing, and model roles underneath it work just as well with yours. This page covers generating a personal mode, capturing lessons from a session, fixing the repo so agents stop repeating mistakes, authoring a focused skill, and testing a skill change before you trust it. Start smaller than you think. You don't need many skills on day one, or even this whole plugin. Prompt plainly, watch where agents fail, and add a skill or a check when the same failure shows up twice. @@ -18,7 +18,7 @@ Run it again whenever your habits drift: /pstack:automate-me update my mode skill with everything since its last edit ``` -Update mode mines only the history since the skill last changed. It keeps rules you haven't contradicted, revises the ones with new evidence, and adds sections only for genuinely new patterns. +Update mode mines only the history since the skill last changed. It keeps rules you haven't contradicted, revises the ones with new evidence, and adds sections only for new patterns. ## Capture a session's lessons with `/pstack:reflect` @@ -69,7 +69,7 @@ Skills aren't the only prose you ship. For docs, RFCs, readmes, PR descriptions, /pstack:technical-writing review the readme changes ``` -[`/pstack:technical-writing`](../../skills/technical-writing/SKILL.md) applies a layered standard with one goal, prose a tired engineer understands on the first read. It picks the document's mode first (tutorial, how-to, reference, or explanation), then works sentence by sentence: who does what, one thought per sentence, nothing readable two ways. Use it to review what you or an agent just wrote, or name it up front when you ask for a doc. +[`/pstack:technical-writing`](../../skills/technical-writing/SKILL.md) applies a layered standard. Its goal is prose that a tired engineer understands on the first read. It picks the document's mode first (tutorial, how-to, reference, or explanation), then works sentence by sentence: who does what, one thought per sentence, nothing readable two ways. Use it to review what you or an agent just wrote, or name it up front when you ask for a doc. ## Test a skill change blind diff --git a/docs/guide/10-recipes-and-pitfalls.md b/docs/guide/10-recipes-and-pitfalls.md index 5d9c7cf..3d0c09e 100644 --- a/docs/guide/10-recipes-and-pitfalls.md +++ b/docs/guide/10-recipes-and-pitfalls.md @@ -42,7 +42,7 @@ Ask only after the design settles. The plan is the deliverable, and it names the ask /pstack:arena for a second opinion on this thread and our approach ``` -Your current design becomes one candidate among several, and the synthesis tells you whether the panel found something better or confirmed what you had. Cheap insurance before a costly commitment. +Your current design becomes one candidate among several, and the synthesis tells you whether the panel found something better or confirmed what you had. It costs little next to a design that is expensive to reverse. ## Check independent slices in parallel @@ -141,7 +141,7 @@ That's the whole prompt. [`/pstack:bro`](../../skills/bro/SKILL.md) restates the - **Leading with your theory of the cause.** The agent searches wherever you pointed. Ask it to restate the problem first, then share your hunch. - **Taking the first design.** One attempt locks in the first shape the model thought of. Ask for prototypes or `/pstack:architect` and pick from evidence. - **Polishing an abstract plan.** Adversarial review of a plan with no code behind it invents risks that will never happen. Settle the open questions with prototypes, then review what got built. -- **Parallel agents in one worktree.** They overwrite each other and the diff becomes archaeology. Run them as cloud sessions, or say "own worktree per attempt". +- **Parallel agents in one worktree.** They overwrite each other, and nobody can tell which agent changed what. Run them as cloud sessions, or say "own worktree per attempt". - **Looping before you trust the loop.** A loop that can't verify its own work only makes unchecked work faster. Get the verification skill working first. - **Trusting an unvetted number.** A warm cache or a skipped code path can fake a speedup. Run `/pstack:benchmark-checklist` before the number goes anywhere. - **Correcting the same mistake by hand.** A correction in chat helps one run. `/pstack:correct` fixes the repo so no later run repeats it. diff --git a/skills/poteto-mode/SKILL.md b/skills/poteto-mode/SKILL.md index 53145cd..5abf329 100644 --- a/skills/poteto-mode/SKILL.md +++ b/skills/poteto-mode/SKILL.md @@ -1,5 +1,5 @@ --- -name: Poteto Mode +name: poteto-mode description: poteto's agent style for concise, detailed responses, deliberate subagents, unslopped prose, simple code, and verified work. Use for poteto, /pstack:poteto-mode, or requests to work in this style. triggers: [user] --- diff --git a/skills/typescript-best-practices/SKILL.md b/skills/typescript-best-practices/SKILL.md index 95c062a..211a691 100644 --- a/skills/typescript-best-practices/SKILL.md +++ b/skills/typescript-best-practices/SKILL.md @@ -11,7 +11,7 @@ Apply the **type-system-discipline** principle skill first. | Rule | Summary | |------|---------| | Discriminated unions | Model variants with a `kind` literal discriminant so impossible states can't be represented. No optional-field bags. | -| Branded types | Brand primitives with `& { readonly __brand: "X" }` so they can't be mixed up. Validate once at the boundary. | +| Branded types | Brand primitives with `& { readonly __brand: "X" }` so they can't be mixed up. Validate once at the boundary. A brand comes from a verifying type guard (`input is AgentId`), never from `as`. | | Constructive modeling | Build the shape so the illegal value can't be constructed. `[T, ...T[]]` for non-empty, `[T, T][]` for even length, `start` plus `duration` for a range. Not a runtime guard, not a wish for refinement types. | | Simplest total type | Keep `T[]` while every operation on it stays total. Strengthen to `NonEmpty` only where the loose type forces `!`, a cast, or a "should never happen" throw. | | `unknown` over `any` | External data is `unknown`. | diff --git a/skills/typescript-best-practices/references/patterns.md b/skills/typescript-best-practices/references/patterns.md index c21d876..f8dd99b 100644 --- a/skills/typescript-best-practices/references/patterns.md +++ b/skills/typescript-best-practices/references/patterns.md @@ -9,9 +9,13 @@ Brand primitives so they can't be mixed up. Validate once at the boundary. Downs ```ts type AgentId = string & { readonly __brand: "AgentId" }; +function isAgentId(input: string): input is AgentId { + return isUUID(input); +} + function parseAgentId(input: string): AgentId { - if (!isUUID(input)) throw new Error(`Invalid agent id: ${input}`); - return input as AgentId; + if (!isAgentId(input)) throw new Error(`Invalid agent id: ${input}`); + return input; } function focusAgent(id: AgentId): void {