@a-company/paradigm 1.5.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 (114) hide show
  1. package/README.md +142 -0
  2. package/dist/accept-orchestration-CWZNCGZX.js +188 -0
  3. package/dist/agents-suggest-35LIQKDH.js +83 -0
  4. package/dist/aggregate-W7Q6VIM2.js +88 -0
  5. package/dist/auto-IU7VN55K.js +470 -0
  6. package/dist/beacon-B47XSTL7.js +251 -0
  7. package/dist/chunk-2M6OSOIG.js +1302 -0
  8. package/dist/chunk-4NCFWYGG.js +110 -0
  9. package/dist/chunk-5C4SGQKH.js +705 -0
  10. package/dist/chunk-5GOA7WYD.js +1095 -0
  11. package/dist/chunk-5JGJACDU.js +37 -0
  12. package/dist/chunk-6QC3YGB6.js +114 -0
  13. package/dist/chunk-753RICFF.js +325 -0
  14. package/dist/chunk-AD2LSCHB.js +1595 -0
  15. package/dist/chunk-CHSHON3O.js +669 -0
  16. package/dist/chunk-ELLR7WP6.js +3175 -0
  17. package/dist/chunk-ILOWBJRC.js +12 -0
  18. package/dist/chunk-IRKUEJVW.js +405 -0
  19. package/dist/chunk-MC7XC7XQ.js +533 -0
  20. package/dist/chunk-MO4EEYFW.js +38 -0
  21. package/dist/chunk-MQWH7PFI.js +13366 -0
  22. package/dist/chunk-N6PJAPDE.js +364 -0
  23. package/dist/chunk-PBHIFAL4.js +259 -0
  24. package/dist/chunk-PMXRGPRQ.js +305 -0
  25. package/dist/chunk-PW2EXJQT.js +689 -0
  26. package/dist/chunk-TAP5N3HH.js +245 -0
  27. package/dist/chunk-THFVK5AE.js +148 -0
  28. package/dist/chunk-UM54F7G5.js +1533 -0
  29. package/dist/chunk-UUZ2DMG5.js +185 -0
  30. package/dist/chunk-WS5KM7OL.js +780 -0
  31. package/dist/chunk-YDNKXH4Z.js +2316 -0
  32. package/dist/chunk-YO6DVTL7.js +99 -0
  33. package/dist/claude-SUYNN72C.js +362 -0
  34. package/dist/claude-cli-OF43XAO3.js +276 -0
  35. package/dist/claude-code-PW6SKD2M.js +126 -0
  36. package/dist/claude-code-teams-JLZ5IXB6.js +199 -0
  37. package/dist/constellation-K3CIQCHI.js +225 -0
  38. package/dist/cost-AEK6R7HK.js +174 -0
  39. package/dist/cost-KYXIQ62X.js +93 -0
  40. package/dist/cursor-cli-IHJMPRCW.js +269 -0
  41. package/dist/cursorrules-KI5QWHIX.js +84 -0
  42. package/dist/diff-AJJ5H6HV.js +125 -0
  43. package/dist/dist-7MPIRMTZ-IOQOREMZ.js +10866 -0
  44. package/dist/dist-NHJQVVUW.js +68 -0
  45. package/dist/dist-ZEMSQV74.js +20 -0
  46. package/dist/doctor-6Y6L6HEB.js +11 -0
  47. package/dist/echo-VYZW3OTT.js +248 -0
  48. package/dist/export-R4FJ5NOH.js +38 -0
  49. package/dist/history-EVO3L6SC.js +277 -0
  50. package/dist/hooks-MBWE4ILT.js +12 -0
  51. package/dist/index.d.ts +2 -0
  52. package/dist/index.js +568 -0
  53. package/dist/lint-HXKTWRNO.js +316 -0
  54. package/dist/manual-Y3QOXWYA.js +204 -0
  55. package/dist/mcp.js +14745 -0
  56. package/dist/orchestrate-4ZH5GUQH.js +323 -0
  57. package/dist/probe-OYCP4JYG.js +151 -0
  58. package/dist/promote-Z52ZJTJU.js +181 -0
  59. package/dist/providers-4PGPZEWP.js +104 -0
  60. package/dist/remember-6VZ74B7E.js +77 -0
  61. package/dist/ripple-SBQOSTZD.js +215 -0
  62. package/dist/sentinel-LCFD56OJ.js +43 -0
  63. package/dist/server-F5ITNK6T.js +9846 -0
  64. package/dist/server-T6WIFYRQ.js +16076 -0
  65. package/dist/setup-DF4F3ICN.js +25 -0
  66. package/dist/setup-JHBPZAG7.js +296 -0
  67. package/dist/shift-HKIAP4ZN.js +226 -0
  68. package/dist/snapshot-GTVPRYZG.js +62 -0
  69. package/dist/spawn-BJRQA2NR.js +196 -0
  70. package/dist/summary-H6J6N6PJ.js +140 -0
  71. package/dist/switch-6EANJ7O6.js +232 -0
  72. package/dist/sync-BEOCW7TZ.js +11 -0
  73. package/dist/team-NWP2KJAB.js +32 -0
  74. package/dist/test-MA5TWJQV.js +934 -0
  75. package/dist/thread-JCJVRUQR.js +258 -0
  76. package/dist/triage-ETVXXFMV.js +1880 -0
  77. package/dist/tutorial-L5Q3ZDHK.js +666 -0
  78. package/dist/university-R2WDQLSI.js +40 -0
  79. package/dist/upgrade-5B3YGGC6.js +550 -0
  80. package/dist/validate-F3YHBCRZ.js +39 -0
  81. package/dist/validate-QEEY6KFS.js +64 -0
  82. package/dist/watch-4LT4O6K7.js +123 -0
  83. package/dist/watch-6IIWPWDN.js +111 -0
  84. package/dist/wisdom-LRM4FFCH.js +319 -0
  85. package/package.json +68 -0
  86. package/templates/paradigm/config.yaml +175 -0
  87. package/templates/paradigm/docs/commands.md +727 -0
  88. package/templates/paradigm/docs/decisions/000-template.md +47 -0
  89. package/templates/paradigm/docs/decisions/README.md +26 -0
  90. package/templates/paradigm/docs/error-patterns.md +215 -0
  91. package/templates/paradigm/docs/patterns.md +358 -0
  92. package/templates/paradigm/docs/queries.md +200 -0
  93. package/templates/paradigm/docs/troubleshooting.md +477 -0
  94. package/templates/paradigm/echoes.yaml +25 -0
  95. package/templates/paradigm/prompts/add-feature.md +152 -0
  96. package/templates/paradigm/prompts/add-gate.md +117 -0
  97. package/templates/paradigm/prompts/debug-auth.md +174 -0
  98. package/templates/paradigm/prompts/implement-ftux.md +722 -0
  99. package/templates/paradigm/prompts/implement-sandbox.md +651 -0
  100. package/templates/paradigm/prompts/read-docs.md +84 -0
  101. package/templates/paradigm/prompts/refactor.md +106 -0
  102. package/templates/paradigm/prompts/run-e2e-tests.md +340 -0
  103. package/templates/paradigm/prompts/trace-flow.md +202 -0
  104. package/templates/paradigm/prompts/validate-portals.md +279 -0
  105. package/templates/paradigm/specs/context-tracking.md +200 -0
  106. package/templates/paradigm/specs/context.md +461 -0
  107. package/templates/paradigm/specs/disciplines.md +413 -0
  108. package/templates/paradigm/specs/history.md +339 -0
  109. package/templates/paradigm/specs/logger.md +303 -0
  110. package/templates/paradigm/specs/navigator.md +236 -0
  111. package/templates/paradigm/specs/purpose.md +265 -0
  112. package/templates/paradigm/specs/scan.md +177 -0
  113. package/templates/paradigm/specs/symbols.md +451 -0
  114. package/templates/paradigm/specs/wisdom.md +294 -0
@@ -0,0 +1,47 @@
1
+ # ADR 000: [Title]
2
+
3
+ **Status:** Proposed | Accepted | Deprecated | Superseded
4
+ **Date:** YYYY-MM-DD
5
+ **Decision Makers:** [Names]
6
+
7
+ ## Context
8
+
9
+ [What is the issue that we're seeing that motivates this decision?]
10
+
11
+ ## Decision
12
+
13
+ [What is the change that we're proposing and/or doing?]
14
+
15
+ ## Rationale
16
+
17
+ [Why did we choose this option? What factors were considered?]
18
+
19
+ | Factor | Option A | Option B | Winner |
20
+ |--------|----------|----------|--------|
21
+ | [Factor 1] | ... | ... | ... |
22
+
23
+ ## Consequences
24
+
25
+ ### Positive
26
+ - [Benefit 1]
27
+ - [Benefit 2]
28
+
29
+ ### Negative
30
+ - [Drawback 1]
31
+ - [Drawback 2]
32
+
33
+ ### Mitigations
34
+ - [How we'll handle negative consequences]
35
+
36
+ ## Alternatives Considered
37
+
38
+ [What other options were considered and why were they rejected?]
39
+
40
+ ## References
41
+
42
+ - [Link to relevant documentation]
43
+ - [Link to related ADRs]
44
+
45
+ ---
46
+
47
+ *ADR format based on [Michael Nygard's template](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions)*
@@ -0,0 +1,26 @@
1
+ # Architecture Decision Records (ADRs)
2
+
3
+ This directory contains Architecture Decision Records that document significant technical decisions made in this project.
4
+
5
+ ## What is an ADR?
6
+
7
+ An ADR captures a single decision about the architecture or design of the system. It explains:
8
+ - **Context:** What problem or situation prompted the decision?
9
+ - **Decision:** What was decided?
10
+ - **Consequences:** What are the trade-offs?
11
+
12
+ ## ADR Template
13
+
14
+ Copy `000-template.md` when creating a new ADR.
15
+
16
+ ## Index
17
+
18
+ | # | Title | Status | Date |
19
+ |---|-------|--------|------|
20
+ | 000 | Template | Template | - |
21
+
22
+ *Add new ADRs to this index.*
23
+
24
+ ---
25
+
26
+ *Part of Paradigm v1.0*
@@ -0,0 +1,215 @@
1
+ # Error Patterns
2
+
3
+ > Standard error handling across the project (Language-Agnostic)
4
+
5
+ ## Error Response Format
6
+
7
+ All APIs/services return errors in this format:
8
+
9
+ ```
10
+ // Error response
11
+ {
12
+ error: string // Human-readable message
13
+ code?: string // Machine-readable code (optional)
14
+ }
15
+
16
+ // Success response
17
+ {
18
+ success?: true // Optional confirmation
19
+ data?: any // Response payload
20
+ }
21
+ ```
22
+
23
+ ## Standard Error Codes
24
+
25
+ | Code | Meaning | When to Use |
26
+ |------|---------|-------------|
27
+ | `INVALID_REQUEST` | Malformed input | Missing fields, wrong types |
28
+ | `INVALID_CREDENTIALS` | Auth validation failed | Wrong password, expired token |
29
+ | `UNAUTHORIZED` | Not authenticated | Missing/expired session |
30
+ | `FORBIDDEN` | Authenticated but denied | Insufficient permissions |
31
+ | `NOT_FOUND` | Resource doesn't exist | Unknown ID, deleted item |
32
+ | `CONFLICT` | State conflict | Duplicate entry, version mismatch |
33
+ | `RATE_LIMITED` | Too many requests | Brute force protection |
34
+ | `SERVER_ERROR` | Internal error | Database down, unexpected crash |
35
+ | `UNAVAILABLE` | Service unavailable | Maintenance, overloaded |
36
+
37
+ ## Patterns (Pseudocode)
38
+
39
+ ### Basic Error Return
40
+
41
+ ```
42
+ // Simple error
43
+ return error_response("Invalid request", status=400)
44
+
45
+ // With code
46
+ return error_response("Too many attempts", code="RATE_LIMITED", status=429)
47
+ ```
48
+
49
+ ### Input Validation
50
+
51
+ ```
52
+ function handle_request(request):
53
+ data = parse_json(request.body)
54
+
55
+ if data is null:
56
+ return error_response("Invalid request body", status=400)
57
+
58
+ if not valid_email(data.email):
59
+ return error_response("Valid email required", status=400)
60
+
61
+ // Continue processing...
62
+ ```
63
+
64
+ ### Auth Check
65
+
66
+ ```
67
+ function require_auth(request):
68
+ user = get_user_from_session(request)
69
+
70
+ if user is null:
71
+ return error_response("Unauthorized", status=401)
72
+
73
+ return user
74
+ ```
75
+
76
+ ### Resource Access
77
+
78
+ ```
79
+ function get_resource(id):
80
+ resource = database.find(id)
81
+
82
+ if resource is null:
83
+ return error_response("Not found", status=404)
84
+
85
+ if not user_can_access(resource):
86
+ return error_response("Forbidden", status=403)
87
+
88
+ return success_response(resource)
89
+ ```
90
+
91
+ ### Database Operations
92
+
93
+ ```
94
+ function query_database(query, params):
95
+ try:
96
+ result = db.execute(query, params)
97
+ return result
98
+ catch DatabaseError as error:
99
+ log.component('#database').error('Query failed', { error })
100
+ return error_response("Database error", status=500)
101
+ ```
102
+
103
+ ## Error Handling Flow
104
+
105
+ ```
106
+ ┌─────────────────┐
107
+ │ Receive Input │
108
+ └────────┬────────┘
109
+
110
+ ┌─────────────────┐ ┌─────────────────┐
111
+ │ Validate Input │────▶│ 400 Bad Request │
112
+ └────────┬────────┘ no └─────────────────┘
113
+ │ yes
114
+
115
+ ┌─────────────────┐ ┌─────────────────┐
116
+ │ Check Auth │────▶│ 401 Unauthorized│
117
+ └────────┬────────┘ no └─────────────────┘
118
+ │ yes
119
+
120
+ ┌─────────────────┐ ┌─────────────────┐
121
+ │ Check Permission│────▶│ 403 Forbidden │
122
+ └────────┬────────┘ no └─────────────────┘
123
+ │ yes
124
+
125
+ ┌─────────────────┐ ┌─────────────────┐
126
+ │ Find Resource │────▶│ 404 Not Found │
127
+ └────────┬────────┘ no └─────────────────┘
128
+ │ yes
129
+
130
+ ┌─────────────────┐ ┌─────────────────┐
131
+ │ Execute Action │────▶│ 500 Server Error│
132
+ └────────┬────────┘ fail└─────────────────┘
133
+ │ ok
134
+
135
+ ┌─────────────────┐
136
+ │ 200 Success │
137
+ └─────────────────┘
138
+ ```
139
+
140
+ ## Logging Errors
141
+
142
+ Always use the Paradigm logger:
143
+
144
+ ```
145
+ // Component context (features)
146
+ log.component('#checkout').error('Payment failed', { reason, order_id })
147
+
148
+ // Component context (infrastructure)
149
+ log.component('#database').error('Connection lost', { host })
150
+
151
+ // Gate context
152
+ log.gate('^auth').warn('Access denied', { user_id, resource })
153
+
154
+ // Component context (integrations)
155
+ log.component('#stripe-client').error('API error', { status, message })
156
+ ```
157
+
158
+ ## Graceful Degradation
159
+
160
+ When non-critical features fail, don't block the user:
161
+
162
+ ```
163
+ // Bad: crashes if optional feature fails
164
+ data = fetch_optional_feature() // throws on error
165
+
166
+ // Good: graceful fallback
167
+ data = null
168
+ try:
169
+ data = fetch_optional_feature()
170
+ catch:
171
+ log.component('#optional').debug('Feature unavailable, using fallback')
172
+
173
+ // Continue with or without optional data
174
+ ```
175
+
176
+ ## Client-Side Handling
177
+
178
+ ```
179
+ function api_call(endpoint, options):
180
+ try:
181
+ response = http.request(endpoint, options)
182
+
183
+ if not response.ok:
184
+ return { error: response.data.error or "Request failed" }
185
+
186
+ return { data: response.data }
187
+ catch NetworkError:
188
+ return { error: "Connection error" }
189
+ ```
190
+
191
+ ## Error State in UI
192
+
193
+ ```
194
+ // State
195
+ error = null
196
+
197
+ function submit():
198
+ error = null // Clear previous error
199
+
200
+ result = api_call('/endpoint', data)
201
+
202
+ if result.error:
203
+ error = result.error
204
+ return
205
+
206
+ // Success handling...
207
+
208
+ // Display
209
+ if error:
210
+ show_error_message(error)
211
+ ```
212
+
213
+ ---
214
+
215
+ *Part of Paradigm v2.0 - Language Agnostic*
@@ -0,0 +1,358 @@
1
+ # Paradigm Coding Patterns
2
+
3
+ Common patterns for working with Paradigm symbols and the logger.
4
+
5
+ ---
6
+
7
+ ## Component Pattern (Features)
8
+
9
+ Components with `[feature]` tag are user-facing operations. They should be logged at entry and exit.
10
+
11
+ ```
12
+ // Component: #login-handler [feature]
13
+
14
+ function login(email, password):
15
+ // 1. Log entry with start() for duration tracking
16
+ tracker = log.component('#login-handler').start('Starting login', { email })
17
+
18
+ try:
19
+ // 2. Perform the operation
20
+ user = authenticate(email, password)
21
+
22
+ // 3. Emit success signal
23
+ log.signal('!login-success').info('User authenticated', {
24
+ userId: user.id
25
+ })
26
+
27
+ // 4. Log successful completion with duration
28
+ tracker.success('Login completed', { userId: user.id })
29
+
30
+ return user
31
+
32
+ catch error:
33
+ // 5. Emit failure signal
34
+ log.signal('!login-failed').warn('Login failed', {
35
+ email,
36
+ error: error.message
37
+ })
38
+
39
+ // 6. Log failure with duration
40
+ tracker.error('Login failed', { error: error.message })
41
+
42
+ throw error
43
+ ```
44
+
45
+ **Key points:**
46
+ - Use `log.component('#name').start()` at entry
47
+ - Emit `!success` and `!failed` signals
48
+ - Always call `tracker.success()` or `tracker.error()`
49
+
50
+ ---
51
+
52
+ ## Gate Pattern
53
+
54
+ Gates (`^`) are authorization checkpoints. Log before and after the check.
55
+
56
+ ```
57
+ // Gate: ^authenticated
58
+
59
+ function requireAuth(request, next):
60
+ // 1. Log gate check start
61
+ log.gate('^authenticated').debug('Checking ^authenticated', {
62
+ path: request.path,
63
+ method: request.method
64
+ })
65
+
66
+ // 2. Perform authorization check
67
+ user = getSessionUser(request)
68
+
69
+ if not user:
70
+ // 3. Log denial
71
+ log.gate('^authenticated').warn('Access denied - no session', {
72
+ path: request.path,
73
+ ip: request.ip
74
+ })
75
+ return unauthorized("Authentication required")
76
+
77
+ // 4. Log success
78
+ log.gate('^authenticated').debug('Gate passed', {
79
+ userId: user.id,
80
+ path: request.path
81
+ })
82
+
83
+ // 5. Continue to next handler
84
+ return next()
85
+ ```
86
+
87
+ **Key points:**
88
+ - Log at `debug` level for routine checks
89
+ - Log at `warn` level for denials
90
+ - Include context (path, userId) for debugging
91
+
92
+ ---
93
+
94
+ ## Component Pattern
95
+
96
+ Components (`#`) are reusable infrastructure. Log operations and errors.
97
+
98
+ ```
99
+ // Component: #database
100
+
101
+ class Database:
102
+ function query(sql, params):
103
+ // 1. Start duration tracking
104
+ tracker = log.component('#database').start('Executing query')
105
+
106
+ try:
107
+ // 2. Perform operation
108
+ result = this.connection.execute(sql, params)
109
+
110
+ // 3. Log success with metrics
111
+ tracker.success('Query completed', {
112
+ rows: result.length,
113
+ table: extractTable(sql)
114
+ })
115
+
116
+ return result
117
+
118
+ catch error:
119
+ // 4. Log failure
120
+ tracker.error('Query failed', {
121
+ error: error.message,
122
+ sql: sql.substring(0, 100) // Truncate for safety
123
+ })
124
+ throw error
125
+
126
+ function connect():
127
+ log.component('#database').info('Connecting to database', {
128
+ host: this.config.host,
129
+ database: this.config.database
130
+ })
131
+
132
+ // ... connection logic
133
+
134
+ log.component('#database').info('Database connected')
135
+ ```
136
+
137
+ **Key points:**
138
+ - Use duration tracking for async operations
139
+ - Log connection lifecycle events
140
+ - Include relevant metrics (rows, duration)
141
+
142
+ ---
143
+
144
+ ## State Component Pattern
145
+
146
+ State components (`#` with `[state]` tag) manage application state. Log changes with before/after values.
147
+
148
+ ```
149
+ // Component: #user-store [state]
150
+
151
+ class AuthStore:
152
+ authenticated = false
153
+ user = null
154
+
155
+ function login(token, userData):
156
+ // 1. Log state change with context
157
+ log.component('#user-store').info('Authenticating user', {
158
+ from: this.authenticated,
159
+ to: true,
160
+ userId: userData.id
161
+ })
162
+
163
+ // 2. Update state
164
+ this.authenticated = true
165
+ this.user = userData
166
+ this.token = token
167
+
168
+ // 3. Emit signal
169
+ log.signal('!login-success').info('User session established', {
170
+ userId: userData.id
171
+ })
172
+
173
+ function logout():
174
+ previousUser = this.user?.id
175
+
176
+ log.component('#user-store').info('Logging out user', {
177
+ from: this.authenticated,
178
+ to: false,
179
+ userId: previousUser
180
+ })
181
+
182
+ this.authenticated = false
183
+ this.user = null
184
+ this.token = null
185
+
186
+ log.signal('!logout').info('User session ended', {
187
+ userId: previousUser
188
+ })
189
+ ```
190
+
191
+ **Key points:**
192
+ - Include `from` and `to` values
193
+ - Pair state changes with signals
194
+ - Log at `info` level for visibility
195
+
196
+ ---
197
+
198
+ ## Flow Pattern
199
+
200
+ Flows (`$`) are multi-step processes. Log step transitions.
201
+
202
+ ```
203
+ // Flow: $checkout-flow
204
+ // Steps: cart → shipping → payment → confirmation
205
+
206
+ class CheckoutFlow:
207
+ currentStep = 'cart'
208
+
209
+ function startFlow(cartId):
210
+ log.flow('$checkout-flow').info('Flow started', {
211
+ cartId,
212
+ step: 'cart'
213
+ })
214
+ this.currentStep = 'cart'
215
+
216
+ function nextStep():
217
+ steps = ['cart', 'shipping', 'payment', 'confirmation']
218
+ currentIndex = steps.indexOf(this.currentStep)
219
+
220
+ if currentIndex < steps.length - 1:
221
+ previousStep = this.currentStep
222
+ this.currentStep = steps[currentIndex + 1]
223
+
224
+ log.flow('$checkout-flow').info('Step completed', {
225
+ from: previousStep,
226
+ to: this.currentStep,
227
+ progress: `${currentIndex + 1}/${steps.length}`
228
+ })
229
+
230
+ function completeFlow(orderId):
231
+ log.flow('$checkout-flow').info('Flow completed', {
232
+ orderId,
233
+ totalSteps: 4
234
+ })
235
+ log.signal('!checkout-complete').info('Order placed', { orderId })
236
+ ```
237
+
238
+ **Key points:**
239
+ - Log flow start and completion
240
+ - Log step transitions with from/to
241
+ - Include progress indicators
242
+
243
+ ---
244
+
245
+ ## Signal Pattern
246
+
247
+ Signals (`!`) are events. Use them consistently for important occurrences.
248
+
249
+ ```
250
+ // Signals for authentication
251
+ log.signal('!login-success').info('User logged in', { userId })
252
+ log.signal('!login-failed').warn('Login attempt failed', { email, reason })
253
+ log.signal('!logout').info('User logged out', { userId })
254
+ log.signal('!session-expired').warn('Session expired', { userId })
255
+
256
+ // Signals for payments
257
+ log.signal('!payment-success').info('Payment processed', { orderId, amount })
258
+ log.signal('!payment-failed').error('Payment declined', { orderId, reason })
259
+ log.signal('!refund-issued').info('Refund processed', { orderId, amount })
260
+
261
+ // Signals for system events
262
+ log.signal('!rate-limit-exceeded').warn('Rate limit hit', { ip, endpoint })
263
+ log.signal('!cache-miss').debug('Cache miss', { key })
264
+ log.signal('!email-sent').info('Email dispatched', { to, template })
265
+ ```
266
+
267
+ **Key points:**
268
+ - Use consistent naming: `!noun-verb` or `!noun-state`
269
+ - Choose appropriate level (info/warn/error)
270
+ - Include relevant context
271
+
272
+ ---
273
+
274
+ ## Error Handling Pattern
275
+
276
+ Consistent error handling with Paradigm logging:
277
+
278
+ ```
279
+ function riskyOperation():
280
+ tracker = log.component('#risky-op').start('Starting operation')
281
+
282
+ try:
283
+ // Happy path
284
+ result = doSomethingRisky()
285
+ tracker.success('Operation completed', { result })
286
+ return result
287
+
288
+ catch KnownError as error:
289
+ // Expected error - warn level
290
+ log.signal('!known-error').warn('Expected error occurred', {
291
+ type: error.type,
292
+ message: error.message
293
+ })
294
+ tracker.error('Operation failed (known)', { error: error.type })
295
+ return fallbackValue
296
+
297
+ catch error:
298
+ // Unexpected error - error level
299
+ log.signal('!unexpected-error').error('Unexpected error', {
300
+ message: error.message,
301
+ stack: error.stack
302
+ })
303
+ tracker.error('Operation failed (unexpected)', {
304
+ error: error.message
305
+ })
306
+ throw error
307
+ ```
308
+
309
+ ---
310
+
311
+ ## Middleware Pattern
312
+
313
+ Logging in request middleware:
314
+
315
+ ```
316
+ function loggingMiddleware(request, next):
317
+ correlationId = request.headers['x-correlation-id'] or generateId()
318
+
319
+ return withCorrelation(correlationId, async () => {
320
+ tracker = log.component('#' + request.path).start('Request started', {
321
+ method: request.method,
322
+ path: request.path
323
+ })
324
+
325
+ try:
326
+ response = await next()
327
+
328
+ tracker.success('Request completed', {
329
+ status: response.status
330
+ })
331
+
332
+ return response
333
+
334
+ catch error:
335
+ tracker.error('Request failed', {
336
+ error: error.message
337
+ })
338
+ throw error
339
+ })
340
+ ```
341
+
342
+ ---
343
+
344
+ ## Testing Pattern
345
+
346
+ When testing, you may want to suppress or capture logs:
347
+
348
+ ```
349
+ // In tests, set LOG_LEVEL=error to reduce noise
350
+ // Or mock the logger to capture calls
351
+
352
+ beforeEach:
353
+ originalLogLevel = process.env.LOG_LEVEL
354
+ process.env.LOG_LEVEL = 'error'
355
+
356
+ afterEach:
357
+ process.env.LOG_LEVEL = originalLogLevel
358
+ ```