mandrel 1.92.0 → 1.94.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.
Files changed (144) hide show
  1. package/.agents/agents/acceptance-critic.md +129 -0
  2. package/.agents/agents/retro.md +42 -0
  3. package/.agents/agents/story-worker.md +162 -0
  4. package/.agents/docs/configuration.md +7 -1
  5. package/.agents/docs/execution-reference.md +27 -2
  6. package/.agents/instructions.md +43 -33
  7. package/.agents/personas/engineer.md +26 -112
  8. package/.agents/personas/security-engineer.md +1 -2
  9. package/.agents/rules/git-conventions-reference.md +225 -0
  10. package/.agents/rules/git-conventions.md +25 -200
  11. package/.agents/rules/security-baseline.md +5 -0
  12. package/.agents/rules/testing-standards.md +106 -13
  13. package/.agents/schemas/agentrc.schema.json +31 -1
  14. package/.agents/schemas/lifecycle/slice.end.schema.json +21 -0
  15. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +20 -0
  16. package/.agents/schemas/lifecycle/slice.start.schema.json +17 -0
  17. package/.agents/scripts/acceptance-eval.js +62 -18
  18. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  19. package/.agents/scripts/bookkeeping-reconcile.js +117 -0
  20. package/.agents/scripts/check-context-budget.js +62 -5
  21. package/.agents/scripts/diagnose-friction.js +0 -6
  22. package/.agents/scripts/epic-deliver-prepare.js +272 -10
  23. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +56 -18
  24. package/.agents/scripts/lib/close-validation/gates.js +159 -21
  25. package/.agents/scripts/lib/config/acceptance-eval.js +52 -5
  26. package/.agents/scripts/lib/config/delivery-routing.js +87 -0
  27. package/.agents/scripts/lib/config/explain.js +2 -0
  28. package/.agents/scripts/lib/config-resolver.js +1 -1
  29. package/.agents/scripts/lib/config-settings-schema-delivery.js +37 -3
  30. package/.agents/scripts/lib/config-settings-schema-quality.js +9 -0
  31. package/.agents/scripts/lib/doc-tiers.js +37 -2
  32. package/.agents/scripts/lib/observability/active-story-env.js +111 -2
  33. package/.agents/scripts/lib/observability/hook-heartbeat.js +219 -0
  34. package/.agents/scripts/lib/observability/tool-trace-hook.js +15 -4
  35. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +111 -0
  36. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +32 -4
  37. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +270 -0
  38. package/.agents/scripts/lib/orchestration/ceremony-routing.js +141 -0
  39. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +3 -124
  40. package/.agents/scripts/lib/orchestration/deliver-route.js +173 -0
  41. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +1 -1
  42. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +233 -0
  43. package/.agents/scripts/lib/orchestration/file-assumptions.js +68 -7
  44. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +270 -0
  45. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +83 -2
  46. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +6 -0
  47. package/.agents/scripts/lib/orchestration/plan-context.js +189 -3
  48. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +3 -2
  49. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +99 -0
  50. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +38 -1
  51. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +16 -1
  52. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +1 -0
  53. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +1 -0
  54. package/.agents/scripts/lib/orchestration/ticket-validator.js +19 -2
  55. package/.agents/scripts/lib/provider-factory.js +1 -1
  56. package/.agents/scripts/lib/templates/decomposer-prompts.js +1 -1
  57. package/.agents/scripts/plan-context.js +28 -10
  58. package/.agents/scripts/post-structured-comment.js +38 -0
  59. package/.agents/scripts/slice-phase.js +361 -0
  60. package/.agents/scripts/sync-claude-agents.js +165 -0
  61. package/.agents/scripts/update-ticket-state.js +31 -0
  62. package/.agents/scripts/wave-tick.js +138 -9
  63. package/.agents/skills/core/api-and-interface-design/SKILL.md +5 -3
  64. package/.agents/skills/core/code-review-and-quality/SKILL.md +63 -7
  65. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +1 -1
  66. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +5 -5
  67. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +8 -8
  68. package/.agents/skills/core/epic-plan-premortem/SKILL.md +4 -4
  69. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +26 -56
  70. package/.agents/skills/core/gates-and-baselines/SKILL.md +149 -0
  71. package/.agents/skills/core/idea-refinement/SKILL.md +2 -8
  72. package/.agents/skills/core/qa-coverage-mapping/SKILL.md +7 -7
  73. package/.agents/skills/skills.index.json +11 -381
  74. package/.agents/workflows/deliver.md +47 -4
  75. package/.agents/workflows/helpers/acceptance-self-eval.md +38 -13
  76. package/.agents/workflows/helpers/deliver-epic-reference.md +18 -5
  77. package/.agents/workflows/helpers/deliver-epic-single.md +331 -0
  78. package/.agents/workflows/helpers/deliver-epic.md +51 -8
  79. package/.agents/workflows/helpers/deliver-stories.md +15 -5
  80. package/.agents/workflows/helpers/epic-deliver-story.md +12 -3
  81. package/.agents/workflows/helpers/mandrel-sync-config.md +1 -1
  82. package/.agents/workflows/helpers/plan-epic-reference.md +19 -8
  83. package/.agents/workflows/helpers/plan-epic.md +95 -27
  84. package/.agents/workflows/helpers/scope-triage-gate.md +9 -0
  85. package/.agents/workflows/mandrel-update.md +1 -1
  86. package/.agents/workflows/plan.md +16 -4
  87. package/docs/CHANGELOG.md +23 -0
  88. package/lib/cli/registry.js +95 -0
  89. package/package.json +4 -2
  90. package/.agents/personas/engineer-mobile.md +0 -120
  91. package/.agents/personas/engineer-web.md +0 -111
  92. package/.agents/personas/product.md +0 -94
  93. package/.agents/personas/refactorer.md +0 -113
  94. package/.agents/personas/sre.md +0 -86
  95. package/.agents/personas/ux-designer.md +0 -95
  96. package/.agents/scripts/epic-plan-decompose.js +0 -54
  97. package/.agents/scripts/epic-plan-spec.js +0 -64
  98. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +0 -109
  99. package/.agents/scripts/plan-critics.js +0 -227
  100. package/.agents/skills/core/baseline-refresh/SKILL.md +0 -181
  101. package/.agents/skills/core/ci-cd-and-automation/SKILL.md +0 -274
  102. package/.agents/skills/core/ci-cd-and-automation/examples.md +0 -211
  103. package/.agents/skills/core/code-simplification/SKILL.md +0 -389
  104. package/.agents/skills/core/context-engineering/SKILL.md +0 -309
  105. package/.agents/skills/core/context-engineering/examples.md +0 -58
  106. package/.agents/skills/core/deprecation-and-migration/SKILL.md +0 -250
  107. package/.agents/skills/core/frontend-ui-engineering/SKILL.md +0 -357
  108. package/.agents/skills/core/hydrate-context/SKILL.md +0 -123
  109. package/.agents/skills/core/idea-refinement/examples.md +0 -437
  110. package/.agents/skills/core/idea-refinement/frameworks.md +0 -135
  111. package/.agents/skills/core/incremental-implementation/SKILL.md +0 -271
  112. package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +0 -213
  113. package/.agents/skills/core/knowledge-transfer/SKILL.md +0 -180
  114. package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +0 -117
  115. package/.agents/skills/core/performance-optimization/SKILL.md +0 -314
  116. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +0 -277
  117. package/.agents/skills/core/property-based-testing/SKILL.md +0 -148
  118. package/.agents/skills/core/refactoring-discipline/SKILL.md +0 -111
  119. package/.agents/skills/core/shipping-and-launch/SKILL.md +0 -328
  120. package/.agents/skills/core/spec-driven-development/SKILL.md +0 -252
  121. package/.agents/skills/core/test-driven-development/SKILL.md +0 -475
  122. package/.agents/skills/core/using-agent-skills/SKILL.md +0 -232
  123. package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +0 -31
  124. package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +0 -51
  125. package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +0 -76
  126. package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +0 -31
  127. package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +0 -33
  128. package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +0 -31
  129. package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +0 -51
  130. package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +0 -54
  131. package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +0 -29
  132. package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +0 -30
  133. package/.agents/skills/stack/backend/stripe-integration/SKILL.md +0 -57
  134. package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +0 -9
  135. package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +0 -48
  136. package/.agents/skills/stack/frontend/astro/SKILL.md +0 -62
  137. package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +0 -30
  138. package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +0 -29
  139. package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +0 -50
  140. package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +0 -58
  141. package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +0 -34
  142. package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +0 -51
  143. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +0 -199
  144. package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +0 -68
@@ -1,211 +0,0 @@
1
- # CI/CD and Automation — Examples
2
-
3
- Long stack-specific snippets extracted from `SKILL.md` so the skill stays
4
- focused on policy and routing. The samples below assume GitHub Actions plus
5
- Node 22 / npm; adapt to your project's runner, package manager, and language.
6
-
7
- ---
8
-
9
- ## GitHub Actions: Basic CI Pipeline
10
-
11
- ```yaml
12
- # .github/workflows/ci.yml
13
- name: CI
14
-
15
- on:
16
- pull_request:
17
- branches: [main]
18
- push:
19
- branches: [main]
20
-
21
- jobs:
22
- quality:
23
- runs-on: ubuntu-latest
24
- steps:
25
- - uses: actions/checkout@v4
26
-
27
- - uses: actions/setup-node@v4
28
- with:
29
- node-version: '22'
30
- cache: 'npm'
31
-
32
- - name: Install dependencies
33
- run: npm ci
34
-
35
- - name: Lint
36
- run: npm run lint
37
-
38
- - name: Type check
39
- run: npx tsc --noEmit
40
-
41
- - name: Test
42
- run: npm test -- --coverage
43
-
44
- - name: Build
45
- run: npm run build
46
-
47
- - name: Security audit
48
- run: npm audit --audit-level=high
49
- ```
50
-
51
- ## GitHub Actions: With Database Integration Tests
52
-
53
- ```yaml
54
- integration:
55
- runs-on: ubuntu-latest
56
- services:
57
- postgres:
58
- image: postgres:16
59
- env:
60
- POSTGRES_DB: testdb
61
- POSTGRES_USER: ci_user
62
- POSTGRES_PASSWORD: ${{ secrets.CI_DB_PASSWORD }}
63
- ports:
64
- - 5432:5432
65
- options: >-
66
- --health-cmd pg_isready --health-interval 10s --health-timeout 5s
67
- --health-retries 5
68
-
69
- steps:
70
- - uses: actions/checkout@v4
71
- - uses: actions/setup-node@v4
72
- with:
73
- node-version: '22'
74
- cache: 'npm'
75
- - run: npm ci
76
- - name: Run migrations
77
- run: npx prisma migrate deploy
78
- env:
79
- DATABASE_URL:
80
- postgresql://ci_user:${{ secrets.CI_DB_PASSWORD
81
- }}@localhost:5432/testdb
82
- - name: Integration tests
83
- run: npm run test:integration
84
- env:
85
- DATABASE_URL:
86
- postgresql://ci_user:${{ secrets.CI_DB_PASSWORD
87
- }}@localhost:5432/testdb
88
- ```
89
-
90
- > **Note:** Even for CI-only test databases, use GitHub Secrets for credentials
91
- > rather than hardcoding values. This builds good habits and prevents accidental
92
- > reuse of test credentials in other contexts.
93
-
94
- ## GitHub Actions: E2E Tests
95
-
96
- ```yaml
97
- e2e:
98
- runs-on: ubuntu-latest
99
- steps:
100
- - uses: actions/checkout@v4
101
- - uses: actions/setup-node@v4
102
- with:
103
- node-version: '22'
104
- cache: 'npm'
105
- - run: npm ci
106
- - name: Install Playwright
107
- run: npx playwright install --with-deps chromium
108
- - name: Build
109
- run: npm run build
110
- - name: Run E2E tests
111
- run: npx playwright test
112
- - uses: actions/upload-artifact@v4
113
- if: failure()
114
- with:
115
- name: playwright-report
116
- path: playwright-report/
117
- ```
118
-
119
- ## Deployment: Preview on PR
120
-
121
- ```yaml
122
- # Deploy preview on PR (Vercel/Netlify/etc.)
123
- deploy-preview:
124
- runs-on: ubuntu-latest
125
- if: github.event_name == 'pull_request'
126
- steps:
127
- - uses: actions/checkout@v4
128
- - name: Deploy preview
129
- run: npx vercel --token=${{ secrets.VERCEL_TOKEN }}
130
- ```
131
-
132
- ## Deployment: Manual Rollback Workflow
133
-
134
- ```yaml
135
- # Manual rollback workflow
136
- name: Rollback
137
- on:
138
- workflow_dispatch:
139
- inputs:
140
- version:
141
- description: 'Version to rollback to'
142
- required: true
143
-
144
- jobs:
145
- rollback:
146
- runs-on: ubuntu-latest
147
- steps:
148
- - name: Rollback deployment
149
- run: |
150
- # Deploy the specified previous version
151
- npx vercel rollback ${{ inputs.version }}
152
- ```
153
-
154
- ## Caching and Parallelism
155
-
156
- ```yaml
157
- jobs:
158
- lint:
159
- runs-on: ubuntu-latest
160
- steps:
161
- - uses: actions/checkout@v4
162
- - uses: actions/setup-node@v4
163
- with: { node-version: '22', cache: 'npm' }
164
- - run: npm ci
165
- - run: npm run lint
166
-
167
- typecheck:
168
- runs-on: ubuntu-latest
169
- steps:
170
- - uses: actions/checkout@v4
171
- - uses: actions/setup-node@v4
172
- with: { node-version: '22', cache: 'npm' }
173
- - run: npm ci
174
- - run: npx tsc --noEmit
175
-
176
- test:
177
- runs-on: ubuntu-latest
178
- steps:
179
- - uses: actions/checkout@v4
180
- - uses: actions/setup-node@v4
181
- with: { node-version: '22', cache: 'npm' }
182
- - run: npm ci
183
- - run: npm test -- --coverage
184
- ```
185
-
186
- ## Dependency Updates: Dependabot
187
-
188
- ```yaml
189
- # .github/dependabot.yml
190
- version: 2
191
- updates:
192
- - package-ecosystem: npm
193
- directory: /
194
- schedule:
195
- interval: weekly
196
- open-pull-requests-limit: 5
197
- ```
198
-
199
- ## Feature Flag Pattern
200
-
201
- ```typescript
202
- // Simple feature flag pattern
203
- if (featureFlags.isEnabled('new-checkout-flow', { userId })) {
204
- return renderNewCheckout();
205
- }
206
- return renderLegacyCheckout();
207
- ```
208
-
209
- **Flag lifecycle:** Create → Enable for testing → Canary → Full rollout →
210
- Remove the flag and dead code. Flags that live forever become technical debt —
211
- set a cleanup date when you create them.
@@ -1,389 +0,0 @@
1
- ---
2
- name: code-simplification
3
- description:
4
- Simplifies code for clarity. Use when refactoring code for clarity without
5
- changing behavior. Use when code works but is harder to read, maintain, or
6
- extend than it should be. Use when reviewing code that has accumulated
7
- unnecessary complexity.
8
- ---
9
-
10
- # Code Simplification
11
-
12
- ## Policy Capsule
13
-
14
- - Preserve behaviour **exactly**: inputs, outputs, side effects, error semantics, and ordering must be identical. If you're not sure a change preserves behaviour, don't make it.
15
- - Every simplification MUST leave existing tests passing without modification; if tests need to change, the refactor changed behaviour and is no longer a simplification.
16
- - Follow project conventions (CLAUDE.md, neighbour-code patterns, import style, naming, error handling). Simplification that breaks consistency is churn, not improvement.
17
- - Prefer clarity over cleverness: explicit code beats compact code whenever the compact form requires a mental pause to parse.
18
- - Comprehend before you simplify — never refactor code you don't yet fully understand.
19
- - Do not simplify for its own sake: skip when code is already clean, when performance would measurably regress, or when the module is about to be rewritten.
20
- - Lines-of-code is **not** the goal. The metric is "would a new team member understand this faster than the original?".
21
- - Make each simplification an isolated commit, not a drive-by inside a feature change (see `git-workflow-and-versioning`).
22
- - Verify behaviourally: run the full test suite, exercise affected paths, and diff the runtime output against the original before claiming the simplification is safe.
23
-
24
- > Inspired by the
25
- > [Claude Code Simplifier plugin](https://github.com/anthropics/claude-plugins-official/blob/main/plugins/code-simplifier/agents/code-simplifier.md).
26
- > Adapted here as a model-agnostic, process-driven skill for any AI coding
27
- > agent.
28
-
29
- ## Overview
30
-
31
- Simplify code by reducing complexity while preserving exact behavior. The goal
32
- is not fewer lines — it's code that is easier to read, understand, modify, and
33
- debug. Every simplification must pass a simple test: "Would a new team member
34
- understand this faster than the original?"
35
-
36
- ## When to Use
37
-
38
- - After a feature is working and tests pass, but the implementation feels
39
- heavier than it needs to be
40
- - During code review when readability or complexity issues are flagged
41
- - When you encounter deeply nested logic, long functions, or unclear names
42
- - When refactoring code written under time pressure
43
- - When consolidating related logic scattered across files
44
- - After merging changes that introduced duplication or inconsistency
45
-
46
- **When NOT to use:**
47
-
48
- - Code is already clean and readable — don't simplify for the sake of it
49
- - You don't understand what the code does yet — comprehend before you simplify
50
- - The code is performance-critical and the "simpler" version would be measurably
51
- slower
52
- - You're about to rewrite the module entirely — simplifying throwaway code
53
- wastes effort
54
-
55
- ## The Five Principles
56
-
57
- ### 1. Preserve Behavior Exactly
58
-
59
- Don't change what the code does — only how it expresses it. All inputs, outputs,
60
- side effects, error behavior, and edge cases must remain identical. If you're
61
- not sure a simplification preserves behavior, don't make it.
62
-
63
- ```text
64
- ASK BEFORE EVERY CHANGE:
65
- → Does this produce the same output for every input?
66
- → Does this maintain the same error behavior?
67
- → Does this preserve the same side effects and ordering?
68
- → Do all existing tests still pass without modification?
69
- ```
70
-
71
- ### 2. Follow Project Conventions
72
-
73
- Simplification means making code more consistent with the codebase, not imposing
74
- external preferences. Before simplifying:
75
-
76
- ```text
77
- 1. Read CLAUDE.md / project conventions
78
- 2. Study how neighboring code handles similar patterns
79
- 3. Match the project's style for:
80
- - Import ordering and module system
81
- - Function declaration style
82
- - Naming conventions
83
- - Error handling patterns
84
- - Type annotation depth
85
- ```
86
-
87
- Simplification that breaks project consistency is not simplification — it's
88
- churn.
89
-
90
- ### 3. Prefer Clarity Over Cleverness
91
-
92
- Explicit code is better than compact code when the compact version requires a
93
- mental pause to parse.
94
-
95
- ```typescript
96
- // UNCLEAR: Dense ternary chain
97
- const label = isNew
98
- ? 'New'
99
- : isUpdated
100
- ? 'Updated'
101
- : isArchived
102
- ? 'Archived'
103
- : 'Active';
104
-
105
- // CLEAR: Readable mapping
106
- function getStatusLabel(item: Item): string {
107
- if (item.isNew) return 'New';
108
- if (item.isUpdated) return 'Updated';
109
- if (item.isArchived) return 'Archived';
110
- return 'Active';
111
- }
112
- ```
113
-
114
- ```typescript
115
- // UNCLEAR: Chained reduces with inline logic
116
- const result = items.reduce(
117
- (acc, item) => ({
118
- ...acc,
119
- [item.id]: { ...acc[item.id], count: (acc[item.id]?.count ?? 0) + 1 },
120
- }),
121
- {},
122
- );
123
-
124
- // CLEAR: Named intermediate step
125
- const countById = new Map<string, number>();
126
- for (const item of items) {
127
- countById.set(item.id, (countById.get(item.id) ?? 0) + 1);
128
- }
129
- ```
130
-
131
- ### 4. Maintain Balance
132
-
133
- Simplification has a failure mode: over-simplification. Watch for these traps:
134
-
135
- - **Inlining too aggressively** — removing a helper that gave a concept a name
136
- makes the call site harder to read
137
- - **Combining unrelated logic** — two simple functions merged into one complex
138
- function is not simpler
139
- - **Removing "unnecessary" abstraction** — some abstractions exist for
140
- extensibility or testability, not complexity
141
- - **Optimizing for line count** — fewer lines is not the goal; easier
142
- comprehension is
143
-
144
- ### 5. Scope to What Changed
145
-
146
- Default to simplifying recently modified code. Avoid drive-by refactors of
147
- unrelated code unless explicitly asked to broaden scope. Unscoped simplification
148
- creates noise in diffs and risks unintended regressions.
149
-
150
- ## The Simplification Process
151
-
152
- ### Step 1: Understand Before Touching (Chesterton's Fence)
153
-
154
- Before changing or removing anything, understand why it exists. This is
155
- Chesterton's Fence: if you see a fence across a road and don't understand why
156
- it's there, don't tear it down. First understand the reason, then decide if the
157
- reason still applies.
158
-
159
- ```text
160
- BEFORE SIMPLIFYING, ANSWER:
161
- - What is this code's responsibility?
162
- - What calls it? What does it call?
163
- - What are the edge cases and error paths?
164
- - Are there tests that define the expected behavior?
165
- - Why might it have been written this way? (Performance? Platform constraint? Historical reason?)
166
- - Check git blame: what was the original context for this code?
167
- ```
168
-
169
- If you can't answer these, you're not ready to simplify. Read more context
170
- first.
171
-
172
- ### Step 2: Identify Simplification Opportunities
173
-
174
- Scan for these patterns — each one is a concrete signal, not a vague smell:
175
-
176
- **Structural complexity:**
177
-
178
- | Pattern | Signal | Simplification |
179
- | -------------------------- | ---------------------------------- | --------------------------------------------------------- |
180
- | Deep nesting (3+ levels) | Hard to follow control flow | Extract conditions into guard clauses or helper functions |
181
- | Long functions (50+ lines) | Multiple responsibilities | Split into focused functions with descriptive names |
182
- | Nested ternaries | Requires mental stack to parse | Replace with if/else chains, switch, or lookup objects |
183
- | Boolean parameter flags | `doThing(true, false, true)` | Replace with options objects or separate functions |
184
- | Repeated conditionals | Same `if` check in multiple places | Extract to a well-named predicate function |
185
-
186
- **Naming and readability:**
187
-
188
- | Pattern | Signal | Simplification |
189
- | -------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------ |
190
- | Generic names | `data`, `result`, `temp`, `val`, `item` | Rename to describe the content: `userProfile`, `validationErrors` |
191
- | Abbreviated names | `usr`, `cfg`, `btn`, `evt` | Use full words unless the abbreviation is universal (`id`, `url`, `api`) |
192
- | Misleading names | Function named `get` that also mutates state | Rename to reflect actual behavior |
193
- | Comments explaining "what" | `// increment counter` above `count++` | Delete the comment — the code is clear enough |
194
- | Comments explaining "why" | `// Retry because the API is flaky under load` | Keep these — they carry intent the code can't express |
195
-
196
- **Redundancy:**
197
-
198
- | Pattern | Signal | Simplification |
199
- | ------------------------- | ------------------------------------------------------------ | --------------------------------------------------------- |
200
- | Duplicated logic | Same 5+ lines in multiple places | Extract to a shared function |
201
- | Dead code | Unreachable branches, unused variables, commented-out blocks | Remove (after confirming it's truly dead) |
202
- | Unnecessary abstractions | Wrapper that adds no value | Inline the wrapper, call the underlying function directly |
203
- | Over-engineered patterns | Factory-for-a-factory, strategy-with-one-strategy | Replace with the simple direct approach |
204
- | Redundant type assertions | Casting to a type that's already inferred | Remove the assertion |
205
-
206
- ### Step 3: Apply Changes Incrementally
207
-
208
- Make one simplification at a time. Run tests after each change. **Submit
209
- refactoring changes separately from feature or bug fix changes.** A PR that
210
- refactors and adds a feature is two PRs — split them.
211
-
212
- ```text
213
- FOR EACH SIMPLIFICATION:
214
- 1. Make the change
215
- 2. Run the test suite
216
- 3. If tests pass → commit (or continue to next simplification)
217
- 4. If tests fail → revert and reconsider
218
- ```
219
-
220
- Avoid batching multiple simplifications into a single untested change. If
221
- something breaks, you need to know which simplification caused it.
222
-
223
- **The Rule of 500:** If a refactoring would touch more than 500 lines, invest in
224
- automation (codemods, sed scripts, AST transforms) rather than making the
225
- changes by hand. Manual edits at that scale are error-prone and exhausting to
226
- review.
227
-
228
- ### Step 4: Verify the Result
229
-
230
- After all simplifications, step back and evaluate the whole:
231
-
232
- ```text
233
- COMPARE BEFORE AND AFTER:
234
- - Is the simplified version genuinely easier to understand?
235
- - Did you introduce any new patterns inconsistent with the codebase?
236
- - Is the diff clean and reviewable?
237
- - Would a teammate approve this change?
238
- ```
239
-
240
- If the "simplified" version is harder to understand or review, revert. Not every
241
- simplification attempt succeeds.
242
-
243
- ## Language-Specific Guidance
244
-
245
- ### TypeScript / JavaScript
246
-
247
- ```typescript
248
- // SIMPLIFY: Unnecessary async wrapper
249
- // Before
250
- async function getUser(id: string): Promise<User> {
251
- return await userService.findById(id);
252
- }
253
- // After
254
- function getUser(id: string): Promise<User> {
255
- return userService.findById(id);
256
- }
257
-
258
- // SIMPLIFY: Verbose conditional assignment
259
- // Before
260
- let displayName: string;
261
- if (user.nickname) {
262
- displayName = user.nickname;
263
- } else {
264
- displayName = user.fullName;
265
- }
266
- // After
267
- const displayName = user.nickname || user.fullName;
268
-
269
- // SIMPLIFY: Manual array building
270
- // Before
271
- const activeUsers: User[] = [];
272
- for (const user of users) {
273
- if (user.isActive) {
274
- activeUsers.push(user);
275
- }
276
- }
277
- // After
278
- const activeUsers = users.filter((user) => user.isActive);
279
-
280
- // SIMPLIFY: Redundant boolean return
281
- // Before
282
- function isValid(input: string): boolean {
283
- if (input.length > 0 && input.length < 100) {
284
- return true;
285
- }
286
- return false;
287
- }
288
- // After
289
- function isValid(input: string): boolean {
290
- return input.length > 0 && input.length < 100;
291
- }
292
- ```
293
-
294
- ### Python
295
-
296
- ```python
297
- # SIMPLIFY: Verbose dictionary building
298
- # Before
299
- result = {}
300
- for item in items:
301
- result[item.id] = item.name
302
- # After
303
- result = {item.id: item.name for item in items}
304
-
305
- # SIMPLIFY: Nested conditionals with early return
306
- # Before
307
- def process(data):
308
- if data is not None:
309
- if data.is_valid():
310
- if data.has_permission():
311
- return do_work(data)
312
- else:
313
- raise PermissionError("No permission")
314
- else:
315
- raise ValueError("Invalid data")
316
- else:
317
- raise TypeError("Data is None")
318
- # After
319
- def process(data):
320
- if data is None:
321
- raise TypeError("Data is None")
322
- if not data.is_valid():
323
- raise ValueError("Invalid data")
324
- if not data.has_permission():
325
- raise PermissionError("No permission")
326
- return do_work(data)
327
- ```
328
-
329
- ### React / JSX
330
-
331
- ```tsx
332
- // SIMPLIFY: Verbose conditional rendering
333
- // Before
334
- function UserBadge({ user }: Props) {
335
- if (user.isAdmin) {
336
- return <Badge variant="admin">Admin</Badge>;
337
- } else {
338
- return <Badge variant="default">User</Badge>;
339
- }
340
- }
341
- // After
342
- function UserBadge({ user }: Props) {
343
- const variant = user.isAdmin ? 'admin' : 'default';
344
- const label = user.isAdmin ? 'Admin' : 'User';
345
- return <Badge variant={variant}>{label}</Badge>;
346
- }
347
-
348
- // SIMPLIFY: Prop drilling through intermediate components
349
- // Before — consider whether context or composition solves this better.
350
- // This is a judgment call — flag it, don't auto-refactor.
351
- ```
352
-
353
- ## Common Rationalizations
354
-
355
- | Rationalization | Reality |
356
- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
357
- | "It's working, no need to touch it" | Working code that's hard to read will be hard to fix when it breaks. Simplifying now saves time on every future change. |
358
- | "Fewer lines is always simpler" | A 1-line nested ternary is not simpler than a 5-line if/else. Simplicity is about comprehension speed, not line count. |
359
- | "I'll just quickly simplify this unrelated code too" | Unscoped simplification creates noisy diffs and risks regressions in code you didn't intend to change. Stay focused. |
360
- | "The types make it self-documenting" | Types document structure, not intent. A well-named function explains _why_ better than a type signature explains _what_. |
361
- | "This abstraction might be useful later" | Don't preserve speculative abstractions. If it's not used now, it's complexity without value. Remove it and re-add when needed. |
362
- | "The original author must have had a reason" | Maybe. Check git blame — apply Chesterton's Fence. But accumulated complexity often has no reason; it's just the residue of iteration under pressure. |
363
- | "I'll refactor while adding this feature" | Separate refactoring from feature work. Mixed changes are harder to review, revert, and understand in history. |
364
-
365
- ## Red Flags
366
-
367
- - Simplification that requires modifying tests to pass (you likely changed
368
- behavior)
369
- - "Simplified" code that is longer and harder to follow than the original
370
- - Renaming things to match your preferences rather than project conventions
371
- - Removing error handling because "it makes the code cleaner"
372
- - Simplifying code you don't fully understand
373
- - Batching many simplifications into one large, hard-to-review commit
374
- - Refactoring code outside the scope of the current task without being asked
375
-
376
- ## Verification
377
-
378
- After completing a simplification pass:
379
-
380
- - [ ] All existing tests pass without modification
381
- - [ ] Build succeeds with no new warnings
382
- - [ ] Linter/formatter passes (no style regressions)
383
- - [ ] Each simplification is a reviewable, incremental change
384
- - [ ] The diff is clean — no unrelated changes mixed in
385
- - [ ] Simplified code follows project conventions (checked against CLAUDE.md or
386
- equivalent)
387
- - [ ] No error handling was removed or weakened
388
- - [ ] No dead code was left behind (unused imports, unreachable branches)
389
- - [ ] A teammate or review agent would approve the change as a net improvement