@exaudeus/workrail 3.27.0 → 3.29.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 (160) hide show
  1. package/dist/console/assets/{index-FtTaDku8.js → index-BZ6HkxGf.js} +1 -1
  2. package/dist/console/index.html +1 -1
  3. package/dist/manifest.json +3 -3
  4. package/docs/README.md +57 -0
  5. package/docs/adrs/001-hybrid-storage-backend.md +38 -0
  6. package/docs/adrs/002-four-layer-context-classification.md +38 -0
  7. package/docs/adrs/003-checkpoint-trigger-strategy.md +35 -0
  8. package/docs/adrs/004-opt-in-encryption-strategy.md +36 -0
  9. package/docs/adrs/005-agent-first-workflow-execution-tokens.md +105 -0
  10. package/docs/adrs/006-append-only-session-run-event-log.md +76 -0
  11. package/docs/adrs/007-resume-and-checkpoint-only-sessions.md +51 -0
  12. package/docs/adrs/008-blocked-nodes-architectural-upgrade.md +178 -0
  13. package/docs/adrs/009-bridge-mode-single-instance-mcp.md +195 -0
  14. package/docs/adrs/010-release-pipeline.md +89 -0
  15. package/docs/architecture/README.md +7 -0
  16. package/docs/architecture/refactor-audit.md +364 -0
  17. package/docs/authoring-v2.md +527 -0
  18. package/docs/authoring.md +873 -0
  19. package/docs/changelog-recent.md +201 -0
  20. package/docs/configuration.md +505 -0
  21. package/docs/ctc-mcp-proposal.md +518 -0
  22. package/docs/design/README.md +22 -0
  23. package/docs/design/agent-cascade-protocol.md +96 -0
  24. package/docs/design/autonomous-console-design-candidates.md +253 -0
  25. package/docs/design/autonomous-console-design-review.md +111 -0
  26. package/docs/design/autonomous-platform-mvp-discovery.md +525 -0
  27. package/docs/design/claude-code-source-deep-dive.md +713 -0
  28. package/docs/design/console-cyberpunk-ui-discovery.md +504 -0
  29. package/docs/design/console-execution-trace-candidates-final.md +160 -0
  30. package/docs/design/console-execution-trace-candidates.md +211 -0
  31. package/docs/design/console-execution-trace-design-candidates-v2.md +113 -0
  32. package/docs/design/console-execution-trace-design-review.md +74 -0
  33. package/docs/design/console-execution-trace-discovery.md +394 -0
  34. package/docs/design/console-execution-trace-final-review.md +77 -0
  35. package/docs/design/console-execution-trace-review.md +92 -0
  36. package/docs/design/console-performance-discovery.md +415 -0
  37. package/docs/design/console-ui-backlog.md +280 -0
  38. package/docs/design/daemon-architecture-discovery.md +853 -0
  39. package/docs/design/daemon-design-candidates.md +318 -0
  40. package/docs/design/daemon-design-review-findings.md +119 -0
  41. package/docs/design/daemon-engine-design-candidates.md +210 -0
  42. package/docs/design/daemon-engine-design-review.md +131 -0
  43. package/docs/design/daemon-execution-engine-discovery.md +280 -0
  44. package/docs/design/daemon-gap-analysis.md +554 -0
  45. package/docs/design/daemon-owns-console-plan.md +168 -0
  46. package/docs/design/daemon-owns-console-review.md +91 -0
  47. package/docs/design/daemon-owns-console.md +195 -0
  48. package/docs/design/data-model-erd.md +11 -0
  49. package/docs/design/design-candidates-consolidate-dev-staleness.md +98 -0
  50. package/docs/design/design-candidates-walk-cache-depth-limit.md +80 -0
  51. package/docs/design/design-review-consolidate-dev-staleness.md +54 -0
  52. package/docs/design/design-review-walk-cache-depth-limit.md +48 -0
  53. package/docs/design/implementation-plan-consolidate-dev-staleness.md +142 -0
  54. package/docs/design/implementation-plan-walk-cache-depth-limit.md +141 -0
  55. package/docs/design/layer3b-ghost-nodes-design-candidates.md +229 -0
  56. package/docs/design/layer3b-ghost-nodes-design-review.md +93 -0
  57. package/docs/design/layer3b-ghost-nodes-implementation-plan.md +219 -0
  58. package/docs/design/list-workflows-latency-fix-plan.md +128 -0
  59. package/docs/design/list-workflows-latency-fix-review.md +55 -0
  60. package/docs/design/list-workflows-latency-fix.md +109 -0
  61. package/docs/design/native-context-management-api.md +11 -0
  62. package/docs/design/performance-sweep-2026-04.md +96 -0
  63. package/docs/design/routines-guide.md +219 -0
  64. package/docs/design/sequence-diagrams.md +11 -0
  65. package/docs/design/subagent-design-principles.md +220 -0
  66. package/docs/design/temporal-patterns-design-candidates.md +312 -0
  67. package/docs/design/temporal-patterns-design-review-findings.md +163 -0
  68. package/docs/design/test-isolation-from-config-file.md +335 -0
  69. package/docs/design/v2-core-design-locks.md +2746 -0
  70. package/docs/design/v2-lock-registry.json +734 -0
  71. package/docs/design/workflow-authoring-v2.md +1044 -0
  72. package/docs/design/workflow-docs-spec.md +218 -0
  73. package/docs/design/workflow-extension-points.md +687 -0
  74. package/docs/design/workrail-auto-trigger-system.md +359 -0
  75. package/docs/design/workrail-config-file-discovery.md +513 -0
  76. package/docs/docker.md +110 -0
  77. package/docs/generated/v2-lock-closure-plan.md +26 -0
  78. package/docs/generated/v2-lock-coverage.json +797 -0
  79. package/docs/generated/v2-lock-coverage.md +177 -0
  80. package/docs/ideas/backlog.md +3927 -0
  81. package/docs/ideas/design-candidates-mcp-resilience.md +208 -0
  82. package/docs/ideas/design-review-findings-mcp-resilience.md +119 -0
  83. package/docs/ideas/implementation_plan.md +249 -0
  84. package/docs/ideas/third-party-workflow-setup-design-thinking.md +1948 -0
  85. package/docs/implementation/02-architecture.md +316 -0
  86. package/docs/implementation/04-testing-strategy.md +124 -0
  87. package/docs/implementation/09-simple-workflow-guide.md +835 -0
  88. package/docs/implementation/13-advanced-validation-guide.md +874 -0
  89. package/docs/implementation/README.md +21 -0
  90. package/docs/integrations/claude-code.md +300 -0
  91. package/docs/integrations/firebender.md +315 -0
  92. package/docs/migration/v0.1.0.md +147 -0
  93. package/docs/naming-conventions.md +45 -0
  94. package/docs/planning/README.md +104 -0
  95. package/docs/planning/github-ticketing-playbook.md +195 -0
  96. package/docs/plans/README.md +24 -0
  97. package/docs/plans/agent-managed-ticketing-design.md +605 -0
  98. package/docs/plans/agentic-orchestration-roadmap.md +112 -0
  99. package/docs/plans/assessment-gates-engine-handoff.md +536 -0
  100. package/docs/plans/content-coherence-and-references.md +151 -0
  101. package/docs/plans/library-extraction-plan.md +340 -0
  102. package/docs/plans/mr-review-workflow-redesign.md +1451 -0
  103. package/docs/plans/native-context-management-epic.md +11 -0
  104. package/docs/plans/perf-fixes-design-candidates.md +225 -0
  105. package/docs/plans/perf-fixes-design-review-findings.md +61 -0
  106. package/docs/plans/perf-fixes-new-issues-candidates.md +264 -0
  107. package/docs/plans/perf-fixes-new-issues-review.md +110 -0
  108. package/docs/plans/prompt-fragments.md +53 -0
  109. package/docs/plans/ui-ux-workflow-design-candidates.md +120 -0
  110. package/docs/plans/ui-ux-workflow-discovery.md +100 -0
  111. package/docs/plans/ui-ux-workflow-review.md +48 -0
  112. package/docs/plans/v2-followup-enhancements.md +587 -0
  113. package/docs/plans/workflow-categories-candidates.md +105 -0
  114. package/docs/plans/workflow-categories-discovery.md +110 -0
  115. package/docs/plans/workflow-categories-review.md +51 -0
  116. package/docs/plans/workflow-discovery-model-candidates.md +94 -0
  117. package/docs/plans/workflow-discovery-model-discovery.md +74 -0
  118. package/docs/plans/workflow-discovery-model-review.md +48 -0
  119. package/docs/plans/workflow-source-setup-phase-1.md +245 -0
  120. package/docs/plans/workflow-source-setup-phase-2.md +361 -0
  121. package/docs/plans/workflow-staleness-detection-candidates.md +104 -0
  122. package/docs/plans/workflow-staleness-detection-review.md +58 -0
  123. package/docs/plans/workflow-staleness-detection.md +80 -0
  124. package/docs/plans/workflow-v2-design.md +69 -0
  125. package/docs/plans/workflow-v2-roadmap.md +74 -0
  126. package/docs/plans/workflow-validation-design.md +98 -0
  127. package/docs/plans/workflow-validation-roadmap.md +108 -0
  128. package/docs/plans/workrail-platform-vision.md +420 -0
  129. package/docs/reference/agent-context-cleaner-snippet.md +94 -0
  130. package/docs/reference/agent-context-guidance.md +140 -0
  131. package/docs/reference/context-optimization.md +284 -0
  132. package/docs/reference/example-workflow-repository-template/.github/workflows/validate.yml +125 -0
  133. package/docs/reference/example-workflow-repository-template/README.md +268 -0
  134. package/docs/reference/example-workflow-repository-template/workflows/example-workflow.json +80 -0
  135. package/docs/reference/external-workflow-repositories.md +916 -0
  136. package/docs/reference/feature-flags-architecture.md +472 -0
  137. package/docs/reference/feature-flags.md +349 -0
  138. package/docs/reference/god-tier-workflow-validation.md +272 -0
  139. package/docs/reference/loop-optimization.md +209 -0
  140. package/docs/reference/loop-validation.md +176 -0
  141. package/docs/reference/loops.md +465 -0
  142. package/docs/reference/mcp-platform-constraints.md +59 -0
  143. package/docs/reference/recovery.md +88 -0
  144. package/docs/reference/releases.md +177 -0
  145. package/docs/reference/troubleshooting.md +105 -0
  146. package/docs/reference/workflow-execution-contract.md +998 -0
  147. package/docs/roadmap/README.md +22 -0
  148. package/docs/roadmap/legacy-planning-status.md +103 -0
  149. package/docs/roadmap/now-next-later.md +70 -0
  150. package/docs/roadmap/open-work-inventory.md +389 -0
  151. package/docs/tickets/README.md +39 -0
  152. package/docs/tickets/next-up.md +76 -0
  153. package/docs/workflow-management.md +317 -0
  154. package/docs/workflow-templates.md +423 -0
  155. package/docs/workflow-validation.md +184 -0
  156. package/docs/workflows.md +254 -0
  157. package/package.json +3 -1
  158. package/spec/authoring-spec.json +61 -16
  159. package/workflows/workflow-for-workflows.json +252 -93
  160. package/workflows/workflow-for-workflows.v2.json +188 -77
@@ -0,0 +1,472 @@
1
+ # Feature Flags Architecture
2
+
3
+ ## System Overview
4
+
5
+ ```
6
+ ┌─────────────────────────────────────────────────────────────────┐
7
+ │ ENVIRONMENT VARIABLES │
8
+ │ │
9
+ │ WORKRAIL_ENABLE_SESSION_TOOLS=true │
10
+ │ WORKRAIL_ENABLE_EXPERIMENTAL_WORKFLOWS=false │
11
+ │ WORKRAIL_VERBOSE_LOGGING=false │
12
+ └────────────────────────┬────────────────────────────────────────┘
13
+
14
+ │ reads at startup
15
+
16
+ ┌─────────────────────────────────────────────────────────────────┐
17
+ │ EnvironmentFeatureFlagProvider │
18
+ │ │
19
+ │ • Parses environment variables │
20
+ │ • Validates boolean values │
21
+ │ • Creates immutable flag map │
22
+ │ • Logs enabled experimental features │
23
+ └────────────────────────┬────────────────────────────────────────┘
24
+
25
+ │ implements
26
+
27
+ ┌─────────────────────────────────────────────────────────────────┐
28
+ │ IFeatureFlagProvider (Interface) │
29
+ │ │
30
+ │ isEnabled(key: FeatureFlagKey): boolean │
31
+ │ getAll(): FeatureFlags │
32
+ │ getSummary(): string │
33
+ └────────────────────────┬────────────────────────────────────────┘
34
+
35
+ │ injected into
36
+
37
+ ┌─────────────────────────────────────────────────────────────────┐
38
+ │ Application Container │
39
+ │ (Dependency Injection) │
40
+ │ │
41
+ │ { │
42
+ │ featureFlags: IFeatureFlagProvider, │
43
+ │ storage: IWorkflowStorage, │
44
+ │ workflowService: WorkflowService, │
45
+ │ validationEngine: ValidationEngine, │
46
+ │ ... │
47
+ │ } │
48
+ └────────────────────────┬────────────────────────────────────────┘
49
+
50
+ │ provides to
51
+
52
+ ┌─────────────────────────────────────────────────────────────────┐
53
+ │ WorkflowOrchestrationServer │
54
+ │ │
55
+ │ constructor(container?: AppContainer) { │
56
+ │ this.featureFlags = container.featureFlags; │
57
+ │ │
58
+ │ if (this.featureFlags.isEnabled('sessionTools')) { │
59
+ │ // Initialize session tools │
60
+ │ this.sessionTools = createSessionTools(...); │
61
+ │ } else { │
62
+ │ this.sessionTools = []; │
63
+ │ } │
64
+ │ } │
65
+ └────────────────────────┬────────────────────────────────────────┘
66
+
67
+ │ registers
68
+
69
+ ┌─────────────────────────────────────────────────────────────────┐
70
+ │ MCP Tools │
71
+ │ │
72
+ │ ┌─────────────────────┐ ┌────────────────────────────┐ │
73
+ │ │ Core Tools │ │ Conditional Tools │ │
74
+ │ │ (always enabled) │ │ (feature flag gated) │ │
75
+ │ ├─────────────────────┤ ├────────────────────────────┤ │
76
+ │ │ • workflow_list │ │ • workrail_create_session │ │
77
+ │ │ • workflow_get │ │ • workrail_update_session │ │
78
+ │ │ • workflow_next │ │ • workrail_read_session │ │
79
+ │ │ • workflow_validate │ │ • workrail_open_dashboard │ │
80
+ │ └─────────────────────┘ └────────────────────────────┘ │
81
+ │ │
82
+ │ Tools are only registered if feature flag is enabled │
83
+ └─────────────────────────────────────────────────────────────────┘
84
+ ```
85
+
86
+ ## Data Flow: Feature Check
87
+
88
+ ```
89
+ Agent calls tool
90
+
91
+
92
+ MCP Server receives request
93
+
94
+
95
+ Is tool name "workrail_*"?
96
+
97
+ ├─── No ──► Route to workflow tools
98
+
99
+ └─── Yes ─► Check feature flag
100
+
101
+
102
+ featureFlags.isEnabled('sessionTools')?
103
+
104
+ ├─── true ──► Execute session tool
105
+ │ Return result
106
+
107
+ └─── false ─► Return error
108
+ "Session tools not enabled.
109
+ Set WORKRAIL_ENABLE_SESSION_TOOLS=true"
110
+ ```
111
+
112
+ ## Testing Flow: Dependency Injection
113
+
114
+ ```
115
+ ┌─────────────────────────────────────────────────────────────────┐
116
+ │ PRODUCTION │
117
+ ├─────────────────────────────────────────────────────────────────┤
118
+ │ │
119
+ │ const container = createAppContainer(); │
120
+ │ // Uses EnvironmentFeatureFlagProvider │
121
+ │ // Reads from process.env │
122
+ │ │
123
+ └─────────────────────────────────────────────────────────────────┘
124
+
125
+ ┌─────────────────────────────────────────────────────────────────┐
126
+ │ TESTING │
127
+ ├─────────────────────────────────────────────────────────────────┤
128
+ │ │
129
+ │ const testFlags = new StaticFeatureFlagProvider({ │
130
+ │ sessionTools: true, // ← Explicit test values │
131
+ │ experimentalWorkflows: false, │
132
+ │ }); │
133
+ │ │
134
+ │ const container = createAppContainer({ │
135
+ │ featureFlags: testFlags, // ← Inject test provider │
136
+ │ }); │
137
+ │ │
138
+ │ // Tests run with known, predictable flag values │
139
+ │ // No environment manipulation needed │
140
+ │ // Fast, isolated, deterministic │
141
+ │ │
142
+ └─────────────────────────────────────────────────────────────────┘
143
+ ```
144
+
145
+ ## Class Diagram
146
+
147
+ ```
148
+ ┌──────────────────────────────────────────────────────┐
149
+ │ <<interface>> │
150
+ │ IFeatureFlagProvider │
151
+ ├──────────────────────────────────────────────────────┤
152
+ │ + isEnabled(key: FeatureFlagKey): boolean │
153
+ │ + getAll(): FeatureFlags │
154
+ │ + getSummary(): string │
155
+ └─────────────────┬────────────────────────────────────┘
156
+
157
+ │ implements
158
+ ┏━━━━━━━━━━┻━━━━━━━━━━┓
159
+ ▼ ▼
160
+ ┌──────────────────┐ ┌────────────────────┐
161
+ │ Environment │ │ Static │
162
+ │ FeatureFlag │ │ FeatureFlag │
163
+ │ Provider │ │ Provider │
164
+ ├──────────────────┤ ├────────────────────┤
165
+ │ - flags: Map │ │ - flags: Map │
166
+ ├──────────────────┤ ├────────────────────┤
167
+ │ Production use │ │ Testing use │
168
+ │ Reads env vars │ │ Explicit values │
169
+ │ At startup │ │ No I/O │
170
+ └──────────────────┘ └────────────────────┘
171
+ ```
172
+
173
+ ## Lifecycle
174
+
175
+ ```
176
+ ┌─────────────────────────────────────────────────────────────────┐
177
+ │ APPLICATION STARTUP │
178
+ └─────────────────────────────────────────────────────────────────┘
179
+
180
+
181
+ ┌─────────────────────────────────────────────────────────────────┐
182
+ │ 1. Read Environment Variables │
183
+ │ - WORKRAIL_ENABLE_SESSION_TOOLS │
184
+ │ - WORKRAIL_ENABLE_EXPERIMENTAL_WORKFLOWS │
185
+ │ - WORKRAIL_VERBOSE_LOGGING │
186
+ └──────────────────────────┬──────────────────────────────────────┘
187
+
188
+ ┌─────────────────────────────────────────────────────────────────┐
189
+ │ 2. Parse & Validate │
190
+ │ - true/1/yes/on → true │
191
+ │ - false/0/no/off/undefined → false │
192
+ │ - Invalid values → warn + use default │
193
+ └──────────────────────────┬──────────────────────────────────────┘
194
+
195
+ ┌─────────────────────────────────────────────────────────────────┐
196
+ │ 3. Create Immutable Flag Map │
197
+ │ { │
198
+ │ sessionTools: false, │
199
+ │ experimentalWorkflows: false, │
200
+ │ verboseLogging: false, │
201
+ │ } │
202
+ └──────────────────────────┬──────────────────────────────────────┘
203
+
204
+ ┌─────────────────────────────────────────────────────────────────┐
205
+ │ 4. Log Enabled Experimental Features │
206
+ │ [FeatureFlags] Session tools disabled │
207
+ │ [FeatureFlags] (enable with WORKRAIL_ENABLE_SESSION_TOOLS)│
208
+ └──────────────────────────┬──────────────────────────────────────┘
209
+
210
+ ┌─────────────────────────────────────────────────────────────────┐
211
+ │ 5. Inject into Container │
212
+ │ container.featureFlags = provider │
213
+ └──────────────────────────┬──────────────────────────────────────┘
214
+
215
+ ┌─────────────────────────────────────────────────────────────────┐
216
+ │ 6. Services Check Flags at Runtime │
217
+ │ if (featureFlags.isEnabled('sessionTools')) { ... } │
218
+ └──────────────────────────┬──────────────────────────────────────┘
219
+
220
+ ┌─────────────────────────────────────────────────────────────────┐
221
+ │ 7. MCP Server Ready │
222
+ │ Tools registered based on enabled features │
223
+ └─────────────────────────────────────────────────────────────────┘
224
+ ```
225
+
226
+ ## Decision Tree: Adding a New Feature
227
+
228
+ ```
229
+ ┌───────────────────┐
230
+ │ New Feature Ready │
231
+ └─────────┬─────────┘
232
+
233
+
234
+ ┌───────────────────┐
235
+ │ Is it stable? │
236
+ └─────────┬─────────┘
237
+
238
+ ┌────────────┴────────────┐
239
+ │ │
240
+ ▼ ▼
241
+ ┌─────────────┐ ┌─────────────┐
242
+ │ YES │ │ NO │
243
+ │ Stable │ │ Experimental│
244
+ └──────┬──────┘ └──────┬──────┘
245
+ │ │
246
+ ▼ ▼
247
+ ┌──────────────────────┐ ┌──────────────────────┐
248
+ │ Add with │ │ Add with │
249
+ │ defaultValue: true │ │ defaultValue: false │
250
+ │ stable: true │ │ stable: false │
251
+ └──────┬───────────────┘ └──────┬───────────────┘
252
+ │ │
253
+ └────────────┬────────────┘
254
+
255
+
256
+ ┌──────────────────────┐
257
+ │ Add to │
258
+ │ FEATURE_FLAG_ │
259
+ │ DEFINITIONS │
260
+ └──────┬───────────────┘
261
+
262
+
263
+ ┌──────────────────────┐
264
+ │ Use in code: │
265
+ │ if (featureFlags │
266
+ │ .isEnabled('key')) │
267
+ └──────┬───────────────┘
268
+
269
+
270
+ ┌──────────────────────┐
271
+ │ Write tests │
272
+ │ (enabled & disabled) │
273
+ └──────┬───────────────┘
274
+
275
+
276
+ ┌──────────────────────┐
277
+ │ Merge to main │
278
+ │ (flag OFF by default)│
279
+ └──────┬───────────────┘
280
+
281
+
282
+ ┌──────────────────────┐
283
+ │ Test in staging │
284
+ │ (enable with env var)│
285
+ └──────┬───────────────┘
286
+
287
+
288
+ ┌──────────────────────┐
289
+ │ Feature proven │
290
+ │ stable? │
291
+ └──────┬───────────────┘
292
+
293
+ ┌────────────┴────────────┐
294
+ │ │
295
+ ▼ ▼
296
+ ┌────────┐ ┌────────────┐
297
+ │ YES │ │ NO - Iterate│
298
+ └────┬───┘ └────────────┘
299
+
300
+
301
+ ┌────────────────────┐
302
+ │ Flip default to ON │
303
+ │ stable: true │
304
+ └────┬───────────────┘
305
+
306
+
307
+ ┌────────────────────┐
308
+ │ After 2+ releases │
309
+ │ Remove flag │
310
+ └────────────────────┘
311
+ ```
312
+
313
+ ## SOLID Principles Visualization
314
+
315
+ ```
316
+ ┌────────────────────────────────────────────────────────────────┐
317
+ │ S - Single Responsibility Principle │
318
+ ├────────────────────────────────────────────────────────────────┤
319
+ │ │
320
+ │ ┌───────────────────────────┐ │
321
+ │ │ EnvironmentFeatureFlag │ One job: Read env vars │
322
+ │ │ Provider │ and parse booleans │
323
+ │ └───────────────────────────┘ │
324
+ │ │
325
+ │ ┌───────────────────────────┐ │
326
+ │ │ StaticFeatureFlagProvider │ One job: Provide test │
327
+ │ │ │ values │
328
+ │ └───────────────────────────┘ │
329
+ │ │
330
+ └────────────────────────────────────────────────────────────────┘
331
+
332
+ ┌────────────────────────────────────────────────────────────────┐
333
+ │ O - Open/Closed Principle │
334
+ ├────────────────────────────────────────────────────────────────┤
335
+ │ │
336
+ │ Add new flags without modifying existing code: │
337
+ │ │
338
+ │ FEATURE_FLAG_DEFINITIONS.push({ │
339
+ │ key: 'newFeature', │
340
+ │ envVar: 'WORKRAIL_NEW_FEATURE', │
341
+ │ defaultValue: false, │
342
+ │ }); │
343
+ │ │
344
+ │ No changes needed to provider classes! │
345
+ │ │
346
+ └────────────────────────────────────────────────────────────────┘
347
+
348
+ ┌────────────────────────────────────────────────────────────────┐
349
+ │ L - Liskov Substitution Principle │
350
+ ├────────────────────────────────────────────────────────────────┤
351
+ │ │
352
+ │ Any IFeatureFlagProvider implementation works: │
353
+ │ │
354
+ │ function useProvider(provider: IFeatureFlagProvider) { │
355
+ │ return provider.isEnabled('sessionTools'); │
356
+ │ } │
357
+ │ │
358
+ │ useProvider(new EnvironmentFeatureFlagProvider()); │
359
+ │ useProvider(new StaticFeatureFlagProvider()); │
360
+ │ useProvider(new CustomProvider()); │
361
+ │ │
362
+ └────────────────────────────────────────────────────────────────┘
363
+
364
+ ┌────────────────────────────────────────────────────────────────┐
365
+ │ I - Interface Segregation Principle │
366
+ ├────────────────────────────────────────────────────────────────┤
367
+ │ │
368
+ │ Focused interface (only 3 methods): │
369
+ │ │
370
+ │ interface IFeatureFlagProvider { │
371
+ │ isEnabled(key): boolean; ← Most used │
372
+ │ getAll(): FeatureFlags; ← Bulk access │
373
+ │ getSummary(): string; ← Debugging │
374
+ │ } │
375
+ │ │
376
+ │ No bloat, no unused methods │
377
+ │ │
378
+ └────────────────────────────────────────────────────────────────┘
379
+
380
+ ┌────────────────────────────────────────────────────────────────┐
381
+ │ D - Dependency Inversion Principle │
382
+ ├────────────────────────────────────────────────────────────────┤
383
+ │ │
384
+ │ ┌──────────────────────┐ │
385
+ │ │ WorkflowServer │ Depends on abstraction │
386
+ │ │ (High-level) │ (not concrete class) │
387
+ │ └──────────┬───────────┘ │
388
+ │ │ │
389
+ │ ▼ │
390
+ │ ┌──────────────────────┐ │
391
+ │ │ IFeatureFlagProvider │ ← Interface (abstraction) │
392
+ │ └──────────┬───────────┘ │
393
+ │ │ │
394
+ │ ▼ │
395
+ │ ┌──────────────────────┐ │
396
+ │ │ EnvironmentFeature │ Concrete implementation │
397
+ │ │ FlagProvider │ depends on interface │
398
+ │ └──────────────────────┘ │
399
+ │ │
400
+ │ Easy to swap implementations │
401
+ │ Easy to test │
402
+ │ │
403
+ └────────────────────────────────────────────────────────────────┘
404
+ ```
405
+
406
+ ## Comparison: Before vs After
407
+
408
+ ### Before (Hardcoded Comments)
409
+
410
+ ```typescript
411
+ class WorkflowOrchestrationServer {
412
+ constructor() {
413
+ // Manual commenting/uncommenting
414
+ // Not testable
415
+ // Blocks releases
416
+
417
+ // Initialize session management (DISABLED for release)
418
+ // TODO: Re-enable session tools when ready for production
419
+ this.sessionManager = new SessionManager();
420
+ this.httpServer = new HttpServer(this.sessionManager);
421
+ this.sessionTools = []; // Disabled: createSessionTools(...)
422
+ }
423
+
424
+ async initialize(): Promise<void> {
425
+ // Start HTTP server (DISABLED for release)
426
+ // TODO: Re-enable when ready
427
+ // await this.httpServer.start();
428
+ }
429
+ }
430
+ ```
431
+
432
+ ### After (Clean Feature Flags)
433
+
434
+ ```typescript
435
+ class WorkflowOrchestrationServer {
436
+ constructor(container?: AppContainer) {
437
+ // Clean boolean check
438
+ // Fully testable
439
+ // Never blocks releases
440
+
441
+ this.container = container ?? createAppContainer();
442
+ this.featureFlags = this.container.featureFlags;
443
+
444
+ if (this.featureFlags.isEnabled('sessionTools')) {
445
+ this.sessionManager = new SessionManager();
446
+ this.httpServer = new HttpServer(this.sessionManager);
447
+ this.sessionTools = createSessionTools(this.sessionManager, this.httpServer);
448
+ } else {
449
+ this.sessionTools = [];
450
+ }
451
+ }
452
+
453
+ async initialize(): Promise<void> {
454
+ if (this.featureFlags.isEnabled('sessionTools') && this.httpServer) {
455
+ await this.httpServer.start();
456
+ }
457
+ }
458
+ }
459
+ ```
460
+
461
+ ## Benefits Summary
462
+
463
+ | Aspect | Before | After |
464
+ |--------|--------|-------|
465
+ | **Enabling feature** | Edit code, uncomment lines | Set env var |
466
+ | **Testing** | Manual mocking, hard to test | Inject `StaticFeatureFlagProvider` |
467
+ | **Release blocking** | Yes, must manually disable | No, flags control features |
468
+ | **Type safety** | No | Full TypeScript support |
469
+ | **Trunk-based dev** | Difficult | Easy |
470
+ | **Code cleanliness** | Comments everywhere | Clean conditional logic |
471
+ | **Debugging** | Unclear what's disabled | Clear logs |
472
+