@simplysm/sd-claude 13.0.60 → 13.0.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/claude/agents/sd-api-reviewer.md +7 -6
  2. package/claude/agents/sd-code-simplifier.md +0 -3
  3. package/claude/agents/sd-security-reviewer.md +14 -3
  4. package/claude/refs/sd-angular.md +127 -0
  5. package/claude/refs/sd-orm-v12.md +81 -0
  6. package/claude/refs/sd-orm.md +7 -1
  7. package/claude/refs/sd-solid.md +8 -0
  8. package/claude/rules/sd-refs-linker.md +41 -9
  9. package/claude/skills/sd-api-name-review/SKILL.md +6 -6
  10. package/claude/skills/sd-brainstorm/SKILL.md +4 -0
  11. package/claude/skills/sd-check/SKILL.md +10 -10
  12. package/claude/skills/sd-check/baseline-analysis.md +24 -3
  13. package/claude/skills/sd-check/test-scenarios.md +34 -1
  14. package/claude/skills/sd-commit/SKILL.md +11 -5
  15. package/claude/skills/sd-debug/SKILL.md +26 -17
  16. package/claude/skills/sd-debug/condition-based-waiting.md +17 -12
  17. package/claude/skills/sd-debug/defense-in-depth.md +14 -8
  18. package/claude/skills/sd-debug/root-cause-tracing.md +18 -4
  19. package/claude/skills/sd-debug/test-baseline-pressure.md +10 -8
  20. package/claude/skills/sd-discuss/SKILL.md +17 -13
  21. package/claude/skills/sd-eml-analyze/SKILL.md +8 -7
  22. package/claude/skills/sd-explore/SKILL.md +2 -0
  23. package/claude/skills/sd-plan/SKILL.md +9 -3
  24. package/claude/skills/sd-plan-dev/SKILL.md +7 -2
  25. package/claude/skills/sd-plan-dev/code-quality-reviewer-prompt.md +2 -0
  26. package/claude/skills/sd-plan-dev/final-review-prompt.md +2 -2
  27. package/claude/skills/sd-readme/SKILL.md +22 -16
  28. package/claude/skills/sd-review/SKILL.md +22 -21
  29. package/claude/skills/sd-skill/SKILL.md +94 -35
  30. package/claude/skills/sd-skill/anthropic-best-practices.md +174 -148
  31. package/claude/skills/sd-skill/examples/CLAUDE_MD_TESTING.md +11 -0
  32. package/claude/skills/sd-skill/persuasion-principles.md +39 -6
  33. package/claude/skills/sd-skill/testing-skills-with-subagents.md +46 -26
  34. package/claude/skills/sd-tdd/SKILL.md +54 -36
  35. package/claude/skills/sd-tdd/testing-anti-patterns.md +40 -22
  36. package/claude/skills/sd-use/SKILL.md +22 -22
  37. package/claude/skills/sd-worktree/SKILL.md +1 -0
  38. package/claude/skills/sd-worktree/sd-worktree.mjs +1 -1
  39. package/package.json +1 -1
  40. package/claude/skills/sd-check/run-checks.mjs +0 -54
@@ -3,23 +3,28 @@
3
3
  ## Scenario 1: Basic Application - Full Project Check (Time Pressure)
4
4
 
5
5
  **Setup:**
6
+
6
7
  - Simulated project with typecheck, lint, test configured
7
8
  - No existing errors
8
9
 
9
10
  **Pressure:**
11
+
10
12
  - Time constraint: "Need results quickly for deployment"
11
13
 
12
14
  **Agent Prompt:**
15
+
13
16
  ```
14
17
  I need to verify the entire simplysm project before deployment. Can you run all checks? We need to deploy soon, so please be fast.
15
18
  ```
16
19
 
17
20
  **Expected Baseline Failures (without skill):**
21
+
18
22
  - May run checks sequentially instead of parallel (slower)
19
23
  - May skip environment pre-checks
20
24
  - May not use haiku model (more expensive)
21
25
 
22
26
  **Success Criteria (with skill):**
27
+
23
28
  - Runs environment pre-checks first
24
29
  - Launches 3 haiku agents in parallel
25
30
  - Reports results correctly
@@ -29,24 +34,29 @@ I need to verify the entire simplysm project before deployment. Can you run all
29
34
  ## Scenario 2: Variation - Specific Path Check (Complex Path)
30
35
 
31
36
  **Setup:**
37
+
32
38
  - Project with multiple packages
33
39
  - Target path: `packages/solid-demo`
34
40
 
35
41
  **Pressure:**
42
+
36
43
  - Complex path with potential typos
37
44
  - User expects path to be handled correctly
38
45
 
39
46
  **Agent Prompt:**
47
+
40
48
  ```
41
49
  Can you verify just the packages/solid-demo directory? I only changed files there.
42
50
  ```
43
51
 
44
52
  **Expected Baseline Failures:**
53
+
45
54
  - May forget to pass path argument to commands
46
55
  - May run full project check instead
47
56
  - May incorrectly format path in commands
48
57
 
49
58
  **Success Criteria:**
59
+
50
60
  - Correctly passes `packages/solid-demo` to all 3 commands
51
61
  - Only reports errors from that path
52
62
 
@@ -55,23 +65,28 @@ Can you verify just the packages/solid-demo directory? I only changed files ther
55
65
  ## Scenario 3: Edge Case - Typecheck Errors (Fix Priority)
56
66
 
57
67
  **Setup:**
68
+
58
69
  - Simulated project with typecheck errors that cascade to lint/test
59
70
 
60
71
  **Pressure:**
72
+
61
73
  - Multiple failing checks (frustration)
62
74
  - Desire to "just make it work"
63
75
 
64
76
  **Agent Prompt:**
77
+
65
78
  ```
66
79
  Please verify the project. (Note: project has typecheck errors that cause lint and test failures)
67
80
  ```
68
81
 
69
82
  **Expected Baseline Failures:**
83
+
70
84
  - May fix lint or test errors first (wrong priority)
71
85
  - May not understand cascade relationship
72
86
  - May fix all errors simultaneously without priority
73
87
 
74
88
  **Success Criteria:**
89
+
75
90
  - Fixes typecheck errors first
76
91
  - Recognizes cascade relationship
77
92
  - Re-verifies after each fix round
@@ -81,24 +96,29 @@ Please verify the project. (Note: project has typecheck errors that cause lint a
81
96
  ## Scenario 4: Edge Case - Repeated Failures (Loop Exit)
82
97
 
83
98
  **Setup:**
99
+
84
100
  - Simulated project with obscure test failure
85
101
  - Root cause is unclear
86
102
 
87
103
  **Pressure:**
104
+
88
105
  - Repeated verification failures (fatigue)
89
106
  - Temptation to give up or skip
90
107
 
91
108
  **Agent Prompt:**
109
+
92
110
  ```
93
111
  Verify the project. (Note: test failures persist after 2-3 fix attempts)
94
112
  ```
95
113
 
96
114
  **Expected Baseline Failures:**
115
+
97
116
  - May keep trying same fix repeatedly (infinite loop)
98
117
  - May skip re-verification to "save time"
99
118
  - May not recommend sd-debug
100
119
 
101
120
  **Success Criteria:**
121
+
102
122
  - After 2-3 failed attempts, recommends `/sd-debug`
103
123
  - Does not enter infinite loop
104
124
  - Always re-verifies after fixes
@@ -108,21 +128,26 @@ Verify the project. (Note: test failures persist after 2-3 fix attempts)
108
128
  ## Scenario 5: Missing Information Test - No Path Argument
109
129
 
110
130
  **Setup:**
131
+
111
132
  - Standard project setup
112
133
 
113
134
  **Pressure:**
135
+
114
136
  - Ambiguous user request
115
137
 
116
138
  **Agent Prompt:**
139
+
117
140
  ```
118
141
  Run sd-check.
119
142
  ```
120
143
 
121
144
  **Expected Baseline Failures:**
145
+
122
146
  - May ask user for path (skill should default to full project)
123
147
  - May incorrectly assume a path
124
148
 
125
149
  **Success Criteria:**
150
+
126
151
  - Runs on entire project (no path argument)
127
152
  - Does not ask user for clarification
128
153
 
@@ -131,21 +156,26 @@ Run sd-check.
131
156
  ## Scenario 6: Missing Information Test - Invalid Environment
132
157
 
133
158
  **Setup:**
134
- - Project missing pnpm-lock.yaml or vitest.config.ts
159
+
160
+ - Project missing `check` script in package.json
135
161
 
136
162
  **Pressure:**
163
+
137
164
  - User expects check to work
138
165
 
139
166
  **Agent Prompt:**
167
+
140
168
  ```
141
169
  Please run sd-check on the project.
142
170
  ```
143
171
 
144
172
  **Expected Baseline Failures:**
173
+
145
174
  - May proceed without environment checks
146
175
  - May report confusing errors from missing dependencies
147
176
 
148
177
  **Success Criteria:**
178
+
149
179
  - Runs environment pre-checks
150
180
  - Stops with clear error message if environment invalid
151
181
  - Reports which specific check failed
@@ -155,17 +185,20 @@ Please run sd-check on the project.
155
185
  ## Testing Methodology
156
186
 
157
187
  ### RED Phase (Current)
188
+
158
189
  1. Run each scenario WITHOUT sd-check skill loaded
159
190
  2. Document exact agent behavior verbatim
160
191
  3. Record rationalizations used
161
192
  4. Identify patterns in failures
162
193
 
163
194
  ### GREEN Phase
195
+
164
196
  1. Write skill addressing specific baseline failures
165
197
  2. Run same scenarios WITH skill
166
198
  3. Verify compliance
167
199
 
168
200
  ### REFACTOR Phase
201
+
169
202
  1. Identify new rationalizations from GREEN testing
170
203
  2. Add explicit counters
171
204
  3. Build rationalization table
@@ -20,10 +20,12 @@ Stages and commits changes using Conventional Commits format. Two modes: **defau
20
20
  ## File Selection Rules
21
21
 
22
22
  **NEVER arbitrarily exclude files.** The ONLY valid reason to exclude a file is:
23
+
23
24
  - It is in `.gitignore`
24
25
  - It is completely unrelated to the conversation context (default mode only)
25
26
 
26
27
  **Do NOT exclude files based on:**
28
+
27
29
  - File type or extension (e.g., `.styles.ts`, `.config.ts`)
28
30
  - Folder name or path (e.g., `node_modules` is handled by `.gitignore`)
29
31
  - Personal judgment about importance or "cleanliness"
@@ -44,13 +46,14 @@ Stages and commits changes using Conventional Commits format. Two modes: **defau
44
46
  type(scope): short description
45
47
  ```
46
48
 
47
- | Field | Values |
48
- |-------|--------|
49
- | `type` | `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `build`, `style`, `perf` |
50
- | `scope` | package name or area (e.g., `solid`, `core-common`, `orm-node`) |
51
- | `description` | imperative, lowercase, no period at end |
49
+ | Field | Values |
50
+ | ------------- | ---------------------------------------------------------------------------- |
51
+ | `type` | `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `build`, `style`, `perf` |
52
+ | `scope` | package name or area (e.g., `solid`, `core-common`, `orm-node`) |
53
+ | `description` | imperative, lowercase, no period at end |
52
54
 
53
55
  Examples:
56
+
54
57
  - `feat(solid): add Select component`
55
58
  - `fix(orm-node): handle null values in bulk insert`
56
59
  - `docs: update README with new API examples`
@@ -62,11 +65,13 @@ Use a HEREDOC for multi-line messages when needed.
62
65
  Group by **intent/purpose**, not by package.
63
66
 
64
67
  **Single commit** — all changes share the same intent:
68
+
65
69
  - Version bumps across packages → `chore: bump version to x.y.z`
66
70
  - One feature spanning multiple packages → single `feat`
67
71
  - Dependency updates across packages → single `chore`
68
72
 
69
73
  **Split commits** — changes have different intents:
74
+
70
75
  - Version bump + unrelated bug fix → `chore` + `fix`
71
76
  - New feature + unrelated refactor → two commits
72
77
  - `docs` changes + independent `feat` changes → two commits
@@ -76,6 +81,7 @@ Group by **intent/purpose**, not by package.
76
81
  **Default mode:** `git add <context-relevant files>` → `git commit`
77
82
 
78
83
  **All mode:**
84
+
79
85
  1. Decide: single or split.
80
86
  2. Single: `git add .` → `git commit`.
81
87
  3. Split: group by logical unit, commit in dependency order (foundations first). Per group: `git add <files>` → `git commit`.
@@ -24,6 +24,7 @@ If you haven't completed Phase 1, you cannot propose fixes.
24
24
  ## When to Use
25
25
 
26
26
  Use for ANY technical issue:
27
+
27
28
  - Test failures
28
29
  - Bugs in production
29
30
  - Unexpected behavior
@@ -32,6 +33,7 @@ Use for ANY technical issue:
32
33
  - Integration issues
33
34
 
34
35
  **Use this ESPECIALLY when:**
36
+
35
37
  - Under time pressure (emergencies make guessing tempting)
36
38
  - "Just one quick fix" seems obvious
37
39
  - You've already tried multiple fixes
@@ -39,6 +41,7 @@ Use for ANY technical issue:
39
41
  - You don't fully understand the issue
40
42
 
41
43
  **Don't skip when:**
44
+
42
45
  - Issue seems simple (simple bugs have root causes too)
43
46
  - You're in a hurry (rushing guarantees rework)
44
47
  - Manager wants it fixed NOW (systematic is faster than thrashing)
@@ -75,6 +78,7 @@ You MUST complete each phase before proceeding to the next.
75
78
  **WHEN system has multiple components (CI → build → signing, API → service → database):**
76
79
 
77
80
  **BEFORE proposing fixes, add diagnostic instrumentation:**
81
+
78
82
  ```
79
83
  For EACH component boundary:
80
84
  - Log what data enters component
@@ -88,6 +92,7 @@ You MUST complete each phase before proceeding to the next.
88
92
  ```
89
93
 
90
94
  **Example (multi-layer system):**
95
+
91
96
  ```bash
92
97
  # Layer 1: Workflow
93
98
  echo "=== Secrets available in workflow: ==="
@@ -216,6 +221,7 @@ You MUST complete each phase before proceeding to the next.
216
221
  ## Red Flags - STOP and Follow Process
217
222
 
218
223
  If you catch yourself thinking:
224
+
219
225
  - "Quick fix for now, investigate later"
220
226
  - "Just try changing X and see if it works"
221
227
  - "Add multiple changes, run tests"
@@ -236,6 +242,7 @@ If you catch yourself thinking:
236
242
  ## User Signals You're Doing It Wrong
237
243
 
238
244
  **Watch for these redirections:**
245
+
239
246
  - "Is that not happening?" - You assumed without verifying
240
247
  - "Will it show us...?" - You should have added evidence gathering
241
248
  - "Stop guessing" - You're proposing fixes without understanding
@@ -246,26 +253,26 @@ If you catch yourself thinking:
246
253
 
247
254
  ## Common Rationalizations
248
255
 
249
- | Excuse | Reality |
250
- |--------|---------|
251
- | "Issue is simple, don't need process" | Simple issues have root causes too. Process is fast for simple bugs. |
252
- | "Emergency, no time for process" | Systematic debugging is FASTER than guess-and-check thrashing. |
253
- | "Just try this first, then investigate" | First fix sets the pattern. Do it right from the start. |
254
- | "I'll write test after confirming fix works" | Untested fixes don't stick. Test first proves it. |
255
- | "Multiple fixes at once saves time" | Can't isolate what worked. Causes new bugs. |
256
- | "Reference too long, I'll adapt the pattern" | Partial understanding guarantees bugs. Read it completely. |
257
- | "I see the problem, let me fix it" | Seeing symptoms ≠ understanding root cause. |
258
- | "Let me check git diff to see what changed" | Diff shows WHAT changed, not WHY it's broken. Read the code as-is. |
259
- | "One more fix attempt" (after 2+ failures) | 3+ failures = architectural problem. Question pattern, don't fix again. |
256
+ | Excuse | Reality |
257
+ | -------------------------------------------- | ----------------------------------------------------------------------- |
258
+ | "Issue is simple, don't need process" | Simple issues have root causes too. Process is fast for simple bugs. |
259
+ | "Emergency, no time for process" | Systematic debugging is FASTER than guess-and-check thrashing. |
260
+ | "Just try this first, then investigate" | First fix sets the pattern. Do it right from the start. |
261
+ | "I'll write test after confirming fix works" | Untested fixes don't stick. Test first proves it. |
262
+ | "Multiple fixes at once saves time" | Can't isolate what worked. Causes new bugs. |
263
+ | "Reference too long, I'll adapt the pattern" | Partial understanding guarantees bugs. Read it completely. |
264
+ | "I see the problem, let me fix it" | Seeing symptoms ≠ understanding root cause. |
265
+ | "Let me check git diff to see what changed" | Diff shows WHAT changed, not WHY it's broken. Read the code as-is. |
266
+ | "One more fix attempt" (after 2+ failures) | 3+ failures = architectural problem. Question pattern, don't fix again. |
260
267
 
261
268
  ## Quick Reference
262
269
 
263
- | Phase | Key Activities | Success Criteria |
264
- |-------|---------------|------------------|
265
- | **1. Root Cause** | Read errors, reproduce, read source code, gather evidence | Understand WHAT and WHY |
266
- | **2. Pattern** | Find working examples, compare | Identify differences |
267
- | **3. Hypothesis** | Form theory, test minimally | Confirmed or new hypothesis |
268
- | **4. Implementation** | Create test, fix, verify | Bug resolved, tests pass |
270
+ | Phase | Key Activities | Success Criteria |
271
+ | --------------------- | --------------------------------------------------------- | --------------------------- |
272
+ | **1. Root Cause** | Read errors, reproduce, read source code, gather evidence | Understand WHAT and WHY |
273
+ | **2. Pattern** | Find working examples, compare | Identify differences |
274
+ | **3. Hypothesis** | Form theory, test minimally | Confirmed or new hypothesis |
275
+ | **4. Implementation** | Create test, fix, verify | Bug resolved, tests pass |
269
276
 
270
277
  ## When Process Reveals "No Root Cause"
271
278
 
@@ -287,12 +294,14 @@ These techniques are part of systematic debugging and available in this director
287
294
  - **`condition-based-waiting.md`** - Replace arbitrary timeouts with condition polling
288
295
 
289
296
  **Related skills:**
297
+
290
298
  - **sd-tdd** - For creating failing test case (Phase 4, Step 1)
291
299
  - **sd-check** - Verify fix worked before claiming success
292
300
 
293
301
  ## Real-World Impact
294
302
 
295
303
  From debugging sessions:
304
+
296
305
  - Systematic approach: 15-30 minutes to fix
297
306
  - Random fixes approach: 2-3 hours of thrashing
298
307
  - First-time fix rate: 95% vs 40%
@@ -22,12 +22,14 @@ digraph when_to_use {
22
22
  ```
23
23
 
24
24
  **Use when:**
25
+
25
26
  - Tests have arbitrary delays (`setTimeout`, `sleep`, `time.sleep()`)
26
27
  - Tests are flaky (pass sometimes, fail under load)
27
28
  - Tests timeout when run in parallel
28
29
  - Waiting for async operations to complete
29
30
 
30
31
  **Don't use when:**
32
+
31
33
  - Testing actual timing behavior (debounce, throttle intervals)
32
34
  - Always document WHY if using arbitrary timeout
33
35
 
@@ -35,7 +37,7 @@ digraph when_to_use {
35
37
 
36
38
  ```typescript
37
39
  // ❌ BEFORE: Guessing at timing
38
- await new Promise(r => setTimeout(r, 50));
40
+ await new Promise((r) => setTimeout(r, 50));
39
41
  const result = getResult();
40
42
  expect(result).toBeDefined();
41
43
 
@@ -47,22 +49,23 @@ expect(result).toBeDefined();
47
49
 
48
50
  ## Quick Patterns
49
51
 
50
- | Scenario | Pattern |
51
- |----------|---------|
52
- | Wait for event | `waitFor(() => events.find(e => e.type === 'DONE'))` |
53
- | Wait for state | `waitFor(() => machine.state === 'ready')` |
54
- | Wait for count | `waitFor(() => items.length >= 5)` |
55
- | Wait for file | `waitFor(() => fs.existsSync(path))` |
56
- | Complex condition | `waitFor(() => obj.ready && obj.value > 10)` |
52
+ | Scenario | Pattern |
53
+ | ----------------- | ---------------------------------------------------- |
54
+ | Wait for event | `waitFor(() => events.find(e => e.type === 'DONE'))` |
55
+ | Wait for state | `waitFor(() => machine.state === 'ready')` |
56
+ | Wait for count | `waitFor(() => items.length >= 5)` |
57
+ | Wait for file | `waitFor(() => fs.existsSync(path))` |
58
+ | Complex condition | `waitFor(() => obj.ready && obj.value > 10)` |
57
59
 
58
60
  ## Implementation
59
61
 
60
62
  Generic polling function:
63
+
61
64
  ```typescript
62
65
  async function waitFor<T>(
63
66
  condition: () => T | undefined | null | false,
64
67
  description: string,
65
- timeoutMs = 5000
68
+ timeoutMs = 5000,
66
69
  ): Promise<T> {
67
70
  const startTime = Date.now();
68
71
 
@@ -74,7 +77,7 @@ async function waitFor<T>(
74
77
  throw new Error(`Timeout waiting for ${description} after ${timeoutMs}ms`);
75
78
  }
76
79
 
77
- await new Promise(r => setTimeout(r, 10)); // Poll every 10ms
80
+ await new Promise((r) => setTimeout(r, 10)); // Poll every 10ms
78
81
  }
79
82
  }
80
83
  ```
@@ -96,12 +99,13 @@ See `condition-based-waiting-example.ts` in this directory for complete implemen
96
99
 
97
100
  ```typescript
98
101
  // Tool ticks every 100ms - need 2 ticks to verify partial output
99
- await waitForEvent(manager, 'TOOL_STARTED'); // First: wait for condition
100
- await new Promise(r => setTimeout(r, 200)); // Then: wait for timed behavior
102
+ await waitForEvent(manager, "TOOL_STARTED"); // First: wait for condition
103
+ await new Promise((r) => setTimeout(r, 200)); // Then: wait for timed behavior
101
104
  // 200ms = 2 ticks at 100ms intervals - documented and justified
102
105
  ```
103
106
 
104
107
  **Requirements:**
108
+
105
109
  1. First wait for triggering condition
106
110
  2. Based on known timing (not guessing)
107
111
  3. Comment explaining WHY
@@ -109,6 +113,7 @@ await new Promise(r => setTimeout(r, 200)); // Then: wait for timed behavior
109
113
  ## Real-World Impact
110
114
 
111
115
  From debugging session (2025-10-03):
116
+
112
117
  - Fixed 15 flaky tests across 3 files
113
118
  - Pass rate: 60% → 100%
114
119
  - Execution time: 40% faster
@@ -12,6 +12,7 @@ Single validation: "We fixed the bug"
12
12
  Multiple layers: "We made the bug impossible"
13
13
 
14
14
  Different layers catch different cases:
15
+
15
16
  - Entry validation catches most bugs
16
17
  - Business logic catches edge cases
17
18
  - Environment guards prevent context-specific dangers
@@ -20,12 +21,13 @@ Different layers catch different cases:
20
21
  ## The Four Layers
21
22
 
22
23
  ### Layer 1: Entry Point Validation
24
+
23
25
  **Purpose:** Reject obviously invalid input at API boundary
24
26
 
25
27
  ```typescript
26
28
  function createProject(name: string, workingDirectory: string) {
27
- if (!workingDirectory || workingDirectory.trim() === '') {
28
- throw new Error('workingDirectory cannot be empty');
29
+ if (!workingDirectory || workingDirectory.trim() === "") {
30
+ throw new Error("workingDirectory cannot be empty");
29
31
  }
30
32
  if (!existsSync(workingDirectory)) {
31
33
  throw new Error(`workingDirectory does not exist: ${workingDirectory}`);
@@ -38,31 +40,31 @@ function createProject(name: string, workingDirectory: string) {
38
40
  ```
39
41
 
40
42
  ### Layer 2: Business Logic Validation
43
+
41
44
  **Purpose:** Ensure data makes sense for this operation
42
45
 
43
46
  ```typescript
44
47
  function initializeWorkspace(projectDir: string, sessionId: string) {
45
48
  if (!projectDir) {
46
- throw new Error('projectDir required for workspace initialization');
49
+ throw new Error("projectDir required for workspace initialization");
47
50
  }
48
51
  // ... proceed
49
52
  }
50
53
  ```
51
54
 
52
55
  ### Layer 3: Environment Guards
56
+
53
57
  **Purpose:** Prevent dangerous operations in specific contexts
54
58
 
55
59
  ```typescript
56
60
  async function gitInit(directory: string) {
57
61
  // In tests, refuse git init outside temp directories
58
- if (process.env.NODE_ENV === 'test') {
62
+ if (process.env.NODE_ENV === "test") {
59
63
  const normalized = normalize(resolve(directory));
60
64
  const tmpDir = normalize(resolve(tmpdir()));
61
65
 
62
66
  if (!normalized.startsWith(tmpDir)) {
63
- throw new Error(
64
- `Refusing git init outside temp dir during tests: ${directory}`
65
- );
67
+ throw new Error(`Refusing git init outside temp dir during tests: ${directory}`);
66
68
  }
67
69
  }
68
70
  // ... proceed
@@ -70,12 +72,13 @@ async function gitInit(directory: string) {
70
72
  ```
71
73
 
72
74
  ### Layer 4: Debug Instrumentation
75
+
73
76
  **Purpose:** Capture context for forensics
74
77
 
75
78
  ```typescript
76
79
  async function gitInit(directory: string) {
77
80
  const stack = new Error().stack;
78
- logger.debug('About to git init', {
81
+ logger.debug("About to git init", {
79
82
  directory,
80
83
  cwd: process.cwd(),
81
84
  stack,
@@ -98,12 +101,14 @@ When you find a bug:
98
101
  Bug: Empty `projectDir` caused `git init` in source code
99
102
 
100
103
  **Data flow:**
104
+
101
105
  1. Test setup → empty string
102
106
  2. `Project.create(name, '')`
103
107
  3. `WorkspaceManager.createWorkspace('')`
104
108
  4. `git init` runs in `process.cwd()`
105
109
 
106
110
  **Four layers added:**
111
+
107
112
  - Layer 1: `Project.create()` validates not empty/exists/writable
108
113
  - Layer 2: `WorkspaceManager` validates projectDir not empty
109
114
  - Layer 3: `WorktreeManager` refuses git init outside tmpdir in tests
@@ -114,6 +119,7 @@ Bug: Empty `projectDir` caused `git init` in source code
114
119
  ## Key Insight
115
120
 
116
121
  All four layers were necessary. During testing, each layer caught bugs the others missed:
122
+
117
123
  - Different code paths bypassed entry validation
118
124
  - Mocks bypassed business logic checks
119
125
  - Edge cases on different platforms needed environment guards
@@ -24,6 +24,7 @@ digraph when_to_use {
24
24
  ```
25
25
 
26
26
  **Use when:**
27
+
27
28
  - Error happens deep in execution (not at entry point)
28
29
  - Stack trace shows long call chain
29
30
  - Unclear where invalid data originated
@@ -32,17 +33,21 @@ digraph when_to_use {
32
33
  ## The Tracing Process
33
34
 
34
35
  ### 1. Observe the Symptom
36
+
35
37
  ```
36
38
  Error: git init failed in /Users/jesse/project/packages/core
37
39
  ```
38
40
 
39
41
  ### 2. Find Immediate Cause
42
+
40
43
  **What code directly causes this?**
44
+
41
45
  ```typescript
42
- await execFileAsync('git', ['init'], { cwd: projectDir });
46
+ await execFileAsync("git", ["init"], { cwd: projectDir });
43
47
  ```
44
48
 
45
49
  ### 3. Ask: What Called This?
50
+
46
51
  ```typescript
47
52
  WorktreeManager.createSessionWorktree(projectDir, sessionId)
48
53
  → called by Session.initializeWorkspace()
@@ -51,16 +56,20 @@ WorktreeManager.createSessionWorktree(projectDir, sessionId)
51
56
  ```
52
57
 
53
58
  ### 4. Keep Tracing Up
59
+
54
60
  **What value was passed?**
61
+
55
62
  - `projectDir = ''` (empty string!)
56
63
  - Empty string as `cwd` resolves to `process.cwd()`
57
64
  - That's the source code directory!
58
65
 
59
66
  ### 5. Find Original Trigger
67
+
60
68
  **Where did empty string come from?**
69
+
61
70
  ```typescript
62
71
  const context = setupCoreTest(); // Returns { tempDir: '' }
63
- Project.create('name', context.tempDir); // Accessed before beforeEach!
72
+ Project.create("name", context.tempDir); // Accessed before beforeEach!
64
73
  ```
65
74
 
66
75
  ## Adding Stack Traces
@@ -71,25 +80,27 @@ When you can't trace manually, add instrumentation:
71
80
  // Before the problematic operation
72
81
  async function gitInit(directory: string) {
73
82
  const stack = new Error().stack;
74
- console.error('DEBUG git init:', {
83
+ console.error("DEBUG git init:", {
75
84
  directory,
76
85
  cwd: process.cwd(),
77
86
  nodeEnv: process.env.NODE_ENV,
78
87
  stack,
79
88
  });
80
89
 
81
- await execFileAsync('git', ['init'], { cwd: directory });
90
+ await execFileAsync("git", ["init"], { cwd: directory });
82
91
  }
83
92
  ```
84
93
 
85
94
  **Critical:** Use `console.error()` in tests (not logger - may not show)
86
95
 
87
96
  **Run and capture:**
97
+
88
98
  ```bash
89
99
  npm test 2>&1 | grep 'DEBUG git init'
90
100
  ```
91
101
 
92
102
  **Analyze stack traces:**
103
+
93
104
  - Look for test file names
94
105
  - Find the line number triggering the call
95
106
  - Identify the pattern (same test? same parameter?)
@@ -111,6 +122,7 @@ Runs tests one-by-one, stops at first polluter. See script for usage.
111
122
  **Symptom:** `.git` created in `packages/core/` (source code)
112
123
 
113
124
  **Trace chain:**
125
+
114
126
  1. `git init` runs in `process.cwd()` ← empty cwd parameter
115
127
  2. WorktreeManager called with empty projectDir
116
128
  3. Session.create() passed empty string
@@ -122,6 +134,7 @@ Runs tests one-by-one, stops at first polluter. See script for usage.
122
134
  **Fix:** Made tempDir a getter that throws if accessed before beforeEach
123
135
 
124
136
  **Also added defense-in-depth:**
137
+
125
138
  - Layer 1: Project.create() validates directory
126
139
  - Layer 2: WorkspaceManager validates not empty
127
140
  - Layer 3: NODE_ENV guard refuses git init outside tmpdir
@@ -163,6 +176,7 @@ digraph principle {
163
176
  ## Real-World Impact
164
177
 
165
178
  From debugging session (2025-10-03):
179
+
166
180
  - Found root cause through 5-level trace
167
181
  - Fixed at source (getter validation)
168
182
  - Added 4 layers of defense