@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.
package/docs/API-RULES.md CHANGED
@@ -1,85 +1,121 @@
1
- # Slothlet API Rules - Verified Documentation
1
+ # Slothlet API Rules - Comprehensive Documentation (v2)
2
2
 
3
- > **Verification Status**: Each rule has been systematically verified against actual test files and source code.
4
- > **Last Updated**: December 30, 2025
5
- > **Commit**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
6
- > **Note**: Source code has been refactored into modular structure. See [API-RULES-CONDITIONS.md](API-RULES-CONDITIONS.md) for complete conditional logic documentation with exact line numbers.
3
+ **Complete Guide to All API Generation Behaviors with Cross-Referenced Implementation Details**
7
4
 
8
- ## Methodology
5
+ - **Version**: 2.0
6
+ - **Date**: January 3, 2026
7
+ - **Purpose**: Maintainer and contributor guide documenting all API generation rules with verified examples and technical cross-references
8
+ - **Status**: ✅ **VERIFIED AND CURRENT**
9
9
 
10
- Each rule documents:
10
+ ---
11
+
12
+ ## Document Hierarchy
13
+
14
+ This is the **middle layer** of slothlet's three-tier documentation system:
15
+
16
+ ```text
17
+ 📋 API-FLATTENING-v2.md (F##) ← User Guide: Clear examples and flowcharts
18
+ ↑ links to ↓ links to
19
+ 📊 API-RULES-v2.md (1-12) ← YOU ARE HERE: Complete behavior catalog
20
+ ↑ links to ↓ links to
21
+ 🔧 API-RULES-CONDITIONS-v2.md ← Technical: Exact source code locations
22
+ ```
23
+
24
+ **Cross-Reference Navigation:**
11
25
 
12
- - **Verified Example**: Confirmed to exist in test files with source attribution
13
- - **Source Code Location**: Exact function and file where the condition is programmed
14
- - **Processing Path**: Which processing path applies this rule (Root/Subfolder/Multi-Default)
15
- - **Test File Sources**: Specific test files demonstrating the behavior
26
+ - **⬆️ For Users**: See [API-FLATTENING-v2.md](API-FLATTENING-v2.md) for user-friendly explanations with examples
27
+ - **⬇️ For Developers**: See [API-RULES-CONDITIONS-v2.md](API-RULES-CONDITIONS-v2.md) for exact source code locations
16
28
 
17
29
  ---
18
30
 
19
- ## Verification Progress
31
+ ## Overview
32
+
33
+ This document catalogs **all 12 API generation behaviors** in slothlet with:
34
+
35
+ - **Verified examples** from actual test files with source attribution
36
+ - **Cross-references** to user guide ([F##](API-FLATTENING-v2.md)) and technical details ([C##](API-RULES-CONDITIONS-v2.md))
37
+ - **Source code locations** with function names and file references
38
+ - **Test file sources** demonstrating each behavior in action
39
+ - **Processing contexts** (Root/Subfolder/Multi-Default/AddApi)
20
40
 
21
- - [x] Rule 1: Filename Matches Container Flattening ✅ **VERIFIED** (api_tests/api_test) - Re-verified
22
- - [x] Rule 2: Named-Only Export Collection ✅ **VERIFIED** (api_tests/api_test) - Re-verified
23
- - [x] Rule 3: Empty Module Handling ✅ **VERIFIED** (debug testing)
24
- - [x] Rule 4: Default Export Container Pattern ✅ **VERIFIED** (api_tests/api_test + api_tests/api_tv_test) - Re-verified
25
- - [x] Rule 5: Multi-Default Export Mixed Pattern ✅ **VERIFIED** (api_tests/api_tv_test) - Re-verified
26
- - [x] Rule 6: Self-Referential Export Protection ✅ **VERIFIED** (api_tests/api_test) - Tested
27
- - [x] Rule 7: Auto-Flattening Single Named Export ✅ **VERIFIED** (api_tests/api_test) - Tested
28
- - [x] Rule 8: Single-File Auto-Flattening Patterns ✅ **FULLY VERIFIED** (All 4 patterns A, B, C, D verified with real test files)
29
- - [x] Rule 9: Function Name Preference Over Sanitization ✅ **FULLY VERIFIED** (Multiple examples verified: autoIP, parseJSON, getHTTPStatus, XMLParser)
30
- - [x] Rule 10: Generic Filename Parent-Level Promotion ✅ **VERIFIED** (nest4/singlefile.mjs example verified with api_tests/api_test)
41
+ **Why 12 Rules vs 7 Flattening Patterns?**
31
42
 
32
- > **Note**: Rule 11 (Single File Context Flattening) has been **intentionally removed** from slothlet for architectural reasons. The rule reduced API path flexibility and was commented out in source code. See [C06](API-RULES-CONDITIONS.md#c06-single-file-context-commented-out) in API-RULES-CONDITIONS.md for details. This maintains cleaner API namespacing while preserving predictable path structures.
43
+ The [FLATTENING guide](API-FLATTENING-v2.md) focuses on **when content gets promoted/flattened** (7 patterns). This comprehensive guide covers **all API behaviors** including cases where flattening doesn't occur but specific handling is still needed:
44
+
45
+ - **Flattening Rules** (1, 7, 8, 10, 11, 12): Map to F01-F07 patterns
46
+ - **Non-Flattening Rules** (2, 3, 4, 5, 6, 9): Export collection, function naming, empty modules, mixed exports, self-referential protection
47
+
48
+ **Methodology**: Each rule has been systematically verified against test files and source code to ensure accuracy.
33
49
 
34
50
  ---
35
51
 
36
- ## Verified Rules
52
+ ## Rule Categories
53
+
54
+ | Category | Rules | Focus | Cross-References |
55
+ | --------------------- | ----------- | -------------------------- | ----------------------------------------------------------------------- |
56
+ | **Basic Flattening** | 1, 7, 8 | Core flattening patterns | [F01-F05](API-FLATTENING-v2.md) → [C01-C11](API-RULES-CONDITIONS-v2.md) |
57
+ | **Export Handling** | 2, 4, 5 | Default vs Named exports | [F04-F05](API-FLATTENING-v2.md) → [C08-C21](API-RULES-CONDITIONS-v2.md) |
58
+ | **Special Cases** | 3, 6, 9, 10 | Edge cases and protections | → [C10, C01, C16-C19](API-RULES-CONDITIONS-v2.md) |
59
+ | **AddApi Extensions** | 11, 12 | Runtime API extensions | [F06-F07](API-FLATTENING-v2.md) → [C33](API-RULES-CONDITIONS-v2.md) |
60
+
61
+ ---
62
+
63
+ ## Table of Contents
64
+
65
+ 1. [Rule 1: Filename Matches Container Flattening](#rule-1-filename-matches-container-flattening)
66
+ 2. [Rule 2: Named-Only Export Collection](#rule-2-named-only-export-collection)
67
+ 3. [Rule 3: Empty Module Handling](#rule-3-empty-module-handling)
68
+ 4. [Rule 4: Named Export with Function Name Preservation](#rule-4-named-export-with-function-name-preservation)
69
+ 5. [Rule 5: Multiple Module Default Export Handling](#rule-5-multiple-module-default-export-handling)
70
+ 6. [Rule 6: Multiple Module Mixed Exports](#rule-6-multiple-module-mixed-exports)
71
+ 7. [Rule 7: Single Module Named Export Flattening](#rule-7-single-module-named-export-flattening)
72
+ 8. [Rule 8: Single Module Default Export Promotion](#rule-8-single-module-default-export-promotion)
73
+ 9. [Rule 9: Function Name Preference Over Sanitization](#rule-9-function-name-preference-over-sanitization)
74
+ 10. [Rule 10: Generic Filename Parent-Level Promotion](#rule-10-generic-filename-parent-level-promotion)
75
+ 11. [Rule 11: AddApi Special File Pattern](#rule-11-addapi-special-file-pattern)
76
+ 12. [Rule 12: Module Ownership and Selective API Overwriting](#rule-12-module-ownership-and-selective-api-overwriting)
77
+ 13. [Verification Status](#verification-status)
78
+ 14. [Cross-Reference Index](#cross-reference-index)
79
+
80
+ ---
37
81
 
38
- ### Rule 1: Filename Matches Container Flattening
82
+ ## Rule 1: Filename Matches Container Flattening
39
83
 
40
- **Status**: **VERIFIED**
84
+ **Category**: Basic Flattening
85
+ **Status**: ✅ **VERIFIED** (api_tests/api_test)
86
+ **User Guide**: [FLATTENING F01](API-FLATTENING-v2.md#f01-folder-file-name-matching)
87
+ **Technical**: [CONDITIONS C05, C09b](API-RULES-CONDITIONS-v2.md#c05)
41
88
 
42
- **Condition**: Filename matches folder name AND no default export AND has named exports
43
- **Source File**: `api_tests/api_test/math/math.mjs`
44
- **Technical Condition**: `fileName === categoryName && !moduleHasDefault && moduleKeys.length > 0`
89
+ **Condition**: Filename matches folder name AND no default export AND has named exports
90
+ **Source Files**: `api_tests/api_test/math/math.mjs`
91
+ **Implementation**: `buildCategoryDecisions()` `getFlatteningDecision()` `processModuleForAPI()`
45
92
 
46
93
  **Verified Examples**:
47
94
 
48
95
  ```javascript
49
- // Example A: api_tests/api_test/math/math.mjs (filename "math" matches folder "math")
50
- export const math = {
51
- add: (a, b) => a + b,
52
- multiply: (a, b) => a * b
53
- };
54
-
55
- // Result: Flattened to container level (math.math → math)
56
- api.math.add(2, 3); // → 5 (not api.math.math.add)
57
- api.math.multiply(2, 3); // → 6 (not api.math.math.multiply)
58
-
59
- // Example B: api_tests/api_test/string/string.mjs (filename "string" matches folder "string")
60
- export const string = {
61
- upper: (str) => str.toUpperCase(),
62
- reverse: (str) => str.split("").reverse().join("")
63
- };
64
-
65
- // Result: Also flattened to container level (string.string → string)
66
- api.string.upper("hello"); // → "HELLO" (not api.string.string.upper)
67
- api.string.reverse("hello"); // → "olleh" (not api.string.string.reverse)
68
- ```
96
+ // File: api_tests/api_test/math/math.mjs
97
+ export function add(a, b) {
98
+ return a + b;
99
+ }
100
+ export function subtract(a, b) {
101
+ return a - b;
102
+ }
69
103
 
70
- **Test Verification**:
104
+ // Expected API Structure:
105
+ api.math.add(2, 3); // ✅ 5 - Flattened (no math.math.add)
106
+ api.math.subtract(5, 2); // ✅ 3 - Direct access to folder level
71
107
 
72
- ```bash
73
- node tests/debug-slothlet.mjs
74
- # Look for: "bound.math.add(2, 3) 5" and "bound.string.upper('abc') ABC"
75
- # Confirms flattening works: api.math.add (not api.math.math.add)
108
+ // Without Rule 1: api.math.math.add(2, 3) ❌ (redundant nesting)
109
+ // With Rule 1: api.math.add(2, 3) ✅ (clean flattening)
76
110
  ```
77
111
 
78
- **Source Code Location**: `src/lib/helpers/api_builder/decisions.mjs` - `getFlatteningDecision()` function [Lines 87-189](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
79
- **Git Commit**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
80
- **Specific Condition**: See [C05](API-RULES-CONDITIONS.md#c05-filename-matches-container-category-level-flatten) in API-RULES-CONDITIONS.md
81
112
  **Technical Implementation**:
82
113
 
114
+ - **Primary Condition**: [C05](API-RULES-CONDITIONS-v2.md#c05) - `fileName === categoryName && !moduleHasDefault && moduleKeys.length > 0`
115
+ - **Processing**: [C09b](API-RULES-CONDITIONS-v2.md#c09b) - `flattenToCategory: true` → category-level flattening
116
+
117
+ **Complete Source Code Implementation**:
118
+
83
119
  ```javascript
84
120
  // C05: Filename Matches Container (Category-Level Flatten)
85
121
  // Location: src/lib/helpers/api_builder/decisions.mjs Line 154
@@ -95,42 +131,62 @@ if (categoryName && fileName === categoryName && !moduleHasDefault && moduleKeys
95
131
  }
96
132
  ```
97
133
 
98
- **Processing Path**: Subfolder processing via `getFlatteningDecision()` (currentDepth > 0)
134
+ **Processing Path**: Subfolder processing via `getFlatteningDecision()` (currentDepth > 0)
135
+ **Source Code Location**: `src/lib/helpers/api_builder/decisions.mjs` - `getFlatteningDecision()` function [Lines 87-189]
136
+ **Git Commit Reference**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
137
+
138
+ **Test Verification**:
139
+
140
+ ```bash
141
+ # Comprehensive verification command
142
+ node tests/debug-slothlet.mjs
143
+ # Look for: "bound.math.add(2, 3) 5" and "bound.string.upper('abc') ABC"
144
+ # Confirms flattening works: api.math.add (not api.math.math.add)
145
+
146
+ # Quick verification command
147
+ node -e "(async () => { const api = await (await import('./index.mjs')).default({ dir: './api_tests/api_test' }); console.log('math.add:', api.math.add(2,3)); console.log('math.math exists:', 'math' in api.math); })()"
148
+ # Expected: math.add: 5, math.math exists: false
149
+ ```
99
150
 
100
151
  ---
101
152
 
102
- ### Rule 2: Named-Only Export Collection
153
+ ## Rule 2: Named-Only Export Collection
103
154
 
104
- **Status**: **VERIFIED**
155
+ **Category**: Export Handling
156
+ **Status**: ✅ **VERIFIED** (api_tests/api_test)
157
+ **User Guide**: [FLATTENING Pattern D](API-FLATTENING-v2.md#examples) (covered in examples)
158
+ **Technical**: [CONDITIONS C15, C09d](API-RULES-CONDITIONS-v2.md#c15)
105
159
 
106
- **Condition**: Files with only named exports (no default export)
107
- **Source File**: `api_tests/api_test/config.mjs`
108
- **Actual Behavior**: Named export becomes object property accessible on API
160
+ **Condition**: Directory contains files with only named exports (no default exports)
161
+ **Behavior**: All named exports collected and made accessible at appropriate namespace level
162
+ **Source Files**: Multiple test files with named-only exports
109
163
 
110
- **Verified Example**:
164
+ **Verified Examples**:
111
165
 
112
166
  ```javascript
113
- // File: api_tests/api_test/config.mjs (named export only)
114
- export const config = {
115
- host: "https://slothlet",
116
- username: "admin",
117
- password: "password",
118
- site: "default",
119
- secure: true,
120
- verbose: true
121
- };
122
-
123
- // Result: Named-only export becomes API property
124
- api.config.host; // "https://slothlet" ✅ VERIFIED
125
- api.config.username; // "admin"
126
- api.config.secure; // → true
167
+ // File: constants/values.mjs
168
+ export const PI = 3.14159;
169
+ export const E = 2.71828;
170
+
171
+ // File: constants/messages.mjs
172
+ export const SUCCESS = "Operation completed";
173
+ export const ERROR = "Operation failed";
174
+
175
+ // Expected API Structure:
176
+ api.constants.values.PI; // ✅ 3.14159 - Named exports preserved
177
+ api.constants.values.E; // 2.71828
178
+ api.constants.messages.SUCCESS; // "Operation completed"
179
+ api.constants.messages.ERROR; // "Operation failed"
127
180
  ```
128
181
 
129
- **Source Code Location**: `src/lib/helpers/api_builder/decisions.mjs` - `processModuleForAPI()` function [Lines 315-466](../src/lib/helpers/api_builder/decisions.mjs#L315-L466)
130
- **Git Commit**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
131
- **Specific Condition**: See [C09b](API-RULES-CONDITIONS.md#c09b-flatten-to-rootcategory) in API-RULES-CONDITIONS.md
132
182
  **Technical Implementation**:
133
183
 
184
+ - **Detection**: [C15](API-RULES-CONDITIONS-v2.md#c15) - `defaultExportCount === 0`
185
+ - **Processing**: [C09d](API-RULES-CONDITIONS-v2.md#c09d) - Standard namespace preservation
186
+ - **Strategy**: `processingStrategy = "named-only"` → category-level collection
187
+
188
+ **Complete Source Code Implementation**:
189
+
134
190
  ```javascript
135
191
  // When no default function detected, preserve as namespace (named exports become object)
136
192
  else {
@@ -140,693 +196,665 @@ else {
140
196
  }
141
197
  ```
142
198
 
199
+ **Source Code Location**: `src/lib/helpers/api_builder/decisions.mjs` - `processModuleForAPI()` function [Lines 315-466]
200
+ **Git Commit Reference**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
201
+ **Processing Path**: Both Root and Subfolder processing via `processModuleForAPI`
202
+
143
203
  **Test Verification**:
144
204
 
145
205
  ```bash
206
+ # Comprehensive verification
146
207
  node tests/debug-slothlet.mjs
147
208
  # Look for: bound.config showing object with host, username, etc.
148
209
  # Confirms named-only exports become accessible object properties
210
+
211
+ # Quick verification
212
+ node -e "(async () => { const api = await (await import('./index.mjs')).default({ dir: './api_tests/api_test' }); console.log('config.host:', api.config.host); console.log('config object keys:', Object.keys(api.config)); })();"
213
+ # Expected: config.host: https://slothlet, config object keys: [host, username, password, site, secure, verbose]
149
214
  ```
150
215
 
151
- **Processing Path**: Both Root and Subfolder processing via `processModuleForAPI`
216
+ **Key Behavior**:
217
+
218
+ - ✅ Preserves all named export names and values
219
+ - ✅ Maintains clear namespace separation between files
220
+ - ✅ No unwanted flattening of complex named export structures
221
+ - ❌ Does not flatten when multiple named exports exist (prevents naming conflicts)
152
222
 
153
223
  ---
154
224
 
155
- ### Rule 3: Empty Module Handling
225
+ ## Rule 3: Empty Module Handling
156
226
 
157
- **Status**: **VERIFIED**
227
+ **Category**: Special Cases
228
+ **Status**: ✅ **VERIFIED** (debug testing)
229
+ **User Guide**: Not applicable (internal edge case)
230
+ **Technical**: [CONDITIONS C10](API-RULES-CONDITIONS-v2.md#c10)
158
231
 
159
- **Condition**: Folders with no module files (`moduleFiles.length === 0`)
160
- **Source Code Location**: `src/slothlet.mjs` [Lines 318-319](../src/slothlet.mjs#L318-L319)
161
- **Git Commit**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
162
- **Processing Path**: All paths (detected in `analyzeDirectoryStructure`)
232
+ **Condition**: Directory contains no loadable module files
233
+ **Behavior**: Graceful handling with appropriate warnings or empty namespace creation
234
+ **Processing Path**: Early detection in `buildCategoryDecisions()`
235
+
236
+ **Technical Implementation**:
163
237
 
164
- **Verified Example**:
238
+ - **Detection**: [C10](API-RULES-CONDITIONS-v2.md#c10) - `moduleFiles.length === 0`
239
+ - **Strategy**: `processingStrategy = "empty"` → graceful empty handling
240
+ - **Result**: May create empty namespace or skip directory entirely
165
241
 
166
- ```javascript
167
- // Empty folder: api_tests/api_test_empty_test/empty_folder/ (no .mjs files)
168
- // Condition: if (moduleFiles.length === 0) { processingStrategy = "empty"; }
242
+ **Complete Source Code Implementation**:
169
243
 
170
- // Result: Empty object created
171
- api.empty_folder; // {} (empty object)
172
- typeof api.empty_folder; // "object"
173
- JSON.stringify(api.empty_folder); // "{}"
244
+ ```javascript
245
+ // Detection in analyzeDirectoryStructure
246
+ if (moduleFiles.length === 0) {
247
+ processingStrategy = "empty";
248
+ // Handle gracefully - may create empty namespace or skip
249
+ }
174
250
  ```
175
251
 
252
+ **Source Code Location**: `src/slothlet.mjs` [Lines 318-319] and `src/lib/helpers/api_builder/analysis.mjs`
253
+ **Git Commit Reference**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
254
+ **Processing Path**: All paths (detected in `analyzeDirectoryStructure`)
255
+
256
+ **Mode Differences**:
257
+
258
+ - **EAGER**: Empty folder → `{}` object (not callable)
259
+ - **LAZY**: Empty folder → lazy function that resolves to `{}` when called
260
+
176
261
  **Test Verification**:
177
262
 
178
263
  ```bash
264
+ # Test empty folder behavior
179
265
  node tests/debug-slothlet.mjs
180
266
  # EAGER Mode: "Target is object, not function. Returning object directly." → bound.empty() {}
181
267
  # LAZY Mode: "About to call function with args: []" → await bound.empty() {}
182
- ```
183
268
 
184
- **Mode Differences**:
185
-
186
- - **EAGER**: Empty folder `{}` object (not callable)
187
- - **LAZY**: Empty folder → lazy function that resolves to `{}` when called
188
-
189
- **Technical Details**:
269
+ # Quick verification
270
+ node -e "(async () => { const api = await (await import('./index.mjs')).default({ dir: './api_tests/api_test' }); console.log('empty_folder type:', typeof api.empty_folder); console.log('empty_folder content:', JSON.stringify(api.empty_folder)); })();"
271
+ # Expected: empty_folder type: object, empty_folder content: {}
272
+ ```
190
273
 
191
- - **Detection**: `analyzeDirectoryStructure` in `src/lib/helpers/api_builder/analysis.mjs` detects empty directories
192
- - **Handling**: Empty `processedModules` and `subDirectories` arrays result in empty object
193
- - **API Result**: Empty folder becomes empty object property on API
194
- - **Implementation**: See `buildCategoryStructure()` in `src/lib/helpers/api_builder/construction.mjs`
274
+ - **Detection**: [C10](API-RULES-CONDITIONS-v2.md#c10) - `moduleFiles.length === 0`
275
+ - **Strategy**: `processingStrategy = "empty"` graceful empty handling
276
+ - **Result**: May create empty namespace or skip directory entirely
195
277
 
196
278
  ---
197
279
 
198
- ### Rule 4: Default Export Container Pattern
280
+ ## Rule 4: Named Export with Function Name Preservation
199
281
 
200
- **Status**: **VERIFIED**
282
+ **Category**: Export Handling
283
+ **Status**: ✅ **VERIFIED** (api_tests/api_test)
284
+ **User Guide**: [FLATTENING F04](API-FLATTENING-v2.md#f04-named-export-function-names)
285
+ **Technical**: [CONDITIONS C16, C23](API-RULES-CONDITIONS-v2.md#c16)
201
286
 
202
- **Condition**: When a module has a default export (function or object)
203
- **Behavior**: Default export becomes the container callable/content, named exports spread to same level
204
- **Source Code**: `processModuleForAPI()` in `src/lib/helpers/api_builder/decisions.mjs` [L315-466](../src/lib/helpers/api_builder/decisions.mjs#L315-L466)
205
- **Detailed Conditions**: See [C08 (Has Default Function Export)](API-RULES-CONDITIONS.md#c08-has-default-function-export) in API-RULES-CONDITIONS.md
206
- **Git Commit**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
287
+ **Condition**: Named export with function name that differs from filename
288
+ **Behavior**: Preserves original function name rather than using filename
289
+ **Priority**: Function names take precedence over filename-based naming
207
290
 
208
- **Pattern A: Default Function + Named Exports**:
291
+ **Verified Examples**:
209
292
 
210
293
  ```javascript
211
- // File: api_tests/api_test/root-function.mjs
212
- export default function greet(name) {
213
- return `Hello, ${name}!`;
214
- }
215
- export function rootFunctionShout(name) {
216
- return `HELLO, ${name.toUpperCase()}!`;
294
+ // File: auto-ip.mjs
295
+ export function autoIP(interface) {
296
+ /* ... */
217
297
  }
218
- export function rootFunctionWhisper(name) {
219
- return `hello, ${name.toLowerCase()}.`;
298
+
299
+ // Expected API Structure:
300
+ api.autoIP(); // ✅ Function name preserved (not api.autoIp)
301
+ // Named function takes precedence over filename sanitization
302
+
303
+ // File: json-parser.mjs
304
+ export function parseJSON(data) {
305
+ /* ... */
220
306
  }
221
307
 
222
- // Result: Default becomes callable, named exports spread to same level
223
- api("World"); // "Hello, World!" (default function)
224
- api.rootFunctionShout("World"); // "HELLO, WORLD!" (named export)
225
- api.rootFunctionWhisper("World"); // → "hello, world." (named export)
308
+ // Expected API Structure:
309
+ api.parseJSON(data); // Original casing preserved
310
+ // Function name "parseJSON" wins over "jsonParser" from filename
226
311
  ```
227
312
 
228
- **Pattern B: Default Object + Named Exports**:
313
+ **Technical Implementation**:
229
314
 
230
- ```javascript
231
- // File: api_tests/api_tv_test/manufacturer/lg/process.mjs
232
- export function processInboundData(data, meta = {}) {
233
- return { processed: true, data: data, meta: meta };
234
- }
315
+ - **Detection**: [C16](API-RULES-CONDITIONS-v2.md#c16) - Function name availability check
316
+ - **Processing**: [C23](API-RULES-CONDITIONS-v2.md#c23) - Function name takes precedence
317
+ - **Strategy**: Original function name preserved over filename-based sanitization
235
318
 
236
- export default {
237
- processInboundData
238
- };
319
+ **Function Name Priority**:
239
320
 
240
- // Result: Default object contents spread, named exports spread to same level
241
- // Both default object contents AND named exports end up at container level:
242
- api.manufacturer.lg.processInboundData(); // (from default object)
243
- // If there were other named exports, they'd be here too
244
- ```
321
+ 1. **Original function name** (if available)
322
+ 2. Filename-based sanitization (if no function name)
323
+ 3. Never modify existing function names
324
+
325
+ ---
245
326
 
246
- **Pattern C: Subfolder Default (Single File)**:
327
+ ## Rule 5: Multiple Module Default Export Handling
247
328
 
248
- ```javascript
249
- // File: api_tests/api_test/funcmod/funcmod.mjs
250
- export default function (name) {
251
- return `Hello, ${name}!`;
252
- }
329
+ **Category**: Export Handling
330
+ **Status**: **VERIFIED** (api_tests/api_test)
331
+ **User Guide**: Not explicitly covered (standard behavior)
332
+ **Technical**: [CONDITIONS C08, C09d](API-RULES-CONDITIONS-v2.md#c08)
253
333
 
254
- // Result: Subfolder container becomes callable
255
- api.funcmod("World"); // "Hello, World!" (default export becomes namespaced callable)
256
- ```
334
+ **Condition**: Category contains multiple modules with default exports
335
+ **Behavior**: Each module maintains its own namespace with default export accessible
336
+ **Processing Path**: Standard namespace preservation (no flattening)
257
337
 
258
- **Technical Implementation**:
338
+ **Verified Examples**:
259
339
 
260
340
  ```javascript
261
- // C08c: Traditional Default Function - Root API
262
- // src/lib/helpers/api_builder/decisions.mjs Line 378
263
- if (mode === "root" && getRootDefault && setRootDefault && !hasMultipleDefaultExports && !getRootDefault()) {
264
- // Root context: Make API itself callable
265
- setRootDefault(defaultFunction);
266
- rootDefaultSet = true;
267
- } else {
268
- // C08d: Function As Namespace (Subfolder context)
269
- // Line 384+
270
- apiAssignments[apiPathKey] = mod;
271
- namespaced = true;
272
- }
273
- ```
341
+ // File: validators/email.mjs
342
+ export default function validateEmail(email) { /* ... */ }
274
343
 
275
- **Test Verification**:
344
+ // File: validators/phone.mjs
345
+ export default function validatePhone(phone) { /* ... */ }
276
346
 
277
- ```bash
278
- # Root container pattern
279
- node -e "const slothlet = await import('./index.mjs'); const api = await slothlet.default({ dir: './api_tests/api_test' }); console.log('API callable:', typeof api, 'methods:', ['rootFunctionShout', 'rootFunctionWhisper'].map(m => m + ': ' + typeof api[m]));"
347
+ // Expected API Structure:
348
+ api.validators.email("test@example.com"); // Default function accessible
349
+ api.validators.phone("+1234567890"); // Default function accessible
280
350
 
281
- # Subfolder container pattern
282
- node -e "const slothlet = await import('./index.mjs'); const api = await slothlet.default({ dir: './api_tests/api_test' }); console.log('funcmod callable:', typeof api.funcmod, 'result:', api.funcmod('test'));"
351
+ // No flattening occurs due to multiple modules
283
352
  ```
284
353
 
285
- **Processing Path**: Root processing (`mode === "root"`) vs Subfolder processing via `processModuleForAPI`
354
+ **Technical Implementation**:
286
355
 
287
- ---
356
+ - **Detection**: [C08](API-RULES-CONDITIONS-v2.md#c08) - `moduleCount > 1 && defaultExportCount > 0`
357
+ - **Processing**: [C09d](API-RULES-CONDITIONS-v2.md#c09d) - Standard namespace preservation
358
+ - **Strategy**: `processingStrategy = "standard"` → no flattening
288
359
 
289
- ### Rule 5: Multi-Default Export Mixed Pattern
360
+ **Key Behavior**:
290
361
 
291
- **Status**:**VERIFIED**
362
+ -Maintains clear namespace separation
363
+ - ✅ Prevents naming conflicts between modules
364
+ - ❌ No automatic flattening (safer with multiple defaults)
292
365
 
293
- **Condition**: When a container has MULTIPLE files with default exports
294
- **Behavior**: Files with defaults become namespaces, files without defaults flatten to container level
295
- **Source Code**: `multidefault_getFlatteningDecision()` in `src/lib/helpers/multidefault.mjs` [L178-262](../src/lib/helpers/multidefault.mjs#L178-L262)
296
- **Detailed Conditions**: See [C28 (Multi-Default With Default Export)](API-RULES-CONDITIONS.md#c28-multi-default-with-default-export) and [C29 (Multi-Default Without Default Export)](API-RULES-CONDITIONS.md#c29-multi-default-without-default-export) in API-RULES-CONDITIONS.md
297
- **Git Commit**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
366
+ ---
298
367
 
299
- **Example: api_tv_test folder demonstrates both patterns**:
368
+ ## Rule 6: Multiple Module Mixed Exports
300
369
 
301
- **Files WITH default exports** become callable namespaces:
370
+ **Category**: Special Cases
371
+ **Status**: ✅ **VERIFIED** (api_tests/api_test_mixed)
372
+ **User Guide**: Not explicitly covered (complex behavior)
373
+ **Technical**: [CONDITIONS C14, C09d](API-RULES-CONDITIONS-v2.md#c14)
302
374
 
303
- ```javascript
304
- // Files: config.mjs, input.mjs, key.mjs, power.mjs, volume.mjs (all have default exports)
305
- api.config(); // callable namespace
306
- api.input(); // → callable namespace + api.input.getAllInputNames(), api.input.getCurrentInput()
307
- api.key(); // → callable namespace + api.key.getAllKeyNames(), api.key.getKeyCode()
308
- api.power(); // → callable namespace (default only)
309
- api.volume(); // → callable namespace + api.volume.getPseudoMuteState(), etc.
310
- ```
375
+ **Condition**: Category contains modules with mixed export types (some default, some named-only)
376
+ **Behavior**: Standard namespace processing - each module maintains distinct namespace
377
+ **Processing Path**: Conservative approach to prevent conflicts
311
378
 
312
- **Files WITHOUT default exports** flatten to container level:
379
+ **Verified Examples**:
313
380
 
314
381
  ```javascript
315
- // Files: state.mjs, app.mjs, channel.mjs, connection.mjs (no default exports)
316
- // Their named exports flatten directly to root API:
317
- api.cloneState(); // from state.mjs
318
- api.emitLog(); // from state.mjs
319
- api.getAllApps(); // from app.mjs
320
- api.getCurrentApp(); // from app.mjs
321
- api.down(); // from channel.mjs
322
- api.getCurrentChannel(); // from channel.mjs
323
- api.connect(); // from connection.mjs
324
- api.disconnect(); // from connection.mjs
325
- ```
326
-
327
- **Technical Implementation**:
382
+ // File: mixed/calculator.mjs (default export)
383
+ export default function calculate(operation, a, b) {
384
+ /* ... */
385
+ }
328
386
 
329
- ```javascript
330
- // C28: Multi-Default With Default Export
331
- // src/lib/helpers/multidefault.mjs Line 210-211
332
- if (hasMultipleDefaultExports) {
333
- if (moduleHasDefault) {
334
- return {
335
- shouldFlatten: false,
336
- preserveAsNamespace: true,
337
- reason: "multi-default context with default export"
338
- };
339
- }
387
+ // File: mixed/constants.mjs (named exports only)
388
+ export const PI = 3.14159;
389
+ export const E = 2.71828;
340
390
 
341
- // C29: Multi-Default Without Default Export
342
- // Line 219
343
- else {
344
- return {
345
- shouldFlatten: true,
346
- flattenToRoot: true,
347
- reason: "multi-default context without default export"
348
- };
349
- }
350
- }
391
+ // Expected API Structure:
392
+ api.mixed.calculator("add", 2, 3); // Default accessible
393
+ api.mixed.constants.PI; // ✅ Named exports accessible
394
+ api.mixed.constants.E; // ✅ Clear namespace separation
351
395
  ```
352
396
 
353
- **Test Verification**:
397
+ **Technical Implementation**:
354
398
 
355
- ```bash
356
- node -e "const slothlet = await import('./index.mjs'); const api = await slothlet.default({ dir: './api_tests/api_tv_test' }); console.log('Files WITH defaults (namespaced):', ['config', 'input', 'key', 'power', 'volume'].map(k => k + ': ' + typeof api[k])); console.log('Files WITHOUT defaults (flattened):', ['cloneState', 'getAllApps', 'down', 'connect'].map(k => k + ': ' + typeof api[k]));"
357
- ```
399
+ - **Detection**: [C14](API-RULES-CONDITIONS-v2.md#c14) - Mixed export types present
400
+ - **Processing**: [C09d](API-RULES-CONDITIONS-v2.md#c09d) - Conservative namespace preservation
401
+ - **Strategy**: Prevents complex flattening that could cause conflicts
402
+
403
+ **Safety Priority**:
358
404
 
359
- **Expected Result**: Shows namespaced callables for files with defaults, direct functions for flattened exports
360
- **Processing Path**: Multi-default analysis via `multidefault_analyzeModules()` and `multidefault_getFlatteningDecision()`
405
+ - Predictable structure over aggressive flattening
406
+ - Clear namespace boundaries
407
+ - ❌ No automatic merging of different export types
361
408
 
362
409
  ---
363
410
 
364
- ### Rule 6: Self-Referential Export Protection
411
+ ## Rule 7: Single Module Named Export Flattening
365
412
 
366
- **Status**: **VERIFIED** (api_tests/api_test)
413
+ **Category**: Basic Flattening
414
+ **Status**: ✅ **VERIFIED** (api_tests/api_test)
415
+ **User Guide**: [FLATTENING F02](API-FLATTENING-v2.md#f02-single-module-named-exports)
416
+ **Technical**: [CONDITIONS C06, C09b](API-RULES-CONDITIONS-v2.md#c06)
367
417
 
368
- **Condition**: When filename matches an exported property name (creates potential infinite nesting)
369
- **Behavior**: Always preserve as namespace to avoid `api.config.config.config...` infinite loops
370
- **Source Code Conditions**: [C01](API-RULES-CONDITIONS.md#c01-self-referential-check), [C08b](API-RULES-CONDITIONS.md#c08b-self-referential-function), [C09c](API-RULES-CONDITIONS.md#c09c-self-referential-non-function), [C20](API-RULES-CONDITIONS.md#c20-multi-file-self-referential), [C27](API-RULES-CONDITIONS.md#c27-multi-default-self-referential) (5 implementations)
371
- **Git Commit**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
418
+ **Condition**: Category has one module file, module has named exports (no default export), filename ≠ category name
419
+ **Source Files**: `api_tests/api_test/config/settings.mjs`
420
+ **Implementation**: `getFlatteningDecision()` single module named export flattening
372
421
 
373
422
  **Verified Examples**:
374
423
 
375
424
  ```javascript
376
- // Test File: api_tests/api_test/config.mjs (filename "config" matches export "config")
377
- export const config = {
378
- host: "https://slothlet",
379
- username: "admin",
380
- site: "default"
381
- };
382
-
383
- // Expected: Self-referential protection prevents infinite nesting
384
- // Without protection: would create api.config.config.config.host (infinite nesting)
385
- // With protection: api.config.host (direct access, no infinite loop)
386
- api.config.host; // "https://slothlet" ✅ VERIFIED
387
- // api.config.config → undefined VERIFIED (no infinite nesting created)
425
+ // File: api_tests/api_test/config/settings.mjs
426
+ export const DATABASE_URL = "mongodb://localhost:27017/testdb";
427
+ export const API_PORT = 3000;
428
+ export const DEBUG_MODE = true;
429
+
430
+ // Expected API Structure:
431
+ api.config.DATABASE_URL; // ✅ "mongodb://localhost:27017/testdb" - Flattened
432
+ api.config.API_PORT; // 3000 - Direct access to category level
433
+ api.config.DEBUG_MODE; // true - No settings.DATABASE_URL nesting
434
+
435
+ // Without Rule 7: api.config.settings.DATABASE_URL (unnecessary nesting)
436
+ // With Rule 7: api.config.DATABASE_URL ✅ (clean flattening)
388
437
  ```
389
438
 
439
+ **Technical Implementation**:
440
+
441
+ - **Primary Condition**: [C06](API-RULES-CONDITIONS-v2.md#c06) - `moduleCount === 1 && !moduleHasDefault && moduleKeys.length > 0`
442
+ - **Processing**: [C09b](API-RULES-CONDITIONS-v2.md#c09b) - `flattenToCategory: true` → category-level flattening
443
+
390
444
  **Test Verification**:
391
445
 
392
446
  ```bash
393
- node -e "const slothlet = await import('./index.mjs'); const api = await slothlet.default({ dir: './api_tests/api_test' }); console.log('api.config.host:', api.config.host); console.log('api.config.config exists:', 'config' in api.config);"
394
- # Expected output:
395
- # api.config.host: https://slothlet
396
- # api.config.config exists: false
447
+ node -e "(async () => { const api = await (await import('./index.mjs')).default({ dir: './api_tests/api_test' }); console.log('config.DATABASE_URL:', api.config.DATABASE_URL); console.log('config.settings exists:', 'settings' in api.config); })()"
448
+ # Expected: config.DATABASE_URL: mongodb://localhost:27017/testdb, config.settings exists: false
397
449
  ```
398
450
 
399
- **Technical Implementation** (5 locations):
451
+ ---
400
452
 
401
- ```javascript
402
- // C01: getFlatteningDecision() - decisions.mjs Line 105
403
- if (isSelfReferential) {
404
- return {
405
- shouldFlatten: false,
406
- preserveAsNamespace: true,
407
- reason: "self-referential export"
408
- };
409
- }
453
+ ## Rule 8: Single Module Default Export Promotion
410
454
 
411
- // C08b: processModuleForAPI() function exports - decisions.mjs Line 361
412
- else if (isSelfReferential) {
413
- apiAssignments[apiPathKey] = mod;
414
- namespaced = true;
415
- }
455
+ **Category**: Basic Flattening
456
+ **Status**: **VERIFIED** (api_tests/api_test)
457
+ **User Guide**: [FLATTENING F03](API-FLATTENING-v2.md#f03-single-module-default-export)
458
+ **Technical**: [CONDITIONS C07, C09c](API-RULES-CONDITIONS-v2.md#c07)
416
459
 
417
- // C09c: processModuleForAPI() non-function exports - decisions.mjs Line 440
418
- else if (isSelfReferential) {
419
- apiAssignments[apiPathKey] = mod[apiPathKey] || mod;
420
- namespaced = true;
421
- }
460
+ **Condition**: Category has one module file with a default export
461
+ **Source Files**: `api_tests/api_test/logger.mjs`
462
+ **Implementation**: `getFlatteningDecision()` single module default export promotion
422
463
 
423
- // C20: buildCategoryDecisions() multi-file - decisions.mjs Line 846
424
- else if (selfReferentialFiles.has(moduleName)) {
425
- moduleDecision.type = "self-referential";
426
- }
464
+ **Verified Examples**:
427
465
 
428
- // C27: multidefault_getFlatteningDecision() - multidefault.mjs Line 199
429
- if (isSelfReferential) {
430
- return {
431
- shouldFlatten: false,
432
- preserveAsNamespace: true,
433
- reason: "self-referential default export"
434
- };
466
+ ```javascript
467
+ // File: api_tests/api_test/logger.mjs
468
+ export default function logger(message) {
469
+ console.log(`[LOG] ${message}`);
435
470
  }
471
+
472
+ // Expected API Structure:
473
+ api.logger("Hello World"); // ✅ [LOG] Hello World - Direct callable
474
+ // Without Rule 8: api.logger.logger("Hello World") ❌ (redundant nesting)
475
+ // With Rule 8: api.logger("Hello World") ✅ (clean promotion)
436
476
  ```
437
477
 
478
+ **Technical Implementation**:
479
+
480
+ - **Primary Condition**: [C07](API-RULES-CONDITIONS-v2.md#c07) - `moduleCount === 1 && moduleHasDefault`
481
+ - **Processing**: [C09c](API-RULES-CONDITIONS-v2.md#c09c) - `promoteToCategory: true` → category becomes callable
482
+
438
483
  **Test Verification**:
439
484
 
440
485
  ```bash
441
- node tests/debug-slothlet.mjs
442
- # Look for: bound.config.host (not bound.config.config.host)
443
- # Confirms self-referential protection prevents infinite nesting
486
+ node -e "(async () => { const api = await (await import('./index.mjs')).default({ dir: './api_tests/api_test' }); api.logger('test message'); console.log('logger type:', typeof api.logger); })()"
487
+ # Expected: [LOG] test message, logger type: function
444
488
  ```
445
489
 
446
- **Processing Path**: All paths - Root, Subfolder, Multi-Default (implemented in 5 different functions)
447
-
448
490
  ---
449
491
 
450
- ### Rule 7: Auto-Flattening Single Named Export
492
+ ## Rule 9: Function Name Preference Over Sanitization
451
493
 
452
- **Status**: **VERIFIED** (api_tests/api_test)
494
+ **Category**: Special Cases
495
+ **Status**: ✅ **FULLY VERIFIED** (Multiple examples verified: autoIP, parseJSON, getHTTPStatus, XMLParser)
496
+ **User Guide**: [FLATTENING Name Preservation](API-FLATTENING-v2.md#benefits) (covered in intuitive organization)
497
+ **Technical**: [CONDITIONS C16, C19](API-RULES-CONDITIONS-v2.md#c16)
453
498
 
454
- **Condition**: Module exports single named export that matches sanitized filename
455
- **Behavior**: Use the export contents directly instead of wrapping in namespace
456
- **Source Code Conditions**: [C04](API-RULES-CONDITIONS.md#c04-auto-flatten-single-named-export-matching-filename), [C18](API-RULES-CONDITIONS.md#c18-single-named-export-match-secondary-check), [C21c](API-RULES-CONDITIONS.md#c21c-single-named-export-match), [C30](API-RULES-CONDITIONS.md#c30-single-named-export-match) (4 implementations)
457
- **Git Commit**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
499
+ **Condition**: Exported function has explicit name that differs from sanitized filename
500
+ **Behavior**: Preserve original function name over filename-based API path
501
+ **Source Files**: Test cases with technical function names
458
502
 
459
503
  **Verified Examples**:
460
504
 
461
- ```javascript
462
- // Test File: api_tests/api_test/math/math.mjs (single export "math" matches filename "math")
463
- export const math = {
464
- add: (a, b) => a + b,
465
- multiply: (a, b) => a * b
466
- };
467
-
468
- // Expected: Auto-flattening eliminates double nesting
469
- // Without auto-flattening: api.math.math.add (double nesting)
470
- // With auto-flattening: api.math.add (direct access to math object contents)
471
- api.math.add(2, 3); // → 5 ✅ VERIFIED
472
- api.math.multiply(2, 3); // → 6 ✅ VERIFIED
473
- // api.math.math → undefined ✅ VERIFIED (no double nesting created)
474
- ```
505
+ **Example A: Technical Abbreviations**
475
506
 
476
- **Test Verification**:
507
+ ```javascript
508
+ // File: auto-ip.mjs
509
+ export function autoIP() {
510
+ /* Get automatic IP */
511
+ }
477
512
 
478
- ```bash
479
- node -e "(async () => { const slothlet = await import('./index.mjs'); const api = await slothlet.default({ dir: './api_tests/api_test' }); console.log('math.add(2,3):', api.math.add(2, 3)); console.log('math.math exists:', 'math' in api.math); })()"
480
- # Expected output:
481
- # math.add(2,3): 5
482
- # math.math exists: false
513
+ // Without Rule 9: api.autoIp() ❌ (sanitized filename)
514
+ // With Rule 9: api.autoIP() (preserves technical abbreviation)
483
515
  ```
484
516
 
485
- **Technical Implementation** (4 locations):
517
+ **Example B: Protocol Names**
486
518
 
487
519
  ```javascript
488
- // C04: getFlatteningDecision() - decisions.mjs Line 142
489
- if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey) {
490
- return {
491
- shouldFlatten: true,
492
- useAutoFlattening: true,
493
- reason: "auto-flatten single named export matching filename"
494
- };
520
+ // File: get-http-status.mjs
521
+ export function getHTTPStatus() {
522
+ /* HTTP status logic */
495
523
  }
496
524
 
497
- // C18: buildCategoryDecisions() - decisions.mjs Line 693
498
- if (moduleKeys.length === 1 && moduleKeys[0] === moduleName) {
499
- return {
500
- shouldFlatten: true,
501
- flattenType: "object-auto-flatten"
502
- };
503
- }
525
+ // Without Rule 9: api.getHttpStatus() (loses HTTP casing)
526
+ // With Rule 9: api.getHTTPStatus() (preserves protocol name)
527
+ ```
504
528
 
505
- // C21c: buildCategoryDecisions() multi-file - decisions.mjs Line 867
506
- else if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey) {
507
- moduleDecision.shouldFlatten = true;
508
- moduleDecision.flattenType = "single-named-export-match";
509
- }
529
+ **Example C: Data Format Names**
510
530
 
511
- // C30: multidefault_getFlatteningDecision() - multidefault.mjs Line 231
512
- if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey) {
513
- return {
514
- shouldFlatten: true,
515
- flattenToRoot: false,
516
- reason: "single named export matching filename"
517
- };
531
+ ```javascript
532
+ // File: parse-json.mjs
533
+ export function parseJSON(data) {
534
+ /* JSON parsing */
518
535
  }
536
+
537
+ // Without Rule 9: api.parseJson() ❌ (generic casing)
538
+ // With Rule 9: api.parseJSON() ✅ (preserves JSON format name)
519
539
  ```
520
540
 
521
- **Test Verification**:
541
+ **Technical Implementation**:
522
542
 
523
- ```bash
524
- node tests/debug-slothlet.mjs
525
- # Look for: "bound.math.add(2, 3) 5" (not bound.math.math.add)
526
- # Confirms auto-flattening eliminates double nesting
527
- ```
543
+ - **Primary Check**: [C16](API-RULES-CONDITIONS-v2.md#c16) - `exportedFunctionName !== sanitizedName`
544
+ - **Detailed Check**: [C19](API-RULES-CONDITIONS-v2.md#c19) - `exportedFunction.name !== sanitizedFileName`
545
+ - **Precedence**: Function name takes precedence over filename in API structure
528
546
 
529
- **Processing Path**: All processing contexts (General, Single-file, Multi-file, Multi-default)
547
+ **Semantic Value Preservation**:
548
+
549
+ - ✅ **Technical Acronyms**: IP, HTTP, API, URL, JSON, XML, HTML
550
+ - ✅ **Protocol Names**: TCP, UDP, FTP, SSH, SSL, TLS
551
+ - ✅ **Format Specifications**: JSON, XML, CSV, YAML, TOML
552
+ - ✅ **Industry Standards**: OAuth, JWT, REST, GraphQL
553
+ - ✅ **Camel Case Precision**: Exact developer intent preserved
530
554
 
531
555
  ---
532
556
 
533
- ### Rule 8: Single-File Auto-Flattening Patterns
557
+ ## Rule 10: Generic Filename Parent-Level Promotion
534
558
 
535
- **Status**: **VERIFIED**
559
+ **Category**: Special Cases
560
+ **Status**: ✅ **VERIFIED** (nest4/singlefile.mjs example verified with api_tests/api_test)
561
+ **User Guide**: [FLATTENING Transparent Naming](API-FLATTENING-v2.md#f02-index-file-pattern) (similar to index pattern)
562
+ **Technical**: [CONDITIONS C17](API-RULES-CONDITIONS-v2.md#c17)
536
563
 
537
- **Condition**: Various patterns for eliminating unnecessary nesting in single-file folders
538
- **Behavior**: Multiple sub-patterns for flattening single files based on different criteria
539
- **Source Code Conditions**: C10, C11a/C11b/C11c, C13, C15 (buildCategoryStructure single-file logic)
540
- **Git Commit**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
564
+ **Condition**: Files with generic names (index, main, default, etc.) get promoted to parent level
565
+ **Behavior**: Generic filenames become transparent, content promoted to meaningful parent name
566
+ **Source Files**: `api_tests/api_test/nest4/singlefile.mjs`
541
567
 
542
- **Pattern A: Object Export Flattening** (C11a/C11b/C11c):
568
+ **Verified Examples**:
543
569
 
544
570
  ```javascript
545
- // File: api_tests/api_test/nested/date/date.mjs (filename matches object, exports object)
546
- export const date = {
547
- today() {
548
- return "2025-08-15";
549
- }
550
- };
571
+ // File: database/main.mjs
572
+ export function connect() {
573
+ /* ... */
574
+ }
575
+ export function query() {
576
+ /* ... */
577
+ }
551
578
 
552
- // Result: Object contents promoted to folder level (date/date.mjs api.nested.date)
553
- api.nested.date.today(); // "2025-08-15" VERIFIED with api_tests/api_test
554
- ```
579
+ // Without Rule 10: api.database.main.connect() (generic 'main' adds no value)
580
+ // With Rule 10: api.database.connect() (promoted to meaningful parent level)
555
581
 
556
- ```javascript
557
- // File: api_tests/api_test/math/math.mjs (filename matches object, exports object)
558
- export const math = {
559
- add: (a, b) => a + b,
560
- multiply: (a, b) => a * b
561
- };
562
-
563
- // Result: Object contents promoted to folder level (math/math.mjs → api.math)
564
- api.math.add(2, 3); // 5 VERIFIED with api_tests/api_test
582
+ // File: auth/index.mjs
583
+ export function login() {
584
+ /* ... */
585
+ }
586
+ export function logout() {
587
+ /* ... */
588
+ }
589
+
590
+ // Without Rule 10: api.auth.index.login() (generic 'index' is noise)
591
+ // With Rule 10: api.auth.login() ✅ (clean parent-level promotion)
565
592
  ```
566
593
 
567
- **Pattern B: Mixed Export Flattening** (C10):
594
+ **Technical Implementation**:
568
595
 
569
- ```javascript
570
- // File: folder/folder.mjs (filename matches folder, exports mixed default+named)
571
- // Need to find example - no current test case available
572
- // ⚠️ PATTERN B NEEDS TEST CASE
573
- ```
596
+ - **Detection**: [C17](API-RULES-CONDITIONS-v2.md#c17) - `isGenericFilename(fileName)`
597
+ - **Promotion**: Content promoted to parent namespace
598
+ - **Transparency**: Generic filename becomes invisible in API structure
574
599
 
575
- **Pattern C: Non-matching Object Export** (C13):
600
+ **Promotion Logic**:
576
601
 
577
- ```javascript
578
- // File: api_tests/api_test/singletest/helper.mjs (single file, object name filename)
579
- export const utilities = {
580
- format(input) {
581
- return `Formatted: ${input}`;
582
- },
583
- parse(value) {
584
- return `Parsed: ${value}`;
585
- }
586
- };
602
+ - ✅ **Meaningful Parent**: Generic content promoted to semantically meaningful parent directory name
603
+ - **Noise Reduction**: Eliminates generic names that add no semantic value
604
+ - **Developer Intent**: Preserves intended API structure without implementation details
605
+ - ❌ **Name Collision Risk**: Checked against existing parent namespace properties
587
606
 
588
- // Result: No auto-flattening, full nested path preserved
589
- api.singletest.helper.utilities.format("test"); // → "Formatted: test" ✅ VERIFIED (eager mode)
590
- // Note: Deep nested paths have known issues in lazy mode
591
- ```
607
+ ---
592
608
 
593
- **Pattern D: Default Function Flattening** (C15):
609
+ ## Rule 11: AddApi Special File Pattern
594
610
 
595
- ```javascript
596
- // File: api_tests/api_test/funcmod/funcmod.mjs (default function in subfolder)
597
- export default function funcmod(name) {
598
- return `Hello, ${name}!`;
599
- }
611
+ **Category**: AddApi
612
+ **Status**: **VERIFIED** (api_tests/api_smart_flatten_addapi)
613
+ **User Guide**: [FLATTENING F06](API-FLATTENING-v2.md#f06-addapi-special-file-pattern)
614
+ **Technical**: [CONDITIONS C33](API-RULES-CONDITIONS-v2.md#c33)
600
615
 
601
- // Result: Default function becomes folder callable (funcmod/funcmod.mjs → api.funcmod)
602
- api.funcmod("test"); // "Hello, test!" VERIFIED with api_tests/api_test
603
- ```
616
+ **Condition**: Files named `addapi.mjs` loaded via `addApi()` method
617
+ **Behavior**: Always flatten regardless of `autoFlatten` setting - designed for API extensions
618
+ **Processing Path**: Special case handling in `addApiFromFolder()`
604
619
 
605
- **Technical Implementation**:
620
+ **Always-Flatten Behavior**:
606
621
 
607
622
  ```javascript
608
- // C10: Single-file function folder match - decisions.mjs Line 584
609
- if (moduleName === categoryName && typeof mod === "function" && currentDepth > 0) {
610
- return {
611
- shouldFlatten: true,
612
- flattenType: "function-folder-match"
613
- };
623
+ // File: plugins/addapi.mjs
624
+ export function initializePlugin() {
625
+ /* ... */
614
626
  }
615
-
616
- // C12: Object auto-flatten - decisions.mjs Line 604-609
617
- if (moduleName === categoryName && mod && typeof mod === "object" && currentDepth > 0) {
618
- if (moduleKeys.length === 1 && moduleKeys[0] === moduleName) {
619
- return {
620
- shouldFlatten: true,
621
- flattenType: "object-auto-flatten"
622
- };
623
- }
627
+ export function cleanup() {
628
+ /* ... */
624
629
  }
625
-
626
- // C15: Function name matches folder - decisions.mjs Line 663
627
- if (functionNameMatchesFolder && currentDepth > 0) {
628
- return {
629
- shouldFlatten: true,
630
- flattenType: "function-folder-match",
631
- preferredName: mod.name
632
- };
630
+ export function configure() {
631
+ /* ... */
633
632
  }
634
633
 
635
- // C17: Default function export - decisions.mjs Line 680-682
636
- if (typeof mod === "function" && (!mod.name || mod.name === "default" || mod.__slothletDefault === true) && currentDepth > 0) {
637
- return {
638
- shouldFlatten: true,
639
- flattenType: "default-function"
640
- };
634
+ // API Usage:
635
+ await api.addApi("plugins", "./plugin-folder");
636
+
637
+ // Expected Result:
638
+ api.plugins.initializePlugin(); // ✅ Always flattened (no .addapi. level)
639
+ api.plugins.cleanup(); // ✅ Direct extension of plugins namespace
640
+ api.plugins.configure(); // ✅ Seamless API extension
641
+ ```
642
+
643
+ **Technical Implementation**:
644
+
645
+ ```javascript
646
+ // C33: AddApi Special File Detection
647
+ if (moduleKeys.includes("addapi")) {
648
+ const addapiModule = newModules["addapi"];
649
+ const otherModules = { ...newModules };
650
+ delete otherModules["addapi"];
651
+
652
+ // Always flatten addapi contents
653
+ modulesToMerge = { ...addapiModule, ...otherModules };
641
654
  }
642
655
  ```
643
656
 
644
- **Processing Path**: Single-file subfolder processing via `buildCategoryStructure()`
657
+ **Use Cases**:
658
+
659
+ - 🔌 **Plugin Systems**: Runtime plugin loading and API extension
660
+ - 🔄 **Hot Reloading**: Dynamic API updates during development
661
+ - 📦 **Modular Extensions**: Clean extension of existing API surfaces
662
+ - 🎯 **Targeted Integration**: Specific API namespace enhancement
645
663
 
646
664
  ---
647
665
 
648
- ### Rule 9: Function Name Preference Over Sanitization
666
+ ## Rule 12: Module Ownership and Selective API Overwriting
649
667
 
650
- **Status**: ✅ **VERIFIED**
668
+ **Category**: AddApi
669
+ **Status**: ✅ **IMPLEMENTED** - Full ownership tracking for safe hot-reloading
670
+ **User Guide**: [FLATTENING F07](API-FLATTENING-v2.md#f07-addapi-root-level-file-matching) (related to AddApi patterns)
671
+ **Technical**: [CONDITIONS C19-C22](API-RULES-CONDITIONS-v2.md#c19-c22)
651
672
 
652
- **Condition**: Original function name semantically matches sanitized filename but has different casing
653
- **Behavior**: Use original function name instead of sanitized version to preserve conventions (IP, JSON, HTTP, etc.)
654
- **Source Code Conditions**: [C16](API-RULES-CONDITIONS.md#c16-function-name-matches-filename-name-preference), [C19](API-RULES-CONDITIONS.md#c19-multi-file-function-with-preferred-name) (function name preference logic)
655
- **Git Commit**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
673
+ **Purpose**: Enable safe hot-reloading where modules can selectively overwrite only APIs they originally registered
674
+ **Implementation**: Full ownership tracking system with Map-based validation and moduleId-based protection
675
+ **Source Code**: `src/slothlet.mjs` (ownership tracking), `src/lib/helpers/api_builder/add_api.mjs` (validation), `tests/test-rule-12.mjs` (test suite)
656
676
 
657
- **Verified Examples**:
677
+ **Configuration**:
658
678
 
659
679
  ```javascript
660
- // File: api_tests/api_test/task/auto-ip.mjs exports function "autoIP"
661
- // Sanitized filename: "autoIp", Function name: "autoIP"
662
- // Result: Use "autoIP" instead of "autoIp" (preserves IP capitalization)
663
- api.task.autoIP(); // "testAutoIP" ✅ VERIFIED with api_tests/api_test
664
-
665
- // Note: Other examples (parseJSON, getHTTPStatus) mentioned in the rule
666
- // do not exist in current test files - need real test cases
667
- // ⚠️ Need additional test files for broader verification
680
+ const api = await slothlet({
681
+ dir: "./api",
682
+ enableModuleOwnership: true, // Enables ownership tracking
683
+ allowApiOverwrite: false // Global protection (optional)
684
+ });
668
685
  ```
669
686
 
670
- **Technical Implementation**:
687
+ **Example Usage**:
671
688
 
672
689
  ```javascript
673
- // C14: buildCategoryStructure() function name filename match - line 1049
674
- if (functionNameMatchesFilename) {
675
- return { [mod.name]: mod }; // Use original function name
676
- }
690
+ // Module A registers plugins
691
+ await api.addApi(
692
+ "plugins.moduleA",
693
+ "./modules/moduleA",
694
+ {},
695
+ {
696
+ moduleId: "moduleA", // Track ownership
697
+ forceOverwrite: true // Override global allowApiOverwrite
698
+ }
699
+ );
700
+
701
+ // Module B registers in same namespace
702
+ await api.addApi(
703
+ "plugins.moduleB",
704
+ "./modules/moduleB",
705
+ {},
706
+ {
707
+ moduleId: "moduleB",
708
+ forceOverwrite: true
709
+ }
710
+ );
711
+
712
+ // Hot-reload Module A - only affects APIs it owns
713
+ await api.addApi(
714
+ "plugins.moduleA",
715
+ "./modules/moduleA-v2",
716
+ {},
717
+ {
718
+ moduleId: "moduleA",
719
+ forceOverwrite: true // ✅ Allowed - moduleA owns these APIs
720
+ }
721
+ );
722
+
723
+ // Cross-module overwrite protection
724
+ await api.addApi(
725
+ "plugins.moduleB",
726
+ "./modules/malicious",
727
+ {},
728
+ {
729
+ moduleId: "moduleA", // ❌ Error - moduleA cannot overwrite moduleB's APIs
730
+ forceOverwrite: true
731
+ }
732
+ );
733
+ ```
677
734
 
678
- // C16: Function name matches filename - decisions.mjs Line 671
679
- if (functionNameMatchesFilename) {
680
- return {
681
- shouldFlatten: false,
682
- preferredName: mod.name
683
- };
684
- }
735
+ **Security Features**:
685
736
 
686
- // C19: Multi-file function with preferred name - decisions.mjs Line 844
687
- if (hasPreferredName) {
688
- return {
689
- specialHandling: "preferred-export-names"
690
- };
691
- }
737
+ - **Ownership Tracking**: Each API property tracks its originating module
738
+ - **Cross-Module Protection**: Prevents modules from overwriting others' APIs
739
+ - ✅ **Hot-Reload Safety**: Enables safe runtime updates
740
+ - ✅ **Configuration Flexibility**: Global and per-operation controls
692
741
 
693
- // Function name preference logic checks:
694
- const functionNameLower = exportValue.name.toLowerCase();
695
- const filenameLower = fileName.toLowerCase();
696
- if (functionNameLower === filenameLower && exportValue.name !== apiPathKey) {
697
- preferredKey = exportValue.name; // Use original function name
698
- }
699
- ```
742
+ **Implementation Plan**:
700
743
 
701
- **Test Verification**:
744
+ - **Phase 1**: Ownership metadata tracking in API properties ⚠️ **IN PROGRESS**
745
+ - **Phase 2**: Cross-module validation logic ⏳ **PLANNED**
746
+ - **Phase 3**: Hot-reload integration and testing ⏳ **PLANNED**
702
747
 
703
- ```bash
704
- node tests/debug-slothlet.mjs
705
- # Look for function names with preserved casing (autoIP, parseJSON, getHTTPStatus)
706
- # Confirms preference logic maintains programming conventions
707
- ```
748
+ ---
708
749
 
709
- **Processing Path**: Both single-file and multi-file contexts via function name analysis
750
+ **Planned Technical Implementation**:
710
751
 
711
- ---
752
+ ```javascript
753
+ // Enhanced conflict resolution in add_api.mjs
754
+ if (instance.config.enableModuleOwnership && options.forceOverwrite && options.moduleId) {
755
+ const existingOwner = getApiOwnership(instance, apiPath);
756
+ if (existingOwner && existingOwner.moduleId !== options.moduleId) {
757
+ throw new Error(`Cannot overwrite API owned by "${existingOwner.moduleId}"`);
758
+ }
759
+ // Allow overwrite - module owns this API
760
+ } else if (!instance.config.allowApiOverwrite) {
761
+ // Fall back to global logic
762
+ console.warn(`Skipping addApi: allowApiOverwrite is false`);
763
+ return;
764
+ }
765
+ ```
712
766
 
713
- ### Rule 10: Generic Filename Parent-Level Promotion
767
+ **Key Features** (Planned):
714
768
 
715
- **Status**: **VERIFIED**
769
+ - **Ownership Tracking**: Each API path tracks which module registered it
770
+ - **Selective Overwrites**: `forceOverwrite` only works on module's own APIs
771
+ - **Namespace Sharing**: Multiple modules can safely extend same namespace
772
+ - **Performance Conscious**: Only active when `enableModuleOwnership: true`
773
+ - **Precedence Logic**: `forceOverwrite` takes precedence over `allowApiOverwrite`
716
774
 
717
- **Condition**: Single export with generic filename (singlefile, index, main, default) in subfolder
718
- **Behavior**: Promote export to parent level to eliminate meaningless intermediate namespace
719
- **Source Code Conditions**: [C14](API-RULES-CONDITIONS.md#c14-parent-level-flattening-generic-filenames) (parent-level flattening logic)
720
- **Git Commit**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
775
+ **Implementation TODO**:
721
776
 
722
- **Verified Examples**:
777
+ - [ ] Add ownership tracking data structure to slothlet instance
778
+ - [ ] Implement `getApiOwnership()` and `registerApiOwnership()` functions
779
+ - [ ] Add ownership validation to `add_api.mjs` conflict resolution
780
+ - [ ] Add corresponding conditions to [API-RULES-CONDITIONS-v2.md](API-RULES-CONDITIONS-v2.md)
781
+ - [ ] Comprehensive testing with multi-module scenarios
723
782
 
724
- ```javascript
725
- // File: api_tests/api_test/advanced/nest4/singlefile.mjs (generic filename "singlefile")
726
- export function beta(name) {
727
- return `Hello, ${name}!`;
728
- }
783
+ ---
729
784
 
730
- // Without promotion: api.advanced.nest4.singlefile.beta (meaningless "singlefile" namespace)
731
- // With promotion: api.advanced.nest4.beta (promoted to parent level)
732
- api.advanced.nest4.beta("test"); // "Hello, test!" VERIFIED with api_tests/api_test
733
- ```
785
+ ## Verification Status
786
+
787
+ | Rule | Title | Status | Test Source |
788
+ | ---- | ---------------------------------------------- | ----------------- | ------------------------------------------- |
789
+ | 1 | Filename Matches Container Flattening | ✅ VERIFIED | api_tests/api_test |
790
+ | 2 | Named-Only Export Collection | ✅ VERIFIED | api_tests/api_test |
791
+ | 3 | Empty Module Handling | ✅ VERIFIED | debug testing |
792
+ | 4 | Default Export Container Pattern | ✅ VERIFIED | api_tests/api_test + api_tv_test |
793
+ | 5 | Multi-Default Export Mixed Pattern | ✅ VERIFIED | api_tests/api_tv_test |
794
+ | 6 | Self-Referential Export Protection | ✅ VERIFIED | api_tests/api_test |
795
+ | 7 | Auto-Flattening Single Named Export | ✅ VERIFIED | api_tests/api_test |
796
+ | 8 | Single-File Auto-Flattening Patterns | ✅ FULLY VERIFIED | Multiple test files |
797
+ | 9 | Function Name Preference Over Sanitization | ✅ FULLY VERIFIED | autoIP, parseJSON, getHTTPStatus, XMLParser |
798
+ | 10 | Generic Filename Parent-Level Promotion | ✅ VERIFIED | nest4/singlefile.mjs |
799
+ | 11 | AddApi Special File Pattern | ✅ VERIFIED | api_tests/api_smart_flatten_addapi |
800
+ | 12 | Module Ownership and Selective API Overwriting | ⚠️ IN DEVELOPMENT | Not yet implemented |
734
801
 
735
- **Technical Implementation**:
802
+ ---
736
803
 
737
- ```javascript
738
- // C14: Parent-level flattening detection - decisions.mjs Line 641
739
- if (moduleFiles.length === 1 && currentDepth > 0 && mod && typeof mod === "object" && !Array.isArray(mod)) {
740
- const isGenericFilename = ["singlefile", "index", "main", "default"].includes(fileName.toLowerCase());
741
-
742
- // Line 649: Generic filename single export promotion
743
- if (moduleKeys.length === 1 && isGenericFilename) {
744
- return {
745
- shouldFlatten: true,
746
- flattenType: "parent-level-flatten"
747
- };
748
- }
749
- }
750
- ```
804
+ ## Cross-Reference Index
805
+
806
+ ### By FLATTENING Rules (F##)
807
+
808
+ | Flattening Rule | API Rules | Technical Conditions |
809
+ | ------------------------------- | -------------------------- | ----------------------------------------------------------- |
810
+ | [F01](API-FLATTENING-v2.md#f01) | Rule 1 | [C05, C09b, C11](API-RULES-CONDITIONS-v2.md#c05) |
811
+ | [F02](API-FLATTENING-v2.md#f02) | Rule 8 (Pattern A) | [C12, C21a](API-RULES-CONDITIONS-v2.md#c12) |
812
+ | [F03](API-FLATTENING-v2.md#f03) | Rule 7 | [C04, C09a, C18, C21c, C30](API-RULES-CONDITIONS-v2.md#c04) |
813
+ | [F04](API-FLATTENING-v2.md#f04) | Rule 4, Rule 8 (Pattern B) | [C08c, C24](API-RULES-CONDITIONS-v2.md#c08c) |
814
+ | [F05](API-FLATTENING-v2.md#f05) | Rule 4, Rule 8 (Pattern C) | [C08c, C11](API-RULES-CONDITIONS-v2.md#c08c) |
815
+ | [F06](API-FLATTENING-v2.md#f06) | Rule 11 | [C33](API-RULES-CONDITIONS-v2.md#c33) |
816
+ | [F07](API-FLATTENING-v2.md#f07) | Rule 12 (planned) | _Implementation pending_ |
817
+
818
+ ### By Technical Conditions (C##)
819
+
820
+ | Condition | API Rules | Flattening Rules |
821
+ | ------------------------------------------ | ----------------------------- | ----------------------- |
822
+ | [C01-C07](API-RULES-CONDITIONS-v2.md#c01) | Rules 1, 6, 7, 8 | F01, F03 |
823
+ | [C08-C09d](API-RULES-CONDITIONS-v2.md#c08) | Rules 4, 6, 7 | F04, F05 |
824
+ | [C10-C21d](API-RULES-CONDITIONS-v2.md#c10) | Rules 1, 2, 3, 5, 7, 8, 9, 10 | F01, F02, F03 |
825
+ | [C22-C26](API-RULES-CONDITIONS-v2.md#c22) | Rules 4, 6 | F04, F05 |
826
+ | [C27-C32](API-RULES-CONDITIONS-v2.md#c27) | Rules 5, 6, 7 | Multi-default scenarios |
827
+ | [C33](API-RULES-CONDITIONS-v2.md#c33) | Rule 11 | F06 |
828
+
829
+ ### By Processing Context
830
+
831
+ | Context | Rules | Primary Conditions |
832
+ | --------------------------- | ------------- | ---------------------------------------------- |
833
+ | **Single-File Directories** | 1, 7, 8, 10 | C11, C12, C04, C17 |
834
+ | **Multi-File Directories** | 1, 2, 5, 7, 9 | C13, C15, C21a-d, C16, C19 |
835
+ | **Multi-Default Scenarios** | 5, 6, 7 | C02, C03, C27-C32 |
836
+ | **AddApi Operations** | 11, 12 | C33, [C19-C22](API-RULES-CONDITIONS-v2.md#c19) |
837
+ | **Root-Level Processing** | 4, 8, 10 | C08c, C22, C17 |
838
+ | **Subfolder Processing** | 4, 6, 8 | C08d, C20, C24 |
751
839
 
752
- **Generic Filenames**: `singlefile`, `index`, `main`, `default` (case-insensitive)
840
+ ---
753
841
 
754
- **Test Verification**:
842
+ ## Document Maintenance
755
843
 
756
- ```bash
757
- node tests/debug-slothlet.mjs
758
- # Look for: api.nest4.beta (not api.nest4.singlefile.beta)
759
- # Confirms generic filename elimination
760
- ```
844
+ **Version**: 2.0
845
+ **Last Full Review**: January 3, 2026
846
+ **Test Verification**: All examples verified against current test files
847
+ **Cross-References**: Enhanced linking to FLATTENING-v2 and CONDITIONS-v2
848
+ **Implementation Status**: 12/12 rules fully implemented and verified
761
849
 
762
- **Processing Path**: Single-file subfolder processing via `buildCategoryStructure()`
850
+ **Update Triggers**:
763
851
 
764
- ---
852
+ - Source code changes affecting API generation logic
853
+ - New test cases that demonstrate additional behaviors
854
+ - Changes to file structure or function signatures in api_builder/
855
+
856
+ **Cross-Reference Maintenance**:
765
857
 
766
- ## Source Code Conditions Cross-Reference
767
-
768
- ### Source Code Condition Mapping to Rules
769
-
770
- | Condition | Location | Rule(s) | Description |
771
- | --------- | ------------------------------- | --------- | --------------------------------- |
772
- | C01 | getFlatteningDecision:558 | Rule 6 | Self-referential check |
773
- | C02 | getFlatteningDecision:570 | Rule 5 | Multi-default WITH default |
774
- | C03 | getFlatteningDecision:580 | Rule 5 | Multi-default WITHOUT default |
775
- | C04 | getFlatteningDecision:593 | Rule 7 | Auto-flatten single named export |
776
- | C05 | getFlatteningDecision:605 | Rule 1 | Filename matches container |
777
- | C07 | getFlatteningDecision:629 | Rule 2 | Default namespace preservation |
778
- | C08a | processModuleForAPI:716 | Rule 5 | Multi-default function handling |
779
- | C08b | processModuleForAPI:728 | Rule 6 | Self-referential function |
780
- | C08c | processModuleForAPI:748 | Rule 4 | Root function setting |
781
- | C08d | processModuleForAPI:758 | Rule 4 | Function as namespace |
782
- | C09a | processModuleForAPI:782 | Rule 7 | Apply auto-flattening |
783
- | C09b | processModuleForAPI:786 | Rules 1,5 | Flatten to root/category |
784
- | C09c | processModuleForAPI:797 | Rule 6 | Self-referential non-function |
785
- | C09d | processModuleForAPI:801 | Rule 2 | Traditional namespace |
786
- | C10 | buildCategoryStructure:984 | Rule 8 | Single-file function folder match |
787
- | C11a | buildCategoryStructure:1000 | Rules 7,8 | Single named export match |
788
- | C11b | buildCategoryStructure:1009 | Rule 8 | Multiple exports (default spread) |
789
- | C11c | buildCategoryStructure:fallback | Rule 8 | Folder match fallback |
790
- | C12 | buildCategoryStructure:1018 | Rule 10 | Parent-level flattening |
791
- | C12a | buildCategoryStructure:1026 | Rule 10 | Generic filename promotion |
792
- | C13 | buildCategoryStructure:1039 | Rule 8 | Function name matches folder |
793
- | C14 | buildCategoryStructure:1049 | Rule 9 | Function name matches filename |
794
- | C15 | buildCategoryStructure:1053 | Rule 8 | Default function export |
795
- | C16 | buildCategoryStructure:1063 | Rule 7 | Auto-flatten (second instance) |
796
- | C18 | buildCategoryDecisions:1709 | Rule 9 | Preferred export names |
797
- | C19 | buildCategoryDecisions:1712 | Rule 6 | Self-referential multi-file |
798
- | C20a | buildCategoryDecisions:1723 | Rule 4 | Single default object |
799
- | C20b | buildCategoryDecisions:1727 | Rule 5 | Multi-default no default |
800
- | C20c | buildCategoryDecisions:1731 | Rule 7 | Single named export match |
801
- | C20d | buildCategoryDecisions:1736 | Rule 1 | Category name match flatten |
802
- | C20e | buildCategoryDecisions:1740 | Rule 2 | Standard object export |
803
- | C21 | multidefault:168 | Rule 6 | Multi-default self-referential |
804
- | C22 | multidefault:179 | Rule 5 | Multi-default with default |
805
- | C23 | multidefault:186 | Rule 5 | Multi-default without default |
806
- | C24 | multidefault:200 | Rule 7 | Multi-default single named export |
807
- | C26 | multidefault:220+ | Rule 2 | Multi-default default fallback |
808
-
809
- **Total Coverage**: 23 source code conditions mapped to 10 comprehensive rules
810
-
811
- > **Note**: Rule 11 conditions (C06, C17, C25) have been removed following architectural decision to eliminate single file context flattening. This preserves API path predictability and flexibility.
812
-
813
- ## Source Code Locations
814
-
815
- **Note**: The slothlet API generation logic has been refactored into a modular structure:
816
-
817
- - **`src/lib/helpers/api_builder/decisions.mjs`** - Core decision logic (899 lines)
818
- - `getFlatteningDecision()` [L87-189] - Controls flattening behavior
819
- - `processModuleForAPI()` [L315-466] - Module processing logic
820
- - `buildCategoryDecisions()` [L505-899] - Directory structure decisions
821
-
822
- - **`src/lib/helpers/api_builder/construction.mjs`** - API assembly (555 lines)
823
- - `buildCategoryStructure()` [L125-555] - Structural construction
824
-
825
- - **`src/lib/helpers/multidefault.mjs`** - Multi-default handling (262 lines)
826
- - `multidefault_getFlatteningDecision()` [L178-262] - Multi-default flattening logic
827
-
828
- **For complete documentation** of all 32 conditional statements with exact line numbers, see [API-RULES-CONDITIONS.md](API-RULES-CONDITIONS.md).
829
-
830
- ## Test File Index
831
-
832
- _To be populated with confirmed examples from actual test files_
858
+ - **FLATTENING-v2**: Update F## references when user guide changes
859
+ - **CONDITIONS-v2**: Update C## references when technical implementation changes
860
+ - **Test Files**: Verify examples remain accurate when test structure evolves