Class: RosettAi::Workflow::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/rosett_ai/workflow/engine.rb

Overview

Orchestrates declarative workflow execution.

Loads workflow YAML, validates against schema, and executes steps sequentially. Supports dry-run (simulate), resume from audit log, and per-step on_failure handling.

Author:

  • hugo

  • claude

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(workflow_path:, audit_log_path: nil) ⇒ Engine

Returns a new instance of Engine.

Parameters:

  • workflow_path (Pathname)

    path to workflow YAML file

  • audit_log_path (Pathname, nil) (defaults to: nil)

    path to audit log file



26
27
28
29
30
31
32
# File 'lib/rosett_ai/workflow/engine.rb', line 26

def initialize(workflow_path:, audit_log_path: nil)
  @workflow_path = workflow_path
  @workflow_data = load_workflow
  @audit_log = AuditLog.new(log_path: audit_log_path)
  @step_runner = StepRunner.new
  @validator = SchemaValidator.new
end

Instance Attribute Details

#audit_logObject (readonly)

Returns the value of attribute audit_log.



22
23
24
# File 'lib/rosett_ai/workflow/engine.rb', line 22

def audit_log
  @audit_log
end

#workflow_dataObject (readonly)

Returns the value of attribute workflow_data.



22
23
24
# File 'lib/rosett_ai/workflow/engine.rb', line 22

def workflow_data
  @workflow_data
end

Instance Method Details

#execute(resume: false) ⇒ Hash

Executes the workflow.

Runs each step in order. Skips steps already completed (via audit log). Stops on first failure unless the step has on_failure: continue.

Parameters:

  • resume (Boolean) (defaults to: false)

    skip already-completed steps

Returns:

  • (Hash)

    execution summary with :status, :results, :workflow

Raises:



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/rosett_ai/workflow/engine.rb', line 60

def execute(resume: false)
  errors = validate
  raise RosettAi::WorkflowError, "Workflow validation failed: #{errors.join(', ')}" unless errors.empty?

  workflow_name = @workflow_data.fetch('name')
  completed = resume ? @audit_log.completed_steps(workflow_name) : []
  results = []
  failed = false

  @workflow_data.fetch('steps').each do |step_def|
    step_name = step_def.fetch('name')

    if completed.include?(step_name)
      results << { step: step_name, status: 'skip', message: 'Already completed (resume)' }
      next
    end

    if failed
      results << skip_result(step_name)
      record_audit(workflow_name, step_name, 'skip')
      next
    end

    result = run_step(workflow_name, step_def)
    results << result

    failed = true if result[:status] == 'fail' && step_def.fetch('on_failure', 'stop') == 'stop'
  end

  build_summary(workflow_name, results)
end

#simulateArray<String>

Returns step descriptions for dry-run mode.

Returns:

  • (Array<String>)

    descriptions of each step

Raises:



44
45
46
47
48
49
50
51
# File 'lib/rosett_ai/workflow/engine.rb', line 44

def simulate
  errors = validate
  raise RosettAi::WorkflowError, "Workflow validation failed: #{errors.join(', ')}" unless errors.empty?

  @workflow_data.fetch('steps').map do |step_def|
    @step_runner.describe(step_def)
  end
end

#validateArray<String>

Validates the workflow definition.

Returns:

  • (Array<String>)

    validation errors (empty if valid)



37
38
39
# File 'lib/rosett_ai/workflow/engine.rb', line 37

def validate
  @validator.validate(@workflow_data)
end