igniter 0.4.0 → 0.4.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/README.md +238 -218
- data/docs/LLM_V1.md +335 -0
- data/docs/PATTERNS.md +189 -0
- data/docs/SERVER_V1.md +313 -0
- data/examples/README.md +129 -0
- data/examples/agents.rb +150 -0
- data/examples/differential.rb +161 -0
- data/examples/distributed_server.rb +94 -0
- data/examples/effects.rb +184 -0
- data/examples/invariants.rb +179 -0
- data/examples/order_pipeline.rb +163 -0
- data/examples/provenance.rb +122 -0
- data/examples/saga.rb +110 -0
- data/lib/igniter/agent/mailbox.rb +96 -0
- data/lib/igniter/agent/message.rb +21 -0
- data/lib/igniter/agent/ref.rb +86 -0
- data/lib/igniter/agent/runner.rb +129 -0
- data/lib/igniter/agent/state_holder.rb +23 -0
- data/lib/igniter/agent.rb +155 -0
- data/lib/igniter/compiler/validators/callable_validator.rb +21 -3
- data/lib/igniter/differential/divergence.rb +29 -0
- data/lib/igniter/differential/formatter.rb +96 -0
- data/lib/igniter/differential/report.rb +86 -0
- data/lib/igniter/differential/runner.rb +130 -0
- data/lib/igniter/differential.rb +51 -0
- data/lib/igniter/dsl/contract_builder.rb +32 -0
- data/lib/igniter/effect.rb +91 -0
- data/lib/igniter/effect_registry.rb +78 -0
- data/lib/igniter/errors.rb +11 -1
- data/lib/igniter/execution_report/builder.rb +54 -0
- data/lib/igniter/execution_report/formatter.rb +50 -0
- data/lib/igniter/execution_report/node_entry.rb +24 -0
- data/lib/igniter/execution_report/report.rb +65 -0
- data/lib/igniter/execution_report.rb +32 -0
- data/lib/igniter/extensions/differential.rb +114 -0
- data/lib/igniter/extensions/execution_report.rb +27 -0
- data/lib/igniter/extensions/invariants.rb +116 -0
- data/lib/igniter/extensions/provenance.rb +45 -0
- data/lib/igniter/extensions/saga.rb +74 -0
- data/lib/igniter/integrations/agents.rb +18 -0
- data/lib/igniter/invariant.rb +50 -0
- data/lib/igniter/model/effect_node.rb +37 -0
- data/lib/igniter/model.rb +1 -0
- data/lib/igniter/property_testing/formatter.rb +66 -0
- data/lib/igniter/property_testing/generators.rb +115 -0
- data/lib/igniter/property_testing/result.rb +45 -0
- data/lib/igniter/property_testing/run.rb +43 -0
- data/lib/igniter/property_testing/runner.rb +47 -0
- data/lib/igniter/property_testing.rb +64 -0
- data/lib/igniter/provenance/builder.rb +97 -0
- data/lib/igniter/provenance/lineage.rb +82 -0
- data/lib/igniter/provenance/node_trace.rb +65 -0
- data/lib/igniter/provenance/text_formatter.rb +70 -0
- data/lib/igniter/provenance.rb +29 -0
- data/lib/igniter/registry.rb +67 -0
- data/lib/igniter/runtime/resolver.rb +15 -0
- data/lib/igniter/saga/compensation.rb +31 -0
- data/lib/igniter/saga/compensation_record.rb +20 -0
- data/lib/igniter/saga/executor.rb +85 -0
- data/lib/igniter/saga/formatter.rb +49 -0
- data/lib/igniter/saga/result.rb +47 -0
- data/lib/igniter/saga.rb +56 -0
- data/lib/igniter/stream_loop.rb +80 -0
- data/lib/igniter/supervisor.rb +167 -0
- data/lib/igniter/version.rb +1 -1
- data/lib/igniter.rb +10 -0
- metadata +57 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Igniter
|
|
4
|
+
module Saga
|
|
5
|
+
# Immutable result of a saga execution (resolve_saga call).
|
|
6
|
+
#
|
|
7
|
+
# Attributes:
|
|
8
|
+
# contract — the contract instance that was executed
|
|
9
|
+
# error — Igniter::Error that caused failure (nil on success)
|
|
10
|
+
# failed_node — Symbol name of the first node that failed (nil on success)
|
|
11
|
+
# compensations — Array<CompensationRecord> for all attempted compensations
|
|
12
|
+
class Result
|
|
13
|
+
attr_reader :contract, :error, :failed_node, :compensations
|
|
14
|
+
|
|
15
|
+
def initialize(success:, contract:, error: nil, failed_node: nil, compensations: [])
|
|
16
|
+
@success = success
|
|
17
|
+
@contract = contract
|
|
18
|
+
@error = error
|
|
19
|
+
@failed_node = failed_node
|
|
20
|
+
@compensations = compensations.freeze
|
|
21
|
+
freeze
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def success? = @success
|
|
25
|
+
def failed? = !@success
|
|
26
|
+
|
|
27
|
+
# Human-readable saga report.
|
|
28
|
+
def explain
|
|
29
|
+
Formatter.format(self)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
alias to_s explain
|
|
33
|
+
|
|
34
|
+
# Structured (serialisable) representation.
|
|
35
|
+
def to_h
|
|
36
|
+
{
|
|
37
|
+
success: success?,
|
|
38
|
+
failed_node: failed_node,
|
|
39
|
+
error: error&.message,
|
|
40
|
+
compensations: compensations.map do |rec|
|
|
41
|
+
{ node: rec.node_name, success: rec.success?, error: rec.error&.message }
|
|
42
|
+
end
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/igniter/saga.rb
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "errors"
|
|
4
|
+
require_relative "saga/compensation"
|
|
5
|
+
require_relative "saga/compensation_record"
|
|
6
|
+
require_relative "saga/formatter"
|
|
7
|
+
require_relative "saga/result"
|
|
8
|
+
require_relative "saga/executor"
|
|
9
|
+
|
|
10
|
+
module Igniter
|
|
11
|
+
# Saga pattern — compensating transactions for Igniter contracts.
|
|
12
|
+
#
|
|
13
|
+
# When a contract execution fails partway through, the saga system
|
|
14
|
+
# automatically runs the compensating actions for all previously
|
|
15
|
+
# SUCCEEDED nodes, in reverse topological order.
|
|
16
|
+
#
|
|
17
|
+
# Usage:
|
|
18
|
+
#
|
|
19
|
+
# require "igniter/extensions/saga"
|
|
20
|
+
#
|
|
21
|
+
# class OrderWorkflow < Igniter::Contract
|
|
22
|
+
# define do
|
|
23
|
+
# input :order_id
|
|
24
|
+
# input :amount
|
|
25
|
+
#
|
|
26
|
+
# compute :reserve_stock, depends_on: :order_id do |order_id:|
|
|
27
|
+
# InventoryService.reserve(order_id)
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# compute :charge_card, depends_on: %i[order_id amount reserve_stock] do |amount:, **|
|
|
31
|
+
# raise "Declined" if amount > 1000
|
|
32
|
+
# PaymentService.charge(amount)
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# output :charge_card
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# compensate :charge_card do |inputs:, value:|
|
|
39
|
+
# PaymentService.refund(value[:charge_id])
|
|
40
|
+
# end
|
|
41
|
+
#
|
|
42
|
+
# compensate :reserve_stock do |inputs:, value:|
|
|
43
|
+
# InventoryService.release(value[:reservation_id])
|
|
44
|
+
# end
|
|
45
|
+
# end
|
|
46
|
+
#
|
|
47
|
+
# result = OrderWorkflow.new(order_id: "x1", amount: 1500).resolve_saga
|
|
48
|
+
# result.success? # => false
|
|
49
|
+
# result.failed_node # => :charge_card
|
|
50
|
+
# result.compensations.map(&:node_name) # => [:reserve_stock]
|
|
51
|
+
# puts result.explain
|
|
52
|
+
#
|
|
53
|
+
module Saga
|
|
54
|
+
class SagaError < Igniter::Error; end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Igniter
|
|
4
|
+
# Runs an Igniter contract in a continuous tick-loop.
|
|
5
|
+
#
|
|
6
|
+
# Each tick resolves the contract with the current inputs and delivers the
|
|
7
|
+
# result to the on_result callback. Useful for sensor polling, feed
|
|
8
|
+
# processing, or any recurring computation.
|
|
9
|
+
#
|
|
10
|
+
# stream = Igniter::StreamLoop.new(
|
|
11
|
+
# contract: SensorContract,
|
|
12
|
+
# tick_interval: 0.1,
|
|
13
|
+
# inputs: { sensor_id: "temp-1", threshold: 25.0 },
|
|
14
|
+
# on_result: ->(result) { puts result.status },
|
|
15
|
+
# on_error: ->(err) { warn err.message }
|
|
16
|
+
# )
|
|
17
|
+
#
|
|
18
|
+
# stream.start
|
|
19
|
+
# stream.update_inputs(threshold: 30.0) # hot-swap inputs between ticks
|
|
20
|
+
# stream.stop
|
|
21
|
+
#
|
|
22
|
+
class StreamLoop
|
|
23
|
+
def initialize(contract:, tick_interval: 1.0, inputs: {}, on_result: nil, on_error: nil)
|
|
24
|
+
@contract_class = contract
|
|
25
|
+
@tick_interval = tick_interval.to_f
|
|
26
|
+
@on_result = on_result
|
|
27
|
+
@on_error = on_error
|
|
28
|
+
@mutex = Mutex.new
|
|
29
|
+
@current_inputs = inputs.dup
|
|
30
|
+
@running = false
|
|
31
|
+
@thread = nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Start the loop in a background thread. Returns self.
|
|
35
|
+
def start
|
|
36
|
+
@running = true
|
|
37
|
+
@thread = Thread.new { loop_body }
|
|
38
|
+
@thread.abort_on_exception = false
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Stop the loop and wait for the current tick to finish.
|
|
43
|
+
def stop(timeout: 5)
|
|
44
|
+
@running = false
|
|
45
|
+
@thread&.join(timeout)
|
|
46
|
+
self
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Merge +new_inputs+ into the current input set. Takes effect on the next tick.
|
|
50
|
+
def update_inputs(new_inputs)
|
|
51
|
+
@mutex.synchronize { @current_inputs.merge!(new_inputs) }
|
|
52
|
+
self
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def alive?
|
|
56
|
+
@thread&.alive? || false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def loop_body
|
|
62
|
+
while @running
|
|
63
|
+
tick_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
64
|
+
run_tick
|
|
65
|
+
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - tick_start
|
|
66
|
+
sleep_for = [@tick_interval - elapsed, 0].max
|
|
67
|
+
sleep(sleep_for) if sleep_for.positive? && @running
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def run_tick
|
|
72
|
+
inputs = @mutex.synchronize { @current_inputs.dup }
|
|
73
|
+
contract = @contract_class.new(**inputs)
|
|
74
|
+
contract.resolve_all
|
|
75
|
+
@on_result&.call(contract.result)
|
|
76
|
+
rescue StandardError => e
|
|
77
|
+
@on_error&.call(e)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Igniter
|
|
4
|
+
# Supervises a group of agents and restarts them when they crash.
|
|
5
|
+
#
|
|
6
|
+
# Subclass Supervisor and declare children with the class-level DSL:
|
|
7
|
+
#
|
|
8
|
+
# class AppSupervisor < Igniter::Supervisor
|
|
9
|
+
# strategy :one_for_one # default
|
|
10
|
+
# max_restarts 5, within: 60 # default
|
|
11
|
+
#
|
|
12
|
+
# children do |c|
|
|
13
|
+
# c.worker :counter, CounterAgent
|
|
14
|
+
# c.worker :logger, LoggerAgent, initial_state: { level: :info }
|
|
15
|
+
# end
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# sup = AppSupervisor.start
|
|
19
|
+
# sup.child(:counter).send(:increment, by: 1)
|
|
20
|
+
# sup.stop
|
|
21
|
+
#
|
|
22
|
+
# Restart strategies:
|
|
23
|
+
# :one_for_one — restart only the crashed agent (default)
|
|
24
|
+
# :one_for_all — stop all agents and restart them all when any one crashes
|
|
25
|
+
#
|
|
26
|
+
# Restart budget: if more than +max_restarts+ crashes happen within +within+
|
|
27
|
+
# seconds, the supervisor logs the failure and stops trying to restart.
|
|
28
|
+
#
|
|
29
|
+
class Supervisor
|
|
30
|
+
class RestartBudgetExceeded < Igniter::Error; end
|
|
31
|
+
|
|
32
|
+
# ── ChildSpec ────────────────────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
ChildSpec = Struct.new(:name, :agent_class, :init_opts, keyword_init: true)
|
|
35
|
+
|
|
36
|
+
class ChildSpecBuilder
|
|
37
|
+
attr_reader :specs
|
|
38
|
+
|
|
39
|
+
def initialize
|
|
40
|
+
@specs = []
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def worker(name, agent_class, **opts)
|
|
44
|
+
@specs << ChildSpec.new(name: name.to_sym, agent_class: agent_class, init_opts: opts)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# ── Class-level defaults ─────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
@strategy = :one_for_one
|
|
51
|
+
@max_restarts = 5
|
|
52
|
+
@restart_window = 60
|
|
53
|
+
@spec_builder = ChildSpecBuilder.new
|
|
54
|
+
|
|
55
|
+
class << self
|
|
56
|
+
def inherited(subclass)
|
|
57
|
+
super
|
|
58
|
+
subclass.instance_variable_set(:@strategy, :one_for_one)
|
|
59
|
+
subclass.instance_variable_set(:@max_restarts, 5)
|
|
60
|
+
subclass.instance_variable_set(:@restart_window, 60)
|
|
61
|
+
subclass.instance_variable_set(:@spec_builder, ChildSpecBuilder.new)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def strategy(sym)
|
|
65
|
+
@strategy = sym
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def max_restarts(count, within:)
|
|
69
|
+
@max_restarts = count
|
|
70
|
+
@restart_window = within
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def children(&block)
|
|
74
|
+
block.call(@spec_builder)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def child_specs
|
|
78
|
+
@spec_builder.specs
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def start
|
|
82
|
+
new.tap(&:start_all)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# ── Instance ─────────────────────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
def initialize
|
|
89
|
+
@refs = {}
|
|
90
|
+
@specs_by_name = {}
|
|
91
|
+
@restart_log = []
|
|
92
|
+
@mutex = Mutex.new
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def start_all
|
|
96
|
+
self.class.child_specs.each do |spec|
|
|
97
|
+
@specs_by_name[spec.name] = spec
|
|
98
|
+
start_child(spec)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Return the Ref for a named child. Returns nil if not found.
|
|
103
|
+
def child(name)
|
|
104
|
+
@mutex.synchronize { @refs[name.to_sym] }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Stop all children gracefully.
|
|
108
|
+
def stop
|
|
109
|
+
refs = @mutex.synchronize { @refs.values.dup }
|
|
110
|
+
refs.each do |ref|
|
|
111
|
+
ref.stop
|
|
112
|
+
rescue StandardError
|
|
113
|
+
nil
|
|
114
|
+
end
|
|
115
|
+
self
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
private
|
|
119
|
+
|
|
120
|
+
def start_child(spec)
|
|
121
|
+
opts = spec.init_opts.dup
|
|
122
|
+
opts[:on_crash] = ->(error) { handle_crash(spec, error) }
|
|
123
|
+
ref = spec.agent_class.start(**opts)
|
|
124
|
+
@mutex.synchronize { @refs[spec.name] = ref }
|
|
125
|
+
ref
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def handle_crash(spec, _error)
|
|
129
|
+
check_restart_budget!
|
|
130
|
+
|
|
131
|
+
case self.class.instance_variable_get(:@strategy)
|
|
132
|
+
when :one_for_one
|
|
133
|
+
start_child(spec)
|
|
134
|
+
when :one_for_all
|
|
135
|
+
stop_all_children
|
|
136
|
+
self.class.child_specs.each { |s| start_child(s) }
|
|
137
|
+
end
|
|
138
|
+
rescue RestartBudgetExceeded => e
|
|
139
|
+
warn "Igniter::Supervisor #{self.class.name}: #{e.message}"
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def check_restart_budget! # rubocop:disable Metrics/MethodLength
|
|
143
|
+
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
144
|
+
window = self.class.instance_variable_get(:@restart_window).to_f
|
|
145
|
+
max = self.class.instance_variable_get(:@max_restarts)
|
|
146
|
+
|
|
147
|
+
@mutex.synchronize do
|
|
148
|
+
@restart_log.reject! { |t| now - t > window }
|
|
149
|
+
@restart_log << now
|
|
150
|
+
|
|
151
|
+
if @restart_log.size > max
|
|
152
|
+
raise RestartBudgetExceeded,
|
|
153
|
+
"#{@restart_log.size} crashes in #{window}s (max=#{max})"
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def stop_all_children
|
|
159
|
+
refs = @mutex.synchronize { @refs.values.dup }
|
|
160
|
+
refs.each do |ref|
|
|
161
|
+
ref.stop(timeout: 2)
|
|
162
|
+
rescue StandardError
|
|
163
|
+
nil
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
data/lib/igniter/version.rb
CHANGED
data/lib/igniter.rb
CHANGED
|
@@ -5,6 +5,8 @@ require_relative "igniter/errors"
|
|
|
5
5
|
require_relative "igniter/type_system"
|
|
6
6
|
require_relative "igniter/executor"
|
|
7
7
|
require_relative "igniter/executor_registry"
|
|
8
|
+
require_relative "igniter/effect"
|
|
9
|
+
require_relative "igniter/effect_registry"
|
|
8
10
|
require_relative "igniter/model"
|
|
9
11
|
require_relative "igniter/compiler"
|
|
10
12
|
require_relative "igniter/events"
|
|
@@ -32,6 +34,14 @@ module Igniter
|
|
|
32
34
|
executor_registry.register(key, executor_class, **metadata)
|
|
33
35
|
end
|
|
34
36
|
|
|
37
|
+
def effect_registry
|
|
38
|
+
@effect_registry ||= EffectRegistry.new
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def register_effect(key, adapter_class, **metadata)
|
|
42
|
+
effect_registry.register(key, adapter_class, **metadata)
|
|
43
|
+
end
|
|
44
|
+
|
|
35
45
|
def compile(&block)
|
|
36
46
|
DSL::ContractBuilder.compile(&block)
|
|
37
47
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: igniter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alexander
|
|
@@ -57,19 +57,35 @@ files:
|
|
|
57
57
|
- docs/DISTRIBUTED_CONTRACTS_V1.md
|
|
58
58
|
- docs/EXECUTION_MODEL_V2.md
|
|
59
59
|
- docs/IGNITER_CONCEPTS.md
|
|
60
|
+
- docs/LLM_V1.md
|
|
60
61
|
- docs/PATTERNS.md
|
|
62
|
+
- docs/SERVER_V1.md
|
|
61
63
|
- docs/STORE_ADAPTERS.md
|
|
62
64
|
- examples/README.md
|
|
65
|
+
- examples/agents.rb
|
|
63
66
|
- examples/async_store.rb
|
|
64
67
|
- examples/basic_pricing.rb
|
|
65
68
|
- examples/collection.rb
|
|
66
69
|
- examples/collection_partial_failure.rb
|
|
67
70
|
- examples/composition.rb
|
|
68
71
|
- examples/diagnostics.rb
|
|
72
|
+
- examples/differential.rb
|
|
73
|
+
- examples/distributed_server.rb
|
|
69
74
|
- examples/distributed_workflow.rb
|
|
75
|
+
- examples/effects.rb
|
|
76
|
+
- examples/invariants.rb
|
|
70
77
|
- examples/marketing_ergonomics.rb
|
|
78
|
+
- examples/order_pipeline.rb
|
|
79
|
+
- examples/provenance.rb
|
|
71
80
|
- examples/ringcentral_routing.rb
|
|
81
|
+
- examples/saga.rb
|
|
72
82
|
- lib/igniter.rb
|
|
83
|
+
- lib/igniter/agent.rb
|
|
84
|
+
- lib/igniter/agent/mailbox.rb
|
|
85
|
+
- lib/igniter/agent/message.rb
|
|
86
|
+
- lib/igniter/agent/ref.rb
|
|
87
|
+
- lib/igniter/agent/runner.rb
|
|
88
|
+
- lib/igniter/agent/state_holder.rb
|
|
73
89
|
- lib/igniter/compiler.rb
|
|
74
90
|
- lib/igniter/compiler/compiled_graph.rb
|
|
75
91
|
- lib/igniter/compiler/graph_compiler.rb
|
|
@@ -91,26 +107,44 @@ files:
|
|
|
91
107
|
- lib/igniter/diagnostics/introspection/formatters/mermaid_formatter.rb
|
|
92
108
|
- lib/igniter/diagnostics/introspection/formatters/text_tree_formatter.rb
|
|
93
109
|
- lib/igniter/diagnostics/report.rb
|
|
110
|
+
- lib/igniter/differential.rb
|
|
111
|
+
- lib/igniter/differential/divergence.rb
|
|
112
|
+
- lib/igniter/differential/formatter.rb
|
|
113
|
+
- lib/igniter/differential/report.rb
|
|
114
|
+
- lib/igniter/differential/runner.rb
|
|
94
115
|
- lib/igniter/dsl.rb
|
|
95
116
|
- lib/igniter/dsl/contract_builder.rb
|
|
96
117
|
- lib/igniter/dsl/schema_builder.rb
|
|
118
|
+
- lib/igniter/effect.rb
|
|
119
|
+
- lib/igniter/effect_registry.rb
|
|
97
120
|
- lib/igniter/errors.rb
|
|
98
121
|
- lib/igniter/events.rb
|
|
99
122
|
- lib/igniter/events/bus.rb
|
|
100
123
|
- lib/igniter/events/event.rb
|
|
124
|
+
- lib/igniter/execution_report.rb
|
|
125
|
+
- lib/igniter/execution_report/builder.rb
|
|
126
|
+
- lib/igniter/execution_report/formatter.rb
|
|
127
|
+
- lib/igniter/execution_report/node_entry.rb
|
|
128
|
+
- lib/igniter/execution_report/report.rb
|
|
101
129
|
- lib/igniter/executor.rb
|
|
102
130
|
- lib/igniter/executor_registry.rb
|
|
103
131
|
- lib/igniter/extensions.rb
|
|
104
132
|
- lib/igniter/extensions/auditing.rb
|
|
105
133
|
- lib/igniter/extensions/auditing/timeline.rb
|
|
134
|
+
- lib/igniter/extensions/differential.rb
|
|
135
|
+
- lib/igniter/extensions/execution_report.rb
|
|
106
136
|
- lib/igniter/extensions/introspection.rb
|
|
107
137
|
- lib/igniter/extensions/introspection/graph_formatter.rb
|
|
108
138
|
- lib/igniter/extensions/introspection/plan_formatter.rb
|
|
109
139
|
- lib/igniter/extensions/introspection/runtime_formatter.rb
|
|
140
|
+
- lib/igniter/extensions/invariants.rb
|
|
141
|
+
- lib/igniter/extensions/provenance.rb
|
|
110
142
|
- lib/igniter/extensions/reactive.rb
|
|
111
143
|
- lib/igniter/extensions/reactive/engine.rb
|
|
112
144
|
- lib/igniter/extensions/reactive/matcher.rb
|
|
113
145
|
- lib/igniter/extensions/reactive/reaction.rb
|
|
146
|
+
- lib/igniter/extensions/saga.rb
|
|
147
|
+
- lib/igniter/integrations/agents.rb
|
|
114
148
|
- lib/igniter/integrations/llm.rb
|
|
115
149
|
- lib/igniter/integrations/llm/config.rb
|
|
116
150
|
- lib/igniter/integrations/llm/context.rb
|
|
@@ -126,17 +160,31 @@ files:
|
|
|
126
160
|
- lib/igniter/integrations/rails/generators/install/install_generator.rb
|
|
127
161
|
- lib/igniter/integrations/rails/railtie.rb
|
|
128
162
|
- lib/igniter/integrations/rails/webhook_concern.rb
|
|
163
|
+
- lib/igniter/invariant.rb
|
|
129
164
|
- lib/igniter/model.rb
|
|
130
165
|
- lib/igniter/model/await_node.rb
|
|
131
166
|
- lib/igniter/model/branch_node.rb
|
|
132
167
|
- lib/igniter/model/collection_node.rb
|
|
133
168
|
- lib/igniter/model/composition_node.rb
|
|
134
169
|
- lib/igniter/model/compute_node.rb
|
|
170
|
+
- lib/igniter/model/effect_node.rb
|
|
135
171
|
- lib/igniter/model/graph.rb
|
|
136
172
|
- lib/igniter/model/input_node.rb
|
|
137
173
|
- lib/igniter/model/node.rb
|
|
138
174
|
- lib/igniter/model/output_node.rb
|
|
139
175
|
- lib/igniter/model/remote_node.rb
|
|
176
|
+
- lib/igniter/property_testing.rb
|
|
177
|
+
- lib/igniter/property_testing/formatter.rb
|
|
178
|
+
- lib/igniter/property_testing/generators.rb
|
|
179
|
+
- lib/igniter/property_testing/result.rb
|
|
180
|
+
- lib/igniter/property_testing/run.rb
|
|
181
|
+
- lib/igniter/property_testing/runner.rb
|
|
182
|
+
- lib/igniter/provenance.rb
|
|
183
|
+
- lib/igniter/provenance/builder.rb
|
|
184
|
+
- lib/igniter/provenance/lineage.rb
|
|
185
|
+
- lib/igniter/provenance/node_trace.rb
|
|
186
|
+
- lib/igniter/provenance/text_formatter.rb
|
|
187
|
+
- lib/igniter/registry.rb
|
|
140
188
|
- lib/igniter/runtime.rb
|
|
141
189
|
- lib/igniter/runtime/cache.rb
|
|
142
190
|
- lib/igniter/runtime/collection_result.rb
|
|
@@ -157,6 +205,12 @@ files:
|
|
|
157
205
|
- lib/igniter/runtime/stores/file_store.rb
|
|
158
206
|
- lib/igniter/runtime/stores/memory_store.rb
|
|
159
207
|
- lib/igniter/runtime/stores/redis_store.rb
|
|
208
|
+
- lib/igniter/saga.rb
|
|
209
|
+
- lib/igniter/saga/compensation.rb
|
|
210
|
+
- lib/igniter/saga/compensation_record.rb
|
|
211
|
+
- lib/igniter/saga/executor.rb
|
|
212
|
+
- lib/igniter/saga/formatter.rb
|
|
213
|
+
- lib/igniter/saga/result.rb
|
|
160
214
|
- lib/igniter/server.rb
|
|
161
215
|
- lib/igniter/server/client.rb
|
|
162
216
|
- lib/igniter/server/config.rb
|
|
@@ -170,6 +224,8 @@ files:
|
|
|
170
224
|
- lib/igniter/server/rack_app.rb
|
|
171
225
|
- lib/igniter/server/registry.rb
|
|
172
226
|
- lib/igniter/server/router.rb
|
|
227
|
+
- lib/igniter/stream_loop.rb
|
|
228
|
+
- lib/igniter/supervisor.rb
|
|
173
229
|
- lib/igniter/type_system.rb
|
|
174
230
|
- lib/igniter/version.rb
|
|
175
231
|
- sig/igniter.rbs
|