@lenardangeloolajay/len-toolkit 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +209 -0
  3. package/bin/cli.js +244 -0
  4. package/package.json +35 -0
  5. package/src/installer.js +236 -0
  6. package/templates/configs/.editorconfig +12 -0
  7. package/templates/configs/sample.gitignore +8 -0
  8. package/templates/docs/FEATURE.md +40 -0
  9. package/templates/docs/HANDOFF.md +39 -0
  10. package/templates/docs/IMPLEMENTATION_PLAN.md +47 -0
  11. package/templates/docs/SPEC_INDEX.md +12 -0
  12. package/templates/docs/VERIFICATION.md +14 -0
  13. package/templates/docs/product/ARCHITECTURE.md +22 -0
  14. package/templates/docs/product/CONSTRAINTS.md +22 -0
  15. package/templates/docs/product/DATA_MODEL.md +22 -0
  16. package/templates/docs/product/OVERVIEW.md +22 -0
  17. package/templates/examples/flutter-handoff/EXERCISES.md +16 -0
  18. package/templates/examples/flutter-handoff/HANDOFF.md +32 -0
  19. package/templates/examples/flutter-handoff/docs/SPEC_INDEX.md +19 -0
  20. package/templates/examples/flutter-handoff/docs/evidence/FEAT-001-verification.md +14 -0
  21. package/templates/examples/flutter-handoff/docs/features/FEAT-001-local-note.md +40 -0
  22. package/templates/examples/flutter-handoff/docs/plans/FEAT-001-implementation.md +43 -0
  23. package/templates/examples/flutter-handoff/docs/product/ARCHITECTURE.md +24 -0
  24. package/templates/examples/flutter-handoff/docs/product/CONSTRAINTS.md +13 -0
  25. package/templates/examples/flutter-handoff/docs/product/DATA_MODEL.md +20 -0
  26. package/templates/examples/flutter-handoff/docs/product/OVERVIEW.md +26 -0
  27. package/templates/rules/.cursorrules +7 -0
  28. package/templates/rules/AGENTS.md +61 -0
  29. package/templates/rules/GEMINI.md +7 -0
  30. package/templates/skills/a-philosophy-of-software-design/SKILL.md +11 -0
  31. package/templates/skills/a-philosophy-of-software-design/a-philosophy-of-software-design.md +370 -0
  32. package/templates/skills/a-philosophy-of-software-design/a-philosophy-of-software-design.mini.md +46 -0
  33. package/templates/skills/a-philosophy-of-software-design/a-philosophy-of-software-design.nano.md +35 -0
  34. package/templates/skills/clean-architecture/SKILL.md +11 -0
  35. package/templates/skills/clean-architecture/clean-architecture.md +515 -0
  36. package/templates/skills/clean-architecture/clean-architecture.mini.md +49 -0
  37. package/templates/skills/clean-architecture/clean-architecture.nano.md +36 -0
  38. package/templates/skills/clean-code/SKILL.md +11 -0
  39. package/templates/skills/clean-code/clean-code.md +297 -0
  40. package/templates/skills/clean-code/clean-code.mini.md +47 -0
  41. package/templates/skills/clean-code/clean-code.nano.md +32 -0
  42. package/templates/skills/code-complete/SKILL.md +11 -0
  43. package/templates/skills/code-complete/code-complete.md +354 -0
  44. package/templates/skills/code-complete/code-complete.mini.md +56 -0
  45. package/templates/skills/code-complete/code-complete.nano.md +41 -0
  46. package/templates/skills/council/SKILL.md +37 -0
  47. package/templates/skills/designing-data-intensive-applications/SKILL.md +11 -0
  48. package/templates/skills/designing-data-intensive-applications/designing-data-intensive-applications.md +393 -0
  49. package/templates/skills/designing-data-intensive-applications/designing-data-intensive-applications.mini.md +55 -0
  50. package/templates/skills/designing-data-intensive-applications/designing-data-intensive-applications.nano.md +34 -0
  51. package/templates/skills/domain-driven-design/SKILL.md +11 -0
  52. package/templates/skills/domain-driven-design/domain-driven-design.md +979 -0
  53. package/templates/skills/domain-driven-design/domain-driven-design.mini.md +48 -0
  54. package/templates/skills/domain-driven-design/domain-driven-design.nano.md +39 -0
  55. package/templates/skills/domain-driven-design-distilled/SKILL.md +11 -0
  56. package/templates/skills/domain-driven-design-distilled/domain-driven-design-distilled.md +317 -0
  57. package/templates/skills/domain-driven-design-distilled/domain-driven-design-distilled.mini.md +56 -0
  58. package/templates/skills/domain-driven-design-distilled/domain-driven-design-distilled.nano.md +41 -0
  59. package/templates/skills/implementation-plan/SKILL.md +42 -0
  60. package/templates/skills/implementing-domain-driven-design/SKILL.md +11 -0
  61. package/templates/skills/implementing-domain-driven-design/implementing-domain-driven-design.md +337 -0
  62. package/templates/skills/implementing-domain-driven-design/implementing-domain-driven-design.mini.md +57 -0
  63. package/templates/skills/implementing-domain-driven-design/implementing-domain-driven-design.nano.md +37 -0
  64. package/templates/skills/patterns-of-enterprise-application-architecture/SKILL.md +11 -0
  65. package/templates/skills/patterns-of-enterprise-application-architecture/patterns-of-enterprise-application-architecture.md +404 -0
  66. package/templates/skills/patterns-of-enterprise-application-architecture/patterns-of-enterprise-application-architecture.mini.md +54 -0
  67. package/templates/skills/patterns-of-enterprise-application-architecture/patterns-of-enterprise-application-architecture.nano.md +35 -0
  68. package/templates/skills/ponytail/SKILL.md +124 -0
  69. package/templates/skills/ponytail-audit/SKILL.md +45 -0
  70. package/templates/skills/ponytail-debt/SKILL.md +48 -0
  71. package/templates/skills/ponytail-gain/SKILL.md +17 -0
  72. package/templates/skills/ponytail-help/SKILL.md +42 -0
  73. package/templates/skills/ponytail-review/SKILL.md +61 -0
  74. package/templates/skills/refactoring/SKILL.md +11 -0
  75. package/templates/skills/refactoring/refactoring.md +433 -0
  76. package/templates/skills/refactoring/refactoring.mini.md +49 -0
  77. package/templates/skills/refactoring/refactoring.nano.md +37 -0
  78. package/templates/skills/refactoring-guru/SKILL.md +11 -0
  79. package/templates/skills/refactoring-guru/refactoring-guru.md +765 -0
  80. package/templates/skills/refactoring-guru/refactoring-guru.mini.md +64 -0
  81. package/templates/skills/refactoring-guru/refactoring-guru.nano.md +41 -0
  82. package/templates/skills/release-it/SKILL.md +11 -0
  83. package/templates/skills/release-it/release-it.md +382 -0
  84. package/templates/skills/release-it/release-it.mini.md +48 -0
  85. package/templates/skills/release-it/release-it.nano.md +38 -0
  86. package/templates/skills/security-audit/AI-AND-LLM.md +83 -0
  87. package/templates/skills/security-audit/ATTACK-CLASSES.md +130 -0
  88. package/templates/skills/security-audit/CLIENT-SIDE.md +83 -0
  89. package/templates/skills/security-audit/CLOUD-AND-DEPLOYMENT.md +86 -0
  90. package/templates/skills/security-audit/DATA-ISOLATION-AND-LIFECYCLE.md +84 -0
  91. package/templates/skills/security-audit/DESKTOP-MOBILE-AND-LOCAL-IPC.md +89 -0
  92. package/templates/skills/security-audit/HUNTING.md +251 -0
  93. package/templates/skills/security-audit/MEMORY-SAFETY-AND-BINARY.md +101 -0
  94. package/templates/skills/security-audit/PROTOCOLS-RPC-AND-MESSAGING.md +81 -0
  95. package/templates/skills/security-audit/RECONNAISSANCE.md +156 -0
  96. package/templates/skills/security-audit/RESOURCE-EXHAUSTION-AND-AVAILABILITY.md +78 -0
  97. package/templates/skills/security-audit/SKILL.md +192 -0
  98. package/templates/skills/security-audit/SUPPLY-CHAIN-AND-RELEASE.md +73 -0
  99. package/templates/skills/security-audit/VALIDATION-AND-REPORTING.md +186 -0
  100. package/templates/skills/security-audit/WEB-PROTOCOL-AND-AUTH.md +105 -0
  101. package/templates/skills/security-audit/report-schema.json +461 -0
  102. package/templates/skills/security-audit/validate-coverage-ledger.cjs +872 -0
  103. package/templates/skills/security-audit/validate-coverage-ledger.test.cjs +740 -0
  104. package/templates/skills/security-audit/validate-findings.cjs +773 -0
  105. package/templates/skills/security-audit/validate-findings.test.cjs +652 -0
  106. package/templates/skills/spec/SKILL.md +55 -0
  107. package/templates/skills/the-pragmatic-programmer/SKILL.md +11 -0
  108. package/templates/skills/the-pragmatic-programmer/the-pragmatic-programmer.md +359 -0
  109. package/templates/skills/the-pragmatic-programmer/the-pragmatic-programmer.mini.md +65 -0
  110. package/templates/skills/the-pragmatic-programmer/the-pragmatic-programmer.nano.md +44 -0
  111. package/templates/skills/working-effectively-with-legacy-code/SKILL.md +11 -0
  112. package/templates/skills/working-effectively-with-legacy-code/working-effectively-with-legacy-code.md +371 -0
  113. package/templates/skills/working-effectively-with-legacy-code/working-effectively-with-legacy-code.mini.md +50 -0
  114. package/templates/skills/working-effectively-with-legacy-code/working-effectively-with-legacy-code.nano.md +35 -0
@@ -0,0 +1,43 @@
1
+ # Implementation Plan: Local note creation
2
+
3
+ Created: 2026-09-05T15:29:25+08:00
4
+ Updated: 2026-09-05T15:29:25+08:00
5
+ Revision: 1
6
+ Status: Awaiting approval
7
+ Feature spec: [FEAT-001 revision 1](../features/FEAT-001-local-note.md)
8
+ Baseline and architecture: Revision 1 drafts, not approved
9
+ Len's chat approval: Not recorded
10
+ Target branch: Unverified; no Flutter repository exists in this example
11
+
12
+ ## Scope
13
+
14
+ Implement FEAT-001/REQ-001 through REQ-004 only after the baseline assumptions and verification environment are resolved and Len approves the documents.
15
+ This sample plan is not executable as-is.
16
+
17
+ ## Phase 1: Capture and reopen a note offline
18
+
19
+ State: Awaiting approval
20
+
21
+ ### Tasks
22
+
23
+ - [ ] Connect editor validation and pending-save state to the verified existing storage API.
24
+ - [ ] Preserve failed drafts and display accessible error/retry feedback.
25
+ - [ ] Load saved notes newest first and show a useful empty state.
26
+ - [ ] Add focused checks covering invalid input, duplicate taps, failed writes, and persistence.
27
+
28
+ ### Verification
29
+
30
+ - [ ] Confirm and run the real project's test and analysis commands; proposed `flutter test` and `flutter analyze` are unverified here.
31
+ - [ ] On the selected Android emulator, disable connectivity, save a valid note, restart the app, and confirm it remains first.
32
+ - [ ] Exercise empty/oversized input, repeated Save taps, and a controlled storage failure with expected results from REQ-001 through REQ-003.
33
+ - [ ] Record actual outcomes and a meaningful UI screenshot in the [evidence](../evidence/FEAT-001-verification.md).
34
+
35
+ ### Review and checkpoint
36
+
37
+ - [ ] Review the diff against the approved architecture and scope.
38
+ - [ ] Update the plan, evidence, and handoff.
39
+ - [ ] Stage reviewed phase paths only and inspect the staged diff.
40
+ - [ ] Commit and confirm success with `feat(notes): add verified offline note capture`.
41
+
42
+ No checkpoint exists in this fictional example.
43
+ If verification fails, use the shared three-attempt policy and retain unfinished work uncommitted.
@@ -0,0 +1,24 @@
1
+ # Pocket Notes architecture
2
+
3
+ Created: 2026-09-05T15:29:25+08:00
4
+ Updated: 2026-09-05T15:29:25+08:00
5
+ Revision: 1
6
+ Status: Draft example
7
+
8
+ ## Proposed design
9
+
10
+ Use one Flutter screen with a local notes list and an editor.
11
+ Route storage through the host project's existing local-storage API, retaining entered text until a write succeeds.
12
+ Reload saved notes through that same API when opening the app.
13
+ No new dependency, server, or state-management framework is proposed.
14
+
15
+ ## Assumptions and failure modes
16
+
17
+ An existing storage API and Flutter project are assumed for illustration; neither is present in this example.
18
+ Before approval, inspect the real storage API, its durability guarantees, and failure behavior.
19
+ If it cannot meet the data model, return the architecture decision to GPT and Len instead of inventing a replacement during implementation.
20
+ Storage errors must preserve the editor contents and must not display a false success message.
21
+
22
+ ## Authority
23
+
24
+ This proposal is not approved or validated.
@@ -0,0 +1,13 @@
1
+ # Pocket Notes constraints
2
+
3
+ Created: 2026-09-05T15:29:25+08:00
4
+ Updated: 2026-09-05T15:29:25+08:00
5
+ Revision: 1
6
+ Status: Draft example
7
+
8
+ All note creation and listing behavior must work with connectivity disabled.
9
+ The editor and Save action require accessible labels and an announced validation or storage error.
10
+ Do not log note text or require unrelated permissions.
11
+ Android version support is unresolved and must be decided before approval.
12
+ Emulator scenarios can verify the stated behavior in the selected emulator configuration.
13
+ Physical-device validation remains for Len, and no hardware or field-effectiveness claim is applicable to this example.
@@ -0,0 +1,20 @@
1
+ # Pocket Notes data model
2
+
3
+ Created: 2026-09-05T15:29:25+08:00
4
+ Updated: 2026-09-05T15:29:25+08:00
5
+ Revision: 1
6
+ Status: Draft example
7
+
8
+ ## Note
9
+
10
+ | Field | Definition |
11
+ | --- | --- |
12
+ | id | Unique identifier supplied by the existing local storage API |
13
+ | text | Trimmed, nonempty text; maximum 200 Unicode scalar values |
14
+ | createdAt | UTC creation timestamp |
15
+
16
+ The device's local store owns the saved record.
17
+ An unsaved draft belongs to the editor until successful persistence.
18
+ The storage operation returns the saved record or an error; no result is inferred from merely starting a write.
19
+ No data is sent off-device.
20
+ The actual storage API must be inspected before this draft can be approved.
@@ -0,0 +1,26 @@
1
+ # Pocket Notes product overview
2
+
3
+ Created: 2026-09-05T15:29:25+08:00
4
+ Updated: 2026-09-05T15:29:25+08:00
5
+ Revision: 1
6
+ Status: Draft example
7
+
8
+ ## Purpose and users
9
+
10
+ A fictional personal Flutter Android app for short notes without an account or network connection.
11
+ This example demonstrates specification organization; it is not an implemented application.
12
+
13
+ ## Planned capabilities
14
+
15
+ FEAT-001 creates and lists local notes, including reopening the app.
16
+ A later feature may delete a selected note after confirmation; its detailed spec is not ready and it is not part of the FEAT-001 plan.
17
+ The main flow is opening the note list, entering text, saving, and seeing the saved item.
18
+
19
+ ## Non-goals
20
+
21
+ No sync, sharing, search, photos, accounts, or background collection.
22
+
23
+ ## Readiness
24
+
25
+ Len has not approved this fictional baseline.
26
+ Supported Android versions and the existing project's verification commands must be established before implementation.
@@ -0,0 +1,7 @@
1
+ # Len's Vibe Coding Rules for Cursor / Copilot
2
+
3
+ - Bias towards standard library and native platform features over third-party packages.
4
+ - Always check if an existing helper or utility in this codebase already solves the problem before writing new code.
5
+ - Keep diffs minimal, atomic, and focused. Do not refactor unrelated code.
6
+ - When planning multi-step features, suggest a phased plan with test checks and git commit milestones.
7
+ - Write code first, followed by concise explanations.
@@ -0,0 +1,61 @@
1
+ # Len's personal coding workflow
2
+
3
+ ## Start and resume
4
+
5
+ At each coding session, run `npx len-toolkit start` if setup has not been checked in that session.
6
+ Use the local source command when developing this toolkit before publication.
7
+ Inspect reported instruction differences and preserve custom content; setup success is not permission to implement.
8
+ Read `docs/SPEC_INDEX.md`, the current root `HANDOFF.md`, and its linked approved documents before implementation.
9
+ If no handoff exists, use the spec workflow to create the missing documents and obtain approval first.
10
+ Inspect Git status and reconcile files with the handoff rather than trusting prior conversation memory.
11
+
12
+ ## Specification and authority
13
+
14
+ GPT explores the entire product with Len, then details features individually.
15
+ GPT proposes architecture; Len approves the product baseline and architecture in chat, then each feature spec and implementation plan.
16
+ Record approval against exact document revisions or a Git commit; never invent an approval record.
17
+ Gemini follows the approved architecture and scope, reports disagreements, and does not silently redesign or add features.
18
+ Changes to behavior, acceptance criteria, or architecture require new approval for affected work.
19
+ Editorial corrections do not expand authorized behavior.
20
+ Search current specs before creating documents, update overlapping specs, and archive superseded documents with replacement links.
21
+ Keep stable filenames, feature and requirement IDs, and Philippine-time ISO 8601 timestamps inside documents.
22
+ Keep behavior in specs, execution tasks in plans, actual results in evidence, and one current handoff pointing to them.
23
+ Choose the Flutter or web stack per project.
24
+
25
+ ## Phase execution and commits
26
+
27
+ Execute every approved phase without routine approval stops.
28
+ For each phase: implement, run required checks, review correctness and scope, record evidence and progress, and commit only reviewed phase-related paths.
29
+ Inspect the staged diff and preserve unrelated staged or unstaged work; never use blanket staging.
30
+ A phase is complete only when its checks pass and Git confirms a successful commit.
31
+ Use a unique conventional phase commit message as the checkpoint reference; verify its hash from Git after committing.
32
+ Do not make extra commits just to insert a commit's own hash into that same commit.
33
+ Continue to the next approved phase after the checkpoint succeeds.
34
+ A failed check or commit leaves the phase incomplete; interrupted or failing work stays uncommitted.
35
+ Update the current handoff with completed work, unfinished work, actual checks, attempts, and the next action before ending a session.
36
+ Never push, reset, discard edits, or overwrite working features without explicit authorization.
37
+
38
+ ## Failure recovery
39
+
40
+ Reproduce bugs through the real user flow where possible, then trace shared callers before editing.
41
+ Investigate and fix within the approved design.
42
+ Allow at most three unsuccessful fix-and-check attempts for the same unresolved problem after its initial observed failure.
43
+ Persist counts and attempted fixes in the handoff across sessions; renaming a problem does not reset its count.
44
+ After the third unsuccessful attempt, stop affected work and report evidence, attempted fixes, outstanding edits, and what is needed to proceed.
45
+ Stop affected work immediately for a required user decision, unavailable access or hardware, or necessary scope/architecture changes.
46
+ Continue independent approved work only when it does not rely on the blocked decision.
47
+ Fix failures caused by or blocking the approved work; report other issues separately rather than expanding scope.
48
+
49
+ ## Evidence and engineering
50
+
51
+ Use existing code, the standard library, and native platform features before adding custom machinery.
52
+ No new dependency without Len's authorization.
53
+ Preserve input validation, error handling, security, accessibility, existing working features, and tests.
54
+ Record actual verification commands or scenarios, results, conditions, timestamps, and limitations.
55
+ Never describe an unrun check as passing or implementation as proof of real-world effectiveness.
56
+ Emulator checks establish emulator behavior; Len handles physical-device validation.
57
+ Keep emulator, physical-device, hardware-bench, and field evidence separate and pending until actual results exist.
58
+ Attach screenshots for meaningful UI checks when capture is available.
59
+ Do not put credentials or secrets in specs, handoffs, examples, or evidence.
60
+ Use plain dashes, not em dashes, and one full sentence per line in long Markdown.
61
+ Do not manually edit CHANGELOG.md or generated files, and do not add an agent co-author to commits.
@@ -0,0 +1,7 @@
1
+ # Len's Gemini entry point
2
+
3
+ Read the project-root `AGENTS.md` for the shared workflow policy.
4
+ Then read `docs/SPEC_INDEX.md`, root `HANDOFF.md`, and every approved document it links before implementing.
5
+ Paths above are relative to the project root even when this entry point is under `.agents/rules/`.
6
+ Read relevant skills from `.agents/skills/` explicitly if automatic discovery is unavailable.
7
+ GPT defines architecture with Len; execute only the approved handoff and use the shared phase, recovery, and evidence rules.
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: a-philosophy-of-software-design
3
+ description: Apply John Ousterhout-inspired software design rules when reducing complexity, designing module boundaries, or reviewing APIs and abstractions.
4
+ license: MIT
5
+ ---
6
+
7
+ # A Philosophy of Software Design Skill
8
+
9
+ Use this skill when a task involves module design, API design, information hiding, abstraction depth, cognitive load, or refactoring shallow interfaces.
10
+
11
+ Before making design or code decisions, read and apply [a-philosophy-of-software-design.mini.md](a-philosophy-of-software-design.mini.md). Use [a-philosophy-of-software-design.md](a-philosophy-of-software-design.md) only as a deeper reference when the mini rules are not enough for the current design tradeoff.
@@ -0,0 +1,370 @@
1
+ # OBEY A Philosophy of Software Design by John Ousterhout
2
+
3
+ ## Purpose
4
+
5
+ This repository follows **A Philosophy of Software Design** in the sense of John Ousterhout:
6
+ fight complexity directly by designing modules with deep value, clean interfaces, strong information hiding, and low cognitive load.
7
+
8
+ All code generation, edits, and reviews must optimize for:
9
+ - lower complexity
10
+ - deeper modules
11
+ - simpler interfaces
12
+ - stronger information hiding
13
+ - fewer special cases
14
+ - clear separation between interface and implementation
15
+ - strategic design over tactical patching
16
+
17
+ This file is a binding engineering policy: `MUST` is binding, `SHOULD` is a strong default, and `MUST NOT` is forbidden.
18
+
19
+ ---
20
+
21
+ ## Primary Directive
22
+
23
+ Complexity is anything that makes software hard to understand or hard to change.
24
+
25
+ When uncertain, prefer the design that:
26
+ 1. reduces the number of things a reader must know at once
27
+ 2. hides more details behind a stable interface
28
+ 3. eliminates exceptions and awkward cases
29
+ 4. creates a deeper module instead of a shallower one
30
+ 5. lowers future cognitive load, not just present typing effort
31
+
32
+ Do not optimize for shorter files, fewer lines, or clever compactness if complexity rises.
33
+
34
+ ---
35
+
36
+ ## Core Complexity Rules
37
+
38
+ ### Symptoms of Complexity
39
+ Treat these as architectural warnings:
40
+ - change amplification
41
+ - cognitive load
42
+ - unknown unknowns
43
+ - hidden dependencies
44
+ - information spread across many places
45
+ - temporal coupling that readers must reconstruct mentally
46
+
47
+ ### Default Response
48
+ When a feature feels awkward, first ask:
49
+ - is the interface too wide?
50
+ - is the behavior scattered?
51
+ - are details leaking that should be hidden?
52
+ - are there too many special cases?
53
+ - are we solving a tactical local problem while increasing global complexity?
54
+
55
+ ---
56
+
57
+ ## Module Depth Rules
58
+
59
+ ### Prefer Deep Modules
60
+ A deep module offers a simple interface but hides substantial complexity behind it.
61
+
62
+ Rules (MUST unless marked SHOULD or MUST NOT):
63
+ 1. Design modules to hide meaningful internal complexity.
64
+ 2. Prefer a small interface with strong semantics over a large surface with minor helpers.
65
+ 3. Make each module carry its own weight.
66
+ 4. A module that only forwards work is usually too shallow.
67
+
68
+ ### Avoid Shallow Modules
69
+ Shallow modules are bad when:
70
+ - the interface exposes almost as much complexity as the implementation
71
+ - layers exist mostly to redirect calls
72
+ - small wrappers multiply concepts without reducing reader burden
73
+
74
+ Anti-patterns (MUST NOT):
75
+ - pass-through service classes
76
+ - thin wrappers around libraries with no simplification
77
+ - helper modules that only rename obvious operations
78
+
79
+ ---
80
+
81
+ ## Information Hiding Rules
82
+
83
+ 1. Hide design decisions that are likely to change.
84
+ 2. Hide internal data representations.
85
+ 3. Hide incidental workflow steps and bookkeeping.
86
+ 4. Keep callers from depending on implementation detail, performance hacks, or storage shape.
87
+ 5. Encapsulate messy edge conditions and normalization logic.
88
+
89
+ Anti-patterns (MUST NOT):
90
+ - exposing internal representation or state through module interfaces
91
+ - leaking storage, protocol, framework, or file-format details through module interfaces
92
+ - callers coordinating object internals across multiple modules
93
+
94
+ ---
95
+
96
+ ## Interface Design Rules
97
+
98
+ 1. Design interfaces around what clients need to know, not how the implementation works.
99
+ 2. Keep interfaces narrow but meaningful.
100
+ 3. Avoid APIs that require callers to stage operations in fragile sequences.
101
+ 4. Eliminate arguments that only exist to expose internal implementation choices.
102
+ 5. Use names and method shapes that reveal the abstraction, not the mechanism.
103
+
104
+ Good interface signs (SHOULD):
105
+ - few methods
106
+ - strong semantic guarantees
107
+ - limited required context
108
+ - callers do not need to understand internals
109
+
110
+ Bad interface signs (warning; usually MUST NOT):
111
+ - many configuration flags
112
+ - call-order traps
113
+ - multiple setup methods required before use
114
+ - booleans and mode parameters switching internal behavior
115
+
116
+ ---
117
+
118
+ ## Strategic Programming over Tactical Programming
119
+
120
+ ### Strategic Programming
121
+ 1. Spend time reducing future complexity, not only making the current change pass.
122
+ 2. Reshape abstractions when recurring friction appears.
123
+ 3. Invest in interfaces and decomposition that make future changes local.
124
+ 4. Leave behind clearer structure after every substantial edit.
125
+
126
+ ### Tactical Programming
127
+ Avoid:
128
+ - patching local symptoms while increasing global complexity
129
+ - copy/paste to meet a deadline
130
+ - exposing one more internal detail instead of designing a better boundary
131
+ - adding flags and exceptions to avoid a better abstraction
132
+
133
+ ---
134
+
135
+ ## General-Purpose vs Special-Purpose Modules
136
+
137
+ 1. Prefer modules that capture a reusable concept at the right abstraction level.
138
+ 2. Do not overfit interfaces to one narrow caller if a slightly more general concept is obvious.
139
+ 3. Do not generalize so far that the abstraction becomes vague.
140
+ 4. The best module is specific enough to be strong and general enough to be reusable within its domain.
141
+
142
+ ---
143
+
144
+ ## Error Handling and Exception Elimination
145
+
146
+ 1. Define APIs that make misuse hard.
147
+ 2. Define away invalid states and awkward cases where possible.
148
+ 3. Eliminate exception cases by changing the interface or invariant, not only by adding more checks.
149
+ 4. Use special/general decomposition when unusual cases clutter the main abstraction.
150
+ 5. Keep the normal path obvious and the exceptional path isolated.
151
+
152
+ Anti-patterns (MUST NOT):
153
+ - APIs that require every caller to repeat defensive ceremony
154
+ - “special case” branches scattered across many call sites
155
+ - exposing half-valid objects and asking callers to tiptoe around them
156
+
157
+ ---
158
+
159
+ ## Pull Complexity Downward
160
+
161
+ 1. Put complexity in one place rather than many.
162
+ 2. Hide intricate logic behind a simpler public contract.
163
+ 3. Prefer a slightly more complex implementation if it makes all callers simpler.
164
+ 4. Remove repeated reasoning burdens from call sites.
165
+
166
+ This is the opposite of pushing complexity outward through flags, setup steps, and coupled operations.
167
+
168
+ ---
169
+
170
+ ## Comment Rules
171
+
172
+ Comments must reduce complexity, not narrate obvious code.
173
+
174
+ Use comments for:
175
+ - interface contracts
176
+ - non-obvious invariants
177
+ - hidden design decisions
178
+ - the reason an abstraction exists
179
+ - tricky implementation facts callers do not need to know
180
+
181
+ Do not use comments to compensate for:
182
+ - bad naming
183
+ - poor decomposition
184
+ - confusing control flow
185
+ - missing abstraction
186
+
187
+ ---
188
+
189
+ ## Function and Variable Rules
190
+
191
+ 1. Keep functions deep enough to hide a meaningful amount of work.
192
+ 2. Avoid long functions only when they create cognitive load, not as a numeric ritual.
193
+ 3. Avoid pass-through variables that do not add meaning.
194
+ 4. Use variables to capture meaning, not to mirror syntax.
195
+ 5. Keep local details local.
196
+
197
+ Anti-patterns (MUST NOT):
198
+ - chains of tiny functions where readers must jump constantly to understand one idea
199
+ - variables introduced only to satisfy style rather than clarity
200
+ - exposing intermediate states that should stay internal
201
+
202
+ ---
203
+
204
+ ## Temporal Decomposition Rules
205
+
206
+ 1. Do not structure modules primarily around execution order if the real structure is conceptual.
207
+ 2. Prefer decomposition around stable concepts and responsibilities.
208
+ 3. Initialization steps, processing phases, and cleanup stages should not force readers to reconstruct the design from time-order alone.
209
+ 4. Keep call ordering simple and explicit where it matters.
210
+
211
+ Anti-patterns (MUST NOT):
212
+ - `prepare/process/finalize` everywhere without domain concepts
213
+ - APIs that require secret temporal knowledge
214
+ - partial objects whose meaning depends on which phase has already run
215
+
216
+ ---
217
+
218
+ ## Special-General Decomposition
219
+
220
+ Use special-general decomposition when a small number of exceptions are cluttering the main logic.
221
+
222
+ Rules (MUST unless marked SHOULD or MUST NOT):
223
+ 1. Keep the general case simple.
224
+ 2. Isolate the unusual or rare behavior.
225
+ 3. Do not pollute the main abstraction with every edge case.
226
+
227
+ This is preferable to accreting conditionals into the core path forever.
228
+
229
+ ---
230
+
231
+ ## Combine or Separate Code
232
+
233
+ 1. Separate code only when the separation reduces complexity, hides a real design decision, or creates a stronger abstraction.
234
+ 2. Combine code when split pieces force readers to jump between shallow fragments to understand one idea.
235
+ 3. Keep related state, behavior, and invariants together when separating them would create change amplification.
236
+ 4. Do not preserve a boundary merely because it already exists if it exposes almost as much complexity as it hides.
237
+ 5. Prefer one coherent deeper module over several tiny modules that require callers to coordinate details.
238
+
239
+ Anti-patterns (MUST NOT):
240
+ - splitting code by execution phase when the stable concept is not temporal
241
+ - separating normal and special cases so far apart that their shared invariant is hidden
242
+ - adding helper layers that distribute one design decision across many files
243
+
244
+ ---
245
+
246
+ ## Design Alternatives and Comments-First Design
247
+
248
+ 1. For non-trivial design choices, compare at least two plausible designs before implementing the first one that works.
249
+ 2. Evaluate alternatives by interface simplicity, information hiding, special-case reduction, and future cognitive load.
250
+ 3. When an interface or abstraction is unclear, sketch the public contract and explanatory comments before committing to implementation.
251
+ 4. Use comments-first design to clarify abstraction boundaries, not to preserve vague or misleading code.
252
+ 5. Revise the abstraction when the comment needed to explain it becomes complicated.
253
+
254
+ Anti-patterns (MUST NOT):
255
+ - accepting the first design because it is locally convenient
256
+ - using comments to justify a confusing interface instead of changing the interface
257
+ - documenting implementation mechanics that callers should not need to know
258
+
259
+ ---
260
+
261
+ ## Naming, Consistency, and Obviousness
262
+
263
+ 1. Names must reveal the abstraction, not the internal mechanism.
264
+ 2. Use consistent names, argument order, error behavior, and interface conventions for related operations.
265
+ 3. Prefer obvious code where a reader can infer behavior from local structure and names.
266
+ 4. Remove non-obvious behavior unless it is hidden behind a clear contract.
267
+ 5. When code surprises a reader, treat that as complexity even if the code is short.
268
+
269
+ ---
270
+
271
+ ## Performance, Trends, and Tests
272
+
273
+ 1. Do not sacrifice module depth or information hiding for performance without evidence that the tradeoff matters.
274
+ 2. When performance matters, hide optimization details behind stable interfaces so callers do not inherit the complexity.
275
+ 3. Prefer measurements and targeted changes over broad speculative tuning.
276
+ 4. Do not adopt a trend, paradigm, pattern, or framework unless it reduces complexity in this codebase.
277
+ 5. Use tests to preserve behavior while changing structure, but do not let test convenience force shallow or leaky interfaces.
278
+
279
+ ---
280
+
281
+ ## Review Rules
282
+
283
+ When reviewing code, actively look for:
284
+ - shallow modules
285
+ - pass-through layers
286
+ - interfaces that expose implementation detail
287
+ - excessive flags or mode parameters
288
+ - scattered special cases
289
+ - cognitive load caused by too many interacting modules
290
+ - hidden temporal constraints
291
+ - complexity pushed to callers
292
+ - comments that explain what should be encoded in structure
293
+ - tactical patches that increase future difficulty
294
+
295
+ ---
296
+
297
+ ## Forbidden Patterns
298
+
299
+ ### Shallow Decomposition
300
+ - splitting code into many tiny units that do not reduce understanding cost
301
+ - wrappers and facades that add names but not simplification
302
+
303
+ ### Interface Leakage
304
+ - APIs that expose storage, transport, or caching mechanics to ordinary callers
305
+ - method sequences that require callers to know internal workflow
306
+
307
+ ### Tactical Complexity Debt
308
+ - adding one more flag, callback, or conditional instead of improving the abstraction
309
+ - fixing the local symptom while making the design harder overall
310
+
311
+ ### Complexity Spread
312
+ - repeating the same special handling in many places
313
+ - making all callers responsible for one module's awkwardness
314
+
315
+ ---
316
+
317
+ ## Code Generation Rules
318
+
319
+ When generating code, default to:
320
+ 1. identify the concept that deserves a module boundary
321
+ 2. design the narrowest strong interface around that concept
322
+ 3. hide volatile or complicated details inside
323
+ 4. simplify all callers, even if implementation grows slightly
324
+ 5. isolate special cases
325
+ 6. reduce the number of facts a reader must juggle at once
326
+
327
+ Avoid by default:
328
+ - pass-through layers
329
+ - needless tiny abstractions
330
+ - exposing internal data formats
331
+ - temporal APIs with fragile call sequences
332
+ - multiplying concepts without reducing complexity
333
+
334
+ ---
335
+
336
+ ## Testing Rules
337
+
338
+ 1. Test public behavior and interface contracts.
339
+ 2. Test hidden complexity through stable public APIs where possible.
340
+ 3. Add focused tests around isolated special cases.
341
+ 4. Avoid tests that force callers to know implementation detail if the abstraction promises otherwise.
342
+
343
+ ---
344
+
345
+ ## Review Checklist
346
+
347
+ Before finalizing any change, verify:
348
+ - Did this change reduce or increase cognitive load?
349
+ - Is the module deeper or shallower after the edit?
350
+ - Did we hide more complexity behind a stable interface?
351
+ - Did we reduce special-case handling at call sites?
352
+ - Did we remove an implementation detail from the public surface?
353
+ - Did we avoid a pass-through layer?
354
+ - Does the interface describe the abstraction rather than the mechanism?
355
+ - Did we improve future changeability, not just present convenience?
356
+
357
+ If any answer is no, revise before shipping.
358
+
359
+ ---
360
+
361
+ ## Final Instruction
362
+
363
+ When uncertain, prefer the design that:
364
+ 1. creates a deeper module
365
+ 2. hides more complexity
366
+ 3. reduces special cases
367
+ 4. lowers cognitive load for callers
368
+ 5. improves the abstraction instead of patching around it
369
+
370
+ Fight complexity directly.
@@ -0,0 +1,46 @@
1
+ # OBEY A Philosophy of Software Design by John Ousterhout
2
+
3
+ ## When to use
4
+
5
+ Use for module design, API changes, decomposition, refactoring, naming, comments, tests, performance work, and changes that feel awkward or spread complexity across files.
6
+
7
+ ## Primary bias to correct
8
+
9
+ Working code, small pieces, familiar patterns, flags, wrappers, and extra documentation do not make a design simple when they increase cognitive load or leak knowledge.
10
+
11
+ ## Decision rules
12
+
13
+ - Use reduced complexity as the primary success metric. Prefer the design that lowers cognitive load, change amplification, hidden dependencies, temporal coupling, and the number of facts a reader must hold at once.
14
+ - Treat design as continuous work. A first working patch is not done if it worsens future changeability; compare plausible alternatives for non-trivial interface, decomposition, or abstraction choices.
15
+ - Prefer deep modules: small, semantic interfaces that hide meaningful internal complexity. Reject pass-through services, thin library wrappers, helper modules, and tiny split-outs that add names without reducing reader burden.
16
+ - Design interfaces around what callers need to know, not how the implementation works. Avoid fragile staging, setup sequences, mode flags, configuration knobs, and arguments that expose internal choices.
17
+ - Hide volatile decisions, internal representations, storage shape, protocols, file formats, performance hacks, bookkeeping, normalization, and messy edge handling inside the module that owns the knowledge.
18
+ - Pull complexity downward when the lower module owns the detail. Prefer a slightly more complex implementation if it gives callers a simpler public contract and removes repeated reasoning from call sites.
19
+ - Choose generality at the right level. Avoid one-caller overfitting, vague speculative abstractions, and core paths polluted by rare edge cases; isolate special behavior with special-general decomposition.
20
+ - Combine or split by total complexity, not by size, runtime order, habit, or aesthetics. Keep related state, behavior, invariants, and design decisions together unless the new boundary is deeper and independently understandable.
21
+ - Reduce exception surface by changing interfaces or invariants where possible. Define away invalid states and awkward cases instead of making every caller repeat defensive ceremony.
22
+ - Use comments to reduce complexity: document interface contracts, invariants, hidden design decisions, rationale, and tricky implementation facts callers should not need to know. Do not narrate code or compensate for bad names, poor decomposition, or confusing flow.
23
+ - Treat names, consistency, and obviousness as design information. Names should reveal abstractions rather than mechanisms; related operations should share conventions; surprising code is complexity even when short.
24
+ - Use tests to protect behavior through public contracts and stable APIs, especially around hidden complexity and isolated special cases. Do not let test convenience force shallow or leaky interfaces.
25
+ - Add performance optimizations, trends, paradigms, patterns, or frameworks only when they reduce complexity in this codebase or evidence shows the tradeoff matters; hide optimization details behind stable interfaces.
26
+
27
+ ## Trigger rules
28
+
29
+ - When a feature feels awkward, one change spreads across files, or reviewers must reconstruct hidden dependencies, look for missing information hiding, shallow modules, temporal coupling, or complexity pushed to callers.
30
+ - When adding a module, layer, service, helper, wrapper, facade, pattern, option, callback, or argument, prove that it hides more complexity than it adds.
31
+ - When touching an API, check whether ordinary callers must know sequencing, representation, storage, transport, caching, protocol, file format, internal workflow, or too many setup steps.
32
+ - When adding a special case, flag, exception path, conditional, or exposed container, first ask whether the owning module can eliminate the invalid state, isolate the unusual behavior, or provide a stronger operation.
33
+ - When splitting, extracting, or introducing variables, check whether the new boundary or name captures meaning or only adds jumps, pass-through state, and visible intermediate steps.
34
+ - When code is organized as `prepare/process/finalize`, staged objects, or other execution-order phases, verify that temporal structure is the real concept; otherwise reorganize around stable responsibilities.
35
+ - When naming is vague, mechanism-focused, inconsistent, or surprising, reconsider the abstraction boundary instead of accepting a near miss.
36
+ - When comments get long, duplicate code, justify a confusing interface, or explain usage by exposing internals, redesign the abstraction or move the missing contract to the interface.
37
+ - When optimizing performance, measure first and hide the optimization; do not sacrifice module depth or information hiding without evidence that the tradeoff matters.
38
+ - When testing or reviewing, focus on public behavior, interface contracts, hidden complexity through stable APIs, and special cases isolated behind the abstraction.
39
+
40
+ ## Final checklist
41
+
42
+ - Did the change reduce the effort required to understand, modify, verify, and extend the system?
43
+ - Does every interface element, wrapper, layer, helper, option, and name hide enough complexity to justify its existence?
44
+ - Are important decisions localized, dependencies visible, caller-needed constraints documented, and mutable internals protected?
45
+ - Did common cases become automatic while rare controls, special cases, performance tricks, and exception details stayed out of the common path?
46
+ - Are names precise and consistent, comments current and non-duplicative, and conventions followed unless new information justified changing them?