claude-mpm 4.15.6__py3-none-any.whl → 4.21.0__py3-none-any.whl

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.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (194) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_ENGINEER.md +286 -0
  3. claude_mpm/agents/BASE_PM.md +272 -23
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +49 -0
  5. claude_mpm/agents/agent_loader.py +4 -4
  6. claude_mpm/agents/templates/engineer.json +5 -1
  7. claude_mpm/agents/templates/php-engineer.json +10 -4
  8. claude_mpm/agents/templates/python_engineer.json +8 -3
  9. claude_mpm/agents/templates/rust_engineer.json +12 -7
  10. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  11. claude_mpm/cli/commands/__init__.py +2 -0
  12. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  13. claude_mpm/cli/commands/mpm_init/core.py +525 -0
  14. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  15. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  16. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  17. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  18. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  19. claude_mpm/cli/commands/mpm_init_handler.py +67 -1
  20. claude_mpm/cli/commands/skills.py +488 -0
  21. claude_mpm/cli/executor.py +2 -0
  22. claude_mpm/cli/parsers/base_parser.py +7 -0
  23. claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
  24. claude_mpm/cli/parsers/skills_parser.py +137 -0
  25. claude_mpm/cli/startup.py +57 -0
  26. claude_mpm/commands/mpm-auto-configure.md +52 -0
  27. claude_mpm/commands/mpm-help.md +3 -0
  28. claude_mpm/commands/mpm-init.md +112 -6
  29. claude_mpm/commands/mpm-version.md +113 -0
  30. claude_mpm/commands/mpm.md +1 -0
  31. claude_mpm/config/agent_config.py +2 -2
  32. claude_mpm/constants.py +12 -0
  33. claude_mpm/core/config.py +42 -0
  34. claude_mpm/core/factories.py +1 -1
  35. claude_mpm/core/interfaces.py +56 -1
  36. claude_mpm/core/optimized_agent_loader.py +3 -3
  37. claude_mpm/hooks/__init__.py +8 -0
  38. claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
  39. claude_mpm/hooks/session_resume_hook.py +121 -0
  40. claude_mpm/models/resume_log.py +340 -0
  41. claude_mpm/services/agents/auto_config_manager.py +1 -1
  42. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  43. claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
  44. claude_mpm/services/agents/deployment/agent_validator.py +17 -1
  45. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  46. claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
  47. claude_mpm/services/agents/local_template_manager.py +1 -1
  48. claude_mpm/services/agents/recommender.py +47 -0
  49. claude_mpm/services/cli/resume_service.py +617 -0
  50. claude_mpm/services/cli/session_manager.py +87 -0
  51. claude_mpm/services/cli/session_pause_manager.py +504 -0
  52. claude_mpm/services/cli/session_resume_helper.py +372 -0
  53. claude_mpm/services/core/interfaces.py +56 -1
  54. claude_mpm/services/core/models/agent_config.py +3 -0
  55. claude_mpm/services/core/models/process.py +4 -0
  56. claude_mpm/services/core/path_resolver.py +1 -1
  57. claude_mpm/services/diagnostics/models.py +21 -0
  58. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  59. claude_mpm/services/local_ops/__init__.py +2 -0
  60. claude_mpm/services/mcp_config_manager.py +7 -131
  61. claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
  62. claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
  63. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
  64. claude_mpm/services/session_manager.py +205 -1
  65. claude_mpm/services/unified/deployment_strategies/local.py +1 -1
  66. claude_mpm/services/version_service.py +104 -1
  67. claude_mpm/skills/__init__.py +21 -0
  68. claude_mpm/skills/agent_skills_injector.py +324 -0
  69. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  70. claude_mpm/skills/bundled/api-documentation.md +393 -0
  71. claude_mpm/skills/bundled/async-testing.md +571 -0
  72. claude_mpm/skills/bundled/code-review.md +143 -0
  73. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  74. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  75. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  76. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  77. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  78. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  79. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  80. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  81. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  82. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  83. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  84. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  85. claude_mpm/skills/bundled/database-migration.md +199 -0
  86. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  87. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  88. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  89. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  90. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  91. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  92. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  93. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  94. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  95. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  96. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  97. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  98. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  99. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  100. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  101. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  102. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  103. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  104. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  105. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  106. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  107. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  108. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  109. claude_mpm/skills/bundled/git-workflow.md +414 -0
  110. claude_mpm/skills/bundled/imagemagick.md +204 -0
  111. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  112. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  113. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  114. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  115. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  116. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  117. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  118. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  119. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  120. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  121. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  122. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  123. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  124. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  125. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  126. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  127. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  128. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  129. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  130. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  131. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  132. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  133. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  134. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  135. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  136. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  137. claude_mpm/skills/bundled/pdf.md +141 -0
  138. claude_mpm/skills/bundled/performance-profiling.md +567 -0
  139. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  140. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  141. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  142. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  143. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  144. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  145. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  146. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  147. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  148. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  149. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  150. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  151. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  152. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  153. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  154. claude_mpm/skills/bundled/security-scanning.md +327 -0
  155. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  156. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  157. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  158. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  159. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  160. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  161. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  162. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  163. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  164. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  165. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  166. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  167. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  168. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  169. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  170. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  171. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  172. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  173. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  174. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  175. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  176. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  177. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  178. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  179. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  180. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  181. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  182. claude_mpm/skills/bundled/xlsx.md +157 -0
  183. claude_mpm/skills/registry.py +97 -9
  184. claude_mpm/skills/skills_registry.py +348 -0
  185. claude_mpm/skills/skills_service.py +739 -0
  186. claude_mpm/utils/agent_dependency_loader.py +2 -2
  187. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/METADATA +211 -33
  188. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/RECORD +192 -60
  189. claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md +0 -602
  190. claude_mpm/cli/commands/mpm_init.py +0 -2008
  191. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/WHEEL +0 -0
  192. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/entry_points.txt +0 -0
  193. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/licenses/LICENSE +0 -0
  194. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,587 @@
1
+ # Real-World Tracing Examples
2
+
3
+ Detailed examples showing complete root cause tracing processes with full trace chains and solutions.
4
+
5
+ ## Example 1: Git Init in Wrong Directory
6
+
7
+ ### The Symptom
8
+
9
+ **Observed behavior:**
10
+ ```bash
11
+ $ npm test
12
+ ...
13
+ Error: fatal: .git directory created in /Users/jesse/project/packages/core
14
+ ```
15
+
16
+ Tests were creating a `.git` directory in the source code folder instead of a temporary directory.
17
+
18
+ ### Initial Investigation
19
+
20
+ **First thought:** "Just validate the directory parameter in git init"
21
+
22
+ **WRONG:** This would be a symptom fix. We need to find WHY the directory is wrong.
23
+
24
+ ### The Trace
25
+
26
+ #### Step 1: Find Immediate Cause
27
+
28
+ ```typescript
29
+ // worktree-manager.ts:45
30
+ async function createSessionWorktree(projectDir: string, sessionId: string) {
31
+ // This line creates .git in wrong place
32
+ await execFileAsync('git', ['init'], { cwd: projectDir });
33
+ }
34
+ ```
35
+
36
+ **Discovery:** `projectDir` is an empty string `''`
37
+ **Why is this wrong:** Empty string as `cwd` resolves to `process.cwd()` (current directory)
38
+
39
+ #### Step 2: Where Does Empty String Come From?
40
+
41
+ ```typescript
42
+ // session.ts:34
43
+ static async create(name: string, projectDir: string) {
44
+ const session = new Session(name);
45
+ await session.initializeWorkspace(projectDir); // ← calls worktree manager
46
+ return session;
47
+ }
48
+ ```
49
+
50
+ **Discovery:** Session.create() receives `projectDir = ''`
51
+ **Question:** Where does Session.create() get this value?
52
+
53
+ #### Step 3: Trace to Caller
54
+
55
+ ```typescript
56
+ // project.ts:67
57
+ static async create(name: string, directory: string) {
58
+ await Session.create(name, directory); // ← passes directory through
59
+ // ...
60
+ }
61
+ ```
62
+
63
+ **Discovery:** Project.create() also receives `directory = ''`
64
+ **Question:** What calls Project.create() with empty string?
65
+
66
+ #### Step 4: Check Test Code
67
+
68
+ ```typescript
69
+ // project.test.ts:12
70
+ const context = setupCoreTest();
71
+ const PROJECT_DIR = context.tempDir; // ← Accessed at module load time!
72
+
73
+ describe('Project', () => {
74
+ it('should create project', async () => {
75
+ await Project.create('test-project', PROJECT_DIR);
76
+ });
77
+ });
78
+ ```
79
+
80
+ **Discovery:** `PROJECT_DIR` is set to `context.tempDir` at module load time
81
+ **Question:** What is `context.tempDir` at module load time?
82
+
83
+ #### Step 5: Root Cause Found
84
+
85
+ ```typescript
86
+ // test-setup.ts
87
+ export function setupCoreTest() {
88
+ let _tempDir = ''; // ← Initial value is empty string
89
+
90
+ beforeEach(() => {
91
+ _tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-'));
92
+ });
93
+
94
+ afterEach(() => {
95
+ if (_tempDir) fs.rmSync(_tempDir, { recursive: true });
96
+ });
97
+
98
+ return {
99
+ tempDir: _tempDir // ← Returns empty string at module load time
100
+ };
101
+ }
102
+ ```
103
+
104
+ **ROOT CAUSE:** The test accesses `context.tempDir` at module load time (when defining `PROJECT_DIR`), but `_tempDir` is only set during `beforeEach`. At module load time, it's still `''`.
105
+
106
+ ### The Solution
107
+
108
+ #### Fix at Source
109
+
110
+ ```typescript
111
+ export function setupCoreTest() {
112
+ let _tempDir: string | null = null; // ← null instead of empty string
113
+
114
+ beforeEach(() => {
115
+ _tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-'));
116
+ });
117
+
118
+ afterEach(() => {
119
+ if (_tempDir) fs.rmSync(_tempDir, { recursive: true });
120
+ _tempDir = null;
121
+ });
122
+
123
+ return {
124
+ get tempDir(): string {
125
+ if (!_tempDir) {
126
+ throw new Error('tempDir accessed before beforeEach ran');
127
+ }
128
+ return _tempDir;
129
+ }
130
+ };
131
+ }
132
+ ```
133
+
134
+ **Why this works:**
135
+ - Accessing `context.tempDir` at module load time now throws immediately
136
+ - Forces tests to access it only within test cases
137
+ - Clear error message guides developers to fix
138
+
139
+ #### Add Defense-in-Depth
140
+
141
+ ```typescript
142
+ // Layer 1: Project.create() validates directory
143
+ static async create(name: string, directory: string) {
144
+ if (!directory || directory.trim() === '') {
145
+ throw new Error('Project directory cannot be empty');
146
+ }
147
+ // ...
148
+ }
149
+
150
+ // Layer 2: WorkspaceManager validates not empty
151
+ async function initializeWorkspace(projectDir: string) {
152
+ if (!projectDir) {
153
+ throw new Error('projectDir cannot be empty');
154
+ }
155
+ // ...
156
+ }
157
+
158
+ // Layer 3: NODE_ENV guard refuses git init outside tmpdir
159
+ async function createSessionWorktree(projectDir: string, sessionId: string) {
160
+ if (process.env.NODE_ENV === 'test' && !projectDir.includes('tmp')) {
161
+ throw new Error(`Test safety: refusing git init outside tmpdir: ${projectDir}`);
162
+ }
163
+ await execFileAsync('git', ['init'], { cwd: projectDir });
164
+ }
165
+
166
+ // Layer 4: Stack trace logging before git init
167
+ async function createSessionWorktree(projectDir: string, sessionId: string) {
168
+ if (!projectDir || projectDir === process.cwd()) {
169
+ console.error('DEBUG git init:', {
170
+ projectDir,
171
+ cwd: process.cwd(),
172
+ stack: new Error().stack
173
+ });
174
+ }
175
+ await execFileAsync('git', ['init'], { cwd: projectDir });
176
+ }
177
+ ```
178
+
179
+ ### Results
180
+
181
+ - 1847 tests passed
182
+ - Zero `.git` pollution
183
+ - Clear error message for similar issues
184
+ - Multiple layers prevent similar bugs
185
+
186
+ ### Time Saved
187
+
188
+ **With root cause tracing:** 45 minutes
189
+ **Without (symptom fixes):** 3+ hours of whack-a-mole
190
+
191
+ ## Example 2: Database Connection URL Wrong
192
+
193
+ ### The Symptom
194
+
195
+ ```
196
+ Error: Connection failed: database "undefined" does not exist
197
+ at Database.connect (database.ts:34)
198
+ ```
199
+
200
+ Application crashes on startup because database name is undefined.
201
+
202
+ ### The Trace
203
+
204
+ #### Step 1: Find Immediate Cause
205
+
206
+ ```typescript
207
+ // database.ts:34
208
+ async function connect(url: string) {
209
+ this.connection = await pg.connect(url); // ← Crashes here
210
+ }
211
+ ```
212
+
213
+ **Discovery:** `url = "postgresql://localhost/undefined"`
214
+ **Why is this wrong:** Database name is literally the string "undefined"
215
+
216
+ #### Step 2: Where Does URL Come From?
217
+
218
+ ```typescript
219
+ // database.ts:12
220
+ constructor(config: DatabaseConfig) {
221
+ this.url = `postgresql://${config.host}/${config.database}`; // ← constructs URL
222
+ }
223
+ ```
224
+
225
+ **Discovery:** `config.database = undefined`
226
+ **Question:** Where does config come from?
227
+
228
+ #### Step 3: Trace to Configuration Loading
229
+
230
+ ```typescript
231
+ // app.ts:23
232
+ const dbConfig: DatabaseConfig = {
233
+ host: process.env.DATABASE_HOST || 'localhost',
234
+ database: process.env.DATABASE_NAME, // ← No default value!
235
+ port: parseInt(process.env.DATABASE_PORT || '5432')
236
+ };
237
+ ```
238
+
239
+ **Discovery:** `DATABASE_NAME` environment variable is not set
240
+ **Question:** Why isn't it set?
241
+
242
+ #### Step 4: Check Environment Setup
243
+
244
+ ```typescript
245
+ // .env file
246
+ DATABASE_HOST=localhost
247
+ DATABASE_PORT=5432
248
+ # DATABASE_NAME missing!
249
+ ```
250
+
251
+ **ROOT CAUSE:** Environment variable not defined, and code doesn't validate required variables.
252
+
253
+ ### The Solution
254
+
255
+ #### Fix at Source
256
+
257
+ ```typescript
258
+ // config.ts - Load and validate environment
259
+ export function loadDatabaseConfig(): DatabaseConfig {
260
+ const requiredEnvVars = ['DATABASE_NAME', 'DATABASE_HOST'];
261
+ const missing = requiredEnvVars.filter(v => !process.env[v]);
262
+
263
+ if (missing.length > 0) {
264
+ throw new Error(`Required environment variables missing: ${missing.join(', ')}`);
265
+ }
266
+
267
+ return {
268
+ host: process.env.DATABASE_HOST!,
269
+ database: process.env.DATABASE_NAME!,
270
+ port: parseInt(process.env.DATABASE_PORT || '5432')
271
+ };
272
+ }
273
+ ```
274
+
275
+ #### Add Defense-in-Depth
276
+
277
+ ```typescript
278
+ // Layer 1: Type-safe config with validation
279
+ interface DatabaseConfig {
280
+ host: string;
281
+ database: string;
282
+ port: number;
283
+ }
284
+
285
+ // Layer 2: Constructor validates config
286
+ constructor(config: DatabaseConfig) {
287
+ if (!config.database || config.database === 'undefined') {
288
+ throw new Error('Database name cannot be empty or undefined');
289
+ }
290
+ this.url = `postgresql://${config.host}/${config.database}`;
291
+ }
292
+
293
+ // Layer 3: Validate URL before connect
294
+ async function connect(url: string) {
295
+ if (url.includes('/undefined')) {
296
+ throw new Error(`Invalid database URL: ${url}`);
297
+ }
298
+ this.connection = await pg.connect(url);
299
+ }
300
+ ```
301
+
302
+ ### Results
303
+
304
+ - Application fails fast at startup with clear error
305
+ - Developers immediately know which env var is missing
306
+ - Prevents confusing "database undefined does not exist" error
307
+
308
+ ## Example 3: User ID = 0 in Database Query
309
+
310
+ ### The Symptom
311
+
312
+ ```
313
+ Error: Cannot query user: id cannot be 0
314
+ at UserRepository.findById (user-repository.ts:45)
315
+ ```
316
+
317
+ Database query fails because user ID is 0 (invalid).
318
+
319
+ ### The Trace
320
+
321
+ #### Step 1: Find Immediate Cause
322
+
323
+ ```typescript
324
+ // user-repository.ts:45
325
+ async findById(id: number): Promise<User> {
326
+ if (id === 0) {
327
+ throw new Error('Cannot query user: id cannot be 0');
328
+ }
329
+ return await this.db.query('SELECT * FROM users WHERE id = ?', [id]);
330
+ }
331
+ ```
332
+
333
+ **Discovery:** `id = 0` being passed to query
334
+ **Question:** Where does this come from?
335
+
336
+ #### Step 2: Trace to Caller
337
+
338
+ ```typescript
339
+ // auth-middleware.ts:67
340
+ async authenticate(req: Request): Promise<User> {
341
+ const userId = this.extractUserId(req);
342
+ return await this.userRepo.findById(userId); // ← userId is 0
343
+ }
344
+ ```
345
+
346
+ **Discovery:** `extractUserId()` returns 0
347
+ **Question:** Why does it return 0?
348
+
349
+ #### Step 3: Check ID Extraction
350
+
351
+ ```typescript
352
+ // auth-middleware.ts:34
353
+ private extractUserId(req: Request): number {
354
+ const token = req.headers.authorization?.replace('Bearer ', '');
355
+ if (!token) return 0; // ← Default to 0 if no token!
356
+
357
+ const decoded = jwt.verify(token, SECRET);
358
+ return decoded.userId;
359
+ }
360
+ ```
361
+
362
+ **Discovery:** Returns 0 when no authorization header
363
+ **Question:** Why is there no authorization header?
364
+
365
+ #### Step 4: Check Request Handling
366
+
367
+ ```typescript
368
+ // router.ts:23
369
+ app.get('/api/user/profile', async (req, res) => {
370
+ const user = await authMiddleware.authenticate(req); // ← Called on public route!
371
+ res.json(user);
372
+ });
373
+ ```
374
+
375
+ **ROOT CAUSE:** Authentication middleware called on public route that doesn't require authentication. When no token present, it defaults to userId=0.
376
+
377
+ ### The Solution
378
+
379
+ #### Fix at Source
380
+
381
+ ```typescript
382
+ // router.ts - Separate public and protected routes
383
+ app.get('/api/public/profile', async (req, res) => {
384
+ // Public route - no authentication
385
+ res.json({ message: 'Public profile' });
386
+ });
387
+
388
+ app.get('/api/user/profile',
389
+ requireAuth(), // ← Middleware throws if no auth
390
+ async (req, res) => {
391
+ const user = await authMiddleware.authenticate(req);
392
+ res.json(user);
393
+ }
394
+ );
395
+ ```
396
+
397
+ #### Add Defense-in-Depth
398
+
399
+ ```typescript
400
+ // Layer 1: Don't default to 0, throw instead
401
+ private extractUserId(req: Request): number {
402
+ const token = req.headers.authorization?.replace('Bearer ', '');
403
+ if (!token) {
404
+ throw new UnauthorizedError('No authorization token provided');
405
+ }
406
+
407
+ const decoded = jwt.verify(token, SECRET);
408
+ return decoded.userId;
409
+ }
410
+
411
+ // Layer 2: Validate userId before query
412
+ async findById(id: number): Promise<User> {
413
+ if (!id || id <= 0) {
414
+ throw new Error(`Invalid user ID: ${id}`);
415
+ }
416
+ return await this.db.query('SELECT * FROM users WHERE id = ?', [id]);
417
+ }
418
+
419
+ // Layer 3: Type system (use branded types)
420
+ type UserId = number & { readonly __brand: 'UserId' };
421
+
422
+ function validateUserId(id: number): UserId {
423
+ if (!id || id <= 0) throw new Error('Invalid user ID');
424
+ return id as UserId;
425
+ }
426
+ ```
427
+
428
+ ### Results
429
+
430
+ - Authentication errors are clear and immediate
431
+ - Protected routes always require authentication
432
+ - No magic "0" default that causes confusing errors
433
+
434
+ ## Example 4: React Component Renders Wrong Data
435
+
436
+ ### The Symptom
437
+
438
+ ```
439
+ Component shows data from previous user after logout/login
440
+ ```
441
+
442
+ User logs out, logs in as different user, but sees previous user's data briefly.
443
+
444
+ ### The Trace
445
+
446
+ #### Step 1: Observe Behavior
447
+
448
+ - User A logs in → sees correct data
449
+ - User A logs out → data clears
450
+ - User B logs in → sees User A's data for ~100ms
451
+ - After 100ms → sees correct User B data
452
+
453
+ **Discovery:** Stale data being shown before new data loads
454
+
455
+ #### Step 2: Check Component Data Source
456
+
457
+ ```typescript
458
+ // UserDashboard.tsx
459
+ function UserDashboard() {
460
+ const user = useSelector(state => state.auth.user);
461
+ const data = useSelector(state => state.userData.data);
462
+
463
+ useEffect(() => {
464
+ dispatch(fetchUserData(user.id)); // ← Fetches new data
465
+ }, [user.id]);
466
+
467
+ return <div>{data.name}</div>; // ← Shows stale data during fetch
468
+ }
469
+ ```
470
+
471
+ **Discovery:** Redux store still has old user's data when new user logs in
472
+ **Question:** Why isn't the old data cleared?
473
+
474
+ #### Step 3: Check Login/Logout Actions
475
+
476
+ ```typescript
477
+ // auth.actions.ts
478
+ export function logout() {
479
+ return { type: 'LOGOUT' }; // ← Only clears auth state
480
+ }
481
+
482
+ // auth.reducer.ts
483
+ case 'LOGOUT':
484
+ return { user: null }; // ← Only clears user
485
+
486
+ // userData.reducer.ts (SEPARATE REDUCER)
487
+ case 'FETCH_USER_DATA':
488
+ return { ...state, data: action.payload }; // ← Never cleared!
489
+ ```
490
+
491
+ **ROOT CAUSE:** Logout action only clears auth state, not user data. User data reducer never listens to LOGOUT action.
492
+
493
+ ### The Solution
494
+
495
+ #### Fix at Source
496
+
497
+ ```typescript
498
+ // userData.reducer.ts
499
+ import { LOGOUT } from './auth.actions';
500
+
501
+ case LOGOUT:
502
+ return initialState; // ← Clear data on logout
503
+
504
+ case 'FETCH_USER_DATA':
505
+ return { ...state, data: action.payload };
506
+ ```
507
+
508
+ #### Add Defense-in-Depth
509
+
510
+ ```typescript
511
+ // Layer 1: Clear all data on logout
512
+ export function logout() {
513
+ return (dispatch) => {
514
+ dispatch({ type: 'LOGOUT' });
515
+ dispatch({ type: 'CLEAR_USER_DATA' });
516
+ dispatch({ type: 'CLEAR_PREFERENCES' });
517
+ dispatch({ type: 'CLEAR_CACHE' });
518
+ };
519
+ }
520
+
521
+ // Layer 2: Check user ID matches before showing data
522
+ function UserDashboard() {
523
+ const user = useSelector(state => state.auth.user);
524
+ const userData = useSelector(state => state.userData.data);
525
+
526
+ // Don't show data if user IDs don't match
527
+ const dataIsValid = userData && userData.userId === user?.id;
528
+
529
+ return <div>{dataIsValid ? userData.name : 'Loading...'}</div>;
530
+ }
531
+
532
+ // Layer 3: Reset all reducers on logout
533
+ const appReducer = combineReducers({
534
+ auth: authReducer,
535
+ userData: userDataReducer,
536
+ // ...
537
+ });
538
+
539
+ const rootReducer = (state, action) => {
540
+ if (action.type === 'LOGOUT') {
541
+ state = undefined; // ← Reset entire store
542
+ }
543
+ return appReducer(state, action);
544
+ };
545
+ ```
546
+
547
+ ### Results
548
+
549
+ - No stale data shown after logout
550
+ - Clean state for each user session
551
+ - Prevents data leakage between users
552
+
553
+ ## Common Patterns Across Examples
554
+
555
+ ### Pattern: Unvalidated Input at Boundaries
556
+
557
+ **Examples:**
558
+ - Git init: Empty string not caught at entry point
559
+ - Database: Missing env var not validated at startup
560
+ - User ID: Missing token defaulted to 0
561
+
562
+ **Solution:** Validate at system boundaries (entry points, config loading)
563
+
564
+ ### Pattern: State Not Cleared on Transitions
565
+
566
+ **Examples:**
567
+ - Test setup: tempDir accessed before initialization
568
+ - React: User data not cleared on logout
569
+
570
+ **Solution:** Explicit state transitions with cleanup
571
+
572
+ ### Pattern: Magic Default Values
573
+
574
+ **Examples:**
575
+ - Empty string defaulting to process.cwd()
576
+ - 0 as default user ID
577
+ - undefined becoming string "undefined"
578
+
579
+ **Solution:** No magic defaults - fail fast with errors
580
+
581
+ ## Takeaways
582
+
583
+ 1. **Never stop at symptoms** - Always trace to root cause
584
+ 2. **Fix at source** - Don't add bandaids at error point
585
+ 3. **Add defense** - Multiple layers catch similar issues
586
+ 4. **Document trace** - Write down call chain as you go
587
+ 5. **Verify fix** - Ensure fix addresses root cause, not just symptom