agentme 0.12.0 → 0.13.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.
@@ -9,6 +9,7 @@ Propose changes via pull request. All changes must be verified for clarity and n
9
9
  Foundational standards, principles, and guidelines.
10
10
 
11
11
  - [agentme-edr-002](principles/002-coding-best-practices.md) - **Coding best practices** - Keep files small, tests nearby, and docs synchronized
12
+ - [agentme-edr-023](principles/023-coding-abstraction-practices.md) - **Coding abstraction practices** - Define when abstractions are justified and when they must be inlined
12
13
  - [agentme-edr-004](principles/004-unit-test-requirements.md) - **Unit test requirements** - Define minimum unit-test coverage and naming expectations
13
14
  - [agentme-edr-007](principles/007-project-quality-standards.md) - **Project quality standards** - Require build, lint, and test verification before completion
14
15
  - [agentme-edr-009](principles/009-error-handling.md) - **Error handling** - Standardize explicit errors, logging, and propagation rules
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: agentme-edr-policy-023-coding-abstraction-practices
3
+ description: Defines when abstractions (functions, classes, wrappers, factories) are justified and when they must be avoided. Tightly related to agentme-edr-policy-002-coding-best-practices.
4
+ apply-to: All software projects
5
+ valid-from: 2026-05-29
6
+ ---
7
+
8
+ # agentme-edr-policy-023: Coding abstraction practices
9
+
10
+ ## Context and Problem Statement
11
+
12
+ Abstractions (helper functions, wrapper classes, factories, indirection layers) can clarify intent and reduce duplication — but when applied without discipline they obscure logic, force unnecessary navigation, and inflate codebases. Teams need clear criteria for when an abstraction earns its place versus when it adds unjustified indirection.
13
+
14
+ What principles should guide the decision to introduce — or reject — an abstraction?
15
+
16
+ ## Decision Outcome
17
+
18
+ **Apply a bias toward explicit, functional, input→processing→output code. Introduce abstractions only when they demonstrably add value in logic, intent, reusability or readability.**
19
+
20
+ ### Details
21
+
22
+ #### 01-prioritize-functional-programming
23
+
24
+ Prefer functional programming: pure functions with clear input → processing → output flow. Object-oriented patterns (classes, inheritance) are allowed **only** when there is a clear benefit from the additional abstraction they bring — e.g., when complex context management or true inheritance hierarchies are intrinsically part of the best solution for a problem.
25
+
26
+ *Why:* Functional units are simpler to reason about, test, and compose. OO introduces shared mutable state and implicit coupling that must earn its place.
27
+
28
+ ---
29
+
30
+ #### 02-prefer-explicit-calls-over-indirections
31
+
32
+ A sequence of direct calls to libraries and resources makes logic straightforward. Avoid:
33
+
34
+ - Aspect-oriented programming (AOP)
35
+ - Implicit context injection / dependency injection containers
36
+ - Magic decorators that alter control flow invisibly
37
+
38
+ These patterns obfuscate the main program flow and create behavioral indirections that require prior knowledge of state machines living outside the code itself.
39
+
40
+ *When indirection is acceptable:* Framework-mandated patterns (middleware chains, React context, etc.) where the reader already expects the indirection.
41
+
42
+ ---
43
+
44
+ #### 03-trivial-wrappers-are-prohibited
45
+
46
+ A function that merely delegates to another function or API call without adding meaningful logic, domain intent, or readability **must be inlined**. A wrapper is justified only when it:
47
+
48
+ - Encapsulates non-trivial logic (validation, retry, transformation).
49
+ - Communicates a domain concept the underlying expression does not convey.
50
+ - Improves readability of a complex flow by giving a clear name to a cohesive block of work.
51
+
52
+ **Bad — trivial wrapper:**
53
+
54
+ ```typescript
55
+ function getUser(id: string) {
56
+ return db.users.findById(id);
57
+ }
58
+ ```
59
+
60
+ **Good — adds domain intent:**
61
+
62
+ ```typescript
63
+ function isEligibleForTrial(user: User): boolean {
64
+ return !user.hasSubscription && user.createdAt > trialCutoffDate && !user.isBanned;
65
+ }
66
+ ```
67
+
68
+ ---
69
+
70
+ #### 04-object-factories-must-add-value
71
+
72
+ A function that constructs an object (e.g., configuration, options) is only justified if it:
73
+
74
+ - Performs validation or assertion.
75
+ - Computes values dynamically based on inputs.
76
+ - Combines data in a non-linear or conditional way.
77
+ - Is reused by multiple callers.
78
+
79
+ A function that restructures simple static data in an almost 1-to-1 mapping forces the reader to trace indirection for no benefit and must be inlined.
80
+
81
+ **Bad — trivial factory:**
82
+
83
+ ```typescript
84
+ function createConfig(port: number, host: string) {
85
+ return { port, host };
86
+ }
87
+ ```
88
+
89
+ **Good — adds validation and defaults:**
90
+
91
+ ```typescript
92
+ function createServerConfig(opts: Partial<ServerOpts>): ServerConfig {
93
+ if (opts.port && (opts.port < 1 || opts.port > 65535)) {
94
+ throw new Error(`Invalid port: ${opts.port}`);
95
+ }
96
+ return {
97
+ port: opts.port ?? 3000,
98
+ host: opts.host ?? 'localhost',
99
+ timeout: computeTimeout(opts.environment),
100
+ };
101
+ }
102
+ ```
103
+
104
+ ---
105
+
106
+ #### 05-abstractions-for-business-logic-are-encouraged
107
+
108
+ Extracting domain logic into a named function is **encouraged** when it:
109
+
110
+ - Encapsulates a business rule so the reader does not need to parse low-level conditions to understand domain intent.
111
+ - Communicates intent at a glance, making compound conditions or multi-step checks self-describing.
112
+
113
+ **Example:**
114
+
115
+ ```typescript
116
+ // Good — named function conveys business intent
117
+ if (isAllowed(event)) { ... }
118
+
119
+ // Bad — forces reader to decode domain meaning from raw conditions
120
+ if (event.status === 'active' && event.role !== 'guest' && event.quota > 0) { ... }
121
+ ```
122
+
123
+ ---
124
+
125
+ #### 06-idiomatic-framework-patterns-are-exempt
126
+
127
+ React hooks, higher-order components, middleware chains, and similar patterns established by the framework in use are **not** considered unnecessary abstraction. The reader already expects them, and fighting the framework's idioms creates more confusion than it removes.
128
+
129
+ This exemption does not override other rules — a trivial wrapper inside a hook is still prohibited.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentme",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "",
5
5
  "dependencies": {
6
6
  "filedist": "^0.34.1"