Skip to content

Commit d5ba25d

Browse files
committed
Merge branch 'main' of github.com:jschulte/stackshift
2 parents f70f749 + 8f63ec0 commit d5ba25d

File tree

13 files changed

+1422
-37
lines changed

13 files changed

+1422
-37
lines changed
Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
<!--
2+
SPDX-License-Identifier: MIT
3+
Copyright (c) 2024 Jonah Schulte
4+
-->
5+
6+
# Brownfield Upgrade Mode
7+
8+
**Modernize dependencies without a full rewrite**
9+
10+
---
11+
12+
## Overview
13+
14+
Brownfield Upgrade Mode allows you to upgrade ALL dependencies to their latest versions after establishing complete spec coverage. Unlike a full rewrite (Greenfield), this approach modernizes your existing codebase systematically using specs as your safety net.
15+
16+
**When to use:**
17+
- Legacy app stuck on old dependencies (security vulnerabilities)
18+
- Want modern tooling benefits without full rewrite
19+
- Have completed StackShift Gears 1-6 (full spec coverage)
20+
- Ready for systematic modernization
21+
22+
**What you get:**
23+
- All dependencies at latest stable versions
24+
- 85%+ test coverage (improved using spec acceptance criteria)
25+
- Specs validated to match upgraded code
26+
- Security vulnerabilities eliminated
27+
- Breaking changes fixed with spec guidance
28+
29+
---
30+
31+
## Inspiration: existing migration tools
32+
33+
34+
35+
### Phase 0: Spec-Guided Test Coverage (30-90 min)
36+
37+
**Goal:** Achieve 85%+ test coverage BEFORE upgrading
38+
39+
**Why first:**
40+
- Acts as safety net during upgrade
41+
- Detects regressions immediately
42+
- Validates behavior preservation
43+
44+
**Approach:**
45+
1. Load all specs from `.specify/memory/specifications/`
46+
2. Extract acceptance criteria from each spec
47+
3. Map existing tests to acceptance criteria
48+
4. Write tests for missing criteria
49+
5. Iterate until 85%+ coverage
50+
51+
**Output:**
52+
- `.upgrade/spec-coverage-map.json` - Maps tests to specs
53+
- 85%+ test coverage
54+
- Every acceptance criterion has test
55+
56+
**Example:**
57+
58+
From `user-authentication.md`:
59+
```markdown
60+
## Acceptance Criteria
61+
- AC-1: Given valid email, When user submits, Then account created
62+
- AC-2: Given weak password, When user submits, Then error shown
63+
- AC-3: Given user logs in, When session expires, Then redirect to login
64+
```
65+
66+
Tests written:
67+
```typescript
68+
// AC-1 test
69+
it('should create account with valid email', ...)
70+
71+
// AC-2 test
72+
it('should show error for weak password', ...)
73+
74+
// AC-3 test
75+
it('should redirect to login when session expires', ...)
76+
```
77+
78+
---
79+
80+
### Phase 1: Baseline & Analysis - READ ONLY (15-30 min)
81+
82+
**Goal:** Understand current state and plan upgrade
83+
84+
**Why read-only:**
85+
- Understand impact before making changes
86+
- Plan fixes before breaking things
87+
- Identify high-risk areas
88+
89+
**Steps:**
90+
1. Run `/speckit.analyze` → Document current spec-code alignment
91+
2. Run `npm outdated` → See what will change
92+
3. Analyze spec impact → Which specs affected by breaking changes?
93+
4. Generate upgrade plan → `.upgrade/UPGRADE_PLAN.md`
94+
5. Create tracking file → `.upgrade/stackshift-upgrade.yml`
95+
96+
**Output:**
97+
- `.upgrade/UPGRADE_PLAN.md` - Complete upgrade plan
98+
- `.upgrade/spec-impact-analysis.json` - Which specs affected
99+
- `.upgrade/dependencies-before.txt` - Current versions
100+
- `.upgrade/stackshift-upgrade.yml` - Progress tracking
101+
102+
**Example Spec Impact:**
103+
104+
```json
105+
{
106+
"react": {
107+
"current": "17.0.2",
108+
"latest": "19.2.0",
109+
"breaking": true,
110+
"affectedSpecs": [
111+
"user-interface.md", // Uses React components
112+
"form-handling.md" // State batching changes
113+
],
114+
"risk": "HIGH"
115+
}
116+
}
117+
```
118+
119+
---
120+
121+
### Phase 2: Upgrade & Spec-Guided Fixes (1-4 hours)
122+
123+
**Goal:** Upgrade dependencies, fix breaking changes
124+
125+
**Approach:**
126+
1. Create upgrade branch
127+
2. Upgrade ALL dependencies (`npx npm-check-updates -u`)
128+
3. Run tests → Detect failures
129+
4. For EACH failure:
130+
- Load spec that test validates (from coverage map)
131+
- Read acceptance criterion test is checking
132+
- Fix code to preserve spec behavior
133+
- Verify fix with test
134+
- Commit incremental fix
135+
5. Continue until all tests pass
136+
137+
**Spec-Guided Fix Example:**
138+
139+
```
140+
Test fails: user-interface.test.ts - "renders user profile"
141+
142+
1. Find spec: spec-coverage-map.json → "user-interface.md"
143+
144+
2. Load spec:
145+
cat .specify/memory/specifications/user-interface.md
146+
147+
3. Find AC:
148+
"AC-5: Given user profile data, When component renders,
149+
Then displays name, email, and avatar"
150+
151+
4. Fix code:
152+
- React 19 changed rendering behavior
153+
- Update component to preserve "displays name, email, avatar" behavior
154+
- Ensure spec AC-5 still met
155+
156+
5. Verify:
157+
npm test -- user-interface.test.ts ✅
158+
```
159+
160+
**Decision Matrix:**
161+
162+
| Situation | Action |
163+
|-----------|--------|
164+
| Breaking change, spec clear | Fix code to match spec |
165+
| Breaking change, spec unclear | Run `/speckit.clarify` first |
166+
| Breaking change is improvement | Update spec + code (document why) |
167+
| Just API change, same behavior | Update code only (no spec change) |
168+
169+
---
170+
171+
### Phase 3: Validation & PR (15-30 min)
172+
173+
**Goal:** Ensure specs match code, create PR
174+
175+
**Steps:**
176+
1. Run `/speckit.analyze` → Validate no drift
177+
2. Verify coverage ≥85%
178+
3. Run full validation (tests, build, lint)
179+
4. Generate upgrade report
180+
5. Create PR with spec validation
181+
182+
**Validation:**
183+
184+
```bash
185+
# All must pass
186+
npm test # ✅ All passing
187+
npm run build # ✅ Successful
188+
npm run lint # ✅ No errors
189+
/speckit.analyze # ✅ All specs match code
190+
npm audit # ✅ No high/critical
191+
192+
# Coverage check
193+
COVERAGE=$(jq '.total.lines.pct' coverage/coverage-summary.json)
194+
[ $(echo "$COVERAGE >= 85" | bc) -eq 1 ] && echo "✅ Coverage: ${COVERAGE}%" || echo "❌ Coverage too low"
195+
```
196+
197+
---
198+
199+
200+
## Usage
201+
202+
### Option 1: During Initial Analysis (Gear 1)
203+
204+
When asked about Brownfield mode:
205+
206+
```
207+
Would you like to enable Upgrade mode?
208+
209+
A) Standard - Spec the current state as-is
210+
B) Upgrade - Spec current state + modernize dependencies
211+
212+
Choose: B
213+
```
214+
215+
This sets `modernize: true` in state. After Gear 6, modernize auto-triggers.
216+
217+
### Option 2: After Gear 6
218+
219+
If you completed Gears 1-6 without upgrade mode:
220+
221+
```bash
222+
# Run the slash command
223+
/stackshift.modernize
224+
225+
# Or invoke the skill
226+
"I want to modernize this application's dependencies"
227+
```
228+
229+
---
230+
231+
## Prerequisites
232+
233+
Before running modernize:
234+
235+
- ✅ Completed Gears 1-6 (Brownfield route)
236+
- ✅ Full spec coverage in `.specify/memory/specifications/`
237+
-`/speckit.*` commands available
238+
- ✅ Tests currently passing
239+
- ✅ Build currently working
240+
- ✅ Git working tree clean
241+
242+
If any missing, fix first.
243+
244+
---
245+
246+
## Files Created
247+
248+
```
249+
.upgrade/
250+
├── stackshift-upgrade.yml # Progress tracking
251+
├── spec-coverage-map.json # Tests → Specs mapping
252+
├── baseline-coverage.txt # Pre-upgrade test coverage
253+
├── dependencies-before.txt # Pre-upgrade versions
254+
├── UPGRADE_PLAN.md # Phase 1 analysis & plan
255+
├── spec-impact-analysis.json # Which specs affected
256+
├── dependencies-after.txt # Post-upgrade versions
257+
├── test-results-post-upgrade.txt # Initial test run
258+
├── fixes-applied.log # Each breaking change fix
259+
├── final-spec-analysis.txt # /speckit.analyze results
260+
└── UPGRADE_REPORT.md # Final comprehensive report
261+
```
262+
263+
---
264+
265+
## Success Criteria
266+
267+
Upgrade complete when:
268+
269+
- ✅ All dependencies at latest stable versions
270+
- ✅ Test coverage ≥85%
271+
- ✅ All tests passing
272+
- ✅ Build successful
273+
- ✅ Lint passing
274+
-`/speckit.analyze` shows all specs COMPLETE (no drift)
275+
- ✅ No high/critical security vulnerabilities
276+
- ✅ PR created with comprehensive report
277+
- ✅ Specs updated if behavior changed (documented why)
278+
279+
---
280+
281+
## Benefits
282+
283+
**vs. Staying on Old Dependencies:**
284+
- ✅ Eliminate security vulnerabilities
285+
- ✅ Get modern tooling features
286+
- ✅ Improved performance
287+
- ✅ Active maintenance/support
288+
289+
**vs. Full Rewrite (Greenfield):**
290+
- ✅ Much faster (days vs. months)
291+
- ✅ Lower risk (incremental changes)
292+
- ✅ Keep working code
293+
- ✅ Spec-guided safety net
294+
295+
**vs. Manual Upgrade:**
296+
- ✅ Systematic process
297+
- ✅ Spec guidance on fixes
298+
- ✅ Comprehensive validation
299+
- ✅ Documented in upgrade report
300+
301+
---
302+
303+
## Example: Next.js 12 → 15 Upgrade
304+
305+
```bash
306+
# Before upgrade
307+
next: 12.3.0
308+
react: 17.0.2
309+
test coverage: 78%
310+
311+
# After Phase 0
312+
test coverage: 87% (added tests from spec ACs)
313+
314+
# After Phase 1
315+
.upgrade/UPGRADE_PLAN.md created
316+
Identified: 5 high-risk specs affected by Next.js 15 changes
317+
318+
# After Phase 2
319+
next: 15.1.0
320+
react: 19.2.0
321+
Breaking changes: 12 fixed (spec-guided)
322+
All tests passing ✅
323+
324+
# After Phase 3
325+
/speckit.analyze: All specs validated ✅
326+
PR created with upgrade report
327+
```
328+
329+
---
330+
331+
## Related Commands
332+
333+
- `/speckit.analyze` - Validate specs match code
334+
- `/speckit.clarify` - Resolve spec ambiguities
335+
- `/stackshift.modernize` - This command
336+
337+
---
338+
339+
**Remember:** Specs make upgrades safer. They're your contract defining how the system should behave. Preserve that contract while modernizing underneath.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)