@martinffx/atelier 0.1.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 (130) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/LICENSE +21 -0
  3. package/README.md +285 -0
  4. package/agents/architect.md +38 -0
  5. package/agents/oracle.md +40 -0
  6. package/agents/recon.md +39 -0
  7. package/dist/atelier.js +33082 -0
  8. package/package.json +44 -0
  9. package/skills/code-conventional-commit/SKILL.md +134 -0
  10. package/skills/code-conventional-commit/evals/evals.json +23 -0
  11. package/skills/code-conventional-commit/workspace/iteration-1/eval-0/with_skill/outputs/commit-message.txt +4 -0
  12. package/skills/code-conventional-commit/workspace/iteration-1/eval-0/with_skill/outputs/eval_metadata.json +6 -0
  13. package/skills/code-conventional-commit/workspace/iteration-1/eval-1/with_skill/outputs/eval_metadata.json +6 -0
  14. package/skills/code-conventional-commit/workspace/iteration-1/eval-1/with_skill/outputs/validation-result.txt +16 -0
  15. package/skills/code-conventional-commit/workspace/iteration-1/eval-2/with_skill/outputs/commit-message.txt +8 -0
  16. package/skills/code-conventional-commit/workspace/iteration-1/eval-2/with_skill/outputs/eval_metadata.json +6 -0
  17. package/skills/code-conventional-commit/workspace/iteration-1/report.html +1325 -0
  18. package/skills/code-debug/SKILL.md +271 -0
  19. package/skills/code-debug/references/language-tools.md +139 -0
  20. package/skills/code-debug/references/techniques.md +117 -0
  21. package/skills/code-docs/SKILL.md +171 -0
  22. package/skills/code-docs/references/api-docs.md +116 -0
  23. package/skills/code-docs/references/changelog.md +64 -0
  24. package/skills/code-docs/references/readme-structure.md +94 -0
  25. package/skills/code-git-worktrees/SKILL.md +218 -0
  26. package/skills/code-perf/SKILL.md +163 -0
  27. package/skills/code-perf/references/common-bottlenecks.md +124 -0
  28. package/skills/code-perf/references/optimization-patterns.md +167 -0
  29. package/skills/code-perf/references/profiling-tools.md +126 -0
  30. package/skills/code-review/SKILL.md +78 -0
  31. package/skills/code-review/references/output.md +200 -0
  32. package/skills/code-review/references/reviewers.md +719 -0
  33. package/skills/code-review/references/rq.md +357 -0
  34. package/skills/code-review/references/rs.md +30 -0
  35. package/skills/code-security/SKILL.md +183 -0
  36. package/skills/code-security/references/owasp-top-10.md +129 -0
  37. package/skills/code-security/references/security-tools.md +102 -0
  38. package/skills/code-security/references/vulnerability-patterns.md +129 -0
  39. package/skills/code-stacked-commit/SKILL.md +155 -0
  40. package/skills/code-subagents/SKILL.md +184 -0
  41. package/skills/code-subagents/references/code-quality-reviewer-prompt.md +48 -0
  42. package/skills/code-subagents/references/implementor-prompt.md +79 -0
  43. package/skills/code-subagents/references/spec-reviewer-prompt.md +62 -0
  44. package/skills/oracle-architect/SKILL.md +246 -0
  45. package/skills/oracle-architect/references/api-design.md +345 -0
  46. package/skills/oracle-architect/references/data-modeling.md +318 -0
  47. package/skills/oracle-architect/references/ddd-patterns.md +247 -0
  48. package/skills/oracle-challenge/SKILL.md +126 -0
  49. package/skills/oracle-testing/SKILL.md +237 -0
  50. package/skills/oracle-testing/references/anti-patterns.md +618 -0
  51. package/skills/oracle-testing/references/boundaries.md +579 -0
  52. package/skills/oracle-testing/references/core-testing.md +691 -0
  53. package/skills/oracle-testing/references/edge-testing.md +794 -0
  54. package/skills/oracle-testing/references/stub-driven-tdd.md +322 -0
  55. package/skills/oracle-thinkdeep/SKILL.md +164 -0
  56. package/skills/python-architecture/SKILL.md +148 -0
  57. package/skills/python-architecture/references/data-modeling.md +558 -0
  58. package/skills/python-architecture/references/ddd.md +569 -0
  59. package/skills/python-architecture/references/functional-core.md +337 -0
  60. package/skills/python-build-tools/SKILL.md +153 -0
  61. package/skills/python-build-tools/references/basedpyright.md +321 -0
  62. package/skills/python-build-tools/references/ruff.md +225 -0
  63. package/skills/python-build-tools/references/uv.md +257 -0
  64. package/skills/python-fastapi/SKILL.md +184 -0
  65. package/skills/python-fastapi/references/api-design.md +563 -0
  66. package/skills/python-fastapi/references/dependencies.md +479 -0
  67. package/skills/python-fastapi/references/middleware.md +475 -0
  68. package/skills/python-fastapi/references/validation.md +497 -0
  69. package/skills/python-modern-python/SKILL.md +201 -0
  70. package/skills/python-modern-python/references/async.md +76 -0
  71. package/skills/python-modern-python/references/pattern-matching.md +89 -0
  72. package/skills/python-modern-python/references/typing.md +96 -0
  73. package/skills/python-monorepo/SKILL.md +146 -0
  74. package/skills/python-monorepo/references/docker.md +515 -0
  75. package/skills/python-monorepo/references/namespace-packages.md +426 -0
  76. package/skills/python-monorepo/references/workspace-config.md +341 -0
  77. package/skills/python-sqlalchemy/SKILL.md +119 -0
  78. package/skills/python-sqlalchemy/references/async.md +51 -0
  79. package/skills/python-sqlalchemy/references/models.md +67 -0
  80. package/skills/python-sqlalchemy/references/queries.md +57 -0
  81. package/skills/python-temporal/SKILL.md +128 -0
  82. package/skills/python-temporal/references/patterns.md +87 -0
  83. package/skills/python-temporal/references/testing.md +54 -0
  84. package/skills/python-testing/SKILL.md +161 -0
  85. package/skills/python-testing/references/boundaries.md +449 -0
  86. package/skills/python-testing/references/mocking.md +449 -0
  87. package/skills/python-testing/references/pytest.md +524 -0
  88. package/skills/spec-brainstorm/SKILL.md +325 -0
  89. package/skills/spec-finish/SKILL.md +159 -0
  90. package/skills/spec-implement/SKILL.md +296 -0
  91. package/skills/spec-orchestrator/SKILL.md +156 -0
  92. package/skills/spec-plan/SKILL.md +248 -0
  93. package/skills/typescript-api-design/SKILL.md +396 -0
  94. package/skills/typescript-api-design/references/error-responses.md +469 -0
  95. package/skills/typescript-build-tools/SKILL.md +447 -0
  96. package/skills/typescript-build-tools/references/biome.md +436 -0
  97. package/skills/typescript-build-tools/references/bun.md +432 -0
  98. package/skills/typescript-build-tools/references/turborepo.md +426 -0
  99. package/skills/typescript-build-tools/references/vitest.md +518 -0
  100. package/skills/typescript-drizzle-orm/SKILL.md +398 -0
  101. package/skills/typescript-drizzle-orm/references/cloudflare.md +392 -0
  102. package/skills/typescript-drizzle-orm/references/entity-pattern.md +412 -0
  103. package/skills/typescript-drizzle-orm/references/postgresql.md +191 -0
  104. package/skills/typescript-drizzle-orm/references/repository-pattern.md +479 -0
  105. package/skills/typescript-drizzle-orm/references/sqlite.md +291 -0
  106. package/skills/typescript-dynamodb-toolbox/SKILL.md +370 -0
  107. package/skills/typescript-dynamodb-toolbox/references/entity-layer.md +574 -0
  108. package/skills/typescript-dynamodb-toolbox/references/error-handling.md +495 -0
  109. package/skills/typescript-dynamodb-toolbox/references/modeling.md +332 -0
  110. package/skills/typescript-dynamodb-toolbox/references/repository-layer.md +631 -0
  111. package/skills/typescript-dynamodb-toolbox/references/testing.md +718 -0
  112. package/skills/typescript-dynamodb-toolbox/references/transactions.md +423 -0
  113. package/skills/typescript-effect-ts/SKILL.md +341 -0
  114. package/skills/typescript-effect-ts/references/core.md +412 -0
  115. package/skills/typescript-effect-ts/references/error-handling.md +468 -0
  116. package/skills/typescript-effect-ts/references/resources.md +476 -0
  117. package/skills/typescript-effect-ts/references/schema.md +536 -0
  118. package/skills/typescript-effect-ts/references/services.md +461 -0
  119. package/skills/typescript-fastify/SKILL.md +405 -0
  120. package/skills/typescript-fastify/references/plugins.md +329 -0
  121. package/skills/typescript-fastify/references/typeid.md +315 -0
  122. package/skills/typescript-functional-patterns/SKILL.md +402 -0
  123. package/skills/typescript-functional-patterns/references/adts.md +497 -0
  124. package/skills/typescript-functional-patterns/references/branded-types.md +542 -0
  125. package/skills/typescript-functional-patterns/references/migration-guide.md +695 -0
  126. package/skills/typescript-functional-patterns/references/option-result.md +585 -0
  127. package/skills/typescript-testing/SKILL.md +353 -0
  128. package/skills/typescript-testing/references/mocking.md +675 -0
  129. package/skills/typescript-testing/references/msw.md +852 -0
  130. package/skills/typescript-testing/references/snapshot-testing.md +774 -0
@@ -0,0 +1,402 @@
1
+ ---
2
+ name: typescript-functional-patterns
3
+ description: Functional programming patterns for reliable TypeScript. Use when modeling state machines, discriminated unions, Result/Option types, branded types, or building type-safe domain models.
4
+ user-invocable: false
5
+ ---
6
+
7
+ # Functional Patterns for Reliable TypeScript
8
+
9
+ Build reliable systems using Algebraic Data Types (ADTs), discriminated unions, Result/Option types, and branded types. These patterns enable the compiler to prove correctness, prevent runtime errors, and make illegal states unrepresentable.
10
+
11
+ ## Why Functional Patterns?
12
+
13
+ **Reliability through types**: Use the type system to encode business rules, making invalid states impossible to construct. The compiler becomes your safety net, catching errors at build time rather than runtime.
14
+
15
+ **Key benefits:**
16
+ - Exhaustiveness checking prevents missing cases
17
+ - Impossible states become unrepresentable
18
+ - Business logic encoded in types, not runtime checks
19
+ - Refactoring becomes safe and mechanical
20
+ - Self-documenting code through types
21
+
22
+ ## Quick Reference
23
+
24
+ For detailed patterns and examples, see:
25
+ - [ADTs (Algebraic Data Types)](./references/adts.md) - Sum types, product types, discriminated unions
26
+ - [Option & Result](./references/option-result.md) - Type-safe error handling and nullable values
27
+ - [Branded Types](./references/branded-types.md) - Smart constructors and nominal typing
28
+ - [Migration Guide](./references/migration-guide.md) - Step-by-step adoption playbook
29
+
30
+ ## Core Patterns Overview
31
+
32
+ ### 1. Discriminated Unions (Sum Types)
33
+
34
+ Model "one of several variants" with exhaustive pattern matching:
35
+
36
+ ```typescript
37
+ type PaymentMethod =
38
+ | { kind: "card"; last4: string; brand: string }
39
+ | { kind: "ach"; accountNumber: string; routingNumber: string }
40
+ | { kind: "wallet"; provider: "apple" | "google" }
41
+
42
+ function processPayment(method: PaymentMethod): void {
43
+ switch (method.kind) {
44
+ case "card":
45
+ // TypeScript knows: method.last4 and method.brand exist
46
+ return processCard(method.last4, method.brand)
47
+ case "ach":
48
+ // TypeScript knows: method.accountNumber and method.routingNumber exist
49
+ return processACH(method.accountNumber, method.routingNumber)
50
+ case "wallet":
51
+ // TypeScript knows: method.provider exists
52
+ return processWallet(method.provider)
53
+ default:
54
+ assertNever(method) // Compiler error if cases missing
55
+ }
56
+ }
57
+ ```
58
+
59
+ ### 2. Option Type (Nullable Values)
60
+
61
+ Explicit handling of "value may be absent":
62
+
63
+ ```typescript
64
+ type Option<T> = { _tag: "None" } | { _tag: "Some"; value: T }
65
+
66
+ function findUser(id: string): Option<User> {
67
+ const user = database.get(id)
68
+ return user ? Some(user) : None
69
+ }
70
+
71
+ const result = findUser("123")
72
+ switch (result._tag) {
73
+ case "Some":
74
+ console.log(result.value.name) // Type-safe access
75
+ break
76
+ case "None":
77
+ console.log("User not found")
78
+ break
79
+ }
80
+ ```
81
+
82
+ ### 3. Result Type (Error Handling)
83
+
84
+ Explicit error handling without exceptions:
85
+
86
+ ```typescript
87
+ type Result<T, E> = { _tag: "Ok"; value: T } | { _tag: "Err"; error: E }
88
+
89
+ function parseConfig(raw: string): Result<Config, ParseError> {
90
+ try {
91
+ const data = JSON.parse(raw)
92
+ return Ok(validateConfig(data))
93
+ } catch (e) {
94
+ return Err({ message: "Invalid JSON", cause: e })
95
+ }
96
+ }
97
+
98
+ const result = parseConfig(rawConfig)
99
+ switch (result._tag) {
100
+ case "Ok":
101
+ startServer(result.value)
102
+ break
103
+ case "Err":
104
+ logger.error(result.error.message)
105
+ break
106
+ }
107
+ ```
108
+
109
+ ### 4. Branded Types (Type-Safe Units)
110
+
111
+ Prevent unit confusion and invalid values:
112
+
113
+ ```typescript
114
+ type Brand<K, T> = K & { __brand: T }
115
+ type Cents = Brand<number, "Cents">
116
+ type Dollars = Brand<number, "Dollars">
117
+
118
+ const Cents = (n: number): Cents => {
119
+ if (!Number.isInteger(n) || n < 0) throw new Error("Invalid cents")
120
+ return n as Cents
121
+ }
122
+
123
+ const Dollars = (n: number): Dollars => {
124
+ if (n < 0) throw new Error("Invalid dollars")
125
+ return n as Dollars
126
+ }
127
+
128
+ // Compiler prevents mixing units:
129
+ const price: Cents = Cents(100)
130
+ const budget: Dollars = Dollars(10)
131
+ const total: Cents = price + budget // Type error! Cannot mix Cents and Dollars
132
+ ```
133
+
134
+ ## When to Use
135
+
136
+ ### Use Discriminated Unions When:
137
+ - Modeling state machines (pending → settled → reconciled)
138
+ - Representing mutually exclusive variants (payment methods, user roles)
139
+ - Building domain models with distinct states
140
+ - Replacing boolean flags with explicit states
141
+
142
+ ### Use Option When:
143
+ - Value may be absent (but absence is expected/valid)
144
+ - Replacing `null` or `undefined` checks
145
+ - Chaining operations that may fail to find values
146
+ - Making nullability explicit in APIs
147
+
148
+ ### Use Result When:
149
+ - Operation may fail with recoverable errors
150
+ - You need to propagate error context
151
+ - Replacing try/catch for expected failures
152
+ - Building error handling into function signatures
153
+
154
+ ### Use Branded Types When:
155
+ - Preventing unit confusion (cents vs dollars, ms vs seconds)
156
+ - Enforcing validation invariants (email format, positive numbers)
157
+ - Creating type-safe IDs (UserId vs OrderId)
158
+ - Domain-driven design with value objects
159
+
160
+ ## Quick Start - Paste-Ready Helpers
161
+
162
+ Copy these into your project to start using functional patterns:
163
+
164
+ ```typescript
165
+ // ============================================
166
+ // Option Type
167
+ // ============================================
168
+ type None = { _tag: "None" }
169
+ type Some<T> = { _tag: "Some"; value: T }
170
+ type Option<T> = None | Some<T>
171
+
172
+ const None: None = { _tag: "None" }
173
+ const Some = <T>(value: T): Option<T> => ({ _tag: "Some", value })
174
+
175
+ // Utilities
176
+ const isNone = <T>(opt: Option<T>): opt is None => opt._tag === "None"
177
+ const isSome = <T>(opt: Option<T>): opt is Some<T> => opt._tag === "Some"
178
+
179
+ const getOrElse = <T>(opt: Option<T>, defaultValue: T): T =>
180
+ opt._tag === "Some" ? opt.value : defaultValue
181
+
182
+ const map = <T, U>(opt: Option<T>, fn: (value: T) => U): Option<U> =>
183
+ opt._tag === "Some" ? Some(fn(opt.value)) : None
184
+
185
+ const flatMap = <T, U>(opt: Option<T>, fn: (value: T) => Option<U>): Option<U> =>
186
+ opt._tag === "Some" ? fn(opt.value) : None
187
+
188
+ // ============================================
189
+ // Result Type
190
+ // ============================================
191
+ type Ok<T> = { _tag: "Ok"; value: T }
192
+ type Err<E> = { _tag: "Err"; error: E }
193
+ type Result<T, E> = Ok<T> | Err<E>
194
+
195
+ const Ok = <T>(value: T): Result<T, never> => ({ _tag: "Ok", value })
196
+ const Err = <E>(error: E): Result<never, E> => ({ _tag: "Err", error })
197
+
198
+ // Utilities
199
+ const isOk = <T, E>(result: Result<T, E>): result is Ok<T> => result._tag === "Ok"
200
+ const isErr = <T, E>(result: Result<T, E>): result is Err<E> => result._tag === "Err"
201
+
202
+ const mapResult = <T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E> =>
203
+ result._tag === "Ok" ? Ok(fn(result.value)) : result
204
+
205
+ const flatMapResult = <T, U, E>(
206
+ result: Result<T, E>,
207
+ fn: (value: T) => Result<U, E>
208
+ ): Result<U, E> =>
209
+ result._tag === "Ok" ? fn(result.value) : result
210
+
211
+ // ============================================
212
+ // Exhaustiveness Checking
213
+ // ============================================
214
+ const assertNever = (x: never): never => {
215
+ throw new Error(`Unhandled variant: ${JSON.stringify(x)}`)
216
+ }
217
+
218
+ // ============================================
219
+ // Branded Types
220
+ // ============================================
221
+ type Brand<K, T> = K & { __brand: T }
222
+
223
+ // Example: Cents (integer cents to prevent floating point errors)
224
+ type Cents = Brand<number, "Cents">
225
+ const Cents = (n: number): Cents => {
226
+ if (!Number.isInteger(n)) throw new Error("Cents must be integer")
227
+ if (n < 0) throw new Error("Cents cannot be negative")
228
+ return n as Cents
229
+ }
230
+
231
+ // Example: Email (validated email address)
232
+ type Email = Brand<string, "Email">
233
+ const Email = (s: string): Email => {
234
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s)) throw new Error("Invalid email")
235
+ return s as Email
236
+ }
237
+
238
+ // Example: Millis (timestamp in milliseconds)
239
+ type Millis = Brand<number, "Millis">
240
+ const Millis = (n: number): Millis => {
241
+ if (n < 0) throw new Error("Millis cannot be negative")
242
+ return n as Millis
243
+ }
244
+ ```
245
+
246
+ ## Guidelines
247
+
248
+ ### Pattern Matching Best Practices
249
+
250
+ 1. **Always use `assertNever` in default case** for exhaustiveness checking:
251
+ ```typescript
252
+ switch (variant.kind) {
253
+ case "a": return handleA(variant)
254
+ case "b": return handleB(variant)
255
+ default: assertNever(variant) // Compiler error if cases missing
256
+ }
257
+ ```
258
+
259
+ 2. **Use discriminant field consistently** (`kind`, `type`, `_tag`):
260
+ ```typescript
261
+ // Good: consistent discriminant
262
+ type Result<T, E> = { _tag: "Ok"; value: T } | { _tag: "Err"; error: E }
263
+
264
+ // Avoid: mixing discriminants
265
+ type Bad = { kind: "a" } | { type: "b" } // Inconsistent!
266
+ ```
267
+
268
+ 3. **Narrow types early** to unlock type safety:
269
+ ```typescript
270
+ if (result._tag === "Ok") {
271
+ // TypeScript knows: result.value exists
272
+ return result.value.data
273
+ }
274
+ ```
275
+
276
+ ### Error Handling Strategy
277
+
278
+ 1. **Use Option for expected absence**:
279
+ ```typescript
280
+ function findUser(id: string): Option<User>
281
+ ```
282
+
283
+ 2. **Use Result for recoverable errors**:
284
+ ```typescript
285
+ function parseConfig(raw: string): Result<Config, ParseError>
286
+ ```
287
+
288
+ 3. **Use exceptions for programmer errors**:
289
+ ```typescript
290
+ function unreachable(message: string): never {
291
+ throw new Error(`Unreachable: ${message}`)
292
+ }
293
+ ```
294
+
295
+ ### Branded Types Guidelines
296
+
297
+ 1. **Validate in smart constructor**:
298
+ ```typescript
299
+ const PositiveInt = (n: number): PositiveInt => {
300
+ if (!Number.isInteger(n) || n <= 0) throw new Error("Must be positive integer")
301
+ return n as PositiveInt
302
+ }
303
+ ```
304
+
305
+ 2. **Use branded types for domain concepts**:
306
+ ```typescript
307
+ type UserId = Brand<string, "UserId">
308
+ type OrderId = Brand<string, "OrderId">
309
+ // Compiler prevents: const userId: UserId = orderId
310
+ ```
311
+
312
+ 3. **Prevent unit confusion**:
313
+ ```typescript
314
+ type Seconds = Brand<number, "Seconds">
315
+ type Millis = Brand<number, "Millis">
316
+ // Compiler prevents: const s: Seconds = millis
317
+ ```
318
+
319
+ ### Migration Strategy
320
+
321
+ Start small and expand:
322
+ 1. New features: Use functional patterns from day one
323
+ 2. Bug fixes: Refactor to discriminated unions when touching code
324
+ 3. High-risk areas: Prioritize financial calculations, state machines
325
+ 4. Team adoption: Share paste-ready helpers, pair on first implementations
326
+
327
+ Enable TypeScript strict mode flags:
328
+ - `strictNullChecks: true` - Make nullability explicit
329
+ - `noImplicitReturns: true` - Ensure all code paths return
330
+ - `strictFunctionTypes: true` - Safer function signatures
331
+
332
+ ## Examples by Domain
333
+
334
+ ### State Machine (Transaction Lifecycle)
335
+ ```typescript
336
+ type TxnState =
337
+ | { kind: "pending"; createdAt: Millis }
338
+ | { kind: "settled"; ledgerId: string; settledAt: Millis }
339
+ | { kind: "failed"; reason: FailureReason; failedAt: Millis }
340
+ | { kind: "reversed"; originalLedgerId: string; reversedAt: Millis }
341
+
342
+ function canReverse(state: TxnState): boolean {
343
+ switch (state.kind) {
344
+ case "pending": return false
345
+ case "settled": return true
346
+ case "failed": return false
347
+ case "reversed": return false
348
+ default: assertNever(state)
349
+ }
350
+ }
351
+ ```
352
+
353
+ ### Configuration Parsing
354
+ ```typescript
355
+ type ConfigError = { field: string; message: string }
356
+
357
+ function parsePort(raw: unknown): Result<number, ConfigError> {
358
+ if (typeof raw !== "number") {
359
+ return Err({ field: "port", message: "must be number" })
360
+ }
361
+ if (raw < 1 || raw > 65535) {
362
+ return Err({ field: "port", message: "must be 1-65535" })
363
+ }
364
+ return Ok(raw)
365
+ }
366
+ ```
367
+
368
+ ### Financial Calculations
369
+ ```typescript
370
+ type Cents = Brand<number, "Cents">
371
+
372
+ function addCents(a: Cents, b: Cents): Cents {
373
+ return Cents(a + b) // Smart constructor validates result
374
+ }
375
+
376
+ function calculateFee(amount: Cents, bps: number): Cents {
377
+ const feeAmount = Math.round((amount * bps) / 10000)
378
+ return Cents(feeAmount)
379
+ }
380
+ ```
381
+
382
+ ## Further Reading
383
+
384
+ - [ADT Reference](./references/adts.md) - Deep dive on sum types, product types, and pattern matching
385
+ - [Option & Result Reference](./references/option-result.md) - Comprehensive error handling patterns
386
+ - [Branded Types Reference](./references/branded-types.md) - Advanced nominal typing techniques
387
+ - [Migration Guide](./references/migration-guide.md) - Step-by-step adoption playbook
388
+
389
+ ## Credits
390
+
391
+ These patterns are inspired by **[Why Reliability Demands Functional Programming, ADTs, Safety and Critical Infrastructure](https://rastrian.com/why-reliability-demands-functional-programming-adts-safety-and-critical-infrastructure/)** by Rastrian. The blog post explores how functional programming techniques and Algebraic Data Types enable building reliable systems in critical infrastructure contexts.
392
+
393
+ ## When This Skill Loads
394
+
395
+ This skill automatically loads when discussing:
396
+ - Discriminated unions and sum types
397
+ - State machine modeling
398
+ - Result/Option types and error handling
399
+ - Branded types and smart constructors
400
+ - Type-safe domain models
401
+ - Making illegal states unrepresentable
402
+ - Functional programming in TypeScript