hecks 0.3.0 → 1.0.1
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/lib/hecks/adapters/driven/d1.rb +38 -14
- data/lib/hecks/adapters/driven/governance_authorization.rb +41 -2
- data/lib/hecks/adapters/driven/heki/journal.rb +7 -2
- data/lib/hecks/adapters/driven/heki/saga_store.rb +0 -0
- data/lib/hecks/adapters/driven/heki/snapshot.rb +31 -4
- data/lib/hecks/adapters/driven/heki.rb +40 -9
- data/lib/hecks/adapters/driven/lambda.rb +16 -2
- data/lib/hecks/adapters/driven/postgres/codec.rb +8 -0
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +45 -6
- data/lib/hecks/adapters/driven/postgres.rb +76 -29
- data/lib/hecks/adapters/driven/postgres_era.adapter +11 -0
- data/lib/hecks/adapters/driven/sql_query_builder.rb +1 -1
- data/lib/hecks/adapters/driven/sqlite/codec.rb +17 -0
- data/lib/hecks/adapters/driven/sqlite/projection.rb +76 -9
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +17 -5
- data/lib/hecks/adapters/driven/sqlite.rb +30 -9
- data/lib/hecks/adapters/driven.rb +19 -1
- data/lib/hecks/behaviors/dsl.rb +29 -0
- data/lib/hecks/behaviors/expectations.rb +62 -2
- data/lib/hecks/bluebook/assembly/contracts.rb +36 -7
- data/lib/hecks/bluebook/assembly/marks.rb +4 -3
- data/lib/hecks/bluebook/assembly.rb +14 -1
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +18 -1
- data/lib/hecks/bluebook/behaviour/process_manager.rb +14 -1
- data/lib/hecks/bluebook/behaviour/value_object.rb +13 -7
- data/lib/hecks/bluebook/chapter.rb +21 -11
- data/lib/hecks/bluebook/command.rb +1 -1
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +117 -5
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +21 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +71 -2
- data/lib/hecks/bluebook/dsl/command_builder.rb +144 -3
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +49 -7
- data/lib/hecks/bluebook/dsl/entity_builder.rb +129 -4
- data/lib/hecks/bluebook/dsl/policy_builder.rb +18 -3
- data/lib/hecks/bluebook/dsl/port_builder.rb +12 -3
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +109 -10
- data/lib/hecks/bluebook/dsl/rule_reference.rb +1 -0
- data/lib/hecks/bluebook/dsl/word_gate.rb +9 -2
- data/lib/hecks/bluebook/dsl/world_builder.rb +44 -4
- data/lib/hecks/bluebook/expression/ast_json.rb +149 -0
- data/lib/hecks/bluebook/expression/canonical_form.rb +71 -3
- data/lib/hecks/bluebook/expression/evaluator.rb +50 -7
- data/lib/hecks/bluebook/expression/projection.json +48 -0
- data/lib/hecks/bluebook/expression/resolver.rb +161 -10
- data/lib/hecks/bluebook/expression.rb +1 -0
- data/lib/hecks/bluebook/hexagon.rb +1 -1
- data/lib/hecks/bluebook/meta_validator/judge.rb +78 -16
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +4 -0
- data/lib/hecks/bluebook/meta_validator/readings.rb +14 -4
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +42 -3
- data/lib/hecks/bluebook/meta_validator/shapes.rb +30 -10
- data/lib/hecks/bluebook/meta_validator.rb +103 -13
- data/lib/hecks/bluebook/model_check.rb +147 -6
- data/lib/hecks/bluebook/pattern_subset.rb +66 -2
- data/lib/hecks/bluebook/process_manager.rb +53 -11
- data/lib/hecks/bluebook/project_register.rb +25 -0
- data/lib/hecks/bluebook/value_object.rb +19 -2
- data/lib/hecks/doc/reference.rb +22 -1
- data/lib/hecks/facade/cli_door.rb +6 -3
- data/lib/hecks/facade/json_door.rb +16 -4
- data/lib/hecks/forms/app.rb +47 -6
- data/lib/hecks/forms/command_form_renderer.rb +1 -1
- data/lib/hecks/forms/field_renderer.rb +11 -4
- data/lib/hecks/forms/html.rb +31 -0
- data/lib/hecks/forms/params.rb +30 -1
- data/lib/hecks/forms/port_argument.rb +46 -0
- data/lib/hecks/forms/record_renderer.rb +6 -2
- data/lib/hecks/forms/record_table.rb +6 -1
- data/lib/hecks/framework/bluebook/console_settings.bluebook +19 -19
- data/lib/hecks/framework/bluebook/governance.bluebook +26 -11
- data/lib/hecks/framework/bluebook/identity.bluebook +2 -2
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +527 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +3 -2
- data/lib/hecks/fuzzing/isolated_boot.rb +212 -18
- data/lib/hecks/fuzzing/properties.rb +52 -6
- data/lib/hecks/fuzzing/replay.rb +51 -18
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +28 -2
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +71 -6
- data/lib/hecks/fuzzing/sequence_generator.rb +5 -4
- data/lib/hecks/fuzzing/value_generator.rb +25 -2
- data/lib/hecks/grammar/evolve.rb +33 -0
- data/lib/hecks/grammar/expression.bluebook +8 -5
- data/lib/hecks/grammar/expression_operators.json +497 -1
- data/lib/hecks/language/bluebook/aggregate.bluebook +12 -12
- data/lib/hecks/language/bluebook/bluebook.bluebook +3 -3
- data/lib/hecks/language/bluebook/command.bluebook +42 -8
- data/lib/hecks/language/bluebook/entity.bluebook +86 -10
- data/lib/hecks/language/bluebook/policy.bluebook +21 -4
- data/lib/hecks/language/bluebook/process_manager.bluebook +135 -18
- data/lib/hecks/language/bluebook/projection.bluebook +6 -6
- data/lib/hecks/language/bluebook/query.bluebook +4 -4
- data/lib/hecks/language/bluebook/shape.bluebook +6 -6
- data/lib/hecks/language/bluebook/syntax.bluebook +12 -11
- data/lib/hecks/language/bluebook/vocabulary.bluebook +22 -7
- data/lib/hecks/language/hecksagon/domain_port.bluebook +25 -1
- data/lib/hecks/language/oidc.json +20 -0
- data/lib/hecks/language/port.bluebook +30 -2
- data/lib/hecks/naming.rb +54 -1
- data/lib/hecks/ports/access_control.port +7 -2
- data/lib/hecks/ports/access_control.rb +1 -1
- data/lib/hecks/ports/agent.port +6 -2
- data/lib/hecks/ports/agent.rb +1 -1
- data/lib/hecks/ports/authentication.port +4 -2
- data/lib/hecks/ports/authentication.rb +1 -1
- data/lib/hecks/ports/authorization.port +5 -2
- data/lib/hecks/ports/authorization.rb +14 -11
- data/lib/hecks/ports/clock.port +3 -2
- data/lib/hecks/ports/clock.rb +1 -1
- data/lib/hecks/ports/extraction.port +3 -2
- data/lib/hecks/ports/extraction.rb +1 -1
- data/lib/hecks/ports/identity_assignment.port +3 -2
- data/lib/hecks/ports/identity_assignment.rb +1 -1
- data/lib/hecks/ports/identity_generation.port +3 -2
- data/lib/hecks/ports/identity_generation.rb +1 -1
- data/lib/hecks/ports/identity_resolution.port +3 -2
- data/lib/hecks/ports/identity_resolution.rb +1 -1
- data/lib/hecks/ports/persistence/append_only.rb +40 -4
- data/lib/hecks/ports/persistence/execution.rb +6 -1
- data/lib/hecks/ports/persistence/plugin.rb +54 -0
- data/lib/hecks/{runtime → ports/persistence/plugins/era}/era_check.rb +41 -8
- data/lib/hecks/{runtime → ports/persistence/plugins/era}/era_guard.rb +24 -56
- data/lib/hecks/ports/persistence/{lineage.rb → plugins/era/lineage.rb} +31 -4
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage/era_store.rb +3 -3
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage/head_compiler.rb +59 -10
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage/mint_transaction.rb +2 -2
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage/provisioning.rb +29 -1
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage/tail_merge.rb +11 -4
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage/transform_installer.rb +20 -0
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage.rb +1 -1
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage_manager/coverage_check.rb +5 -5
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage_manager/era_resolver.rb +5 -2
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage_manager/merge_coordinator.rb +2 -2
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage_manager/minter.rb +4 -4
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage_manager.rb +2 -2
- data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era.rb +116 -29
- data/lib/hecks/{translation → ports/persistence/plugins/era/translation}/audit/approval_digest.rb +1 -1
- data/lib/hecks/{translation → ports/persistence/plugins/era/translation}/audit/layer_one.rb +14 -5
- data/lib/hecks/{translation → ports/persistence/plugins/era/translation}/audit/layer_two.rb +31 -6
- data/lib/hecks/{translation → ports/persistence/plugins/era/translation}/audit/unfed_report.rb +5 -1
- data/lib/hecks/{translation → ports/persistence/plugins/era/translation}/reattest.rb +3 -3
- data/lib/hecks/{translation → ports/persistence/plugins/era/translation}/scaffold/differ.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era.rb +48 -0
- data/lib/hecks/ports/persistence.rb +1 -1
- data/lib/hecks/ports/projection.rb +20 -0
- data/lib/hecks/projections/diagrams.rb +230 -1
- data/lib/hecks/projections/shape.rb +15 -2
- data/lib/hecks/projector/cli_projector.rb +10 -1
- data/lib/hecks/projector/exporter.rb +19 -2
- data/lib/hecks/query_ir.rb +19 -0
- data/lib/hecks/query_specification/common/null_policy.rb +13 -1
- data/lib/hecks/query_specification/field_path.rb +20 -2
- data/lib/hecks/query_specification/hop_path.rb +7 -5
- data/lib/hecks/runtime/aggregate_lock.rb +45 -0
- data/lib/hecks/runtime/boot_gates.rb +41 -0
- data/lib/hecks/runtime/caller.rb +19 -3
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +13 -2
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +12 -0
- data/lib/hecks/runtime/command_interpreter.rb +165 -34
- data/lib/hecks/runtime/command_rules/admissibility.rb +101 -16
- data/lib/hecks/runtime/command_rules/arithmetic.rb +40 -4
- data/lib/hecks/runtime/command_rules/authorization.rb +2 -1
- data/lib/hecks/runtime/command_rules/references.rb +27 -19
- data/lib/hecks/runtime/dependency_planning.rb +66 -5
- data/lib/hecks/runtime/dispatcher.rb +19 -4
- data/lib/hecks/runtime/entity_interpreter.rb +92 -14
- data/lib/hecks/runtime/errors.rb +22 -0
- data/lib/hecks/runtime/identity.rb +30 -2
- data/lib/hecks/runtime/instance.rb +59 -4
- data/lib/hecks/runtime/interpreting.rb +21 -0
- data/lib/hecks/runtime/loader.rb +59 -18
- data/lib/hecks/runtime/query_interpreter.rb +36 -4
- data/lib/hecks/runtime/reaction_invocation.rb +9 -1
- data/lib/hecks/runtime/read_model_interpreter.rb +89 -5
- data/lib/hecks/runtime/refusal_wording.rb +2 -0
- data/lib/hecks/runtime/registry/saga_persistence.rb +75 -3
- data/lib/hecks/runtime/registry/verification.rb +88 -0
- data/lib/hecks/runtime/registry.rb +69 -8
- data/lib/hecks/runtime/saga_interpreter.rb +215 -13
- data/lib/hecks/runtime/saga_pending_dispatch.rb +45 -0
- data/lib/hecks/runtime/value/admission.rb +19 -1
- data/lib/hecks/runtime/value/coercion.rb +75 -10
- data/lib/hecks/runtime.rb +17 -5
- data/lib/hecks/storehouse.rb +632 -0
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks/vocabulary.rb +6 -1
- data/lib/hecks.rb +28 -3
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +90 -0
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +128 -0
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +160 -0
- metadata +49 -37
- /data/lib/hecks/{runtime → ports/persistence/plugins/era}/era_guard/shape_diff.rb +0 -0
- /data/lib/hecks/{runtime → ports/persistence/plugins/era}/era_tamper.rb +0 -0
- /data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage/field_cache.rb +0 -0
- /data/lib/hecks/{adapters/driven → ports/persistence/plugins/era}/postgres_era/lineage/resumable_backfill.rb +0 -0
- /data/lib/hecks/{runtime → ports/persistence/plugins/era}/storage_shape.rb +0 -0
- /data/lib/hecks/{translation → ports/persistence/plugins/era/translation}/audit.rb +0 -0
- /data/lib/hecks/{translation → ports/persistence/plugins/era/translation}/rule_compiler.rb +0 -0
- /data/lib/hecks/{translation → ports/persistence/plugins/era/translation}/scaffold/renderer.rb +0 -0
- /data/lib/hecks/{translation → ports/persistence/plugins/era/translation}/scaffold/writer.rb +0 -0
- /data/lib/hecks/{translation → ports/persistence/plugins/era/translation}/scaffold.rb +0 -0
- /data/lib/hecks/{translation.rb → ports/persistence/plugins/era/translation.rb} +0 -0
|
@@ -54,6 +54,28 @@ Hecks.bluebook "Bluebook" do
|
|
|
54
54
|
attribute :value, String
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
# ONE DISPATCH'S OWN ORDER AMONG ITS HANDLER'S SIBLINGS — named
|
|
58
|
+
# DispatchPosition rather than reusing ProcessManager's own `Position`
|
|
59
|
+
# four lines below (same discipline as `MemberPosition`/shape.bluebook's
|
|
60
|
+
# own comment on the identical choice): that one orders process
|
|
61
|
+
# managers among a CHAPTER's siblings ; this one orders dispatches
|
|
62
|
+
# within ONE handler. Same shape, different fact.
|
|
63
|
+
#
|
|
64
|
+
# Part of `identified_by`, below, alongside `command_name` — a real
|
|
65
|
+
# handler fans the SAME command out more than once with different
|
|
66
|
+
# `with:` bindings each leg (item #151's own real example: one
|
|
67
|
+
# BodyPulse handler dispatching Signal.FireSignal once per organ),
|
|
68
|
+
# and `command_name` alone collided the instant it did: the Judge's
|
|
69
|
+
# own `entity_duplicate` check raised the moment a second dispatch of
|
|
70
|
+
# the same command was declared, an uncaught crash for a legitimate,
|
|
71
|
+
# common pattern. `position` names WHICH send this is and is safe to
|
|
72
|
+
# fold into identity exactly where it would not be for Handler's own
|
|
73
|
+
# `from_state` (a real business value) — a Dispatch is declared once,
|
|
74
|
+
# at load time, and never re-addressed by identity afterward.
|
|
75
|
+
value_object "DispatchPosition" do
|
|
76
|
+
attribute :value, Integer
|
|
77
|
+
end
|
|
78
|
+
|
|
57
79
|
# The way back: everything DECLARED IN the chapter above. The parent
|
|
58
80
|
# reference IS the query.
|
|
59
81
|
# WHERE IT SITS AMONG ITS SIBLINGS. Declaration order is a FACT ABOUT THE
|
|
@@ -96,7 +118,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
96
118
|
sets :starts_on
|
|
97
119
|
sets :ends_on
|
|
98
120
|
sets :position
|
|
99
|
-
emits
|
|
121
|
+
emits SagaDeclared
|
|
100
122
|
end
|
|
101
123
|
|
|
102
124
|
command "State" do
|
|
@@ -107,7 +129,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
107
129
|
|
|
108
130
|
sets :states, append: { name: :name }
|
|
109
131
|
|
|
110
|
-
emits
|
|
132
|
+
emits SagaStateAttached
|
|
111
133
|
end
|
|
112
134
|
|
|
113
135
|
# THE HANDLER'S OWN CREATION. S17, ADR 0026 — Handler is a genuine
|
|
@@ -136,7 +158,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
136
158
|
|
|
137
159
|
sets :handlers, append: { event_type: :event_type, from_state: :from_state, to_state: :to_state }
|
|
138
160
|
|
|
139
|
-
emits
|
|
161
|
+
emits LegDeclared
|
|
140
162
|
end
|
|
141
163
|
|
|
142
164
|
# S17, ADR 0026 — ONE HANDLER, nested rather than its own root
|
|
@@ -147,22 +169,34 @@ Hecks.bluebook "Bluebook" do
|
|
|
147
169
|
# wrong thing, holds nothing, and duplicates the reference beside it.
|
|
148
170
|
#
|
|
149
171
|
# `event_type` is an event name, or one of the Trigger vocabulary's
|
|
150
|
-
# members when the leg answers something no aggregate announces —
|
|
151
|
-
#
|
|
152
|
-
#
|
|
153
|
-
#
|
|
154
|
-
#
|
|
172
|
+
# members when the leg answers something no aggregate announces — but
|
|
173
|
+
# NOT, alone, Handler's own identity any more (items #151/#152's own
|
|
174
|
+
# finding): a state machine legitimately answers the SAME event
|
|
175
|
+
# differently depending on which state it is currently in — one event
|
|
176
|
+
# name, several distinct legs (a BodyPulse handler that moves
|
|
177
|
+
# `attentive -> attentive` and, separately, `sleeping_light ->
|
|
178
|
+
# sleeping_light`) — and `event_type` alone collided the instant a
|
|
179
|
+
# real corpus declared that shape: the Judge's own `entity_duplicate`
|
|
180
|
+
# check raised `AlreadyExists` the moment the second leg was declared,
|
|
181
|
+
# an uncaught crash, not a refusal, for a common, legitimate pattern.
|
|
182
|
+
# `from_state` joins it below for exactly this reason — a real
|
|
183
|
+
# business value, not a stand-in for missing meaning, the same
|
|
184
|
+
# distinction `DispatchPosition`'s own comment (above) draws for its
|
|
185
|
+
# sibling `Dispatch`. The process manager this leg belongs to stays
|
|
186
|
+
# structural (which list this element sits in), never a stored field.
|
|
155
187
|
entity "Handler" do
|
|
156
188
|
description "One handler inside a process manager — the event it answers, the state move it makes, and the commands it sends. Nested under the process manager because a handler holds nested dispatches, which hold nested bindings."
|
|
157
189
|
|
|
158
|
-
|
|
159
|
-
|
|
190
|
+
attribute :event_type, HandlerText
|
|
160
191
|
attribute :from_state, HandlerText
|
|
161
192
|
attribute :to_state, HandlerText
|
|
162
193
|
# S17, ADR 0026 — Dispatch nested here too (see `entity "Dispatch"`,
|
|
163
194
|
# below), one level further in than Handler itself.
|
|
164
195
|
attribute :dispatches, list_of(Dispatch)
|
|
165
196
|
|
|
197
|
+
# BOTH FIELDS TOGETHER — see the class-level comment above.
|
|
198
|
+
identified_by :event_type, :from_state
|
|
199
|
+
|
|
166
200
|
# THE DISPATCH'S OWN CREATION — same reason Handler's own creation
|
|
167
201
|
# lives on ProcessManager, one level up: an entity is never created
|
|
168
202
|
# through its own dotted verb. Reached as a DOTTED verb itself
|
|
@@ -174,10 +208,17 @@ Hecks.bluebook "Bluebook" do
|
|
|
174
208
|
goal "Open a dispatch inside a handler"
|
|
175
209
|
|
|
176
210
|
attribute :command_name, DispatchText
|
|
211
|
+
# THE WALK INDEX, never author-supplied — the same generic
|
|
212
|
+
# POSITION handling `ValueObject.Member`'s own creating command
|
|
213
|
+
# already relies on (`Judge#appends`), which fills this from
|
|
214
|
+
# where the walk found the dispatch, not from a field the row
|
|
215
|
+
# happens to hold. No real `.bluebook` author ever calls this
|
|
216
|
+
# verb directly; only the Judge's own replay does.
|
|
217
|
+
attribute :position, DispatchPosition
|
|
177
218
|
|
|
178
|
-
sets :dispatches, append: { command_name: :command_name }
|
|
219
|
+
sets :dispatches, append: { command_name: :command_name, position: :position }
|
|
179
220
|
|
|
180
|
-
emits
|
|
221
|
+
emits SendDeclared
|
|
181
222
|
end
|
|
182
223
|
|
|
183
224
|
# S17, ADR 0026 — ONE COMMAND A HANDLER DISPATCHES, nested two
|
|
@@ -185,12 +226,21 @@ Hecks.bluebook "Bluebook" do
|
|
|
185
226
|
# its Handler" (the ADR's own words). The bindings are an open
|
|
186
227
|
# map, which no value object can hold — that was always a reason
|
|
187
228
|
# it could not be one, never a reason it could not be an entity.
|
|
188
|
-
# `command_name`
|
|
189
|
-
#
|
|
229
|
+
# `command_name` ALONE used to be Dispatch's own identity, the same
|
|
230
|
+
# shape Handler's own `event_type` took one level up — and collided
|
|
231
|
+
# the same way, for the same real reason (item #151): one handler
|
|
232
|
+
# fanning the SAME command out several times with different `with:`
|
|
233
|
+
# bindings each time (one BodyPulse handler dispatching
|
|
234
|
+
# Signal.FireSignal once per organ). `position` joins it below —
|
|
235
|
+
# see `DispatchPosition`'s own comment for why that field, unlike
|
|
236
|
+
# Handler's `from_state`, is safe to fold into identity.
|
|
190
237
|
entity "Dispatch" do
|
|
191
238
|
description "One command a handler dispatches, with the arguments it binds. Nested under the handler because the bindings are an open map, which no value object can hold."
|
|
192
239
|
|
|
193
|
-
|
|
240
|
+
attribute :command_name, DispatchText
|
|
241
|
+
attribute :position, DispatchPosition
|
|
242
|
+
|
|
243
|
+
identified_by :command_name, :position
|
|
194
244
|
|
|
195
245
|
attribute :with_spec, list_of(Binding)
|
|
196
246
|
|
|
@@ -203,7 +253,50 @@ Hecks.bluebook "Bluebook" do
|
|
|
203
253
|
|
|
204
254
|
sets :with_spec, append: { key: :key, value: :value }
|
|
205
255
|
|
|
206
|
-
emits
|
|
256
|
+
emits BindingAttached
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# THE COMPENSATING DISPATCH THIS ONE COMPENSATES FOR, IF ANY —
|
|
260
|
+
# FLAT FIELDS on THIS SAME entity, mirroring `command_name`/
|
|
261
|
+
# `with_spec` above one-for-one, rather than a nested (or
|
|
262
|
+
# self-referential) second `Dispatch`: an entity's own attribute
|
|
263
|
+
# type has to resolve against a value object, and neither a
|
|
264
|
+
# self-reference to `Dispatch` (written from inside its own
|
|
265
|
+
# block, before it exists to reference) nor a plain nested
|
|
266
|
+
# entity reference passes that check the way `Handler.
|
|
267
|
+
# dispatches: list_of(Dispatch)` does — that one resolves a
|
|
268
|
+
# SIBLING already fully built by the time deferred construction
|
|
269
|
+
# (ADR 0028) finishes; a dispatch compensating for itself has no
|
|
270
|
+
# such sibling. `compensates_command_name` absent means no
|
|
271
|
+
# compensation; present, together with whatever
|
|
272
|
+
# `compensates_with_spec` holds, is everything
|
|
273
|
+
# `Reconstruction#dispatch` needs to assemble the SAME
|
|
274
|
+
# `DispatchSpec` shape `compensates` (the real, author-facing
|
|
275
|
+
# word) fills.
|
|
276
|
+
attribute :compensates_command_name, DispatchText, optional: true
|
|
277
|
+
attribute :compensates_with_spec, list_of(Binding)
|
|
278
|
+
|
|
279
|
+
command "Compensates" do
|
|
280
|
+
role "Language"
|
|
281
|
+
goal "Name the command this dispatch compensates for"
|
|
282
|
+
|
|
283
|
+
attribute :compensates_command_name, DispatchText
|
|
284
|
+
|
|
285
|
+
sets :compensates_command_name
|
|
286
|
+
|
|
287
|
+
emits "CompensationDeclared"
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
command "BindCompensation" do
|
|
291
|
+
role "Language"
|
|
292
|
+
goal "Bind one argument of the compensation's own dispatched command"
|
|
293
|
+
|
|
294
|
+
attribute :key, DispatchText
|
|
295
|
+
attribute :value, DispatchText
|
|
296
|
+
|
|
297
|
+
sets :compensates_with_spec, append: { key: :key, value: :value }
|
|
298
|
+
|
|
299
|
+
emits "CompensationBindingAttached"
|
|
207
300
|
end
|
|
208
301
|
end
|
|
209
302
|
end
|
|
@@ -224,11 +317,30 @@ Hecks.bluebook "Bluebook" do
|
|
|
224
317
|
attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
|
|
225
318
|
|
|
226
319
|
member word: "correlates_by", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "correlates_by"
|
|
227
|
-
|
|
228
|
-
|
|
320
|
+
# BARE CONSTANT ACCEPTED (ADR 0025, S6 — "events first-class"),
|
|
321
|
+
# `starts_on Transfer::TransferRequested` / `ends_on
|
|
322
|
+
# Transfer::TransferSettled`, same `kind: "constant"` + `kind:
|
|
323
|
+
# "text"` ArgumentSeed pair `emits`/policy's own `on` already
|
|
324
|
+
# carry (this row's own comment there). Now `calls:`-routed
|
|
325
|
+
# (`starts_on_impl`/`ends_on_impl`, hand-written — GenericDispatch's
|
|
326
|
+
# own `COERCE_BY_KIND` has no "constant" entry, so a bare
|
|
327
|
+
# constant needs the same `Naming.event_ref` resolution `on_impl`/
|
|
328
|
+
# `transition_impl` already do, not the plain `.to_s` a single
|
|
329
|
+
# `kind: "text"` row used to get for free).
|
|
330
|
+
member word: "starts_on", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "", calls: "starts_on_impl"
|
|
331
|
+
member word: "ends_on", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "", calls: "ends_on_impl"
|
|
229
332
|
member word: "transition", context: "ProcessManager", body: "keywords", inner: "Handler", opens: "Handler", fills: "", calls: "transition_impl"
|
|
230
333
|
member word: "transition", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "", calls: "transition_impl"
|
|
334
|
+
# TWO ROWS, the SAME PAIR SHAPE `transition` takes just above —
|
|
335
|
+
# `body: "none"` was already the only row (`opens: "Dispatch"`
|
|
336
|
+
# already anticipated a block, unused until now); `body:
|
|
337
|
+
# "keywords"` is the new one, opening `compensates` on the
|
|
338
|
+
# dispatch it sits inside (per-dispatch saga compensation — see
|
|
339
|
+
# `ProcessManagerBuilder::HandlerBuilder#dispatch_impl`'s own
|
|
340
|
+
# comment).
|
|
341
|
+
member word: "dispatch", context: "Handler", body: "keywords", inner: "Dispatch", opens: "Dispatch", fills: "", calls: "dispatch_impl"
|
|
231
342
|
member word: "dispatch", context: "Handler", body: "none", inner: "", opens: "Dispatch", fills: "", calls: "dispatch_impl"
|
|
343
|
+
member word: "compensates", context: "Dispatch", body: "none", inner: "", opens: "", fills: "", calls: "compensates_impl"
|
|
232
344
|
|
|
233
345
|
end
|
|
234
346
|
|
|
@@ -250,7 +362,9 @@ Hecks.bluebook "Bluebook" do
|
|
|
250
362
|
attribute :blank_message, String
|
|
251
363
|
|
|
252
364
|
member keyword: "correlates_by", context: "ProcessManager", at: "1", named: "", kind: "symbol", required: "true", fills: "correlates_by"
|
|
365
|
+
member keyword: "starts_on", context: "ProcessManager", at: "1", named: "", kind: "constant", required: "true", fills: "starts_on"
|
|
253
366
|
member keyword: "starts_on", context: "ProcessManager", at: "1", named: "", kind: "text", required: "true", fills: "starts_on"
|
|
367
|
+
member keyword: "ends_on", context: "ProcessManager", at: "1", named: "", kind: "constant", required: "true", fills: "ends_on"
|
|
254
368
|
member keyword: "ends_on", context: "ProcessManager", at: "1", named: "", kind: "text", required: "true", fills: "ends_on"
|
|
255
369
|
member keyword: "transition", context: "ProcessManager", at: "1", named: "", kind: "pairs", required: "true", fills: "", pair_key_fills: "event_type", pair_value_fills: "to_state", pairs_shape: "fields"
|
|
256
370
|
member keyword: "transition", context: "ProcessManager", at: "", named: "from", kind: "text", required: "true", fills: "from_state"
|
|
@@ -258,6 +372,9 @@ Hecks.bluebook "Bluebook" do
|
|
|
258
372
|
member keyword: "dispatch", context: "Handler", at: "1", named: "", kind: "constant", required: "true", fills: "command_name"
|
|
259
373
|
member keyword: "dispatch", context: "Handler", at: "1", named: "", kind: "text", required: "true", fills: "command_name"
|
|
260
374
|
member keyword: "dispatch", context: "Handler", at: "", named: "with", kind: "pairs", required: "false", fills: "with_spec", pairs_shape: "verbatim"
|
|
375
|
+
member keyword: "compensates", context: "Dispatch", at: "1", named: "", kind: "constant", required: "true", fills: "command_name"
|
|
376
|
+
member keyword: "compensates", context: "Dispatch", at: "1", named: "", kind: "text", required: "true", fills: "command_name"
|
|
377
|
+
member keyword: "compensates", context: "Dispatch", at: "", named: "with", kind: "pairs", required: "false", fills: "with_spec", pairs_shape: "verbatim"
|
|
261
378
|
|
|
262
379
|
end
|
|
263
380
|
end
|
|
@@ -110,7 +110,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
110
110
|
sets :reference_name
|
|
111
111
|
sets :reference_target
|
|
112
112
|
sets :position
|
|
113
|
-
emits
|
|
113
|
+
emits ProjectionDeclared
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
command "Gather" do
|
|
@@ -140,7 +140,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
140
140
|
|
|
141
141
|
sets :aggregate_heads, append: { aggregate: :aggregate, as: :as, many: :many }
|
|
142
142
|
|
|
143
|
-
emits
|
|
143
|
+
emits HeadGathered
|
|
144
144
|
end
|
|
145
145
|
|
|
146
146
|
command "GroupBy" do
|
|
@@ -153,7 +153,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
153
153
|
|
|
154
154
|
sets :group_by, append: { field: :field }
|
|
155
155
|
|
|
156
|
-
emits
|
|
156
|
+
emits GroupByFieldAdded
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
# `count`/`median` are LATE-SET scalars, the same shape `Lifecycle`'s
|
|
@@ -171,7 +171,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
171
171
|
|
|
172
172
|
sets :count
|
|
173
173
|
|
|
174
|
-
emits
|
|
174
|
+
emits CountDeclared
|
|
175
175
|
end
|
|
176
176
|
|
|
177
177
|
command "Median" do
|
|
@@ -183,7 +183,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
183
183
|
|
|
184
184
|
sets :median_field
|
|
185
185
|
|
|
186
|
-
emits
|
|
186
|
+
emits MedianFieldSet
|
|
187
187
|
end
|
|
188
188
|
|
|
189
189
|
command "Option" do
|
|
@@ -200,7 +200,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
200
200
|
|
|
201
201
|
sets :options, append: { option: :option, key: :key, value: :value, at: :at }
|
|
202
202
|
|
|
203
|
-
emits
|
|
203
|
+
emits OptionAttached
|
|
204
204
|
end
|
|
205
205
|
|
|
206
206
|
# HOW READMODEL IS SPELLED. These rows live with the concept
|
|
@@ -118,7 +118,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
118
118
|
sets :order_way
|
|
119
119
|
sets :limit
|
|
120
120
|
sets :position
|
|
121
|
-
emits
|
|
121
|
+
emits AskDeclared
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
command "Filter" do
|
|
@@ -132,7 +132,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
132
132
|
|
|
133
133
|
sets :wheres, append: { field: :field, op: :op, value: :value }
|
|
134
134
|
|
|
135
|
-
emits
|
|
135
|
+
emits FilterAttached
|
|
136
136
|
end
|
|
137
137
|
|
|
138
138
|
command "Option" do
|
|
@@ -153,7 +153,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
153
153
|
|
|
154
154
|
sets :options, append: { option: :option, key: :key, value: :value, at: :at }
|
|
155
155
|
|
|
156
|
-
emits
|
|
156
|
+
emits OptionAttached
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
command "Argument" do
|
|
@@ -176,7 +176,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
176
176
|
|
|
177
177
|
sets :attributes, append: { name: :name, type: :type, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
178
178
|
|
|
179
|
-
emits
|
|
179
|
+
emits AskArgumentAttached
|
|
180
180
|
end
|
|
181
181
|
|
|
182
182
|
|
|
@@ -109,7 +109,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
109
109
|
sets :aggregate
|
|
110
110
|
sets :name
|
|
111
111
|
sets :position
|
|
112
|
-
emits
|
|
112
|
+
emits ShapeDeclared
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
command "Field" do
|
|
@@ -134,7 +134,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
134
134
|
|
|
135
135
|
sets :attributes, append: { name: :name, type: :type, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
136
136
|
|
|
137
|
-
emits
|
|
137
|
+
emits ShapeFieldAttached
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
command "Close" do
|
|
@@ -150,7 +150,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
150
150
|
|
|
151
151
|
sets :rows
|
|
152
152
|
|
|
153
|
-
emits
|
|
153
|
+
emits ShapeClosed
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
command "Assert" do
|
|
@@ -165,7 +165,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
165
165
|
|
|
166
166
|
sets :invariants, append: { description: :description, canonical: :canonical }
|
|
167
167
|
|
|
168
|
-
emits
|
|
168
|
+
emits AssertionAttached
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
value_object "ValueObjectText" do
|
|
@@ -192,7 +192,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
192
192
|
|
|
193
193
|
sets :members, append: { position: :position }
|
|
194
194
|
|
|
195
|
-
emits
|
|
195
|
+
emits MemberDeclared
|
|
196
196
|
end
|
|
197
197
|
|
|
198
198
|
# S17, ADR 0026 — ONE ADMITTED ROW, nested rather than its own root
|
|
@@ -228,7 +228,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
228
228
|
|
|
229
229
|
sets :pairs, append: { key: :key, value: :value }
|
|
230
230
|
|
|
231
|
-
emits
|
|
231
|
+
emits PairBound
|
|
232
232
|
end
|
|
233
233
|
end
|
|
234
234
|
|
|
@@ -86,8 +86,8 @@ Hecks.bluebook "Bluebook" do
|
|
|
86
86
|
value_object "Context" do
|
|
87
87
|
attribute :name, String,
|
|
88
88
|
one_of: ["File", "Bluebook", "Aggregate", "Entity", "Command", "Query", "ValueObject", "OneOf",
|
|
89
|
-
"Lifecycle", "Policy", "ProcessManager", "Handler", "
|
|
90
|
-
"World", "DomainPort", "PortOperation", "Port", "Adapter", "Translation",
|
|
89
|
+
"Lifecycle", "Policy", "ProcessManager", "Handler", "Dispatch", "ReadModel", "Type",
|
|
90
|
+
"Hecksagon", "World", "DomainPort", "PortOperation", "Port", "Adapter", "Translation",
|
|
91
91
|
"TranslationAggregate"]
|
|
92
92
|
end
|
|
93
93
|
|
|
@@ -252,8 +252,9 @@ Hecks.bluebook "Bluebook" do
|
|
|
252
252
|
# WHICH DISAMBIGUATOR keyword argument a bare reference may supply
|
|
253
253
|
# when `resolves_via` is `owner_keyed` — see `Disambiguator`'s own
|
|
254
254
|
# comment. BLANK unless `resolves_via` is `owner_keyed` AND more
|
|
255
|
-
# than one candidate can register (today:
|
|
256
|
-
#
|
|
255
|
+
# than one candidate can register (today: `given` on Aggregate,
|
|
256
|
+
# and `given` on Entity, one level down — chapter-wide sharing at
|
|
257
|
+
# each scope it has grown to).
|
|
257
258
|
attribute :disambiguator, KeywordSeedText, admits: "Syntax::Disambiguator", optional: true
|
|
258
259
|
# THE ESCAPE HATCH — item #13's full metaprogrammed dispatch (slice
|
|
259
260
|
# 3, whole-project table-unification survey). BLANK for every word
|
|
@@ -291,14 +292,14 @@ Hecks.bluebook "Bluebook" do
|
|
|
291
292
|
role "Language"
|
|
292
293
|
goal "Mark a word as on its way out, still read"
|
|
293
294
|
|
|
294
|
-
emits
|
|
295
|
+
emits KeywordDeprecated
|
|
295
296
|
end
|
|
296
297
|
|
|
297
298
|
command "Retire" do
|
|
298
299
|
role "Language"
|
|
299
300
|
goal "Remove a word from every generated parser table"
|
|
300
301
|
|
|
301
|
-
emits
|
|
302
|
+
emits KeywordRetired
|
|
302
303
|
end
|
|
303
304
|
end
|
|
304
305
|
|
|
@@ -375,14 +376,14 @@ Hecks.bluebook "Bluebook" do
|
|
|
375
376
|
role "Language"
|
|
376
377
|
goal "Mark an argument as on its way out, still read"
|
|
377
378
|
|
|
378
|
-
emits
|
|
379
|
+
emits ArgumentDeprecated
|
|
379
380
|
end
|
|
380
381
|
|
|
381
382
|
command "Retire" do
|
|
382
383
|
role "Language"
|
|
383
384
|
goal "Remove an argument from every generated parser table"
|
|
384
385
|
|
|
385
|
-
emits
|
|
386
|
+
emits ArgumentRetired
|
|
386
387
|
end
|
|
387
388
|
end
|
|
388
389
|
|
|
@@ -408,7 +409,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
408
409
|
sets :bluebook
|
|
409
410
|
sets :name
|
|
410
411
|
|
|
411
|
-
emits
|
|
412
|
+
emits SyntaxDeclared
|
|
412
413
|
end
|
|
413
414
|
|
|
414
415
|
# THE KEYWORD'S OWN CREATION. An entity is never created through its
|
|
@@ -426,7 +427,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
426
427
|
inner: :inner, opens: :opens, fills: :fills, was: :was,
|
|
427
428
|
resolves_via: :resolves_via, disambiguator: :disambiguator, calls: :calls }
|
|
428
429
|
|
|
429
|
-
emits
|
|
430
|
+
emits KeywordAdmitted
|
|
430
431
|
end
|
|
431
432
|
|
|
432
433
|
command "Argument" do
|
|
@@ -441,7 +442,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
441
442
|
variadic: :variadic, minimum: :minimum,
|
|
442
443
|
coerce: :coerce, blank_message: :blank_message }
|
|
443
444
|
|
|
444
|
-
emits
|
|
445
|
+
emits ArgumentAdmitted
|
|
445
446
|
end
|
|
446
447
|
end
|
|
447
448
|
end
|
|
@@ -130,6 +130,13 @@ Hecks.bluebook "Bluebook" do
|
|
|
130
130
|
# shape append does (`with: {...}` is a field map, same as
|
|
131
131
|
# append's own `fields:`), so it carries no sign, same reading.
|
|
132
132
|
member name: "delegate", sign: ""
|
|
133
|
+
# CommandBuilder#corrects_impl's own comment gives the full
|
|
134
|
+
# reasoning — a command declaring a past event it amends, rather
|
|
135
|
+
# than a fresh mutation of its own. Rides the SAME multi-binding
|
|
136
|
+
# wire shape append/delegate do (`as:`/`reason:`/`reverses:`,
|
|
137
|
+
# assembled into one `source` hash by hand, same as `with:` is),
|
|
138
|
+
# so it carries no sign either.
|
|
139
|
+
member name: "corrects", sign: ""
|
|
133
140
|
end
|
|
134
141
|
|
|
135
142
|
# QuerySpecification::Common::Comparators::COMPARATORS — a where-clause's
|
|
@@ -175,17 +182,23 @@ Hecks.bluebook "Bluebook" do
|
|
|
175
182
|
|
|
176
183
|
# EntityInterpreter#call — the same shape
|
|
177
184
|
# one level down, on a piece an aggregate holds rather than the aggregate
|
|
178
|
-
# itself.
|
|
179
|
-
#
|
|
180
|
-
#
|
|
181
|
-
#
|
|
185
|
+
# itself. `refuse_unknown_arguments`/`refuse_absent_arguments` lead it,
|
|
186
|
+
# the same position they hold in AggregateDispatchOrder — bug audit H1
|
|
187
|
+
# (docs/audits/2026-08-10-main-bug-audit.md): an entity command used to
|
|
188
|
+
# run NEITHER at all, on a since-corrected comment claiming it "inherits
|
|
189
|
+
# its aggregate's own gate" — nothing on this path ever ran one, and a
|
|
190
|
+
# bogus argument or a silently-nil'd absent one both went straight
|
|
191
|
+
# through. The only real difference from AggregateDispatchOrder now is
|
|
192
|
+
# that an entity is never CREATED through this path (no
|
|
193
|
+
# assign_creation_attributes) — hydrating the parent and locating the
|
|
182
194
|
# element replace a single hydrate. resolve_references stayed, though —
|
|
183
195
|
# an entity command can declare a reference-typed attribute the same way
|
|
184
196
|
# an aggregate command can (CommandRules#resolve_references is shared by
|
|
185
197
|
# both interpreters), even though nothing in the real corpus does yet.
|
|
186
198
|
value_object "EntityDispatchOrder" do
|
|
187
199
|
attribute :step, String,
|
|
188
|
-
one_of: ["
|
|
200
|
+
one_of: ["refuse_unknown_arguments", "refuse_absent_arguments", "normalize_args",
|
|
201
|
+
"refuse_role_mismatch", "resolve_references", "hydrate_parent",
|
|
189
202
|
"locate_element", "enforce_givens", "admissible_transition", "apply_mutations",
|
|
190
203
|
"advance_lifecycle", "enforce_ensures", "enforce_invariants", "save", "emit"]
|
|
191
204
|
end
|
|
@@ -196,8 +209,8 @@ Hecks.bluebook "Bluebook" do
|
|
|
196
209
|
value_object "DomainRefusal" do
|
|
197
210
|
attribute :name, String,
|
|
198
211
|
one_of: ["AbsentArgument", "AlreadyExists", "AttributeAbsent", "EnsuresNotMet", "GivenNotMet",
|
|
199
|
-
"InvariantViolation", "LifecycleRefused", "
|
|
200
|
-
"TypeMismatch", "Unauthorized", "UnknownArgument", "UnknownVerb"]
|
|
212
|
+
"InvariantViolation", "LifecycleRefused", "NothingToCorrect", "NotFound", "ProjectionAbsent",
|
|
213
|
+
"RemoteRefusal", "TypeMismatch", "Unauthorized", "UnknownArgument", "UnknownVerb"]
|
|
201
214
|
end
|
|
202
215
|
|
|
203
216
|
# THE WORDING ITSELF, for every DomainRefusal site that is not already
|
|
@@ -279,6 +292,8 @@ Hecks.bluebook "Bluebook" do
|
|
|
279
292
|
template: "{type} is a composite identity — an identity must have exactly one field"
|
|
280
293
|
member refusal: "TypeMismatch", site: "numeric_field",
|
|
281
294
|
template: "{type}.{field} expects {expected}, got {offered}"
|
|
295
|
+
member refusal: "TypeMismatch", site: "non_finite_field",
|
|
296
|
+
template: "{type}.{field} must be a finite number, got {offered}"
|
|
282
297
|
member refusal: "TypeMismatch", site: "pattern_mismatch",
|
|
283
298
|
template: "{type}.{field} must match {pattern}, got {offered}"
|
|
284
299
|
member refusal: "TypeMismatch", site: "arithmetic_amount",
|
|
@@ -4,7 +4,9 @@ Hecks.bluebook "Hecksagon" do
|
|
|
4
4
|
|
|
5
5
|
identified_by PortName, as: :name
|
|
6
6
|
|
|
7
|
-
attribute :verb,
|
|
7
|
+
attribute :verb, PortVerb, optional: true
|
|
8
|
+
attribute :signal, PortSignal, optional: true
|
|
9
|
+
attribute :answers, list_of(PortAnswer)
|
|
8
10
|
|
|
9
11
|
value_object "PortName" do
|
|
10
12
|
attribute :value, String
|
|
@@ -16,6 +18,24 @@ Hecks.bluebook "Hecksagon" do
|
|
|
16
18
|
invariant("a verb is named") { !value.to_s.empty? }
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
# SAME CLOSED SET port.bluebook's own "Port" aggregate declares —
|
|
22
|
+
# kept as its own local value object rather than shared cross-
|
|
23
|
+
# chapter, the same way PortVerb already is here.
|
|
24
|
+
value_object "PortSignal" do
|
|
25
|
+
attribute :value, String, one_of: ["reply", "effect"]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# `answers` — DomainPortBuilder's own twin of PortBuilder#answers
|
|
29
|
+
# (port.bluebook's "Port" aggregate, same shape), added once a real
|
|
30
|
+
# `.port` file migrated to parse through this builder (the repoint
|
|
31
|
+
# `lib/hecks.rb#port`'s own comment describes) used the word
|
|
32
|
+
# (`extraction.port`'s own `answers :canonical`). Local, not shared
|
|
33
|
+
# cross-chapter, same reasoning as PortSignal just above.
|
|
34
|
+
value_object "PortAnswer" do
|
|
35
|
+
attribute :value, String
|
|
36
|
+
invariant("an answer names a real method") { !value.to_s.empty? }
|
|
37
|
+
end
|
|
38
|
+
|
|
19
39
|
# HOW DOMAINPORT IS SPELLED. These rows live with the concept
|
|
20
40
|
# they describe; SyntaxBoot discovers every aggregate-local seed table.
|
|
21
41
|
# Contexts represented here: DomainPort.
|
|
@@ -35,6 +55,8 @@ Hecks.bluebook "Hecksagon" do
|
|
|
35
55
|
member word: "tells", context: "DomainPort", body: "keywords", inner: "PortOperation", opens: "PortOperation", fills: "", calls: "tells_impl"
|
|
36
56
|
member word: "asks", context: "DomainPort", body: "keywords", inner: "PortOperation", opens: "PortOperation", fills: "", calls: "asks_impl"
|
|
37
57
|
member word: "verb", context: "DomainPort", body: "none", inner: "", opens: "", fills: "verb"
|
|
58
|
+
member word: "signal", context: "DomainPort", body: "none", inner: "", opens: "", fills: "signal"
|
|
59
|
+
member word: "answers", context: "DomainPort", body: "none", inner: "", opens: "", fills: "answers"
|
|
38
60
|
|
|
39
61
|
end
|
|
40
62
|
|
|
@@ -59,6 +81,8 @@ Hecks.bluebook "Hecksagon" do
|
|
|
59
81
|
member keyword: "tells", context: "DomainPort", at: "1", named: "", kind: "text", required: "true", fills: "name"
|
|
60
82
|
member keyword: "asks", context: "DomainPort", at: "1", named: "", kind: "text", required: "true", fills: "name"
|
|
61
83
|
member keyword: "verb", context: "DomainPort", at: "1", named: "", kind: "text", required: "true", fills: "verb"
|
|
84
|
+
member keyword: "signal", context: "DomainPort", at: "1", named: "", kind: "symbol", required: "true", fills: "signal"
|
|
85
|
+
member keyword: "answers", context: "DomainPort", at: "1", named: "", kind: "symbol", required: "true", fills: "answers"
|
|
62
86
|
|
|
63
87
|
# THE RECEIVING AGGREGATE — PortOperationBuilder's own `reference_to`
|
|
64
88
|
# (inside the block) is refused (#335); this is the sanctioned
|
|
@@ -126,6 +126,11 @@
|
|
|
126
126
|
"verb": "Bluebook::Entity.Declare",
|
|
127
127
|
"role": "Language"
|
|
128
128
|
},
|
|
129
|
+
{
|
|
130
|
+
"scope": "bluebook:entity.holds",
|
|
131
|
+
"verb": "Bluebook::Entity.Holds",
|
|
132
|
+
"role": "Language"
|
|
133
|
+
},
|
|
129
134
|
{
|
|
130
135
|
"scope": "bluebook:entity.identify",
|
|
131
136
|
"verb": "Bluebook::Entity.Identify",
|
|
@@ -146,6 +151,11 @@
|
|
|
146
151
|
"verb": "Bluebook::Entity.Precondition",
|
|
147
152
|
"role": "Language"
|
|
148
153
|
},
|
|
154
|
+
{
|
|
155
|
+
"scope": "bluebook:entity.reference",
|
|
156
|
+
"verb": "Bluebook::Entity.Reference",
|
|
157
|
+
"role": "Language"
|
|
158
|
+
},
|
|
149
159
|
{
|
|
150
160
|
"scope": "bluebook:entity.seal",
|
|
151
161
|
"verb": "Bluebook::Entity.Seal",
|
|
@@ -186,6 +196,16 @@
|
|
|
186
196
|
"verb": "Bluebook::ProcessManager.Handler.Dispatch.Bind",
|
|
187
197
|
"role": "Language"
|
|
188
198
|
},
|
|
199
|
+
{
|
|
200
|
+
"scope": "bluebook:process_manager.handler.dispatch.bind_compensation",
|
|
201
|
+
"verb": "Bluebook::ProcessManager.Handler.Dispatch.BindCompensation",
|
|
202
|
+
"role": "Language"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"scope": "bluebook:process_manager.handler.dispatch.compensates",
|
|
206
|
+
"verb": "Bluebook::ProcessManager.Handler.Dispatch.Compensates",
|
|
207
|
+
"role": "Language"
|
|
208
|
+
},
|
|
189
209
|
{
|
|
190
210
|
"scope": "bluebook:process_manager.state",
|
|
191
211
|
"verb": "Bluebook::ProcessManager.State",
|