hecks 1.4.0 → 1.5.0
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/claude_code.rb +65 -0
- data/lib/hecks/adapters/driven/folder.rb +73 -0
- data/lib/hecks/adapters/driven/google_authentication.rb +25 -4
- data/lib/hecks/adapters/driven/governance_authorization.rb +57 -6
- data/lib/hecks/adapters/driven/heki/journal.rb +8 -0
- data/lib/hecks/adapters/driven/heki/saga_store.rb +53 -7
- data/lib/hecks/adapters/driven/heki/snapshot.rb +1 -1
- data/lib/hecks/adapters/driven/heki.rb +93 -2
- data/lib/hecks/adapters/driven/identity_registry.rb +10 -0
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +22 -0
- data/lib/hecks/adapters/driven/in_process_key_vault.adapter +3 -0
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +53 -0
- data/lib/hecks/adapters/driven/lambda/client.rb +35 -7
- data/lib/hecks/adapters/driven/lambda.rb +43 -2
- data/lib/hecks/adapters/driven/local_storage.rb +67 -1
- data/lib/hecks/adapters/driven/memory.rb +13 -13
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +20 -0
- data/lib/hecks/adapters/driven/prism.rb +46 -7
- data/lib/hecks/adapters/driven/secure_random_identity.rb +3 -0
- data/lib/hecks/adapters/driven/system_clock.rb +3 -0
- data/lib/hecks/adapters/driven/tenant_provisioner.adapter +3 -0
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +66 -0
- data/lib/hecks/adapters/driven.rb +2 -0
- data/lib/hecks/adapters/driving/github_webhook.rb +14 -1
- data/lib/hecks/behaviors/dsl.rb +58 -0
- data/lib/hecks/behaviors/expectations.rb +168 -7
- data/lib/hecks/behaviors/ir.rb +11 -0
- data/lib/hecks/behaviors/rspec.rb +8 -0
- data/lib/hecks/behaviors/runner.rb +19 -0
- data/lib/hecks/behaviors.rb +8 -0
- data/lib/hecks/bluebook/aggregate.rb +30 -0
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +7 -0
- data/lib/hecks/bluebook/assembly/build.rb +25 -4
- data/lib/hecks/bluebook/assembly/contract.rb +66 -14
- data/lib/hecks/bluebook/assembly/contracts.rb +24 -19
- data/lib/hecks/bluebook/assembly/marks.rb +143 -14
- data/lib/hecks/bluebook/assembly/specializer.rb +19 -0
- data/lib/hecks/bluebook/assembly.rb +25 -7
- data/lib/hecks/bluebook/attribute.rb +17 -3
- data/lib/hecks/bluebook/behaviour/aggregate.rb +32 -0
- data/lib/hecks/bluebook/behaviour/attribute.rb +13 -0
- data/lib/hecks/bluebook/behaviour/chapter.rb +55 -2
- data/lib/hecks/bluebook/behaviour/command.rb +33 -3
- data/lib/hecks/bluebook/behaviour/domain_port.rb +20 -0
- data/lib/hecks/bluebook/behaviour/entity.rb +12 -0
- data/lib/hecks/bluebook/behaviour/hexagon.rb +26 -0
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +23 -2
- data/lib/hecks/bluebook/behaviour/policy.rb +34 -9
- data/lib/hecks/bluebook/behaviour/process_manager.rb +32 -1
- data/lib/hecks/bluebook/behaviour/query.rb +5 -0
- data/lib/hecks/bluebook/behaviour/read_model.rb +21 -0
- data/lib/hecks/bluebook/behaviour/traits.rb +36 -0
- data/lib/hecks/bluebook/behaviour/value_object.rb +17 -5
- data/lib/hecks/bluebook/chapter.rb +23 -0
- data/lib/hecks/bluebook/command.rb +53 -8
- data/lib/hecks/bluebook/domain_port.rb +25 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +196 -37
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +79 -42
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +59 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +385 -53
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +135 -21
- data/lib/hecks/bluebook/dsl/command_builder.rb +189 -27
- data/lib/hecks/bluebook/dsl/entity_builder.rb +139 -9
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +41 -0
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +23 -6
- data/lib/hecks/bluebook/dsl/policy_builder.rb +60 -19
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +79 -15
- data/lib/hecks/bluebook/dsl/query_builder.rb +33 -4
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +102 -27
- data/lib/hecks/bluebook/dsl/rule_reference.rb +60 -8
- data/lib/hecks/bluebook/dsl/translation_builder.rb +146 -40
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +55 -7
- data/lib/hecks/bluebook/entity.rb +29 -0
- data/lib/hecks/bluebook/expression/ast_json.rb +115 -23
- data/lib/hecks/bluebook/expression/ast_reader.rb +29 -0
- data/lib/hecks/bluebook/expression/canonical_form.rb +48 -9
- data/lib/hecks/bluebook/expression/evaluator.rb +207 -29
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +36 -0
- data/lib/hecks/bluebook/expression/resolver.rb +320 -77
- data/lib/hecks/bluebook/hexagon.rb +34 -0
- data/lib/hecks/bluebook/lifecycle.rb +11 -0
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -0
- data/lib/hecks/bluebook/meta_validator/judge.rb +30 -26
- data/lib/hecks/bluebook/meta_validator/plan.rb +43 -8
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +1 -0
- data/lib/hecks/bluebook/meta_validator/readings.rb +157 -7
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +24 -4
- data/lib/hecks/bluebook/meta_validator/shapes.rb +141 -0
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +149 -23
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +5 -4
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +1 -0
- data/lib/hecks/bluebook/meta_validator.rb +180 -84
- data/lib/hecks/bluebook/model_check.rb +268 -24
- data/lib/hecks/bluebook/pattern_subset.rb +23 -1
- data/lib/hecks/bluebook/process_manager.rb +13 -0
- data/lib/hecks/bluebook/project_discovery.rb +5 -0
- data/lib/hecks/bluebook/project_loader.rb +40 -0
- data/lib/hecks/bluebook/project_register.rb +44 -0
- data/lib/hecks/bluebook/query.rb +27 -0
- data/lib/hecks/bluebook/read_model.rb +21 -1
- data/lib/hecks/bluebook/reference.rb +21 -8
- data/lib/hecks/bluebook/smoke_test.rb +29 -6
- data/lib/hecks/bluebook/synthesizer.rb +34 -0
- data/lib/hecks/bluebook/translation.rb +30 -1
- data/lib/hecks/bluebook/value_object.rb +23 -5
- data/lib/hecks/bluebook.rb +3 -4
- data/lib/hecks/codemod.rb +107 -20
- data/lib/hecks/construct.rb +15 -1
- data/lib/hecks/corpus.rb +146 -25
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +19 -0
- data/lib/hecks/doc/reference.rb +185 -16
- data/lib/hecks/embryonaut_bluebook.rb +32 -9
- data/lib/hecks/facade/handle.rb +76 -3
- data/lib/hecks/facade/surface/aggregate_door.rb +8 -0
- data/lib/hecks/forms/field_shape.rb +3 -0
- data/lib/hecks/forms/page.rb +14 -0
- data/lib/hecks/forms/port_argument.rb +12 -0
- data/lib/hecks/forms/query_form_renderer.rb +63 -0
- data/lib/hecks/forms/record_renderer.rb +58 -0
- data/lib/hecks/forms/record_table.rb +27 -0
- data/lib/hecks/forms/reference_options.rb +24 -0
- data/lib/hecks/forms/value_object_shape.rb +10 -0
- data/lib/hecks/fqn.rb +58 -0
- data/lib/hecks/framework/bluebook/privacy.bluebook +155 -0
- data/lib/hecks/framework/oidc.json +15 -0
- data/lib/hecks/framework.rb +43 -20
- data/lib/hecks/freezer.rb +17 -1
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +159 -24
- data/lib/hecks/fuzzing/combination_miner.rb +59 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +109 -8
- data/lib/hecks/fuzzing/coverage_campaign.rb +56 -13
- data/lib/hecks/fuzzing/differential.rb +34 -0
- data/lib/hecks/fuzzing/domain_generator.rb +188 -11
- data/lib/hecks/fuzzing/era_boundary.rb +45 -15
- data/lib/hecks/fuzzing/form_census.rb +86 -0
- data/lib/hecks/fuzzing/generated_domain_check.rb +76 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +39 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +79 -22
- data/lib/hecks/fuzzing/nondeterministic.rb +13 -1
- data/lib/hecks/fuzzing/persistence_parity.rb +95 -3
- data/lib/hecks/fuzzing/properties/corrections.rb +25 -0
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +158 -14
- data/lib/hecks/fuzzing/properties/guards.rb +44 -0
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +48 -0
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +18 -0
- data/lib/hecks/fuzzing/properties/outbox.rb +49 -11
- data/lib/hecks/fuzzing/properties/querying.rb +68 -14
- data/lib/hecks/fuzzing/properties.rb +24 -15
- data/lib/hecks/fuzzing/qa_settings.rb +12 -0
- data/lib/hecks/fuzzing/replay.rb +137 -29
- data/lib/hecks/fuzzing/rotation_priority.rb +41 -21
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +46 -20
- data/lib/hecks/fuzzing/self_consistency.rb +189 -40
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +12 -6
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +1 -1
- data/lib/hecks/fuzzing/sequence_generator.rb +47 -0
- data/lib/hecks/fuzzing/shrinker.rb +114 -2
- data/lib/hecks/fuzzing/structural_skips.rb +18 -4
- data/lib/hecks/fuzzing/sweep_depth.rb +8 -0
- data/lib/hecks/fuzzing/target_capabilities.rb +61 -14
- data/lib/hecks/fuzzing/value_generator.rb +98 -10
- data/lib/hecks/grammar/evolve.rb +178 -2
- data/lib/hecks/grammar.rb +46 -0
- data/lib/hecks/ir.rb +38 -7
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +11 -0
- data/lib/hecks/literal.rb +32 -0
- data/lib/hecks/naming.rb +88 -7
- data/lib/hecks/ports/access_control.rb +5 -10
- data/lib/hecks/ports/authorization.rb +3 -6
- data/lib/hecks/ports/identity_assignment.rb +1 -2
- data/lib/hecks/ports/identity_resolution.rb +1 -2
- data/lib/hecks/ports/key_vault.port +6 -0
- data/lib/hecks/ports/key_vault.rb +58 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +6 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +38 -2
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +6 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +40 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +92 -1
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +15 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +8 -0
- data/lib/hecks/ports/query/in_memory.rb +39 -6
- data/lib/hecks/ports/query/ordering.rb +15 -0
- data/lib/hecks/ports.rb +1 -0
- data/lib/hecks/projections/bootstrap_table.rb +43 -8
- data/lib/hecks/projections/diagrams.rb +243 -7
- data/lib/hecks/projections/glossary/html.rb +88 -0
- data/lib/hecks/projections/glossary/markdown.rb +47 -0
- data/lib/hecks/projections/glossary/mermaid.rb +48 -0
- data/lib/hecks/projections/glossary/sentences.rb +105 -0
- data/lib/hecks/projections/glossary.rb +161 -19
- data/lib/hecks/projections/model/deviations.rb +44 -0
- data/lib/hecks/projections/model.rb +51 -1
- data/lib/hecks/projections/oidc.rb +40 -3
- data/lib/hecks/projections/parser_table.rb +49 -8
- data/lib/hecks/projections/reference.rb +12 -0
- data/lib/hecks/projections/rust_vocabulary.rb +219 -16
- data/lib/hecks/projections/shape.rb +8 -0
- data/lib/hecks/projections/statements.rb +63 -16
- data/lib/hecks/projections/vocabulary.rb +17 -0
- data/lib/hecks/projector/cli_projector.rb +218 -10
- data/lib/hecks/projector/docs_projector.rb +145 -19
- data/lib/hecks/projector/exporter.rb +65 -11
- data/lib/hecks/projector/ir_projector.rb +6 -0
- data/lib/hecks/projector/narrate_projector.rb +136 -15
- data/lib/hecks/projector/target.rb +29 -5
- data/lib/hecks/projector.rb +74 -6
- data/lib/hecks/query_ir.rb +47 -0
- data/lib/hecks/query_specification/common/null_policy.rb +5 -3
- data/lib/hecks/rendering.rb +6 -0
- data/lib/hecks/router/namespace_installer.rb +13 -0
- data/lib/hecks/router.rb +55 -0
- data/lib/hecks/runtime/aggregate_lock.rb +9 -0
- data/lib/hecks/runtime/boot_gates.rb +18 -0
- data/lib/hecks/runtime/caller.rb +32 -0
- data/lib/hecks/runtime/capability_graph.rb +11 -0
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +23 -21
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +14 -15
- data/lib/hecks/runtime/command_interpreter.rb +42 -17
- data/lib/hecks/runtime/command_rules/admissibility.rb +165 -14
- data/lib/hecks/runtime/command_rules/arithmetic.rb +17 -5
- data/lib/hecks/runtime/command_rules/references.rb +118 -28
- data/lib/hecks/runtime/dependency_planning.rb +45 -0
- data/lib/hecks/runtime/dispatcher.rb +28 -50
- data/lib/hecks/runtime/entity_element.rb +161 -8
- data/lib/hecks/runtime/entity_interpreter.rb +44 -9
- data/lib/hecks/runtime/errors.rb +18 -4
- data/lib/hecks/runtime/event.rb +10 -5
- data/lib/hecks/runtime/identity.rb +71 -3
- data/lib/hecks/runtime/instance.rb +67 -7
- data/lib/hecks/runtime/interpreting.rb +13 -5
- data/lib/hecks/runtime/invocation.rb +118 -36
- data/lib/hecks/runtime/loader.rb +94 -8
- data/lib/hecks/runtime/outbox.rb +145 -7
- data/lib/hecks/runtime/policy_interpreter.rb +22 -9
- data/lib/hecks/runtime/port_operation_interpreter.rb +20 -0
- data/lib/hecks/runtime/query_interpreter.rb +40 -12
- data/lib/hecks/runtime/reaction_invocation.rb +53 -8
- data/lib/hecks/runtime/read_model_interpreter.rb +23 -7
- data/lib/hecks/runtime/rebuild_sweep.rb +28 -0
- data/lib/hecks/runtime/reference_hop.rb +42 -0
- data/lib/hecks/runtime/refusal_wording.rb +50 -0
- data/lib/hecks/runtime/registry/saga_persistence.rb +11 -0
- data/lib/hecks/runtime/registry/verification.rb +119 -4
- data/lib/hecks/runtime/registry.rb +157 -4
- data/lib/hecks/runtime/remote_dispatcher.rb +92 -6
- data/lib/hecks/runtime/routing.rb +27 -2
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +10 -12
- data/lib/hecks/runtime/saga_interpreter.rb +27 -13
- data/lib/hecks/runtime/tenant_check.rb +26 -6
- data/lib/hecks/runtime/tenant_scope.rb +18 -0
- data/lib/hecks/runtime/value/coercion.rb +255 -33
- data/lib/hecks/runtime/value/entity_list_coercion.rb +102 -30
- data/lib/hecks/runtime/value.rb +50 -0
- data/lib/hecks/runtime.rb +32 -0
- data/lib/hecks/storehouse.rb +305 -9
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +130 -0
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +32 -0
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks.rb +79 -1
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -0
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +12 -2
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +29 -5
- metadata +11 -5
- data/lib/hecks/codemod/legacy_dispatch_args.rb +0 -299
- data/lib/hecks/codemod/legacy_dispatch_recorder.rb +0 -186
- data/lib/hecks/deprecation.rb +0 -95
|
@@ -19,6 +19,8 @@ module Hecks
|
|
|
19
19
|
|
|
20
20
|
attr_reader :classification
|
|
21
21
|
|
|
22
|
+
# @param name [String] the chapter's declared name
|
|
23
|
+
# @param version [String, nil] the chapter's pinned version, or nil for unversioned
|
|
22
24
|
def initialize(name, version: nil)
|
|
23
25
|
@name = name
|
|
24
26
|
@version = version
|
|
@@ -62,17 +64,26 @@ module Hecks
|
|
|
62
64
|
end
|
|
63
65
|
private :adopt_version
|
|
64
66
|
|
|
67
|
+
# Records the chapter's vision statement.
|
|
68
|
+
#
|
|
69
|
+
# @param value [String] the vision text, as given to `vision "..."`
|
|
70
|
+
# @return [void]
|
|
65
71
|
def vision(value)
|
|
66
72
|
# moved to the language: Vision invariant, on Chapter.Declare
|
|
67
73
|
|
|
68
74
|
@vision = value
|
|
69
75
|
end
|
|
70
76
|
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
77
|
+
# Records the chapter's earlier name, so the storage layer recognizes its own history
|
|
78
|
+
# under that old name instead of minting a brand-new lineage from nothing — a chapter's
|
|
79
|
+
# identity can change, and this is where the new declaration says what it was.
|
|
80
|
+
#
|
|
81
|
+
# @param value [String, Symbol] the chapter's earlier name
|
|
82
|
+
# @return [String] `value`, stringified, as stored
|
|
74
83
|
def formerly_known_as(value) = @formerly_known_as = value.to_s
|
|
75
84
|
|
|
85
|
+
# Names a core grammar context this chapter's sub-language extends.
|
|
86
|
+
#
|
|
76
87
|
# **A sub-language names where it lands**. ADR 0026's own seam: the core
|
|
77
88
|
# grammar does not name its extension points, so this chapter names
|
|
78
89
|
# itself onto them instead — the core contexts (e.g. "Query",
|
|
@@ -80,12 +91,18 @@ module Hecks
|
|
|
80
91
|
# aggregate contributes rows for. Variadic, and accumulating across
|
|
81
92
|
# calls the same reason `identified_by`/`group_by` are: nothing here
|
|
82
93
|
# requires one call to name every context at once.
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
# chapters like Paging use it
|
|
86
|
-
#
|
|
94
|
+
#
|
|
95
|
+
# Reached through `calls: "attaches_to_impl"` rather than `GenericDispatch`'s default —
|
|
96
|
+
# not bootstrap-reachable, since only sub-language chapters like Paging use it, never a
|
|
97
|
+
# core chapter.
|
|
98
|
+
#
|
|
99
|
+
# @param contexts [Array<String>] one or more core grammar context names, such as
|
|
100
|
+
# `"Query"`/`"ReadModel"`
|
|
101
|
+
# @return [Array<String>] every context named so far, this call's included
|
|
87
102
|
def attaches_to_impl(*contexts) = (@attaches_to ||= []).concat(contexts.map(&:to_s))
|
|
88
103
|
|
|
104
|
+
# Records a capability this chapter answers for other domains.
|
|
105
|
+
#
|
|
89
106
|
# A capability this chapter answers for other domains, declared so
|
|
90
107
|
# nothing has to recognise the chapter by name — Governance's
|
|
91
108
|
# `provides "authorization", assignments: ..., grant: ...,
|
|
@@ -93,6 +110,13 @@ module Hecks
|
|
|
93
110
|
# each capability requires is checked once the chapter is whole
|
|
94
111
|
# (`Validation#validate_provisions!`), since the verbs it names may
|
|
95
112
|
# be declared further down the file.
|
|
113
|
+
#
|
|
114
|
+
# @param capability [String] the capability's own name, such as `"authorization"`
|
|
115
|
+
# @param verbs [Hash{Symbol => String}] one command/query reference per capability
|
|
116
|
+
# key, e.g. `grant: "RoleAssignment.Assign"`
|
|
117
|
+
# @return [Array<Bluebook::Chapter::Provision>] every provision row declared so far,
|
|
118
|
+
# this capability's included
|
|
119
|
+
# @raise [Bluebook::DSL::Malformed] if `verbs` is empty
|
|
96
120
|
def provides_impl(capability, **verbs)
|
|
97
121
|
if verbs.empty?
|
|
98
122
|
raise Malformed, "#{@name}'s provides #{capability.inspect} names no verb — say which of this " \
|
|
@@ -103,10 +127,24 @@ module Hecks
|
|
|
103
127
|
(@provides ||= []).concat(rows)
|
|
104
128
|
end
|
|
105
129
|
|
|
130
|
+
# Classifies this chapter as core to the framework, rather than a domain built on it.
|
|
131
|
+
#
|
|
132
|
+
# @return [Symbol] `:core`
|
|
106
133
|
def core = @classification = :core
|
|
134
|
+
|
|
135
|
+
# Classifies this chapter as a supporting piece of the framework, rather than a domain
|
|
136
|
+
# built on it.
|
|
137
|
+
#
|
|
138
|
+
# @return [Symbol] `:supporting`
|
|
107
139
|
def supporting = @classification = :supporting
|
|
140
|
+
|
|
141
|
+
# Classifies this chapter as generic infrastructure, rather than a domain built on it.
|
|
142
|
+
#
|
|
143
|
+
# @return [Symbol] `:generic`
|
|
108
144
|
def generic = @classification = :generic
|
|
109
145
|
|
|
146
|
+
# Declares an aggregate belonging to this chapter.
|
|
147
|
+
#
|
|
110
148
|
# `@chapter_named_givens` is threaded into every aggregate this
|
|
111
149
|
# chapter builds — see `AggregateBuilder#given`'s own comment
|
|
112
150
|
# for the sharing this enables; not a new top-level DSL word
|
|
@@ -115,10 +153,16 @@ module Hecks
|
|
|
115
153
|
# the identical shape `EntityBuilder#given`'s own write-through
|
|
116
154
|
# to its owner aggregate's pool already takes — no new spelling
|
|
117
155
|
# for "declare a precondition," one level wider, same word).
|
|
118
|
-
#
|
|
119
|
-
#
|
|
120
|
-
# chapter's own top-level shape is written
|
|
121
|
-
# named in GenericDispatch::BOOTSTRAP_CALLS_FALLBACK
|
|
156
|
+
#
|
|
157
|
+
# Reached through `calls: "aggregate_impl"`, not `GenericDispatch`'s default —
|
|
158
|
+
# bootstrap-reachable (every core/attached chapter's own top-level shape is written
|
|
159
|
+
# with it), so also named in `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`.
|
|
160
|
+
#
|
|
161
|
+
# @param name [String] the aggregate's own name
|
|
162
|
+
# @yield the aggregate body, evaluated against a new `AggregateBuilder`; may be omitted
|
|
163
|
+
# @return [Array<Bluebook::Aggregate>] every aggregate declared so far, this one last
|
|
164
|
+
# @raise [Bluebook::DSL::Malformed] if the aggregate's own body fails any check
|
|
165
|
+
# `AggregateBuilder#build` raises
|
|
122
166
|
def aggregate_impl(name, &)
|
|
123
167
|
@aggregates << AggregateBuilder.build(name, chapter_named_givens: @chapter_named_givens,
|
|
124
168
|
chapter_pending_givens: @chapter_pending_givens,
|
|
@@ -126,6 +170,8 @@ module Hecks
|
|
|
126
170
|
chapter_entity_pending_givens: @chapter_entity_pending_givens, &)
|
|
127
171
|
end
|
|
128
172
|
|
|
173
|
+
# Declares a read model belonging to this chapter.
|
|
174
|
+
#
|
|
129
175
|
# `read_model` is the word (ADR 0025 reverts `report` — the IR
|
|
130
176
|
# construct, the registry API, and the docs filename all said
|
|
131
177
|
# `read_model` the whole time; no era was ever minted under
|
|
@@ -134,6 +180,12 @@ module Hecks
|
|
|
134
180
|
# bridge) for the same reason `has_many` does — frozen era text
|
|
135
181
|
# that used it must keep booting; live source refuses it, naming
|
|
136
182
|
# the replacement.
|
|
183
|
+
#
|
|
184
|
+
# @param name [String] the read model's own name
|
|
185
|
+
# @yield the read model body, evaluated against a new `ReadModelBuilder`
|
|
186
|
+
# @return [Array<Bluebook::ReadModel>] every read model declared so far, this one last
|
|
187
|
+
# @raise [Bluebook::DSL::Malformed] if the body fails any check `ReadModelBuilder#build`
|
|
188
|
+
# raises
|
|
137
189
|
def read_model(name, &)
|
|
138
190
|
# A read model gathers heads from several aggregates, so no single head
|
|
139
191
|
# declares it — the chapter does. Its owner is stamped in `build`, where
|
|
@@ -141,20 +193,49 @@ module Hecks
|
|
|
141
193
|
@read_models << ReadModelBuilder.build(name, &)
|
|
142
194
|
end
|
|
143
195
|
|
|
196
|
+
# The retired spelling of `read_model`, still answered under shadow-parsing so frozen
|
|
197
|
+
# era text keeps booting; live source refuses it and names the replacement.
|
|
198
|
+
#
|
|
199
|
+
# @param name [String] the read model's own name
|
|
200
|
+
# @yield the read model body, evaluated against a new `ReadModelBuilder`
|
|
201
|
+
# @return [Array<Bluebook::ReadModel>] every read model declared so far, this one last,
|
|
202
|
+
# under shadow-parsing
|
|
203
|
+
# @raise [Bluebook::DSL::Malformed] always, outside shadow-parsing — `report` is retired
|
|
144
204
|
def report(name, &)
|
|
145
205
|
return read_model(name, &) if MetaValidator.shadow_parsing?
|
|
146
206
|
|
|
147
207
|
raise Malformed, "report is gone — read_model is the word now"
|
|
148
208
|
end
|
|
149
209
|
|
|
210
|
+
# Declares a policy belonging to this chapter.
|
|
211
|
+
#
|
|
212
|
+
# @param name [String] the policy's own name
|
|
213
|
+
# @yield the policy body, evaluated against a new `PolicyBuilder`
|
|
214
|
+
# @return [Array<Bluebook::Policy>] every chapter-level policy declared so far,
|
|
215
|
+
# this one last
|
|
150
216
|
def policy(name, &)
|
|
151
217
|
@policies << PolicyBuilder.build(name, &)
|
|
152
218
|
end
|
|
153
219
|
|
|
220
|
+
# Declares a process manager (saga) belonging to this chapter.
|
|
221
|
+
#
|
|
222
|
+
# @param name [String] the process manager's own name
|
|
223
|
+
# @yield the process manager body, evaluated against a new `ProcessManagerBuilder`
|
|
224
|
+
# @return [Array<Bluebook::ProcessManager>] every process manager declared so far,
|
|
225
|
+
# this one last
|
|
154
226
|
def process_manager(name, &)
|
|
155
227
|
@process_managers << ProcessManagerBuilder.build(name, &)
|
|
156
228
|
end
|
|
157
229
|
|
|
230
|
+
# Assembles this builder's accumulated declarations into a judged `Chapter`.
|
|
231
|
+
#
|
|
232
|
+
# @return [Bluebook::Chapter] the built chapter, judged by the language when not
|
|
233
|
+
# deferring across a multi-file chapter
|
|
234
|
+
# @raise [Bluebook::DSL::Malformed] if a chapter-wide given reference cannot be
|
|
235
|
+
# resolved, if cross-construct validation fails, or if the language's own
|
|
236
|
+
# whole-document judgment refuses the chapter
|
|
237
|
+
# @raise [Bluebook::DSL::ProcessManagerBuilder::InvalidProcessManager] if a process
|
|
238
|
+
# manager's own structural check fails
|
|
158
239
|
def build
|
|
159
240
|
# The chapter is the top of the construct chain — `Bluebook` is a
|
|
160
241
|
# root, and its constructor stamps every aggregate and read model with
|
|
@@ -226,6 +307,12 @@ module Hecks
|
|
|
226
307
|
# which only exists on the builder instance still open for this
|
|
227
308
|
# chapter (`MetaValidator.judge_deferred!` reaches it via
|
|
228
309
|
# `registry.bluebook_builder(name)`, guaranteed already present).
|
|
310
|
+
#
|
|
311
|
+
# @return [void]
|
|
312
|
+
# @raise [Bluebook::DSL::Malformed] if a pending reference's own `description` names no
|
|
313
|
+
# precondition any aggregate in this chapter declares, is ambiguous across several
|
|
314
|
+
# aggregates with no `declared_by:` to disambiguate, or `declared_by:` names an
|
|
315
|
+
# aggregate that does not declare it
|
|
229
316
|
def resolve_pending_chapter_givens!
|
|
230
317
|
@chapter_pending_givens.each do |entry|
|
|
231
318
|
resolved = resolve_pending_chapter_given(entry)
|
|
@@ -268,6 +355,12 @@ module Hecks
|
|
|
268
355
|
# The entity-scoped analogue, one level down — see
|
|
269
356
|
# `#resolve_pending_chapter_givens!`'s own comment; identical
|
|
270
357
|
# shape, resolved against `@chapter_entity_named_givens` instead.
|
|
358
|
+
#
|
|
359
|
+
# @return [void]
|
|
360
|
+
# @raise [Bluebook::DSL::Malformed] if a pending reference's own `description` names no
|
|
361
|
+
# precondition any piece in this chapter declares, is ambiguous across several pieces
|
|
362
|
+
# with no `declared_by:` to disambiguate, or `declared_by:` names a piece that does
|
|
363
|
+
# not declare it
|
|
271
364
|
def resolve_pending_chapter_entity_givens!
|
|
272
365
|
@chapter_entity_pending_givens.each do |entry|
|
|
273
366
|
resolved = resolve_pending_chapter_entity_given(entry)
|
|
@@ -307,31 +400,52 @@ module Hecks
|
|
|
307
400
|
end
|
|
308
401
|
private :resolve_pending_chapter_entity_given
|
|
309
402
|
|
|
403
|
+
# Builds a `Chapter` from a `Hecks.bluebook "Name" do ... end` block, reusing the same
|
|
404
|
+
# open builder across several files that share one chapter name.
|
|
405
|
+
#
|
|
310
406
|
# A chapter may be declared in several files, meant to merge into one
|
|
311
407
|
# domain — `lib/hecks/language/bluebook/*.bluebook` all open
|
|
312
|
-
# `Hecks.bluebook "Bluebook" do ... end`.
|
|
313
|
-
#
|
|
314
|
-
#
|
|
408
|
+
# `Hecks.bluebook "Bluebook" do ... end`. The registry holds the builder open across
|
|
409
|
+
# calls — the first file for a name creates it, every later file for the same name
|
|
410
|
+
# reuses the same instance — rather than minting a fresh builder per call, which would
|
|
411
|
+
# let a second file with the same chapter name silently replace the first's aggregates
|
|
412
|
+
# instead of adding to them.
|
|
315
413
|
#
|
|
316
|
-
#
|
|
317
|
-
#
|
|
318
|
-
# same instance, so `@aggregates`/`@read_models` accumulate. `#build` is
|
|
319
|
-
# safe to call once per file on the same builder — it constructs a fresh
|
|
414
|
+
# `@aggregates`/`@read_models` accumulate across calls on the reused instance. `#build`
|
|
415
|
+
# is safe to call once per file on the same builder — it constructs a fresh
|
|
320
416
|
# `Bluebook` from whatever is currently held and re-`Namespace.install`s
|
|
321
417
|
# over the previous one, so the last file's call leaves every aggregate
|
|
322
418
|
# seen so far reachable, and each call's IR is a strict superset of the
|
|
323
419
|
# one before. `Registry#add_bluebook` still simply stores by name — with
|
|
324
420
|
# this in place, "last write wins" is the cumulative, correct write.
|
|
421
|
+
#
|
|
422
|
+
# @param name [String] the chapter's declared name
|
|
423
|
+
# @param version [String, nil] the chapter's pinned version, or nil for unversioned
|
|
424
|
+
# @yield the chapter's body, `instance_eval`'d against the builder, with a `const_missing`
|
|
425
|
+
# resolver installed so a bare constant resolves to a `ConstShim::ScopedConstant`
|
|
426
|
+
# @return [Bluebook::Chapter] the built, judged chapter
|
|
427
|
+
# @raise [Bluebook::DSL::Malformed] if this call's `version` conflicts with a version
|
|
428
|
+
# already adopted for this chapter name, or if the built chapter fails any check
|
|
429
|
+
# `#build` raises
|
|
430
|
+
# @raise [Bluebook::DSL::ProcessManagerBuilder::InvalidProcessManager] if a process
|
|
431
|
+
# manager's own structural check fails
|
|
325
432
|
def self.build(name, version: nil, &block)
|
|
326
433
|
registry = Hecks.current_registry
|
|
327
|
-
|
|
434
|
+
# WHICH FILE CALLED `Hecks.bluebook`, recorded for
|
|
435
|
+
# `Registry#record_bluebook_source` — two frames up: this
|
|
436
|
+
# method's own caller is `Hecks.bluebook` (hecks.rb), and ITS
|
|
437
|
+
# caller is the real `.bluebook` file's own top-level call site.
|
|
438
|
+
caller_location = caller_locations(2, 1)&.first
|
|
439
|
+
registry&.record_bluebook_source(name, caller_location&.path)
|
|
440
|
+
builder = registry ? registry.bluebook_builder(name) { new(name, version: version) } : new(name, version: version)
|
|
328
441
|
builder.__send__(:adopt_version, version)
|
|
329
442
|
# A bare constant in a bluebook — `attribute :name, PizzaName` — is a name,
|
|
330
443
|
# not a reference to something Ruby has heard of. `const_missing` hands
|
|
331
444
|
# over a `ConstShim::ScopedConstant` (S0b, const_shim.rb's own comment),
|
|
332
445
|
# and that is still the whole answer for a bare name: `Attribute` spells
|
|
333
|
-
# it with `to_s`, so the `TypeName` wrapper
|
|
334
|
-
#
|
|
446
|
+
# it with `to_s`, so the concept never needed a `TypeName` wrapper class
|
|
447
|
+
# of its own — any such wrapper would exist only long enough to be
|
|
448
|
+
# stringified. The concept still has a home — the
|
|
335
449
|
# language declares `value_object "TypeName"` — it just needed no Ruby
|
|
336
450
|
# class of its own. A Module rather than a Symbol is what also lets
|
|
337
451
|
# `Account::Debit`/`admits: Account::LedgerDirection` answer their own
|