@schilling.mark.a/software-methodology 1.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/.github/copilot-instructions.md +106 -0
- package/LICENSE +21 -0
- package/README.md +174 -0
- package/atdd-workflow/SKILL.md +117 -0
- package/atdd-workflow/references/green-phase.md +38 -0
- package/atdd-workflow/references/red-phase.md +62 -0
- package/atdd-workflow/references/refactor-phase.md +75 -0
- package/bdd-specification/SKILL.md +88 -0
- package/bdd-specification/references/example-mapping.md +105 -0
- package/bdd-specification/references/gherkin-patterns.md +214 -0
- package/cicd-pipeline/SKILL.md +64 -0
- package/cicd-pipeline/references/deployment-rollback.md +176 -0
- package/cicd-pipeline/references/environment-promotion.md +159 -0
- package/cicd-pipeline/references/pipeline-stages.md +198 -0
- package/clean-code/SKILL.md +77 -0
- package/clean-code/references/behavioral-patterns.md +329 -0
- package/clean-code/references/creational-patterns.md +197 -0
- package/clean-code/references/enterprise-patterns.md +334 -0
- package/clean-code/references/solid.md +230 -0
- package/clean-code/references/structural-patterns.md +238 -0
- package/continuous-improvement/SKILL.md +69 -0
- package/continuous-improvement/references/measurement.md +133 -0
- package/continuous-improvement/references/process-update.md +118 -0
- package/continuous-improvement/references/root-cause-analysis.md +144 -0
- package/dist/atdd-workflow.skill +0 -0
- package/dist/bdd-specification.skill +0 -0
- package/dist/cicd-pipeline.skill +0 -0
- package/dist/clean-code.skill +0 -0
- package/dist/continuous-improvement.skill +0 -0
- package/dist/green-implementation.skill +0 -0
- package/dist/product-strategy.skill +0 -0
- package/dist/story-mapping.skill +0 -0
- package/dist/ui-design-system.skill +0 -0
- package/dist/ui-design-workflow.skill +0 -0
- package/dist/ux-design.skill +0 -0
- package/dist/ux-research.skill +0 -0
- package/docs/INTEGRATION.md +229 -0
- package/docs/QUICKSTART.md +126 -0
- package/docs/SHARING.md +828 -0
- package/docs/SKILLS.md +296 -0
- package/green-implementation/SKILL.md +155 -0
- package/green-implementation/references/angular-patterns.md +239 -0
- package/green-implementation/references/common-rejections.md +180 -0
- package/green-implementation/references/playwright-patterns.md +321 -0
- package/green-implementation/references/rxjs-patterns.md +161 -0
- package/package.json +57 -0
- package/product-strategy/SKILL.md +71 -0
- package/product-strategy/references/business-model-canvas.md +199 -0
- package/product-strategy/references/canvas-alignment.md +108 -0
- package/product-strategy/references/value-proposition-canvas.md +159 -0
- package/project-templates/context.md.template +56 -0
- package/project-templates/test-strategy.md.template +87 -0
- package/story-mapping/SKILL.md +104 -0
- package/story-mapping/references/backbone.md +66 -0
- package/story-mapping/references/release-planning.md +92 -0
- package/story-mapping/references/task-template.md +78 -0
- package/story-mapping/references/walking-skeleton.md +63 -0
- package/ui-design-system/SKILL.md +48 -0
- package/ui-design-system/references/accessibility.md +134 -0
- package/ui-design-system/references/components.md +257 -0
- package/ui-design-system/references/design-tokens.md +209 -0
- package/ui-design-system/references/layout.md +136 -0
- package/ui-design-system/references/typography.md +114 -0
- package/ui-design-workflow/SKILL.md +90 -0
- package/ui-design-workflow/references/acceptance-targets.md +144 -0
- package/ui-design-workflow/references/component-selection.md +108 -0
- package/ui-design-workflow/references/scenario-to-ui.md +151 -0
- package/ui-design-workflow/references/screen-flows.md +116 -0
- package/ux-design/SKILL.md +75 -0
- package/ux-design/references/information-architecture.md +144 -0
- package/ux-design/references/interaction-patterns.md +141 -0
- package/ux-design/references/onboarding.md +159 -0
- package/ux-design/references/usability-evaluation.md +132 -0
- package/ux-research/SKILL.md +75 -0
- package/ux-research/references/journey-mapping.md +168 -0
- package/ux-research/references/mental-models.md +106 -0
- package/ux-research/references/personas.md +102 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Structural Patterns
|
|
2
|
+
|
|
3
|
+
Patterns for composing objects and classes into larger structures.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Adapter
|
|
8
|
+
|
|
9
|
+
**When to use:**
|
|
10
|
+
- You need to use an existing class but its interface doesn't match what your code expects
|
|
11
|
+
- You want to wrap an external or legacy system behind your own interface
|
|
12
|
+
- You want to isolate your domain from third-party APIs
|
|
13
|
+
|
|
14
|
+
**Smell that triggers it:**
|
|
15
|
+
- Direct calls to an external API scattered through business logic
|
|
16
|
+
- Changing the external provider would require changes across the codebase
|
|
17
|
+
- Unit tests fail because they can't mock the external system
|
|
18
|
+
|
|
19
|
+
**Solution:**
|
|
20
|
+
```
|
|
21
|
+
// External system you don't control
|
|
22
|
+
class StripePaymentGateway:
|
|
23
|
+
chargeCard(cardNumber, amount, currency, metadata): StripeResponse
|
|
24
|
+
|
|
25
|
+
// Your domain's contract — defined by YOUR needs, not Stripe's
|
|
26
|
+
interface PaymentProcessor:
|
|
27
|
+
process(payment: Payment): PaymentResult
|
|
28
|
+
|
|
29
|
+
// Adapter — translates between your world and theirs
|
|
30
|
+
class StripeAdapter implements PaymentProcessor:
|
|
31
|
+
constructor(stripe: StripePaymentGateway)
|
|
32
|
+
|
|
33
|
+
process(payment: Payment): PaymentResult
|
|
34
|
+
stripeResponse = this.stripe.chargeCard(
|
|
35
|
+
payment.cardNumber,
|
|
36
|
+
payment.amount.value,
|
|
37
|
+
payment.amount.currency,
|
|
38
|
+
{ invoiceId: payment.invoiceId }
|
|
39
|
+
)
|
|
40
|
+
return new PaymentResult(stripeResponse.id, stripeResponse.status)
|
|
41
|
+
|
|
42
|
+
// Business logic knows nothing about Stripe
|
|
43
|
+
class InvoicePaymentService:
|
|
44
|
+
constructor(processor: PaymentProcessor) ← depends on YOUR interface
|
|
45
|
+
|
|
46
|
+
pay(invoice, payment):
|
|
47
|
+
result = this.processor.process(payment)
|
|
48
|
+
invoice.markPaid(result.transactionId)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Key insight:** Switching from Stripe to PayPal means writing a new adapter. `InvoicePaymentService` never changes. Tests inject a mock `PaymentProcessor` — no real payment gateway needed.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Facade
|
|
56
|
+
|
|
57
|
+
**When to use:**
|
|
58
|
+
- A subsystem has many classes with complex interdependencies
|
|
59
|
+
- You want to provide a simple entry point to a complex system
|
|
60
|
+
- You want to decouple clients from the internal structure of a subsystem
|
|
61
|
+
|
|
62
|
+
**Smell that triggers it:**
|
|
63
|
+
- Calling code needs to orchestrate 5+ steps across multiple classes to accomplish one logical action
|
|
64
|
+
- Internal details of a subsystem leak into the calling code
|
|
65
|
+
|
|
66
|
+
**Solution:**
|
|
67
|
+
```
|
|
68
|
+
// Complex subsystem internals
|
|
69
|
+
class TaxEngine: ...
|
|
70
|
+
class DiscountCalculator: ...
|
|
71
|
+
class InvoiceFormatter: ...
|
|
72
|
+
class InvoiceValidator: ...
|
|
73
|
+
class InvoiceRepository: ...
|
|
74
|
+
|
|
75
|
+
// Facade — single entry point, hides orchestration
|
|
76
|
+
class InvoiceService:
|
|
77
|
+
constructor(taxEngine, discountCalc, formatter, validator, repo)
|
|
78
|
+
|
|
79
|
+
createAndSave(invoiceData): Invoice
|
|
80
|
+
invoice = new Invoice(invoiceData)
|
|
81
|
+
invoice.applyDiscount(this.discountCalc.calculate(invoice))
|
|
82
|
+
invoice.applyTax(this.taxEngine.calculate(invoice))
|
|
83
|
+
this.validator.validate(invoice)
|
|
84
|
+
formatted = this.formatter.format(invoice)
|
|
85
|
+
this.repo.save(formatted)
|
|
86
|
+
return invoice
|
|
87
|
+
|
|
88
|
+
// Caller sees only one method
|
|
89
|
+
service.createAndSave(data)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Key insight:** The facade doesn't prevent direct access to subsystem classes if needed, but it provides the simple path for the common case. Internal classes can change without affecting callers that go through the facade.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Composite
|
|
97
|
+
|
|
98
|
+
**When to use:**
|
|
99
|
+
- You have a tree structure where individual objects and compositions of objects are treated uniformly
|
|
100
|
+
- Clients should be able to interact with individual objects and compositions through the same interface
|
|
101
|
+
|
|
102
|
+
**Smell that triggers it:**
|
|
103
|
+
- Code that checks "is this a leaf or a container?" before acting
|
|
104
|
+
- Recursive structures (categories containing subcategories, directories containing files or subdirectories)
|
|
105
|
+
|
|
106
|
+
**Solution:**
|
|
107
|
+
```
|
|
108
|
+
interface PriceComponent:
|
|
109
|
+
getPrice(): Money
|
|
110
|
+
getDescription(): string
|
|
111
|
+
|
|
112
|
+
class LineItem implements PriceComponent: ← leaf
|
|
113
|
+
constructor(description, price)
|
|
114
|
+
getPrice(): return this.price
|
|
115
|
+
getDescription(): return this.description
|
|
116
|
+
|
|
117
|
+
class InvoiceSection implements PriceComponent: ← composite
|
|
118
|
+
private items: PriceComponent[] = []
|
|
119
|
+
|
|
120
|
+
add(item: PriceComponent): this.items.push(item)
|
|
121
|
+
|
|
122
|
+
getPrice(): Money
|
|
123
|
+
return this.items.reduce((sum, item) => sum.add(item.getPrice()), Money.zero())
|
|
124
|
+
|
|
125
|
+
getDescription(): string
|
|
126
|
+
return this.items.map(i => i.getDescription()).join(", ")
|
|
127
|
+
|
|
128
|
+
// Usage — sections can contain items OR other sections
|
|
129
|
+
consulting = new InvoiceSection("Consulting")
|
|
130
|
+
consulting.add(new LineItem("Architecture Review", 2000))
|
|
131
|
+
consulting.add(new LineItem("Code Review", 500))
|
|
132
|
+
|
|
133
|
+
development = new InvoiceSection("Development")
|
|
134
|
+
development.add(new LineItem("Feature X", 5000))
|
|
135
|
+
|
|
136
|
+
invoice = new InvoiceSection("Invoice Total")
|
|
137
|
+
invoice.add(consulting) ← section inside section
|
|
138
|
+
invoice.add(development)
|
|
139
|
+
|
|
140
|
+
invoice.getPrice() ← recursively sums everything: 7500
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Key insight:** The caller never checks types. Every `PriceComponent` responds to `getPrice()` the same way, whether it's a single item or a tree of sections.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Decorator
|
|
148
|
+
|
|
149
|
+
**When to use:**
|
|
150
|
+
- You need to add behavior to an object dynamically, without modifying its class
|
|
151
|
+
- You want to stack multiple behaviors independently
|
|
152
|
+
- Subclassing would create a combinatorial explosion of classes
|
|
153
|
+
|
|
154
|
+
**Smell that triggers it:**
|
|
155
|
+
- A growing list of subclasses, each adding one behavior variant
|
|
156
|
+
- A class accumulating flags/booleans that conditionally activate features
|
|
157
|
+
- "I want Invoice to optionally have tax, optionally have discount, optionally have header"
|
|
158
|
+
|
|
159
|
+
**Solution:**
|
|
160
|
+
```
|
|
161
|
+
interface InvoiceRenderer:
|
|
162
|
+
render(invoice): string
|
|
163
|
+
|
|
164
|
+
class BasicInvoiceRenderer implements InvoiceRenderer: ← base
|
|
165
|
+
render(invoice): return formatBasicInvoice(invoice)
|
|
166
|
+
|
|
167
|
+
class WithHeaderDecorator implements InvoiceRenderer: ← adds header
|
|
168
|
+
constructor(wrapped: InvoiceRenderer)
|
|
169
|
+
render(invoice):
|
|
170
|
+
return renderHeader() + this.wrapped.render(invoice)
|
|
171
|
+
|
|
172
|
+
class WithFooterDecorator implements InvoiceRenderer: ← adds footer
|
|
173
|
+
constructor(wrapped: InvoiceRenderer)
|
|
174
|
+
render(invoice):
|
|
175
|
+
return this.wrapped.render(invoice) + renderFooter()
|
|
176
|
+
|
|
177
|
+
class WithPageNumbersDecorator implements InvoiceRenderer:
|
|
178
|
+
constructor(wrapped: InvoiceRenderer)
|
|
179
|
+
render(invoice):
|
|
180
|
+
return addPageNumbers(this.wrapped.render(invoice))
|
|
181
|
+
|
|
182
|
+
// Compose at runtime — any combination, any order
|
|
183
|
+
renderer = new WithPageNumbersDecorator(
|
|
184
|
+
new WithHeaderDecorator(
|
|
185
|
+
new WithFooterDecorator(
|
|
186
|
+
new BasicInvoiceRenderer()
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
output = renderer.render(invoice)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Key insight:** Each decorator is independent. Adding a new rendering behavior means one new class. No modification to existing decorators or the base renderer. The wrapping order determines execution order.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Bridge
|
|
199
|
+
|
|
200
|
+
**When to use:**
|
|
201
|
+
- You have two dimensions of variation (e.g., shape × color, platform × UI control)
|
|
202
|
+
- You want to avoid a combinatorial explosion of subclasses
|
|
203
|
+
- You want to vary implementation and abstraction independently
|
|
204
|
+
|
|
205
|
+
**Smell that triggers it:**
|
|
206
|
+
- Class hierarchy growing as every combination of two independent concepts creates a new subclass
|
|
207
|
+
- `RedCircle`, `BlueCircle`, `RedSquare`, `BlueSquare`... and new colors or shapes keep appearing
|
|
208
|
+
|
|
209
|
+
**Solution:**
|
|
210
|
+
```
|
|
211
|
+
// Implementation dimension
|
|
212
|
+
interface Renderer:
|
|
213
|
+
renderCircle(radius)
|
|
214
|
+
renderRectangle(width, height)
|
|
215
|
+
|
|
216
|
+
class CanvasRenderer implements Renderer: ...
|
|
217
|
+
class SVGRenderer implements Renderer: ...
|
|
218
|
+
class PDFRenderer implements Renderer: ...
|
|
219
|
+
|
|
220
|
+
// Abstraction dimension — holds a reference to implementation
|
|
221
|
+
abstract class Shape:
|
|
222
|
+
constructor(renderer: Renderer)
|
|
223
|
+
|
|
224
|
+
class Circle extends Shape:
|
|
225
|
+
constructor(renderer, radius)
|
|
226
|
+
draw(): this.renderer.renderCircle(this.radius)
|
|
227
|
+
|
|
228
|
+
class Rectangle extends Shape:
|
|
229
|
+
constructor(renderer, width, height)
|
|
230
|
+
draw(): this.renderer.renderRectangle(this.width, this.height)
|
|
231
|
+
|
|
232
|
+
// New renderer = one new class. New shape = one new class.
|
|
233
|
+
// No combinatorial explosion.
|
|
234
|
+
circle = new Circle(new SVGRenderer(), 50)
|
|
235
|
+
circle.draw()
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Key insight:** Two independent hierarchies connected by composition, not inheritance. Adding a new renderer or a new shape is one class each, never a product of both.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: continuous-improvement
|
|
3
|
+
description: Post-release quality and process improvement skill grounded in Deming's system thinking. Use after a release ships, when the team wants to run a retrospective, when defects or rework surfaced during a release cycle, when the user says "retrospective", "what went wrong", "improve our process", or "why did that happen". Reads release plans, usability evaluations, and commit history. Produces measurement reports, root cause analyses, and process updates that feed back into the other skills. This is the closing loop — without it the methodology cannot learn from itself.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Continuous Improvement
|
|
7
|
+
|
|
8
|
+
## Core Principle: The System, Not the Individual
|
|
9
|
+
|
|
10
|
+
Most defects are produced by the system — the process, the tools, the structure — not by the people in it. A bug that slips to production is not evidence that a developer made a mistake. It is evidence that the process allowed it through. A design that required rework is not evidence that a designer failed. It is evidence that the evaluation caught it too late or not at all.
|
|
11
|
+
|
|
12
|
+
This skill investigates the system. It asks "why did the process produce this outcome?" not "who made this mistake?" Root cause analysis that ends with blaming an individual has found a symptom, not a cause. The cause is always upstream in the process.
|
|
13
|
+
|
|
14
|
+
## When to Run This Skill
|
|
15
|
+
|
|
16
|
+
- **After every release ships** — run measurement (Step 1) as a lightweight check
|
|
17
|
+
- **When a defect reaches production** — run full root cause analysis (Step 2)
|
|
18
|
+
- **When a feature required significant rework** — run root cause analysis to find where the process failed to catch it earlier
|
|
19
|
+
- **After 3+ releases** — run process update (Step 3) to see if patterns have emerged
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
### Step 1: Measure
|
|
24
|
+
|
|
25
|
+
Collect the data the release naturally produced. This is not a separate instrumentation effort — every artifact in the methodology already contains the signals. The job here is to read them and record the numbers.
|
|
26
|
+
|
|
27
|
+
See `references/measurement.md` for what to measure, where each signal comes from, and the measurement report format.
|
|
28
|
+
|
|
29
|
+
Create: `/docs/continuous-improvement/measurements/r[N]-[name].md`
|
|
30
|
+
|
|
31
|
+
### Step 2: Root Cause Analysis
|
|
32
|
+
|
|
33
|
+
When a defect reached production, or a feature required rework that should have been caught earlier, investigate why. The goal is to find the earliest point in the process where the outcome was already determined — not the point where it was discovered.
|
|
34
|
+
|
|
35
|
+
See `references/root-cause-analysis.md` for the investigation method, the "5 Whys" technique adapted for software process, and the report format.
|
|
36
|
+
|
|
37
|
+
Create: `/docs/continuous-improvement/root-causes/[incident-name].md`
|
|
38
|
+
|
|
39
|
+
### Step 3: Process Update
|
|
40
|
+
|
|
41
|
+
Findings from measurement and root cause analysis feed back into the methodology. A pattern in the data means a skill needs updating. A single root cause points to a specific gap.
|
|
42
|
+
|
|
43
|
+
See `references/process-update.md` for how to decide what changes, how to apply changes to the skills, and how to validate that the change worked.
|
|
44
|
+
|
|
45
|
+
Update: the relevant skill's SKILL.md or references as identified.
|
|
46
|
+
|
|
47
|
+
## File Structure
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
docs/continuous-improvement/
|
|
51
|
+
├── measurements/
|
|
52
|
+
│ ├── r1-[name].md ← measurement report per release
|
|
53
|
+
│ └── r2-[name].md
|
|
54
|
+
└── root-causes/
|
|
55
|
+
└── [incident-name].md ← root cause analysis per incident
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Integration
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
ux-research → story-mapping → bdd-specification → ux-design →
|
|
62
|
+
ui-design-workflow → atdd-workflow → [RELEASE SHIPS]
|
|
63
|
+
↓
|
|
64
|
+
continuous-improvement (this skill)
|
|
65
|
+
↓
|
|
66
|
+
feeds back into any skill above
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
This is the only skill that writes back into other skills. Every other skill in the methodology is a consumer. This one is the loop that closes.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Measurement
|
|
2
|
+
|
|
3
|
+
## Why Measure?
|
|
4
|
+
|
|
5
|
+
You cannot improve what you do not measure. But measurement is only useful if it measures the right things — signals that reveal whether the process is healthy, not vanity numbers that feel productive but change nothing.
|
|
6
|
+
|
|
7
|
+
The methodology already produces every signal needed. No new instrumentation. No dashboards. No tracking tools. The data lives in the artifacts each skill already creates. This skill reads them after a release and records the numbers.
|
|
8
|
+
|
|
9
|
+
## What to Measure
|
|
10
|
+
|
|
11
|
+
Nine signals. Each one maps to a specific artifact that already exists.
|
|
12
|
+
|
|
13
|
+
### Signal 1: Scenarios Written vs Scenarios Passing
|
|
14
|
+
|
|
15
|
+
**What it measures:** How well the acceptance criteria matched what was actually built. A large gap means scenarios were ambiguous or the implementation drifted from intent.
|
|
16
|
+
|
|
17
|
+
**Where to find it:**
|
|
18
|
+
- Written: count the Scenario blocks in `/features/[domain]/*.feature`
|
|
19
|
+
- Passing: count the passing acceptance tests in the test run report
|
|
20
|
+
|
|
21
|
+
**Healthy range:** 95–100% passing on first release. Below 90% indicates scenarios need refinement before implementation begins.
|
|
22
|
+
|
|
23
|
+
### Signal 2: Usability Violations Found vs Violations Found Late
|
|
24
|
+
|
|
25
|
+
**What it measures:** Whether the usability evaluation is catching problems at the right time. Violations found during evaluation (before screen design) cost nothing. Violations found during implementation or after shipping cost a full rework cycle.
|
|
26
|
+
|
|
27
|
+
**Where to find it:**
|
|
28
|
+
- Planned violations: `/docs/ux-design/usability-evaluation/[feature].md` — the Violations Found section
|
|
29
|
+
- Late violations: any design change that occurred after ui-design-workflow produced screen flows, or any bug report that maps to a usability heuristic
|
|
30
|
+
|
|
31
|
+
**Healthy range:** >80% of violations found during evaluation. Any violation discovered after shipping is a process failure worth investigating.
|
|
32
|
+
|
|
33
|
+
### Signal 3: Acceptance Targets Defined vs Acceptance Targets Tested
|
|
34
|
+
|
|
35
|
+
**What it measures:** Whether every design decision that matters has a test behind it. Untested design decisions drift.
|
|
36
|
+
|
|
37
|
+
**Where to find it:**
|
|
38
|
+
- Defined: count the checkboxes in the Acceptance Targets section of `/docs/ui-design/screen-flows/[feature].md`
|
|
39
|
+
- Tested: count the acceptance test assertions that map to those targets
|
|
40
|
+
|
|
41
|
+
**Healthy range:** 100%. Every defined target has a test. Any gap means a design decision is unverified.
|
|
42
|
+
|
|
43
|
+
### Signal 4: Red-Green-Refactor Cycles Per Feature
|
|
44
|
+
|
|
45
|
+
**What it measures:** How tight the implementation loop is. A large number of cycles per feature is healthy — it means the developer is working in small, verified increments. A small number means either the feature was trivially simple or the developer wrote large chunks without verification.
|
|
46
|
+
|
|
47
|
+
**Where to find it:** Count the commits tagged with `feat:`, `test:`, and `refactor:` per feature in git history. Each RED-GREEN-REFACTOR sequence is one cycle.
|
|
48
|
+
|
|
49
|
+
**Healthy range:** 3+ cycles per feature. Fewer than 3 on a non-trivial feature means the ATDD loop is not being followed tightly enough.
|
|
50
|
+
|
|
51
|
+
### Signal 5: Defects Reaching Production
|
|
52
|
+
|
|
53
|
+
**What it measures:** How many bugs escaped the entire methodology and reached users. This is the most expensive signal — every production defect represents a failure somewhere upstream in the process.
|
|
54
|
+
|
|
55
|
+
**Where to find it:** Bug reports or production incident logs. Each defect is tagged with which feature it belongs to.
|
|
56
|
+
|
|
57
|
+
**Healthy range:** 0 per release for critical defects. Any critical defect in production triggers a root cause analysis (see root-cause-analysis.md).
|
|
58
|
+
|
|
59
|
+
### Signal 6: Rework After Screen Flows Were Designed
|
|
60
|
+
|
|
61
|
+
**What it measures:** Whether the design process produced stable specifications. Rework after screen flows means something was missed during ux-design or ui-design-workflow.
|
|
62
|
+
|
|
63
|
+
**Where to find it:** Compare the original screen flow document date to any subsequent revisions. Any revision after atdd-workflow began implementation is rework.
|
|
64
|
+
|
|
65
|
+
**Healthy range:** 0 revisions after implementation begins. Any rework after that point triggers root cause analysis.
|
|
66
|
+
|
|
67
|
+
### Signal 7: Story Map Accuracy
|
|
68
|
+
|
|
69
|
+
**What it measures:** How well the story map predicted what actually shipped. Tasks that were Must Have but didn't ship, or tasks that shipped but weren't planned, indicate the estimation and prioritization process needs calibration.
|
|
70
|
+
|
|
71
|
+
**Where to find it:**
|
|
72
|
+
- Planned: `/docs/story-map/releases/r[N]-[name].md` — the Tasks section with MoSCoW priorities
|
|
73
|
+
- Actual: what actually shipped in the release
|
|
74
|
+
|
|
75
|
+
**Healthy range:** All Must Have tasks shipped. Should Have tasks shipped or explicitly deferred with documented reason. No unplanned work shipped without a documented decision to include it.
|
|
76
|
+
|
|
77
|
+
### Signal 8: Time From Scenario to Shipped
|
|
78
|
+
|
|
79
|
+
**What it measures:** The total flow time for a feature — from when the scenario was written to when it shipped. This reveals whether bottlenecks exist in the process. A long gap between scenario and shipped means something stalled.
|
|
80
|
+
|
|
81
|
+
**Where to find it:** Compare the feature file creation date (or first commit to the .feature file) to the release ship date.
|
|
82
|
+
|
|
83
|
+
**Healthy range:** Consistent across features in the same release. Large variance between features indicates a bottleneck on specific types of work.
|
|
84
|
+
|
|
85
|
+
### Signal 9: Mental Model Conflicts Found
|
|
86
|
+
|
|
87
|
+
**What it measures:** Whether the product is drifting away from user mental models. Conflicts found during ux-design are cheap to fix. Conflicts discovered by users after shipping are expensive and erode trust.
|
|
88
|
+
|
|
89
|
+
**Where to find it:**
|
|
90
|
+
- Planned conflicts: `/docs/ux-research/mental-models/*.md` — the "Where the System Model Differs" section
|
|
91
|
+
- User-discovered conflicts: support tickets, user feedback, or usability testing results that indicate confusion about how the product works
|
|
92
|
+
|
|
93
|
+
**Healthy range:** All known conflicts addressed before shipping. Any user-discovered conflict not predicted by the mental model documents indicates the research phase missed something.
|
|
94
|
+
|
|
95
|
+
## Measurement Report Format
|
|
96
|
+
|
|
97
|
+
Create: `/docs/continuous-improvement/measurements/r[N]-[name].md`
|
|
98
|
+
|
|
99
|
+
```markdown
|
|
100
|
+
# Measurement Report: Release [N] — [Name]
|
|
101
|
+
|
|
102
|
+
**Release date:** [Date]
|
|
103
|
+
**Features shipped:** [List]
|
|
104
|
+
|
|
105
|
+
## Signals
|
|
106
|
+
|
|
107
|
+
| Signal | Target | Actual | Status |
|
|
108
|
+
|---|---|---|---|
|
|
109
|
+
| Scenarios written vs passing | ≥95% | [N]% | ✅ / ⚠️ / 🔴 |
|
|
110
|
+
| Usability violations: found early vs late | ≥80% early | [N]% early | ✅ / ⚠️ / 🔴 |
|
|
111
|
+
| Acceptance targets: defined vs tested | 100% | [N]% | ✅ / ⚠️ / 🔴 |
|
|
112
|
+
| Red-Green-Refactor cycles per feature | ≥3 | [N] avg | ✅ / ⚠️ / 🔴 |
|
|
113
|
+
| Defects reaching production | 0 critical | [N] | ✅ / ⚠️ / 🔴 |
|
|
114
|
+
| Rework after screen flows designed | 0 | [N] | ✅ / ⚠️ / 🔴 |
|
|
115
|
+
| Story map accuracy | All Must Have shipped | [summary] | ✅ / ⚠️ / 🔴 |
|
|
116
|
+
| Time from scenario to shipped | Consistent | [range] | ✅ / ⚠️ / 🔴 |
|
|
117
|
+
| Mental model conflicts | 0 user-discovered | [N] | ✅ / ⚠️ / 🔴 |
|
|
118
|
+
|
|
119
|
+
**Status key:** ✅ Within healthy range. ⚠️ Borderline — monitor next release. 🔴 Outside healthy range — investigate.
|
|
120
|
+
|
|
121
|
+
## Summary
|
|
122
|
+
[1–2 sentences: overall process health this release. Which signals are healthy, which need attention.]
|
|
123
|
+
|
|
124
|
+
## Signals Requiring Investigation
|
|
125
|
+
[List any 🔴 signals. Each becomes a root cause analysis if the cause is not immediately obvious.]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Rules
|
|
129
|
+
|
|
130
|
+
- Run measurement after every release. It takes 30 minutes if the artifacts are well-maintained.
|
|
131
|
+
- Record actuals even when they are healthy. Trends over multiple releases reveal drift that a single measurement cannot.
|
|
132
|
+
- A 🔴 signal does not mean the team failed. It means the system produced an outcome worth investigating. See root-cause-analysis.md.
|
|
133
|
+
- Do not skip signals because they are inconvenient. Every signal exists for a reason. Skipping one creates a blind spot.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Process Update
|
|
2
|
+
|
|
3
|
+
## What Is a Process Update?
|
|
4
|
+
|
|
5
|
+
A process update is a change to one of the other skills in the methodology, made in response to findings from measurement or root cause analysis. It is the mechanism by which the methodology learns.
|
|
6
|
+
|
|
7
|
+
Without process updates, the methodology is static. It will produce the same outcomes forever — including the same failures. Process updates close the loop.
|
|
8
|
+
|
|
9
|
+
## When to Make a Process Update
|
|
10
|
+
|
|
11
|
+
Not every finding warrants a change. Changes add complexity. Unnecessary complexity degrades the process just as surely as missing checks do.
|
|
12
|
+
|
|
13
|
+
### Change if:
|
|
14
|
+
|
|
15
|
+
- A root cause analysis identified a specific gap in a skill — a missing check, a missing signal, an insufficient prompt
|
|
16
|
+
- A measurement signal was 🔴 for two consecutive releases (common cause — the system is producing this outcome consistently)
|
|
17
|
+
- A root cause analysis identified a new class of risk the methodology has no check for
|
|
18
|
+
|
|
19
|
+
### Do NOT change if:
|
|
20
|
+
|
|
21
|
+
- A measurement signal was 🔴 once but recovered the next release (likely special cause — addressed by the specific root cause fix, not a systemic change)
|
|
22
|
+
- The finding is about team behavior, not process structure ("the team should be more careful" is not a process update)
|
|
23
|
+
- The proposed change would add a step that every feature must go through, but the problem only affects rare edge cases (the cost of the check exceeds the cost of the occasional failure)
|
|
24
|
+
|
|
25
|
+
## How to Decide What Changes
|
|
26
|
+
|
|
27
|
+
### Step 1: Locate the Gap
|
|
28
|
+
|
|
29
|
+
The root cause analysis already points to a specific skill and a specific gap. Confirm by reading the relevant skill file. The gap will be one of these types:
|
|
30
|
+
|
|
31
|
+
**Missing check:** The skill does not require verification at a point where a problem can be caught. Fix: add the check.
|
|
32
|
+
|
|
33
|
+
**Insufficient prompt:** The skill requires a check but does not ask the right questions. Fix: add specificity to the prompt or checklist.
|
|
34
|
+
|
|
35
|
+
**Missing signal:** The measurement report does not track something that would have revealed this problem earlier. Fix: add the signal to measurement.md.
|
|
36
|
+
|
|
37
|
+
**Wrong ordering:** The skill requires a check but at a point too late in the process to prevent the cost. Fix: move the check earlier.
|
|
38
|
+
|
|
39
|
+
### Step 2: Scope the Change
|
|
40
|
+
|
|
41
|
+
Before changing anything, state precisely:
|
|
42
|
+
- What file changes
|
|
43
|
+
- What line or section changes
|
|
44
|
+
- What is added, removed, or modified
|
|
45
|
+
- What the change prevents that was not previously prevented
|
|
46
|
+
|
|
47
|
+
A process update should be surgical. If the change requires rewriting an entire reference file, the scope is wrong — narrow it.
|
|
48
|
+
|
|
49
|
+
### Step 3: Apply the Change
|
|
50
|
+
|
|
51
|
+
Edit the skill directly. The skills live in the repository alongside the product code. A process update is a commit just like any other.
|
|
52
|
+
|
|
53
|
+
**Commit convention for process updates:**
|
|
54
|
+
```
|
|
55
|
+
chore(continuous-improvement): [brief description of what changed and why]
|
|
56
|
+
|
|
57
|
+
Example:
|
|
58
|
+
chore(continuous-improvement): add numeric field constraint check to example mapping
|
|
59
|
+
|
|
60
|
+
Root cause: RCA-2024-03 found that example mapping does not surface
|
|
61
|
+
numeric validation rules. Added explicit prompt for min/max/zero
|
|
62
|
+
constraints on all numeric fields.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Step 4: Validate the Change Worked
|
|
66
|
+
|
|
67
|
+
This is the most important step and the most commonly skipped. A change that is never validated is just a guess that was written down.
|
|
68
|
+
|
|
69
|
+
**How to validate:**
|
|
70
|
+
- Define the validation criterion before making the change: "In the next release, if a numeric field exists, the example mapping will have documented its constraints."
|
|
71
|
+
- After the next release, check whether the criterion was met.
|
|
72
|
+
- If met: the fix worked. Close the loop.
|
|
73
|
+
- If not met: the fix was insufficient. Re-investigate. This is not failure — it is the loop working as designed.
|
|
74
|
+
|
|
75
|
+
**Record validation in the root cause analysis document.** Update the "Applied" checkbox and add a note under Validation with the result.
|
|
76
|
+
|
|
77
|
+
## Types of Process Updates
|
|
78
|
+
|
|
79
|
+
### Adding a Checklist Item
|
|
80
|
+
|
|
81
|
+
The most common update. A check that should exist does not.
|
|
82
|
+
|
|
83
|
+
**Example:** Root cause analysis found that example mapping does not ask about numeric field constraints. The fix is to add an item to the example mapping checklist in `bdd-specification/references/example-mapping.md`.
|
|
84
|
+
|
|
85
|
+
**How to apply:** Find the checklist or prompt section in the relevant reference. Add the item. Keep it specific — "What values are invalid for this field?" not "Check for edge cases."
|
|
86
|
+
|
|
87
|
+
### Adding a Measurement Signal
|
|
88
|
+
|
|
89
|
+
A problem was not visible in measurement because nothing was tracking it.
|
|
90
|
+
|
|
91
|
+
**Example:** Root cause analysis found that design rework after implementation began was not being tracked. The fix is to add Signal 6 (Rework after screen flows designed) to `continuous-improvement/references/measurement.md`.
|
|
92
|
+
|
|
93
|
+
**How to apply:** Add the signal to measurement.md with: what it measures, where to find it, and what the healthy range is.
|
|
94
|
+
|
|
95
|
+
### Strengthening an Evaluation
|
|
96
|
+
|
|
97
|
+
An evaluation exists but is not catching a class of problem it should catch.
|
|
98
|
+
|
|
99
|
+
**Example:** Usability evaluation consistently misses state transition issues. The fix is to add a specific check for state visibility and transition feedback to the heuristic H1 section in `ux-design/references/usability-evaluation.md`.
|
|
100
|
+
|
|
101
|
+
**How to apply:** Find the relevant heuristic. Add a specific check question that would have caught the missed problem.
|
|
102
|
+
|
|
103
|
+
### Moving a Check Earlier
|
|
104
|
+
|
|
105
|
+
A check exists but fires too late — after the cost of the problem has already grown.
|
|
106
|
+
|
|
107
|
+
**Example:** Mental model conflicts are being discovered during implementation rather than during ux-design. The fix is to add a mental model consistency check to the scenario validation step in `bdd-specification/SKILL.md` — scenarios are checked against mental models before they reach ux-design.
|
|
108
|
+
|
|
109
|
+
**How to apply:** Add the check to the earlier skill's workflow. Update the later skill's input assumptions to reflect that this check has already been performed.
|
|
110
|
+
|
|
111
|
+
## Rules
|
|
112
|
+
|
|
113
|
+
- Every process update traces back to a specific root cause analysis or a specific measurement pattern. No speculative changes.
|
|
114
|
+
- Changes are small and surgical. One fix per commit.
|
|
115
|
+
- Every change has a defined validation criterion. Without it, the change is not applied.
|
|
116
|
+
- Process updates are reviewed by reading the changed skill end-to-end after the change. Ensure the change does not conflict with or duplicate anything else in the skill.
|
|
117
|
+
- If a process update would affect how two or more skills interact, update both skills and document the dependency in both.
|
|
118
|
+
- The methodology is the team's shared tool. A process update that makes the methodology better for one person but harder for others is not a good update. Discuss before applying.
|