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.
Files changed (267) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hecks/adapters/driven/claude_code.rb +65 -0
  3. data/lib/hecks/adapters/driven/folder.rb +73 -0
  4. data/lib/hecks/adapters/driven/google_authentication.rb +25 -4
  5. data/lib/hecks/adapters/driven/governance_authorization.rb +57 -6
  6. data/lib/hecks/adapters/driven/heki/journal.rb +8 -0
  7. data/lib/hecks/adapters/driven/heki/saga_store.rb +53 -7
  8. data/lib/hecks/adapters/driven/heki/snapshot.rb +1 -1
  9. data/lib/hecks/adapters/driven/heki.rb +93 -2
  10. data/lib/hecks/adapters/driven/identity_registry.rb +10 -0
  11. data/lib/hecks/adapters/driven/in_memory_ordering.rb +22 -0
  12. data/lib/hecks/adapters/driven/in_process_key_vault.adapter +3 -0
  13. data/lib/hecks/adapters/driven/in_process_key_vault.rb +53 -0
  14. data/lib/hecks/adapters/driven/lambda/client.rb +35 -7
  15. data/lib/hecks/adapters/driven/lambda.rb +43 -2
  16. data/lib/hecks/adapters/driven/local_storage.rb +67 -1
  17. data/lib/hecks/adapters/driven/memory.rb +13 -13
  18. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +20 -0
  19. data/lib/hecks/adapters/driven/prism.rb +46 -7
  20. data/lib/hecks/adapters/driven/secure_random_identity.rb +3 -0
  21. data/lib/hecks/adapters/driven/system_clock.rb +3 -0
  22. data/lib/hecks/adapters/driven/tenant_provisioner.adapter +3 -0
  23. data/lib/hecks/adapters/driven/tenant_provisioner.rb +66 -0
  24. data/lib/hecks/adapters/driven.rb +2 -0
  25. data/lib/hecks/adapters/driving/github_webhook.rb +14 -1
  26. data/lib/hecks/behaviors/dsl.rb +58 -0
  27. data/lib/hecks/behaviors/expectations.rb +168 -7
  28. data/lib/hecks/behaviors/ir.rb +11 -0
  29. data/lib/hecks/behaviors/rspec.rb +8 -0
  30. data/lib/hecks/behaviors/runner.rb +19 -0
  31. data/lib/hecks/behaviors.rb +8 -0
  32. data/lib/hecks/bluebook/aggregate.rb +30 -0
  33. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +7 -0
  34. data/lib/hecks/bluebook/assembly/build.rb +25 -4
  35. data/lib/hecks/bluebook/assembly/contract.rb +66 -14
  36. data/lib/hecks/bluebook/assembly/contracts.rb +24 -19
  37. data/lib/hecks/bluebook/assembly/marks.rb +143 -14
  38. data/lib/hecks/bluebook/assembly/specializer.rb +19 -0
  39. data/lib/hecks/bluebook/assembly.rb +25 -7
  40. data/lib/hecks/bluebook/attribute.rb +17 -3
  41. data/lib/hecks/bluebook/behaviour/aggregate.rb +32 -0
  42. data/lib/hecks/bluebook/behaviour/attribute.rb +13 -0
  43. data/lib/hecks/bluebook/behaviour/chapter.rb +55 -2
  44. data/lib/hecks/bluebook/behaviour/command.rb +33 -3
  45. data/lib/hecks/bluebook/behaviour/domain_port.rb +20 -0
  46. data/lib/hecks/bluebook/behaviour/entity.rb +12 -0
  47. data/lib/hecks/bluebook/behaviour/hexagon.rb +26 -0
  48. data/lib/hecks/bluebook/behaviour/lifecycle.rb +23 -2
  49. data/lib/hecks/bluebook/behaviour/policy.rb +34 -9
  50. data/lib/hecks/bluebook/behaviour/process_manager.rb +32 -1
  51. data/lib/hecks/bluebook/behaviour/query.rb +5 -0
  52. data/lib/hecks/bluebook/behaviour/read_model.rb +21 -0
  53. data/lib/hecks/bluebook/behaviour/traits.rb +36 -0
  54. data/lib/hecks/bluebook/behaviour/value_object.rb +17 -5
  55. data/lib/hecks/bluebook/chapter.rb +23 -0
  56. data/lib/hecks/bluebook/command.rb +53 -8
  57. data/lib/hecks/bluebook/domain_port.rb +25 -0
  58. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +196 -37
  59. data/lib/hecks/bluebook/dsl/attribute_collector.rb +79 -42
  60. data/lib/hecks/bluebook/dsl/binding_proxy.rb +59 -0
  61. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +385 -53
  62. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +135 -21
  63. data/lib/hecks/bluebook/dsl/command_builder.rb +189 -27
  64. data/lib/hecks/bluebook/dsl/entity_builder.rb +139 -9
  65. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +41 -0
  66. data/lib/hecks/bluebook/dsl/identity_declaration.rb +23 -6
  67. data/lib/hecks/bluebook/dsl/policy_builder.rb +60 -19
  68. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +79 -15
  69. data/lib/hecks/bluebook/dsl/query_builder.rb +33 -4
  70. data/lib/hecks/bluebook/dsl/read_model_builder.rb +102 -27
  71. data/lib/hecks/bluebook/dsl/rule_reference.rb +60 -8
  72. data/lib/hecks/bluebook/dsl/translation_builder.rb +146 -40
  73. data/lib/hecks/bluebook/dsl/value_object_builder.rb +55 -7
  74. data/lib/hecks/bluebook/entity.rb +29 -0
  75. data/lib/hecks/bluebook/expression/ast_json.rb +115 -23
  76. data/lib/hecks/bluebook/expression/ast_reader.rb +29 -0
  77. data/lib/hecks/bluebook/expression/canonical_form.rb +48 -9
  78. data/lib/hecks/bluebook/expression/evaluator.rb +207 -29
  79. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +36 -0
  80. data/lib/hecks/bluebook/expression/resolver.rb +320 -77
  81. data/lib/hecks/bluebook/hexagon.rb +34 -0
  82. data/lib/hecks/bluebook/lifecycle.rb +11 -0
  83. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -0
  84. data/lib/hecks/bluebook/meta_validator/judge.rb +30 -26
  85. data/lib/hecks/bluebook/meta_validator/plan.rb +43 -8
  86. data/lib/hecks/bluebook/meta_validator/port_judge.rb +1 -0
  87. data/lib/hecks/bluebook/meta_validator/readings.rb +157 -7
  88. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +24 -4
  89. data/lib/hecks/bluebook/meta_validator/shapes.rb +141 -0
  90. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +149 -23
  91. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +5 -4
  92. data/lib/hecks/bluebook/meta_validator/world_judge.rb +1 -0
  93. data/lib/hecks/bluebook/meta_validator.rb +180 -84
  94. data/lib/hecks/bluebook/model_check.rb +268 -24
  95. data/lib/hecks/bluebook/pattern_subset.rb +23 -1
  96. data/lib/hecks/bluebook/process_manager.rb +13 -0
  97. data/lib/hecks/bluebook/project_discovery.rb +5 -0
  98. data/lib/hecks/bluebook/project_loader.rb +40 -0
  99. data/lib/hecks/bluebook/project_register.rb +44 -0
  100. data/lib/hecks/bluebook/query.rb +27 -0
  101. data/lib/hecks/bluebook/read_model.rb +21 -1
  102. data/lib/hecks/bluebook/reference.rb +21 -8
  103. data/lib/hecks/bluebook/smoke_test.rb +29 -6
  104. data/lib/hecks/bluebook/synthesizer.rb +34 -0
  105. data/lib/hecks/bluebook/translation.rb +30 -1
  106. data/lib/hecks/bluebook/value_object.rb +23 -5
  107. data/lib/hecks/bluebook.rb +3 -4
  108. data/lib/hecks/codemod.rb +107 -20
  109. data/lib/hecks/construct.rb +15 -1
  110. data/lib/hecks/corpus.rb +146 -25
  111. data/lib/hecks/deploy/bluebook/deploy.hecksagon +19 -0
  112. data/lib/hecks/doc/reference.rb +185 -16
  113. data/lib/hecks/embryonaut_bluebook.rb +32 -9
  114. data/lib/hecks/facade/handle.rb +76 -3
  115. data/lib/hecks/facade/surface/aggregate_door.rb +8 -0
  116. data/lib/hecks/forms/field_shape.rb +3 -0
  117. data/lib/hecks/forms/page.rb +14 -0
  118. data/lib/hecks/forms/port_argument.rb +12 -0
  119. data/lib/hecks/forms/query_form_renderer.rb +63 -0
  120. data/lib/hecks/forms/record_renderer.rb +58 -0
  121. data/lib/hecks/forms/record_table.rb +27 -0
  122. data/lib/hecks/forms/reference_options.rb +24 -0
  123. data/lib/hecks/forms/value_object_shape.rb +10 -0
  124. data/lib/hecks/fqn.rb +58 -0
  125. data/lib/hecks/framework/bluebook/privacy.bluebook +155 -0
  126. data/lib/hecks/framework/oidc.json +15 -0
  127. data/lib/hecks/framework.rb +43 -20
  128. data/lib/hecks/freezer.rb +17 -1
  129. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +159 -24
  130. data/lib/hecks/fuzzing/combination_miner.rb +59 -0
  131. data/lib/hecks/fuzzing/concurrent_dispatch.rb +109 -8
  132. data/lib/hecks/fuzzing/coverage_campaign.rb +56 -13
  133. data/lib/hecks/fuzzing/differential.rb +34 -0
  134. data/lib/hecks/fuzzing/domain_generator.rb +188 -11
  135. data/lib/hecks/fuzzing/era_boundary.rb +45 -15
  136. data/lib/hecks/fuzzing/form_census.rb +86 -0
  137. data/lib/hecks/fuzzing/generated_domain_check.rb +76 -0
  138. data/lib/hecks/fuzzing/invalid_value_generator.rb +39 -0
  139. data/lib/hecks/fuzzing/isolated_boot.rb +79 -22
  140. data/lib/hecks/fuzzing/nondeterministic.rb +13 -1
  141. data/lib/hecks/fuzzing/persistence_parity.rb +95 -3
  142. data/lib/hecks/fuzzing/properties/corrections.rb +25 -0
  143. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +158 -14
  144. data/lib/hecks/fuzzing/properties/guards.rb +44 -0
  145. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +48 -0
  146. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +18 -0
  147. data/lib/hecks/fuzzing/properties/outbox.rb +49 -11
  148. data/lib/hecks/fuzzing/properties/querying.rb +68 -14
  149. data/lib/hecks/fuzzing/properties.rb +24 -15
  150. data/lib/hecks/fuzzing/qa_settings.rb +12 -0
  151. data/lib/hecks/fuzzing/replay.rb +137 -29
  152. data/lib/hecks/fuzzing/rotation_priority.rb +41 -21
  153. data/lib/hecks/fuzzing/rust_gap_manifest.rb +46 -20
  154. data/lib/hecks/fuzzing/self_consistency.rb +189 -40
  155. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +12 -6
  156. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +1 -1
  157. data/lib/hecks/fuzzing/sequence_generator.rb +47 -0
  158. data/lib/hecks/fuzzing/shrinker.rb +114 -2
  159. data/lib/hecks/fuzzing/structural_skips.rb +18 -4
  160. data/lib/hecks/fuzzing/sweep_depth.rb +8 -0
  161. data/lib/hecks/fuzzing/target_capabilities.rb +61 -14
  162. data/lib/hecks/fuzzing/value_generator.rb +98 -10
  163. data/lib/hecks/grammar/evolve.rb +178 -2
  164. data/lib/hecks/grammar.rb +46 -0
  165. data/lib/hecks/ir.rb +38 -7
  166. data/lib/hecks/language/hecksagon/hecksagon.bluebook +11 -0
  167. data/lib/hecks/literal.rb +32 -0
  168. data/lib/hecks/naming.rb +88 -7
  169. data/lib/hecks/ports/access_control.rb +5 -10
  170. data/lib/hecks/ports/authorization.rb +3 -6
  171. data/lib/hecks/ports/identity_assignment.rb +1 -2
  172. data/lib/hecks/ports/identity_resolution.rb +1 -2
  173. data/lib/hecks/ports/key_vault.port +6 -0
  174. data/lib/hecks/ports/key_vault.rb +58 -0
  175. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +6 -0
  176. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +38 -2
  177. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +6 -0
  178. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +40 -0
  179. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +92 -1
  180. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +15 -0
  181. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +8 -0
  182. data/lib/hecks/ports/query/in_memory.rb +39 -6
  183. data/lib/hecks/ports/query/ordering.rb +15 -0
  184. data/lib/hecks/ports.rb +1 -0
  185. data/lib/hecks/projections/bootstrap_table.rb +43 -8
  186. data/lib/hecks/projections/diagrams.rb +243 -7
  187. data/lib/hecks/projections/glossary/html.rb +88 -0
  188. data/lib/hecks/projections/glossary/markdown.rb +47 -0
  189. data/lib/hecks/projections/glossary/mermaid.rb +48 -0
  190. data/lib/hecks/projections/glossary/sentences.rb +105 -0
  191. data/lib/hecks/projections/glossary.rb +161 -19
  192. data/lib/hecks/projections/model/deviations.rb +44 -0
  193. data/lib/hecks/projections/model.rb +51 -1
  194. data/lib/hecks/projections/oidc.rb +40 -3
  195. data/lib/hecks/projections/parser_table.rb +49 -8
  196. data/lib/hecks/projections/reference.rb +12 -0
  197. data/lib/hecks/projections/rust_vocabulary.rb +219 -16
  198. data/lib/hecks/projections/shape.rb +8 -0
  199. data/lib/hecks/projections/statements.rb +63 -16
  200. data/lib/hecks/projections/vocabulary.rb +17 -0
  201. data/lib/hecks/projector/cli_projector.rb +218 -10
  202. data/lib/hecks/projector/docs_projector.rb +145 -19
  203. data/lib/hecks/projector/exporter.rb +65 -11
  204. data/lib/hecks/projector/ir_projector.rb +6 -0
  205. data/lib/hecks/projector/narrate_projector.rb +136 -15
  206. data/lib/hecks/projector/target.rb +29 -5
  207. data/lib/hecks/projector.rb +74 -6
  208. data/lib/hecks/query_ir.rb +47 -0
  209. data/lib/hecks/query_specification/common/null_policy.rb +5 -3
  210. data/lib/hecks/rendering.rb +6 -0
  211. data/lib/hecks/router/namespace_installer.rb +13 -0
  212. data/lib/hecks/router.rb +55 -0
  213. data/lib/hecks/runtime/aggregate_lock.rb +9 -0
  214. data/lib/hecks/runtime/boot_gates.rb +18 -0
  215. data/lib/hecks/runtime/caller.rb +32 -0
  216. data/lib/hecks/runtime/capability_graph.rb +11 -0
  217. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +23 -21
  218. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +14 -15
  219. data/lib/hecks/runtime/command_interpreter.rb +42 -17
  220. data/lib/hecks/runtime/command_rules/admissibility.rb +165 -14
  221. data/lib/hecks/runtime/command_rules/arithmetic.rb +17 -5
  222. data/lib/hecks/runtime/command_rules/references.rb +118 -28
  223. data/lib/hecks/runtime/dependency_planning.rb +45 -0
  224. data/lib/hecks/runtime/dispatcher.rb +28 -50
  225. data/lib/hecks/runtime/entity_element.rb +161 -8
  226. data/lib/hecks/runtime/entity_interpreter.rb +44 -9
  227. data/lib/hecks/runtime/errors.rb +18 -4
  228. data/lib/hecks/runtime/event.rb +10 -5
  229. data/lib/hecks/runtime/identity.rb +71 -3
  230. data/lib/hecks/runtime/instance.rb +67 -7
  231. data/lib/hecks/runtime/interpreting.rb +13 -5
  232. data/lib/hecks/runtime/invocation.rb +118 -36
  233. data/lib/hecks/runtime/loader.rb +94 -8
  234. data/lib/hecks/runtime/outbox.rb +145 -7
  235. data/lib/hecks/runtime/policy_interpreter.rb +22 -9
  236. data/lib/hecks/runtime/port_operation_interpreter.rb +20 -0
  237. data/lib/hecks/runtime/query_interpreter.rb +40 -12
  238. data/lib/hecks/runtime/reaction_invocation.rb +53 -8
  239. data/lib/hecks/runtime/read_model_interpreter.rb +23 -7
  240. data/lib/hecks/runtime/rebuild_sweep.rb +28 -0
  241. data/lib/hecks/runtime/reference_hop.rb +42 -0
  242. data/lib/hecks/runtime/refusal_wording.rb +50 -0
  243. data/lib/hecks/runtime/registry/saga_persistence.rb +11 -0
  244. data/lib/hecks/runtime/registry/verification.rb +119 -4
  245. data/lib/hecks/runtime/registry.rb +157 -4
  246. data/lib/hecks/runtime/remote_dispatcher.rb +92 -6
  247. data/lib/hecks/runtime/routing.rb +27 -2
  248. data/lib/hecks/runtime/saga_interpreter/correlation.rb +10 -12
  249. data/lib/hecks/runtime/saga_interpreter.rb +27 -13
  250. data/lib/hecks/runtime/tenant_check.rb +26 -6
  251. data/lib/hecks/runtime/tenant_scope.rb +18 -0
  252. data/lib/hecks/runtime/value/coercion.rb +255 -33
  253. data/lib/hecks/runtime/value/entity_list_coercion.rb +102 -30
  254. data/lib/hecks/runtime/value.rb +50 -0
  255. data/lib/hecks/runtime.rb +32 -0
  256. data/lib/hecks/storehouse.rb +305 -9
  257. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +130 -0
  258. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +32 -0
  259. data/lib/hecks/version.rb +1 -1
  260. data/lib/hecks.rb +79 -1
  261. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -0
  262. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +12 -2
  263. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +29 -5
  264. metadata +11 -5
  265. data/lib/hecks/codemod/legacy_dispatch_args.rb +0 -299
  266. data/lib/hecks/codemod/legacy_dispatch_recorder.rb +0 -186
  267. 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
- # A domain's own identity can change — this names what it used to
72
- # be, so the storage layer can recognize its own history under the
73
- # old name instead of minting a brand-new lineage from nothing.
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
- # Renamed from `attaches_to` — item #13's full metaprogrammed
84
- # dispatch (slice 4c). Not bootstrap-reachable (only sub-language
85
- # chapters like Paging use it; the core chapters never describe
86
- # themselves with it).
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
- # Renamed from `aggregate` — item #13's full metaprogrammed
119
- # dispatch (slice 4c). Bootstrap-reachable (every core/attached
120
- # chapter's own top-level shape is written with it), so also
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`. Each `Hecks.bluebook` call used to
313
- # mint a fresh builder, so a second file with the same chapter name
314
- # silently replaced the first's aggregates instead of adding to them.
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
- # The registry now holds the builder open across calls : the first file
317
- # for a name creates it, every later file for the same name reuses the
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
- builder = registry ? registry.bluebook_builder(name) { new(name, version: version) } : new(name, version: version)
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 this used to build existed
334
- # only long enough to be stringified. The concept still has a home — the
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