trailblazer-activity-dsl-linear 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -5
  3. data/CHANGES.md +72 -0
  4. data/Gemfile +6 -3
  5. data/lib/trailblazer/activity/dsl/linear/feature/merge.rb +2 -2
  6. data/lib/trailblazer/activity/dsl/linear/feature/patch.rb +9 -9
  7. data/lib/trailblazer/activity/dsl/linear/feature/variable_mapping/dsl.rb +19 -29
  8. data/lib/trailblazer/activity/dsl/linear/feature/variable_mapping/runtime.rb +6 -8
  9. data/lib/trailblazer/activity/dsl/linear/feature/variable_mapping.rb +25 -35
  10. data/lib/trailblazer/activity/dsl/linear/helper/path.rb +37 -18
  11. data/lib/trailblazer/activity/dsl/linear/helper.rb +27 -18
  12. data/lib/trailblazer/activity/dsl/linear/normalizer/extensions.rb +63 -0
  13. data/lib/trailblazer/activity/dsl/linear/normalizer/inherit.rb +90 -0
  14. data/lib/trailblazer/activity/dsl/linear/normalizer/output_tuples.rb +160 -0
  15. data/lib/trailblazer/activity/dsl/linear/normalizer/terminus.rb +26 -29
  16. data/lib/trailblazer/activity/dsl/linear/normalizer.rb +96 -148
  17. data/lib/trailblazer/activity/dsl/linear/sequence/builder.rb +3 -2
  18. data/lib/trailblazer/activity/dsl/linear/sequence/compiler.rb +21 -17
  19. data/lib/trailblazer/activity/dsl/linear/sequence/search.rb +2 -8
  20. data/lib/trailblazer/activity/dsl/linear/strategy.rb +17 -17
  21. data/lib/trailblazer/activity/dsl/linear/version.rb +1 -1
  22. data/lib/trailblazer/activity/dsl/linear.rb +12 -1
  23. data/lib/trailblazer/activity/fast_track.rb +91 -54
  24. data/lib/trailblazer/activity/path.rb +22 -29
  25. data/lib/trailblazer/activity/railway.rb +60 -54
  26. data/trailblazer-activity-dsl-linear.gemspec +7 -8
  27. metadata +21 -36
  28. data/.github/workflows/ci_jruby.yml +0 -19
  29. data/.github/workflows/ci_legacy.yml +0 -19
  30. data/.github/workflows/ci_truffleruby.yml +0 -19
  31. data/lib/trailblazer/activity/dsl/linear/feature/variable_mapping/inherit.rb +0 -38
@@ -6,10 +6,7 @@ module Trailblazer
6
6
  # and then get processed in the normalizer.
7
7
  #
8
8
  # @private
9
- OutputSemantic = Struct.new(:value)
10
- Id = Struct.new(:value)
11
- Track = Struct.new(:color, :adds, :options)
12
- Extension = Struct.new(:callable) do
9
+ Extension = Struct.new(:callable) do
13
10
  def call(*args, &block)
14
11
  callable.(*args, &block)
15
12
  end
@@ -27,14 +24,14 @@ module Trailblazer
27
24
 
28
25
  # Output( Left, :failure )
29
26
  # Output( :failure ) #=> Output::Semantic
30
- def Output(signal, semantic=nil)
31
- return OutputSemantic.new(signal) if semantic.nil?
27
+ def Output(signal, semantic = nil)
28
+ return Normalizer::OutputTuples::Output::Semantic.new(signal) if semantic.nil?
32
29
 
33
- Activity.Output(signal, semantic)
30
+ Normalizer::OutputTuples::Output::CustomOutput.new(signal, semantic)
34
31
  end
35
32
 
36
33
  def End(semantic)
37
- Activity.End(semantic)
34
+ Normalizer::OutputTuples::End.new(semantic).freeze
38
35
  end
39
36
 
40
37
  def end_id(semantic:, **)
@@ -42,15 +39,15 @@ module Trailblazer
42
39
  end
43
40
 
44
41
  def Track(color, wrap_around: false)
45
- Track.new(color, [], wrap_around: wrap_around).freeze
42
+ Normalizer::OutputTuples::Track.new(color, [], wrap_around: wrap_around).freeze
46
43
  end
47
44
 
48
45
  def Id(id)
49
- Id.new(id).freeze
46
+ Normalizer::OutputTuples::Id.new(id).freeze
50
47
  end
51
48
 
52
49
  def Path(**options, &block)
53
- options = options.merge(block: block) if block_given?
50
+ options = options.merge(block: block) if block
54
51
 
55
52
  Linear::PathBranch.new(options) # picked up by normalizer.
56
53
  end
@@ -59,27 +56,39 @@ module Trailblazer
59
56
  # @param :strict If true, all outputs of {activity} will be wired to the track named after the
60
57
  # output's semantic.
61
58
  def Subprocess(activity, patch: {}, strict: false)
62
- activity = Linear.Patch(activity, patch)
59
+ activity = Linear::Patch.customize(activity, options: patch)
63
60
 
64
61
  outputs = activity.to_h[:outputs]
65
62
  options = {}
66
63
 
67
64
  if strict
68
65
  options.merge!(
69
- outputs.collect { |output| [Output(output.semantic), Track(output.semantic)] }.to_h
66
+ outputs.collect { |output| [Normalizer::OutputTuples::Output::Semantic.new(output.semantic, true), Track(output.semantic)] }.to_h
70
67
  )
71
68
  end
72
69
 
73
70
  {
74
71
  task: activity,
75
72
  outputs: outputs.collect { |output| [output.semantic, output] }.to_h,
76
- }.
77
- merge(options)
73
+ }
74
+ .merge(options)
78
75
  end
79
76
 
80
- def In(**kws); VariableMapping::DSL::In(**kws); end
81
- def Out(**kws); VariableMapping::DSL::Out(**kws); end
82
- def Inject(*args, **kws); VariableMapping::DSL::Inject(*args, **kws); end
77
+ def In(**kws)
78
+ VariableMapping::DSL::In(**kws)
79
+ end
80
+
81
+ def Out(**kws)
82
+ VariableMapping::DSL::Out(**kws)
83
+ end
84
+
85
+ def Inject(*args, **kws)
86
+ VariableMapping::DSL::Inject(*args, **kws)
87
+ end
88
+
89
+ def Extension(*args, **kws)
90
+ Normalizer::Extensions.Extension(*args, **kws)
91
+ end
83
92
 
84
93
  def DataVariable
85
94
  DataVariableName.new
@@ -0,0 +1,63 @@
1
+ module Trailblazer
2
+ class Activity
3
+ module DSL
4
+ module Linear
5
+ module Normalizer
6
+ # Implements {:extensions} option and allows adding taskWrap extensions using
7
+ # Linear::Normalizer::Extensions.Extension().
8
+ module Extensions
9
+ module_function
10
+
11
+ Extension = Struct.new(:generic?, :id)
12
+
13
+ def Extension(is_generic: false)
14
+ Extension.new(is_generic, rand) # {id} has to be unique for every Extension instance (for Hash identity).
15
+ end
16
+
17
+ # Convert {:extensions} option to {Extension} tuples. The new way of adding extensions is
18
+ # step ..., Extension() => my_extension
19
+ def convert_extensions_option_to_tuples(ctx, non_symbol_options:, extensions: nil, **)
20
+ return unless extensions
21
+ # TODO: deprecate {:extensions} in the DSL?
22
+
23
+ extensions_tuples = extensions.collect { |ext| [Extension(), ext] }.to_h
24
+
25
+ ctx.merge!(
26
+ non_symbol_options: non_symbol_options.merge(extensions_tuples)
27
+ )
28
+ end
29
+
30
+ def compile_extensions(ctx, non_symbol_options:, **)
31
+ extensions_ary =
32
+ non_symbol_options
33
+ .find_all { |k, v| k.instance_of?(Extension) }
34
+ .to_h
35
+ .values
36
+
37
+ ctx.merge!(
38
+ extensions: extensions_ary
39
+ )
40
+ end
41
+
42
+ # Don't record Extension()s created by the DSL! This happens in VariableMapping, for instance.
43
+ # Either the user also inherits I/O tuples and the extension will be recreated,
44
+ # or they really don't want this particular extension to be inherited.
45
+ def compile_recorded_extensions(ctx, non_symbol_options:, **)
46
+ recorded_extension_tuples =
47
+ non_symbol_options
48
+ .find_all { |k, v| k.instance_of?(Extension) }
49
+ .reject { |k, v| k.generic? }
50
+ .to_h
51
+
52
+ ctx.merge!(
53
+ non_symbol_options: non_symbol_options.merge(
54
+ Normalizer::Inherit.Record(recorded_extension_tuples, type: :extensions)
55
+ )
56
+ )
57
+ end
58
+ end # Extensions
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,90 @@
1
+ module Trailblazer
2
+ class Activity
3
+ module DSL
4
+ module Linear
5
+ module Normalizer
6
+ # Implements the generic {:inherit} option.
7
+ # Features such as variable mapping or the Wiring API can
8
+ # use the generic behavior for their inheritance.
9
+
10
+ # "generic": built by the DSL from options, options that are inherited, so you might not want to record or inherit generic options
11
+ module Inherit
12
+ module_function
13
+
14
+ # Options you want to have stored and inherited can be
15
+ # declared using Record.
16
+ Record = Struct.new(:options, :type, :non_symbol_options?) # FIXME: i hate symbol vs. non-symbol.
17
+
18
+ def Record(options, type:, non_symbol_options: true)
19
+ {Record.new(options, type, non_symbol_options) => nil}
20
+ end
21
+
22
+ # Currently, the {:inherit} option copies over {:extensions} from the original step and merges them with new :extensions.
23
+ #
24
+ ### Recall
25
+ # Fetch remembered options and add them to the processed options.
26
+ def recall_recorded_options(ctx, non_symbol_options:, sequence:, id:, inherit: nil, extensions: [], **)
27
+ return unless inherit === true || inherit.is_a?(Array)
28
+
29
+ # E.g. {variable_mapping: true, wiring_api: true}
30
+ types_to_recall =
31
+ if inherit === true
32
+ # we want to inherit "everything": extensions, output_tuples, variable_mapping
33
+ Hash.new { true }
34
+ else
35
+ inherit.collect { |type| [type, true] }.to_h
36
+ end
37
+
38
+ row = find_row(sequence, id) # from this row we're inheriting options.
39
+
40
+ # DISCUSS: should we maybe revert the idea of separating options by type?
41
+ # Anyway, key idea here is that Record() users don't have to know these details
42
+ # about symbol vs. non-symbol.
43
+ symbol_options_to_merge = {}
44
+ non_symbol_options_to_merge = {}
45
+
46
+ row.data[:recorded_options].each do |type, record|
47
+ next unless types_to_recall[type]
48
+
49
+ target = record.non_symbol_options? ? non_symbol_options_to_merge : symbol_options_to_merge
50
+ target.merge!(record.options)
51
+ end
52
+
53
+ ctx[:non_symbol_options] = non_symbol_options_to_merge.merge(non_symbol_options)
54
+
55
+ ctx.merge!(symbol_options_to_merge)
56
+
57
+ ctx.merge!(
58
+ inherited_recorded_options: row.data[:recorded_options]
59
+ )
60
+ end
61
+
62
+ def find_row(sequence, id)
63
+ index = Activity::Adds::Insert.find_index(sequence, id)
64
+ sequence[index]
65
+ end
66
+
67
+ ### Record
68
+ # Figure out what to remember from the options and store it in {row.data[:recorded_options]}.
69
+ # Note that this is generic logic not tied to variable_mapping, OutputTuples or anything.
70
+ def compile_recorded_options(ctx, non_symbol_options:, **)
71
+ recorded_options = {}
72
+
73
+ non_symbol_options
74
+ .find_all { |k, v| k.instance_of?(Record) }
75
+ .collect do |k, v|
76
+ recorded_options[k.type] = k # DISCUSS: we overwrite potential data with same type.
77
+ end
78
+
79
+ ctx.merge!(
80
+ recorded_options: recorded_options,
81
+ # add {row.data[:recorded_options]} in Sequence:
82
+ non_symbol_options: non_symbol_options.merge(Strategy.DataVariable() => :recorded_options)
83
+ )
84
+ end
85
+ end # Inherit
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,160 @@
1
+ module Trailblazer
2
+ class Activity
3
+ module DSL
4
+ module Linear
5
+ module Normalizer
6
+ # Implements Output(:success) => Track(:success)
7
+ # Internals are documented: https://trailblazer.to/2.1/docs/internals.html#internals-wiring-api-output-tuples
8
+ module OutputTuples
9
+ module_function
10
+
11
+ # Connector when using Id(:validate).
12
+ class Id < Struct.new(:value)
13
+ def to_a(*)
14
+ return [Linear::Sequence::Search.method(:ById), value], [] # {value} is the "target".
15
+ end
16
+ end
17
+
18
+ # Connector when using Track(:success).
19
+ class Track < Struct.new(:color, :adds, :options)
20
+ def to_a(*)
21
+ search_strategy = options[:wrap_around] ? :WrapAround : :Forward
22
+
23
+ return [Linear::Sequence::Search.method(search_strategy), color], adds
24
+ end
25
+ end
26
+
27
+ # Connector representing a (to-be-created?) terminus when using End(:semantic).
28
+ class End < Struct.new(:semantic)
29
+ def to_a(ctx)
30
+ end_id = Linear::Strategy.end_id(semantic: semantic)
31
+ end_exists = Activity::Adds::Insert.find_index(ctx[:sequence], end_id)
32
+
33
+ terminus = Activity.End(semantic)
34
+
35
+ adds = end_exists ? [] : OutputTuples::Connections.add_terminus(terminus, id: end_id, sequence: ctx[:sequence], normalizers: ctx[:normalizers])
36
+
37
+ return [Linear::Sequence::Search.method(:ById), end_id], adds
38
+ end
39
+ end
40
+
41
+ # Logic related to {Output() => ...}, called "Wiring API".
42
+ # TODO: move to different namespace (feature/dsl)
43
+ def Output(semantic, is_generic: true)
44
+ Normalizer::OutputTuples::Output::Semantic.new(semantic, is_generic)
45
+ end
46
+
47
+ module Output
48
+ # Note that both {Semantic} and {CustomOutput} are {is_a?(Output)}
49
+ Semantic = Struct.new(:semantic, :generic?).include(Output)
50
+ CustomOutput = Struct.new(:signal, :semantic, :generic?).include(Output) # generic? is always false
51
+ end
52
+
53
+ def normalize_output_tuples(ctx, non_symbol_options:, **)
54
+ output_tuples = non_symbol_options.find_all { |k, v| k.is_a?(OutputTuples::Output) }
55
+
56
+ ctx.merge!(output_tuples: output_tuples)
57
+ end
58
+
59
+ # Remember all custom (non-generic) {:output_tuples}.
60
+ def remember_custom_output_tuples(ctx, output_tuples:, non_symbol_options:, **)
61
+ # We don't include generic OutputSemantic (from Subprocess(strict: true)) for inheritance, as this is not a user customization.
62
+ custom_output_tuples = output_tuples.reject { |k, v| k.generic? }
63
+
64
+ # save Output() tuples under {:custom_output_tuples} for inheritance.
65
+ ctx.merge!(
66
+ non_symbol_options: non_symbol_options.merge(
67
+ Normalizer::Inherit.Record(custom_output_tuples.to_h, type: :custom_output_tuples)
68
+ )
69
+ )
70
+ end
71
+
72
+ # Take all Output(signal, semantic), convert to OutputSemantic and extend {:outputs}.
73
+ # Since only users use this style, we don't have to filter.
74
+ def register_additional_outputs(ctx, output_tuples:, outputs:, **)
75
+ # We need to preserve the order when replacing Output with OutputSemantic,
76
+ # that's why we recreate {output_tuples} here.
77
+ output_tuples =
78
+ output_tuples.collect do |(output, connector)|
79
+ if output.is_a?(Output::CustomOutput)
80
+ # add custom output to :outputs.
81
+ outputs = outputs.merge(output.semantic => Activity.Output(output.signal, output.semantic))
82
+
83
+ # Convert Output to OutputSemantic.
84
+ [Strategy.Output(output.semantic), connector]
85
+ else
86
+ [output, connector]
87
+ end
88
+ end
89
+
90
+ ctx.merge!(
91
+ output_tuples: output_tuples,
92
+ outputs: outputs
93
+ )
94
+ end
95
+
96
+ # Implements {inherit: :outputs, strict: false}
97
+ # return connections from {parent} step which are supported by current step
98
+ def filter_inherited_output_tuples(ctx, outputs:, output_tuples:, inherit: false, inherited_recorded_options: {}, **)
99
+ return unless inherit === true
100
+ strict_outputs = false # TODO: implement "strict outputs" for inherit! meaning we connect all inherited Output regardless of the new activity's interface
101
+ return if strict_outputs === true
102
+
103
+ # Grab the inherited {:custom_output_tuples} so we can throw those out if the new activity doesn't support
104
+ # the respective outputs.
105
+ inherited_output_tuples_record = inherited_recorded_options[:custom_output_tuples]
106
+ inherited_output_tuples = inherited_output_tuples_record ? inherited_output_tuples_record.options : {}
107
+
108
+ allowed_semantics = outputs.keys # these outputs are exposed by the inheriting step.
109
+ inherited_semantics = inherited_output_tuples.collect { |output, _| output.semantic }
110
+ unsupported_semantics = inherited_semantics - allowed_semantics
111
+
112
+ filtered_output_tuples = output_tuples.reject { |output, _| unsupported_semantics.include?(output.semantic) }
113
+
114
+ ctx.merge!(
115
+ output_tuples: filtered_output_tuples.to_h
116
+ )
117
+ end
118
+
119
+ # Compile connections from tuples.
120
+ module Connections
121
+ module_function
122
+
123
+ # we want this in the end:
124
+ # {output.semantic => search strategy}
125
+ # Process {Output(:semantic) => target} and make them {:connections}.
126
+ # This combines {:connections} and {:outputs}
127
+ def compile_wirings(ctx, adds:, output_tuples:, outputs:, id:, **)
128
+ # DISCUSS: how could we add another magnetic_to to an end?
129
+ # Go through all {Output() => Track()/Id()/End()} tuples.
130
+ wirings =
131
+ output_tuples.collect do |output, connector|
132
+ (search_builder, search_args), connector_adds = connector.to_a(ctx) # Call {#to_a} on Track/Id/End/...
133
+
134
+ adds += connector_adds
135
+
136
+ semantic = output.semantic
137
+ output = outputs[semantic] || raise("No `#{semantic}` output found for #{id.inspect} and outputs #{outputs.inspect}")
138
+
139
+ # return proc to be called when compiling Seq, e.g. {ById(output, :id)}
140
+ search_builder.(output, *search_args)
141
+ end
142
+
143
+ ctx[:wirings] = wirings
144
+ ctx[:adds] = adds
145
+ end
146
+
147
+ # Returns ADDS for the new terminus.
148
+ # @private
149
+ def add_terminus(end_event, id:, sequence:, normalizers:)
150
+ step_options = Linear::Sequence::Builder.invoke_normalizer_for(:terminus, end_event, {id: id}, sequence: sequence, normalizer_options: {}, normalizers: normalizers)
151
+
152
+ step_options[:adds]
153
+ end
154
+ end # Connections
155
+ end # OutputTuples
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
@@ -10,28 +10,28 @@ module Trailblazer
10
10
  def Normalizer
11
11
  normalizer_steps =
12
12
  {
13
- "activity.normalize_step_interface" => Normalizer.Task(Normalizer.method(:normalize_step_interface)), # first
14
- "activity.merge_library_options" => Normalizer.Task(Normalizer.method(:merge_library_options)), # Merge "macro"/user options over library options.
15
- "activity.normalize_for_macro" => Normalizer.Task(Normalizer.method(:merge_user_options)),
16
- "activity.normalize_normalizer_options" => Normalizer.Task(Normalizer.method(:merge_normalizer_options)),
17
- "activity.normalize_non_symbol_options" => Normalizer.Task(Normalizer.method(:normalize_non_symbol_options)),
18
- "activity.normalize_context" => Normalizer.method(:normalize_context),
19
- "terminus.normalize_task" => Normalizer.Task(Terminus.method(:normalize_task)),
20
- "terminus.normalize_id" => Normalizer.Task(method(:normalize_id)),
21
- "terminus.normalize_magnetic_to" => Normalizer.Task(Terminus.method(:normalize_magnetic_to)),
22
- "terminus.append_end" => Normalizer.Task(Terminus.method(:append_end)),
13
+ "activity.normalize_step_interface" => Normalizer.Task(Normalizer.method(:normalize_step_interface)), # first
14
+ "activity.merge_library_options" => Normalizer.Task(Normalizer.method(:merge_library_options)), # Merge "macro"/user options over library options.
15
+ "activity.normalize_for_macro" => Normalizer.Task(Normalizer.method(:merge_user_options)),
16
+ "activity.normalize_normalizer_options" => Normalizer.Task(Normalizer.method(:merge_normalizer_options)),
17
+ "activity.normalize_non_symbol_options" => Normalizer.Task(Normalizer.method(:normalize_non_symbol_options)),
18
+ "activity.normalize_context" => Normalizer.method(:normalize_context),
19
+ "terminus.normalize_task" => Normalizer.Task(Terminus.method(:normalize_task)),
20
+ "terminus.normalize_id" => Normalizer.Task(method(:normalize_id)),
21
+ "terminus.normalize_magnetic_to" => Normalizer.Task(Terminus.method(:normalize_magnetic_to)),
22
+ "terminus.append_end" => Normalizer.Task(Terminus.method(:append_end)),
23
23
 
24
- "activity.compile_data" => Normalizer.Task(Normalizer.method(:compile_data)), # FIXME
25
- "activity.create_row" => Normalizer.Task(Normalizer.method(:create_row)),
26
- "activity.create_add" => Normalizer.Task(Normalizer.method(:create_add)),
27
- "activity.create_adds" => Normalizer.Task(Normalizer.method(:create_adds)),
24
+ "activity.compile_data" => Normalizer.Task(Normalizer.method(:compile_data)), # FIXME: redundant with {Linear::Normalizer}.
25
+ "activity.create_row" => Normalizer.Task(Normalizer.method(:create_row)),
26
+ "activity.create_add" => Normalizer.Task(Normalizer.method(:create_add)),
27
+ "activity.create_adds" => Normalizer.Task(Normalizer.method(:create_adds)),
28
28
  }
29
29
 
30
30
  TaskWrap::Pipeline.new(normalizer_steps.to_a)
31
31
  end
32
32
 
33
33
  # @private
34
- def normalize_id(ctx, id: nil, semantic:, **)
34
+ def normalize_id(ctx, semantic:, id: nil, **)
35
35
  ctx.merge!(
36
36
  id: id || Strategy.end_id(semantic: semantic)
37
37
  )
@@ -40,11 +40,11 @@ module Trailblazer
40
40
  # @private
41
41
  # Set {:task} and {:semantic}.
42
42
  def normalize_task(ctx, task:, **)
43
- if task.kind_of?(Activity::End) # DISCUSS: do we want this check?
44
- ctx = _normalize_task_for_end_event(ctx, **ctx)
43
+ if task.is_a?(Activity::End) # DISCUSS: do we want this check?
44
+ _ctx = _normalize_task_for_end_event(ctx, **ctx)
45
45
  else
46
46
  # When used such as {terminus :found}, create the end event automatically.
47
- ctx = _normalize_task_for_symbol(ctx, **ctx)
47
+ _ctx = _normalize_task_for_symbol(ctx, **ctx)
48
48
  end
49
49
  end
50
50
 
@@ -56,8 +56,8 @@ module Trailblazer
56
56
 
57
57
  def _normalize_task_for_symbol(ctx, task:, semantic: task, **)
58
58
  ctx.merge!(
59
- task: Strategy.End(semantic),
60
- semantic: semantic,
59
+ task: Activity.End(semantic),
60
+ semantic: semantic
61
61
  )
62
62
  end
63
63
 
@@ -68,19 +68,16 @@ module Trailblazer
68
68
  end
69
69
 
70
70
  # @private
71
- def append_end(ctx, task:, semantic:, append_to: "End.success", **)
71
+ def append_end(ctx, task:, append_to: "End.success", non_symbol_options:, **)
72
72
  terminus_args = {
73
- sequence_insert: [Activity::Adds::Insert.method(:Append), append_to],
74
- stop_event: true
73
+ sequence_insert: [Activity::Adds::Insert.method(:Append), append_to],
74
+ stop_event: true,
75
+ non_symbol_options: non_symbol_options.merge(Strategy.DataVariable() => [:stop_event, :semantic])
75
76
  }
76
77
 
77
78
  ctx.merge!(
78
- wirings: [
79
- Linear::Sequence::Search::Noop(
80
- Activity::Output.new(task, semantic), # DISCUSS: do we really want to transport the semantic "in" the object?
81
- )
82
- ],
83
- adds: [],
79
+ wirings: [],
80
+ adds: [],
84
81
  **terminus_args
85
82
  )
86
83
  end