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
|
@@ -146,7 +146,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
146
146
|
sets :description
|
|
147
147
|
sets :provenance
|
|
148
148
|
sets :position
|
|
149
|
-
emits
|
|
149
|
+
emits RootDeclared
|
|
150
150
|
end
|
|
151
151
|
|
|
152
152
|
# ONE PART OF THE IDENTITY, attached the way one attribute is. It was an
|
|
@@ -182,7 +182,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
182
182
|
given("an identity part names something") { !path.value.to_s.empty? }
|
|
183
183
|
|
|
184
184
|
sets :identified_by, append: { value: :path }
|
|
185
|
-
emits
|
|
185
|
+
emits RootIdentified
|
|
186
186
|
end
|
|
187
187
|
|
|
188
188
|
# The way back, one level down: the aggregates DECLARED IN a chapter, found by
|
|
@@ -238,7 +238,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
238
238
|
|
|
239
239
|
sets :attributes, append: { name: :name, type: :type, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
240
240
|
|
|
241
|
-
emits
|
|
241
|
+
emits AttributeAttached
|
|
242
242
|
end
|
|
243
243
|
|
|
244
244
|
# An attribute that points at ANOTHER aggregate's head.
|
|
@@ -276,7 +276,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
276
276
|
|
|
277
277
|
sets :attributes, append: { name: :name, type: :points_at, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
278
278
|
|
|
279
|
-
emits
|
|
279
|
+
emits ReferenceAttached
|
|
280
280
|
end
|
|
281
281
|
|
|
282
282
|
# An attribute whose type names a PIECE this aggregate holds.
|
|
@@ -303,7 +303,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
303
303
|
|
|
304
304
|
sets :attributes, append: { name: :name, type: :holds, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
305
305
|
|
|
306
|
-
emits
|
|
306
|
+
emits PieceHeld
|
|
307
307
|
end
|
|
308
308
|
|
|
309
309
|
# THE ONLY RULE THAT CAN REFUSE AN UNNAMED ATTRIBUTE, and it lives here.
|
|
@@ -357,7 +357,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
357
357
|
sets :state_field
|
|
358
358
|
sets :state_start
|
|
359
359
|
|
|
360
|
-
emits
|
|
360
|
+
emits LifecycleNamed
|
|
361
361
|
end
|
|
362
362
|
|
|
363
363
|
command "Transition" do
|
|
@@ -370,7 +370,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
370
370
|
|
|
371
371
|
sets :transitions, append: { command: :command, from_state: :from_state, to_state: :to_state }
|
|
372
372
|
|
|
373
|
-
emits
|
|
373
|
+
emits TransitionAttached
|
|
374
374
|
end
|
|
375
375
|
|
|
376
376
|
command "Seal" do
|
|
@@ -410,7 +410,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
410
410
|
# is Identify's rule ; this one only asks that there be one.
|
|
411
411
|
given("an aggregate says what it is known by") { !identified_by.empty? }
|
|
412
412
|
|
|
413
|
-
emits
|
|
413
|
+
emits RootSealed
|
|
414
414
|
end
|
|
415
415
|
|
|
416
416
|
command "Value" do
|
|
@@ -421,7 +421,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
421
421
|
|
|
422
422
|
sets :value_objects, append: { name: :name }
|
|
423
423
|
|
|
424
|
-
emits
|
|
424
|
+
emits ValueDeclared
|
|
425
425
|
end
|
|
426
426
|
|
|
427
427
|
# THE AGGREGATE BOUNDARY (S10, ADR 0025 — "Rules") — the same shape
|
|
@@ -438,7 +438,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
438
438
|
|
|
439
439
|
sets :invariants, append: { description: :description, canonical: :canonical }
|
|
440
440
|
|
|
441
|
-
emits
|
|
441
|
+
emits InvariantAttached
|
|
442
442
|
end
|
|
443
443
|
|
|
444
444
|
# A PRECONDITION SHARED ACROSS COMMANDS, DECLARED ONCE (S10, ADR
|
|
@@ -456,7 +456,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
456
456
|
|
|
457
457
|
sets :preconditions, append: { description: :description, canonical: :canonical }
|
|
458
458
|
|
|
459
|
-
emits
|
|
459
|
+
emits PreconditionAttached
|
|
460
460
|
end
|
|
461
461
|
|
|
462
462
|
# THE LOCAL HALF OF A CROSS-AGGREGATE READ (S12, ADR 0025) — the
|
|
@@ -478,7 +478,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
478
478
|
|
|
479
479
|
sets :projected_fields, append: { name: :name, reference: :reference, remote_field: :remote_field }
|
|
480
480
|
|
|
481
|
-
emits
|
|
481
|
+
emits ProjectedFieldAttached
|
|
482
482
|
end
|
|
483
483
|
|
|
484
484
|
# HOW AGGREGATE IS SPELLED. These rows live with the concept
|
|
@@ -136,7 +136,7 @@ Hecks.bluebook "Bluebook", version: "1" do
|
|
|
136
136
|
sets :version
|
|
137
137
|
sets :formerly_known_as
|
|
138
138
|
|
|
139
|
-
emits
|
|
139
|
+
emits ChapterDeclared
|
|
140
140
|
end
|
|
141
141
|
|
|
142
142
|
# ONE CONTEXT THE CHAPTER ATTACHES TO, appended the way one identity
|
|
@@ -156,7 +156,7 @@ Hecks.bluebook "Bluebook", version: "1" do
|
|
|
156
156
|
# ledger entry was posted") { ledger.size == old.ledger.size + 1
|
|
157
157
|
# } — one more row than before, never fewer, never the same.
|
|
158
158
|
ensures("the list grew by exactly one") { attaches_to.size == old.attaches_to.size + 1 }
|
|
159
|
-
emits
|
|
159
|
+
emits ChapterAttached
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
# THE WAY BACK.
|
|
@@ -192,7 +192,7 @@ Hecks.bluebook "Bluebook", version: "1" do
|
|
|
192
192
|
replacement: :replacement, boundary: :boundary, position: :position
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
emits
|
|
195
|
+
emits NormalisationAttached
|
|
196
196
|
end
|
|
197
197
|
|
|
198
198
|
# HOW BLUEBOOK IS SPELLED. These rows live with the concept
|
|
@@ -161,7 +161,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
161
161
|
sets :provenance
|
|
162
162
|
sets :from
|
|
163
163
|
sets :position
|
|
164
|
-
emits
|
|
164
|
+
emits VerbDeclared
|
|
165
165
|
end
|
|
166
166
|
|
|
167
167
|
command "Argument" do
|
|
@@ -190,7 +190,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
190
190
|
|
|
191
191
|
sets :attributes, append: { name: :name, type: :type, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
192
192
|
|
|
193
|
-
emits
|
|
193
|
+
emits ArgumentAttached
|
|
194
194
|
end
|
|
195
195
|
|
|
196
196
|
# An argument that points at ANOTHER aggregate's head — the same word
|
|
@@ -223,7 +223,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
223
223
|
|
|
224
224
|
sets :attributes, append: { name: :name, type: :points_at, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
225
225
|
|
|
226
|
-
emits
|
|
226
|
+
emits ArgumentReferenceAttached
|
|
227
227
|
end
|
|
228
228
|
|
|
229
229
|
value_object "ArgName" do
|
|
@@ -248,7 +248,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
248
248
|
|
|
249
249
|
sets :givens, append: { description: :description, canonical: :canonical }
|
|
250
250
|
|
|
251
|
-
emits
|
|
251
|
+
emits RuleAttached
|
|
252
252
|
end
|
|
253
253
|
|
|
254
254
|
command "Ensure" do
|
|
@@ -263,7 +263,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
263
263
|
|
|
264
264
|
sets :ensures, append: { description: :description, canonical: :canonical }
|
|
265
265
|
|
|
266
|
-
emits
|
|
266
|
+
emits EnsureAttached
|
|
267
267
|
end
|
|
268
268
|
|
|
269
269
|
value_object "RuleText" do
|
|
@@ -289,7 +289,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
289
289
|
|
|
290
290
|
sets :mutations, append: { target: :target, op: :op, field: :field, kind: :kind, source: :source }
|
|
291
291
|
|
|
292
|
-
emits
|
|
292
|
+
emits ChangeAttached
|
|
293
293
|
end
|
|
294
294
|
|
|
295
295
|
value_object "FieldRef" do
|
|
@@ -319,7 +319,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
319
319
|
|
|
320
320
|
sets :references, to: :root
|
|
321
321
|
|
|
322
|
-
emits
|
|
322
|
+
emits ReferenceNamed
|
|
323
323
|
end
|
|
324
324
|
|
|
325
325
|
command "Announce" do
|
|
@@ -332,7 +332,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
332
332
|
|
|
333
333
|
sets :emits, append: { name: :announces }
|
|
334
334
|
|
|
335
|
-
emits
|
|
335
|
+
emits AnnouncementNamed
|
|
336
336
|
end
|
|
337
337
|
|
|
338
338
|
# HOW COMMAND IS SPELLED. These rows live with the concept
|
|
@@ -375,6 +375,19 @@ Hecks.bluebook "Bluebook" do
|
|
|
375
375
|
member word: "state", context: "Command", body: "none", inner: "", opens: "", fills: "mutations"
|
|
376
376
|
member word: "attribute", context: "Command", body: "none", inner: "", opens: "", fills: "attributes", calls: "attribute_impl"
|
|
377
377
|
member word: "ensures", context: "Command", body: "source", inner: "", opens: "", fills: "ensures"
|
|
378
|
+
# RETROACTIVE CORRECTION — a command that amends a specific past
|
|
379
|
+
# event rather than acting fresh (see this domain's own ADR on why:
|
|
380
|
+
# sagas only compensate their OWN anticipated failures, eras only
|
|
381
|
+
# reinterpret stored shape, and the event log stays append-only —
|
|
382
|
+
# so nothing existing lets a command say "this is amending a fact
|
|
383
|
+
# we already announced, and here is why"). STORED AS A MUTATION,
|
|
384
|
+
# not a new Command field — the same reasoning `delegates_to`'s own
|
|
385
|
+
# comment gives in full: `mutations:` is ALREADY a fully round-
|
|
386
|
+
# tripped part of the self-hosted meta-domain's own contract, and a
|
|
387
|
+
# genuinely new top-level Command field is not. `corrects` rides the
|
|
388
|
+
# SAME multi-binding wire shape `append`/`delegate` already use
|
|
389
|
+
# (CommandBuilder#corrects_impl's own comment has the rest).
|
|
390
|
+
member word: "corrects", context: "Command", body: "none", inner: "", opens: "", fills: "mutations", calls: "corrects_impl"
|
|
378
391
|
|
|
379
392
|
end
|
|
380
393
|
|
|
@@ -422,6 +435,15 @@ Hecks.bluebook "Bluebook" do
|
|
|
422
435
|
member keyword: "then_set", context: "Command", at: "", named: "remove", kind: "literal", required: "false", fills: "source", selects: "op=remove"
|
|
423
436
|
member keyword: "delegates_to", context: "Command", at: "1", named: "", kind: "text", required: "true", fills: "target"
|
|
424
437
|
member keyword: "delegates_to", context: "Command", at: "", named: "with", kind: "literal", required: "false", fills: "source", selects: "op=delegate"
|
|
438
|
+
# BARE CONSTANT ACCEPTED (ADR 0025, S6 — "events first-class"),
|
|
439
|
+
# `emits Account::AccountFrozen`, same `kind: "constant"` +
|
|
440
|
+
# `kind: "text"` pair `on`'s own row in `policy.bluebook` carries
|
|
441
|
+
# — both stay admitted, the old spelling not refused, for the
|
|
442
|
+
# same reason (event names aren't 100% corpus-migrated the way
|
|
443
|
+
# command references are). `CommandBuilder#emits` (hand-written,
|
|
444
|
+
# no `calls:` needed — the single-fill path already invokes it by
|
|
445
|
+
# its own word name) resolves either shape via `Naming.event_ref`.
|
|
446
|
+
member keyword: "emits", context: "Command", at: "1", named: "", kind: "constant", required: "true", fills: "emits"
|
|
425
447
|
member keyword: "emits", context: "Command", at: "1", named: "", kind: "text", required: "true", fills: "emits"
|
|
426
448
|
member keyword: "state", context: "Command", at: "1", named: "", kind: "symbol", required: "true", fills: "source"
|
|
427
449
|
member keyword: "attribute", context: "Command", at: "1", named: "", kind: "symbol", required: "true", fills: "name"
|
|
@@ -431,6 +453,18 @@ Hecks.bluebook "Bluebook" do
|
|
|
431
453
|
member keyword: "attribute", context: "Command", at: "", named: "pattern", kind: "text", required: "false", fills: "pattern"
|
|
432
454
|
member keyword: "attribute", context: "Command", at: "", named: "admits", kind: "text", required: "false", fills: "admits"
|
|
433
455
|
member keyword: "attribute", context: "Command", at: "", named: "one_of", kind: "list", required: "false", fills: "one_of"
|
|
456
|
+
# `corrects` — see the KeywordSeed row's own comment. `event` is the
|
|
457
|
+
# only positional and the only required-by-the-grammar argument;
|
|
458
|
+
# `reason` is required IN PRACTICE (CommandBuilder#corrects_impl
|
|
459
|
+
# refuses its absence by hand, the same way `sets` refuses two ops
|
|
460
|
+
# at once — a fact about runtime state, not a pure per-row fill, so
|
|
461
|
+
# it stays hand-enforced rather than declared `required: "true"`
|
|
462
|
+
# here, which would only gate the row's OWN presence, not a sibling
|
|
463
|
+
# kwarg's).
|
|
464
|
+
member keyword: "corrects", context: "Command", at: "1", named: "", kind: "text", required: "true", fills: "target"
|
|
465
|
+
member keyword: "corrects", context: "Command", at: "", named: "as", kind: "symbol", required: "false", fills: "source"
|
|
466
|
+
member keyword: "corrects", context: "Command", at: "", named: "reason", kind: "text", required: "false", fills: "source"
|
|
467
|
+
member keyword: "corrects", context: "Command", at: "", named: "reverses", kind: "flag", required: "false", fills: "source"
|
|
434
468
|
|
|
435
469
|
end
|
|
436
470
|
end
|
|
@@ -107,7 +107,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
107
107
|
sets :name
|
|
108
108
|
sets :description
|
|
109
109
|
sets :position
|
|
110
|
-
emits
|
|
110
|
+
emits PieceDeclared
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
# ONE PART OF THE PIECE'S IDENTITY, attached exactly as an aggregate's is.
|
|
@@ -134,7 +134,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
134
134
|
given("an identity part names something") { !path.value.to_s.empty? }
|
|
135
135
|
|
|
136
136
|
sets :identified_by, append: { value: :path }
|
|
137
|
-
emits
|
|
137
|
+
emits PieceIdentified
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
command "Seal" do
|
|
@@ -146,15 +146,23 @@ Hecks.bluebook "Bluebook" do
|
|
|
146
146
|
|
|
147
147
|
given("an entity says what it is known by") { !identified_by.empty? }
|
|
148
148
|
|
|
149
|
-
emits
|
|
149
|
+
emits PieceSealed
|
|
150
150
|
end
|
|
151
151
|
|
|
152
152
|
command "Attribute" do
|
|
153
153
|
role "Language"
|
|
154
154
|
goal "Attach one attribute to the entity"
|
|
155
155
|
|
|
156
|
+
# THE TYPE IS A REFERENCE TO THE VALUE OBJECT IT NAMES — the same rule
|
|
157
|
+
# Aggregate.Attribute enforces one construct over (see that command's own
|
|
158
|
+
# comment). An entity declares no value objects of its own (Entity never
|
|
159
|
+
# answers `value_object` — entity.rb's own comment says why); its
|
|
160
|
+
# attributes read the SAME pool its enclosing aggregate declares, so this
|
|
161
|
+
# still resolves as a reference, not free text. An entity attribute naming
|
|
162
|
+
# an undeclared value object failed to fail: `type` rode as plain text, so
|
|
163
|
+
# reference resolution never ran and a typo'd or invented type boots clean.
|
|
164
|
+
reference_to ValueObject, as: :type
|
|
156
165
|
attribute :name, EntityText
|
|
157
|
-
attribute :type, EntityText
|
|
158
166
|
attribute :list, EntityText
|
|
159
167
|
attribute :optional, EntityText, optional: true
|
|
160
168
|
attribute :pattern, EntityText, optional: true
|
|
@@ -164,7 +172,66 @@ Hecks.bluebook "Bluebook" do
|
|
|
164
172
|
|
|
165
173
|
sets :attributes, append: { name: :name, type: :type, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
166
174
|
|
|
167
|
-
emits
|
|
175
|
+
emits PieceAttributeAttached
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# An attribute that points at ANOTHER AGGREGATE'S HEAD — the SAME
|
|
179
|
+
# construct Aggregate.Reference is, one level down (see that
|
|
180
|
+
# command's own comment for why the type cannot be text): `belongs_to`/
|
|
181
|
+
# `has_one`/`has_many`/`reference_to` are declared on an entity by the
|
|
182
|
+
# same DSL (`EntityBuilder`/`AttributeCollector`) an aggregate uses,
|
|
183
|
+
# and a real fixture already exercises it (`spec/relationship_
|
|
184
|
+
# declaration_spec.rb`'s "uses the same relationship declarations on
|
|
185
|
+
# an entity", `docs/reference/entity.md`). Without this verb such an
|
|
186
|
+
# attribute fell to the SAME `Attribute` verb above, which reads
|
|
187
|
+
# `type` as a value-object reference — so a cross-aggregate reference
|
|
188
|
+
# declared on a piece failed reference resolution against the wrong
|
|
189
|
+
# pool the moment entity attributes started being checked at all.
|
|
190
|
+
command "Reference" do
|
|
191
|
+
role "Language"
|
|
192
|
+
goal "Attach an attribute that points at another aggregate's head"
|
|
193
|
+
|
|
194
|
+
reference_to Aggregate, as: :points_at
|
|
195
|
+
attribute :name, EntityText
|
|
196
|
+
attribute :list, EntityText
|
|
197
|
+
attribute :optional, EntityText, optional: true
|
|
198
|
+
attribute :pattern, EntityText, optional: true
|
|
199
|
+
attribute :default, EntityText, optional: true
|
|
200
|
+
attribute :admits, EntityText, optional: true
|
|
201
|
+
attribute :relationship, EntityText, optional: true
|
|
202
|
+
|
|
203
|
+
sets :attributes, append: { name: :name, type: :points_at, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
204
|
+
|
|
205
|
+
emits PieceReferenceAttached
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# An attribute whose type names a PIECE NESTED INSIDE THIS ONE — the
|
|
209
|
+
# SAME construct Aggregate.Holds is, one level down (see that
|
|
210
|
+
# command's own comment): `attribute :dispatches, list_of(Dispatch)`
|
|
211
|
+
# inside `entity "Handler"` (S17, ADR 0026's own two-level chain) is
|
|
212
|
+
# exactly `Account#ledger` one level further in. Without this verb
|
|
213
|
+
# such an attribute fell to the SAME `Attribute` verb above, which
|
|
214
|
+
# reads `type` as a value-object reference — so a piece nested inside
|
|
215
|
+
# a piece failed reference resolution against the wrong pool the
|
|
216
|
+
# moment entity attributes started being checked at all (found live:
|
|
217
|
+
# the meta-grammar's own `Handler.dispatches` naming `Dispatch`,
|
|
218
|
+
# nested inside Handler itself).
|
|
219
|
+
command "Holds" do
|
|
220
|
+
role "Language"
|
|
221
|
+
goal "Attach an attribute whose type is a piece nested inside this one"
|
|
222
|
+
|
|
223
|
+
reference_to Entity, as: :holds
|
|
224
|
+
attribute :name, EntityText
|
|
225
|
+
attribute :list, EntityText
|
|
226
|
+
attribute :optional, EntityText, optional: true
|
|
227
|
+
attribute :pattern, EntityText, optional: true
|
|
228
|
+
attribute :default, EntityText, optional: true
|
|
229
|
+
attribute :admits, EntityText, optional: true
|
|
230
|
+
attribute :relationship, EntityText, optional: true
|
|
231
|
+
|
|
232
|
+
sets :attributes, append: { name: :name, type: :holds, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
233
|
+
|
|
234
|
+
emits PieceHeld
|
|
168
235
|
end
|
|
169
236
|
|
|
170
237
|
|
|
@@ -184,7 +251,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
184
251
|
|
|
185
252
|
sets :preconditions, append: { description: :description, canonical: :canonical }
|
|
186
253
|
|
|
187
|
-
emits
|
|
254
|
+
emits PiecePreconditionAttached
|
|
188
255
|
end
|
|
189
256
|
|
|
190
257
|
# A PIECE'S OWN SHAPE RULE, DECLARED ONCE (round 7) — see
|
|
@@ -203,7 +270,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
203
270
|
|
|
204
271
|
sets :invariants, append: { description: :description, canonical: :canonical }
|
|
205
272
|
|
|
206
|
-
emits
|
|
273
|
+
emits PieceInvariantAttached
|
|
207
274
|
end
|
|
208
275
|
|
|
209
276
|
command "Lifecycle" do
|
|
@@ -214,7 +281,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
214
281
|
sets :state_field
|
|
215
282
|
sets :state_start
|
|
216
283
|
|
|
217
|
-
emits
|
|
284
|
+
emits PieceLifecycleNamed
|
|
218
285
|
end
|
|
219
286
|
|
|
220
287
|
command "Transition" do
|
|
@@ -227,7 +294,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
227
294
|
|
|
228
295
|
sets :transitions, append: { command: :command, from_state: :from_state, to_state: :to_state }
|
|
229
296
|
|
|
230
|
-
emits
|
|
297
|
+
emits PieceTransitionAttached
|
|
231
298
|
end
|
|
232
299
|
|
|
233
300
|
# HOW ENTITY IS SPELLED. These rows live with the concept
|
|
@@ -248,7 +315,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
248
315
|
member word: "description", context: "Entity", body: "none", inner: "", opens: "", fills: "description"
|
|
249
316
|
member word: "identified_by", context: "Entity", body: "keywords", inner: "ValueObject", opens: "ValueObject", fills: "identified_by", calls: "identified_by_impl"
|
|
250
317
|
member word: "identified_by", context: "Entity", body: "none", inner: "", opens: "", fills: "identified_by", calls: "identified_by_impl"
|
|
251
|
-
member word: "given", context: "Entity", body: "source", inner: "", opens: "", fills: "preconditions", calls: "given_impl"
|
|
318
|
+
member word: "given", context: "Entity", body: "source", inner: "", opens: "", fills: "preconditions", resolves_via: "owner_keyed", disambiguator: "declared_by", calls: "given_impl"
|
|
252
319
|
member word: "invariant", context: "Entity", body: "source", inner: "", opens: "", fills: "invariants", calls: "invariant_impl"
|
|
253
320
|
member word: "command", context: "Entity", body: "keywords", inner: "Command", opens: "Command", fills: "", calls: "command_impl"
|
|
254
321
|
member word: "query", context: "Entity", body: "keywords", inner: "Query", opens: "Query", fills: "", calls: "query_impl"
|
|
@@ -282,6 +349,15 @@ Hecks.bluebook "Bluebook" do
|
|
|
282
349
|
|
|
283
350
|
member keyword: "description", context: "Entity", at: "1", named: "", kind: "text", required: "true", fills: "description", coerce: "false"
|
|
284
351
|
member keyword: "given", context: "Entity", at: "1", named: "", kind: "text", required: "true", fills: "description"
|
|
352
|
+
# PLAIN TEXT, not `kind: "constant"` — unlike `Aggregate`'s own
|
|
353
|
+
# `declared_by:` (which names a real aggregate constant), a piece
|
|
354
|
+
# has no first-class, independently-addressable reference anywhere
|
|
355
|
+
# in this language. "AggregateName.EntityName" ships as a string,
|
|
356
|
+
# the same way `admits:` shipped textual before its own
|
|
357
|
+
# constant-bridge existed — see `EntityBuilder#given_impl`'s own
|
|
358
|
+
# comment for why this is a deliberate, not temporary-by-oversight,
|
|
359
|
+
# divergence.
|
|
360
|
+
member keyword: "given", context: "Entity", at: "", named: "declared_by", kind: "text", required: "false", fills: "declared_by"
|
|
285
361
|
member keyword: "invariant", context: "Entity", at: "1", named: "", kind: "text", required: "true", fills: "description"
|
|
286
362
|
member keyword: "identified_by", context: "Entity", at: "1", named: "", kind: "symbol", required: "false", fills: "identified_by", variadic: "true", minimum: "2"
|
|
287
363
|
member keyword: "identified_by", context: "Entity", at: "1", named: "", kind: "constant", required: "false", fills: "type"
|
|
@@ -105,7 +105,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
105
105
|
sets :where
|
|
106
106
|
sets :for_each
|
|
107
107
|
sets :position
|
|
108
|
-
emits
|
|
108
|
+
emits ReactionDeclared
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
command "Bind" do
|
|
@@ -117,12 +117,28 @@ Hecks.bluebook "Bluebook" do
|
|
|
117
117
|
|
|
118
118
|
sets :with_spec, append: { key: :key, value: :value }
|
|
119
119
|
|
|
120
|
-
emits
|
|
120
|
+
emits TriggerBindingAttached
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
# HOW POLICY IS SPELLED. These rows live with the concept
|
|
124
124
|
# they describe; SyntaxBoot discovers every aggregate-local seed table.
|
|
125
125
|
# Contexts represented here: Policy.
|
|
126
|
+
#
|
|
127
|
+
# `on`'s ArgumentSeed gained a `kind: "constant"` row alongside its
|
|
128
|
+
# existing `kind: "text"` one (ADR 0025, S6 — "events first-class"),
|
|
129
|
+
# same shape `trigger`'s own pair already carries — `on
|
|
130
|
+
# Account::AccountFrozen`, a bare constant, now parses the same way
|
|
131
|
+
# `trigger Account::Debit` does. `calls: "on_impl"` routes the word
|
|
132
|
+
# through a hand-written method (`PolicyBuilder#on_impl`) instead of
|
|
133
|
+
# the generic single-fill coercion, mirroring `trigger`'s own
|
|
134
|
+
# `calls: "trigger_impl"` on the row below. UNLIKE `trigger`,
|
|
135
|
+
# `on_impl` does NOT refuse the quoted-text form outside
|
|
136
|
+
# `shadow_parse` — command references were safe to refuse that way
|
|
137
|
+
# only because they're 100% migrated across the live corpus; event
|
|
138
|
+
# names (`emits`/`on`) are not (only Account's `AccountFrozen` is,
|
|
139
|
+
# this pass), so refusing the old spelling here would break every
|
|
140
|
+
# live `.bluebook` site this pass didn't touch. Both forms stay
|
|
141
|
+
# admitted until a full corpus migration lands.
|
|
126
142
|
value_object "KeywordSeed" do
|
|
127
143
|
attribute :word, String
|
|
128
144
|
attribute :context, String, admits: "Syntax::Context"
|
|
@@ -135,7 +151,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
135
151
|
attribute :resolves_via, String, default: "", admits: "Syntax::ResolutionScope"
|
|
136
152
|
attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
|
|
137
153
|
|
|
138
|
-
member word: "on", context: "Policy", body: "none", inner: "", opens: "", fills: "on_event"
|
|
154
|
+
member word: "on", context: "Policy", body: "none", inner: "", opens: "", fills: "on_event", calls: "on_impl"
|
|
139
155
|
member word: "trigger", context: "Policy", body: "none", inner: "", opens: "", fills: "trigger_command", calls: "trigger_impl"
|
|
140
156
|
member word: "across", context: "Policy", body: "none", inner: "", opens: "", fills: "target_domain"
|
|
141
157
|
member word: "where", context: "Policy", body: "source", inner: "", opens: "", fills: "where"
|
|
@@ -160,7 +176,8 @@ Hecks.bluebook "Bluebook" do
|
|
|
160
176
|
attribute :coerce, String
|
|
161
177
|
attribute :blank_message, String
|
|
162
178
|
|
|
163
|
-
member keyword: "on", context: "Policy", at: "1", named: "", kind: "
|
|
179
|
+
member keyword: "on", context: "Policy", at: "1", named: "", kind: "constant", required: "true", fills: "on_event"
|
|
180
|
+
member keyword: "on", context: "Policy", at: "1", named: "", kind: "text", required: "true", fills: "on_event"
|
|
164
181
|
member keyword: "trigger", context: "Policy", at: "1", named: "", kind: "constant", required: "true", fills: "trigger_command"
|
|
165
182
|
member keyword: "trigger", context: "Policy", at: "1", named: "", kind: "text", required: "true", fills: "trigger_command"
|
|
166
183
|
member keyword: "across", context: "Policy", at: "1", named: "", kind: "text", required: "true", fills: "target_domain"
|