mindsystem-cc 3.22.0 → 3.22.1
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/agents/ms-debugger.md +196 -880
- package/commands/ms/debug.md +24 -24
- package/mindsystem/workflows/diagnose-issues.md +0 -1
- package/package.json +1 -1
- package/skills/senior-review/AGENTS.md +531 -0
- package/skills/senior-review/SKILL.md +216 -0
- package/skills/senior-review/principles/dependencies-api-boundary-design.md +32 -0
- package/skills/senior-review/principles/dependencies-data-not-flags.md +32 -0
- package/skills/senior-review/principles/dependencies-temporal-coupling.md +32 -0
- package/skills/senior-review/principles/pragmatism-consistent-error-handling.md +32 -0
- package/skills/senior-review/principles/pragmatism-speculative-generality.md +32 -0
- package/skills/senior-review/principles/state-invalid-states.md +33 -0
- package/skills/senior-review/principles/state-single-source-of-truth.md +32 -0
- package/skills/senior-review/principles/state-type-hierarchies.md +32 -0
- package/skills/senior-review/principles/structure-composition-over-config.md +32 -0
- package/skills/senior-review/principles/structure-feature-isolation.md +32 -0
- package/skills/senior-review/principles/structure-module-cohesion.md +32 -0
- package/mindsystem/references/debugging/debugging-mindset.md +0 -11
- package/mindsystem/references/debugging/hypothesis-testing.md +0 -11
- package/mindsystem/references/debugging/investigation-techniques.md +0 -11
- package/mindsystem/references/debugging/verification-patterns.md +0 -11
- package/mindsystem/references/debugging/when-to-research.md +0 -11
- package/mindsystem/references/git-integration.md +0 -254
- package/mindsystem/references/verification-patterns.md +0 -558
- package/mindsystem/workflows/debug.md +0 -14
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: senior-review
|
|
3
|
+
description: Review code for architectural and structural design issues across any tech stack. Use when reviewing PRs, auditing component design, evaluating state management, or identifying problems that make code hard to evolve. Optimized for web/fullstack (Next.js, React, Node) but applicable to any language.
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
author: Roland Tolnay
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
date: February 2026
|
|
9
|
+
abstract: Tech-agnostic code review framework focused on structural improvements that typical reviews miss. Uses 3 core lenses (State Modeling, Responsibility Boundaries, Abstraction Timing) backed by 11 detailed principles organized into 4 categories. Each principle includes detection signals and reasoning — no code examples, as the model already knows language patterns.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Senior Review
|
|
13
|
+
|
|
14
|
+
Senior engineering principles for code across any tech stack. Apply when reviewing, refactoring, or writing code to identify structural improvements that make code evolvable, not just working.
|
|
15
|
+
|
|
16
|
+
## When to Apply
|
|
17
|
+
|
|
18
|
+
Reference these guidelines when:
|
|
19
|
+
- Reviewing code changes (commits, PRs, patches)
|
|
20
|
+
- Refactoring existing code
|
|
21
|
+
- Writing new features or components
|
|
22
|
+
- Identifying why code feels hard to change
|
|
23
|
+
- Planning structural improvements
|
|
24
|
+
|
|
25
|
+
## Senior Mindset
|
|
26
|
+
|
|
27
|
+
Junior and mid-level engineers ask: **"Does this code work?"**
|
|
28
|
+
Senior engineers ask: **"How will this code change? What happens when requirements shift?"**
|
|
29
|
+
|
|
30
|
+
This distinction drives everything. Code that "works" today becomes a liability when:
|
|
31
|
+
- A new state is added and 5 files need coordinated updates
|
|
32
|
+
- A feature toggle requires touching code scattered across the codebase
|
|
33
|
+
- A bug fix in one place breaks assumptions elsewhere
|
|
34
|
+
|
|
35
|
+
Focus on **structural issues that compound over time** - the kind that turn "add a simple feature" into "refactor half the codebase first."
|
|
36
|
+
|
|
37
|
+
Do NOT look for:
|
|
38
|
+
- Style preferences or formatting
|
|
39
|
+
- Minor naming improvements
|
|
40
|
+
- "Nice to have" abstractions
|
|
41
|
+
- Issues already covered by linters/analyzers
|
|
42
|
+
|
|
43
|
+
## Core Lenses
|
|
44
|
+
|
|
45
|
+
Apply these three lenses to every review. They catch 80% of structural issues.
|
|
46
|
+
|
|
47
|
+
### Lens 1: State Modeling
|
|
48
|
+
|
|
49
|
+
**Question:** Can this code represent invalid states?
|
|
50
|
+
|
|
51
|
+
Look for:
|
|
52
|
+
- Multiple boolean flags (2^n possible states, many invalid)
|
|
53
|
+
- Primitive obsession (stringly-typed status, magic numbers)
|
|
54
|
+
- Same decision logic repeated in multiple places
|
|
55
|
+
|
|
56
|
+
**Senior pattern:** Discriminated unions/enums where each variant is a valid state. Factory functions that encapsulate decision logic. Compiler-enforced exhaustive handling.
|
|
57
|
+
|
|
58
|
+
Related principles: `state-invalid-states.md`, `state-type-hierarchies.md`, `state-single-source-of-truth.md`
|
|
59
|
+
|
|
60
|
+
### Lens 2: Responsibility Boundaries
|
|
61
|
+
|
|
62
|
+
**Question:** If I remove/modify feature X, how many files change?
|
|
63
|
+
|
|
64
|
+
Look for:
|
|
65
|
+
- Optional feature logic scattered throughout a parent component
|
|
66
|
+
- Components/modules with 6+ parameters (doing too much)
|
|
67
|
+
- Deep callback chains passing flags through layers
|
|
68
|
+
|
|
69
|
+
**Senior pattern:** Wrapper/decorator components for optional features. Typed data objects instead of flag parades. Each module has one job.
|
|
70
|
+
|
|
71
|
+
Related principles: `structure-feature-isolation.md`, `structure-composition-over-config.md`, `structure-module-cohesion.md`
|
|
72
|
+
|
|
73
|
+
### Lens 3: Abstraction Timing
|
|
74
|
+
|
|
75
|
+
**Question:** Is this abstraction earned or speculative?
|
|
76
|
+
|
|
77
|
+
Look for:
|
|
78
|
+
- Interfaces with only one implementation
|
|
79
|
+
- Factories that create only one type
|
|
80
|
+
- "Flexible" config that's never varied
|
|
81
|
+
- BUT ALSO: Duplicated code that should be unified
|
|
82
|
+
|
|
83
|
+
**Senior pattern:** Abstract when you have 2-3 concrete cases, not before. Extract when duplication causes bugs or drift, not for aesthetics.
|
|
84
|
+
|
|
85
|
+
Related principles: `pragmatism-speculative-generality.md`, `dependencies-data-not-flags.md`
|
|
86
|
+
|
|
87
|
+
## Principle Categories
|
|
88
|
+
|
|
89
|
+
| Category | Principles | Focus |
|
|
90
|
+
|----------|------------|-------|
|
|
91
|
+
| State & Types | 1, 2, 3 | Invalid states, type hierarchies, single source of truth |
|
|
92
|
+
| Structure | 4, 5, 6 | Feature isolation, composition, module cohesion |
|
|
93
|
+
| Dependencies | 7, 8, 9 | Data flow, temporal coupling, API boundary design |
|
|
94
|
+
| Pragmatism | 10, 11 | Avoiding over-engineering, consistent error handling |
|
|
95
|
+
|
|
96
|
+
## Quick Reference
|
|
97
|
+
|
|
98
|
+
### State & Type Safety
|
|
99
|
+
- **invalid-states** - Replace boolean flag combinations with discriminated unions/enums
|
|
100
|
+
- **type-hierarchies** - Use factories to encapsulate decision logic in the type system
|
|
101
|
+
- **single-source-of-truth** - One owner per state, derive the rest
|
|
102
|
+
|
|
103
|
+
### Structure & Composition
|
|
104
|
+
- **feature-isolation** - Isolate optional feature logic into wrapper/decorator components
|
|
105
|
+
- **composition-over-config** - Small focused components over god components with many flags
|
|
106
|
+
- **module-cohesion** - Group related logic into cohesive module boundaries
|
|
107
|
+
|
|
108
|
+
### Dependencies & Flow
|
|
109
|
+
- **data-not-flags** - Pass typed data objects through layers, not boolean flag parades
|
|
110
|
+
- **temporal-coupling** - Enforce operation sequences via types, not documentation
|
|
111
|
+
- **api-boundary-design** - Typed request/response contracts with validation at boundaries
|
|
112
|
+
|
|
113
|
+
### Pragmatism
|
|
114
|
+
- **speculative-generality** - Don't abstract until 2-3 concrete cases exist
|
|
115
|
+
- **consistent-error-handling** - One strategy applied everywhere, not ad-hoc try/catch
|
|
116
|
+
|
|
117
|
+
## How to Use
|
|
118
|
+
|
|
119
|
+
Read individual principle files for detailed explanations:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
principles/state-invalid-states.md
|
|
123
|
+
principles/structure-feature-isolation.md
|
|
124
|
+
principles/dependencies-api-boundary-design.md
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Each principle file contains:
|
|
128
|
+
- Brief explanation of what to do instead
|
|
129
|
+
- Detection signals (what to look for)
|
|
130
|
+
- Why it matters (evolution impact)
|
|
131
|
+
- Senior pattern description
|
|
132
|
+
- Detection questions for self-review
|
|
133
|
+
|
|
134
|
+
## Context Gathering
|
|
135
|
+
|
|
136
|
+
When asked to review code, first identify the target:
|
|
137
|
+
|
|
138
|
+
If target is unclear, ask:
|
|
139
|
+
- What code should be reviewed? (specific files, a feature folder, uncommitted changes, a commit, a patch file)
|
|
140
|
+
- Is there a specific concern or area of focus?
|
|
141
|
+
|
|
142
|
+
For the specified target, gather the relevant code:
|
|
143
|
+
- **Commit**: `git show <commit>`
|
|
144
|
+
- **Patch file**: Read the patch file
|
|
145
|
+
- **Uncommitted changes**: `git diff` and `git diff --cached`
|
|
146
|
+
- **Folder/feature**: Read the relevant files in that directory
|
|
147
|
+
- **Specific file**: Read that file and related files it imports/uses
|
|
148
|
+
|
|
149
|
+
## Analysis Process
|
|
150
|
+
|
|
151
|
+
1. **Read thoroughly** - Understand what the code does, not just its structure
|
|
152
|
+
|
|
153
|
+
2. **Apply the three lenses** - For each lens, note specific instances (or note "no issues found")
|
|
154
|
+
|
|
155
|
+
3. **Check for additional patterns** - If you notice issues beyond the core lenses, consult the principle files for precise diagnosis
|
|
156
|
+
|
|
157
|
+
4. **Prioritize by evolution impact**:
|
|
158
|
+
- High: Will cause cascading changes when requirements shift
|
|
159
|
+
- Medium: Creates friction but contained to one area
|
|
160
|
+
- Low: Suboptimal but won't compound
|
|
161
|
+
|
|
162
|
+
5. **Formulate concrete suggestions** - Name specific extractions, describe before/after for the highest-impact change
|
|
163
|
+
|
|
164
|
+
## Output Format
|
|
165
|
+
|
|
166
|
+
```markdown
|
|
167
|
+
## Senior Review: [Target]
|
|
168
|
+
|
|
169
|
+
### Summary
|
|
170
|
+
[1-2 sentences: Overall assessment and the single most important structural opportunity]
|
|
171
|
+
|
|
172
|
+
### Findings
|
|
173
|
+
|
|
174
|
+
#### High Impact: [Issue Name]
|
|
175
|
+
**What I noticed:** [Specific code pattern observed]
|
|
176
|
+
**Why it matters:** [How this will cause problems as code evolves]
|
|
177
|
+
**Suggestion:** [Concrete refactoring - name the types/modules to extract]
|
|
178
|
+
|
|
179
|
+
#### Medium Impact: [Issue Name]
|
|
180
|
+
[Same structure]
|
|
181
|
+
|
|
182
|
+
#### Low Impact: [Issue Name]
|
|
183
|
+
[Same structure]
|
|
184
|
+
|
|
185
|
+
### No Issues Found
|
|
186
|
+
[If a lens revealed no problems, briefly note: "State modeling: No boolean flag combinations or repeated decision logic detected."]
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
**What's your take on these suggestions? Any context I'm missing?**
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
After the markdown output, append a YAML summary block for orchestrator parsing:
|
|
194
|
+
|
|
195
|
+
```yaml
|
|
196
|
+
# review-summary
|
|
197
|
+
findings: [number of findings]
|
|
198
|
+
high_impact: [count]
|
|
199
|
+
medium_impact: [count]
|
|
200
|
+
low_impact: [count]
|
|
201
|
+
top_issue: "[one-line description of highest impact finding]"
|
|
202
|
+
verdict: "clean | minor_issues | needs_refactoring | structural_concerns"
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Success Criteria
|
|
206
|
+
|
|
207
|
+
- At least one finding per applicable lens (or explicit "no issues" statement)
|
|
208
|
+
- Each finding tied to evolution impact, not just "could be better"
|
|
209
|
+
- Suggestions are concrete: specific types/modules named, not vague advice
|
|
210
|
+
- No forced findings - if code is solid, say so
|
|
211
|
+
- User has opportunity to provide context before changes
|
|
212
|
+
- YAML summary block included for orchestrator parsing
|
|
213
|
+
|
|
214
|
+
## Full Compiled Document
|
|
215
|
+
|
|
216
|
+
For the complete guide with all principles expanded: `AGENTS.md`
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: API Boundary Design
|
|
3
|
+
category: dependencies
|
|
4
|
+
impact: HIGH
|
|
5
|
+
impactDescription: Prevents invalid data from propagating
|
|
6
|
+
tags: api-contracts, validation, boundaries, request-response
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## API Boundary Design
|
|
10
|
+
|
|
11
|
+
Define typed request/response contracts with validation at system boundaries. Trust internal code; verify external input.
|
|
12
|
+
|
|
13
|
+
**Detection signals:**
|
|
14
|
+
- API handlers that accept `any` or untyped request bodies
|
|
15
|
+
- Validation logic scattered across business logic instead of at the boundary
|
|
16
|
+
- No shared type between client and server for the same endpoint
|
|
17
|
+
- Error responses that leak internal details (stack traces, database errors)
|
|
18
|
+
- Different endpoints handling the same entity with inconsistent field names
|
|
19
|
+
|
|
20
|
+
**Why it matters:**
|
|
21
|
+
- Invalid data is caught at the boundary before it reaches business logic
|
|
22
|
+
- Internal code operates on validated, typed data — no defensive checks everywhere
|
|
23
|
+
- Client and server stay in sync through shared types or generated contracts
|
|
24
|
+
- Error responses are consistent and safe for consumers
|
|
25
|
+
|
|
26
|
+
**Senior pattern:** Validate and parse at the boundary: incoming data is unknown until validated, then flows as typed objects through internal layers. Define request/response types explicitly (schema validation, codegen, or shared type packages). Internal functions receive validated types and trust them — they don't re-validate. Error responses follow a consistent shape with safe, user-facing messages.
|
|
27
|
+
|
|
28
|
+
**Detection questions:**
|
|
29
|
+
- Do API handlers accept untyped or `any` request bodies?
|
|
30
|
+
- Is validation scattered across business logic instead of concentrated at boundaries?
|
|
31
|
+
- Is there a shared type contract between client and server?
|
|
32
|
+
- Do error responses leak internal details like stack traces?
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Data Objects Over Flag Parades
|
|
3
|
+
category: dependencies
|
|
4
|
+
impact: MEDIUM-HIGH
|
|
5
|
+
impactDescription: Stabilizes APIs between layers
|
|
6
|
+
tags: data-objects, flags, coupling, api-design
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Data Objects Over Flag Parades
|
|
10
|
+
|
|
11
|
+
Pass typed data objects through layers instead of boolean flag parades that couple caller to implementation.
|
|
12
|
+
|
|
13
|
+
**Detection signals:**
|
|
14
|
+
- Functions/components have 4+ boolean or primitive parameters beyond core data
|
|
15
|
+
- Boolean flags being passed through multiple layers unchanged
|
|
16
|
+
- Changing a child's behavior requires changing every intermediate caller's signature
|
|
17
|
+
- Parameters that are only used in some conditions
|
|
18
|
+
- Same group of parameters appears in multiple function signatures
|
|
19
|
+
|
|
20
|
+
**Why it matters:**
|
|
21
|
+
- Consumer's API is stable even as internal requirements change
|
|
22
|
+
- Callers don't need to know the consumer's internal decision logic
|
|
23
|
+
- Data dependencies are explicit in the object's type
|
|
24
|
+
- Easier to test: create data objects directly without reconstructing call chains
|
|
25
|
+
|
|
26
|
+
**Senior pattern:** Group related parameters into a typed data object (interface, type, struct, record). The object carries everything the consumer needs to make its own decisions. The caller constructs the object from available context — if construction is complex, use a factory. The consumer's public API accepts the data object, not individual flags.
|
|
27
|
+
|
|
28
|
+
**Detection questions:**
|
|
29
|
+
- Are there 4+ boolean/primitive parameters being passed alongside core data?
|
|
30
|
+
- Are flags being threaded through multiple layers without being used in intermediate ones?
|
|
31
|
+
- Would changing a child's behavior require updating every caller's signature?
|
|
32
|
+
- Do the same parameter groups appear in multiple function signatures?
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Temporal Coupling
|
|
3
|
+
category: dependencies
|
|
4
|
+
impact: MEDIUM
|
|
5
|
+
impactDescription: Catches misuse at compile time
|
|
6
|
+
tags: builder-pattern, type-state, initialization, sequence
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Temporal Coupling
|
|
10
|
+
|
|
11
|
+
Enforce operation sequences via types, not documentation. Make it impossible to call methods in the wrong order.
|
|
12
|
+
|
|
13
|
+
**Detection signals:**
|
|
14
|
+
- Methods that must be called before others
|
|
15
|
+
- Comments like "must call X first" or "call after Y"
|
|
16
|
+
- Objects can be in an "invalid" state between operations
|
|
17
|
+
- Tests have setup steps that could be forgotten
|
|
18
|
+
- Init/setup methods that must run before the object is usable
|
|
19
|
+
|
|
20
|
+
**Why it matters:**
|
|
21
|
+
- Compiler catches misuse, not runtime errors
|
|
22
|
+
- Self-documenting: types show valid sequences
|
|
23
|
+
- Impossible to forget required steps
|
|
24
|
+
- Easier onboarding: the API guides you through the correct order
|
|
25
|
+
|
|
26
|
+
**Senior pattern:** Use the builder pattern (fluent API that accumulates required state before producing the final object) or the type-state pattern (each step returns a different type that only exposes the next valid operation). For simpler cases, require all necessary data in the constructor so an object is always valid from creation.
|
|
27
|
+
|
|
28
|
+
**Detection questions:**
|
|
29
|
+
- Are there methods that must be called before others?
|
|
30
|
+
- Are there comments like "must call X first" or "call after Y"?
|
|
31
|
+
- Can objects be in an "invalid" state between operations?
|
|
32
|
+
- Do tests have setup steps that could be forgotten?
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Consistent Error Handling
|
|
3
|
+
category: pragmatism
|
|
4
|
+
impact: MEDIUM
|
|
5
|
+
impactDescription: Improves UX and debugging
|
|
6
|
+
tags: error-handling, try-catch, error-boundaries, consistency
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Consistent Error Handling
|
|
10
|
+
|
|
11
|
+
Adopt one error handling strategy and apply it everywhere. Ad-hoc try/catch leads to inconsistent UX and swallowed errors.
|
|
12
|
+
|
|
13
|
+
**Detection signals:**
|
|
14
|
+
- Errors appear differently across screens (toasts vs dialogs vs inline vs nothing)
|
|
15
|
+
- try/catch blocks scattered in component/handler code with different recovery strategies
|
|
16
|
+
- Inconsistent error messaging (raw exceptions shown to users in some places)
|
|
17
|
+
- No standard retry mechanism
|
|
18
|
+
- Some code paths silently swallow errors with empty catch blocks
|
|
19
|
+
|
|
20
|
+
**Why it matters:**
|
|
21
|
+
- Users get a consistent experience when things go wrong
|
|
22
|
+
- Developers follow one pattern — no decision fatigue per error site
|
|
23
|
+
- Error states are explicit and testable, not hidden in catch blocks
|
|
24
|
+
- Debugging is faster: errors flow through a known path
|
|
25
|
+
|
|
26
|
+
**Senior pattern:** Establish a single error handling strategy for the project: errors flow through a known path (Result types, error boundaries, middleware, or global handlers) and surface to users through one consistent mechanism. Individual call sites don't decide how to present errors — they report them, and the strategy handles presentation. Empty catch blocks are banned; if an error is truly ignorable, document why.
|
|
27
|
+
|
|
28
|
+
**Detection questions:**
|
|
29
|
+
- Do errors appear differently across different screens or endpoints?
|
|
30
|
+
- Are try/catch blocks scattered with different recovery strategies?
|
|
31
|
+
- Are there empty catch blocks that silently swallow errors?
|
|
32
|
+
- Is there a standard, documented error handling strategy for the project?
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Speculative Generality
|
|
3
|
+
category: pragmatism
|
|
4
|
+
impact: MEDIUM
|
|
5
|
+
impactDescription: Reduces unnecessary complexity
|
|
6
|
+
tags: abstraction, yagni, over-engineering, interfaces
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Speculative Generality
|
|
10
|
+
|
|
11
|
+
Don't abstract until 2-3 concrete cases exist. Build for today's requirements; extract abstractions when you have real examples.
|
|
12
|
+
|
|
13
|
+
**Detection signals:**
|
|
14
|
+
- Interface with only one implementation
|
|
15
|
+
- Factory that only creates one type
|
|
16
|
+
- Configuration options no one uses
|
|
17
|
+
- Abstraction added "in case we need it later"
|
|
18
|
+
- Generic type parameters that are always the same concrete type
|
|
19
|
+
|
|
20
|
+
**Why it matters:**
|
|
21
|
+
- Less code to maintain and less indirection to trace
|
|
22
|
+
- Abstractions based on real needs fit better than guesses
|
|
23
|
+
- Easier to understand: concrete code is simpler than abstract code
|
|
24
|
+
- When you do need the abstraction, you'll know the right shape because you have concrete examples
|
|
25
|
+
|
|
26
|
+
**Senior pattern:** Write concrete code for the first case. When the second or third case appears, you'll see the real variation axis and can extract the right abstraction. The refactoring from concrete to abstract is straightforward — but the reverse (removing a premature abstraction) is painful because code depends on the abstraction's shape.
|
|
27
|
+
|
|
28
|
+
**Detection questions:**
|
|
29
|
+
- Is there an interface with only one implementation?
|
|
30
|
+
- Is there a factory that only creates one type?
|
|
31
|
+
- Are there configuration options no one uses?
|
|
32
|
+
- Was this abstraction added "in case we need it later"?
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Make Invalid States Unrepresentable
|
|
3
|
+
category: state
|
|
4
|
+
impact: CRITICAL
|
|
5
|
+
impactDescription: Eliminates entire class of bugs
|
|
6
|
+
tags: discriminated-union, boolean-flags, state-modeling, type-safety
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Make Invalid States Unrepresentable
|
|
10
|
+
|
|
11
|
+
Replace boolean flag combinations with discriminated unions/enums where each variant represents exactly one valid state.
|
|
12
|
+
|
|
13
|
+
**Detection signals:**
|
|
14
|
+
- 3+ boolean parameters passed together
|
|
15
|
+
- Same boolean checks repeated in multiple places
|
|
16
|
+
- if/else chains checking flag combinations
|
|
17
|
+
- Some flag combinations would cause undefined behavior
|
|
18
|
+
- State represented as string literals compared with `===`
|
|
19
|
+
|
|
20
|
+
**Why it matters:**
|
|
21
|
+
- Compiler/type checker enforces exhaustive handling of all states
|
|
22
|
+
- New states are added explicitly, not as boolean combinations
|
|
23
|
+
- Impossible to create invalid state combinations at the type level
|
|
24
|
+
- Self-documenting: the union/enum shows all possible states in one place
|
|
25
|
+
|
|
26
|
+
**Senior pattern:** Define a discriminated union (TypeScript), enum with associated data (Rust/Swift), or sealed interface (Kotlin/Java) where each variant carries only the data relevant to that state. Use exhaustive pattern matching (switch/match) so the compiler flags unhandled cases when a new variant is added.
|
|
27
|
+
|
|
28
|
+
**Detection questions:**
|
|
29
|
+
- Are there 3+ boolean parameters being passed together?
|
|
30
|
+
- Do you see the same boolean checks repeated in multiple places?
|
|
31
|
+
- Are there if/else chains checking combinations of flags?
|
|
32
|
+
- Could some flag combinations cause undefined behavior?
|
|
33
|
+
- Would adding a new state require updating multiple scattered conditionals?
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Single Source of Truth
|
|
3
|
+
category: state
|
|
4
|
+
impact: HIGH
|
|
5
|
+
impactDescription: Prevents stale data bugs
|
|
6
|
+
tags: state-management, derived-state, duplication, synchronization
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Single Source of Truth
|
|
10
|
+
|
|
11
|
+
One owner per piece of state. Derive everything else via selectors, computed properties, or transformations — never duplicate.
|
|
12
|
+
|
|
13
|
+
**Detection signals:**
|
|
14
|
+
- Same data stored in both global state and local component state
|
|
15
|
+
- Effect hooks syncing local state from global state
|
|
16
|
+
- Two sources of truth that could disagree
|
|
17
|
+
- Derived data being cached in state instead of computed on access
|
|
18
|
+
- Manual synchronization logic between stores or contexts
|
|
19
|
+
|
|
20
|
+
**Why it matters:**
|
|
21
|
+
- No "which value is authoritative?" confusion
|
|
22
|
+
- State updates propagate automatically through derivations
|
|
23
|
+
- Easier debugging: one place to inspect each piece of state
|
|
24
|
+
- Eliminates stale data bugs caused by desynchronized copies
|
|
25
|
+
|
|
26
|
+
**Senior pattern:** Identify the single authoritative owner for each piece of state. All other consumers read from that owner or derive values from it. Local component state is reserved for truly ephemeral UI concerns (focus, hover, animation progress) that no other component needs. If two components need the same state, lift it to a shared owner rather than syncing copies.
|
|
27
|
+
|
|
28
|
+
**Detection questions:**
|
|
29
|
+
- Is the same data stored in both a global store and local component state?
|
|
30
|
+
- Are there effect hooks whose sole purpose is syncing one state source to another?
|
|
31
|
+
- Could two sources of truth disagree? What happens when they do?
|
|
32
|
+
- Is derived data being cached in state instead of computed from the source?
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Explicit Type Hierarchies
|
|
3
|
+
category: state
|
|
4
|
+
impact: HIGH
|
|
5
|
+
impactDescription: Centralizes decision logic
|
|
6
|
+
tags: factory, type-system, decision-logic, pattern-matching
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Explicit Type Hierarchies
|
|
10
|
+
|
|
11
|
+
Encode decision logic in the type system using factories, not scattered if/else chains across components.
|
|
12
|
+
|
|
13
|
+
**Detection signals:**
|
|
14
|
+
- Complex if/else chains determining which component to render or which path to take
|
|
15
|
+
- Same decision logic duplicated across multiple modules
|
|
16
|
+
- Components receive data they only use to make decisions (not to display or process)
|
|
17
|
+
- New requirement would add another boolean parameter
|
|
18
|
+
- Switch statements on string values or numeric codes
|
|
19
|
+
|
|
20
|
+
**Why it matters:**
|
|
21
|
+
- Decision logic lives in one place (the factory)
|
|
22
|
+
- Consumers receive pre-computed decisions, not raw data to interpret
|
|
23
|
+
- Adding new variants is explicit and type-checked
|
|
24
|
+
- Testing is clearer: test the factory, then test each variant's behavior
|
|
25
|
+
|
|
26
|
+
**Senior pattern:** Create a factory function or static method that takes raw inputs and returns a typed variant. The factory is the single place where decision logic lives. Consumers pattern-match on the result and handle each variant — they never inspect raw data to make decisions themselves.
|
|
27
|
+
|
|
28
|
+
**Detection questions:**
|
|
29
|
+
- Are there complex if/else chains determining behavior scattered across components?
|
|
30
|
+
- Is the same decision logic duplicated in multiple places?
|
|
31
|
+
- Do components receive data they only use to decide what to do?
|
|
32
|
+
- Would a new requirement add another boolean parameter to existing interfaces?
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Composition Over Configuration
|
|
3
|
+
category: structure
|
|
4
|
+
impact: MEDIUM
|
|
5
|
+
impactDescription: Simplifies component APIs
|
|
6
|
+
tags: composition, god-component, flags, single-responsibility
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Composition Over Configuration
|
|
10
|
+
|
|
11
|
+
Build focused components that compose together instead of god components with many boolean flags.
|
|
12
|
+
|
|
13
|
+
**Detection signals:**
|
|
14
|
+
- Component has more than 6-8 parameters/props
|
|
15
|
+
- Boolean parameters that are mutually exclusive
|
|
16
|
+
- Component is really 3 different components pretending to be 1
|
|
17
|
+
- Adding a new variant would require another boolean flag
|
|
18
|
+
- Conditionals inside the component that render entirely different structures
|
|
19
|
+
|
|
20
|
+
**Why it matters:**
|
|
21
|
+
- Each component has one job and is easy to understand
|
|
22
|
+
- New variants don't bloat existing components
|
|
23
|
+
- Easier to test: focused inputs and outputs
|
|
24
|
+
- Flexible: compose for custom needs, use shortcuts for common ones
|
|
25
|
+
|
|
26
|
+
**Senior pattern:** Split the god component into focused units, each handling one variant or concern. Provide composition points (children/slots/render props) for flexibility. For common combinations, offer convenience wrappers that compose the focused units — but the building blocks remain available for custom needs.
|
|
27
|
+
|
|
28
|
+
**Detection questions:**
|
|
29
|
+
- Does this component have more than 6-8 parameters?
|
|
30
|
+
- Are there boolean parameters that are mutually exclusive?
|
|
31
|
+
- Is this component really multiple components pretending to be one?
|
|
32
|
+
- Would adding a new variant require another boolean flag?
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Isolate Feature Responsibility
|
|
3
|
+
category: structure
|
|
4
|
+
impact: HIGH
|
|
5
|
+
impactDescription: Features become removable
|
|
6
|
+
tags: wrapper, decorator, feature-isolation, composition
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Isolate Feature Responsibility
|
|
10
|
+
|
|
11
|
+
Extract optional feature logic into wrapper/decorator components. The wrapper owns all feature-specific state; the core component doesn't know the feature exists.
|
|
12
|
+
|
|
13
|
+
**Detection signals:**
|
|
14
|
+
- More than 30% of a component's code dedicated to one optional feature
|
|
15
|
+
- Removing a feature requires deleting scattered lines throughout the file
|
|
16
|
+
- Multiple `if (featureEnabled)` checks spread across the component
|
|
17
|
+
- State variables only used by one feature mixed with core state
|
|
18
|
+
- Feature-specific imports polluting the core module
|
|
19
|
+
|
|
20
|
+
**Why it matters:**
|
|
21
|
+
- Feature can be disabled/removed by removing one wrapper
|
|
22
|
+
- Core component remains focused and testable
|
|
23
|
+
- Feature logic is cohesive and isolated in one place
|
|
24
|
+
- Multiple features compose without polluting each other
|
|
25
|
+
|
|
26
|
+
**Senior pattern:** Move all feature-specific state, effects, and rendering into a wrapper/decorator component that wraps the core. The wrapper provides feature context to the core through a render prop, slot, or composition pattern. The core component has zero awareness of the feature — it renders its own concern and accepts optional enhancement points.
|
|
27
|
+
|
|
28
|
+
**Detection questions:**
|
|
29
|
+
- Is more than 30% of a component's code dedicated to one optional feature?
|
|
30
|
+
- Would removing a feature require deleting scattered lines throughout the file?
|
|
31
|
+
- Are there multiple `if (featureEnabled)` checks spread across the component?
|
|
32
|
+
- Does the component have state variables only used by one feature?
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Module Cohesion
|
|
3
|
+
category: structure
|
|
4
|
+
impact: MEDIUM-HIGH
|
|
5
|
+
impactDescription: Changes stay contained to one module
|
|
6
|
+
tags: cohesion, boundaries, feature-folders, colocation
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Module Cohesion
|
|
10
|
+
|
|
11
|
+
Group related logic into cohesive module boundaries so that a single feature change touches one module, not many.
|
|
12
|
+
|
|
13
|
+
**Detection signals:**
|
|
14
|
+
- A feature's logic is spread across 4+ directories by technical layer (routes/, models/, services/, utils/)
|
|
15
|
+
- Changing one feature requires touching files in many unrelated folders
|
|
16
|
+
- Related types, helpers, and constants live far from the code that uses them
|
|
17
|
+
- Shared utility files that grow unbounded because "everything needs it"
|
|
18
|
+
- Circular dependencies between modules
|
|
19
|
+
|
|
20
|
+
**Why it matters:**
|
|
21
|
+
- Feature changes are contained: one module to understand, one module to test
|
|
22
|
+
- Dependencies between modules are explicit and minimal
|
|
23
|
+
- Easier to extract, replace, or delete a feature entirely
|
|
24
|
+
- New developers can navigate by feature, not by guessing which technical layer holds what
|
|
25
|
+
|
|
26
|
+
**Senior pattern:** Organize by feature/domain first, technical layer second. Each feature module contains its types, logic, and tests colocated. Shared utilities exist only when genuinely used across 3+ features — otherwise the "utility" belongs in the feature that uses it. Module boundaries are enforced by explicit public APIs (barrel files, index exports) that hide internal structure.
|
|
27
|
+
|
|
28
|
+
**Detection questions:**
|
|
29
|
+
- Does changing one feature require touching files in many unrelated directories?
|
|
30
|
+
- Is related logic (types, helpers, constants) colocated with the code that uses it?
|
|
31
|
+
- Are there shared utility files that grow unbounded?
|
|
32
|
+
- Can you describe what each module "owns" in one sentence?
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Debugging Mindset (DEPRECATED)
|
|
2
|
-
|
|
3
|
-
This reference has been consolidated into the `ms-debugger` agent.
|
|
4
|
-
|
|
5
|
-
**Location:** `agents/ms-debugger.md`
|
|
6
|
-
|
|
7
|
-
**Section:** `<philosophy>`
|
|
8
|
-
|
|
9
|
-
**Reason:** Debugging expertise is now baked into the agent. Loading separate reference files into orchestrator context was wasteful (~95% context reduction).
|
|
10
|
-
|
|
11
|
-
See `agents/ms-debugger.md` for the consolidated debugging methodology.
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Hypothesis Testing (DEPRECATED)
|
|
2
|
-
|
|
3
|
-
This reference has been consolidated into the `ms-debugger` agent.
|
|
4
|
-
|
|
5
|
-
**Location:** `agents/ms-debugger.md`
|
|
6
|
-
|
|
7
|
-
**Section:** `<hypothesis_testing>`
|
|
8
|
-
|
|
9
|
-
**Reason:** Debugging expertise is now baked into the agent. Loading separate reference files into orchestrator context was wasteful (~95% context reduction).
|
|
10
|
-
|
|
11
|
-
See `agents/ms-debugger.md` for the consolidated debugging methodology.
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Investigation Techniques (DEPRECATED)
|
|
2
|
-
|
|
3
|
-
This reference has been consolidated into the `ms-debugger` agent.
|
|
4
|
-
|
|
5
|
-
**Location:** `agents/ms-debugger.md`
|
|
6
|
-
|
|
7
|
-
**Section:** `<investigation_techniques>`
|
|
8
|
-
|
|
9
|
-
**Reason:** Debugging expertise is now baked into the agent. Loading separate reference files into orchestrator context was wasteful (~95% context reduction).
|
|
10
|
-
|
|
11
|
-
See `agents/ms-debugger.md` for the consolidated debugging methodology.
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Verification Patterns (DEPRECATED)
|
|
2
|
-
|
|
3
|
-
This reference has been consolidated into the `ms-debugger` agent.
|
|
4
|
-
|
|
5
|
-
**Location:** `agents/ms-debugger.md`
|
|
6
|
-
|
|
7
|
-
**Section:** `<verification_patterns>`
|
|
8
|
-
|
|
9
|
-
**Reason:** Debugging expertise is now baked into the agent. Loading separate reference files into orchestrator context was wasteful (~95% context reduction).
|
|
10
|
-
|
|
11
|
-
See `agents/ms-debugger.md` for the consolidated debugging methodology.
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# When to Research (DEPRECATED)
|
|
2
|
-
|
|
3
|
-
This reference has been consolidated into the `ms-debugger` agent.
|
|
4
|
-
|
|
5
|
-
**Location:** `agents/ms-debugger.md`
|
|
6
|
-
|
|
7
|
-
**Section:** `<research_vs_reasoning>`
|
|
8
|
-
|
|
9
|
-
**Reason:** Debugging expertise is now baked into the agent. Loading separate reference files into orchestrator context was wasteful (~95% context reduction).
|
|
10
|
-
|
|
11
|
-
See `agents/ms-debugger.md` for the consolidated debugging methodology.
|