trellis

Manual SAGA Pattern (Compensation)

Distributed transactions are complex. In durable workflows, we often use the SAGA Pattern to guarantee consistency across external systems without distributed locks.

Note: This guide describes how to implement SAGA manually in Trellis v0.6. For the new Automatic Rollback feature (v0.7), see the Native SAGA Guide and the examples/compensation-native demo.

The Concept: For every “Do” action, define an “Undo” action. If any step fails, execute the “Undos” in reverse order for successfully completed steps.

Implementing Manual SAGA in Trellis

Trellis supports this pattern natively using metadata for annotation and on_error for flow control.

1. Define Compensatable Nodes

Use the metadata.undo_action key to indicate which tool/node reverses effect.

# book_flight.md
type: tool
tool_call:
  name: book_flight
metadata:
  undo_action: cancel_flight
save_to: flight_id
on_error: rollback_manager

2. Triggering the Rollback

You can initiate the saga compensation flow in two ways: system errors or explicit business logic.

2.1 On Error (System Failure)

When a critical step fails (e.g., API timeout, database error), trigger the rollback sequence via on_error.

# book_car.md
type: tool
tool_call:
  name: book_car
# If this fails, go to rollback
on_error: rollback_manager

2.2 Programmatic (Logic-Based)

Sometimes a “rejection” is a valid business result, not a system error. You can trigger the rollback sequence explicitly using a transition to the reserved keyword rollback.

# review_request.md
type: tool
do: ...
transitions:
  - if: input == "rejected"
    to: rollback

3. Implement the Rollback Manager (Manual Chain)

In v0.6, you manually chain the compensation logic. A simple pattern is to have a “Rollback Entry” followed by the compensation steps.

graph TD
    Start --> Flight
    Flight --> Hotel
    Hotel --> Car
    Car -- Error --> Rollback
    Car -- "Rejected" --> Rollback
    Rollback --> CancelHotel
    CancelHotel --> CancelFlight
    CancelFlight --> End

Example

See examples/compensation-manual for a complete working implementation.

Run it with:

go run ./examples/compensation-manual

You will see:

  1. Flight Booked (Success)
  2. Hotel Booked (Success)
  3. Car Booking Fails (Error)
  4. Rollback Initiated
  5. Hotel Cancelled
  6. Flight Cancelled