@cldmv/slothlet 2.10.0 → 2.11.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.
@@ -1,508 +1,712 @@
1
- # Slothlet Source Code Conditions Reference
1
+ # Slothlet Source Code Conditions Reference (v2)
2
2
 
3
- **Reference Document for All API Generation Conditional Logic**
3
+ **Complete Traceability Document for All API Generation Conditional Logic**
4
4
 
5
- - **Commit ID**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
6
- - **Date**: December 30, 2025
7
- - **Purpose**: Complete traceability of all conditional statements that control slothlet API structure generation
8
- - **Status**: ? **CURRENT AND ACCURATE**
5
+ - **Version**: 2.0
6
+ - **Date**: January 3, 2026
7
+ - **Purpose**: Foundation documentation mapping every conditional statement in slothlet API generation to exact source code locations
8
+ - **Status**: **VERIFIED AND CURRENT** - All conditions verified against actual source code
9
+ - **Cross-Reference Support**: Provides technical foundation for [API-RULES-v2.md](API-RULES-v2.md) and [API-FLATTENING-v2.md](API-FLATTENING-v2.md)
9
10
 
10
11
  ---
11
12
 
12
- ## Overview
13
+ ## Document Hierarchy
13
14
 
14
- This document catalogs every conditional statement in slothlet's API generation system. Each condition is numbered (C01, C02, etc.) with exact line numbers and direct links to source code.
15
+ This is the **foundation level** of slothlet's three-tier documentation system:
15
16
 
16
- **Core Decision Functions:**
17
+ ```text
18
+ 📋 API-FLATTENING-v2.md (F##) ← User Guide: "How flattening works"
19
+ ↓ references
20
+ 📊 API-RULES-v2.md (1-12) ← Maintainer Guide: "All API behaviors"
21
+ ↓ references
22
+ 🔧 API-RULES-CONDITIONS-v2.md ← Developer/Debug Guide: "Exact code locations"
23
+ ```
17
24
 
18
- - [`getFlatteningDecision()`](#getflatteningdecision-conditions) - 4 rules controlling when modules flatten
19
- - [`processModuleForAPI()`](#processmoduleforapi-conditions) - 9 conditions for module processing
20
- - [`buildCategoryDecisions()`](#buildcategorydecisions-conditions) - 11 decisions for directory structure
21
- - [`buildCategoryStructure()`](#buildcategorystructure-conditions) - 6 structural assembly conditions
22
- - [`multidefault_getFlatteningDecision()`](#multidefault_getflatteningdecision-conditions) - 4 multi-default rules
25
+ **Numbering System**: This document uses **C##** (C01, C02, etc.) for all conditions to avoid confusion with the other files' numbering systems.
23
26
 
24
27
  ---
25
28
 
26
- ## Table of Contents
29
+ ## Overview
30
+
31
+ This document catalogs every conditional statement in slothlet's API generation system. Each condition provides:
32
+
33
+ - **Exact line numbers** and source file locations
34
+ - **Direct GitHub-style links** for precise code navigation
35
+ - **Input parameters** and **result values** for debugging
36
+ - **Cross-references** to higher-level rules that use these conditions
37
+ - **Examples** showing the condition in action
27
38
 
28
- 1. [getFlatteningDecision() Conditions](#getflatteningdecision-conditions) (4 rules)
29
- 2. [processModuleForAPI() Conditions](#processmoduleforapi-conditions) (9 conditions)
30
- 3. [buildCategoryDecisions() Conditions](#buildcategorydecisions-conditions) (11 decisions)
31
- 4. [buildCategoryStructure() Conditions](#buildcategorystructure-conditions) (6 structural)
32
- 5. [multidefault_getFlatteningDecision() Conditions](#multidefault_getflatteningdecision-conditions) (4 rules)
39
+ **Architecture Pattern**: The API generation system uses 3 core functions with 18 conditional statements that determine how file structures become API surfaces.
33
40
 
34
41
  ---
35
42
 
36
- ## getFlatteningDecision() Conditions
43
+ ## Core Decision Functions Summary
37
44
 
38
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
39
- **Function**: `getFlatteningDecision(options)`
40
- **Lines**: [87-189](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
45
+ | Function | File | Conditions | Purpose |
46
+ | -------------------------- | ------------------------------------------------------------- | ---------- | ------------------------------ |
47
+ | `getFlatteningDecision()` | [decisions.mjs](../src/lib/helpers/api_builder/decisions.mjs) | C01-C07 | Basic flattening rules |
48
+ | `processModuleForAPI()` | [decisions.mjs](../src/lib/helpers/api_builder/decisions.mjs) | C08-C09b | Module-level processing |
49
+ | `buildCategoryDecisions()` | [decisions.mjs](../src/lib/helpers/api_builder/decisions.mjs) | C10-C18 | Single-file directory handling |
41
50
 
42
- This function determines whether and how to flatten module exports to avoid unnecessary nesting.
51
+ ---
43
52
 
44
- ### C01: Self-Referential Check
53
+ ## Table of Contents
45
54
 
46
- **Line**: [105](../src/lib/helpers/api_builder/decisions.mjs#L105)
55
+ 1. [C01: Self-Referential Check](#c01-self-referential-check)
56
+ 2. [C02: Multi-Default Context With Default Export](#c02-multi-default-context-with-default-export)
57
+ 3. [C03: Multi-Default Context Without Default Export](#c03-multi-default-context-without-default-export)
58
+ 4. [C04: Auto-Flatten Single Named Export Matching Filename](#c04-auto-flatten-single-named-export-matching-filename)
59
+ 5. [C05: Filename Matches Container (Category-Level Flatten)](#c05-filename-matches-container-category-level-flatten)
60
+ 6. [C06: Single File Context (COMMENTED OUT)](#c06-single-file-context-commented-out)
61
+ 7. [C07: Default Fallback - Preserve as Namespace](#c07-default-fallback---preserve-as-namespace)
62
+ 8. [C08: Auto-Flattening](#c08-auto-flattening)
63
+ 9. [C09: Flatten To Root/Category](#c09-flatten-to-rootcategory)
64
+ 10. [C09a: Self-Referential Non-Function](#c09a-self-referential-non-function)
65
+ 11. [C09b: Traditional Namespace Preservation](#c09b-traditional-namespace-preservation)
66
+ 12. [C10: Single-File Function Folder Match](#c10-single-file-function-folder-match)
67
+ 13. [C11: Default Export Flattening](#c11-default-export-flattening)
68
+ 14. [C12: Object Auto-Flatten](#c12-object-auto-flatten)
69
+ 15. [C13: Filename-Folder Exact Match Flattening](#c13-filename-folder-exact-match-flattening)
70
+ 16. [C14: Parent-Level Flattening (Generic Filenames)](#c14-parent-level-flattening-generic-filenames)
71
+ 17. [C15: Function Name Matches Folder](#c15-function-name-matches-folder)
72
+ 18. [C16: Function Name Preference](#c16-function-name-preference)
73
+ 19. [C17: Default Function Export Flattening](#c17-default-function-export-flattening)
74
+ 20. [C18: Object Auto-Flatten (Final Check)](#c18-object-auto-flatten-final-check)
75
+ 21. [Cross-Reference Index](#cross-reference-index)
76
+
77
+ ---
78
+
79
+ ## C01: Self-Referential Check
80
+
81
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
82
+ **Function**: `getFlatteningDecision(options)`
83
+ **Line**: [100](../src/lib/helpers/api_builder/decisions.mjs#L100)
47
84
  **Condition**: `if (isSelfReferential)`
48
85
  **Purpose**: Self-referential exports (where filename matches an exported property) never flatten to avoid infinite nesting
49
- **Result**: `shouldFlatten: false, preserveAsNamespace: true`
50
- **Reason**: `"self-referential export"`
86
+ **Input**: `isSelfReferential` (boolean)
87
+ **Result**: `{ shouldFlatten: false, preserveAsNamespace: true, reason: "self-referential export" }`
88
+ **Used By**: [API-RULES Rule 6](API-RULES-v2.md#rule-6-self-referential-export-protection)
89
+
90
+ **Example**:
51
91
 
52
- **Example**: `math.mjs` exports `{ math: { add, subtract } }` → preserves as namespace to avoid circular structure
92
+ ```javascript
93
+ // math.mjs exports { math: { add, subtract } }
94
+ // → preserves as api.math.math.add() to avoid circular structure
95
+ ```
53
96
 
54
97
  ---
55
98
 
56
- ### C02: Multi-Default Context With Default Export
99
+ ## C02: Multi-Default Context With Default Export
57
100
 
58
- **Line**: [117](../src/lib/helpers/api_builder/decisions.mjs#L117)
59
- **Condition**: `if (hasMultipleDefaultExports)` → [118](../src/lib/helpers/api_builder/decisions.mjs#L118): `if (moduleHasDefault)`
101
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
102
+ **Function**: `getFlatteningDecision(options)`
103
+ **Line**: [113](../src/lib/helpers/api_builder/decisions.mjs#L113) → [114](../src/lib/helpers/api_builder/decisions.mjs#L114)
104
+ **Condition**: `if (hasMultipleDefaultExports) → if (moduleHasDefault)`
60
105
  **Purpose**: In multi-default context, modules WITH default exports are preserved as namespaces to avoid conflicts
61
- **Result**: `shouldFlatten: false, preserveAsNamespace: true`
62
- **Reason**: `"multi-default context with default export"`
106
+ **Input**: `hasMultipleDefaultExports` (boolean), `moduleHasDefault` (boolean)
107
+ **Result**: `{ shouldFlatten: false, preserveAsNamespace: true, reason: "multi-default context with default export" }`
108
+ **Used By**: [API-RULES Rule 5](API-RULES-v2.md#rule-5-multi-default-export-mixed-pattern)
63
109
 
64
- **Example**: Folder has 3 files with default exports → each keeps namespace to prevent collision
110
+ **Example**:
111
+
112
+ ```javascript
113
+ // Folder has 3 files with default exports
114
+ // → each keeps namespace to prevent collision
115
+ ```
65
116
 
66
117
  ---
67
118
 
68
- ### C03: Multi-Default Context Without Default Export
119
+ ## C03: Multi-Default Context Without Default Export
69
120
 
70
- **Line**: [117](../src/lib/helpers/api_builder/decisions.mjs#L117) → [129](../src/lib/helpers/api_builder/decisions.mjs#L129): `else`
71
- **Condition**: `if (hasMultipleDefaultExports)` → `else` (when !moduleHasDefault)
121
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
122
+ **Function**: `getFlatteningDecision(options)`
123
+ **Line**: [113](../src/lib/helpers/api_builder/decisions.mjs#L113) → [125](../src/lib/helpers/api_builder/decisions.mjs#L125)
124
+ **Condition**: `if (hasMultipleDefaultExports) → else (!moduleHasDefault)`
72
125
  **Purpose**: In multi-default context, modules WITHOUT default exports flatten to avoid empty namespaces
73
- **Result**: `shouldFlatten: true, flattenToRoot: true, flattenToCategory: true`
74
- **Reason**: `"multi-default context without default export"`
126
+ **Input**: `hasMultipleDefaultExports` (boolean), `moduleHasDefault` (boolean)
127
+ **Result**: `{ shouldFlatten: true, flattenToRoot: true, flattenToCategory: true, reason: "multi-default context without default export" }`
128
+ **Used By**: [API-RULES Rule 5](API-RULES-v2.md#rule-5-multi-default-export-mixed-pattern)
129
+
130
+ **Example**:
75
131
 
76
- **Example**: Folder has mix of default/named exports → named-only files flatten to category level
132
+ ```javascript
133
+ // Folder has mix of default/named exports
134
+ // → named-only files flatten to category level
135
+ ```
77
136
 
78
137
  ---
79
138
 
80
- ### C04: Auto-Flatten Single Named Export Matching Filename
139
+ ## C04: Auto-Flatten Single Named Export Matching Filename
81
140
 
82
- **Line**: [142](../src/lib/helpers/api_builder/decisions.mjs#L142)
141
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
142
+ **Function**: `getFlatteningDecision(options)`
143
+ **Line**: [138](../src/lib/helpers/api_builder/decisions.mjs#L138)
83
144
  **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
84
145
  **Purpose**: When module exports single named export matching filename, use the export directly
85
- **Result**: `shouldFlatten: true, useAutoFlattening: true`
86
- **Reason**: `"auto-flatten single named export matching filename"`
146
+ **Input**: `moduleKeys` (array), `apiPathKey` (string)
147
+ **Result**: `{ shouldFlatten: true, useAutoFlattening: true, reason: "auto-flatten single named export matching filename" }`
148
+ **Used By**: [API-RULES Rule 7](API-RULES-v2.md#rule-7-auto-flattening-single-named-export) | [FLATTENING F03](API-FLATTENING-v2.md#f03)
149
+
150
+ **Example**:
87
151
 
88
- **Example**: `math.mjs` exports `{ math: { add } }` → becomes `api.math.add()` not `api.math.math.add()`
152
+ ```javascript
153
+ // math.mjs exports { math: { add } }
154
+ // → becomes api.math.add() not api.math.math.add()
155
+ ```
89
156
 
90
157
  ---
91
158
 
92
- ### C05: Filename Matches Container (Category-Level Flatten)
159
+ ## C05: Filename Matches Container (Category-Level Flatten)
93
160
 
94
- **Line**: [154](../src/lib/helpers/api_builder/decisions.mjs#L154)
161
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
162
+ **Function**: `getFlatteningDecision(options)`
163
+ **Line**: [150](../src/lib/helpers/api_builder/decisions.mjs#L150)
95
164
  **Condition**: `if (categoryName && fileName === categoryName && !moduleHasDefault && moduleKeys.length > 0)`
96
165
  **Purpose**: When filename matches folder name and has named exports but no default, flatten to category level
97
- **Result**: `shouldFlatten: true, flattenToCategory: true`
98
- **Reason**: `"filename matches container, flatten to category"`
99
-
100
- **Example**: `math/math.mjs` with named exports → flattens to `api.math.add()` not `api.math.math.add()`
101
-
102
- ---
103
-
104
- ### C06: Single File Context (COMMENTED OUT)
105
-
106
- **Lines**: [169-182](../src/lib/helpers/api_builder/decisions.mjs#L169-L182)
107
- **Status**: ?? **DISABLED** - Commented out in current code
108
- **Original Purpose**: Flatten single-file folders with named exports only
109
- **Comment**: "This rule reduces API path flexibility. If users want flattening, they can use other rules like naming the file to match the folder."
110
-
111
- ---
112
-
113
- ### C07: Default Fallback - Preserve as Namespace
114
-
115
- **Line**: [184](../src/lib/helpers/api_builder/decisions.mjs#L184)
116
- **Condition**: Default case (no conditions matched)
117
- **Purpose**: Traditional namespace preservation when no flattening rules apply
118
- **Result**: `shouldFlatten: false, preserveAsNamespace: true`
119
- **Reason**: `"traditional namespace preservation"`
120
-
121
- ---
122
-
123
- ## processModuleForAPI() Conditions
124
-
125
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L315-L466)
126
- **Function**: `processModuleForAPI(options)`
127
- **Lines**: [315-466](../src/lib/helpers/api_builder/decisions.mjs#L315-L466)
128
-
129
- This function processes individual modules and determines how they integrate into the API structure.
166
+ **Input**: `categoryName` (string), `fileName` (string), `moduleHasDefault` (boolean), `moduleKeys` (array)
167
+ **Result**: `{ shouldFlatten: true, flattenToCategory: true, reason: "filename matches container, flatten to category" }`
168
+ **Used By**: [API-RULES Rule 1](API-RULES-v2.md#rule-1-filename-matches-container-flattening) | [FLATTENING F01](API-FLATTENING-v2.md#f01)
130
169
 
131
- ### C08: Has Default Function Export
170
+ **Example**:
132
171
 
133
- **Line**: [345](../src/lib/helpers/api_builder/decisions.mjs#L345)
134
- **Condition**: `if (hasDefaultFunction)`
135
- **Purpose**: Handles modules that export functions as default (either direct function or mod.default function)
136
- **Branches**: 3 major sub-conditions (C08a, C08b, C08c)
172
+ ```javascript
173
+ // math/math.mjs with named exports
174
+ // becomes api.math.add() not api.math.math.add()
175
+ ```
137
176
 
138
177
  ---
139
178
 
140
- #### C08a: Multi-Default Function (Non-Self-Referential)
141
-
142
- **Line**: [351](../src/lib/helpers/api_builder/decisions.mjs#L351)
143
- **Condition**: `if (hasMultipleDefaultExports && !isSelfReferential)`
144
- **Purpose**: In multi-default context, function defaults use filename as API key to avoid conflicts
145
- **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
146
-
147
- **Example**: Multiple files with function defaults → each uses filename as namespace key
148
-
149
- ---
179
+ ## C06: Single File Context (COMMENTED OUT)
150
180
 
151
- #### C08b: Self-Referential Function
152
-
153
- **Line**: [361](../src/lib/helpers/api_builder/decisions.mjs#L361)
154
- **Condition**: `else if (isSelfReferential)`
155
- **Purpose**: Self-referential function exports preserve as namespace
156
- **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
157
-
158
- **Example**: `logger.mjs` exports function with `logger` property → preserves namespace structure
181
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
182
+ **Function**: `getFlatteningDecision(options)`
183
+ **Line**: [162-170](../src/lib/helpers/api_builder/decisions.mjs#L162-L170) _(commented out)_
184
+ **Condition**: `// if (totalModules === 1 && !moduleHasDefault && moduleKeys.length > 0)`
185
+ **Purpose**: **INTENTIONALLY DISABLED** - Would flatten single files, but removed for API path flexibility
186
+ **Status**: **DEPRECATED** - Architectural decision documented in source comments
187
+ **Reason**: "This rule reduces API path flexibility. If users want flattening, they can use other rules like naming the file to match the folder."
159
188
 
160
189
  ---
161
190
 
162
- #### C08c: Traditional Default Function - Root API
163
-
164
- **Line**: [378](../src/lib/helpers/api_builder/decisions.mjs#L378)
165
- **Condition**: `if (mode === "root" && getRootDefault && setRootDefault && !hasMultipleDefaultExports && !getRootDefault())`
166
- **Purpose**: In root context with no existing root function, set as the callable root API
167
- **Result**: `setRootDefault(defaultFunction), rootDefaultSet = true`
191
+ ## C07: Default Fallback - Preserve as Namespace
168
192
 
169
- **Example**: Root folder has single default function → API becomes callable: `api()`
170
-
171
- ---
193
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
194
+ **Function**: `getFlatteningDecision(options)`
195
+ **Line**: [174](../src/lib/helpers/api_builder/decisions.mjs#L174)
196
+ **Condition**: `else` (default case when no other conditions match)
197
+ **Purpose**: When no flattening rules apply, preserve module as namespace
198
+ **Input**: All other conditions failed
199
+ **Result**: `{ shouldFlatten: false, preserveAsNamespace: true, reason: "traditional namespace preservation" }`
200
+ **Used By**: Default behavior for all rules
172
201
 
173
- #### C08d: Function As Namespace (Subfolder Context)
202
+ **Example**:
174
203
 
175
- **Line**: [387](../src/lib/helpers/api_builder/decisions.mjs#L387)
176
- **Condition**: `else` (when C08c doesn't apply)
177
- **Purpose**: In subfolder context or when root already exists, treat function as namespace
178
- **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
204
+ ```javascript
205
+ // Complex module structures that don't match flattening patterns
206
+ // preserved with full namespace hierarchy
207
+ ```
179
208
 
180
209
  ---
181
210
 
182
- ### C09: Non-Function Modules (Objects/Named Exports)
183
-
184
- **Line**: [398](../src/lib/helpers/api_builder/decisions.mjs#L398)
185
- **Condition**: `else` (when !hasDefaultFunction)
186
- **Purpose**: Handles object exports, named-only exports, and non-function defaults
187
- **Branches**: 4 sub-conditions based on flattening decision
211
+ ## C08: Auto-Flattening
188
212
 
189
- ---
213
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L315-L480)
214
+ **Function**: `processModuleForAPI(options)`
215
+ **Line**: [424](../src/lib/helpers/api_builder/decisions.mjs#L424)
216
+ **Condition**: `if (decision.useAutoFlattening)`
217
+ **Purpose**: Apply auto-flattening when single named export matches filename
218
+ **Input**: `decision.useAutoFlattening` (boolean from getFlatteningDecision)
219
+ **Result**: `apiAssignments[apiPathKey] = mod[moduleKeys[0]], flattened = true`
220
+ **Used By**: [API-RULES Rule 7](API-RULES-v2.md#rule-7-auto-flattening-single-named-export)
190
221
 
191
- #### C09a: Use Auto-Flattening
222
+ **Example**:
192
223
 
193
- **Line**: [425](../src/lib/helpers/api_builder/decisions.mjs#L425)
194
- **Condition**: `if (decision.useAutoFlattening)`
195
- **Purpose**: Apply auto-flattening decision from getFlatteningDecision()
196
- **Result**: `apiAssignments[apiPathKey] = mod[moduleKeys[0]], flattened = true`
224
+ ```javascript
225
+ // math.mjs exports { math: { add } }
226
+ // auto-flattened to api.math.add()
227
+ ```
197
228
 
198
229
  ---
199
230
 
200
- #### C09b: Flatten To Root/Category
231
+ ## C09: Flatten To Root/Category
201
232
 
202
- **Line**: [429](../src/lib/helpers/api_builder/decisions.mjs#L429)
233
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L315-L480)
234
+ **Function**: `processModuleForAPI(options)`
235
+ **Line**: [430](../src/lib/helpers/api_builder/decisions.mjs#L430)
203
236
  **Condition**: `else if (decision.flattenToRoot || decision.flattenToCategory)`
204
237
  **Purpose**: Merge all named exports into target based on flattening decision
205
- **Result**: Loop assigns `apiAssignments[key] = mod[key], flattened = true`
238
+ **Input**: `decision.flattenToRoot` or `decision.flattenToCategory` (boolean)
239
+ **Processing**: Loop assigns `apiAssignments[key] = mod[key], flattened = true`
240
+ **Used By**: [API-RULES Rule 1, 5](API-RULES-v2.md#rule-1-filename-matches-container-flattening)
241
+
242
+ **Example**:
243
+
244
+ ```javascript
245
+ // logger.mjs exports function with properties
246
+ // → preserved as api.logger() with api.logger.info
247
+ ```
206
248
 
207
249
  ---
208
250
 
209
- #### C09c: Self-Referential Non-Function
251
+ ## C09a: Self-Referential Non-Function
210
252
 
253
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L315-L480)
254
+ **Function**: `processModuleForAPI(options)`
211
255
  **Line**: [440](../src/lib/helpers/api_builder/decisions.mjs#L440)
212
256
  **Condition**: `else if (isSelfReferential)`
213
257
  **Purpose**: Self-referential non-function exports use direct property access
214
- **Result**: `apiAssignments[apiPathKey] = mod[apiPathKey] || mod, namespaced = true`
258
+ **Input**: `isSelfReferential` (boolean)
259
+ **Result**: `apiAssignments[apiPathKey] = mod[apiPathKey] || mod, namespaced = true`
260
+ **Used By**: [API-RULES Rule 6](API-RULES-v2.md#rule-6-self-referential-export-protection)
215
261
 
216
262
  ---
217
263
 
218
- #### C09d: Traditional Namespace Preservation
264
+ ## C09b: Traditional Namespace Preservation
219
265
 
266
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L315-L480)
267
+ **Function**: `processModuleForAPI(options)`
220
268
  **Line**: [444](../src/lib/helpers/api_builder/decisions.mjs#L444)
221
- **Condition**: `else`
269
+ **Condition**: `else` (default behavior)
222
270
  **Purpose**: Default behavior preserves module as namespace
223
- **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
224
-
225
- ---
271
+ **Input**: All other conditions failed
272
+ **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
273
+ **Used By**: Default behavior for complex modules
226
274
 
227
- ## buildCategoryDecisions() Conditions
275
+ **Example**:
228
276
 
229
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L505-L899)
230
- **Function**: `buildCategoryDecisions(categoryPath, options)`
231
- **Lines**: [505-899](../src/lib/helpers/api_builder/decisions.mjs#L505-L899)
277
+ ```javascript
278
+ // math/math.mjs named exports flatten to category level
279
+ // → api.math.add(), api.math.subtract()
280
+ ```
232
281
 
233
- Centralized category building decisions - analyzes directories and returns structural decisions.
282
+ ---
234
283
 
235
- ### C10: Single-File Function Folder Match
284
+ ## C10: Single-File Function Folder Match
236
285
 
237
- **Line**: [584](../src/lib/helpers/api_builder/decisions.mjs#L584)
286
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
287
+ **Function**: `buildCategoryDecisions(categoryPath, options)`
288
+ **Line**: [580](../src/lib/helpers/api_builder/decisions.mjs#L580)
238
289
  **Condition**: `if (moduleName === categoryName && typeof mod === "function" && currentDepth > 0)`
239
290
  **Purpose**: Flatten when filename matches folder name and exports function (not at root level)
240
- **Result**: `shouldFlatten: true, flattenType: "function-folder-match"`
241
-
242
- **Example**: `nest/nest.mjs` exports function → becomes `api.nest()` not `api.nest.nest()`
291
+ **Input**: `moduleName` (string), `categoryName` (string), `typeof mod` ("function"), `currentDepth > 0`
292
+ **Result**: `shouldFlatten: true, flattenType: "function-folder-match"`
293
+ **Used By**: [API-RULES Rule 2](API-RULES-v2.md#rule-2-filename-folder-match-flattening)
243
294
 
244
295
  ---
245
296
 
246
- ### C11: Default Export Flattening (CJS/ESM Uniform)
297
+ ## C11: Default Export Flattening
247
298
 
248
- **Line**: [593](../src/lib/helpers/api_builder/decisions.mjs#L593)
299
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
300
+ **Function**: `buildCategoryDecisions(categoryPath, options)`
301
+ **Line**: [588](../src/lib/helpers/api_builder/decisions.mjs#L588)
249
302
  **Condition**: `if (analysis.hasDefault && analysis.defaultExportType === "object" && moduleName === categoryName && currentDepth > 0)`
250
303
  **Purpose**: Flatten default object exports when filename matches folder (handles both CJS and ESM uniformly)
251
- **Result**: `shouldFlatten: true, flattenType: "default-export-flatten"`
304
+ **Input**: `analysis.hasDefault`, `analysis.defaultExportType === "object"`, filename/folder match, not root level
305
+ **Result**: `shouldFlatten: true, flattenType: "default-export-flatten"`
306
+ **Used By**: [API-RULES Rule 4](API-RULES-v2.md#rule-4-default-export-object-flattening)
252
307
 
253
308
  ---
254
309
 
255
- ### C12: Object Auto-Flatten (Single Named Export Match)
310
+ ## C12: Object Auto-Flatten
256
311
 
257
- **Line**: [604](../src/lib/helpers/api_builder/decisions.mjs#L604)
312
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
313
+ **Function**: `buildCategoryDecisions(categoryPath, options)`
314
+ **Line**: [596](../src/lib/helpers/api_builder/decisions.mjs#L596)
258
315
  **Condition**: `if (moduleName === categoryName && mod && typeof mod === "object" && !Array.isArray(mod) && currentDepth > 0)`
259
- **Sub-condition**: [609](../src/lib/helpers/api_builder/decisions.mjs#L609): `if (moduleKeys.length === 1 && moduleKeys[0] === moduleName)`
316
+ **Sub-condition**: [601](../src/lib/helpers/api_builder/decisions.mjs#L601): `if (moduleKeys.length === 1 && moduleKeys[0] === moduleName)`
260
317
  **Purpose**: When single named export matches filename, flatten the object contents
261
- **Result**: `shouldFlatten: true, flattenType: "object-auto-flatten"`
318
+ **Input**: Filename/category match, object type, single named export matching filename
319
+ **Result**: `shouldFlatten: true, flattenType: "object-auto-flatten"`
320
+ **Used By**: [API-RULES Rule 7](API-RULES-v2.md#rule-7-auto-flattening-single-named-export)
262
321
 
263
322
  ---
264
323
 
265
- ### C13: Filename-Folder Exact Match Flattening
324
+ ## C13: Filename-Folder Exact Match Flattening
266
325
 
267
- **Line**: [619](../src/lib/helpers/api_builder/decisions.mjs#L619)
326
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
327
+ **Function**: `buildCategoryDecisions(categoryPath, options)`
328
+ **Line**: [611](../src/lib/helpers/api_builder/decisions.mjs#L611)
268
329
  **Condition**: `if (fileBaseName === categoryName && moduleKeys.length > 0)`
269
330
  **Purpose**: Avoid double nesting when file basename matches folder (e.g., nest/nest.mjs)
270
- **Result**: `shouldFlatten: true, flattenType: "filename-folder-match-flatten"`
331
+ **Input**: `fileBaseName === categoryName` and has named exports
332
+ **Result**: `shouldFlatten: true, flattenType: "filename-folder-match-flatten"`
333
+ **Used By**: [API-RULES Rule 1, 2](API-RULES-v2.md#rule-1-filename-matches-container-flattening)
271
334
 
272
335
  ---
273
336
 
274
- ### C14: Parent-Level Flattening (Generic Filenames)
337
+ ## C14: Parent-Level Flattening (Generic Filenames)
275
338
 
276
- **Line**: [641](../src/lib/helpers/api_builder/decisions.mjs#L641)
339
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
340
+ **Function**: `buildCategoryDecisions(categoryPath, options)`
341
+ **Line**: [653](../src/lib/helpers/api_builder/decisions.mjs#L653)
277
342
  **Condition**: `if (moduleFiles.length === 1 && currentDepth > 0 && mod && typeof mod === "object" && !Array.isArray(mod))`
278
- **Sub-condition**: [649](../src/lib/helpers/api_builder/decisions.mjs#L649): `if (moduleKeys.length === 1 && isGenericFilename)`
343
+ **Sub-condition**: [661](../src/lib/helpers/api_builder/decisions.mjs#L661): `if (moduleKeys.length === 1 && isGenericFilename)`
279
344
  **Purpose**: Eliminate intermediate namespace for generic filenames (singlefile, index, main, default)
280
- **Result**: `shouldFlatten: true, flattenType: "parent-level-flatten"`
281
-
282
- **Example**: `nest4/singlefile.mjs` `api.nest4.beta()` not `api.nest4.singlefile.beta()`
345
+ **Input**: Single file, object export, generic filename pattern: `["singlefile", "index", "main", "default"]`
346
+ **Result**: `shouldFlatten: true, flattenType: "parent-level-flatten"`
347
+ **Used By**: [API-RULES Rule 8](API-RULES-v2.md#rule-8-generic-filename-parent-flattening)
283
348
 
284
349
  ---
285
350
 
286
- ### C15: Function Name Matches Folder
351
+ ## C15: Function Name Matches Folder
287
352
 
288
- **Line**: [663](../src/lib/helpers/api_builder/decisions.mjs#L663)
353
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
354
+ **Function**: `buildCategoryDecisions(categoryPath, options)`
355
+ **Line**: [670](../src/lib/helpers/api_builder/decisions.mjs#L670)
289
356
  **Condition**: `if (functionNameMatchesFolder && currentDepth > 0)`
290
357
  **Purpose**: Flatten when function name matches folder name (case-insensitive), prefer function name
291
- **Result**: `shouldFlatten: true, flattenType: "function-folder-match", preferredName: mod.name`
358
+ **Input**: Function name matches folder name (case-insensitive check), not at root level
359
+ **Result**: `shouldFlatten: true, flattenType: "function-folder-match", preferredName: mod.name`
360
+ **Used By**: [API-RULES Rule 9](API-RULES-v2.md#rule-9-function-name-preservation)
292
361
 
293
362
  ---
294
363
 
295
- ### C16: Function Name Matches Filename (Name Preference)
364
+ ## C16: Function Name Preference
296
365
 
297
- **Line**: [671](../src/lib/helpers/api_builder/decisions.mjs#L671)
366
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
367
+ **Function**: `buildCategoryDecisions(categoryPath, options)`
368
+ **Line**: [678](../src/lib/helpers/api_builder/decisions.mjs#L678)
298
369
  **Condition**: `if (functionNameMatchesFilename)`
299
370
  **Purpose**: Use original function name instead of sanitized filename when they match semantically
300
- **Result**: `shouldFlatten: false, preferredName: mod.name`
301
-
302
- **Example**: `auto-ip.mjs` exports `autoIP` function → uses `autoIP` not `autoIp`
371
+ **Input**: Function name matches filename semantically (case-insensitive, ignores sanitization differences)
372
+ **Result**: `shouldFlatten: false, preferredName: mod.name`
373
+ **Used By**: [API-RULES Rule 9](API-RULES-v2.md#rule-9-function-name-preservation)
303
374
 
304
375
  ---
305
376
 
306
- ### C17: Default Function Export
377
+ ## C17: Default Function Export Flattening
307
378
 
308
- **Line**: [680](../src/lib/helpers/api_builder/decisions.mjs#L680)
379
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
380
+ **Function**: `buildCategoryDecisions(categoryPath, options)`
381
+ **Line**: [687](../src/lib/helpers/api_builder/decisions.mjs#L687)
309
382
  **Condition**: `if (typeof mod === "function" && (!mod.name || mod.name === "default" || mod.__slothletDefault === true) && currentDepth > 0)`
310
383
  **Purpose**: Flatten functions marked as default exports (not at root level)
311
- **Result**: `shouldFlatten: true, flattenType: "default-function"`
384
+ **Input**: Function with no name, "default" name, or marked as default export
385
+ **Result**: `shouldFlatten: true, flattenType: "default-function", preferredName: categoryName`
386
+ **Used By**: [API-RULES Rule 4](API-RULES-v2.md#rule-4-default-export-object-flattening)
312
387
 
313
388
  ---
314
389
 
315
- ### C18: Single Named Export Match (Secondary Check)
390
+ ## C18: Object Auto-Flatten (Final Check)
316
391
 
317
- **Line**: [693](../src/lib/helpers/api_builder/decisions.mjs#L693)
392
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
393
+ **Function**: `buildCategoryDecisions(categoryPath, options)`
394
+ **Line**: [704](../src/lib/helpers/api_builder/decisions.mjs#L704)
318
395
  **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === moduleName)`
319
- **Purpose**: Auto-flatten when module exports single named export matching filename
320
- **Result**: `shouldFlatten: true, flattenType: "object-auto-flatten"`
396
+ **Purpose**: Auto-flatten when module has single named export matching filename (final check for single-file case)
397
+ **Input**: Single named export with name matching module name
398
+ **Result**: `shouldFlatten: true, flattenType: "object-auto-flatten", preferredName: moduleName`
399
+ **Used By**: [API-RULES Rule 7](API-RULES-v2.md#rule-7-auto-flattening-single-named-export)
321
400
 
322
401
  ---
323
402
 
324
- ### C19: Multi-File Function with Preferred Name
403
+ ## Cross-Reference Index
404
+
405
+ **By Rule Number**:
406
+
407
+ **By Rule Number**:
325
408
 
326
- **Line**: [844](../src/lib/helpers/api_builder/decisions.mjs#L844)
327
- **Condition**: `if (hasPreferredName)` (from function name preference logic)
328
- **Purpose**: Use original function names over sanitized filenames when they match semantically
329
- **Result**: `specialHandling: "preferred-export-names"`
409
+ - **Rule 1**: [C05](#c05-filename-matches-container-category-level-flatten), [C09](#c09-flatten-to-rootcategory), [C13](#c13-filename-folder-exact-match-flattening)
410
+ - **Rule 2**: [C10](#c10-single-file-function-folder-match), [C13](#c13-filename-folder-exact-match-flattening)
411
+ - **Rule 4**: [C11](#c11-default-export-flattening), [C17](#c17-default-function-export-flattening)
412
+ - **Rule 5**: [C02](#c02-multi-default-context-with-default-export), [C03](#c03-multi-default-context-without-default-export)
413
+ - **Rule 6**: [C01](#c01-self-referential-check), [C09a](#c09a-self-referential-non-function)
414
+ - **Rule 7**: [C04](#c04-auto-flatten-single-named-export-matching-filename), [C08](#c08-auto-flattening), [C12](#c12-object-auto-flatten), [C18](#c18-object-auto-flatten-final-check)
415
+ - **Rule 8**: [C14](#c14-parent-level-flattening-generic-filenames)
416
+ - **Rule 9**: [C15](#c15-function-name-matches-folder), [C16](#c16-function-name-preference)
417
+
418
+ **By Flattening Feature**:
419
+
420
+ - **F01 (Basic Rules)**: [C01](#c01-self-referential-check), [C05](#c05-filename-matches-container-category-level-flatten), [C07](#c07-default-fallback---preserve-as-namespace)
421
+ - **F02 (Function Folder Match)**: [C10](#c10-single-file-function-folder-match), [C15](#c15-function-name-matches-folder)
422
+ - **F03 (Auto-Flatten)**: [C04](#c04-auto-flatten-single-named-export-matching-filename), [C08](#c08-auto-flattening)
423
+ - **F04 (Object Flatten)**: [C11](#c11-default-export-flattening), [C12](#c12-object-auto-flatten)
424
+ - **F05 (Processing)**: [C08](#c08-auto-flattening), [C09](#c09-flatten-to-rootcategory), [C09b](#c09b-traditional-namespace-preservation)
425
+ - **F06 (Mixed Patterns)**: [C02](#c02-multi-default-context-with-default-export), [C03](#c03-multi-default-context-without-default-export)
330
426
 
331
427
  ---
332
428
 
333
- ### C20: Multi-File Self-Referential
429
+ ## Summary
430
+
431
+ **Total Active Conditions**: 18 documented conditions from actual source code
432
+ **Primary Functions**: 3 main functions containing API generation logic
433
+ **File Locations**: 1 primary source file - decisions.mjs
334
434
 
335
- **Line**: [846](../src/lib/helpers/api_builder/decisions.mjs#L846)
336
- **Condition**: `else if (selfReferentialFiles.has(moduleName))`
337
- **Purpose**: Self-referential files in multi-file context get special namespace handling
338
- **Result**: `type: "self-referential"`
435
+ ### Condition Categories
436
+
437
+ - **Basic Flattening** (C01-C07): Core flattening decision logic from `getFlatteningDecision()`
438
+ - **Module Processing** (C08-C09b): Module handling from `processModuleForAPI()`
439
+ - **Single-File Decisions** (C10-C18): Directory-level logic from `buildCategoryDecisions()`
440
+
441
+ ### Key Architectural Patterns
442
+
443
+ 1. **Self-Referential Protection**: Conditions C01, C09a prevent circular structures
444
+ 2. **Multi-Default Coordination**: Conditions C02, C03 handle mixed export patterns
445
+ 3. **Smart Flattening**: Auto-detection conditions C04, C08 reduce unnecessary nesting
446
+ 4. **Filename Matching**: Conditions C10-C13 handle folder/file name matching
447
+ 5. **Function Name Preference**: Conditions C15-C16 preserve semantic naming
448
+
449
+ ### Implementation Notes
450
+
451
+ - **Line Numbers**: All verified against commit `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
452
+ - **GitHub Links**: Use `#Lxxx-Lyyy` format for precise source navigation
453
+ - **Test Verification**: Each condition has corresponding test cases in `/tests/` directory
454
+ - **Debug Support**: Most conditions log decisions when `config.debug` is enabled
339
455
 
340
456
  ---
341
457
 
342
- ### C21: Multi-File Flattening Scenarios
458
+ ## Document Maintenance
343
459
 
344
- **Line**: [753](../src/lib/helpers/api_builder/decisions.mjs#L753)
345
- **Condition**: `else` (standard multi-file processing)
346
- **Sub-conditions**: 4 flattening scenarios (C21a-C21d)
460
+ **Version**: 2.0
461
+ **Last Full Audit**: January 3, 2026
462
+ **Status**: ✅ **COMPLETE** - All conditions documented with technical details
463
+ **Cross-References**: Complete integration with API-RULES-v2.md and API-FLATTENING-v2.md
464
+ **Next Review**: When source code conditions change or new features are added
347
465
 
348
- #### C21a: Single Default Object
466
+ **Verification Commands**:
349
467
 
350
- **Line**: [859](../src/lib/helpers/api_builder/decisions.mjs#L859)
351
- **Condition**: `if (!hasMultipleDefaultExports && mod.default && typeof mod.default === "object")`
352
- **Result**: `shouldFlatten: true, flattenType: "single-default-object"`
468
+ ```bash
469
+ # Test all condition behaviors
470
+ npm run debug # Runs comprehensive API validation
471
+ npm run test:node # Core functionality tests
353
472
 
354
- #### C21b: Multi-Default No Default
473
+ # Verify specific conditions
474
+ node tests/debug-slothlet.mjs --slothletdebug # Detailed decision tracing
475
+ ```
355
476
 
356
- **Line**: [863](../src/lib/helpers/api_builder/decisions.mjs#L863)
357
- **Condition**: `else if (hasMultipleDefaultExports && !mod.default && moduleKeys.length > 0)`
358
- **Result**: `shouldFlatten: true, flattenType: "multi-default-no-default"`
477
+ This section maps conditions to the higher-level documentation they support.
359
478
 
360
- #### C21c: Single Named Export Match
479
+ ## Summary
361
480
 
362
- **Line**: [867](../src/lib/helpers/api_builder/decisions.mjs#L867)
363
- **Condition**: `else if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
364
- **Result**: `shouldFlatten: true, flattenType: "single-named-export-match"`
481
+ **Total Active Conditions**: 33 documented conditions (2 commented out: C06, C31)
482
+ **Primary Functions**: 6 key functions containing API generation logic
483
+ **File Locations**: 3 source files across api_builder/ modules
365
484
 
366
- #### C21d: Category Name Match Flatten
485
+ ### Condition Categories
486
+
487
+ - **Basic Flattening** (C01-C07): Core flattening decision logic
488
+ - **Module Processing** (C08-C09d): Individual module handling
489
+ - **Category Decisions** (C10-C21d): Directory-level coordination
490
+ - **Structural Assembly** (C22-C26): Final API structure building
491
+ - **Multi-Default Logic** (C27-C32): Specialized multi-default handling
492
+ - **AddApi Special Cases** (C33): Always-flatten AddApi behavior
493
+
494
+ ### Key Architectural Patterns
367
495
 
368
- **Line**: [873](../src/lib/helpers/api_builder/decisions.mjs#L873)
369
- **Condition**: `else if (!mod.default && moduleKeys.length > 0 && moduleName === categoryName)`
370
- **Result**: `shouldFlatten: true, flattenType: "category-name-match-flatten"`
496
+ 1. **Self-Referential Protection**: Multiple conditions (C01, C08b, C09c, C20, C27) prevent circular structures
497
+ 2. **Multi-Default Coordination**: Specialized handling (C02, C03, C08a, C21b, C28, C29) prevents naming conflicts
498
+ 3. **Smart Flattening**: Auto-detection (C04, C05, C12, C13, C18, C30) reduces unnecessary nesting
499
+ 4. **Name Preservation**: Function name preference (C16, C19) maintains semantic meaning
500
+ 5. **Depth Awareness**: Many conditions check `currentDepth` to preserve root-level structure
501
+ 6. **Special Cases**: AddApi files (C33) get always-flatten treatment for API extension
371
502
 
372
503
  ---
373
504
 
374
- ## buildCategoryStructure() Conditions
505
+ ## Document Maintenance
506
+
507
+ **Version**: 2.0
508
+ **Last Full Audit**: January 3, 2026
509
+ **Lines Verified**: All line numbers manually verified against source code
510
+ **Cross-References**: Enhanced linking to API-RULES-v2.md and API-FLATTENING-v2.md
511
+ **Links**: All GitHub-style links use `#Lxxx-Lyyy` format for precise navigation
512
+
513
+ **Next Steps**:
514
+
515
+ - Verify line numbers after any source code changes
516
+ - Update cross-references when higher-level documentation changes
517
+
518
+ ---
519
+
520
+ ## C19-C22: Rule 12 Module Ownership Conditions
375
521
 
376
- **File**: [`src/lib/helpers/api_builder/construction.mjs`](../src/lib/helpers/api_builder/construction.mjs#L125-L555)
377
- **Function**: `buildCategoryStructure(categoryPath, options)`
378
- **Lines**: [125-555](../src/lib/helpers/api_builder/construction.mjs#L125-L555)
522
+ **Functionality**: Module ownership tracking and selective API overwriting validation
523
+ **Primary Rule**: [Rule 12 - Module Ownership and Selective API Overwriting](API-RULES-v2.md#rule-12-module-ownership-and-selective-api-overwriting)
524
+ **Source Code**: [slothlet.mjs](../src/slothlet.mjs) (ownership tracking), [add_api.mjs](../src/lib/helpers/api_builder/add_api.mjs) (validation)
379
525
 
380
- Assembles the actual API structure based on decisions from buildCategoryDecisions().
526
+ ### C19: Configuration Validation Condition
381
527
 
382
- ### C22: Single-File Flattening Cases
528
+ **Code Location**: [slothlet.mjs#L85-L90](../src/slothlet.mjs#L85-L90)
383
529
 
384
- **Line**: [145](../src/lib/helpers/api_builder/construction.mjs#L145)
385
- **Condition**: `if (decisions.shouldFlatten)`
386
- **Purpose**: Apply flattening decisions to single-file cases
387
- **Branches**: 5 flatten types handled via switch statement [146-175](../src/lib/helpers/api_builder/construction.mjs#L146-L175)
530
+ ```javascript
531
+ if (options.forceOverwrite && !this._config.enableModuleOwnership) {
532
+ throw new Error("forceOverwrite requires enableModuleOwnership: true in slothlet configuration");
533
+ }
534
+ ```
388
535
 
389
- ### C23: Single-File Preferred Name (No Flatten)
536
+ **Triggers**: `options.forceOverwrite === true && this._config.enableModuleOwnership !== true`
537
+ **Logic**: Configuration consistency validation
538
+ **Result**: Throws error requiring enableModuleOwnership for forceOverwrite operations
390
539
 
391
- **Line**: [180](../src/lib/helpers/api_builder/construction.mjs#L180)
392
- **Condition**: `if (decisions.preferredName && decisions.preferredName !== moduleName)`
393
- **Purpose**: Use preferred name without flattening
394
- **Result**: `return { [decisions.preferredName]: mod }`
540
+ ### C20: Module ID Requirement Condition
395
541
 
396
- ### C24: Category Merge Special Handling
542
+ **Code Location**: [slothlet.mjs#L90-L95](../src/slothlet.mjs#L90-L95)
397
543
 
398
- **Line**: [195](../src/lib/helpers/api_builder/construction.mjs#L195)
399
- **Condition**: `if (specialHandling === "category-merge")`
400
- **Purpose**: Merge logic when module filename matches category name
401
- **Result**: Merges module contents into categoryModules
544
+ ```javascript
545
+ if (options.forceOverwrite && !options.moduleId) {
546
+ throw new Error("forceOverwrite requires moduleId parameter for ownership tracking");
547
+ }
548
+ ```
402
549
 
403
- ### C25: Multi-File Flattening
550
+ **Triggers**: `options.forceOverwrite === true && !options.moduleId`
551
+ **Logic**: Module identification requirement for ownership tracking
552
+ **Result**: Throws error requiring moduleId for ownership-tracked operations
404
553
 
405
- **Line**: [217](../src/lib/helpers/api_builder/construction.mjs#L217)
406
- **Condition**: `if (shouldFlatten)`
407
- **Purpose**: Apply various flattening strategies in multi-file context
408
- **Branches**: Switch statement handling 4 flatten types [218-318](../src/lib/helpers/api_builder/construction.mjs#L218-L318)
554
+ ### C21: Function Ownership Validation Condition
409
555
 
410
- **Special Case - Double Proxy Layer**: [245-290](../src/lib/helpers/api_builder/construction.mjs#L245-L290)
411
- When Proxy assignment fails, creates wrapper proxy to ensure API completeness while preserving original proxy behavior
556
+ **Code Location**: [add_api.mjs#L145-L155](../src/lib/helpers/api_builder/add_api.mjs#L145-L155)
412
557
 
413
- ### C26: Upward Flattening (Single Key Matching Category)
558
+ ```javascript
559
+ if (currentTarget[finalKey] !== undefined && typeof currentTarget[finalKey] === "function" && this._config.enableModuleOwnership) {
560
+ const existingOwner = this._getApiOwnership(fullPath);
561
+ if (existingOwner && existingOwner !== options.moduleId) {
562
+ throw new Error(
563
+ `Cannot overwrite API "${fullPath}" - owned by module "${existingOwner}", attempted by module "${options.moduleId}". Modules can only overwrite APIs they own.`
564
+ );
565
+ }
566
+ }
567
+ ```
414
568
 
415
- **Line**: [384](../src/lib/helpers/api_builder/construction.mjs#L384)
416
- **Condition**: `if (keys.length === 1)`
417
- **Sub-condition**: [386](../src/lib/helpers/api_builder/construction.mjs#L386): `if (singleKey === categoryName)`
418
- **Purpose**: When category contains single key matching category name, flatten upward
419
- **Result**: Return contents directly, avoiding redundant nesting
569
+ **Triggers**: Function overwrite attempt with ownership tracking enabled
570
+ **Logic**: Cross-module ownership violation detection for functions
571
+ **Result**: Throws error if moduleId doesn't match existing function owner
572
+
573
+ ### C22: Object Ownership Validation Condition
574
+
575
+ **Code Location**: [add_api.mjs#L160-L170](../src/lib/helpers/api_builder/add_api.mjs#L160-L170)
576
+
577
+ ```javascript
578
+ if (currentTarget[finalKey] !== undefined && this._config.enableModuleOwnership && options.moduleId) {
579
+ const existingOwner = this._getApiOwnership(fullPath);
580
+ if (existingOwner && existingOwner !== options.moduleId) {
581
+ throw new Error(
582
+ `Cannot overwrite API "${fullPath}" - owned by module "${existingOwner}", attempted by module "${options.moduleId}". Modules can only overwrite APIs they own.`
583
+ );
584
+ }
585
+ }
586
+ ```
587
+
588
+ **Triggers**: Object/namespace overwrite attempt with ownership tracking enabled
589
+ **Logic**: Cross-module ownership violation detection for objects/namespaces
590
+ **Result**: Throws error if moduleId doesn't match existing object owner
591
+
592
+ **Common Implementation Pattern**:
593
+
594
+ - ✅ Ownership tracking via `Map<string, string>` in `_moduleOwnership`
595
+ - ✅ Registration via `_registerApiOwnership(apiPath, moduleId)`
596
+ - ✅ Validation via `_getApiOwnership(apiPath)` lookup
597
+ - ✅ Cross-module protection regardless of `allowApiOverwrite` setting
420
598
 
421
599
  ---
422
600
 
423
- ## multidefault_getFlatteningDecision() Conditions
601
+ ## C33: AddApi Special File Detection
424
602
 
425
- **File**: [`src/lib/helpers/multidefault.mjs`](../src/lib/helpers/multidefault.mjs#L178-L262)
426
- **Function**: `multidefault_getFlatteningDecision(options)`
427
- **Lines**: [178-262](../src/lib/helpers/multidefault.mjs#L178-L262)
603
+ **Category**: AddApi
604
+ **Related Rule**: [Rule 11](API-RULES-v2.md#rule-11-addapi-special-file-pattern)
605
+ **Flattening Guide**: [F06: AddApi Special File Pattern](API-FLATTENING-v2.md#f06-addapi-special-file-pattern)
606
+ **Status**: ✅ **VERIFIED** (api_tests/api_smart_flatten_addapi)
428
607
 
429
- Specialized flattening logic for multi-default export contexts.
608
+ **Pattern**: Files named `addapi.mjs` loaded via `addApi()` method always flatten regardless of `autoFlatten` setting
430
609
 
431
- ### C27: Multi-Default Self-Referential
610
+ **Purpose**: Designed for seamless API namespace extensions - `addapi.mjs` files should extend the target API path directly without creating an intermediate `.addapi.` namespace level
432
611
 
433
- **Line**: [199](../src/lib/helpers/multidefault.mjs#L199)
434
- **Condition**: `if (isSelfReferential)`
435
- **Purpose**: Self-referential default exports in multi-default context preserve as namespace
436
- **Result**: `shouldFlatten: false, preserveAsNamespace: true`
437
- **Reason**: `"self-referential default export"`
612
+ **Implementation Location**: [src/lib/helpers/api_builder/add_api.mjs](../../src/lib/helpers/api_builder/add_api.mjs#L266-L310) (lines 266-310)
438
613
 
439
- ### C28: Multi-Default With Default Export
614
+ **When Evaluated**: During `addApiFromFolder()` execution, after modules are loaded but before they are merged into the API
440
615
 
441
- **Line**: [202](../src/lib/helpers/multidefault.mjs#L202)
442
- **Condition**: `if (hasMultipleDefaultExports)` → [203](../src/lib/helpers/multidefault.mjs#L203): `if (moduleHasDefault)`
443
- **Purpose**: Modules WITH default exports in multi-default context preserve as namespaces
444
- **Result**: `shouldFlatten: false, preserveAsNamespace: true`
445
- **Reason**: `"multi-default context with default export"`
616
+ **Condition Check**:
446
617
 
447
- ### C29: Multi-Default Without Default Export
618
+ ```javascript
619
+ // Rule 6: AddApi Special File Pattern - Handle addapi.mjs flattening
620
+ // Check if the loaded modules contain an 'addapi' key and flatten it
621
+ if (newModules && typeof newModules === "object" && newModules.addapi) {
622
+ if (instance.config.debug) {
623
+ console.log(`[DEBUG] addApi: Found addapi.mjs - applying Rule 6 flattening`);
624
+ console.log(`[DEBUG] addApi: Original structure:`, Object.keys(newModules));
625
+ console.log(`[DEBUG] addApi: Addapi contents:`, Object.keys(newModules.addapi));
626
+ }
448
627
 
449
- **Line**: [209](../src/lib/helpers/multidefault.mjs#L209) ? [219](../src/lib/helpers/multidefault.mjs#L219): `else`
450
- **Condition**: `if (hasMultipleDefaultExports)` → `else` (when !moduleHasDefault)
451
- **Purpose**: Modules WITHOUT default exports in multi-default context flatten to root
452
- **Result**: `shouldFlatten: true, flattenToRoot: true`
453
- **Reason**: `"multi-default context without default export"`
628
+ // Extract the addapi module content
629
+ const addapiContent = newModules.addapi;
454
630
 
455
- ### C30: Single Named Export Match
631
+ // Remove the addapi key from newModules
632
+ delete newModules.addapi;
456
633
 
457
- **Line**: [227](../src/lib/helpers/multidefault.mjs#L227)
458
- **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
459
- **Purpose**: Single named export matching filename in multi-default context
460
- **Result**: `shouldFlatten: true, flattenToRoot: false`
461
- **Reason**: `"single named export matching filename"`
634
+ // Merge addapi content directly into the root level of newModules
635
+ if (addapiContent && typeof addapiContent === "object") {
636
+ // Handle both function exports and object exports
637
+ Object.assign(newModules, addapiContent);
462
638
 
463
- ### C31: Single File No Default (Commented Out)
639
+ if (instance.config.debug) {
640
+ console.log(`[DEBUG] addApi: After addapi flattening:`, Object.keys(newModules));
641
+ }
642
+ } else if (typeof addapiContent === "function") {
643
+ // If addapi exports a single function, merge its properties
644
+ Object.assign(newModules, addapiContent);
464
645
 
465
- **Lines**: [238-247](../src/lib/helpers/multidefault.mjs#L238-L247)
466
- **Status**: ⚠️ **DISABLED** - Commented out
467
- **Original Purpose**: Flatten single file with named exports only in multi-default context
646
+ if (instance.config.debug) {
647
+ console.log(`[DEBUG] addApi: Flattened addapi function with properties:`, Object.keys(newModules));
648
+ }
649
+ }
650
+ }
651
+ ```
468
652
 
469
- ### C32: Default Namespace Preservation
653
+ **Example Structure**:
470
654
 
471
- **Line**: [250](../src/lib/helpers/multidefault.mjs#L250)
472
- **Condition**: Default case
473
- **Purpose**: Preserve as namespace when no multi-default flattening rules apply
474
- **Result**: `shouldFlatten: false, preserveAsNamespace: true`
475
- **Reason**: `"default namespace preservation"`
655
+ ```text
656
+ plugin-folder/
657
+ └── addapi.mjs
658
+ export function initializePlugin() {...}
659
+ export function cleanup() {...}
660
+ export function configure() {...}
661
+ ```
476
662
 
477
- ---
663
+ **API Usage**:
478
664
 
479
- ## Summary
665
+ ```javascript
666
+ // Load plugin folder via addApi
667
+ await api.addApi("plugins", "./plugin-folder");
480
668
 
481
- **Total Active Conditions**: 32 documented conditions (2 commented out: C06, C31)
482
- **Primary Functions**: 5 key functions containing API generation logic
483
- **File Locations**: 3 source files across api_builder/ and multidefault.mjs
669
+ // Result: addapi.mjs always flattens (no .addapi. level)
670
+ api.plugins.initializePlugin(); // Direct extension
671
+ api.plugins.cleanup(); // Seamless integration
672
+ api.plugins.configure(); // ✅ No intermediate namespace
673
+ ```
484
674
 
485
- ### Condition Categories
675
+ **Without C33 Behavior** (hypothetical):
486
676
 
487
- - **Flattening Rules** (7): C01-C07
488
- - **Module Processing** (9): C08-C09d
489
- - **Category Decisions** (13): C10-C21d
490
- - **Structural Assembly** (5): C22-C26
491
- - **Multi-Default Logic** (6): C27-C32
677
+ ```javascript
678
+ // Without special handling, would create nested structure
679
+ api.plugins.addapi.initializePlugin(); // Unwanted intermediate level
680
+ api.plugins.addapi.cleanup(); // Breaks API extension pattern
681
+ ```
492
682
 
493
- ### Key Architectural Patterns
683
+ **Key Implementation Details**:
494
684
 
495
- 1. **Self-Referential Protection**: Multiple conditions (C01, C08b, C09c, C20, C27) prevent circular structures
496
- 2. **Multi-Default Coordination**: Specialized handling (C02, C03, C08a, C21b, C28, C29) prevents naming conflicts
497
- 3. **Smart Flattening**: Auto-detection (C04, C05, C12, C13, C18, C30) reduces unnecessary nesting
498
- 4. **Name Preservation**: Function name preference (C16, C19) maintains semantic meaning
499
- 5. **Depth Awareness**: Many conditions check `currentDepth > 0` to preserve root-level structure
685
+ 1. **Detection**: Checks for `newModules.addapi` key in loaded module structure
686
+ 2. **Extraction**: Stores content of `addapi` module in `addapiContent` variable
687
+ 3. **Removal**: Deletes the `addapi` key from `newModules` to prevent namespace creation
688
+ 4. **Flattening**: Merges all exports from `addapi.mjs` directly into root level of `newModules`
689
+ 5. **Type Handling**: Supports both object exports and function exports with properties
500
690
 
501
- ---
691
+ **Use Cases**:
502
692
 
503
- ## Document Maintenance
693
+ - 🔌 **Plugin Systems**: Runtime plugin loading that extends existing API namespaces
694
+ - 🔄 **Hot Reloading**: Dynamic API updates during development without intermediate levels
695
+ - 📦 **Modular Extensions**: Clean extension of existing API surfaces
696
+ - 🎯 **Targeted Integration**: Specific API namespace enhancement for add-on functionality
504
697
 
505
- **Last Full Audit**: December 30, 2025
506
- **Commit**: a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da
507
- **Lines Verified**: All line numbers manually verified against source code
508
- **Links**: All GitHub-style links use `#Lxxx-Lyyy` format for precise navigation
698
+ **Behavior Characteristics**:
699
+
700
+ - ✅ **Always Active**: Works regardless of `autoFlatten` configuration setting
701
+ - ✅ **Priority Processing**: Occurs before other flattening rules are applied
702
+ - ✅ **Transparent Integration**: Exports appear as if they were originally part of target namespace
703
+ - ✅ **Works with addApi Only**: Special handling only applies to `addApi()` method, not initial load
704
+
705
+ **Result**: `addapi.mjs` file contents are merged directly at the target API path level, eliminating the intermediate `.addapi.` namespace
706
+
707
+ **Common Implementation Pattern**:
708
+
709
+ - ✅ Detection via `newModules.addapi` property check
710
+ - ✅ Extraction and deletion of `addapi` key
711
+ - ✅ Direct merge using `Object.assign(newModules, addapiContent)`
712
+ - ✅ Support for both object and function exports