> {
+ -> CutResult {
```
vs. wholesale replacement. 🎯
.mermaid[
graph LR
A["Full file rewrite"] --> B["💣 All comments lost"]
C["Targeted edit"] --> D["✅ Comments preserved"]
D --> E["Happy user 😊"]
B --> F["Angry user 😤"]
style A fill:#5c1a1a
style B fill:#5c1a1a
style C fill:#1a3d1a
style D fill:#1a3d1a
]
---
## Mistake #3 🏆
class: nord-light, middle, center
## 🏆 Mistake #3: Careless Bulk replaceAll
---
### What Happened
I used `replaceAll` to change `.row(` → `.set_row(` across test files:
```cpp
m1.set_row(0) = Vec{25.0, 15.0, -5.0}; // WRONG! Missing paren
```
The `)` from `row(0)` got consumed, leaving `set_row(0` without closure. **40+ compilation errors.** 🤦
---
### The Fallout
I had to fix with a **chain of 4 regex replacements** across 4 files:
```
Step 1: .row( → .set_row( (replaceAll)
Step 2: ) = Vec{ → , Vec{ (replaceAll)
Step 3: Vec{...}; → Vec{...}); (regex)
Step 4: verify syntax, re-fix semicolons...
```
Each regex was a **new opportunity for breakage**. The `;` was dropped in step 2, then the `)` was dropped in step 3.
---
### The Lesson
**Test syntax incrementally.** After each replaceAll:
```bash
xmake -j 10 # build immediately
# 40 errors? Stop! Don't pile on more replacements.
```
Better approach: **compile after each file**, not after all 4.
.mermaid[
flowchart LR
A["Edit file 1"] --> B["Build 🔨"]
B --> C{"Errors?"}
C -->|"Yes"| D["Fix & rebuild"]
C -->|"No"| E["Edit file 2"]
D --> B
E --> F["Build 🔨"]
style A fill:#ff9800
style E fill:#4caf50
style B fill:#2196f3
style F fill:#2196f3
]
---
## Mistake #4 🏆
class: nord-light, middle, center
## 🏆 Mistake #4: Changed Numerical Values in Tests
---
### What Happened
When converting `calc_bias_cut(beta, tsq)` → `calc_bias_cut(beta, tau)`:
```cpp
// Old call: beta=0.05, tsq=0.01 → internal sqrt → tau=0.1
// New call: beta=0.05, tau=0.1 → GREAT, same value ✓
// BUT:
// Old call: beta=0.05, tsq=0.1 → internal sqrt → tau=0.316...
// New call: beta=0.05, tau=0.1 → tau=0.1, NOT 0.316! ✗
```
Result: `rho` went from $0.103 \to 0.06$. The test expected $0.103246$. **Test silently wrong.** 🎭
---
### Root Cause
The parameter **changed semantic meaning** — from $t^2$ to $t$ — but I updated the call sites mechanically instead of carefully:
.mermaid[
flowchart LR
A["tsq=0.1 passed to calc_bias_cut"] --> B["OLD: interpret as t²"]
B --> C["sqrt(0.1) = 0.3162..."]
A --> D["NEW: interpret as t"]
D --> E["tau=0.1 (wrong!)"]
B --> F["eta = 0.5162 → rho = 0.1032"]
D --> G["eta = 0.3 → rho = 0.06"]
F --> H["✅ Test expects 0.1032"]
G --> I["❌ Test gets 0.06"]
style D fill:#5c1a1a
style I fill:#5c1a1a
]
---
### The Proper Approach
**Don't change parameter semantics.** If a method historically takes $t^2$, keep it. Compute $\tau$ internally:
```cpp
// calc_bias_cut(beta, tsq) — tsq is STILL tsq
auto r = ell_calc.calc_bias_cut(0.05, 0.1);
// Internally: tau = sqrt(0.1) = 0.3162... ✓
```
Or, if changing to $\tau$ is essential, **audit EVERY call site** and convert $t^2 \to \sqrt{t^2}$:
| Old $t^2$ | New $\tau = \sqrt{t^2}$ | Effect on test |
|-----------|------------------------|---------------|
| 0.01 | 0.1 | Same values ✓ |
| 0.10 | 0.316227... | **Values change!** ⚠️ |
---
## Mistake #5 🏆
class: nord-light, middle, center
## 🏆 Mistake #5: Over-Ambitious Batch Changes
---
### The Pattern
I proposed **7 simultaneous changes** to the user:
.pull-left[
1. P0: Matrix backend 🏗️
2. P1: CutResult struct 📦
3. P2: Loop counter types 🔢
4. P3: const double& → double 📐
]
.pull-right[
5. P4: no_defer_trick fold (skipped)
6. P5: Move sqrt up 📈
7. P6: Scratch vector 📎
]
**Result**: 3 changes rolled back, 2 required test files rewritten, the user had to say "revert everything." 😓
---
### Decomposition Diagram
.mermaid[
flowchart TD
subgraph "Batch 1: Safe(no test impact)"
P2["P2: Loop counters"] --> OK1["✅ Builds clean"]
P3["P3: const double& → double"] --> OK1
P6["P6: Scratch vector"] --> OK1
end
subgraph "Batch 2: API change(test update needed)"
P0["P0: Matrix vector"] --> T1["Update test_ell_matrix"]
P1["P1: CutResult struct"] --> T2["Update test_calc"]
end
subgraph "Batch 3: Numeric(very risky)"
P5["P5: Move sqrt up"] --> NUM["⚠️ IEEE 754 issues"]
NUM --> ROLL["Reverted 🔙"]
end
T1 --> OK2["✅ Builds clean"]
T2 --> OK2
style ROLL fill:#5c1a1a
style NUM fill:#ff9800
style OK1 fill:#1a3d1a
style OK2 fill:#1a3d1a
]
---
### The Lesson
**Ship in small, verifiable increments:**
1. **Batch 1** — changes with zero test/numeric impact → build + test
2. **Batch 2** — API-only changes (return types) → update tests → build + test
3. **Batch 3** — ONE numerical change → verify identical results → build + test
Never mix "safe" and "risky" changes in the same commit. **CI is your lifeline.** 🚑
---
class: nord-light, middle, center
## 🧠 Key Takeaways
---
### Lessons Learned
.mermaid[
graph TB
subgraph "✅ Do This"
A["Targeted edits\n(preserve comments)"]
B["Incremental build\n(after each file)"]
C["Separate safe & risky\nchanges into batches"]
D["Keep original values\nwhen changing API semantics"]
E["Use existing member\ninstead of reconstructing"]
end
subgraph "❌ Avoid This"
F["Full-file rewrite\n(loses docstrings)"]
G["Bulk replaceAll\n(chain reactions)"]
H["7 changes at once\n(can't diagnose failures)"]
I["Change parameter meaning\nwithout auditing callers"]
J["tau × tau instead of tsq\n(IEEE 754 drift)"]
end
style A fill:#1a3d1a
style B fill:#1a3d1a
style C fill:#1a3d1a
style D fill:#1a3d1a
style E fill:#1a3d1a
style F fill:#5c1a1a
style G fill:#5c1a1a
style H fill:#5c1a1a
style I fill:#5c1a1a
style J fill:#5c1a1a
]
---
### The Golden Rule of Agent-Driven Refactoring
> **"First, do no harm."** 🏥
>
> — The AI Agent's Hippocratic Oath
1. **Preserve** existing documentation
2. **Incrementally** build and test
3. **Separate** safe changes from risky ones
4. **Never** change numerical semantics without verification
5. **Never** reconstruct a value you already hold
---
### Statistical Summary
| Metric | Value |
|--------|-------|
| Changes proposed | 7 |
| Reverted completely | 1 (P5) |
| Required test rewrites | 2 (P0, P1) |
| Caused compilation errors | 4 |
| Total build-test cycles | 12 |
| Final tests passing | **102/102** ✅ |
| User frustration level | Medium-High 🔥 |
---
count: false
class: nord-dark, middle, center
## Q&A 🎤
> "The best teacher is the one who makes you realize you already knew the answer, but screwed it up anyway."
>
> — Someone wise, probably after their first refactoring PR
---
count: false
class: nord-dark, middle, center
# Thank You! 🙏
## End of Presentation