@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,404 @@
1
+ # OBEY Patterns of Enterprise Application Architecture by Martin Fowler
2
+
3
+ ## Purpose
4
+
5
+ This repository follows the practical style of **Patterns of Enterprise Application Architecture**:
6
+ structure enterprise software around clear responsibilities for domain logic, persistence, transaction boundaries, integration, and presentation.
7
+
8
+ All code generation, edits, and reviews must optimize for:
9
+ - explicit separation of concerns
10
+ - predictable business logic placement
11
+ - appropriate enterprise patterns instead of accidental coupling
12
+ - manageable persistence and transaction boundaries
13
+ - clear mapping between in-memory objects and external systems
14
+ - code that is maintainable under real enterprise constraints
15
+
16
+ This file is a binding engineering policy: `MUST` is binding, `SHOULD` is a strong default, and `MUST NOT` is forbidden.
17
+
18
+ ---
19
+
20
+ ## Primary Directive
21
+
22
+ Enterprise software is not improved by inventing architecture from scratch for every feature.
23
+ Prefer a small number of well-understood structural patterns, applied deliberately.
24
+
25
+ When uncertain, choose the design that makes these responsibilities explicit:
26
+ - presentation and transport
27
+ - application workflow
28
+ - domain logic
29
+ - data source interaction
30
+ - transaction management
31
+ - concurrency control
32
+ - integration boundaries
33
+
34
+ Do not let one class or layer own all of them.
35
+
36
+ ---
37
+
38
+ ## Architectural Baseline
39
+
40
+ ### Layering
41
+ Use layering as a default organizing principle:
42
+ 1. presentation and delivery
43
+ 2. application coordination
44
+ 3. domain logic
45
+ 4. data source and integration access
46
+
47
+ Rules (MUST unless marked SHOULD or MUST NOT):
48
+ - upper layers may depend on lower ones
49
+ - lower layers must not reach into presentation concerns
50
+ - each layer must earn its existence by reducing coupling or clarifying responsibility
51
+
52
+ Anti-patterns (MUST NOT):
53
+ - controllers reaching directly into SQL and transaction details
54
+ - domain logic embedded in views or handlers
55
+ - repositories returning HTTP-shaped DTOs
56
+ - fake layers that only pass calls through
57
+
58
+ ---
59
+
60
+ ## Choosing the Business Logic Pattern
61
+
62
+ ### Transaction Script
63
+ Use when:
64
+ - logic is simple
65
+ - each request or use case is mostly independent
66
+ - rich domain modeling is unnecessary
67
+
68
+ Rules (MUST unless marked SHOULD or MUST NOT):
69
+ - scripts must remain short and use-case focused
70
+ - do not let transaction scripts become dumping grounds for all business logic
71
+ - if duplication, lifecycle, or invariant complexity grows, escalate to a stronger pattern
72
+
73
+ ### Table Module
74
+ Use when:
75
+ - logic is naturally organized around tabular data sets
76
+ - calculations are set-oriented
77
+ - object identity is not the key organizing force
78
+
79
+ Rules (MUST unless marked SHOULD or MUST NOT):
80
+ - keep behavior centered on the table abstraction
81
+ - do not fake entities if the real model is fundamentally tabular
82
+ - isolate tabular logic from presentation and transport
83
+
84
+ ### Domain Model
85
+ Use when:
86
+ - domain complexity is significant
87
+ - business rules, invariants, and lifecycles matter
88
+ - identity, collaboration, and behavior belong in the model
89
+
90
+ Rules (MUST unless marked SHOULD or MUST NOT):
91
+ - rich domain logic belongs in model objects
92
+ - keep application coordination separate from domain decisions
93
+ - avoid anemic models in behavior-rich domains
94
+
95
+ ---
96
+
97
+ ## Application Workflow Rules
98
+
99
+ ### Service Layer
100
+ Use a service layer to define application operations.
101
+
102
+ Rules (MUST unless marked SHOULD or MUST NOT):
103
+ 1. Application services coordinate use cases.
104
+ 2. They define transaction boundaries and orchestration.
105
+ 3. They must not absorb all domain logic by default.
106
+ 4. They should expose an application-oriented API, not UI mechanics.
107
+
108
+ ### Remote Facade
109
+ Use when:
110
+ - the boundary is remote
111
+ - coarse-grained APIs reduce chatty calls
112
+ - transport shape differs from internal design
113
+
114
+ Rules (MUST unless marked SHOULD or MUST NOT):
115
+ - expose coarse remote operations
116
+ - translate between remote contracts and internal model
117
+ - keep remote transport concerns at the boundary
118
+
119
+ ### Data Transfer Object
120
+ Use when:
121
+ - data crosses process or layer boundaries
122
+ - batching values reduces remote or serialization cost
123
+ - translation protects the internal model
124
+
125
+ Rules (MUST unless marked SHOULD or MUST NOT):
126
+ - DTOs are transport structures, not domain models
127
+ - keep mapping explicit
128
+ - do not move business behavior into DTOs
129
+
130
+ ---
131
+
132
+ ## Persistence Pattern Rules
133
+
134
+ ### Repository
135
+ Use repositories to present a collection-like interface over domain object access.
136
+
137
+ Rules (MUST unless marked SHOULD or MUST NOT):
138
+ 1. Repositories must speak in domain terms.
139
+ 2. Repository interfaces should reflect domain access needs rather than table shape.
140
+ 3. Repository implementations hide query, mapping, and storage details.
141
+ 4. Repositories must not become generic “everything” gateways.
142
+
143
+ ### Data Mapper
144
+ Use when:
145
+ - the domain model should remain decoupled from the database structure
146
+ - object-relational mismatch is real
147
+ - persistence logic deserves isolation
148
+
149
+ Rules (MUST unless marked SHOULD or MUST NOT):
150
+ - mapping code belongs outside the domain objects
151
+ - do not force domain objects to know SQL, record formats, or mapping mechanics
152
+ - keep mapping explicit and testable
153
+
154
+ ### Row Data Gateway
155
+ Use when behavior is simple and record-oriented.
156
+
157
+ ### Table Data Gateway
158
+ Use when operations are naturally table-oriented and one table interface can clearly centralize access.
159
+
160
+ ### Active Record
161
+ Use only when domain logic is simple and persistence coupling is acceptable.
162
+ Do not default to Active Record for complex domains.
163
+
164
+ ---
165
+
166
+ ## Identity, Caching, and Unit-of-Work Rules
167
+
168
+ ### Identity Map
169
+ - preserve one in-memory representation per identity per scope where needed
170
+ - avoid duplicate object instances fighting each other inside one logical unit of work
171
+
172
+ ### Unit of Work
173
+ - make transactional write coordination explicit
174
+ - commit work as one logical unit
175
+ - keep unit-of-work scope understandable
176
+
177
+ ### Lazy Load
178
+ - use deliberately, not everywhere
179
+ - know where lazy loading may trigger remote/database chatter
180
+ - avoid lazy loading surprises in loops and serialization paths
181
+
182
+ Anti-patterns (MUST NOT):
183
+ - invisible N+1 behavior everywhere
184
+ - hidden auto-persistence with surprising write timing
185
+ - saving each object ad hoc from random callers
186
+
187
+ ---
188
+
189
+ ## Object-Relational Mapping Pattern Index
190
+
191
+ - USE Identity Field when in-memory objects need stable database identity; keep identity mapping explicit.
192
+ - USE Foreign Key Mapping when object references map to relational keys; avoid hiding expensive joins behind innocent traversal.
193
+ - USE Association Table Mapping when many-to-many relationships need a separate relational table.
194
+ - USE Dependent Mapping when child objects have no independent database identity outside their owner.
195
+ - USE Embedded Value when a small value object can live inside the owning row without independent lifecycle.
196
+ - USE Serialized LOB only when querying inside the value is not required and serialization versioning is controlled.
197
+ - USE Single Table Inheritance when one table with nullable columns is simpler than multiple joins.
198
+ - USE Class Table Inheritance when normalized subtype data is worth join complexity.
199
+ - USE Concrete Table Inheritance when each concrete type can own its table without excessive duplication.
200
+ - USE Inheritance Mappers to isolate inheritance persistence decisions from domain logic.
201
+ - USE Metadata Mapping when mapping rules are regular enough to centralize safely; avoid it when metadata obscures exceptional behavior.
202
+ - USE Query Object when query construction needs a composable object model instead of scattered SQL strings.
203
+
204
+ ---
205
+
206
+ ## Concurrency and Transaction Rules
207
+
208
+ ### Optimistic Offline Lock
209
+ Use when conflicts are possible but uncommon.
210
+
211
+ Rules (MUST unless marked SHOULD or MUST NOT):
212
+ - detect conflicting concurrent updates
213
+ - fail safely and explicitly
214
+ - surface conflict resolution or merge semantics intentionally
215
+
216
+ ### Pessimistic Locking
217
+ Use only when contention is expected and the cost is justified.
218
+
219
+ ### Transaction Boundaries
220
+ 1. Transaction boundaries must be explicit in application workflow.
221
+ 2. Avoid transactions that span remote calls when possible.
222
+ 3. Keep transactions short.
223
+ 4. Do not bury transaction ownership deep in helper classes.
224
+
225
+ ### Additional Offline Concurrency Patterns
226
+ - USE Coarse-Grained Lock when related objects must be locked together to preserve a user-level edit.
227
+ - USE Implicit Lock only when lock acquisition is reliably hidden without making concurrency invisible to maintainers.
228
+ - Do not let implicit locking make transaction ownership or contention impossible to diagnose.
229
+
230
+ ---
231
+
232
+ ## Presentation Layer Rules
233
+
234
+ 1. Presentation code handles input, rendering, and transport concerns.
235
+ 2. Business rules must not live in controllers or views.
236
+ 3. Presentation models may differ from domain models.
237
+ 4. Formatting, pagination, and UI interaction state belong outside domain logic.
238
+
239
+ Choose Page Controller vs Front Controller pragmatically, but keep routing concerns out of business logic.
240
+
241
+ ### Presentation Pattern Index
242
+ - USE Model View Controller to separate domain model, view, and controller responsibilities.
243
+ - USE Page Controller when each page/action can be handled independently.
244
+ - USE Front Controller when centralized request handling, authentication, routing, or dispatch is valuable.
245
+ - USE Template View when server-side templates clearly express the response.
246
+ - USE Transform View when transforming data into output is clearer than embedding logic in templates.
247
+ - USE Two Step View when shared presentation structure should be separated from page-specific content.
248
+ - USE Application Controller when flow and navigation decisions need a dedicated coordinator.
249
+
250
+ ---
251
+
252
+ ## Offline and Integration Rules
253
+
254
+ 1. External systems must be accessed through clear boundaries.
255
+ 2. Translate partner formats into internal concepts.
256
+ 3. Integration events/messages are not domain objects.
257
+ 4. Do not allow integration convenience to dominate internal design.
258
+
259
+ Anti-patterns (MUST NOT):
260
+ - internal code shaped around partner API payloads
261
+ - direct vendor DTOs used across the application
262
+ - business logic embedded in serialization code
263
+
264
+ ---
265
+
266
+ ## Session State and Base Pattern Index
267
+
268
+ - USE Client Session State only when client storage is acceptable and integrity/security implications are handled.
269
+ - USE Server Session State when server-managed session data is needed and scaling/cleanup costs are explicit.
270
+ - USE Database Session State when session durability or server-farm sharing outweighs database load.
271
+ - USE Gateway to isolate access to an external resource or subsystem.
272
+ - USE Mapper to move data between objects or layers while keeping both sides independent.
273
+ - USE Layer Supertype only when shared layer behavior is real and stable.
274
+ - USE Separated Interface when clients should depend on an interface in a different package from implementation details.
275
+ - USE Registry sparingly for well-known objects; avoid turning it into global hidden dependency.
276
+ - USE Value Object for small values where equality by value and immutability simplify code.
277
+ - USE Money for currency amounts so rounding, currency, and arithmetic rules stay explicit.
278
+ - USE Special Case to replace repeated null or exceptional handling with a named object.
279
+ - USE Plugin when implementations must be selected or extended without changing core code.
280
+ - USE Service Stub to test or run without a real remote service.
281
+ - USE Record Set when tabular data is the natural interchange shape and object behavior is not needed.
282
+
283
+ ---
284
+
285
+ ## Distribution Rules
286
+
287
+ 1. Do not distribute objects or services remotely by default.
288
+ 2. Remote boundaries must be coarse-grained.
289
+ 3. Separate local object design from remote contract design.
290
+ 4. Budget explicitly for latency, serialization, versioning, and partial failure.
291
+
292
+ Anti-patterns (MUST NOT):
293
+ - chatty remote object interfaces
294
+ - assuming local method-call semantics over a network
295
+ - leaking domain internals through remote endpoints
296
+
297
+ ---
298
+
299
+ ## Code Generation Rules
300
+
301
+ When generating code, apply this order:
302
+ 1. identify the business logic pattern that actually fits the complexity
303
+ 2. place use-case coordination in an application/service layer
304
+ 3. place domain decisions in the domain model when the domain is rich
305
+ 4. place persistence behind repositories, mappers, or gateways
306
+ 5. define transaction boundaries explicitly
307
+ 6. define DTOs or remote facades only at boundaries
308
+ 7. keep presentation and transport concerns at the edge
309
+
310
+ Default choices:
311
+ - simple CRUD -> transaction script or simple service layer
312
+ - rich invariants -> domain model + repository + mapper
313
+ - table-oriented calculations -> table module or table gateway
314
+ - remote boundary -> remote facade + DTO
315
+
316
+ Avoid by default:
317
+ - using domain model everywhere regardless of complexity
318
+ - generic repository for everything
319
+ - exposing persistence models directly to callers
320
+ - placing transactions, validation, rendering, and SQL in one class
321
+
322
+ ---
323
+
324
+ ## Review Rules
325
+
326
+ When reviewing code, actively look for:
327
+ - domain logic in controllers or views
328
+ - repositories returning transport shapes
329
+ - lower layers knowing presentation details
330
+ - trivial CRUD wrapped in excessive modeling
331
+ - complex rules trapped in transaction scripts
332
+ - SQL spread through business code
333
+ - missing transaction boundaries
334
+ - hidden unit-of-work behavior
335
+ - accidental N+1 loading
336
+ - chatty remote APIs
337
+ - no translation between internal and remote models
338
+
339
+ ---
340
+
341
+ ## Forbidden Patterns
342
+
343
+ ### Layering Theater
344
+ - five layers that only forward method calls
345
+
346
+ ### Generic Repository Everywhere
347
+ - one CRUD abstraction for all domain and data access
348
+ - repository APIs shaped by tables instead of use cases
349
+
350
+ ### ORM-Driven Everything
351
+ - all design decisions dictated by ORM convenience
352
+ - aggregates, services, and DTOs collapsed into one persistence model
353
+
354
+ ### Controller-Centric Enterprise App
355
+ - request handlers coordinating transactions, SQL, domain rules, and external calls
356
+
357
+ ### Distributed Object Fantasy
358
+ - pretending network calls are normal method calls
359
+
360
+ ### Unclear Transaction Ownership
361
+ - random save calls across layers
362
+ - no clear transaction owner
363
+ - long-running workflows treated as one immediate transaction
364
+
365
+ ---
366
+
367
+ ## Testing Rules
368
+
369
+ 1. Test domain logic independently from presentation and persistence when possible.
370
+ 2. Test repositories, mappers, and gateways separately as data-access infrastructure.
371
+ 3. Test service/application workflows for transaction and orchestration behavior.
372
+ 4. Test concurrency behaviors where optimistic or pessimistic locking matters.
373
+ 5. Test DTO and remote facade mapping at the boundaries.
374
+
375
+ ---
376
+
377
+ ## Review Checklist
378
+
379
+ Before finalizing any change, verify:
380
+ - Did we choose the right business logic pattern for the actual complexity?
381
+ - Are presentation, workflow, domain logic, and persistence responsibilities distinct?
382
+ - Is transaction ownership explicit?
383
+ - Are repositories or gateways shaped by use cases or aggregates rather than raw tables?
384
+ - Is mapping isolated from domain logic?
385
+ - Are remote boundaries coarse-grained and translated explicitly?
386
+ - Did we avoid generic repository overreach?
387
+ - Did we avoid controller-centric design?
388
+ - Did we avoid layering theater?
389
+ - Did we keep concurrency and loading assumptions visible?
390
+
391
+ If any answer is no, revise before shipping.
392
+
393
+ ---
394
+
395
+ ## Final Instruction
396
+
397
+ When uncertain, choose the smallest set of enterprise patterns that makes:
398
+ 1. business logic placement obvious
399
+ 2. persistence and mapping explicit
400
+ 3. transaction boundaries clear
401
+ 4. remote boundaries coarse and safe
402
+ 5. the application easier to evolve under real enterprise constraints
403
+
404
+ Reject fashionable complexity and accidental coupling alike.
@@ -0,0 +1,54 @@
1
+ # OBEY Patterns of Enterprise Application Architecture by Martin Fowler
2
+
3
+ ## When to use
4
+
5
+ Use when designing or reviewing enterprise application code that crosses presentation, application workflow, domain logic, persistence, transactions, concurrency, integration, session state, or remote boundaries.
6
+
7
+ ## Primary bias to correct
8
+
9
+ Enterprise applications are not improved by inventing architecture for every feature or by letting the framework, ORM, database schema, or transport shape choose the design. Use a small set of well-understood patterns to make responsibilities and boundaries explicit.
10
+
11
+ ## Decision rules
12
+
13
+ - Make responsibility ownership explicit before naming patterns: presentation and transport, application workflow, domain logic, data source interaction, transaction management, concurrency control, and integration boundaries must not collapse into one class or layer.
14
+ - Use layering as the default organizing principle, but every layer must earn its cost by reducing coupling or clarifying responsibility; forbid lower layers from reaching into presentation concerns and reject pass-through layering theater.
15
+ - Choose the business logic pattern by force: Transaction Script for short independent simple flows, Table Module for table-centered set logic, and Domain Model for significant rules, invariants, identity, lifecycle, or collaboration.
16
+ - Let Transaction Scripts stay use-case focused, Table Modules stay honestly tabular, and Domain Models own rich behavior; escalate when duplication, lifecycle, or invariant complexity grows.
17
+ - Use a Service Layer to define application operations, coordinate use cases, own transaction boundaries and orchestration, expose an application-oriented API, and avoid absorbing all domain logic by default.
18
+ - At remote or cross-layer boundaries, use Remote Facade and DTOs to make coarse operations, batching, translation, and transport shape explicit; DTOs are transport structures, not domain models.
19
+ - Choose persistence patterns deliberately: repositories speak domain terms and hide query/mapping/storage details, Data Mappers keep SQL and record formats outside domain objects, gateways centralize record/table access, and Active Record is only for simple domains where persistence coupling is acceptable.
20
+ - Keep identity, write coordination, and loading behavior visible: use Identity Map for one object per identity per scope, Unit of Work for one logical transactional commit, and Lazy Load only where hidden database or remote chatter will not surprise loops or serializers.
21
+ - Choose object-relational mappings by identity, lifecycle, query needs, schema shape, and evolution cost; keep identity fields, foreign keys, association tables, dependent objects, embedded values, serialized values, inheritance mapping, metadata mapping, and query objects explicit rather than accidental.
22
+ - Design concurrency and transactions in the application workflow: optimistic locks detect conflicts and surface merge semantics, pessimistic locks require justified contention, transactions stay short, remote calls usually sit outside transactions, and helpers must not hide transaction ownership.
23
+ - Use coarse-grained and implicit offline locks only when they preserve a user-level edit without making ownership, contention, or stale-lock cleanup impossible to diagnose.
24
+ - Keep presentation code focused on input, rendering, routing, formatting, pagination, UI state, and transport; business rules stay out of controllers, views, templates, and presentation models.
25
+ - Access external systems through boundaries, translate partner formats into internal concepts, treat integration events and messages as boundary data, and do not let vendor payloads or serialization code shape internal domain design.
26
+ - Choose session state deliberately: client, server, or database session storage must account for integrity, security, scaling, cleanup, durability, server-farm sharing, and database load.
27
+ - Use base patterns only for concrete pressure: Gateway for external resources, Mapper for independent sides, Layer Supertype for real shared behavior, Separated Interface for dependency breaks, Registry for controlled well-known objects, Value Object and Money for value semantics, Special Case for repeated null/default behavior, Plugin for runtime extension, Service Stub for remote-service tests, and Record Set when tabular interchange is natural.
28
+ - Do not distribute objects or services by default; when distribution is required, separate local object design from the remote contract and budget latency, serialization, versioning, and partial failure.
29
+ - Generate code in this order: choose the business logic pattern, place use-case coordination in application services, put rich domain decisions in the domain model, hide persistence behind repositories/mappers/gateways, define transactions explicitly, put DTOs or facades only at boundaries, and keep presentation/transport at the edge.
30
+ - Test each responsibility at the level where it owns behavior: domain logic apart from UI and persistence, repositories/mappers/gateways as data infrastructure, services for workflow and transactions, locking where concurrency matters, and DTO/facade mapping at boundaries.
31
+
32
+ ## Trigger rules
33
+
34
+ - If domain behavior appears in controllers, views, handlers, SQL scripts, triggers, DTOs, framework glue, serialization code, or vendor payload adapters, move it to the owning layer or justify the exception explicitly.
35
+ - If one class or layer coordinates rendering, validation, SQL, transactions, domain rules, and external calls, split by responsibility before adding another pattern.
36
+ - If a Transaction Script accumulates duplicated decisions, invariants, or lifecycle rules, revisit Domain Model and the supporting persistence pattern.
37
+ - If a model is table-shaped in a behavior-rich domain, a repository is generic CRUD, or a service only forwards to persistence, check whether the ORM or database schema has taken over the design.
38
+ - If SQL, mapping, transaction ownership, lock acquisition, saves, or external resource access is scattered across callers, introduce the smallest repository, mapper, gateway, Unit of Work, service boundary, or policy that centralizes the rule.
39
+ - If lazy loading, duplicate in-memory identities, hidden auto-persistence, N+1 behavior, or ad hoc saves can happen inside one logical work scope, define identity scope, Unit of Work, and loading behavior before continuing.
40
+ - If concurrency conflicts, stale locks, user-level edits, or long-running workflows matter, choose explicit optimistic, pessimistic, coarse-grained, or implicit locking semantics instead of relying on informal developer discipline.
41
+ - If a remote API looks like local object collaboration, leaks domain internals, or requires many calls per user action, redesign it as a coarse use-case contract with DTO translation.
42
+ - If session state has unclear owner, lifetime, storage location, security, scaling, failover, durability, or cleanup behavior, choose the session-state pattern before adding features.
43
+ - If a layer exists only to forward calls, a generic repository covers everything, an ORM model doubles as aggregate/service/DTO, or a controller owns the enterprise workflow, treat it as a forbidden-pattern review blocker.
44
+
45
+ ## Final checklist
46
+
47
+ - Are presentation, workflow, domain, persistence, transaction, concurrency, integration, session, and distribution responsibilities separated intentionally?
48
+ - Does the business logic pattern match actual complexity rather than habit or framework shape?
49
+ - Are repositories, mappers, gateways, Active Record, Unit of Work, Identity Map, and Lazy Load used only where their forces fit?
50
+ - Is transaction ownership explicit, short, and kept out of hidden helpers or remote-call spans?
51
+ - Are concurrency conflicts, offline locks, identity scope, and loading behavior visible?
52
+ - Are remote and integration boundaries coarse, translated, version-aware, and failure-aware?
53
+ - Is session state owned, protected, scalable, durable enough, and cleaned up?
54
+ - Are tests aligned to the responsibility that owns each behavior?
@@ -0,0 +1,35 @@
1
+ # OBEY Patterns of Enterprise Application Architecture by Martin Fowler
2
+
3
+ ## When to use
4
+
5
+ Use as a compact always-on compass for enterprise application pattern choices.
6
+
7
+ ## Primary bias to correct
8
+
9
+ Pattern reuse is not pattern choice. Make responsibilities, persistence, transactions, and remote boundaries explicit before naming a pattern.
10
+
11
+ ## Decision rules
12
+
13
+ - Keep presentation/transport, application workflow, domain logic, data source interaction, transaction management, concurrency control, and integration boundaries logically separate.
14
+ - Choose the business logic pattern by complexity: Transaction Script for simple independent flows, Table Module for table-centered set logic, and Domain Model for rich behavior, invariants, identity, or lifecycle.
15
+ - Use Service Layer for use-case coordination and transaction orchestration without turning it into the default home for all domain behavior.
16
+ - Match persistence to coupling pressure: Repository/Data Mapper for domain separation, Gateway for record or table access, and Active Record only for simple persistence-coupled domains.
17
+ - Make Unit of Work, Identity Map, Lazy Load, transaction boundaries, and lock semantics visible before trusting ORM behavior.
18
+ - Keep presentation, DTOs, integration messages, vendor payloads, and serialization code free of business behavior.
19
+ - Treat remote boundaries as expensive and failure-prone: use coarse Remote Facade operations, DTO translation, explicit versioning, and partial-failure handling.
20
+ - Use session-state and base patterns only for concrete pressure; avoid fake layers, generic repositories, ORM-driven design, controller-centric workflows, and distributed-object illusions.
21
+
22
+ ## Trigger rules
23
+
24
+ - If one class or layer owns UI, workflow, domain rules, SQL, transactions, and external calls, split responsibility before adding more patterns.
25
+ - If a simple Transaction Script grows duplication, invariants, or lifecycle decisions, revisit Domain Model and persistence pattern together.
26
+ - If repositories are table-shaped CRUD, models mirror tables in behavior-rich areas, or services only forward calls, check whether the database or ORM has captured the design.
27
+ - If lazy loading, duplicate identities, hidden writes, N+1 behavior, ad hoc saves, or unclear locks appear, define identity scope, Unit of Work, loading, and concurrency semantics explicitly.
28
+ - If a remote API is chatty, object-shaped, or leaks domain internals, redesign it as a coarse use-case boundary with DTO translation.
29
+
30
+ ## Final checklist
31
+
32
+ - Right business logic and persistence pattern for actual complexity?
33
+ - Explicit layer, transaction, identity, loading, lock, session, and integration ownership?
34
+ - Business rules kept out of UI, DTOs, integration, and serialization?
35
+ - Remote boundary coarse, translated, version-aware, and failure-aware?
@@ -0,0 +1,124 @@
1
+ ---
2
+ name: ponytail
3
+ description: >
4
+ Forces the laziest solution that actually works, simplest, shortest, most
5
+ minimal. Channels a senior dev who has seen everything: question whether the
6
+ task needs to exist at all (YAGNI), reach for the standard library before
7
+ custom code, native platform features before dependencies, one line before
8
+ fifty. Supports intensity levels: lite, full (default), ultra. Use on ANY
9
+ coding task: writing, adding, refactoring, fixing, reviewing, or designing
10
+ code, and choosing libraries or dependencies. Also use whenever the user
11
+ says "ponytail", "be lazy", "lazy mode", "simplest solution", "minimal
12
+ solution", "yagni", "do less", or "shortest path", or complains about
13
+ over-engineering, bloat, boilerplate, or unnecessary dependencies. Do NOT
14
+ use for non-coding requests (general knowledge, prose, translation,
15
+ summaries, recipes).
16
+ metadata:
17
+ argument-hint: "[lite|full|ultra]"
18
+ license: MIT
19
+ ---
20
+
21
+ # Ponytail
22
+
23
+ You are a lazy senior developer. Lazy means efficient, not careless. You have
24
+ seen every over-engineered codebase and been paged at 3am for one. The best
25
+ code is the code never written.
26
+
27
+ ## Persistence
28
+
29
+ ACTIVE EVERY RESPONSE. No drift back to over-building. Still active if
30
+ unsure. Off only: "stop ponytail" / "normal mode". Default: **full**.
31
+ Switch: `/ponytail lite|full|ultra`.
32
+
33
+ ## The ladder
34
+
35
+ Stop at the first rung that holds:
36
+
37
+ 1. **Does this need to exist at all?** Speculative need = skip it, say so in one line. (YAGNI)
38
+ 2. **Already in this codebase?** A helper, util, type, or pattern that already lives here → reuse it. Look before you write; re-implementing what's a few files over is the most common slop.
39
+ 3. **Stdlib does it?** Use it.
40
+ 4. **Native platform feature covers it?** `<input type="date">` over a picker lib, CSS over JS, DB constraint over app code.
41
+ 5. **Already-installed dependency solves it?** Use it. Never add a new one for what a few lines can do.
42
+ 6. **Can it be one line?** One line.
43
+ 7. **Only then:** the minimum code that works.
44
+
45
+ The ladder is a reflex, not a research project - but it runs *after* you
46
+ understand the problem, not instead of it. Read the task and the code it
47
+ touches first, trace the real flow end to end, then climb. Two rungs work →
48
+ take the higher one and move on. The first lazy solution that works is the
49
+ right one - once you actually know what the change has to touch.
50
+
51
+ **Bug fix = root cause, not symptom.** A report names a symptom. Before you
52
+ edit, grep every caller of the function you're about to touch. The lazy fix IS
53
+ the root-cause fix: one guard in the shared function is a smaller diff than a
54
+ guard in every caller - and patching only the path the ticket names leaves
55
+ every sibling caller still broken. Fix it once, where all callers route through.
56
+
57
+ ## Rules
58
+
59
+ - No unrequested abstractions: no interface with one implementation, no factory for one product, no config for a value that never changes.
60
+ - No boilerplate, no scaffolding "for later", later can scaffold for itself.
61
+ - Deletion over addition. Boring over clever, clever is what someone decodes at 3am.
62
+ - Fewest files possible. Shortest working diff wins - but only once you understand the problem. The smallest change in the wrong place isn't lazy, it's a second bug.
63
+ - Complex request? Ship the lazy version and question it in the same response, "Did X; Y covers it. Need full X? Say so." Never stall on an answer you can default.
64
+ - Two stdlib options, same size? Take the one that's correct on edge cases. Lazy means writing less code, not picking the flimsier algorithm.
65
+ - Mark deliberate simplifications that cut a real corner with a known ceiling (global lock, O(n²) scan, naive heuristic) with a `ponytail:` comment naming the ceiling and upgrade path (`# ponytail: global lock, per-account locks if throughput matters`).
66
+
67
+ ## Output
68
+
69
+ Code first. Then at most three short lines: what was skipped, when to add it.
70
+ No essays, no feature tours, no design notes. If the explanation is longer
71
+ than the code, delete the explanation, every paragraph defending a
72
+ simplification is complexity smuggled back in as prose. Explanation the user
73
+ explicitly asked for (a report, a walkthrough, per-phase notes) is not debt,
74
+ give it in full, the rule is only against unrequested prose.
75
+
76
+ Pattern: `[code] → skipped: [X], add when [Y].`
77
+
78
+ ## Intensity
79
+
80
+ | Level | What change |
81
+ |-------|------------|
82
+ | **lite** | Build what's asked, but name the lazier alternative in one line. User picks. |
83
+ | **full** | The ladder enforced. Stdlib and native first. Shortest diff, shortest explanation. Default. |
84
+ | **ultra** | YAGNI extremist. Deletion before addition. Ship the one-liner and challenge the rest of the requirement in the same breath. |
85
+
86
+ Example: "Add a cache for these API responses."
87
+ - lite: "Done, cache added. FYI: `functools.lru_cache` covers this in one line if you'd rather not own a cache class."
88
+ - full: "`@lru_cache(maxsize=1000)` on the fetch function. Skipped custom cache class, add when lru_cache measurably falls short."
89
+ - ultra: "No cache until a profiler says so. When it does: `@lru_cache`. A hand-rolled TTL cache class is a bug farm with a hit rate."
90
+
91
+ ## When NOT to be lazy
92
+
93
+ Never simplify away: input validation at trust boundaries, error handling
94
+ that prevents data loss, security measures, accessibility basics, anything
95
+ explicitly requested. User insists on the full version → build it, no
96
+ re-arguing.
97
+
98
+ Never lazy about understanding the problem. The ladder shortens the
99
+ solution, never the reading. Trace the whole thing first - every file the
100
+ change touches, the actual flow - before picking a rung. Laziness that skips
101
+ comprehension to ship a small diff is the dangerous kind: it dresses up as
102
+ efficiency and ships a confident wrong fix. Read fully, then be lazy.
103
+
104
+ Hardware is never the ideal on paper: a real clock drifts, a real sensor
105
+ reads off, a PCA9685 runs a few percent fast. Leave the calibration knob, not
106
+ just less code, the physical world needs tuning a minimal model can't see.
107
+
108
+ Lazy code without its check is unfinished. Non-trivial logic (a branch, a
109
+ loop, a parser, a money/security path) leaves ONE runnable check behind, the
110
+ smallest thing that fails if the logic breaks: an `assert`-based
111
+ `demo()`/`__main__` self-check or one small `test_*.py`. No frameworks, no
112
+ fixtures, no per-function suites unless asked. Trivial one-liners need no
113
+ test, YAGNI applies to tests too.
114
+
115
+ ## Boundaries
116
+
117
+ Ponytail governs what you build, not how you talk (pair with Caveman for
118
+ terse prose). "stop ponytail" / "normal mode": revert. Level persists until
119
+ changed or session end.
120
+
121
+ The shortest path to done is the right path.
122
+
123
+
124
+ Read project AGENTS.md for shared workflow, scope, and evidence policy.
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: ponytail-audit
3
+ description: >
4
+ Whole-repo audit for over-engineering. Like ponytail-review, but scans the
5
+ entire codebase instead of a diff: a ranked list of what to delete, simplify,
6
+ or replace with stdlib/native equivalents. Use when the user says "audit this
7
+ codebase", "audit for over-engineering", "what can I delete from this repo",
8
+ "find bloat", "ponytail-audit", or "/ponytail-audit". One-shot report, does
9
+ not apply fixes.
10
+ license: MIT
11
+ ---
12
+
13
+ ponytail-review, repo-wide. Scan the whole tree instead of a diff. Rank
14
+ findings biggest cut first.
15
+
16
+ ## Tags
17
+
18
+ Same as ponytail-review:
19
+
20
+ - `delete:` dead code, unused flexibility, speculative feature. Replacement: nothing.
21
+ - `stdlib:` hand-rolled thing the standard library ships. Name the function.
22
+ - `native:` dependency or code doing what the platform already does. Name the feature.
23
+ - `yagni:` abstraction with one implementation, config nobody sets, layer with one caller.
24
+ - `shrink:` same logic, fewer lines. Show the shorter form.
25
+
26
+ ## Hunt
27
+
28
+ Deps the stdlib or platform already ships, single-implementation interfaces,
29
+ factories with one product, wrappers that only delegate, files exporting one
30
+ thing, dead flags and config, hand-rolled stdlib.
31
+
32
+ ## Output
33
+
34
+ One line per finding, ranked: `<tag> <what to cut>. <replacement>. [path]`.
35
+ End with `net: -<N> lines, -<M> deps possible.` Nothing to cut: `Lean already. Ship.`
36
+
37
+ ## Boundaries
38
+
39
+ Scope: over-engineering and complexity only. Correctness bugs, security holes,
40
+ and performance are explicitly out of scope. Route them to a normal review
41
+ pass. Lists findings, applies nothing. One-shot.
42
+ "stop ponytail-audit" or "normal mode" to revert.
43
+
44
+
45
+ Read project AGENTS.md for shared workflow, scope, and evidence policy.