From 9511e60321f7e533a187d62854a3d53a53752874 Mon Sep 17 00:00:00 2001 From: lauren Date: Sat, 3 Oct 2026 13:28:30 -0700 Subject: [PATCH 1/3] feat(pstack): add /correct skill (#494) * feat(pstack): add /correct skill (0.15.7) /correct turns mistakes the operator keeps correcting into repo changes that make each one impossible. It mines history for mistake classes, fixes each at the highest level that works, and keeps a table that pairs each rule with what enforces it. Co-authored-by: lauren * docs(pstack): use the operator's short form for the /correct description Co-authored-by: lauren --------- Co-authored-by: Cursor Agent --- pstack/.cursor-plugin/plugin.json | 2 +- pstack/README.md | 2 ++ pstack/skills/correct/SKILL.md | 32 +++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 pstack/skills/correct/SKILL.md diff --git a/pstack/.cursor-plugin/plugin.json b/pstack/.cursor-plugin/plugin.json index a9a1d13a1..1d129c601 100644 --- a/pstack/.cursor-plugin/plugin.json +++ b/pstack/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "pstack", "displayName": "pstack", - "version": "0.15.6", + "version": "0.15.7", "description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence.", "author": { "name": "Lauren Tan" diff --git a/pstack/README.md b/pstack/README.md index a01d2d168..cf64d3602 100644 --- a/pstack/README.md +++ b/pstack/README.md @@ -122,6 +122,7 @@ the full rules and playbooks live in [`skills/poteto-mode/SKILL.md`](./skills/po | [`/make-bot-ui`](./skills/make-bot-ui/SKILL.md) | you want a page or dashboard whose buttons wake a Grok Bot over a webhook, including the sender-key handoff and Tailscale. | | [`/setup-pstack`](./skills/setup-pstack/SKILL.md) | you want to pick which models pstack uses per role. detects your models and writes a config rule. | | [`/reflect`](./skills/reflect/SKILL.md) | a long task landed and you want the recipe captured as a skill edit. | +| [`/correct`](./skills/correct/SKILL.md) | you keep correcting agents for the same mistakes. mines history for mistake classes, fixes each at the highest level that works (architecture, then types, lint, and ci, then tests, with docs last), and keeps a table pairing each rule with what enforces it. | | [`/teach`](./skills/teach/SKILL.md) | you want to actually understand a change or subsystem, not just have it summarized. runs how + why and weaves one plain explanation, built up diagram by diagram. | | [`/tdd`](./skills/tdd/SKILL.md) | you're fixing a bug and there's a cheap local test path. write the failing test first, then the fix. | | [`/benchmark-checklist`](./skills/benchmark-checklist/SKILL.md) | you ran a benchmark or measured a speedup or regression. vets the number (limiter, tuning, errors, repeat runs, end-to-end relevance) before you report or act on it. | @@ -178,6 +179,7 @@ tdd: /tdd implement unslop: can we unslop and tighten the new changes? reflect: /reflect that took too long. capture what we learned so the next run doesn't repeat it. +correct: /correct show-me-your-work: /show-me-your-work keep a decision trail i can review when i'm back. automate-me: /automate-me ``` diff --git a/pstack/skills/correct/SKILL.md b/pstack/skills/correct/SKILL.md new file mode 100644 index 000000000..c09f486e3 --- /dev/null +++ b/pstack/skills/correct/SKILL.md @@ -0,0 +1,32 @@ +--- +name: correct +description: "Find the mistakes agents keep repeating in this repo and make each one impossible. Try architecture first, then types, then a lint whose error names the fix, then a test, and write docs last. Prove each check fails on a real past mistake. Repeat this each time the operator corrects you. Use for /correct." +disable-model-invocation: true +--- + +# Correct + +The operator keeps correcting agents in this repo for the same mistakes. Change the repo so the next agent can't make them. + +Assume every contributor is an agent that sees only the files it opened, copies the nearest example, and takes the shortest path that compiles. Design the repo so a change that looks right from one file is right for the whole repo. + +## Find the mistake classes + +First, read recent commits, reverts, review comments, agent instruction files, and comments that explain workarounds. Group the mistakes into classes. A class counts once it has happened twice. + +## Fix each class at the highest level that works + +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. +4. **Write docs or agent rules last, only for judgment calls.** Nothing fails when an agent skips them. + +## Fix and prove + +Then fix the most frequent classes now, one commit each. Prove each new check fails on a real past mistake. Run the same command locally and in CI. Exceptions go on the offending line with a reason, an expiry date, and a human's approval. + +## Keep the rule table + +Last, keep a table in the agent instruction file that pairs each rule with what enforces it. When the operator corrects you, fix the mistake and add the rule. If the rule was already there and nothing enforces it, that's a repeat, so fix it at the highest level in the same change. Drop a rule once its mistake can't happen. + +**Reply:** each class with its evidence, the level you picked, and why a higher level didn't work. From a58628271271837ef5f386adca29c0812683a19a Mon Sep 17 00:00:00 2001 From: lauren Date: Sat, 3 Oct 2026 16:19:16 -0700 Subject: [PATCH 2/3] feat(pstack): make /architect designs resist agent mistakes (#495) * feat(pstack): judge architect candidates as an agent contributor would change them Co-authored-by: lauren * feat(pstack): add split ownership, two ways, importable internals, and hand-synced list red flags Co-authored-by: lauren * chore(pstack): bump to 0.15.8 Co-authored-by: lauren --------- Co-authored-by: Cursor Agent --- pstack/.cursor-plugin/plugin.json | 2 +- pstack/skills/architect/SKILL.md | 2 +- .../architect/references/design-red-flags.md | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pstack/.cursor-plugin/plugin.json b/pstack/.cursor-plugin/plugin.json index 1d129c601..96bbd7972 100644 --- a/pstack/.cursor-plugin/plugin.json +++ b/pstack/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "pstack", "displayName": "pstack", - "version": "0.15.7", + "version": "0.15.8", "description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence.", "author": { "name": "Lauren Tan" diff --git a/pstack/skills/architect/SKILL.md b/pstack/skills/architect/SKILL.md index afa6eead8..2bd58a7d4 100644 --- a/pstack/skills/architect/SKILL.md +++ b/pstack/skills/architect/SKILL.md @@ -34,7 +34,7 @@ Take the runners from the `architect runners` line in the `pstack-models.mdc` ru Design it twice. Require at least two structurally distinct candidates before synthesis, even when the first looks sufficient. This is the **exhaust-the-design-space** principle skill made concrete. Whole-shape alternatives, not point fixes inside one shape. -Screen every candidate against [`references/design-red-flags.md`](references/design-red-flags.md) before synthesis. Reject or revise shallow modules, information leakage, temporal decomposition, and pass-through methods. +Screen every candidate against [`references/design-red-flags.md`](references/design-red-flags.md) before synthesis. Assume the next contributor is an agent that sees only the files it opened, copies the nearest example, and takes the shortest path that compiles. Prefer the design where a change that looks right from one file is right for the whole repo. Compare viable candidates on interface depth. Prefer the design that hides more complexity behind a smaller, simpler public surface. A rich interface can keep call chains short by concentrating capability instead of scattering it across layers. diff --git a/pstack/skills/architect/references/design-red-flags.md b/pstack/skills/architect/references/design-red-flags.md index 32cb24083..f8503c959 100644 --- a/pstack/skills/architect/references/design-red-flags.md +++ b/pstack/skills/architect/references/design-red-flags.md @@ -31,3 +31,27 @@ Group code around domain knowledge and ownership. Methods that run at different A pass-through method forwards the same arguments to another method with the same shape. It adds a layer without hiding complexity. Remove it or move responsibility to the module that can complete the operation. Keep a forwarding boundary only when it adds policy, adaptation, or a distinct abstraction. + +## Split ownership + +More than one module writes the same state or keeps its own copy of it. An agent that edits one writer can't see the others, so their rules diverge. + +Give each piece of state one owner. Other modules read it or ask the owner to change it. + +## Two ways to do one task + +The design supports more than one way to do the same task. An agent copies whichever way it finds first, so every way keeps gaining callers. + +Keep one way. Move callers off the others and delete them in the same change. + +## Importable internals + +A caller can import a module's internals. An agent takes the shortest path that compiles, so it imports them directly and they become part of the interface. + +Make internals unreachable from outside the module, so an import from outside fails the build. + +## Hand-synced list + +Two or more places list the same items, and adding an item means editing every list. An agent that sees one list updates only that one. + +Keep one list and derive the others from it. If a list can't be derived, make the build fail when the lists disagree. From e43c7ee26e0038c6c1fa8380dd34ce86ff94cb2a Mon Sep 17 00:00:00 2001 From: lauren Date: Sat, 3 Oct 2026 17:06:48 -0700 Subject: [PATCH 3/3] refactor(pstack): use bare performance mantras in perf-issue step 2 (#496) * refactor(pstack): use bare performance mantras in perf-issue step 2 Co-authored-by: lauren * fix(pstack): borrow only the mantra order in hillclimb step 4 Co-authored-by: lauren --------- Co-authored-by: Cursor Agent --- pstack/.cursor-plugin/plugin.json | 2 +- pstack/skills/benchmark-checklist/SKILL.md | 2 +- .../skills/poteto-mode/playbooks/hillclimb.md | 2 +- .../poteto-mode/playbooks/perf-issue.md | 19 ++++++++++--------- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/pstack/.cursor-plugin/plugin.json b/pstack/.cursor-plugin/plugin.json index 96bbd7972..0ab7fa1b6 100644 --- a/pstack/.cursor-plugin/plugin.json +++ b/pstack/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "pstack", "displayName": "pstack", - "version": "0.15.8", + "version": "0.15.9", "description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence.", "author": { "name": "Lauren Tan" diff --git a/pstack/skills/benchmark-checklist/SKILL.md b/pstack/skills/benchmark-checklist/SKILL.md index e54ca31a4..c02adb789 100644 --- a/pstack/skills/benchmark-checklist/SKILL.md +++ b/pstack/skills/benchmark-checklist/SKILL.md @@ -35,5 +35,5 @@ For a quick ballpark the user asked for, one run is enough. Still check question ## How this fits the other perf material -- The **Perf issue** playbook finds and fixes slowness, and its strategy families generate the fixes. This skill vets its baseline before the playbook plans from it, and every number after that. +- The **Perf issue** playbook finds and fixes slowness, and the performance mantras in its step 2 generate the fixes. This skill vets its baseline before the playbook plans from it, and every number after that. - The **Hillclimb** playbook loops on one metric. This skill vets its harness before the harness is frozen. The frozen harness then prints error and work counts, so each keep-or-revert checks questions 4 and 7 for free. diff --git a/pstack/skills/poteto-mode/playbooks/hillclimb.md b/pstack/skills/poteto-mode/playbooks/hillclimb.md index 86f800cb4..c6441b92d 100644 --- a/pstack/skills/poteto-mode/playbooks/hillclimb.md +++ b/pstack/skills/poteto-mode/playbooks/hillclimb.md @@ -7,7 +7,7 @@ Core discipline: one change, one measurement, keep or revert. Never stack untest 1. Ground the workload and architecture before choosing the metric. Run the **how** skill over the target, name the realistic workload dimensions that can move the result (data size, history, state, concurrency), and select a case that reproduces the user's complaint. If no case reproduces it, fix the repro instead of hillclimbing. Then fix one metric, the direction that counts as better, and a checkable stop predicate that pairs a target with a floor on attempts so a lucky early win can't end the run (the example "at least 50% better than baseline and at least 10 iterations" is this shape). Use the user's numbers when given, otherwise agree them. 2. Build the measurement harness, prove its sensitivity, then freeze it (the **build-the-lever** principle skill). Run contrasting realistic workloads and confirm the target case reproduces the symptom while easier cases separate as expected. If the harness cannot distinguish them, revise the workload or metric. Vet the harness with the **benchmark-checklist** skill before you freeze it, and make it print its error count and a count of the work done. Once frozen, one repeatable command emits the metric, sampled enough to clear the noise (median of N, not a single run). Record the baseline metric and a green run of the regression gate (the tests that must keep passing) before any change. 3. Open the decision log via the **show-me-your-work** skill. A `decision.tsv`, one row per attempt: id, hypothesis, change, before, after, delta, tests, verdict (kept or reverted), note. Read it before each attempt. Keep it out of the tree (gitignored). -4. Ground each hypothesis in the architecture model from step 1, so it names a specific mechanism ("defer X off the boot path because it blocks first paint"), not "try memoizing something". +4. Ground each hypothesis in the architecture model from step 1, so it names a specific mechanism ("defer X off the boot path because it blocks first paint"), not "try memoizing something". For a perf metric, order hypotheses by the performance mantras in step 2 of the Perf issue playbook (`playbooks/perf-issue.md`). Borrow only their order, not that step's stop rule. 5. Loop, one hypothesis per iteration: - Hand the change to a subagent using your configured hillclimb model (default `grok-4.7-xhigh-fast`) with a tight scope. Supervise and review the diff rather than typing it (the **guard-the-context-window** principle skill). When several independent hypotheses are live, fan them to parallel subagents, each in its own worktree (the **separate-before-serializing-shared-state** principle skill). - Measure before and after with the frozen harness, and run the regression gate. diff --git a/pstack/skills/poteto-mode/playbooks/perf-issue.md b/pstack/skills/poteto-mode/playbooks/perf-issue.md index 7e024bab4..405c7a436 100644 --- a/pstack/skills/poteto-mode/playbooks/perf-issue.md +++ b/pstack/skills/poteto-mode/playbooks/perf-issue.md @@ -4,15 +4,16 @@ 1. Capture a baseline trace via the matching control skill. Vet the baseline, and each later number, with the **benchmark-checklist** skill. 2. `how` to ground hypotheses. Don't claim a perf ceiling without running it first. - Most fixes come from eight strategy families. Use them as hypothesis generators, not a checklist. A family earns an attempt only when the trace shows the signal it names. - - **Elimination.** Before optimizing the hot path, ask whether it needs to exist: a computation nobody consumes, a feature gate that's always off for this user, a sync that redundantly mirrors state, a legacy path kept "just in case". The trace shows what's slow, never that it's deletable, so this family needs the `how` pass, not the profiler. - - **Divide and conquer.** The dominant cost scales with input size. Split the work so each piece touches less (chunk, shard, prune the search space) or so independent pieces run in parallel. - - **Caching.** The same computation or fetch repeats on identical inputs. Store and reuse the result. Name what invalidates it before claiming the win. - - **Indirection.** The hot path does expensive work a cheaper intermediate could absorb: an index instead of a scan, a queue that shifts work off the interactive thread, a handle that lets a cheaper implementation swap in. Add the hop only when it removes more from the critical path than it adds. - - **Batching.** Many small operations each pay a fixed overhead (RPC, query, syscall, draw call). Coalesce them to pay the overhead once per batch. - - **Redundancy.** The wait hangs on one slow instance or attempt. Duplicate the work (replicas, hedged requests, speculative execution) and take the fastest result. The trace has to show the wait dominates and the system has headroom. - - **Lazy evaluation.** Cost lands on results that are never used or not needed yet (eager init on the boot path, rendering offscreen items). Defer the work until first use. - - **Scheduling.** The work must happen, but not during the interactive moment. Move it to where nobody is waiting: idle callbacks, a background warmup after boot, precompute before the user arrives, cleanup after the frame commits. The win is perceived latency, so measure the interactive path, not total work done. + Try the performance mantras in order, cheapest first: + 1. Don't do it. Stop work whose result nothing uses rather than cheapening it. + 2. Do it, but don't do it again. + 3. Do it less. + 4. Do it later. + 5. Do it when they're not looking. + 6. Do it concurrently. + 7. Do it cheaper. + + When an earlier mantra meets the target, stop. 3. Plan the fix from the trace. If it crosses a function boundary, `architect` first. Delegate implementation to a subagent using your configured perf-issue model (default `grok-4.7-xhigh-fast`). Review the diff. Capture a post-fix trace. Apply the **sequence-verifiable-units** principle skill, verifying each attempt before trying the next. 4. Parse and compare the artifacts (JSON to sqlite, diff). "Inconclusive" or wrong-surface is not a pass. Flag it.