From code-foundations
Enforces pseudocode before coding for designing routines, with invariant checks for clear naming, understanding logic, and alternatives. Use when starting tasks, stuck on code, or in debug loops.
npx claudepluginhub ryanthedev/code-foundationsThis skill uses the workspace's default tool permissions.
| Check | Time | Why Non-Negotiable |
Performs adversarial pre-coding planning: host and peer agents independently investigate codebase, diff specs, and validate plan with execution drill. Use for 'plan this', 'design approach', or scoping before coding.
Guides OOP class and routine design: enforces LSP checks, prefers containment over inheritance, limits parameters >7, evaluates cohesion. For reviews and refactoring.
Guides design-first brainstorming: explores intent/requirements, proposes 2-3 approaches with trade-offs and counter-arguments before coding features or components.
Share bugs, ideas, or general feedback.
| Check | Time | Why Non-Negotiable |
|---|---|---|
| Pseudocode before code | 30 sec | Iterating on pseudocode is cheaper than iterating on code |
| Can you name it clearly? | 15 sec | Naming difficulty = design problem. Stop and clarify purpose. |
| Do you understand why it works? | 30 sec | Working code you don't understand probably doesn't really work |
| Did you consider alternatives? | 30 sec | First design is rarely best; iterate in pseudocode where it's cheap |
Exemption criteria are STRICT. If in doubt, use PPP.
getValue(), setName() with NO logic (no validation, no transformation, no side effects)If you're debating whether it's "trivial enough" to skip PPP, it isn't trivial. Use PPP.
These checks are NON-NEGOTIABLE regardless of user instructions to skip:
| Check | Time | Why Non-Negotiable |
|---|---|---|
| Pseudocode before code | 30 sec | Iterating on pseudocode is cheaper than iterating on code |
| Can you name it clearly? | 15 sec | Naming difficulty = design problem. Stop and clarify purpose. |
| Do you understand why it works? | 30 sec | Working code you don't understand probably doesn't really work |
| Did you consider alternatives? | 30 sec | First design is rarely best; iterate in pseudocode where it's cheap |
Why these four? They catch the most expensive mistakes: unclear designs that "work" but create maintenance nightmares, and premature coding that locks in bad decisions.
These checks apply EVERY TIME, even if:
Minimum Viable PPP (for extreme time pressure): When full PPP is impossible, these 4 items are MANDATORY (total ~4 min):
This is the FLOOR, not the ceiling. If you can't spare 4 minutes, the routine will cost you more in debugging.
Purpose: Guide routine design using PPP technique Triggers:
Constraints:
Key Term Definitions:
Problem: Create a routine to allocate a new resource and return its handle.
Bad Pseudocode (Anti-Pattern):
increment resource number by 1
allocate a dlg struct using malloc
if malloc() returns NULL then return 1
invoke OSrsrc_init to initialize a resource for the operating system
*hRsrcPtr = resource number
return 0
Problems: Uses target language details (*hRsrcPtr, malloc()), focuses on HOW not WHAT, exposes implementation details (returns 1 or 0), won't become good comments.
Good Pseudocode:
If another resource is available
Allocate a dialog box structure
If a dialog box structure could be allocated
Note that one more resource is in use
Initialize the resource
Store the resource number at the location provided by the caller
Return success
Endif
Endif
Return failure
Why better: Pure English, no syntax, level of intent, precise enough to generate code, becomes excellent comments. Note: resource count is updated AFTER successful allocation, not before.
Resulting Code with Comments:
// If another resource is available
if (resourceCount < MAX_RESOURCES) {
// Allocate a dialog box structure
DialogBox* dlg = allocateDialogBox();
// If a dialog box structure could be allocated
if (dlg != NULL) {
// Note that one more resource is in use
// (Using post-increment: store at current index, then increment)
activeResources[resourceCount] = dlg;
*handlePtr = resourceCount;
resourceCount++;
// Initialize the resource
initializeResource(dlg);
return true;
}
}
return false;
Purpose: Verify PPP was followed correctly Triggers:
Check Against:
| Claim | Evidence | Source | Still Valid? |
|---|---|---|---|
| Programmers prefer pseudocode | Survey: preferred for construction ease, detecting insufficient detail, documentation | Ramsey, Atwood, Van Doren 1983 | Yes - methodology unchanged; modern IDEs don't eliminate design thinking need |
| Only 5% external errors | Hardware, compiler, OS errors are rare; 95% are programmer errors | Ostrand and Weyuker 1984 | Yes - if anything, modern tooling has made infrastructure MORE reliable, so programmer error % is likely higher |
| Errors at least-value stage | Key insight: catch errors when least effort invested | McConnell p.220 | Timeless - economic principle |
| Iteration improves design | First design is rarely best; iterating on code is more expensive than iterating on pseudocode | McConnell p.225 | Timeless - economic principle |
Note on dated studies: The 1983-1984 studies predate modern IDEs, but their findings are MORE applicable today: better tooling catches syntax errors faster, making DESIGN errors (which PPP prevents) the dominant problem.
| After | Next |
|---|---|
| Pseudocode complete | cc-routine-and-class-design |
| Implementation done | cc-defensive-programming (CHECKER) |