cmdx 1.9.1 → 1.10.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.
data/LLM.md CHANGED
@@ -1,40 +1,33 @@
1
- # CMDx Documentation
2
-
3
- This file contains all the CMDx documentation consolidated from the docs directory.
1
+ # Getting Started
4
2
 
5
- ---
3
+ CMDx is a Ruby framework for building maintainable, observable business logic through composable command objects. It brings structure, consistency, and powerful developer tools to your business processes.
6
4
 
7
- url: https://github.com/drexed/cmdx/blob/main/docs/getting_started.md
8
- ---
5
+ **Common challenges it solves:**
9
6
 
10
- # Getting Started
7
+ - Inconsistent service object patterns across your codebase
8
+ - Limited logging makes debugging a nightmare
9
+ - Fragile error handling erodes confidence
11
10
 
12
- CMDx is a Ruby framework for building maintainable, observable business logic through composable command objects. Design robust workflows with automatic attribute validation, structured error handling, comprehensive logging, and intelligent execution flow control.
11
+ **What you get:**
13
12
 
14
- **Common Challenges:**
13
+ - Consistent, standardized architecture
14
+ - Built-in flow control and error handling
15
+ - Composable, reusable workflows
16
+ - Comprehensive logging for observability
17
+ - Attribute validation with type coercions
18
+ - Sensible defaults and developer-friendly APIs
15
19
 
16
- - Inconsistent patterns across implementations
17
- - Minimal or no logging, making debugging painful
18
- - Fragile designs that erode developer confidence
20
+ ## The CERO Pattern
19
21
 
20
- **CMDx Solutions:**
22
+ CMDx embraces the Compose, Execute, React, Observe (CERO) pattern—a simple yet powerful approach to building reliable business logic.
21
23
 
22
- - Establishes a consistent, standardized design
23
- - Provides flow control and error handling
24
- - Supports composable, reusable workflows
25
- - Includes detailed logging for observability
26
- - Defines input attributes with fallback defaults
27
- - Adds validations and type coercions
28
- - Plus many other developer-friendly tools
24
+ 🧩 **Compose** Define small, focused tasks with typed attributes and validations
29
25
 
30
- ## Compose, Execute, React, Observe pattern
26
+ **Execute** Run tasks with clear outcomes and pluggable behaviors
31
27
 
32
- CMDx encourages breaking business logic into composable tasks. Each task can be combined into larger workflows, executed with standardized flow control, and fully observed through logging, validations, and context.
28
+ 🔄 **React** Adapt to outcomes by chaining follow-up tasks or handling faults
33
29
 
34
- - **Compose** Define small, contract-driven tasks with typed attributes, validations, and natural workflow composition.
35
- - **Execute** → Run tasks with clear outcomes, intentional halts, and pluggable behaviors via middlewares and callbacks.
36
- - **React** → Adapt to outcomes by chaining follow-up tasks, handling faults, or shaping future flows.
37
- - **Observe** → Capture immutable results, structured logs, and full execution chains for reliable tracing and insight.
30
+ 🔍 **Observe** Capture structured logs and execution chains for debugging
38
31
 
39
32
  ## Installation
40
33
 
@@ -54,45 +47,54 @@ This creates `config/initializers/cmdx.rb` file.
54
47
 
55
48
  ## Configuration Hierarchy
56
49
 
57
- CMDx follows a two-tier configuration hierarchy:
50
+ CMDx uses a straightforward two-tier configuration system:
51
+
52
+ 1. **Global Configuration** — Framework-wide defaults
53
+ 2. **Task Settings** — Class-level overrides using `settings`
58
54
 
59
- 1. **Global Configuration**: Framework-wide defaults
60
- 2. **Task Settings**: Class-level overrides via `settings`
55
+ !!! warning "Important"
61
56
 
62
- > [!IMPORTANT]
63
- > Task-level settings take precedence over global configuration. Settings are inherited from superclasses and can be overridden in subclasses.
57
+ Task settings take precedence over global config. Settings are inherited from parent classes and can be overridden in subclasses.
64
58
 
65
59
  ## Global Configuration
66
60
 
67
- Global configuration settings apply to all tasks inherited from `CMDx::Task`.
68
- Globally these settings are initialized with sensible defaults.
61
+ Configure framework-wide defaults that apply to all tasks. These settings come with sensible defaults out of the box.
69
62
 
70
63
  ### Breakpoints
71
64
 
72
- Raise `CMDx::Fault` when a task called with `execute!` returns a matching status.
65
+ Control when `execute!` raises a `CMDx::Fault` based on task status.
73
66
 
74
67
  ```ruby
75
68
  CMDx.configure do |config|
76
- # String or Array[String]
77
- config.task_breakpoints = "failed"
69
+ config.task_breakpoints = "failed" # String or Array[String]
78
70
  end
79
71
  ```
80
72
 
81
- Workflow breakpoints stops execution and of workflow pipeline on the first task that returns a matching status and throws its `CMDx::Fault`.
73
+ For workflows, configure which statuses halt the execution pipeline:
82
74
 
83
75
  ```ruby
84
76
  CMDx.configure do |config|
85
- # String or Array[String]
86
77
  config.workflow_breakpoints = ["skipped", "failed"]
87
78
  end
88
79
  ```
89
80
 
81
+ ### Rollback
82
+
83
+ Control when a `rollback` of task execution is called.
84
+
85
+ ```ruby
86
+ CMDx.configure do |config|
87
+ config.rollback_on = ["failed"] # String or Array[String]
88
+ end
89
+ ```
90
+
90
91
  ### Backtraces
91
92
 
92
- Enable backtraces to be logged on any non-fault exceptions for improved debugging context. Run them through a cleaner to remove unwanted stack trace noise.
93
+ Enable detailed backtraces for non-fault exceptions to improve debugging. Optionally clean up stack traces to remove framework noise.
94
+
95
+ !!! note
93
96
 
94
- > [!NOTE]
95
- > The `backtrace_cleaner` is set to `Rails.backtrace_cleaner.clean` in a Rails env by default.
97
+ In Rails environments, `backtrace_cleaner` defaults to `Rails.backtrace_cleaner.clean`.
96
98
 
97
99
  ```ruby
98
100
  CMDx.configure do |config|
@@ -109,10 +111,11 @@ end
109
111
 
110
112
  ### Exception Handlers
111
113
 
112
- Use exception handlers are called on non-fault standard error based exceptions.
114
+ Register handlers that run when non-fault exceptions occur.
115
+
116
+ !!! tip
113
117
 
114
- > [!TIP]
115
- > Use exception handlers to send errors to your APM of choice.
118
+ Use exception handlers to send errors to your APM of choice.
116
119
 
117
120
  ```ruby
118
121
  CMDx.configure do |config|
@@ -136,7 +139,7 @@ end
136
139
 
137
140
  ### Middlewares
138
141
 
139
- See the [Middelwares](#https://github.com/drexed/cmdx/blob/main/docs/middlewares.md#declarations) docs for task level configurations.
142
+ See the [Middlewares](https://github.com/drexed/cmdx/blob/main/docs/middlewares.md#declarations) docs for task level configurations.
140
143
 
141
144
  ```ruby
142
145
  CMDx.configure do |config|
@@ -160,12 +163,13 @@ CMDx.configure do |config|
160
163
  end
161
164
  ```
162
165
 
163
- > [!NOTE]
164
- > Middlewares are executed in registration order. Each middleware wraps the next, creating an execution chain around task logic.
166
+ !!! note
167
+
168
+ Middlewares are executed in registration order. Each middleware wraps the next, creating an execution chain around task logic.
165
169
 
166
170
  ### Callbacks
167
171
 
168
- See the [Callbacks](#https://github.com/drexed/cmdx/blob/main/docs/callbacks.md#declarations) docs for task level configurations.
172
+ See the [Callbacks](https://github.com/drexed/cmdx/blob/main/docs/callbacks.md#declarations) docs for task level configurations.
169
173
 
170
174
  ```ruby
171
175
  CMDx.configure do |config|
@@ -191,7 +195,7 @@ end
191
195
 
192
196
  ### Coercions
193
197
 
194
- See the [Attributes - Coercions](#https://github.com/drexed/cmdx/blob/main/docs/attributes/coercions.md#declarations) docs for task level configurations.
198
+ See the [Attributes - Coercions](https://github.com/drexed/cmdx/blob/main/docs/attributes/coercions.md#declarations) docs for task level configurations.
195
199
 
196
200
  ```ruby
197
201
  CMDx.configure do |config|
@@ -217,7 +221,7 @@ end
217
221
 
218
222
  ### Validators
219
223
 
220
- See the [Attributes - Validations](#https://github.com/drexed/cmdx/blob/main/docs/attributes/validations.md#declarations) docs for task level configurations.
224
+ See the [Attributes - Validations](https://github.com/drexed/cmdx/blob/main/docs/attributes/validations.md#declarations) docs for task level configurations.
221
225
 
222
226
  ```ruby
223
227
  CMDx.configure do |config|
@@ -264,7 +268,8 @@ class GenerateInvoice < CMDx::Task
264
268
  deprecated: true, # Task deprecations
265
269
  retries: 3, # Non-fault exception retries
266
270
  retry_on: [External::ApiError], # List of exceptions to retry on
267
- retry_jitter: 1 # Space between retry iteration, eg: current retry num + 1
271
+ retry_jitter: 1, # Space between retry iteration, eg: current retry num + 1
272
+ rollback_on: ["failed", "skipped"], # Rollback on override
268
273
  )
269
274
 
270
275
  def work
@@ -273,13 +278,13 @@ class GenerateInvoice < CMDx::Task
273
278
  end
274
279
  ```
275
280
 
276
- > [!IMPORTANT]
277
- > Retries reuse the same context when executing its work. By default all `StandardErrors` will be retried if no `retry_on` option is passed.
281
+ !!! warning "Important"
282
+
283
+ Retries reuse the same context. By default, all `StandardError` exceptions (including faults) are retried unless you specify `retry_on` option for specific matches.
278
284
 
279
285
  ### Registrations
280
286
 
281
- Register middlewares, callbacks, coercions, and validators on a specific task.
282
- Deregister options that should not be available.
287
+ Register or deregister middlewares, callbacks, coercions, and validators for specific tasks:
283
288
 
284
289
  ```ruby
285
290
  class SendCampaignEmail < CMDx::Task
@@ -331,8 +336,9 @@ end
331
336
 
332
337
  ### Resetting
333
338
 
334
- > [!WARNING]
335
- > Resetting configuration affects the entire application. Use primarily in test environments or during application initialization.
339
+ !!! warning
340
+
341
+ Resetting affects your entire application. Use this primarily in test environments.
336
342
 
337
343
  ```ruby
338
344
  # Reset to framework defaults
@@ -369,8 +375,9 @@ class ModerateBlogPost < CMDx::Task
369
375
  end
370
376
  ```
371
377
 
372
- > [!TIP]
373
- > Use **present tense verbs + noun** for task names, eg: `ModerateBlogPost`, `ScheduleAppointment`, `ValidateDocument`
378
+ !!! tip
379
+
380
+ Use **present tense verbs + noun** for task names, eg: `ModerateBlogPost`, `ScheduleAppointment`, `ValidateDocument`
374
381
 
375
382
  ## Type safety
376
383
 
@@ -381,18 +388,13 @@ CMDx includes built-in RBS (Ruby Type Signature) inline annotations throughout t
381
388
  - **Self-documenting code** — Clear method signatures and return types
382
389
  - **Refactoring confidence** — Type-aware refactoring reduces bugs
383
390
 
384
- ---
385
-
386
- url: https://github.com/drexed/cmdx/blob/main/docs/basics/setup.md
387
- ---
388
-
389
391
  # Basics - Setup
390
392
 
391
- Tasks are the core building blocks of CMDx, encapsulating business logic within structured, reusable objects. Each task represents a unit of work with automatic attribute validation, error handling, and execution tracking.
393
+ Tasks are the heart of CMDx—self-contained units of business logic with built-in validation, error handling, and execution tracking.
392
394
 
393
395
  ## Structure
394
396
 
395
- Tasks inherit from `CMDx::Task` and require only a `work` method:
397
+ Tasks need only two things: inherit from `CMDx::Task` and define a `work` method:
396
398
 
397
399
  ```ruby
398
400
  class ValidateDocument < CMDx::Task
@@ -402,7 +404,7 @@ class ValidateDocument < CMDx::Task
402
404
  end
403
405
  ```
404
406
 
405
- An exception will be raised if a work method is not defined.
407
+ Without a `work` method, execution raises `CMDx::UndefinedMethodError`.
406
408
 
407
409
  ```ruby
408
410
  class IncompleteTask < CMDx::Task
@@ -412,10 +414,25 @@ end
412
414
  IncompleteTask.execute #=> raises CMDx::UndefinedMethodError
413
415
  ```
414
416
 
417
+ ## Rollback
418
+
419
+ Undo any operations linked to the given status, helping to restore a pristine state.
420
+
421
+ ```ruby
422
+ class ValidateDocument < CMDx::Task
423
+ def work
424
+ # Your logic here...
425
+ end
426
+
427
+ def rollback
428
+ # Your undo logic...
429
+ end
430
+ end
431
+ ```
432
+
415
433
  ## Inheritance
416
434
 
417
- All configuration options are inheritable by any child classes.
418
- Create a base class to share common configuration across tasks:
435
+ Share configuration across tasks using inheritance:
419
436
 
420
437
  ```ruby
421
438
  class ApplicationTask < CMDx::Task
@@ -441,10 +458,11 @@ end
441
458
 
442
459
  ## Lifecycle
443
460
 
444
- Tasks follow a predictable call pattern with specific states and statuses:
461
+ Tasks follow a predictable execution pattern:
445
462
 
446
- > [!CAUTION]
447
- > Tasks are single-use objects. Once executed, they are frozen and cannot be executed again.
463
+ !!! danger "Caution"
464
+
465
+ Tasks are single-use objects. Once executed, they're frozen and immutable.
448
466
 
449
467
  | Stage | State | Status | Description |
450
468
  |-------|-------|--------|-------------|
@@ -453,20 +471,15 @@ Tasks follow a predictable call pattern with specific states and statuses:
453
471
  | **Execution** | `executing` | `success`/`failed`/`skipped` | `work` method runs |
454
472
  | **Completion** | `executed` | `success`/`failed`/`skipped` | Result finalized |
455
473
  | **Freezing** | `executed` | `success`/`failed`/`skipped` | Task becomes immutable |
456
-
457
- ---
458
-
459
- url: https://github.com/drexed/cmdx/blob/main/docs/basics/execution.md
460
- ---
474
+ | **Rollback** | `executed` | `failed`/`skipped` | Work undone |
461
475
 
462
476
  # Basics - Execution
463
477
 
464
- Task execution in CMDx provides two distinct methods that handle success and halt scenarios differently. Understanding when to use each method is crucial for proper error handling and control flow in your application workflows.
478
+ CMDx offers two execution methods with different error handling approaches. Choose based on your needs: safe result handling or exception-based control flow.
465
479
 
466
- ## Methods Overview
480
+ ## Execution Methods
467
481
 
468
- Tasks are single-use objects. Once executed, they are frozen and cannot be executed again.
469
- Create a new instance for subsequent executions.
482
+ Both methods return results, but handle failures differently:
470
483
 
471
484
  | Method | Returns | Exceptions | Use Case |
472
485
  |--------|---------|------------|----------|
@@ -475,10 +488,7 @@ Create a new instance for subsequent executions.
475
488
 
476
489
  ## Non-bang Execution
477
490
 
478
- The `execute` method always returns a `CMDx::Result` object regardless of execution outcome.
479
- This is the preferred method for most use cases.
480
-
481
- Any unhandled exceptions will be caught and returned as a task failure.
491
+ Always returns a `CMDx::Result`, never raises exceptions. Perfect for most use cases.
482
492
 
483
493
  ```ruby
484
494
  result = CreateAccount.execute(email: "user@example.com")
@@ -496,23 +506,22 @@ result.status #=> "success"
496
506
 
497
507
  ## Bang Execution
498
508
 
499
- The bang `execute!` method raises a `CMDx::Fault` based exception when tasks fail or are skipped, and returns a `CMDx::Result` object only on success.
500
-
501
- It raises any unhandled non-fault exceptions caused during execution.
509
+ Raises `CMDx::Fault` exceptions on failure or skip. Returns results only on success.
502
510
 
503
511
  | Exception | Raised When |
504
512
  |-----------|-------------|
505
513
  | `CMDx::FailFault` | Task execution fails |
506
514
  | `CMDx::SkipFault` | Task execution is skipped |
507
515
 
508
- > [!IMPORTANT]
509
- > `execute!` behavior depends on the `task_breakpoints` or `workflow_breakpoints` configuration. By default, it raises exceptions only on failures.
516
+ !!! warning "Important"
517
+
518
+ Behavior depends on `task_breakpoints` or `workflow_breakpoints` config. Default: only failures raise exceptions.
510
519
 
511
520
  ```ruby
512
521
  begin
513
522
  result = CreateAccount.execute!(email: "user@example.com")
514
523
  SendWelcomeEmail.execute(result.context)
515
- rescue CMDx::Fault => e
524
+ rescue CMDx::FailFault => e
516
525
  ScheduleAccountRetryJob.perform_later(e.result.context.email)
517
526
  rescue CMDx::SkipFault => e
518
527
  Rails.logger.info("Account creation skipped: #{e.result.reason}")
@@ -534,7 +543,7 @@ task.id #=> "abc123..." (unique task ID)
534
543
  task.context.email #=> "user@example.com"
535
544
  task.context.send_welcome #=> true
536
545
  task.result.state #=> "initialized"
537
- result.status #=> "success"
546
+ task.result.status #=> "success"
538
547
 
539
548
  # Manual execution
540
549
  task.execute
@@ -559,19 +568,15 @@ result.chain #=> Task execution chain
559
568
  # Context and metadata
560
569
  result.context #=> Context with all task data
561
570
  result.metadata #=> Hash with execution metadata
562
-
563
- ---
564
-
565
- url: https://github.com/drexed/cmdx/blob/main/docs/basics/context.md
566
- ---
571
+ ```
567
572
 
568
573
  # Basics - Context
569
574
 
570
- Task context provides flexible data storage, access, and sharing within task execution. It serves as the primary data container for all task inputs, intermediate results, and outputs.
575
+ Context is your data container for inputs, intermediate values, and outputs. It makes sharing data between tasks effortless.
571
576
 
572
577
  ## Assigning Data
573
578
 
574
- Context is automatically populated with all inputs passed to a task. All keys are normalized to symbols for consistent access:
579
+ Context automatically captures all task inputs, normalizing keys to symbols:
575
580
 
576
581
  ```ruby
577
582
  # Direct execution
@@ -581,12 +586,13 @@ CalculateShipping.execute(weight: 2.5, destination: "CA")
581
586
  CalculateShipping.new(weight: 2.5, "destination" => "CA")
582
587
  ```
583
588
 
584
- > [!IMPORTANT]
585
- > String keys are automatically converted to symbols. Use symbols for consistency in your code.
589
+ !!! warning "Important"
590
+
591
+ String keys convert to symbols automatically. Prefer symbols for consistency.
586
592
 
587
593
  ## Accessing Data
588
594
 
589
- Context provides multiple access patterns with automatic nil safety:
595
+ Access context data using method notation, hash keys, or safe accessors:
590
596
 
591
597
  ```ruby
592
598
  class CalculateShipping < CMDx::Task
@@ -609,8 +615,9 @@ class CalculateShipping < CMDx::Task
609
615
  end
610
616
  ```
611
617
 
612
- > [!IMPORTANT]
613
- > Accessing undefined context attributes returns `nil` instead of raising errors, enabling graceful handling of optional attributes.
618
+ !!! warning "Important"
619
+
620
+ Undefined attributes return `nil` instead of raising errors—perfect for optional data.
614
621
 
615
622
  ## Modifying Context
616
623
 
@@ -651,12 +658,13 @@ class CalculateShipping < CMDx::Task
651
658
  end
652
659
  ```
653
660
 
654
- > [!TIP]
655
- > Use context for both input values and intermediate results. This creates natural data flow through your task execution pipeline.
661
+ !!! tip
662
+
663
+ Use context for both input values and intermediate results. This creates natural data flow through your task execution pipeline.
656
664
 
657
665
  ## Data Sharing
658
666
 
659
- Context enables seamless data flow between related tasks in complex workflows:
667
+ Share context across tasks for seamless data flow:
660
668
 
661
669
  ```ruby
662
670
  # During execution
@@ -684,21 +692,17 @@ result = CalculateShipping.execute(destination: "New York, NY")
684
692
  CreateShippingLabel.execute(result)
685
693
  ```
686
694
 
687
- ---
688
-
689
- url: https://github.com/drexed/cmdx/blob/main/docs/basics/chain.md
690
- ---
691
-
692
695
  # Basics - Chain
693
696
 
694
- Chains automatically group related task executions within a thread, providing unified tracking, correlation, and execution context management. Each thread maintains its own chain through thread-local storage, eliminating the need for manual coordination.
697
+ Chains automatically track related task executions within a thread. Think of them as execution traces that help you understand what happened and in what order.
695
698
 
696
699
  ## Management
697
700
 
698
- Each thread maintains its own chain context through thread-local storage, providing automatic isolation without manual coordination.
701
+ Each thread maintains its own isolated chain using thread-local storage.
702
+
703
+ !!! warning
699
704
 
700
- > [!WARNING]
701
- > Chain operations are thread-local. Never share chain references across threads as this can lead to race conditions and data corruption.
705
+ Chains are thread-local. Don't share chain references across threads—it causes race conditions.
702
706
 
703
707
  ```ruby
704
708
  # Thread A
@@ -720,10 +724,11 @@ CMDx::Chain.clear #=> Clears current thread's chain
720
724
 
721
725
  ## Links
722
726
 
723
- Every task execution automatically creates or joins the current thread's chain:
727
+ Tasks automatically create or join the current thread's chain:
728
+
729
+ !!! warning "Important"
724
730
 
725
- > [!IMPORTANT]
726
- > Chain creation is automatic and transparent. You don't need to manually manage chain lifecycle.
731
+ Chain management is automatic—no manual lifecycle handling needed.
727
732
 
728
733
  ```ruby
729
734
  class ImportDataset < CMDx::Task
@@ -746,7 +751,7 @@ end
746
751
 
747
752
  ## Inheritance
748
753
 
749
- When tasks call subtasks within the same thread, all executions automatically inherit the current chain, creating a unified execution trail.
754
+ Subtasks automatically inherit the current thread's chain, building a unified execution trail:
750
755
 
751
756
  ```ruby
752
757
  class ImportDataset < CMDx::Task
@@ -771,10 +776,11 @@ chain.results.map { |r| r.task.class }
771
776
 
772
777
  ## Structure
773
778
 
774
- Chains provide comprehensive execution information with state delegation:
779
+ Chains expose comprehensive execution information:
775
780
 
776
- > [!IMPORTANT]
777
- > Chain state always reflects the first (outer-most) task result, not individual subtask outcomes. Subtasks maintain their own success/failure states.
781
+ !!! warning "Important"
782
+
783
+ Chain state reflects the first (outermost) task result. Subtasks maintain their own states.
778
784
 
779
785
  ```ruby
780
786
  result = ImportDataset.execute(dataset_id: 456)
@@ -795,21 +801,17 @@ chain.results.each_with_index do |result, index|
795
801
  end
796
802
  ```
797
803
 
798
- ---
799
-
800
- url: https://github.com/drexed/cmdx/blob/main/docs/interruptions/halt.md
801
- ---
802
-
803
804
  # Interruptions - Halt
804
805
 
805
- Halting stops task execution with explicit intent signaling. Tasks provide two primary halt methods that control execution flow and result in different outcomes.
806
+ Stop task execution intentionally using `skip!` or `fail!`. Both methods signal clear intent about why execution stopped.
806
807
 
807
808
  ## Skipping
808
809
 
809
- `skip!` communicates that the task is to be intentionally bypassed. This represents a controlled, intentional interruption where the task determines that execution is not necessary or appropriate.
810
+ Use `skip!` when the task doesn't need to run. It's a no-op, not an error.
811
+
812
+ !!! warning "Important"
810
813
 
811
- > [!IMPORTANT]
812
- > Skipping is a no-op, not a failure or error and are considered successful outcomes.
814
+ Skipped tasks are considered "good" outcomes—they succeeded by doing nothing.
813
815
 
814
816
  ```ruby
815
817
  class ProcessInventory < CMDx::Task
@@ -844,7 +846,7 @@ result.reason #=> "Warehouse closed"
844
846
 
845
847
  ## Failing
846
848
 
847
- `fail!` communicates that the task encountered an impediment that prevents successful completion. This represents controlled failure where the task explicitly determines that execution cannot continue.
849
+ Use `fail!` when the task can't complete successfully. It signals controlled, intentional failure:
848
850
 
849
851
  ```ruby
850
852
  class ProcessRefund < CMDx::Task
@@ -879,7 +881,7 @@ result.reason #=> "Refund period has expired"
879
881
 
880
882
  ## Metadata Enrichment
881
883
 
882
- Both halt methods accept metadata to provide additional context about the interruption. Metadata is stored as a hash and becomes available through the result object.
884
+ Enrich halt calls with metadata for better debugging and error handling:
883
885
 
884
886
  ```ruby
885
887
  class ProcessRenewal < CMDx::Task
@@ -979,7 +981,7 @@ end
979
981
 
980
982
  ## Best Practices
981
983
 
982
- Always try to provide a `reason` when using halt methods. This provides clear context for debugging and creates meaningful exception messages.
984
+ Always provide a reason for better debugging and clearer exception messages:
983
985
 
984
986
  ```ruby
985
987
  # Good: Clear, specific reason
@@ -997,10 +999,11 @@ fail! #=> "Unspecified"
997
999
 
998
1000
  ## Manual Errors
999
1001
 
1000
- There are rare cases where you need to manually assign errors.
1002
+ For rare cases, manually add errors before halting:
1001
1003
 
1002
- > [!IMPORTANT]
1003
- > Keep in mind you will still need to initiate a fault if a stoppage of work is required.
1004
+ !!! warning "Important"
1005
+
1006
+ Manual errors don't stop execution—you still need to call `fail!` or `skip!`.
1004
1007
 
1005
1008
  ```ruby
1006
1009
  class ProcessRenewal < CMDx::Task
@@ -1015,14 +1018,9 @@ class ProcessRenewal < CMDx::Task
1015
1018
  end
1016
1019
  ```
1017
1020
 
1018
- ---
1019
-
1020
- url: https://github.com/drexed/cmdx/blob/main/docs/interruptions/faults.md
1021
- ---
1022
-
1023
1021
  # Interruptions - Faults
1024
1022
 
1025
- Faults are exception mechanisms that halt task execution via `skip!` and `fail!` methods. When tasks execute with the `execute!` method, fault exceptions matching the task's interruption status are raised, enabling sophisticated exception handling and control flow patterns.
1023
+ Faults are exceptions raised by `execute!` when tasks halt. They carry rich context about execution state, enabling sophisticated error handling patterns.
1026
1024
 
1027
1025
  ## Fault Types
1028
1026
 
@@ -1032,8 +1030,9 @@ Faults are exception mechanisms that halt task execution via `skip!` and `fail!`
1032
1030
  | `CMDx::SkipFault` | `skip!` method | Optional processing, early returns |
1033
1031
  | `CMDx::FailFault` | `fail!` method | Validation errors, processing failures |
1034
1032
 
1035
- > [!IMPORTANT]
1036
- > All fault exceptions inherit from `CMDx::Fault` and provide access to the complete task execution context including result, task, context, and chain information.
1033
+ !!! warning "Important"
1034
+
1035
+ All faults inherit from `CMDx::Fault` and expose result, task, context, and chain data.
1037
1036
 
1038
1037
  ## Fault Handling
1039
1038
 
@@ -1054,7 +1053,7 @@ end
1054
1053
 
1055
1054
  ## Data Access
1056
1055
 
1057
- Faults provide comprehensive access to execution context, eg:
1056
+ Access rich execution data from fault exceptions:
1058
1057
 
1059
1058
  ```ruby
1060
1059
  begin
@@ -1083,7 +1082,7 @@ end
1083
1082
 
1084
1083
  ### Task-Specific Matching
1085
1084
 
1086
- Use `for?` to handle faults only from specific task classes, enabling targeted exception handling in complex workflows.
1085
+ Handle faults only from specific tasks using `for?`:
1087
1086
 
1088
1087
  ```ruby
1089
1088
  begin
@@ -1113,7 +1112,7 @@ end
1113
1112
 
1114
1113
  ## Fault Propagation
1115
1114
 
1116
- Use `throw!` to propagate failures while preserving fault context and maintaining the error chain for debugging.
1115
+ Propagate failures with `throw!` to preserve context and maintain the error chain:
1117
1116
 
1118
1117
  ### Basic Propagation
1119
1118
 
@@ -1160,7 +1159,7 @@ end
1160
1159
 
1161
1160
  ## Chain Analysis
1162
1161
 
1163
- Results provide methods to analyze fault propagation and identify original failure sources in complex execution chains.
1162
+ Trace fault origins and propagation through the execution chain:
1164
1163
 
1165
1164
  ```ruby
1166
1165
  result = DocumentWorkflow.execute(invalid_data)
@@ -1189,23 +1188,19 @@ if result.failed?
1189
1188
  end
1190
1189
  ```
1191
1190
 
1192
- ---
1193
-
1194
- url: https://github.com/drexed/cmdx/blob/main/docs/interruptions/exceptions.md
1195
- ---
1196
-
1197
1191
  # Interruptions - Exceptions
1198
1192
 
1199
- CMDx provides robust exception handling that differs between the `execute` and `execute!` methods. Understanding how unhandled exceptions are processed is crucial for building reliable task execution flows and implementing proper error handling strategies.
1193
+ Exception handling differs between `execute` and `execute!`. Choose the method that matches your error handling strategy.
1200
1194
 
1201
1195
  ## Exception Handling
1202
1196
 
1203
- > [!IMPORTANT]
1204
- > When designing tasks try not to `raise` your own exceptions directly, instead use `skip!` or `fail!` to signal intent clearly.
1197
+ !!! warning "Important"
1198
+
1199
+ Prefer `skip!` and `fail!` over raising exceptions—they signal intent more clearly.
1205
1200
 
1206
1201
  ### Non-bang execution
1207
1202
 
1208
- The `execute` method captures **all** unhandled exceptions and converts them to failed results, ensuring predictable behavior and consistent result processing.
1203
+ Captures all exceptions and returns them as failed results:
1209
1204
 
1210
1205
  ```ruby
1211
1206
  class CompressDocument < CMDx::Task
@@ -1223,12 +1218,13 @@ result.reason #=> "[ActiveRecord::NotFoundError] record not found"
1223
1218
  result.cause #=> <ActiveRecord::NotFoundError>
1224
1219
  ```
1225
1220
 
1226
- > [!NOTE]
1227
- > The `exception_handler` setting only works with non-bang execution as it catches all exceptions preventing them from reaching your apps global error handler.
1221
+ !!! note
1222
+
1223
+ Use `exception_handler` with `execute` to send exceptions to APM tools before they become failed results.
1228
1224
 
1229
1225
  ### Bang execution
1230
1226
 
1231
- The `execute!` method allows unhandled exceptions to propagate, enabling standard Ruby exception handling while respecting CMDx fault configuration.
1227
+ Lets exceptions propagate naturally for standard Ruby error handling:
1232
1228
 
1233
1229
  ```ruby
1234
1230
  class CompressDocument < CMDx::Task
@@ -1245,21 +1241,17 @@ rescue ActiveRecord::NotFoundError => e
1245
1241
  end
1246
1242
  ```
1247
1243
 
1248
- ---
1249
-
1250
- url: https://github.com/drexed/cmdx/blob/main/docs/outcomes/result.md
1251
- ---
1252
-
1253
1244
  # Outcomes - Result
1254
1245
 
1255
- The result object is the comprehensive return value of task execution, providing complete information about the execution outcome, state, timing, and any data produced during the task lifecycle. Results serve as the primary interface for inspecting task execution outcomes and chaining task operations.
1246
+ Results are your window into task execution. They expose everything: outcome, state, timing, context, and metadata.
1256
1247
 
1257
1248
  ## Result Attributes
1258
1249
 
1259
- Every result provides access to essential execution information:
1250
+ Access essential execution information:
1251
+
1252
+ !!! warning "Important"
1260
1253
 
1261
- > [!IMPORTANT]
1262
- > Result objects are immutable after task execution completes and reflect the final state.
1254
+ Results are immutable after execution completes.
1263
1255
 
1264
1256
  ```ruby
1265
1257
  result = BuildApplication.execute(version: "1.2.3")
@@ -1281,7 +1273,7 @@ result.metadata #=> { error_code: "BUILD_TOOL.NOT_FOUND" }
1281
1273
 
1282
1274
  ## Lifecycle Information
1283
1275
 
1284
- Results provide comprehensive methods for checking execution state and status:
1276
+ Check execution state and status with predicate methods:
1285
1277
 
1286
1278
  ```ruby
1287
1279
  result = BuildApplication.execute(version: "1.2.3")
@@ -1303,7 +1295,7 @@ result.bad? #=> false (skipped or failed)
1303
1295
 
1304
1296
  ## Outcome Analysis
1305
1297
 
1306
- Results provide unified outcome determination depending on the fault causal chain:
1298
+ Get a unified outcome string combining state and status:
1307
1299
 
1308
1300
  ```ruby
1309
1301
  result = BuildApplication.execute(version: "1.2.3")
@@ -1313,7 +1305,7 @@ result.outcome #=> "success" (state and status)
1313
1305
 
1314
1306
  ## Chain Analysis
1315
1307
 
1316
- Use these methods to trace the root cause of faults or trace the cause points.
1308
+ Trace fault origins and propagation:
1317
1309
 
1318
1310
  ```ruby
1319
1311
  result = DeploymentWorkflow.execute(app_name: "webapp")
@@ -1354,7 +1346,7 @@ result.chain.results[result.index] == result #=> true
1354
1346
 
1355
1347
  ## Block Yield
1356
1348
 
1357
- Implement conditional logic using a block expression that yields a result for complete encapsulation.
1349
+ Execute code with direct result access:
1358
1350
 
1359
1351
  ```ruby
1360
1352
  BuildApplication.execute(version: "1.2.3") do |result|
@@ -1370,7 +1362,7 @@ end
1370
1362
 
1371
1363
  ## Handlers
1372
1364
 
1373
- Use result handlers for clean, functional-style conditional logic. Handlers return the result object, enabling method chaining and fluent interfaces.
1365
+ Handle outcomes with functional-style methods. Handlers return the result for chaining:
1374
1366
 
1375
1367
  ```ruby
1376
1368
  result = BuildApplication.execute(version: "1.2.3")
@@ -1394,10 +1386,11 @@ result
1394
1386
 
1395
1387
  ## Pattern Matching
1396
1388
 
1397
- Results support Ruby's pattern matching through array and hash deconstruction:
1389
+ Use Ruby 3.0+ pattern matching for elegant outcome handling:
1390
+
1391
+ !!! warning "Important"
1398
1392
 
1399
- > [!IMPORTANT]
1400
- > Pattern matching requires Ruby 3.0+
1393
+ Pattern matching works with both array and hash deconstruction.
1401
1394
 
1402
1395
  ### Array Pattern
1403
1396
 
@@ -1442,17 +1435,9 @@ in { runtime: time } if time > performance_threshold
1442
1435
  end
1443
1436
  ```
1444
1437
 
1445
- ---
1446
-
1447
- url: https://github.com/drexed/cmdx/blob/main/docs/outcomes/states.md
1448
- ---
1449
-
1450
1438
  # Outcomes - States
1451
1439
 
1452
- States represent the execution lifecycle condition of task execution, tracking
1453
- the progress of tasks through their complete execution journey. States provide
1454
- insight into where a task is in its lifecycle and enable lifecycle-based
1455
- decision making and monitoring.
1440
+ States track where a task is in its execution lifecycle—from creation through completion or interruption.
1456
1441
 
1457
1442
  ## Definitions
1458
1443
 
@@ -1476,8 +1461,9 @@ State-Status combinations:
1476
1461
 
1477
1462
  ## Transitions
1478
1463
 
1479
- > [!CAUTION]
1480
- > States are automatically managed during task execution and should **never** be modified manually. State transitions are handled internally by the CMDx framework.
1464
+ !!! danger "Caution"
1465
+
1466
+ States are managed automatically—never modify them manually.
1481
1467
 
1482
1468
  ```ruby
1483
1469
  # Valid state transition flow
@@ -1504,7 +1490,7 @@ result.executed? #=> true (complete OR interrupted)
1504
1490
 
1505
1491
  ## Handlers
1506
1492
 
1507
- Use state-based handlers for lifecycle event handling. The `on_executed` handler is particularly useful for cleanup operations that should run regardless of success, skipped, or failure.
1493
+ Handle lifecycle events with state-based handlers. Use `handle_executed` for cleanup that runs regardless of outcome:
1508
1494
 
1509
1495
  ```ruby
1510
1496
  result = ProcessVideoUpload.execute
@@ -1516,14 +1502,9 @@ result
1516
1502
  .handle_executed { |result| log_upload_metrics(result) }
1517
1503
  ```
1518
1504
 
1519
- ---
1520
-
1521
- url: https://github.com/drexed/cmdx/blob/main/docs/outcomes/statuses.md
1522
- ---
1523
-
1524
1505
  # Outcomes - Statuses
1525
1506
 
1526
- Statuses represent the business outcome of task execution logic, indicating how the task's business logic concluded. Statuses differ from execution states by focusing on the business outcome rather than the technical execution lifecycle. Understanding statuses is crucial for implementing proper business logic branching and error handling.
1507
+ Statuses represent the business outcome—did the task succeed, skip, or fail? This differs from state, which tracks the execution lifecycle.
1527
1508
 
1528
1509
  ## Definitions
1529
1510
 
@@ -1535,8 +1516,9 @@ Statuses represent the business outcome of task execution logic, indicating how
1535
1516
 
1536
1517
  ## Transitions
1537
1518
 
1538
- > [!IMPORTANT]
1539
- > Status transitions are unidirectional and final. Once a task is marked as skipped or failed, it cannot return to success status. Design your business logic accordingly.
1519
+ !!! warning "Important"
1520
+
1521
+ Status transitions are final and unidirectional. Once skipped or failed, tasks can't return to success.
1540
1522
 
1541
1523
  ```ruby
1542
1524
  # Valid status transitions
@@ -1569,7 +1551,7 @@ result.bad? #=> true if skipped OR failed (not success)
1569
1551
 
1570
1552
  ## Handlers
1571
1553
 
1572
- Use status-based handlers for business logic branching. The `on_good` and `on_bad` handlers are particularly useful for handling success/skip vs failed outcomes respectively.
1554
+ Branch business logic with status-based handlers. Use `handle_good` and `handle_bad` for success/skip vs failed outcomes:
1573
1555
 
1574
1556
  ```ruby
1575
1557
  result = ProcessNotification.execute
@@ -1586,19 +1568,15 @@ result
1586
1568
  .handle_bad { |result| track_delivery_failure(result) }
1587
1569
  ```
1588
1570
 
1589
- ---
1590
-
1591
- url: https://github.com/drexed/cmdx/blob/main/docs/attributes/definitions.md
1592
- ---
1593
-
1594
1571
  # Attributes - Definitions
1595
1572
 
1596
- Attributes define the interface between task callers and implementation, enabling automatic validation, type coercion, and method generation. They provide a contract to verify that task execution arguments match expected requirements and structure.
1573
+ Attributes define your task's interface with automatic validation, type coercion, and accessor generation. They're the contract between callers and your business logic.
1597
1574
 
1598
1575
  ## Declarations
1599
1576
 
1600
- > [!TIP]
1601
- > Prefer using the `required` and `optional` alias for `attributes` for brevity and to clearly signal intent.
1577
+ !!! tip
1578
+
1579
+ Prefer using the `required` and `optional` alias for `attributes` for brevity and to clearly signal intent.
1602
1580
 
1603
1581
  ### Optional
1604
1582
 
@@ -1667,7 +1645,7 @@ PublishArticle.execute(
1667
1645
 
1668
1646
  ## Sources
1669
1647
 
1670
- Attributes delegate to accessible objects within the task. The default source is `:context`, but any accessible method or object can serve as an attribute source.
1648
+ Attributes read from any accessible object—not just context. Use sources to pull data from models, services, or any callable:
1671
1649
 
1672
1650
  ### Context
1673
1651
 
@@ -1747,10 +1725,11 @@ end
1747
1725
 
1748
1726
  ## Nesting
1749
1727
 
1750
- Nested attributes enable complex attribute structures where child attributes automatically inherit their parent as the source. This allows validation and access of structured data.
1728
+ Build complex structures with nested attributes. Children inherit their parent as source and support all attribute options:
1751
1729
 
1752
- > [!NOTE]
1753
- > All options available to top-level attributes are available to nested attributes, eg: naming, coercions, and validations
1730
+ !!! note
1731
+
1732
+ Nested attributes support all features: naming, coercions, validations, defaults, and more.
1754
1733
 
1755
1734
  ```ruby
1756
1735
  class ConfigureServer < CMDx::Task
@@ -1803,15 +1782,17 @@ ConfigureServer.execute(
1803
1782
  )
1804
1783
  ```
1805
1784
 
1806
- > [!IMPORTANT]
1807
- > Child attributes are only required when their parent attribute is provided, enabling flexible optional structures.
1785
+ !!! warning "Important"
1786
+
1787
+ Child requirements only apply when the parent is provided—perfect for optional structures.
1808
1788
 
1809
1789
  ## Error Handling
1810
1790
 
1811
- Attribute validation failures result in structured error information with details about each failed attribute.
1791
+ Validation failures provide detailed, structured error messages:
1792
+
1793
+ !!! note
1812
1794
 
1813
- > [!NOTE]
1814
- > Nested attributes are only ever evaluated when the parent attribute is available and valid.
1795
+ Nested attributes are only validated when their parent is present and valid.
1815
1796
 
1816
1797
  ```ruby
1817
1798
  class ConfigureServer < CMDx::Task
@@ -1861,17 +1842,13 @@ result.metadata #=> {
1861
1842
  # }
1862
1843
  ```
1863
1844
 
1864
- ---
1865
-
1866
- url: https://github.com/drexed/cmdx/blob/main/docs/attributes/naming.md
1867
- ---
1868
-
1869
1845
  # Attributes - Naming
1870
1846
 
1871
- Attribute naming provides method name customization to prevent conflicts and enable flexible attribute access patterns. When attributes share names with existing methods or when multiple attributes from different sources have the same name, affixing ensures clean method resolution within tasks.
1847
+ Customize accessor method names to avoid conflicts and improve clarity. Affixing changes only the generated methods—not the original attribute names.
1848
+
1849
+ !!! note
1872
1850
 
1873
- > [!NOTE]
1874
- > Affixing modifies only the generated accessor method names within tasks.
1851
+ Use naming when attributes conflict with existing methods or need better clarity in your code.
1875
1852
 
1876
1853
  ## Prefix
1877
1854
 
@@ -1934,16 +1911,11 @@ end
1934
1911
  ScheduleMaintenance.execute(scheduled_at: DateTime.new(2024, 12, 15, 2, 0, 0))
1935
1912
  ```
1936
1913
 
1937
- ---
1938
-
1939
- url: https://github.com/drexed/cmdx/blob/main/docs/attributes/coercions.md
1940
- ---
1941
-
1942
1914
  # Attributes - Coercions
1943
1915
 
1944
- Attribute coercions automatically convert task arguments to expected types, ensuring type safety while providing flexible input handling. Coercions transform raw input values into the specified types, supporting simple conversions like string-to-integer and complex operations like JSON parsing.
1916
+ Automatically convert inputs to expected types. Coercions handle everything from simple string-to-integer conversions to JSON parsing.
1945
1917
 
1946
- Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#coercions) docs for global configuration.
1918
+ See [Global Configuration](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#coercions) for custom coercion setup.
1947
1919
 
1948
1920
  ## Usage
1949
1921
 
@@ -1974,8 +1946,9 @@ ParseMetrics.execute(
1974
1946
  )
1975
1947
  ```
1976
1948
 
1977
- > [!TIP]
1978
- > Specify multiple coercion types for attributes that could be a variety of value formats. CMDx attempts each type in order until one succeeds.
1949
+ !!! tip
1950
+
1951
+ Specify multiple coercion types for attributes that could be a variety of value formats. CMDx attempts each type in order until one succeeds.
1979
1952
 
1980
1953
  ## Built-in Coercions
1981
1954
 
@@ -1997,8 +1970,9 @@ ParseMetrics.execute(
1997
1970
 
1998
1971
  ## Declarations
1999
1972
 
2000
- > [!IMPORTANT]
2001
- > Coercions must raise a CMDx::CoercionError and its message is used as part of the fault reason and metadata.
1973
+ !!! warning "Important"
1974
+
1975
+ Custom coercions must raise `CMDx::CoercionError` with a descriptive message.
2002
1976
 
2003
1977
  ### Proc or Lambda
2004
1978
 
@@ -2048,10 +2022,11 @@ end
2048
2022
 
2049
2023
  ## Removals
2050
2024
 
2051
- Remove custom coercions when no longer needed:
2025
+ Remove unwanted coercions:
2026
+
2027
+ !!! warning
2052
2028
 
2053
- > [!WARNING]
2054
- > Only one removal operation is allowed per `deregister` call. Multiple removals require separate calls.
2029
+ Each `deregister` call removes one coercion. Use multiple calls for batch removals.
2055
2030
 
2056
2031
  ```ruby
2057
2032
  class TransformCoordinates < CMDx::Task
@@ -2092,16 +2067,11 @@ result.metadata #=> {
2092
2067
  # }
2093
2068
  ```
2094
2069
 
2095
- ---
2096
-
2097
- url: https://github.com/drexed/cmdx/blob/main/docs/attributes/validations.md
2098
- ---
2099
-
2100
2070
  # Attributes - Validations
2101
2071
 
2102
- Attribute validations ensure task arguments meet specified requirements before execution begins. Validations run after coercions and provide declarative rules for data integrity, supporting both built-in validators and custom validation logic.
2072
+ Ensure inputs meet requirements before execution. Validations run after coercions, giving you declarative data integrity checks.
2103
2073
 
2104
- Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#validations) docs for global configuration.
2074
+ See [Global Configuration](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#validators) for custom validator setup.
2105
2075
 
2106
2076
  ## Usage
2107
2077
 
@@ -2137,8 +2107,9 @@ ProcessSubscription.execute(
2137
2107
  )
2138
2108
  ```
2139
2109
 
2140
- > [!TIP]
2141
- > Validations run after coercions, so you can validate the final coerced values rather than raw input.
2110
+ !!! tip
2111
+
2112
+ Validations run after coercions, so you can validate the final coerced values rather than raw input.
2142
2113
 
2143
2114
  ## Built-in Validators
2144
2115
 
@@ -2293,8 +2264,9 @@ end
2293
2264
 
2294
2265
  ## Declarations
2295
2266
 
2296
- > [!IMPORTANT]
2297
- > Custom validators must raise a `CMDx::ValidationError` and its message is used as part of the fault reason and metadata.
2267
+ !!! warning "Important"
2268
+
2269
+ Custom validators must raise `CMDx::ValidationError` with a descriptive message.
2298
2270
 
2299
2271
  ### Proc or Lambda
2300
2272
 
@@ -2340,10 +2312,11 @@ end
2340
2312
 
2341
2313
  ## Removals
2342
2314
 
2343
- Remove custom validators when no longer needed:
2315
+ Remove unwanted validators:
2344
2316
 
2345
- > [!WARNING]
2346
- > Only one removal operation is allowed per `deregister` call. Multiple removals require separate calls.
2317
+ !!! warning
2318
+
2319
+ Each `deregister` call removes one validator. Use multiple calls for batch removals.
2347
2320
 
2348
2321
  ```ruby
2349
2322
  class SetupApplication < CMDx::Task
@@ -2353,7 +2326,7 @@ end
2353
2326
 
2354
2327
  ## Error Handling
2355
2328
 
2356
- Validation failures provide detailed error information including attribute paths, validation rules, and specific failure reasons:
2329
+ Validation failures provide detailed, structured error messages:
2357
2330
 
2358
2331
  ```ruby
2359
2332
  class CreateProject < CMDx::Task
@@ -2390,18 +2363,13 @@ result.metadata #=> {
2390
2363
  # }
2391
2364
  ```
2392
2365
 
2393
- ---
2394
-
2395
- url: https://github.com/drexed/cmdx/blob/main/docs/attributes/defaults.md
2396
- ---
2397
-
2398
2366
  # Attributes - Defaults
2399
2367
 
2400
- Attribute defaults provide fallback values when arguments are not provided or resolve to `nil`. Defaults ensure tasks have sensible values for optional attributes while maintaining flexibility for callers to override when needed.
2368
+ Provide fallback values for optional attributes. Defaults kick in when values aren't provided or are `nil`.
2401
2369
 
2402
2370
  ## Declarations
2403
2371
 
2404
- Defaults apply when attributes are not provided or resolve to `nil`. They work seamlessly with coercion, validation, and nested attributes.
2372
+ Defaults work seamlessly with coercions, validations, and nested attributes:
2405
2373
 
2406
2374
  ### Static Values
2407
2375
 
@@ -2461,7 +2429,7 @@ end
2461
2429
 
2462
2430
  ## Coercions and Validations
2463
2431
 
2464
- Defaults are subject to the same coercion and validation rules as provided values, ensuring consistency and catching configuration errors early.
2432
+ Defaults follow the same coercion and validation rules as provided values:
2465
2433
 
2466
2434
  ```ruby
2467
2435
  class ScheduleBackup < CMDx::Task
@@ -2473,14 +2441,9 @@ class ScheduleBackup < CMDx::Task
2473
2441
  end
2474
2442
  ```
2475
2443
 
2476
- ---
2477
-
2478
- url: https://github.com/drexed/cmdx/blob/main/docs/attributes/transformations.md
2479
- ---
2480
-
2481
2444
  # Attributes - Transformations
2482
2445
 
2483
- Transformations allow you to modify attribute values after they are derived and coerced from their source but before any validations. This enables data normalization, formatting, and conditional processing within the attribute pipeline.
2446
+ Modify attribute values after coercion but before validation. Perfect for normalization, formatting, and data cleanup.
2484
2447
 
2485
2448
  ## Declarations
2486
2449
 
@@ -2530,7 +2493,7 @@ end
2530
2493
 
2531
2494
  ## Validations
2532
2495
 
2533
- Transformed values are subject to the same validation rules as untransformed values, ensuring consistency and catching configuration errors early.
2496
+ Validations run on transformed values, ensuring data consistency:
2534
2497
 
2535
2498
  ```ruby
2536
2499
  class ScheduleBackup < CMDx::Task
@@ -2542,39 +2505,30 @@ class ScheduleBackup < CMDx::Task
2542
2505
  end
2543
2506
  ```
2544
2507
 
2545
- ---
2546
-
2547
- - **Prev:** [Attributes - Defaults](defaults.md)
2548
- - **Next:** [Callbacks](../callbacks.md)
2549
-
2550
- ---
2551
-
2552
- url: https://github.com/drexed/cmdx/blob/main/docs/callbacks.md
2553
- ---
2554
-
2555
2508
  # Callbacks
2556
2509
 
2557
- Callbacks provide precise control over task execution lifecycle, running custom logic at specific transition points. Callback callables have access to the same context and result information as the `execute` method, enabling rich integration patterns.
2510
+ Run custom logic at specific points during task execution. Callbacks have full access to task context and results, making them perfect for logging, notifications, cleanup, and more.
2558
2511
 
2559
- Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#callbacks) docs for global configuration.
2512
+ See [Global Configuration](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#callbacks) for framework-wide callback setup.
2560
2513
 
2561
- > [!IMPORTANT]
2562
- > Callbacks execute in the order they are declared within each hook type. Multiple callbacks of the same type execute in declaration order (FIFO: first in, first out).
2514
+ !!! warning "Important"
2515
+
2516
+ Callbacks execute in declaration order (FIFO). Multiple callbacks of the same type run sequentially.
2563
2517
 
2564
2518
  ## Available Callbacks
2565
2519
 
2566
- Callbacks execute in precise lifecycle order. Here is the complete execution sequence:
2520
+ Callbacks execute in a predictable lifecycle order:
2567
2521
 
2568
2522
  ```ruby
2569
2523
  1. before_validation # Pre-validation setup
2570
- 2. before_execution # Setup and preparation
2524
+ 2. before_execution # Prepare for execution
2571
2525
 
2572
- # --- Task#work executed ---
2526
+ # --- Task#work executes ---
2573
2527
 
2574
- 3. on_[complete|interrupted] # Based on execution state
2575
- 4. on_executed # Task finished (any outcome)
2576
- 5. on_[success|skipped|failed] # Based on execution status
2577
- 6. on_[good|bad] # Based on outcome classification
2528
+ 3. on_[complete|interrupted] # State-based (execution lifecycle)
2529
+ 4. on_executed # Always runs after work completes
2530
+ 5. on_[success|skipped|failed] # Status-based (business outcome)
2531
+ 6. on_[good|bad] # Outcome-based (success/skip vs fail)
2578
2532
  ```
2579
2533
 
2580
2534
  ## Declarations
@@ -2626,7 +2580,7 @@ end
2626
2580
 
2627
2581
  ### Class or Module
2628
2582
 
2629
- Implement reusable callback logic in dedicated classes:
2583
+ Implement reusable callback logic in dedicated modules and classes:
2630
2584
 
2631
2585
  ```ruby
2632
2586
  class BookingConfirmationCallback
@@ -2693,10 +2647,11 @@ end
2693
2647
 
2694
2648
  ## Callback Removal
2695
2649
 
2696
- Remove callbacks at runtime for dynamic behavior control:
2650
+ Remove unwanted callbacks dynamically:
2651
+
2652
+ !!! warning "Important"
2697
2653
 
2698
- > [!IMPORTANT]
2699
- > Only one removal operation is allowed per `deregister` call. Multiple removals require separate calls.
2654
+ Each `deregister` call removes one callback. Use multiple calls for batch removals.
2700
2655
 
2701
2656
  ```ruby
2702
2657
  class ProcessBooking < CMDx::Task
@@ -2708,23 +2663,19 @@ class ProcessBooking < CMDx::Task
2708
2663
  end
2709
2664
  ```
2710
2665
 
2711
- ---
2712
-
2713
- url: https://github.com/drexed/cmdx/blob/main/docs/middlewares.md
2714
- ---
2715
-
2716
2666
  # Middlewares
2717
2667
 
2718
- Middleware provides Rack-style wrappers around task execution for cross-cutting concerns like authentication, logging, caching, and error handling.
2668
+ Wrap task execution with middleware for cross-cutting concerns like authentication, caching, timeouts, and monitoring. Think Rack middleware, but for your business logic.
2719
2669
 
2720
- Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#middlewares) docs for global configuration.
2670
+ See [Global Configuration](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#middlewares) for framework-wide setup.
2721
2671
 
2722
- ## Order
2672
+ ## Execution Order
2723
2673
 
2724
- Middleware executes in a nested fashion, creating an onion-like execution pattern:
2674
+ Middleware wraps task execution in layers, like an onion:
2725
2675
 
2726
- > [!NOTE]
2727
- > Middleware executes in the order they are registered, with the first registered middleware being the outermost wrapper.
2676
+ !!! note
2677
+
2678
+ First registered = outermost wrapper. They execute in registration order.
2728
2679
 
2729
2680
  ```ruby
2730
2681
  class ProcessCampaign < CMDx::Task
@@ -2800,10 +2751,11 @@ end
2800
2751
 
2801
2752
  ## Removals
2802
2753
 
2803
- Class and Module based declarations can be removed at a global and task level.
2754
+ Remove class or module-based middleware globally or per-task:
2755
+
2756
+ !!! warning
2804
2757
 
2805
- > [!WARNING]
2806
- > Only one removal operation is allowed per `deregister` call. Multiple removals require separate calls.
2758
+ Each `deregister` call removes one middleware. Use multiple calls for batch removals.
2807
2759
 
2808
2760
  ```ruby
2809
2761
  class ProcessCampaign < CMDx::Task
@@ -2816,7 +2768,7 @@ end
2816
2768
 
2817
2769
  ### Timeout
2818
2770
 
2819
- Ensures task execution doesn't exceed a specified time limit:
2771
+ Prevent tasks from running too long:
2820
2772
 
2821
2773
  ```ruby
2822
2774
  class ProcessReport < CMDx::Task
@@ -2852,7 +2804,7 @@ result.metadata #=> { limit: 3 }
2852
2804
 
2853
2805
  ### Correlate
2854
2806
 
2855
- Tags tasks with a global correlation ID for distributed tracing:
2807
+ Add correlation IDs for distributed tracing and request tracking:
2856
2808
 
2857
2809
  ```ruby
2858
2810
  class ProcessExport < CMDx::Task
@@ -2882,8 +2834,7 @@ result.metadata #=> { correlation_id: "550e8400-e29b-41d4-a716-446655440000" }
2882
2834
 
2883
2835
  ### Runtime
2884
2836
 
2885
- The runtime middleware tags tasks with how long it took to execute the task.
2886
- The calculation uses a monotonic clock and the time is returned in milliseconds.
2837
+ Track task execution time in milliseconds using a monotonic clock:
2887
2838
 
2888
2839
  ```ruby
2889
2840
  class PerformanceMonitoringCheck
@@ -2904,18 +2855,13 @@ result = ProcessExport.execute
2904
2855
  result.metadata #=> { runtime: 1247 } (ms)
2905
2856
  ```
2906
2857
 
2907
- ---
2908
-
2909
- url: https://github.com/drexed/cmdx/blob/main/docs/logging.md
2910
- ---
2911
-
2912
2858
  # Logging
2913
2859
 
2914
- CMDx provides comprehensive automatic logging for task execution with structured data, customizable formatters, and intelligent severity mapping. All task results are logged after completion with rich metadata for debugging and monitoring.
2860
+ CMDx automatically logs every task execution with structured data, making debugging and monitoring effortless. Choose from multiple formatters to match your logging infrastructure.
2915
2861
 
2916
2862
  ## Formatters
2917
2863
 
2918
- CMDx supports multiple log formatters to integrate with various logging systems:
2864
+ Choose the format that works best for your logging system:
2919
2865
 
2920
2866
  | Formatter | Use Case | Output Style |
2921
2867
  |-----------|----------|--------------|
@@ -2945,12 +2891,13 @@ E, [2022-07-17T18:43:15.000000 #3784] ERROR -- BillingWorkflow:
2945
2891
  index=3 chain_id="018c2b95-b764-7615-a924-cc5b910ed1e5" type="Task" class="BillingWorkflow" state="interrupted" status="failed" caused_failure={index: 2, class: "CalculateTax", status: "failed"} threw_failure={index: 1, class: "ValidateCustomer", status: "failed"}
2946
2892
  ```
2947
2893
 
2948
- > [!TIP]
2949
- > Logging can be used as low-level eventing system, ingesting all tasks performed within a small action or long running request. This ie where correlation is especially handy.
2894
+ !!! tip
2895
+
2896
+ Use logging as a low-level event stream to track all tasks in a request. Combine with correlation for powerful distributed tracing.
2950
2897
 
2951
2898
  ## Structure
2952
2899
 
2953
- All log entries include comprehensive execution metadata. Field availability depends on execution context and outcome.
2900
+ Every log entry includes rich metadata. Available fields depend on execution context and outcome.
2954
2901
 
2955
2902
  ### Core Fields
2956
2903
 
@@ -2991,7 +2938,7 @@ All log entries include comprehensive execution metadata. Field availability dep
2991
2938
 
2992
2939
  ## Usage
2993
2940
 
2994
- Tasks have access to the frameworks logger.
2941
+ Access the framework logger directly within tasks:
2995
2942
 
2996
2943
  ```ruby
2997
2944
  class ProcessSubscription < CMDx::Task
@@ -3003,18 +2950,13 @@ class ProcessSubscription < CMDx::Task
3003
2950
  end
3004
2951
  ```
3005
2952
 
3006
- ---
3007
-
3008
- url: https://github.com/drexed/cmdx/blob/main/docs/internationalization.md
3009
- ---
3010
-
3011
2953
  # Internationalization (i18n)
3012
2954
 
3013
- CMDx provides comprehensive internationalization support for all error messages, attribute validation failures, coercion errors, and fault messages. All user-facing text is automatically localized based on the current `I18n.locale`, ensuring your applications can serve global audiences with native-language error reporting.
2955
+ CMDx supports 90+ languages out of the box for all error messages, validations, coercions, and faults. Error messages automatically adapt to the current `I18n.locale`, making it easy to build applications for global audiences.
3014
2956
 
3015
- ## Localization
2957
+ ## Usage
3016
2958
 
3017
- CMDx automatically localizes all error messages based on the `I18n.locale` setting.
2959
+ All error messages are automatically localized based on your current locale:
3018
2960
 
3019
2961
  ```ruby
3020
2962
  class ProcessQuote < CMDx::Task
@@ -3033,11 +2975,11 @@ end
3033
2975
 
3034
2976
  ## Configuration
3035
2977
 
3036
- Localization is handled by the `I18n` gem. In Rails applications, locales are loaded automatically and managed via the `I18n.available_locales` setting.
2978
+ CMDx uses the `I18n` gem for localization. In Rails, locales load automatically.
3037
2979
 
3038
- ### Local Copies
2980
+ ### Copy Locale Files
3039
2981
 
3040
- Execute the following command to copy any locale into the Rails applications `config/locales` directory:
2982
+ Copy locale files to your Rails application's `config/locales` directory:
3041
2983
 
3042
2984
  ```bash
3043
2985
  rails generate cmdx:locale [LOCALE]
@@ -3135,23 +3077,141 @@ rails generate cmdx:locale fr
3135
3077
  - zh-TW - Chinese (Traditional)
3136
3078
  - zh-YUE - Chinese (Yue)
3137
3079
 
3138
- ---
3080
+ # Retries
3081
+
3082
+ CMDx provides automatic retry functionality for tasks that encounter transient failures. This is essential for handling temporary issues like network timeouts, rate limits, or database locks without manual intervention.
3139
3083
 
3140
- url: https://github.com/drexed/cmdx/blob/main/docs/deprecation.md
3141
- ---
3084
+ ## Basic Usage
3085
+
3086
+ Configure retries upto n attempts without any delay.
3087
+
3088
+ ```ruby
3089
+ class FetchExternalData < CMDx::Task
3090
+ settings retries: 3
3091
+
3092
+ def work
3093
+ response = HTTParty.get("https://api.example.com/data")
3094
+ context.data = response.parsed_response
3095
+ end
3096
+ end
3097
+ ```
3098
+
3099
+ When an exception occurs during execution, CMDx automatically retries up to the configured limit.
3100
+
3101
+ ## Selective Retries
3102
+
3103
+ By default, CMDx retries on `StandardError` and its subclasses. Narrow this to specific exception types:
3104
+
3105
+ ```ruby
3106
+ class ProcessPayment < CMDx::Task
3107
+ settings retries: 5, retry_on: [Stripe::RateLimitError, Net::ReadTimeout]
3108
+
3109
+ def work
3110
+ # Your logic here...
3111
+ end
3112
+ end
3113
+ ```
3114
+
3115
+ !!! warning "Important"
3116
+
3117
+ Only exceptions matching the `retry_on` configuration will trigger retries. Uncaught exceptions immediately fail the task.
3118
+
3119
+ ## Retry Jitter
3120
+
3121
+ Add delays between retry attempts to avoid overwhelming external services or to implement exponential backoff strategies.
3122
+
3123
+ ### Fixed Value
3124
+
3125
+ Use a numeric value to calculate linear delay (`jitter * current_retry`):
3126
+
3127
+ ```ruby
3128
+ class ImportRecords < CMDx::Task
3129
+ settings retries: 3, retry_jitter: 0.5
3130
+
3131
+ def work
3132
+ # Delays: 0s, 0.5s (retry 1), 1.0s (retry 2), 1.5s (retry 3)
3133
+ context.records = ExternalAPI.fetch_records
3134
+ end
3135
+ end
3136
+ ```
3137
+
3138
+ ### Symbol References
3139
+
3140
+ Define an instance method for custom delay logic:
3141
+
3142
+ ```ruby
3143
+ class SyncInventory < CMDx::Task
3144
+ settings retries: 5, retry_jitter: :exponential_backoff
3145
+
3146
+ def work
3147
+ context.inventory = InventoryAPI.sync
3148
+ end
3149
+
3150
+ private
3151
+
3152
+ def exponential_backoff(current_retry)
3153
+ 2 ** current_retry # 2s, 4s, 8s, 16s, 32s
3154
+ end
3155
+ end
3156
+ ```
3157
+
3158
+ ### Proc or Lambda
3159
+
3160
+ Pass a proc for inline delay calculations:
3161
+
3162
+ ```ruby
3163
+ class PollJobStatus < CMDx::Task
3164
+ # Proc
3165
+ settings retries: 10, retry_jitter: proc { |retry_count| [retry_count * 0.5, 5.0].min }
3166
+
3167
+ # Lambda
3168
+ settings retries: 10, retry_jitter: ->(retry_count) { [retry_count * 0.5, 5.0].min }
3169
+
3170
+ def work
3171
+ # Delays: 0.5s, 1.0s, 1.5s, 2.0s, 2.5s, 3.0s, 3.5s, 4.0s, 4.5s, 5.0s (capped)
3172
+ context.status = JobAPI.check_status(context.job_id)
3173
+ end
3174
+ end
3175
+ ```
3176
+
3177
+ ### Class or Module
3178
+
3179
+ Implement reusable delay logic in dedicated modules and classes:
3180
+
3181
+ ```ruby
3182
+ class ExponentialBackoff
3183
+ def call(task, retry_count)
3184
+ base_delay = task.context.base_delay || 1.0
3185
+ [base_delay * (2 ** retry_count), 60.0].min
3186
+ end
3187
+ end
3188
+
3189
+ class FetchUserProfile < CMDx::Task
3190
+ # Class or Module
3191
+ settings retries: 4, retry_jitter: ExponentialBackoff
3192
+
3193
+ # Instance
3194
+ settings retries: 4, retry_jitter: ExponentialBackoff.new
3195
+
3196
+ def work
3197
+ # Your logic here...
3198
+ end
3199
+ end
3200
+ ```
3142
3201
 
3143
3202
  # Task Deprecation
3144
3203
 
3145
- Task deprecation provides a systematic approach to managing legacy tasks in CMDx applications. The deprecation system enables controlled migration paths by issuing warnings, logging messages, or preventing execution of deprecated tasks entirely, helping teams maintain code quality while providing clear upgrade paths.
3204
+ Manage legacy tasks gracefully with built-in deprecation support. Choose how to handle deprecated tasks—log warnings for awareness, issue Ruby warnings for development, or prevent execution entirely.
3146
3205
 
3147
3206
  ## Modes
3148
3207
 
3149
3208
  ### Raise
3150
3209
 
3151
- `:raise` mode prevents task execution entirely. Use this for tasks that should no longer be used under any circumstances.
3210
+ Prevent task execution completely. Perfect for tasks that must no longer run.
3211
+
3212
+ !!! warning
3152
3213
 
3153
- > [!WARNING]
3154
- > Use `:raise` mode carefully in production environments as it will break existing workflows immediately.
3214
+ Use `:raise` mode carefully—it will break existing workflows immediately.
3155
3215
 
3156
3216
  ```ruby
3157
3217
  class ProcessObsoleteAPI < CMDx::Task
@@ -3168,7 +3228,7 @@ result = ProcessObsoleteAPI.execute
3168
3228
 
3169
3229
  ### Log
3170
3230
 
3171
- `:log` mode allows continued usage while tracking deprecation warnings. Perfect for gradual migration scenarios where immediate replacement isn't feasible.
3231
+ Allow execution while tracking deprecation in logs. Ideal for gradual migrations.
3172
3232
 
3173
3233
  ```ruby
3174
3234
  class ProcessLegacyFormat < CMDx::Task
@@ -3191,7 +3251,7 @@ result.successful? #=> true
3191
3251
 
3192
3252
  ### Warn
3193
3253
 
3194
- `:warn` mode issues Ruby warnings visible in development and testing environments. Useful for alerting developers without affecting production logging.
3254
+ Issue Ruby warnings visible during development and testing. Keeps production logs clean while alerting developers.
3195
3255
 
3196
3256
  ```ruby
3197
3257
  class ProcessOldData < CMDx::Task
@@ -3285,21 +3345,17 @@ class OutdatedConnector < CMDx::Task
3285
3345
  end
3286
3346
  ```
3287
3347
 
3288
- ---
3289
-
3290
- url: https://github.com/drexed/cmdx/blob/main/docs/workflows.md
3291
- ---
3292
-
3293
3348
  # Workflows
3294
3349
 
3295
- Workflow orchestrates sequential execution of multiple tasks in a linear pipeline. Workflows provide a declarative DSL for composing complex business logic from individual task components, with support for conditional execution, context propagation, and configurable halt behavior.
3350
+ Compose multiple tasks into powerful, sequential pipelines. Workflows provide a declarative way to build complex business processes with conditional execution, shared context, and flexible error handling.
3296
3351
 
3297
3352
  ## Declarations
3298
3353
 
3299
- Tasks execute sequentially in declaration order (FIFO). The workflow context propagates to each task, allowing access to data from previous executions.
3354
+ Tasks run in declaration order (FIFO), sharing a common context across the pipeline.
3355
+
3356
+ !!! warning
3300
3357
 
3301
- > [!IMPORTANT]
3302
- > Do **NOT** define a `work` method in workflow tasks. The included module automatically provides the execution logic.
3358
+ Don't define a `work` method in workflows—the module handles execution automatically.
3303
3359
 
3304
3360
  ### Task
3305
3361
 
@@ -3314,15 +3370,17 @@ class OnboardingWorkflow < CMDx::Task
3314
3370
  end
3315
3371
  ```
3316
3372
 
3317
- > [!TIP]
3318
- > Execute tasks in parallel via the [cmdx-parallel](https://github.com/drexed/cmdx-parallel) gem.
3373
+ !!! tip
3374
+
3375
+ Execute tasks in parallel via the [cmdx-parallel](https://github.com/drexed/cmdx-parallel) gem.
3319
3376
 
3320
3377
  ### Group
3321
3378
 
3322
- Group related tasks for better organization and shared configuration:
3379
+ Group related tasks to share configuration:
3323
3380
 
3324
- > [!IMPORTANT]
3325
- > Settings and conditionals for a group apply to all tasks within that group.
3381
+ !!! warning "Important"
3382
+
3383
+ Settings and conditionals apply to all tasks in the group.
3326
3384
 
3327
3385
  ```ruby
3328
3386
  class ContentModerationWorkflow < CMDx::Task
@@ -3385,9 +3443,7 @@ end
3385
3443
 
3386
3444
  ## Halt Behavior
3387
3445
 
3388
- By default skipped tasks are considered no-op executions and does not stop workflow execution.
3389
- This is configurable via global and task level breakpoint settings. Task and group configurations
3390
- can be used together within a workflow.
3446
+ By default, skipped tasks don't stop the workflow—they're treated as no-ops. Configure breakpoints globally or per-task to customize this behavior.
3391
3447
 
3392
3448
  ```ruby
3393
3449
  class AnalyticsWorkflow < CMDx::Task
@@ -3443,7 +3499,7 @@ end
3443
3499
 
3444
3500
  ## Nested Workflows
3445
3501
 
3446
- Workflows can task other workflows for hierarchical composition:
3502
+ Build hierarchical workflows by composing workflows within workflows:
3447
3503
 
3448
3504
  ```ruby
3449
3505
  class EmailPreparationWorkflow < CMDx::Task
@@ -3470,10 +3526,11 @@ end
3470
3526
 
3471
3527
  ## Parallel Execution
3472
3528
 
3473
- Parallel task execution leverages the [Parallel](https://github.com/grosser/parallel) gem, which automatically detects the number of available processors to maximize concurrent task execution.
3529
+ Run tasks concurrently using the [Parallel](https://github.com/grosser/parallel) gem. It automatically uses all available processors for maximum throughput.
3530
+
3531
+ !!! warning
3474
3532
 
3475
- > [!IMPORTANT]
3476
- > Context cannot be modified during parallel execution. Ensure that all required data is preloaded into the context before parallelization begins.
3533
+ Context is read-only during parallel execution. Load all required data beforehand.
3477
3534
 
3478
3535
  ```ruby
3479
3536
  class SendWelcomeNotifications < CMDx::Task
@@ -3511,17 +3568,13 @@ class SendNotifications < CMDx::Task
3511
3568
  end
3512
3569
  ```
3513
3570
 
3514
- > [!TIP]
3515
- > Use **present tense verbs + pluralized noun** for workflow task names, eg: `SendNotifications`, `DownloadFiles`, `ValidateDocuments`
3516
-
3517
- ---
3571
+ !!! tip
3518
3572
 
3519
- url: https://github.com/drexed/cmdx/blob/main/docs/tips_and_tricks.md
3520
- ---
3573
+ Use **present tense verbs + pluralized noun** for workflow task names, eg: `SendNotifications`, `DownloadFiles`, `ValidateDocuments`
3521
3574
 
3522
3575
  # Tips and Tricks
3523
3576
 
3524
- This guide covers advanced patterns and optimization techniques for getting the most out of CMDx in production applications.
3577
+ Best practices, patterns, and techniques to build maintainable CMDx applications.
3525
3578
 
3526
3579
  ## Project Organization
3527
3580
 
@@ -3565,7 +3618,7 @@ class TokenGeneration < CMDx::Task; end # ❌ Avoid
3565
3618
 
3566
3619
  ### Story Telling
3567
3620
 
3568
- Consider using descriptive methods to express the task’s flow, rather than concentrating all logic inside the `work` method.
3621
+ Break down complex logic into descriptive methods that read like a narrative:
3569
3622
 
3570
3623
  ```ruby
3571
3624
  class ProcessOrder < CMDx::Task
@@ -3597,7 +3650,7 @@ end
3597
3650
 
3598
3651
  ### Style Guide
3599
3652
 
3600
- Follow a style pattern for consistent task design:
3653
+ Follow this order for consistent, readable tasks:
3601
3654
 
3602
3655
  ```ruby
3603
3656
  class ExportReport < CMDx::Task
@@ -3640,7 +3693,7 @@ end
3640
3693
 
3641
3694
  ## Attribute Options
3642
3695
 
3643
- Use Rails `with_options` to reduce duplication and improve readability:
3696
+ Use `with_options` to reduce duplication:
3644
3697
 
3645
3698
  ```ruby
3646
3699
  class ConfigureCompany < CMDx::Task
@@ -3666,9 +3719,9 @@ class ConfigureCompany < CMDx::Task
3666
3719
  end
3667
3720
  ```
3668
3721
 
3669
- ## Advance Examples
3722
+ ## More Examples
3670
3723
 
3671
3724
  - [Active Record Query Tagging](https://github.com/drexed/cmdx/blob/main/examples/active_record_query_tagging.md)
3672
3725
  - [Paper Trail Whatdunnit](https://github.com/drexed/cmdx/blob/main/examples/paper_trail_whatdunnit.md)
3726
+ - [Stoplight Circuit Breaker](https://github.com/drexed/cmdx/blob/main/examples/stoplight_circuit_breaker.md)
3673
3727
 
3674
- ---