hecks 1.3.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 (373) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hecks/adapters/driven/claude_code.rb +72 -7
  3. data/lib/hecks/adapters/driven/d1.rb +187 -23
  4. data/lib/hecks/adapters/driven/folder.rb +83 -10
  5. data/lib/hecks/adapters/driven/google_authentication.rb +33 -12
  6. data/lib/hecks/adapters/driven/governance_authorization.rb +87 -18
  7. data/lib/hecks/adapters/driven/heki/journal.rb +13 -4
  8. data/lib/hecks/adapters/driven/heki/saga_store.rb +56 -10
  9. data/lib/hecks/adapters/driven/heki/snapshot.rb +1 -1
  10. data/lib/hecks/adapters/driven/heki.rb +106 -9
  11. data/lib/hecks/adapters/driven/identity_registry.rb +12 -2
  12. data/lib/hecks/adapters/driven/in_memory_ordering.rb +25 -3
  13. data/lib/hecks/adapters/driven/in_process_key_vault.adapter +3 -0
  14. data/lib/hecks/adapters/driven/in_process_key_vault.rb +53 -0
  15. data/lib/hecks/adapters/driven/lambda/client.rb +67 -14
  16. data/lib/hecks/adapters/driven/lambda.rb +82 -35
  17. data/lib/hecks/adapters/driven/local_storage.rb +83 -10
  18. data/lib/hecks/adapters/driven/memory.rb +205 -9
  19. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +21 -1
  20. data/lib/hecks/adapters/driven/postgres/codec.rb +27 -11
  21. data/lib/hecks/adapters/driven/postgres/outbox.rb +40 -2
  22. data/lib/hecks/adapters/driven/postgres/reconnect.rb +23 -7
  23. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +14 -14
  24. data/lib/hecks/adapters/driven/postgres.rb +175 -28
  25. data/lib/hecks/adapters/driven/prism.rb +50 -11
  26. data/lib/hecks/adapters/driven/secure_random_identity.rb +3 -0
  27. data/lib/hecks/adapters/driven/sql_query_builder.rb +34 -22
  28. data/lib/hecks/adapters/driven/sqlite/codec.rb +38 -10
  29. data/lib/hecks/adapters/driven/sqlite/projection.rb +60 -32
  30. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +12 -12
  31. data/lib/hecks/adapters/driven/sqlite.rb +181 -21
  32. data/lib/hecks/adapters/driven/system_clock.rb +3 -0
  33. data/lib/hecks/adapters/driven/tenant_provisioner.adapter +3 -0
  34. data/lib/hecks/adapters/driven/tenant_provisioner.rb +66 -0
  35. data/lib/hecks/adapters/driven.rb +6 -4
  36. data/lib/hecks/adapters/driving/github_webhook.rb +31 -18
  37. data/lib/hecks/behaviors/dsl.rb +60 -2
  38. data/lib/hecks/behaviors/expectations.rb +190 -29
  39. data/lib/hecks/behaviors/ir.rb +12 -1
  40. data/lib/hecks/behaviors/rspec.rb +9 -1
  41. data/lib/hecks/behaviors/runner.rb +21 -2
  42. data/lib/hecks/behaviors.rb +9 -1
  43. data/lib/hecks/bluebook/aggregate.rb +43 -13
  44. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +17 -10
  45. data/lib/hecks/bluebook/assembly/build.rb +26 -5
  46. data/lib/hecks/bluebook/assembly/contract.rb +98 -23
  47. data/lib/hecks/bluebook/assembly/contracts.rb +59 -52
  48. data/lib/hecks/bluebook/assembly/marks.rb +159 -30
  49. data/lib/hecks/bluebook/assembly/specializer.rb +38 -21
  50. data/lib/hecks/bluebook/assembly.rb +32 -14
  51. data/lib/hecks/bluebook/attribute.rb +26 -12
  52. data/lib/hecks/bluebook/behaviour/aggregate.rb +43 -11
  53. data/lib/hecks/bluebook/behaviour/attribute.rb +18 -5
  54. data/lib/hecks/bluebook/behaviour/chapter.rb +76 -5
  55. data/lib/hecks/bluebook/behaviour/command.rb +55 -25
  56. data/lib/hecks/bluebook/behaviour/domain_port.rb +27 -7
  57. data/lib/hecks/bluebook/behaviour/entity.rb +20 -8
  58. data/lib/hecks/bluebook/behaviour/hexagon.rb +30 -4
  59. data/lib/hecks/bluebook/behaviour/lifecycle.rb +27 -6
  60. data/lib/hecks/bluebook/behaviour/policy.rb +42 -17
  61. data/lib/hecks/bluebook/behaviour/process_manager.rb +39 -8
  62. data/lib/hecks/bluebook/behaviour/query.rb +6 -1
  63. data/lib/hecks/bluebook/behaviour/read_model.rb +29 -8
  64. data/lib/hecks/bluebook/behaviour/traits.rb +48 -12
  65. data/lib/hecks/bluebook/behaviour/value_object.rb +21 -9
  66. data/lib/hecks/bluebook/capabilities.rb +27 -0
  67. data/lib/hecks/bluebook/chapter.rb +51 -9
  68. data/lib/hecks/bluebook/command.rb +62 -17
  69. data/lib/hecks/bluebook/domain_port.rb +34 -9
  70. data/lib/hecks/bluebook/dsl/adapter_builder.rb +24 -0
  71. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +49 -49
  72. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +282 -123
  73. data/lib/hecks/bluebook/dsl/attribute_collector.rb +112 -75
  74. data/lib/hecks/bluebook/dsl/binding_proxy.rb +81 -2
  75. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +486 -117
  76. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +179 -47
  77. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +116 -0
  78. data/lib/hecks/bluebook/dsl/command_builder.rb +284 -122
  79. data/lib/hecks/bluebook/dsl/const_shim.rb +46 -15
  80. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +90 -25
  81. data/lib/hecks/bluebook/dsl/entity_builder.rb +191 -61
  82. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +148 -132
  83. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +130 -30
  84. data/lib/hecks/bluebook/dsl/identity_declaration.rb +38 -21
  85. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +27 -4
  86. data/lib/hecks/bluebook/dsl/policy_builder.rb +86 -36
  87. data/lib/hecks/bluebook/dsl/port_builder.rb +38 -7
  88. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +56 -22
  89. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +111 -47
  90. data/lib/hecks/bluebook/dsl/query_builder.rb +37 -8
  91. data/lib/hecks/bluebook/dsl/read_model_builder.rb +127 -52
  92. data/lib/hecks/bluebook/dsl/rule_reference.rb +97 -43
  93. data/lib/hecks/bluebook/dsl/translation_builder.rb +150 -44
  94. data/lib/hecks/bluebook/dsl/value_object_builder.rb +68 -20
  95. data/lib/hecks/bluebook/dsl/word_gate.rb +59 -53
  96. data/lib/hecks/bluebook/dsl/world_builder.rb +51 -8
  97. data/lib/hecks/bluebook/entity.rb +40 -11
  98. data/lib/hecks/bluebook/expression/ast_json.rb +128 -36
  99. data/lib/hecks/bluebook/expression/ast_reader.rb +32 -3
  100. data/lib/hecks/bluebook/expression/canonical_form.rb +55 -16
  101. data/lib/hecks/bluebook/expression/evaluator.rb +221 -43
  102. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +54 -18
  103. data/lib/hecks/bluebook/expression/resolver.rb +369 -128
  104. data/lib/hecks/bluebook/hexagon.rb +35 -1
  105. data/lib/hecks/bluebook/lifecycle.rb +12 -1
  106. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +2 -1
  107. data/lib/hecks/bluebook/meta_validator/judge.rb +126 -108
  108. data/lib/hecks/bluebook/meta_validator/plan.rb +81 -46
  109. data/lib/hecks/bluebook/meta_validator/port_judge.rb +3 -2
  110. data/lib/hecks/bluebook/meta_validator/readings.rb +200 -50
  111. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +68 -41
  112. data/lib/hecks/bluebook/meta_validator/shapes.rb +166 -21
  113. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +286 -46
  114. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +11 -10
  115. data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -5
  116. data/lib/hecks/bluebook/meta_validator.rb +235 -139
  117. data/lib/hecks/bluebook/model_check.rb +434 -104
  118. data/lib/hecks/bluebook/pattern_subset.rb +32 -10
  119. data/lib/hecks/bluebook/policy.rb +15 -13
  120. data/lib/hecks/bluebook/process_manager.rb +27 -14
  121. data/lib/hecks/bluebook/project_discovery.rb +5 -0
  122. data/lib/hecks/bluebook/project_loader.rb +40 -0
  123. data/lib/hecks/bluebook/project_register.rb +50 -6
  124. data/lib/hecks/bluebook/query.rb +31 -4
  125. data/lib/hecks/bluebook/read_model.rb +35 -15
  126. data/lib/hecks/bluebook/reference.rb +26 -13
  127. data/lib/hecks/bluebook/smoke_test.rb +46 -23
  128. data/lib/hecks/bluebook/synthesizer.rb +46 -12
  129. data/lib/hecks/bluebook/translation.rb +34 -5
  130. data/lib/hecks/bluebook/value_object.rb +29 -11
  131. data/lib/hecks/bluebook.rb +5 -6
  132. data/lib/hecks/codemod.rb +138 -50
  133. data/lib/hecks/construct.rb +21 -7
  134. data/lib/hecks/corpus.rb +438 -0
  135. data/lib/hecks/deploy/bluebook/deploy.hecksagon +19 -0
  136. data/lib/hecks/doc/reference.rb +200 -31
  137. data/lib/hecks/embryonaut_bluebook.rb +38 -15
  138. data/lib/hecks/facade/cli_door.rb +69 -10
  139. data/lib/hecks/facade/cli_runner.rb +105 -24
  140. data/lib/hecks/facade/command_request.rb +23 -0
  141. data/lib/hecks/facade/handle.rb +155 -35
  142. data/lib/hecks/facade/json_door.rb +106 -25
  143. data/lib/hecks/facade/surface/aggregate_door.rb +50 -27
  144. data/lib/hecks/facade/surface/chapter.rb +26 -17
  145. data/lib/hecks/facade/surface.rb +16 -3
  146. data/lib/hecks/facade.rb +15 -4
  147. data/lib/hecks/forms/app.rb +46 -30
  148. data/lib/hecks/forms/command_form_renderer.rb +70 -9
  149. data/lib/hecks/forms/field_renderer.rb +142 -6
  150. data/lib/hecks/forms/field_shape.rb +183 -19
  151. data/lib/hecks/forms/html.rb +51 -7
  152. data/lib/hecks/forms/index_renderer.rb +14 -2
  153. data/lib/hecks/forms/page.rb +14 -0
  154. data/lib/hecks/forms/params.rb +120 -23
  155. data/lib/hecks/forms/port_argument.rb +14 -2
  156. data/lib/hecks/forms/query_form_renderer.rb +65 -2
  157. data/lib/hecks/forms/record_renderer.rb +60 -2
  158. data/lib/hecks/forms/record_table.rb +28 -1
  159. data/lib/hecks/forms/reference_options.rb +24 -0
  160. data/lib/hecks/forms/value_object_shape.rb +13 -3
  161. data/lib/hecks/forms.rb +24 -4
  162. data/lib/hecks/fqn.rb +59 -1
  163. data/lib/hecks/framework/bluebook/governance.bluebook +9 -0
  164. data/lib/hecks/framework/bluebook/privacy.bluebook +155 -0
  165. data/lib/hecks/framework/oidc.json +15 -0
  166. data/lib/hecks/framework.rb +79 -25
  167. data/lib/hecks/freezer.rb +27 -11
  168. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +241 -106
  169. data/lib/hecks/fuzzing/combination_miner.rb +178 -0
  170. data/lib/hecks/fuzzing/concurrent_dispatch.rb +241 -45
  171. data/lib/hecks/fuzzing/coverage_campaign.rb +161 -0
  172. data/lib/hecks/fuzzing/differential.rb +192 -0
  173. data/lib/hecks/fuzzing/domain_generator.rb +871 -0
  174. data/lib/hecks/fuzzing/era_boundary.rb +68 -19
  175. data/lib/hecks/fuzzing/form_census.rb +121 -20
  176. data/lib/hecks/fuzzing/generated_domain_check.rb +171 -0
  177. data/lib/hecks/fuzzing/invalid_value_generator.rb +45 -6
  178. data/lib/hecks/fuzzing/isolated_boot.rb +137 -80
  179. data/lib/hecks/fuzzing/nondeterministic.rb +79 -0
  180. data/lib/hecks/fuzzing/persistence_parity.rb +111 -21
  181. data/lib/hecks/fuzzing/properties/corrections.rb +34 -9
  182. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +300 -51
  183. data/lib/hecks/fuzzing/properties/guards.rb +86 -42
  184. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +80 -32
  185. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +40 -35
  186. data/lib/hecks/fuzzing/properties/outbox.rb +70 -32
  187. data/lib/hecks/fuzzing/properties/querying.rb +82 -28
  188. data/lib/hecks/fuzzing/properties.rb +84 -51
  189. data/lib/hecks/fuzzing/qa_settings.rb +164 -0
  190. data/lib/hecks/fuzzing/replay.rb +241 -133
  191. data/lib/hecks/fuzzing/rotation_priority.rb +48 -28
  192. data/lib/hecks/fuzzing/rust_gap_manifest.rb +139 -0
  193. data/lib/hecks/fuzzing/self_consistency.rb +315 -137
  194. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +46 -40
  195. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +18 -11
  196. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +13 -12
  197. data/lib/hecks/fuzzing/sequence_generator/picker.rb +21 -12
  198. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +59 -32
  199. data/lib/hecks/fuzzing/sequence_generator.rb +158 -23
  200. data/lib/hecks/fuzzing/shrinker.rb +309 -0
  201. data/lib/hecks/fuzzing/structural_skips.rb +37 -130
  202. data/lib/hecks/fuzzing/sweep_depth.rb +12 -4
  203. data/lib/hecks/fuzzing/target_capabilities.rb +107 -29
  204. data/lib/hecks/fuzzing/value_generator.rb +110 -22
  205. data/lib/hecks/fuzzing.rb +5 -0
  206. data/lib/hecks/grammar/evolve.rb +188 -12
  207. data/lib/hecks/grammar.rb +53 -7
  208. data/lib/hecks/ir.rb +51 -20
  209. data/lib/hecks/language/bluebook/bluebook.bluebook +41 -0
  210. data/lib/hecks/language/bluebook/policy.bluebook +11 -1
  211. data/lib/hecks/language/bluebook/vocabulary.bluebook +348 -13
  212. data/lib/hecks/language/hecksagon/hecksagon.bluebook +11 -0
  213. data/lib/hecks/language/oidc.json +5 -0
  214. data/lib/hecks/literal.rb +41 -9
  215. data/lib/hecks/naming.rb +112 -31
  216. data/lib/hecks/ports/access_control.rb +53 -2
  217. data/lib/hecks/ports/agent/answers.rb +83 -6
  218. data/lib/hecks/ports/agent.rb +119 -35
  219. data/lib/hecks/ports/authentication.rb +44 -4
  220. data/lib/hecks/ports/authorization.rb +50 -11
  221. data/lib/hecks/ports/clock.rb +42 -23
  222. data/lib/hecks/ports/extraction.rb +16 -0
  223. data/lib/hecks/ports/identity_assignment.rb +23 -2
  224. data/lib/hecks/ports/identity_generation.rb +17 -3
  225. data/lib/hecks/ports/identity_resolution.rb +17 -1
  226. data/lib/hecks/ports/key_vault.port +6 -0
  227. data/lib/hecks/ports/key_vault.rb +58 -0
  228. data/lib/hecks/ports/loading.rb +4 -0
  229. data/lib/hecks/ports/persistence/append_only.rb +172 -8
  230. data/lib/hecks/ports/persistence/binding_policy.rb +34 -0
  231. data/lib/hecks/ports/persistence/codec_boundary.rb +178 -0
  232. data/lib/hecks/ports/persistence/execution.rb +4 -0
  233. data/lib/hecks/ports/persistence/null_saga_store.rb +12 -1
  234. data/lib/hecks/ports/persistence/plugin.rb +42 -4
  235. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +218 -25
  236. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +77 -9
  237. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +81 -24
  238. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +29 -18
  239. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +144 -60
  240. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +103 -8
  241. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +98 -23
  242. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +282 -109
  243. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +63 -25
  244. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +118 -66
  245. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +51 -28
  246. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +34 -5
  247. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +25 -12
  248. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +129 -34
  249. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +51 -6
  250. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +33 -9
  251. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +16 -0
  252. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +95 -6
  253. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +25 -2
  254. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +314 -90
  255. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +68 -10
  256. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +9 -3
  257. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +9 -2
  258. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +48 -8
  259. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -1
  260. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +36 -5
  261. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +23 -3
  262. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +58 -19
  263. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +96 -5
  264. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +15 -0
  265. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +9 -1
  266. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -2
  267. data/lib/hecks/ports/persistence/plugins/era.rb +12 -2
  268. data/lib/hecks/ports/persistence/remote_runtime.rb +9 -2
  269. data/lib/hecks/ports/persistence/repository_factory.rb +23 -3
  270. data/lib/hecks/ports/persistence/state_codec.rb +319 -0
  271. data/lib/hecks/ports/persistence.rb +36 -1
  272. data/lib/hecks/ports/projection.rb +61 -7
  273. data/lib/hecks/ports/query/in_memory.rb +41 -8
  274. data/lib/hecks/ports/query/ordering.rb +21 -6
  275. data/lib/hecks/ports/query.rb +35 -0
  276. data/lib/hecks/ports.rb +1 -0
  277. data/lib/hecks/projections/bootstrap_table.rb +147 -0
  278. data/lib/hecks/projections/diagrams.rb +315 -79
  279. data/lib/hecks/projections/glossary/html.rb +91 -3
  280. data/lib/hecks/projections/glossary/markdown.rb +50 -3
  281. data/lib/hecks/projections/glossary/mermaid.rb +49 -1
  282. data/lib/hecks/projections/glossary/sections.rb +1 -1
  283. data/lib/hecks/projections/glossary/sentences.rb +110 -5
  284. data/lib/hecks/projections/glossary.rb +173 -31
  285. data/lib/hecks/projections/ir.rb +1 -1
  286. data/lib/hecks/projections/model/deviations.rb +62 -17
  287. data/lib/hecks/projections/model.rb +75 -21
  288. data/lib/hecks/projections/oidc.rb +45 -8
  289. data/lib/hecks/projections/parser_table.rb +53 -12
  290. data/lib/hecks/projections/reference.rb +15 -3
  291. data/lib/hecks/projections/rust_vocabulary.rb +646 -0
  292. data/lib/hecks/projections/shape.rb +10 -2
  293. data/lib/hecks/projections/statements.rb +69 -22
  294. data/lib/hecks/projections/vocabulary.rb +26 -9
  295. data/lib/hecks/projections.rb +5 -3
  296. data/lib/hecks/projector/cli_projector.rb +245 -37
  297. data/lib/hecks/projector/docs_projector.rb +154 -28
  298. data/lib/hecks/projector/exporter.rb +104 -29
  299. data/lib/hecks/projector/ir_projector.rb +7 -1
  300. data/lib/hecks/projector/narrate_projector.rb +144 -23
  301. data/lib/hecks/projector/target.rb +42 -18
  302. data/lib/hecks/projector.rb +86 -18
  303. data/lib/hecks/query_ir.rb +94 -47
  304. data/lib/hecks/query_specification/common/comparators.rb +19 -3
  305. data/lib/hecks/query_specification/common/comparison.rb +109 -27
  306. data/lib/hecks/query_specification/common/dsl.rb +65 -9
  307. data/lib/hecks/query_specification/common/null_policy.rb +61 -15
  308. data/lib/hecks/query_specification/common/null_semantics.rb +4 -0
  309. data/lib/hecks/query_specification/common/options.rb +25 -0
  310. data/lib/hecks/query_specification/field_path.rb +69 -15
  311. data/lib/hecks/query_specification/hop_path.rb +57 -20
  312. data/lib/hecks/query_specification/read_model/specification.rb +4 -0
  313. data/lib/hecks/rendering.rb +9 -3
  314. data/lib/hecks/router/namespace_installer.rb +16 -3
  315. data/lib/hecks/router.rb +56 -1
  316. data/lib/hecks/runtime/aggregate_lock.rb +20 -11
  317. data/lib/hecks/runtime/boot_gates.rb +21 -3
  318. data/lib/hecks/runtime/caller.rb +40 -8
  319. data/lib/hecks/runtime/capability_graph.rb +13 -2
  320. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +40 -41
  321. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +45 -67
  322. data/lib/hecks/runtime/command_interpreter.rb +195 -113
  323. data/lib/hecks/runtime/command_rules/admissibility.rb +231 -80
  324. data/lib/hecks/runtime/command_rules/arithmetic.rb +154 -96
  325. data/lib/hecks/runtime/command_rules/authorization.rb +38 -17
  326. data/lib/hecks/runtime/command_rules/emission.rb +18 -1
  327. data/lib/hecks/runtime/command_rules/references.rb +145 -55
  328. data/lib/hecks/runtime/command_rules.rb +3 -0
  329. data/lib/hecks/runtime/dependency_planning.rb +56 -11
  330. data/lib/hecks/runtime/dispatcher.rb +263 -92
  331. data/lib/hecks/runtime/entity_element.rb +304 -67
  332. data/lib/hecks/runtime/entity_interpreter.rb +149 -88
  333. data/lib/hecks/runtime/errors.rb +37 -23
  334. data/lib/hecks/runtime/event.rb +15 -10
  335. data/lib/hecks/runtime/identity.rb +91 -23
  336. data/lib/hecks/runtime/instance.rb +103 -18
  337. data/lib/hecks/runtime/interpreting.rb +24 -16
  338. data/lib/hecks/runtime/invocation.rb +358 -0
  339. data/lib/hecks/runtime/loader.rb +105 -19
  340. data/lib/hecks/runtime/outbox.rb +164 -26
  341. data/lib/hecks/runtime/policy_interpreter.rb +73 -60
  342. data/lib/hecks/runtime/port_operation_interpreter.rb +42 -19
  343. data/lib/hecks/runtime/query_interpreter.rb +93 -74
  344. data/lib/hecks/runtime/reaction_invocation.rb +73 -28
  345. data/lib/hecks/runtime/read_model_interpreter.rb +60 -44
  346. data/lib/hecks/runtime/rebuild_sweep.rb +32 -4
  347. data/lib/hecks/runtime/reference_hop.rb +48 -6
  348. data/lib/hecks/runtime/refusal_wording.rb +142 -115
  349. data/lib/hecks/runtime/registry/saga_persistence.rb +32 -21
  350. data/lib/hecks/runtime/registry/verification.rb +153 -28
  351. data/lib/hecks/runtime/registry.rb +202 -32
  352. data/lib/hecks/runtime/remote_dispatcher.rb +125 -24
  353. data/lib/hecks/runtime/routing.rb +36 -154
  354. data/lib/hecks/runtime/saga_interpreter/correlation.rb +25 -27
  355. data/lib/hecks/runtime/saga_interpreter.rb +90 -76
  356. data/lib/hecks/runtime/saga_pending_dispatch.rb +12 -12
  357. data/lib/hecks/runtime/tenant_check.rb +33 -13
  358. data/lib/hecks/runtime/tenant_scope.rb +23 -5
  359. data/lib/hecks/runtime/value/admission.rb +75 -30
  360. data/lib/hecks/runtime/value/coercion.rb +555 -142
  361. data/lib/hecks/runtime/value/entity_list_coercion.rb +132 -60
  362. data/lib/hecks/runtime/value.rb +71 -21
  363. data/lib/hecks/runtime.rb +39 -7
  364. data/lib/hecks/storehouse.rb +368 -72
  365. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +130 -0
  366. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +32 -0
  367. data/lib/hecks/version.rb +3 -3
  368. data/lib/hecks/vocabulary.rb +205 -4
  369. data/lib/hecks.rb +91 -11
  370. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +19 -11
  371. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +24 -12
  372. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +38 -14
  373. metadata +28 -2
@@ -7,7 +7,7 @@ module Hecks
7
7
  # builder collecting every `aggregate`/`read_model`/`policy`/
8
8
  # `process_manager` a chapter declares, plus the chapter-wide named-
9
9
  # given pools those thread down into (see `#aggregate_impl`'s own
10
- # comment). `.build` reuses the SAME open builder instance across
10
+ # comment). `.build` reuses the same open builder instance across
11
11
  # several files sharing one chapter name (`self.build`'s own comment),
12
12
  # so a chapter split across files accumulates rather than each file
13
13
  # silently replacing the last.
@@ -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
@@ -26,19 +28,19 @@ module Hecks
26
28
  @read_models = []
27
29
  @policies = []
28
30
  @process_managers = []
29
- # THE ROOT of the CHAPTER-WIDE given pool — one level wider
31
+ # The root of the chapter-wide given pool — one level wider
30
32
  # than `AggregateBuilder`'s own `@entity_named_givens` (S10
31
33
  # extended across an aggregate's whole entity tree, earlier
32
34
  # this arc). See `#given`'s own comment for what this closes.
33
35
  @chapter_named_givens = {}
34
- # EVERY BARE CHAPTER-GIVEN REFERENCE THIS CHAPTER'S OWN FILES
35
- # LEFT UNRESOLVED SO FAR — threaded into every aggregate the
36
+ # Every bare chapter-given reference this chapter's own files
37
+ # left unresolved so far — threaded into every aggregate the
36
38
  # same way `@chapter_named_givens` is. See
37
39
  # `AggregateBuilder#pending_chapter_given`'s own comment for
38
40
  # what queues here and `#resolve_pending_chapter_givens!`,
39
41
  # below, for where it drains.
40
42
  @chapter_pending_givens = []
41
- # ONE LEVEL WIDER STILL — the CHAPTER-WIDE, ENTITY-SCOPED pool
43
+ # **One level wider still** — the chapter-wide, entity-scoped pool
42
44
  # (the piece analogue of `@chapter_named_givens`, above). See
43
45
  # `EntityBuilder#given_impl`'s own comment for what this
44
46
  # closes; `docs/implemented/resolution-rules/
@@ -62,46 +64,105 @@ 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
 
76
- # A SUB-LANGUAGE NAMES WHERE IT LANDS. ADR 0026's own seam: the core
85
+ # Names a core grammar context this chapter's sub-language extends.
86
+ #
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
- # ITSELF onto them instead — the core contexts (e.g. "Query",
89
+ # itself onto them instead — the core contexts (e.g. "Query",
79
90
  # "ReadModel") whose own admitted words this chapter's `Syntax`
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
+ #
106
+ # A capability this chapter answers for other domains, declared so
107
+ # nothing has to recognise the chapter by name — Governance's
108
+ # `provides "authorization", assignments: ..., grant: ...,
109
+ # transitions: ...`. One row per key, in the order written; what
110
+ # each capability requires is checked once the chapter is whole
111
+ # (`Validation#validate_provisions!`), since the verbs it names may
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
120
+ def provides_impl(capability, **verbs)
121
+ if verbs.empty?
122
+ raise Malformed, "#{@name}'s provides #{capability.inspect} names no verb — say which of this " \
123
+ "chapter's commands and queries answer it"
124
+ end
125
+
126
+ rows = verbs.map { |key, verb| Chapter::Provision.new(capability: capability.to_s, key: key.to_s, verb: verb.to_s) }
127
+ (@provides ||= []).concat(rows)
128
+ end
129
+
130
+ # Classifies this chapter as core to the framework, rather than a domain built on it.
131
+ #
132
+ # @return [Symbol] `:core`
89
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`
90
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`
91
144
  def generic = @classification = :generic
92
145
 
146
+ # Declares an aggregate belonging to this chapter.
147
+ #
93
148
  # `@chapter_named_givens` is threaded into every aggregate this
94
149
  # chapter builds — see `AggregateBuilder#given`'s own comment
95
- # for the sharing this enables; NOT a new top-level DSL word
96
- # itself (an aggregate's own EXISTING `given` already both
150
+ # for the sharing this enables; not a new top-level DSL word
151
+ # itself (an aggregate's own existing `given` already both
97
152
  # declares locally and write-throughs here as a side effect,
98
153
  # the identical shape `EntityBuilder#given`'s own write-through
99
154
  # to its owner aggregate's pool already takes — no new spelling
100
155
  # for "declare a precondition," one level wider, same word).
101
- # RENAMED FROM `aggregate` — item #13's full metaprogrammed
102
- # dispatch (slice 4c). Bootstrap-reachable (every core/attached
103
- # chapter's own top-level shape is written with it), so also
104
- # 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
105
166
  def aggregate_impl(name, &)
106
167
  @aggregates << AggregateBuilder.build(name, chapter_named_givens: @chapter_named_givens,
107
168
  chapter_pending_givens: @chapter_pending_givens,
@@ -109,6 +170,8 @@ module Hecks
109
170
  chapter_entity_pending_givens: @chapter_entity_pending_givens, &)
110
171
  end
111
172
 
173
+ # Declares a read model belonging to this chapter.
174
+ #
112
175
  # `read_model` is the word (ADR 0025 reverts `report` — the IR
113
176
  # construct, the registry API, and the docs filename all said
114
177
  # `read_model` the whole time; no era was ever minted under
@@ -117,30 +180,65 @@ module Hecks
117
180
  # bridge) for the same reason `has_many` does — frozen era text
118
181
  # that used it must keep booting; live source refuses it, naming
119
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
120
189
  def read_model(name, &)
121
- # A read model gathers heads from SEVERAL aggregates, so no single head
190
+ # A read model gathers heads from several aggregates, so no single head
122
191
  # declares it — the chapter does. Its owner is stamped in `build`, where
123
192
  # the chapter namespace exists.
124
193
  @read_models << ReadModelBuilder.build(name, &)
125
194
  end
126
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
127
204
  def report(name, &)
128
205
  return read_model(name, &) if MetaValidator.shadow_parsing?
129
206
 
130
207
  raise Malformed, "report is gone — read_model is the word now"
131
208
  end
132
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
133
216
  def policy(name, &)
134
217
  @policies << PolicyBuilder.build(name, &)
135
218
  end
136
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
137
226
  def process_manager(name, &)
138
227
  @process_managers << ProcessManagerBuilder.build(name, &)
139
228
  end
140
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
141
239
  def build
142
240
  # The chapter is the top of the construct chain — `Bluebook` is a
143
- # ROOT, and its constructor stamps every aggregate and read model with
241
+ # root, and its constructor stamps every aggregate and read model with
144
242
  # itself as owner, so every `hecks_fqn` below resolves by walking up
145
243
  # to it. No constants are installed at load time : the public door is
146
244
  # a per-boot projection, installed by `Loader.bind_runtime` once a
@@ -152,25 +250,26 @@ module Hecks
152
250
  process_managers: @process_managers,
153
251
  classification: @classification,
154
252
  formerly_known_as: @formerly_known_as,
155
- attaches_to: @attaches_to || [])
253
+ attaches_to: @attaches_to || [],
254
+ provides: @provides || [])
156
255
 
157
- # SAME REASON, SAME GATE — a bare chapter-given may still be
256
+ # **Same reason, same gate** — a bare chapter-given may still be
158
257
  # pending (see `AggregateBuilder#pending_chapter_given`) if a
159
258
  # file that would resolve it hasn't loaded yet; resolving now
160
259
  # would see the same incomplete `@chapter_named_givens`
161
260
  # `validate_assembled!` below would. Deferred to
162
- # `MetaValidator.judge_deferred!` the same way, and BEFORE
261
+ # `MetaValidator.judge_deferred!` the same way, and before
163
262
  # `validate_assembled!` there — nothing downstream should ever
164
263
  # read an unresolved placeholder's fields.
165
264
  resolve_pending_chapter_givens! unless MetaValidator.deferring?
166
265
  resolve_pending_chapter_entity_givens! unless MetaValidator.deferring?
167
266
 
168
- # A CHAPTER MAY BE SPLIT ACROSS FILES (see `self.build`'s own
169
- # comment). Every check below needs the WHOLE chapter present —
267
+ # A chapter may be split across files (see `self.build`'s own
268
+ # comment). Every check below needs the whole chapter present —
170
269
  # a hop, a projection, a correlation key or an event shape can
171
270
  # equally name a construct declared in a file that has not
172
271
  # loaded yet, and `@aggregates`/`@process_managers` here are
173
- # only ever as complete as whatever has loaded SO FAR. So,
272
+ # only ever as complete as whatever has loaded so far. So,
174
273
  # exactly like `MetaValidator.call` below, this is skipped
175
274
  # while `MetaValidator.defer` is loading the chapter's files
176
275
  # and run once instead — by `MetaValidator.judge_deferred!`,
@@ -187,17 +286,17 @@ module Hecks
187
286
  MetaValidator.call(bluebook)
188
287
  end
189
288
 
190
- # THE OTHER HALF OF A CHAPTER-WIDE `given` REFERENCE —
289
+ # The other half of a chapter-wide `given` reference —
191
290
  # `AggregateBuilder#pending_chapter_given` recognised an
192
291
  # unresolved bare reference and deferred it here, unable to
193
- # check further: a later file in this SAME chapter might still
292
+ # check further: a later file in this same chapter might still
194
293
  # declare the real thing. Runs once every file has loaded,
195
294
  # against the now-complete `@chapter_named_givens` pool — the
196
- # IDENTICAL lookup `reference_named_chapter_given` already does,
295
+ # identical lookup `reference_named_chapter_given` already does,
197
296
  # just late enough to see every aggregate's own declarations,
198
297
  # not only the ones loaded before the referencing one.
199
298
  #
200
- # MUTATES each placeholder `Given` IN PLACE rather than
299
+ # Mutates each placeholder `Given` in place rather than
201
300
  # replacing it — it is already embedded, by Ruby object
202
301
  # reference, in the referencing aggregate's own `preconditions`
203
302
  # and in any command (same aggregate) that separately
@@ -208,6 +307,12 @@ module Hecks
208
307
  # which only exists on the builder instance still open for this
209
308
  # chapter (`MetaValidator.judge_deferred!` reaches it via
210
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
211
316
  def resolve_pending_chapter_givens!
212
317
  @chapter_pending_givens.each do |entry|
213
318
  resolved = resolve_pending_chapter_given(entry)
@@ -247,9 +352,15 @@ module Hecks
247
352
  end
248
353
  private :resolve_pending_chapter_given
249
354
 
250
- # THE ENTITY-SCOPED ANALOGUE, one level down — see
355
+ # The entity-scoped analogue, one level down — see
251
356
  # `#resolve_pending_chapter_givens!`'s own comment; identical
252
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
253
364
  def resolve_pending_chapter_entity_givens!
254
365
  @chapter_entity_pending_givens.each do |entry|
255
366
  resolved = resolve_pending_chapter_entity_given(entry)
@@ -289,34 +400,55 @@ module Hecks
289
400
  end
290
401
  private :resolve_pending_chapter_entity_given
291
402
 
292
- # A CHAPTER MAY BE DECLARED IN SEVERAL FILES, meant to merge into ONE
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
+ #
406
+ # A chapter may be declared in several files, meant to merge into one
293
407
  # domain — `lib/hecks/language/bluebook/*.bluebook` all open
294
- # `Hecks.bluebook "Bluebook" do ... end`. Each `Hecks.bluebook` call used to
295
- # mint a fresh builder, so a second file with the same chapter name
296
- # 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.
297
413
  #
298
- # The registry now holds the builder OPEN across calls : the first file
299
- # for a name creates it, every later file for the same name reuses the
300
- # same instance, so `@aggregates`/`@read_models` accumulate. `#build` is
301
- # 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
302
416
  # `Bluebook` from whatever is currently held and re-`Namespace.install`s
303
- # over the previous one, so the LAST file's call leaves every aggregate
417
+ # over the previous one, so the last file's call leaves every aggregate
304
418
  # seen so far reachable, and each call's IR is a strict superset of the
305
419
  # one before. `Registry#add_bluebook` still simply stores by name — with
306
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
307
432
  def self.build(name, version: nil, &block)
308
433
  registry = Hecks.current_registry
309
- 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)
310
441
  builder.__send__(:adopt_version, version)
311
- # A bare constant in a bluebook — `attribute :name, PizzaName` — is a NAME,
442
+ # A bare constant in a bluebook — `attribute :name, PizzaName` — is a name,
312
443
  # not a reference to something Ruby has heard of. `const_missing` hands
313
444
  # over a `ConstShim::ScopedConstant` (S0b, const_shim.rb's own comment),
314
445
  # and that is still the whole answer for a bare name: `Attribute` spells
315
- # it with `to_s`, so the `TypeName` wrapper this used to build existed
316
- # 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
317
449
  # language declares `value_object "TypeName"` — it just needed no Ruby
318
450
  # class of its own. A Module rather than a Symbol is what also lets
319
- # `Account::Debit`/`admits: Account::LedgerDirection` answer their OWN
451
+ # `Account::Debit`/`admits: Account::LedgerDirection` answer their own
320
452
  # `::` — a plain Symbol cannot.
321
453
  resolver = ->(const) { ConstShim::ScopedConstant.for(const) }
322
454
  ConstShim.with(resolver) { builder.instance_eval(&block) } if block
@@ -0,0 +1,116 @@
1
+ # Generated — projected from the language's own Keyword rows (the
2
+ # `calls:`, `resolves_via:` and `disambiguator:` columns of every
3
+ # KeywordSeed under lib/hecks/language/).
4
+ #
5
+ # Do not edit. spec/bootstrap_table_spec.rb re-projects this in memory
6
+ # and refuses a diff — run bin/project_bootstrap_table instead.
7
+ #
8
+ # Plain data, no requires: this is read while the grammar table it was
9
+ # projected from is still being built (`MetaValidator.bootstrapping?`).
10
+
11
+ module Hecks
12
+ module Bluebook
13
+ module DSL
14
+ module BootstrapTable
15
+ # [context, word] => the method a word's whole call forwards to.
16
+ CALLS = {
17
+ ["Aggregate", "provenance"] => :provenance_impl,
18
+ ["Aggregate", "identified_by"] => :identified_by_impl,
19
+ ["Aggregate", "reference_to"] => :reference_to_impl,
20
+ ["Aggregate", "has_many"] => :has_many_impl,
21
+ ["Aggregate", "has_one"] => :has_one_impl,
22
+ ["Aggregate", "belongs_to"] => :belongs_to_impl,
23
+ ["Aggregate", "lifecycle"] => :lifecycle_impl,
24
+ ["Aggregate", "entity"] => :entity_impl,
25
+ ["Aggregate", "query"] => :query_impl,
26
+ ["Aggregate", "policy"] => :policy_impl,
27
+ ["Aggregate", "command"] => :command_impl,
28
+ ["Aggregate", "attribute"] => :attribute_impl,
29
+ ["Aggregate", "invariant"] => :invariant_impl,
30
+ ["Aggregate", "given"] => :given_impl,
31
+ ["Aggregate", "projects"] => :projects_impl,
32
+ ["Lifecycle", "transition"] => :transition_impl,
33
+ ["Bluebook", "attaches_to"] => :attaches_to_impl,
34
+ ["Bluebook", "provides"] => :provides_impl,
35
+ ["Bluebook", "aggregate"] => :aggregate_impl,
36
+ ["Command", "role"] => :role_impl,
37
+ ["Command", "provenance"] => :provenance_impl,
38
+ ["Command", "reference_to"] => :reference_to_impl,
39
+ ["Command", "given"] => :given_impl,
40
+ ["Command", "sets"] => :sets_impl,
41
+ ["Command", "then_set"] => :then_set_impl,
42
+ ["Command", "delegates_to"] => :delegates_to_impl,
43
+ ["Command", "attribute"] => :attribute_impl,
44
+ ["Command", "corrects"] => :corrects_impl,
45
+ ["Entity", "identified_by"] => :identified_by_impl,
46
+ ["Entity", "given"] => :given_impl,
47
+ ["Entity", "invariant"] => :invariant_impl,
48
+ ["Entity", "command"] => :command_impl,
49
+ ["Entity", "query"] => :query_impl,
50
+ ["Entity", "lifecycle"] => :lifecycle_impl,
51
+ ["Entity", "attribute"] => :attribute_impl,
52
+ ["Entity", "reference_to"] => :reference_to_impl,
53
+ ["Entity", "has_many"] => :has_many_impl,
54
+ ["Entity", "has_one"] => :has_one_impl,
55
+ ["Entity", "belongs_to"] => :belongs_to_impl,
56
+ ["Entity", "entity"] => :entity_impl,
57
+ ["Policy", "on"] => :on_impl,
58
+ ["Policy", "trigger"] => :trigger_impl,
59
+ ["Policy", "across"] => :across_impl,
60
+ ["ProcessManager", "starts_on"] => :starts_on_impl,
61
+ ["ProcessManager", "ends_on"] => :ends_on_impl,
62
+ ["ProcessManager", "transition"] => :transition_impl,
63
+ ["Handler", "dispatch"] => :dispatch_impl,
64
+ ["Dispatch", "compensates"] => :compensates_impl,
65
+ ["ReadModel", "reference_to"] => :reference_to_impl,
66
+ ["ReadModel", "include"] => :include_impl,
67
+ ["ReadModel", "group_by"] => :group_by_impl,
68
+ ["ReadModel", "where"] => :where_impl,
69
+ ["ReadModel", "order_by"] => :order_by_impl,
70
+ ["ReadModel", "authorize"] => :authorize_impl,
71
+ ["Query", "attribute"] => :attribute_impl,
72
+ ["Query", "reference_to"] => :reference_to_impl,
73
+ ["Query", "where"] => :where_impl,
74
+ ["Query", "order_by"] => :order_by_impl,
75
+ ["Query", "authorize"] => :authorize_impl,
76
+ ["ValueObject", "attribute"] => :attribute_impl,
77
+ ["ValueObject", "one_of"] => :one_of_impl,
78
+ ["ValueObject", "invariant"] => :invariant_impl,
79
+ ["ValueObject", "member"] => :member_impl,
80
+ ["OneOf", "member"] => :member_impl,
81
+ ["Type", "list_of"] => :list_of_impl,
82
+ ["Type", "one_of"] => :one_of_impl,
83
+ ["World", "realm"] => :realm_impl,
84
+ ["World", "latest"] => :latest_impl,
85
+ ["DomainPort", "operation"] => :tells_impl,
86
+ ["DomainPort", "tells"] => :tells_impl,
87
+ ["DomainPort", "asks"] => :asks_impl,
88
+ ["Hecksagon", "port"] => :port_impl,
89
+ ["PortOperation", "reference_to"] => :reference_to_impl,
90
+ ["PortOperation", "attribute"] => :attribute_impl,
91
+ ["Translation", "aggregate"] => :aggregate_impl,
92
+ ["TranslationAggregate", "rename"] => :rename_impl,
93
+ ["TranslationAggregate", "move"] => :move_impl,
94
+ ["TranslationAggregate", "convert"] => :convert_impl,
95
+ ["TranslationAggregate", "retype"] => :retype_impl,
96
+ ["TranslationAggregate", "compute"] => :compute_impl,
97
+ ["TranslationAggregate", "rekey"] => :rekey_impl,
98
+ ["TranslationAggregate", "backfill"] => :backfill_impl,
99
+ ["TranslationAggregate", "unresolved"] => :unresolved_impl,
100
+ ["Query", "limit"] => :limit_impl,
101
+ ["Query", "offset"] => :offset_impl,
102
+ ["ReadModel", "limit"] => :limit_impl,
103
+ ["ReadModel", "offset"] => :offset_impl
104
+ }.freeze
105
+
106
+ # [word, context] => the RuleReference primitive a bare reference resolves through.
107
+ RESOLVES = {
108
+ ["given", "Aggregate"] => { resolves_via: "owner_keyed", disambiguator: "declared_by" }.freeze,
109
+ ["given", "Command"] => { resolves_via: "hash_chain" }.freeze,
110
+ ["given", "Entity"] => { resolves_via: "owner_keyed", disambiguator: "declared_by" }.freeze,
111
+ ["invariant", "ValueObject"] => { resolves_via: "sibling_scan" }.freeze
112
+ }.freeze
113
+ end
114
+ end
115
+ end
116
+ end