From 718ee6aa683e6cd536f3e8fdd3429fc7e33a27cf Mon Sep 17 00:00:00 2001 From: Sebastian Puskeiler Date: Thu, 20 Aug 2026 09:46:53 +0200 Subject: [PATCH 1/3] pstack: teach explicit variable naming in minimize-reader-load Add one pattern bullet and one test sentence for naming variables after what they are, not the operation that produced them. Scoped to when a transformation changes meaning; outcome-names stay fine inside generics and one-liners. Co-authored-by: Cursor --- pstack/skills/principle-minimize-reader-load/SKILL.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pstack/skills/principle-minimize-reader-load/SKILL.md b/pstack/skills/principle-minimize-reader-load/SKILL.md index 1c5e18c3..ab9e9aab 100644 --- a/pstack/skills/principle-minimize-reader-load/SKILL.md +++ b/pstack/skills/principle-minimize-reader-load/SKILL.md @@ -18,6 +18,7 @@ Maintainability is the work a reader must do to understand code. Track two axes: - **Demand interface compression.** A broad interface that hides little complexity makes readers learn both the surface and the implementation. Prefer boundaries that hide meaningful decisions. - **Shrink state scope:** prefer pure functions (returns over mutations), locals over fields, fields over module state, and module state over globals. Derive instead of sync. - **Name the invariant at the boundary,** not in every consumer, so the reader learns it once. +- **Name the noun, not the operation, when the transformation changes meaning.** `validatedUser` over `result`; `fetchedUser = fetchUser()` restates the call and earns nothing. The rule tightens with scope: `result` or `data` is fine inside a generic or a one-liner, a bug at module level. Two same-typed values in scope need different names. The type can't distinguish them; only the name can. - Before adding a layer or a piece of state, ask: does this reduce reader load somewhere else by at least as much? -**The test:** Can a new reader answer "where does X come from?" and "what can change X?" in under 30 seconds? If not, cut layers or cut state. +**The test:** Can a new reader answer "where does X come from?" and "what can change X?" in under 30 seconds? If not, cut layers or cut state. Could a reader tell two same-typed values in scope apart by name alone? If not, rename to what each one is. From a9a5cc11a94a8cf63ed7286636fd094840526971 Mon Sep 17 00:00:00 2001 From: Sebastian Puskeiler Date: Thu, 20 Aug 2026 10:10:22 +0200 Subject: [PATCH 2/3] pstack: broaden variable naming guidance Cover domain roles and guarantees beyond transformed values, while keeping short generic names acceptable in tight scopes. Co-authored-by: Cursor --- pstack/skills/principle-minimize-reader-load/SKILL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pstack/skills/principle-minimize-reader-load/SKILL.md b/pstack/skills/principle-minimize-reader-load/SKILL.md index ab9e9aab..0ffe53c8 100644 --- a/pstack/skills/principle-minimize-reader-load/SKILL.md +++ b/pstack/skills/principle-minimize-reader-load/SKILL.md @@ -18,7 +18,7 @@ Maintainability is the work a reader must do to understand code. Track two axes: - **Demand interface compression.** A broad interface that hides little complexity makes readers learn both the surface and the implementation. Prefer boundaries that hide meaningful decisions. - **Shrink state scope:** prefer pure functions (returns over mutations), locals over fields, fields over module state, and module state over globals. Derive instead of sync. - **Name the invariant at the boundary,** not in every consumer, so the reader learns it once. -- **Name the noun, not the operation, when the transformation changes meaning.** `validatedUser` over `result`; `fetchedUser = fetchUser()` restates the call and earns nothing. The rule tightens with scope: `result` or `data` is fine inside a generic or a one-liner, a bug at module level. Two same-typed values in scope need different names. The type can't distinguish them; only the name can. +- **Name variables after their domain meaning or role, not the operation's generic outcome.** Prefer `validatedUser`, `pendingRefunds`, or `requester` over `result`, `data`, or `value`. Include provenance or guarantees when they distinguish the value. Short generic names are fine in tight generic scopes; require more explicit names as the distance between declaration and use grows. - Before adding a layer or a piece of state, ask: does this reduce reader load somewhere else by at least as much? -**The test:** Can a new reader answer "where does X come from?" and "what can change X?" in under 30 seconds? If not, cut layers or cut state. Could a reader tell two same-typed values in scope apart by name alone? If not, rename to what each one is. +**The test:** Can a new reader answer "where does X come from?" and "what can change X?" in under 30 seconds? If not, cut layers or cut state. Can a reader understand a value's role without rereading its assignment, and distinguish it from similar values in scope? If not, rename it. From b63c38d90b8680fdfe4abfe4c56446bf538256b2 Mon Sep 17 00:00:00 2001 From: Sebastian Puskeiler Date: Thu, 20 Aug 2026 10:19:14 +0200 Subject: [PATCH 3/3] pstack: integrate variable naming into reader load Tie vague names to remembered state, keep short names valid when declaration and use stay visible together, and update routing summaries so agents discover the guidance. Co-authored-by: Cursor --- pstack/README.md | 2 +- pstack/docs/guide/08-principles.md | 2 +- pstack/skills/poteto-mode/SKILL.md | 2 +- pstack/skills/principle-minimize-reader-load/SKILL.md | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pstack/README.md b/pstack/README.md index cbe932ae..03e13024 100644 --- a/pstack/README.md +++ b/pstack/README.md @@ -203,7 +203,7 @@ twenty-one short skills, one principle each. `poteto-mode` indexes them inline a | [foundational-thinking](./skills/principle-foundational-thinking/SKILL.md) | core | Apply before writing logic: choosing core types and data structures, sequencing scaffold-vs-feature work, asking what concurrent actors share. Get the data structures right so downstream code becomes obvious. | | [redesign-from-first-principles](./skills/principle-redesign-from-first-principles/SKILL.md) | core | Redesign as if the requirement had been a foundational assumption from day one, instead of bolting it on. | | [subtract-before-you-add](./skills/principle-subtract-before-you-add/SKILL.md) | core | Remove dead weight, redundant validators, and stub references first, then build on the simpler base. | -| [minimize-reader-load](./skills/principle-minimize-reader-load/SKILL.md) | core | Count layers between question and answer, and hidden state in the reader's head; collapse one-caller wrappers and shrink mutable scope. | +| [minimize-reader-load](./skills/principle-minimize-reader-load/SKILL.md) | core | Reduce layers between question and answer and state the reader must remember, including value roles hidden by vague names. | | [outcome-oriented-execution](./skills/principle-outcome-oriented-execution/SKILL.md) | core | Apply during planned rewrites and migrations with explicit phase boundaries. Converge on the target architecture; don't preserve smooth intermediate states with throwaway compatibility code. | | [experience-first](./skills/principle-experience-first/SKILL.md) | core | Choose user delight over implementation convenience; ship fewer polished features over more rough ones. | | [exhaust-the-design-space](./skills/principle-exhaust-the-design-space/SKILL.md) | core | Build 2-3 competing prototypes and compare side by side before committing. | diff --git a/pstack/docs/guide/08-principles.md b/pstack/docs/guide/08-principles.md index 97dc61ce..b1f284eb 100644 --- a/pstack/docs/guide/08-principles.md +++ b/pstack/docs/guide/08-principles.md @@ -34,7 +34,7 @@ The core principles decide how much to build and when to rethink the design: - [Foundational Thinking](../../skills/principle-foundational-thinking/SKILL.md) chooses the core data structures before writing logic. - [Redesign from First Principles](../../skills/principle-redesign-from-first-principles/SKILL.md) integrates a new requirement as if it had been there from day one. - [Subtract Before You Add](../../skills/principle-subtract-before-you-add/SKILL.md) removes dead weight before building on top of it. -- [Minimize Reader Load](../../skills/principle-minimize-reader-load/SKILL.md) collapses layers and hidden state a reader must hold in their head. +- [Minimize Reader Load](../../skills/principle-minimize-reader-load/SKILL.md) cuts layers and state readers must remember, including value roles hidden by vague names. - [Outcome-Oriented Execution](../../skills/principle-outcome-oriented-execution/SKILL.md) converges rewrites on the target design instead of preserving throwaway compatibility states. - [Experience First](../../skills/principle-experience-first/SKILL.md) chooses the user's result over implementation convenience. - [Exhaust the Design Space](../../skills/principle-exhaust-the-design-space/SKILL.md) builds two or three competing prototypes when there's no precedent. diff --git a/pstack/skills/poteto-mode/SKILL.md b/pstack/skills/poteto-mode/SKILL.md index a74065cd..3d54ecc9 100644 --- a/pstack/skills/poteto-mode/SKILL.md +++ b/pstack/skills/poteto-mode/SKILL.md @@ -44,7 +44,7 @@ Read the leaf skill in full for any principle you apply. Each entry names when i - **Foundational Thinking** (**principle-foundational-thinking**). Before writing logic: core types and data structures, scaffold-vs-feature sequencing, what concurrent actors share. - **Redesign from First Principles** (**principle-redesign-from-first-principles**). Integrating a new requirement into an existing design. Redesign as if it had been foundational from day one. - **Subtract Before You Add** (**principle-subtract-before-you-add**). Sequencing an addition, refactor, or rewrite. Remove dead weight first, then build on the simpler base. -- **Minimize Reader Load** (**principle-minimize-reader-load**). Reviewing or shaping code that's hard to trace. Count layers and hidden state, collapse one-caller wrappers, shrink mutable scope. +- **Minimize Reader Load** (**principle-minimize-reader-load**). Reviewing or shaping code that's hard to trace. Cut layers and remembered state; name values by role rather than generic outcome. - **Outcome-Oriented Execution** (**principle-outcome-oriented-execution**). Planned rewrites and migrations with explicit phase boundaries. Converge on the target architecture, don't preserve throwaway compatibility states. - **Experience First** (**principle-experience-first**). Product, UX, or feature-scope tradeoffs. Choose user delight over implementation convenience. - **Exhaust the Design Space** (**principle-exhaust-the-design-space**). A novel interaction or architectural decision with no precedent. Build 2-3 competing prototypes and compare before committing. diff --git a/pstack/skills/principle-minimize-reader-load/SKILL.md b/pstack/skills/principle-minimize-reader-load/SKILL.md index 0ffe53c8..a9805dcb 100644 --- a/pstack/skills/principle-minimize-reader-load/SKILL.md +++ b/pstack/skills/principle-minimize-reader-load/SKILL.md @@ -1,6 +1,6 @@ --- name: principle-minimize-reader-load -description: "Apply when reviewing or shaping code that's hard to trace. Count layers between question and answer, and hidden state in the reader's head; collapse one-caller wrappers and shrink mutable scope." +description: "Apply when reviewing or shaping code that's hard to trace. Reduce layers between question and answer and state the reader must remember, including a value's role hidden by vague names." disable-model-invocation: true --- @@ -18,7 +18,7 @@ Maintainability is the work a reader must do to understand code. Track two axes: - **Demand interface compression.** A broad interface that hides little complexity makes readers learn both the surface and the implementation. Prefer boundaries that hide meaningful decisions. - **Shrink state scope:** prefer pure functions (returns over mutations), locals over fields, fields over module state, and module state over globals. Derive instead of sync. - **Name the invariant at the boundary,** not in every consumer, so the reader learns it once. -- **Name variables after their domain meaning or role, not the operation's generic outcome.** Prefer `validatedUser`, `pendingRefunds`, or `requester` over `result`, `data`, or `value`. Include provenance or guarantees when they distinguish the value. Short generic names are fine in tight generic scopes; require more explicit names as the distance between declaration and use grows. +- **Make local names carry meaning instead of reader memory.** Prefer domain roles or guarantees (`requester`, `validatedUser`) over generic outcomes (`result`, `data`). Short names are fine when declaration and use are visible together. - Before adding a layer or a piece of state, ask: does this reduce reader load somewhere else by at least as much? -**The test:** Can a new reader answer "where does X come from?" and "what can change X?" in under 30 seconds? If not, cut layers or cut state. Can a reader understand a value's role without rereading its assignment, and distinguish it from similar values in scope? If not, rename it. +**The test:** Can a new reader answer "where does X come from?", "what can change X?", and "what role does X play?" in under 30 seconds? If not, cut layers, cut state, or rename X.