mindsystem-cc 3.0.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/LICENSE +21 -0
- package/README.md +501 -0
- package/agents/ms-codebase-mapper.md +739 -0
- package/agents/ms-debugger.md +1184 -0
- package/agents/ms-designer.md +414 -0
- package/agents/ms-executor.md +760 -0
- package/agents/ms-integration-checker.md +423 -0
- package/agents/ms-milestone-auditor.md +448 -0
- package/agents/ms-mock-generator.md +182 -0
- package/agents/ms-plan-checker.md +746 -0
- package/agents/ms-research-synthesizer.md +248 -0
- package/agents/ms-researcher.md +962 -0
- package/agents/ms-roadmapper.md +606 -0
- package/agents/ms-verifier.md +779 -0
- package/agents/ms-verify-fixer.md +124 -0
- package/bin/install.js +296 -0
- package/commands/ms/add-phase.md +207 -0
- package/commands/ms/add-todo.md +182 -0
- package/commands/ms/audit-milestone.md +318 -0
- package/commands/ms/check-phase.md +162 -0
- package/commands/ms/check-todos.md +217 -0
- package/commands/ms/complete-milestone.md +137 -0
- package/commands/ms/create-roadmap.md +273 -0
- package/commands/ms/debug.md +149 -0
- package/commands/ms/define-requirements.md +121 -0
- package/commands/ms/design-phase.md +341 -0
- package/commands/ms/discuss-milestone.md +48 -0
- package/commands/ms/discuss-phase.md +60 -0
- package/commands/ms/do-work.md +90 -0
- package/commands/ms/execute-phase.md +289 -0
- package/commands/ms/help.md +623 -0
- package/commands/ms/insert-phase.md +227 -0
- package/commands/ms/list-phase-assumptions.md +50 -0
- package/commands/ms/map-codebase.md +71 -0
- package/commands/ms/new-milestone.md +193 -0
- package/commands/ms/new-project.md +338 -0
- package/commands/ms/pause-work.md +123 -0
- package/commands/ms/plan-milestone-gaps.md +285 -0
- package/commands/ms/plan-phase.md +105 -0
- package/commands/ms/progress.md +370 -0
- package/commands/ms/remove-phase.md +338 -0
- package/commands/ms/research-phase.md +175 -0
- package/commands/ms/research-project.md +339 -0
- package/commands/ms/resume-work.md +40 -0
- package/commands/ms/review-design.md +484 -0
- package/commands/ms/simplify-flutter.md +193 -0
- package/commands/ms/update.md +159 -0
- package/commands/ms/verify-work.md +92 -0
- package/commands/ms/whats-new.md +124 -0
- package/mindsystem/references/checkpoints.md +788 -0
- package/mindsystem/references/continuation-format.md +255 -0
- package/mindsystem/references/debugging/debugging-mindset.md +11 -0
- package/mindsystem/references/debugging/hypothesis-testing.md +11 -0
- package/mindsystem/references/debugging/investigation-techniques.md +11 -0
- package/mindsystem/references/debugging/verification-patterns.md +11 -0
- package/mindsystem/references/debugging/when-to-research.md +11 -0
- package/mindsystem/references/git-integration.md +254 -0
- package/mindsystem/references/goal-backward.md +286 -0
- package/mindsystem/references/mock-patterns.md +294 -0
- package/mindsystem/references/plan-format.md +473 -0
- package/mindsystem/references/principles.md +73 -0
- package/mindsystem/references/questioning.md +140 -0
- package/mindsystem/references/research-pitfalls.md +233 -0
- package/mindsystem/references/scope-estimation.md +256 -0
- package/mindsystem/references/tdd.md +263 -0
- package/mindsystem/references/verification-patterns.md +595 -0
- package/mindsystem/templates/DEBUG.md +159 -0
- package/mindsystem/templates/UAT.md +403 -0
- package/mindsystem/templates/adhoc-summary.md +153 -0
- package/mindsystem/templates/codebase/architecture.md +255 -0
- package/mindsystem/templates/codebase/concerns.md +310 -0
- package/mindsystem/templates/codebase/conventions.md +307 -0
- package/mindsystem/templates/codebase/integrations.md +280 -0
- package/mindsystem/templates/codebase/stack.md +186 -0
- package/mindsystem/templates/codebase/structure.md +285 -0
- package/mindsystem/templates/codebase/testing.md +480 -0
- package/mindsystem/templates/config.json +26 -0
- package/mindsystem/templates/context.md +140 -0
- package/mindsystem/templates/continue-here.md +78 -0
- package/mindsystem/templates/debug-subagent-prompt.md +91 -0
- package/mindsystem/templates/design-iteration.md +208 -0
- package/mindsystem/templates/design.md +417 -0
- package/mindsystem/templates/discovery.md +146 -0
- package/mindsystem/templates/milestone-archive.md +123 -0
- package/mindsystem/templates/milestone-context.md +93 -0
- package/mindsystem/templates/milestone.md +115 -0
- package/mindsystem/templates/phase-prompt.md +574 -0
- package/mindsystem/templates/project.md +184 -0
- package/mindsystem/templates/requirements.md +231 -0
- package/mindsystem/templates/research-project/ARCHITECTURE.md +204 -0
- package/mindsystem/templates/research-project/FEATURES.md +147 -0
- package/mindsystem/templates/research-project/PITFALLS.md +200 -0
- package/mindsystem/templates/research-project/STACK.md +120 -0
- package/mindsystem/templates/research-project/SUMMARY.md +170 -0
- package/mindsystem/templates/research-subagent-prompt.md +92 -0
- package/mindsystem/templates/research.md +529 -0
- package/mindsystem/templates/roadmap.md +214 -0
- package/mindsystem/templates/state.md +224 -0
- package/mindsystem/templates/summary.md +269 -0
- package/mindsystem/templates/user-setup.md +323 -0
- package/mindsystem/templates/verification-report.md +322 -0
- package/mindsystem/workflows/complete-milestone.md +759 -0
- package/mindsystem/workflows/create-milestone.md +203 -0
- package/mindsystem/workflows/debug.md +14 -0
- package/mindsystem/workflows/define-requirements.md +330 -0
- package/mindsystem/workflows/diagnose-issues.md +241 -0
- package/mindsystem/workflows/discovery-phase.md +293 -0
- package/mindsystem/workflows/discuss-milestone.md +310 -0
- package/mindsystem/workflows/discuss-phase.md +237 -0
- package/mindsystem/workflows/do-work.md +359 -0
- package/mindsystem/workflows/execute-phase.md +644 -0
- package/mindsystem/workflows/execute-plan.md +1828 -0
- package/mindsystem/workflows/generate-mocks.md +187 -0
- package/mindsystem/workflows/list-phase-assumptions.md +178 -0
- package/mindsystem/workflows/map-codebase.md +289 -0
- package/mindsystem/workflows/plan-phase.md +876 -0
- package/mindsystem/workflows/research-phase.md +17 -0
- package/mindsystem/workflows/research-project.md +23 -0
- package/mindsystem/workflows/resume-project.md +311 -0
- package/mindsystem/workflows/transition.md +564 -0
- package/mindsystem/workflows/verify-phase.md +629 -0
- package/mindsystem/workflows/verify-work.md +823 -0
- package/package.json +32 -0
- package/scripts/generate-phase-patch.sh +169 -0
- package/scripts/ms-lookup/README.md +112 -0
- package/scripts/ms-lookup/ms_lookup/__init__.py +3 -0
- package/scripts/ms-lookup/ms_lookup/__main__.py +6 -0
- package/scripts/ms-lookup/ms_lookup/backends/__init__.py +6 -0
- package/scripts/ms-lookup/ms_lookup/backends/context7.py +219 -0
- package/scripts/ms-lookup/ms_lookup/backends/perplexity.py +145 -0
- package/scripts/ms-lookup/ms_lookup/cache.py +48 -0
- package/scripts/ms-lookup/ms_lookup/cli.py +219 -0
- package/scripts/ms-lookup/ms_lookup/config.py +23 -0
- package/scripts/ms-lookup/ms_lookup/errors.py +24 -0
- package/scripts/ms-lookup/ms_lookup/output.py +49 -0
- package/scripts/ms-lookup/ms_lookup/tokens.py +56 -0
- package/scripts/ms-lookup/pyproject.toml +17 -0
- package/scripts/ms-lookup/uv.lock +207 -0
- package/scripts/ms-lookup-wrapper.sh +21 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# Goal-Backward Planning
|
|
2
|
+
|
|
3
|
+
How to derive requirements by working backwards from the goal, not forwards from tasks.
|
|
4
|
+
|
|
5
|
+
<core_principle>
|
|
6
|
+
**Forward planning asks:** "What should we build?"
|
|
7
|
+
**Goal-backward planning asks:** "What must be TRUE for the goal to be achieved?"
|
|
8
|
+
|
|
9
|
+
Forward planning produces tasks. Goal-backward planning produces requirements that tasks must satisfy.
|
|
10
|
+
</core_principle>
|
|
11
|
+
|
|
12
|
+
<why_this_matters>
|
|
13
|
+
Forward planning fails silently. A task like "create chat component" can be marked complete when the component is a placeholder. The task was done—a component was created—but the goal "working chat interface" was not achieved.
|
|
14
|
+
|
|
15
|
+
Goal-backward planning starts from "user can chat" and works backwards:
|
|
16
|
+
- What must be TRUE for a user to chat?
|
|
17
|
+
- What must EXIST for those truths to hold?
|
|
18
|
+
- What must be WIRED for those artifacts to function?
|
|
19
|
+
|
|
20
|
+
This produces must-haves that are verifiable. Either a user CAN chat, or they can't. No ambiguity.
|
|
21
|
+
</why_this_matters>
|
|
22
|
+
|
|
23
|
+
<the_process>
|
|
24
|
+
|
|
25
|
+
## Step 1: State the Goal
|
|
26
|
+
|
|
27
|
+
Take the phase goal from ROADMAP.md. This is the outcome, not the work.
|
|
28
|
+
|
|
29
|
+
**Examples:**
|
|
30
|
+
- "Working chat interface" (not "build chat components")
|
|
31
|
+
- "Users can authenticate" (not "implement auth system")
|
|
32
|
+
- "Products display with prices" (not "create product pages")
|
|
33
|
+
|
|
34
|
+
If the roadmap goal is task-shaped ("implement X"), reframe it as outcome-shaped ("X works").
|
|
35
|
+
|
|
36
|
+
## Step 2: Derive Observable Truths
|
|
37
|
+
|
|
38
|
+
Ask: **"What must be TRUE for this goal to be achieved?"**
|
|
39
|
+
|
|
40
|
+
List 3-7 truths from the USER's perspective. These are observable behaviors, not implementation details.
|
|
41
|
+
|
|
42
|
+
**For "working chat interface":**
|
|
43
|
+
- User can see existing messages
|
|
44
|
+
- User can type a new message
|
|
45
|
+
- User can send the message
|
|
46
|
+
- Sent message appears in the list
|
|
47
|
+
- Messages persist across page refresh
|
|
48
|
+
|
|
49
|
+
**For "users can authenticate":**
|
|
50
|
+
- User can reach login page
|
|
51
|
+
- User can enter credentials
|
|
52
|
+
- Valid credentials grant access
|
|
53
|
+
- Invalid credentials show error
|
|
54
|
+
- Session persists across refresh
|
|
55
|
+
- User can log out
|
|
56
|
+
|
|
57
|
+
**Test:** Each truth should be verifiable by a human using the application. If you can't test it by clicking around, it's not observable.
|
|
58
|
+
|
|
59
|
+
## Step 3: Derive Required Artifacts
|
|
60
|
+
|
|
61
|
+
For each truth, ask: **"What must EXIST for this to be true?"**
|
|
62
|
+
|
|
63
|
+
Map truths to concrete artifacts (files, routes, schemas, components).
|
|
64
|
+
|
|
65
|
+
**"User can see existing messages" requires:**
|
|
66
|
+
- Message list component (renders Message[])
|
|
67
|
+
- Messages state (loaded from somewhere)
|
|
68
|
+
- API route or data source (provides messages)
|
|
69
|
+
- Message type definition (shapes the data)
|
|
70
|
+
|
|
71
|
+
**"Valid credentials grant access" requires:**
|
|
72
|
+
- Login form component (captures credentials)
|
|
73
|
+
- Auth API route (validates credentials)
|
|
74
|
+
- Session/token mechanism (persists auth state)
|
|
75
|
+
- User record in database (to validate against)
|
|
76
|
+
|
|
77
|
+
**Test:** Each artifact should be a specific file or database object. If you can't point to where it lives, it's too abstract.
|
|
78
|
+
|
|
79
|
+
## Step 4: Derive Required Wiring
|
|
80
|
+
|
|
81
|
+
For each artifact, ask: **"What must be CONNECTED for this artifact to function?"**
|
|
82
|
+
|
|
83
|
+
Wiring is where most failures hide. The pieces exist but don't talk to each other.
|
|
84
|
+
|
|
85
|
+
**Message list component wiring:**
|
|
86
|
+
- Imports Message type (not using `any`)
|
|
87
|
+
- Receives messages prop or fetches from API
|
|
88
|
+
- Maps over messages to render (not hardcoded)
|
|
89
|
+
- Handles empty state (not just crashes)
|
|
90
|
+
|
|
91
|
+
**Auth API route wiring:**
|
|
92
|
+
- Imports database client
|
|
93
|
+
- Queries users table (not placeholder)
|
|
94
|
+
- Compares password hash (not plaintext)
|
|
95
|
+
- Returns session token (not empty response)
|
|
96
|
+
|
|
97
|
+
**Test:** Wiring is verified by tracing data flow. Does A actually call B? Does B actually return to A? Does A actually use what B returned?
|
|
98
|
+
|
|
99
|
+
## Step 5: Identify Key Links
|
|
100
|
+
|
|
101
|
+
Ask: **"Where is this most likely to break?"**
|
|
102
|
+
|
|
103
|
+
Key links are the critical connections that, if missing, cause cascading failures.
|
|
104
|
+
|
|
105
|
+
**For chat interface:**
|
|
106
|
+
- Input onSubmit → API call (if broken: typing works but sending doesn't)
|
|
107
|
+
- API save → database (if broken: appears to send but doesn't persist)
|
|
108
|
+
- Component → real data (if broken: shows placeholder, not messages)
|
|
109
|
+
|
|
110
|
+
**For authentication:**
|
|
111
|
+
- Form submit → API (if broken: form works but auth doesn't)
|
|
112
|
+
- API → database query (if broken: accepts any password)
|
|
113
|
+
- Session → protected routes (if broken: logged in but can't access anything)
|
|
114
|
+
|
|
115
|
+
Key links get extra verification attention. These are where stubs and placeholders hide.
|
|
116
|
+
|
|
117
|
+
</the_process>
|
|
118
|
+
|
|
119
|
+
<output_format>
|
|
120
|
+
The derive_must_haves step produces a structured list for PLAN.md frontmatter:
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
must_haves:
|
|
124
|
+
truths:
|
|
125
|
+
- "User can see existing messages"
|
|
126
|
+
- "User can send a message"
|
|
127
|
+
- "Messages persist across refresh"
|
|
128
|
+
artifacts:
|
|
129
|
+
- path: "src/components/Chat.tsx"
|
|
130
|
+
provides: "Message list rendering"
|
|
131
|
+
- path: "src/app/api/chat/route.ts"
|
|
132
|
+
provides: "Message CRUD operations"
|
|
133
|
+
- path: "prisma/schema.prisma"
|
|
134
|
+
provides: "Message model"
|
|
135
|
+
key_links:
|
|
136
|
+
- from: "Chat.tsx"
|
|
137
|
+
to: "api/chat"
|
|
138
|
+
via: "fetch in useEffect"
|
|
139
|
+
- from: "api/chat POST"
|
|
140
|
+
to: "database"
|
|
141
|
+
via: "prisma.message.create"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
This structure is machine-readable for verification after execution.
|
|
145
|
+
</output_format>
|
|
146
|
+
|
|
147
|
+
<examples>
|
|
148
|
+
|
|
149
|
+
## Example 1: E-commerce Product Page
|
|
150
|
+
|
|
151
|
+
**Goal:** "Products display with prices and add-to-cart"
|
|
152
|
+
|
|
153
|
+
**Truths:**
|
|
154
|
+
- User can see product image
|
|
155
|
+
- User can see product name and description
|
|
156
|
+
- User can see product price
|
|
157
|
+
- User can click "Add to Cart"
|
|
158
|
+
- Cart updates when product added
|
|
159
|
+
|
|
160
|
+
**Artifacts:**
|
|
161
|
+
- `src/components/ProductCard.tsx` - displays product info
|
|
162
|
+
- `src/components/AddToCart.tsx` - button with cart logic
|
|
163
|
+
- `src/app/products/[id]/page.tsx` - product detail page
|
|
164
|
+
- `src/hooks/useCart.ts` - cart state management
|
|
165
|
+
- `prisma/schema.prisma` - Product model with price field
|
|
166
|
+
|
|
167
|
+
**Key Links:**
|
|
168
|
+
- ProductCard receives product data (not hardcoded)
|
|
169
|
+
- AddToCart calls cart hook (not just console.log)
|
|
170
|
+
- useCart persists to localStorage or API (not just memory)
|
|
171
|
+
- Price displays from product.price (not placeholder "$XX.XX")
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Example 2: User Settings Page
|
|
176
|
+
|
|
177
|
+
**Goal:** "Users can update their profile settings"
|
|
178
|
+
|
|
179
|
+
**Truths:**
|
|
180
|
+
- User can see current settings values
|
|
181
|
+
- User can edit each setting field
|
|
182
|
+
- User can save changes
|
|
183
|
+
- Saved changes persist
|
|
184
|
+
- User sees confirmation of save
|
|
185
|
+
|
|
186
|
+
**Artifacts:**
|
|
187
|
+
- `src/app/settings/page.tsx` - settings page
|
|
188
|
+
- `src/components/SettingsForm.tsx` - form with fields
|
|
189
|
+
- `src/app/api/settings/route.ts` - GET and PUT endpoints
|
|
190
|
+
- `prisma/schema.prisma` - User model with settings fields
|
|
191
|
+
|
|
192
|
+
**Key Links:**
|
|
193
|
+
- Form loads current values on mount (not empty defaults)
|
|
194
|
+
- Submit calls API with form data (not console.log)
|
|
195
|
+
- API updates database (not just returns success)
|
|
196
|
+
- Success triggers UI feedback (not silent)
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Example 3: Real-time Notifications
|
|
201
|
+
|
|
202
|
+
**Goal:** "Users receive notifications in real-time"
|
|
203
|
+
|
|
204
|
+
**Truths:**
|
|
205
|
+
- User sees notification badge/indicator
|
|
206
|
+
- New notifications appear without refresh
|
|
207
|
+
- User can view notification list
|
|
208
|
+
- User can mark notifications as read
|
|
209
|
+
- Read state persists
|
|
210
|
+
|
|
211
|
+
**Artifacts:**
|
|
212
|
+
- `src/components/NotificationBell.tsx` - badge/indicator
|
|
213
|
+
- `src/components/NotificationList.tsx` - dropdown/panel
|
|
214
|
+
- `src/app/api/notifications/route.ts` - CRUD endpoints
|
|
215
|
+
- `src/hooks/useNotifications.ts` - real-time subscription
|
|
216
|
+
- `prisma/schema.prisma` - Notification model
|
|
217
|
+
|
|
218
|
+
**Key Links:**
|
|
219
|
+
- useNotifications connects to WebSocket/SSE (not polling placeholder)
|
|
220
|
+
- NotificationBell shows actual unread count (not hardcoded)
|
|
221
|
+
- Mark-as-read calls API (not just local state)
|
|
222
|
+
- API broadcasts to other clients (if multi-device)
|
|
223
|
+
|
|
224
|
+
</examples>
|
|
225
|
+
|
|
226
|
+
<common_failures>
|
|
227
|
+
|
|
228
|
+
## Failure: Truths Too Vague
|
|
229
|
+
|
|
230
|
+
**Bad:** "User can use chat"
|
|
231
|
+
**Good:** "User can see messages", "User can send message", "Messages persist"
|
|
232
|
+
|
|
233
|
+
Vague truths can't be verified. Break them into specific, observable behaviors.
|
|
234
|
+
|
|
235
|
+
## Failure: Artifacts Too Abstract
|
|
236
|
+
|
|
237
|
+
**Bad:** "Chat system", "Auth module"
|
|
238
|
+
**Good:** "src/components/Chat.tsx", "src/app/api/auth/login/route.ts"
|
|
239
|
+
|
|
240
|
+
Abstract artifacts can't be checked. Point to specific files.
|
|
241
|
+
|
|
242
|
+
## Failure: Missing Wiring
|
|
243
|
+
|
|
244
|
+
**Bad:** Listing components without how they connect
|
|
245
|
+
**Good:** "Chat.tsx fetches from /api/chat via useEffect on mount"
|
|
246
|
+
|
|
247
|
+
Artifacts existing isn't enough. The connections between them are where stubs hide.
|
|
248
|
+
|
|
249
|
+
## Failure: Skipping Key Links
|
|
250
|
+
|
|
251
|
+
**Bad:** Assuming "if files exist, it works"
|
|
252
|
+
**Good:** Identifying the 2-3 critical connections that make-or-break the goal
|
|
253
|
+
|
|
254
|
+
Key links are verification priorities. Without them, you check everything equally (inefficient) or check nothing deeply (ineffective).
|
|
255
|
+
|
|
256
|
+
</common_failures>
|
|
257
|
+
|
|
258
|
+
<integration_with_gsd>
|
|
259
|
+
|
|
260
|
+
## In plan-phase.md
|
|
261
|
+
|
|
262
|
+
The `derive_must_haves` step runs after gathering context, before breaking into tasks.
|
|
263
|
+
|
|
264
|
+
Output: `must_haves` structure written to PLAN.md frontmatter.
|
|
265
|
+
|
|
266
|
+
Tasks are then designed to CREATE the artifacts and ESTABLISH the wiring.
|
|
267
|
+
|
|
268
|
+
## In execute-phase.md
|
|
269
|
+
|
|
270
|
+
The `verify_phase_goal` step runs after all plans execute, before updating roadmap.
|
|
271
|
+
|
|
272
|
+
Input: `must_haves` from PLAN.md frontmatter (or derived from goal if missing).
|
|
273
|
+
|
|
274
|
+
Process: Check each truth against codebase, verify artifacts exist and aren't stubs, trace key links.
|
|
275
|
+
|
|
276
|
+
Output: VERIFICATION.md with pass/fail per item, fix recommendations if gaps found.
|
|
277
|
+
|
|
278
|
+
## The Loop
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
derive_must_haves → tasks → execute → verify → [gaps?] → fix plans → execute → verify → pass
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Must-haves are derived once, verified as many times as needed until all pass.
|
|
285
|
+
|
|
286
|
+
</integration_with_gsd>
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
<overview>
|
|
2
|
+
Mock patterns for manual UAT testing. Mocks are temporary scaffolding to reach testable UI states. They exist only as uncommitted changes — never in commit history.
|
|
3
|
+
</overview>
|
|
4
|
+
|
|
5
|
+
<philosophy>
|
|
6
|
+
**Mocks enable testing states you can't easily reach.**
|
|
7
|
+
|
|
8
|
+
Without mocks, testing "error message display" requires actually triggering server errors. Testing "premium user badge" requires a premium account. Testing "empty list placeholder" requires deleting all data.
|
|
9
|
+
|
|
10
|
+
**With mocks:** Set a flag, hot reload, test the UI state.
|
|
11
|
+
|
|
12
|
+
**Core principles:**
|
|
13
|
+
1. **Temporary** — Mocks are stashed/discarded, never committed
|
|
14
|
+
2. **Minimal** — One override file, minimal production hooks
|
|
15
|
+
3. **Explicit** — Clear flags, clear toggle instructions
|
|
16
|
+
4. **Removable** — Delete file + remove imports = clean
|
|
17
|
+
</philosophy>
|
|
18
|
+
|
|
19
|
+
<git_stash_lifecycle>
|
|
20
|
+
|
|
21
|
+
**Why stash?**
|
|
22
|
+
|
|
23
|
+
Fixes must be clean commits (no mock code). But after fixing, we need mocks back to re-test. Git stash enables this:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
27
|
+
│ Phase 1: Setup │
|
|
28
|
+
├─────────────────────────────────────────────────────────────┤
|
|
29
|
+
│ 1. git stash push -m "pre-verify-work" (if dirty) │
|
|
30
|
+
│ 2. Mock Generator creates mock code (uncommitted) │
|
|
31
|
+
│ 3. User confirms mocks look correct │
|
|
32
|
+
└─────────────────────────────────────────────────────────────┘
|
|
33
|
+
│
|
|
34
|
+
▼
|
|
35
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
36
|
+
│ Phase 2: Test-Fix Loop (per issue) │
|
|
37
|
+
├─────────────────────────────────────────────────────────────┤
|
|
38
|
+
│ 4. User tests on device with mocks active │
|
|
39
|
+
│ 5. User reports issue │
|
|
40
|
+
│ 6. git stash push -m "mocks-batch-N" ← Stash mocks │
|
|
41
|
+
│ 7. Fixer investigates and commits fix ← Clean commit │
|
|
42
|
+
│ 8. git stash pop ← Restore mocks │
|
|
43
|
+
│ 9. User re-tests specific item │
|
|
44
|
+
│ 10. Repeat until fixed or skip │
|
|
45
|
+
└─────────────────────────────────────────────────────────────┘
|
|
46
|
+
│
|
|
47
|
+
▼
|
|
48
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
49
|
+
│ Phase 3: Cleanup │
|
|
50
|
+
├─────────────────────────────────────────────────────────────┤
|
|
51
|
+
│ 11. git stash drop ← Discard mocks │
|
|
52
|
+
│ 12. Generate UAT fixes patch │
|
|
53
|
+
│ 13. git stash pop (if pre-existing) ← Restore user work │
|
|
54
|
+
└─────────────────────────────────────────────────────────────┘
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Stash naming convention:**
|
|
58
|
+
- `pre-verify-work` — User's original uncommitted work
|
|
59
|
+
- `mocks-batch-N` — Current mock state for batch N
|
|
60
|
+
|
|
61
|
+
</git_stash_lifecycle>
|
|
62
|
+
|
|
63
|
+
<conflict_resolution>
|
|
64
|
+
|
|
65
|
+
**When git stash pop conflicts:**
|
|
66
|
+
|
|
67
|
+
This happens when a fix modified the same file as a mock. Resolution:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Conflict means fix touched mock code — take the fix version
|
|
71
|
+
git checkout --theirs <conflicted-file>
|
|
72
|
+
git add <conflicted-file>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Why take fix version?**
|
|
76
|
+
- The fix is committed, intentional work
|
|
77
|
+
- The mock for that file is likely no longer needed (fix replaced relevant code)
|
|
78
|
+
- Regenerating mock for that specific file is easy if still needed
|
|
79
|
+
|
|
80
|
+
**This is rare.** Mocks typically live in data layer, fixes often in UI layer.
|
|
81
|
+
|
|
82
|
+
</conflict_resolution>
|
|
83
|
+
|
|
84
|
+
<flutter_example>
|
|
85
|
+
|
|
86
|
+
**Override file: `lib/test_overrides.dart`**
|
|
87
|
+
|
|
88
|
+
```dart
|
|
89
|
+
// Test Overrides - DELETE THIS FILE BEFORE COMMITTING
|
|
90
|
+
// Used for manual UAT testing only
|
|
91
|
+
|
|
92
|
+
class TestOverrides {
|
|
93
|
+
// === STATE FLAGS ===
|
|
94
|
+
static bool forcePremiumUser = false;
|
|
95
|
+
static bool forceErrorState = false;
|
|
96
|
+
static bool forceEmptyResponse = false;
|
|
97
|
+
static bool forceLoadingState = false;
|
|
98
|
+
|
|
99
|
+
// === MOCK DATA ===
|
|
100
|
+
static String mockErrorMessage = 'Simulated error for testing';
|
|
101
|
+
static Duration mockLoadingDelay = const Duration(seconds: 3);
|
|
102
|
+
|
|
103
|
+
static Map<String, dynamic> mockPremiumUser = {
|
|
104
|
+
'id': 'test-user-001',
|
|
105
|
+
'name': 'Test Premium User',
|
|
106
|
+
'isPremium': true,
|
|
107
|
+
'subscriptionTier': 'gold',
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// === RESET ===
|
|
111
|
+
static void reset() {
|
|
112
|
+
forcePremiumUser = false;
|
|
113
|
+
forceErrorState = false;
|
|
114
|
+
forceEmptyResponse = false;
|
|
115
|
+
forceLoadingState = false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Production hook: `lib/services/user_service.dart`**
|
|
121
|
+
|
|
122
|
+
```dart
|
|
123
|
+
import '../test_overrides.dart';
|
|
124
|
+
|
|
125
|
+
class UserService {
|
|
126
|
+
Future<User> getCurrentUser() async {
|
|
127
|
+
// TEST OVERRIDE - Remove before commit
|
|
128
|
+
if (TestOverrides.forcePremiumUser) {
|
|
129
|
+
return User.fromJson(TestOverrides.mockPremiumUser);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Real implementation
|
|
133
|
+
final response = await _api.get('/user/me');
|
|
134
|
+
return User.fromJson(response.data);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
Future<List<Item>> getItems() async {
|
|
138
|
+
// TEST OVERRIDE - Remove before commit
|
|
139
|
+
if (TestOverrides.forceEmptyResponse) {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
if (TestOverrides.forceErrorState) {
|
|
143
|
+
throw Exception(TestOverrides.mockErrorMessage);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Real implementation
|
|
147
|
+
final response = await _api.get('/items');
|
|
148
|
+
return (response.data as List).map((j) => Item.fromJson(j)).toList();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Toggle instructions:**
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
To enable Premium User state:
|
|
157
|
+
1. Open lib/test_overrides.dart
|
|
158
|
+
2. Set TestOverrides.forcePremiumUser = true
|
|
159
|
+
3. Hot reload (r in terminal)
|
|
160
|
+
4. Verify: User profile shows "Premium" badge
|
|
161
|
+
|
|
162
|
+
To enable Error State:
|
|
163
|
+
1. Open lib/test_overrides.dart
|
|
164
|
+
2. Set TestOverrides.forceErrorState = true
|
|
165
|
+
3. Hot reload (r in terminal)
|
|
166
|
+
4. Verify: Error message appears on relevant screens
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
</flutter_example>
|
|
170
|
+
|
|
171
|
+
<react_example>
|
|
172
|
+
|
|
173
|
+
**Override file: `src/testOverrides.ts`**
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// Test Overrides - DELETE THIS FILE BEFORE COMMITTING
|
|
177
|
+
// Used for manual UAT testing only
|
|
178
|
+
|
|
179
|
+
export const testOverrides = {
|
|
180
|
+
// === STATE FLAGS ===
|
|
181
|
+
forcePremiumUser: false,
|
|
182
|
+
forceErrorState: false,
|
|
183
|
+
forceEmptyResponse: false,
|
|
184
|
+
forceLoadingState: false,
|
|
185
|
+
|
|
186
|
+
// === MOCK DATA ===
|
|
187
|
+
mockErrorMessage: 'Simulated error for testing',
|
|
188
|
+
mockLoadingDelayMs: 3000,
|
|
189
|
+
|
|
190
|
+
mockPremiumUser: {
|
|
191
|
+
id: 'test-user-001',
|
|
192
|
+
name: 'Test Premium User',
|
|
193
|
+
isPremium: true,
|
|
194
|
+
subscriptionTier: 'gold',
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
// === RESET ===
|
|
198
|
+
reset() {
|
|
199
|
+
this.forcePremiumUser = false;
|
|
200
|
+
this.forceErrorState = false;
|
|
201
|
+
this.forceEmptyResponse = false;
|
|
202
|
+
this.forceLoadingState = false;
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**Production hook: `src/services/userService.ts`**
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import { testOverrides } from '../testOverrides';
|
|
211
|
+
|
|
212
|
+
export async function getCurrentUser(): Promise<User> {
|
|
213
|
+
// TEST OVERRIDE - Remove before commit
|
|
214
|
+
if (testOverrides.forcePremiumUser) {
|
|
215
|
+
return testOverrides.mockPremiumUser as User;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Real implementation
|
|
219
|
+
const response = await fetch('/api/user/me');
|
|
220
|
+
return response.json();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export async function getItems(): Promise<Item[]> {
|
|
224
|
+
// TEST OVERRIDE - Remove before commit
|
|
225
|
+
if (testOverrides.forceEmptyResponse) {
|
|
226
|
+
return [];
|
|
227
|
+
}
|
|
228
|
+
if (testOverrides.forceErrorState) {
|
|
229
|
+
throw new Error(testOverrides.mockErrorMessage);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Real implementation
|
|
233
|
+
const response = await fetch('/api/items');
|
|
234
|
+
return response.json();
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Toggle instructions:**
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
To enable Premium User state:
|
|
242
|
+
1. Open src/testOverrides.ts
|
|
243
|
+
2. Set forcePremiumUser: true
|
|
244
|
+
3. Save file (auto hot reload in dev mode)
|
|
245
|
+
4. Verify: User profile shows "Premium" badge
|
|
246
|
+
|
|
247
|
+
To enable Error State:
|
|
248
|
+
1. Open src/testOverrides.ts
|
|
249
|
+
2. Set forceErrorState: true
|
|
250
|
+
3. Save file (auto hot reload)
|
|
251
|
+
4. Verify: Error message appears on relevant screens
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
</react_example>
|
|
255
|
+
|
|
256
|
+
<best_practices>
|
|
257
|
+
|
|
258
|
+
**Do:**
|
|
259
|
+
- Keep all flags in one file
|
|
260
|
+
- Use descriptive flag names (`forcePremiumUser` not `flag1`)
|
|
261
|
+
- Add comments marking test-only code
|
|
262
|
+
- Provide reset function
|
|
263
|
+
- Document toggle instructions clearly
|
|
264
|
+
|
|
265
|
+
**Don't:**
|
|
266
|
+
- Create complex mock infrastructure
|
|
267
|
+
- Add mocks in UI components (use service layer)
|
|
268
|
+
- Commit mock code (ever)
|
|
269
|
+
- Create multiple override files
|
|
270
|
+
- Add conditional compilation / build flags
|
|
271
|
+
|
|
272
|
+
**Signs you're over-engineering:**
|
|
273
|
+
- More than one override file
|
|
274
|
+
- Mock code in more than 3 production files
|
|
275
|
+
- Complex mock data generators
|
|
276
|
+
- Mocking at multiple layers simultaneously
|
|
277
|
+
|
|
278
|
+
</best_practices>
|
|
279
|
+
|
|
280
|
+
<cleanup>
|
|
281
|
+
|
|
282
|
+
**After UAT complete:**
|
|
283
|
+
|
|
284
|
+
1. `git stash drop` — Removes mock stash permanently
|
|
285
|
+
2. Delete override file if still present
|
|
286
|
+
3. Remove any imports/hooks still in production code
|
|
287
|
+
|
|
288
|
+
**Verification:**
|
|
289
|
+
```bash
|
|
290
|
+
git status # Should show no mock-related files
|
|
291
|
+
grep -r "testOverrides" src/ # Should find nothing (or only the override file itself)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
</cleanup>
|