hecks 1.3.0 → 1.4.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 (355) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hecks/adapters/driven/claude_code.rb +7 -7
  3. data/lib/hecks/adapters/driven/d1.rb +187 -23
  4. data/lib/hecks/adapters/driven/folder.rb +10 -10
  5. data/lib/hecks/adapters/driven/google_authentication.rb +8 -8
  6. data/lib/hecks/adapters/driven/governance_authorization.rb +31 -13
  7. data/lib/hecks/adapters/driven/heki/journal.rb +5 -4
  8. data/lib/hecks/adapters/driven/heki/saga_store.rb +5 -5
  9. data/lib/hecks/adapters/driven/heki.rb +13 -7
  10. data/lib/hecks/adapters/driven/identity_registry.rb +2 -2
  11. data/lib/hecks/adapters/driven/in_memory_ordering.rb +3 -3
  12. data/lib/hecks/adapters/driven/lambda/client.rb +34 -9
  13. data/lib/hecks/adapters/driven/lambda.rb +39 -33
  14. data/lib/hecks/adapters/driven/local_storage.rb +17 -10
  15. data/lib/hecks/adapters/driven/memory.rb +205 -9
  16. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +1 -1
  17. data/lib/hecks/adapters/driven/postgres/codec.rb +27 -11
  18. data/lib/hecks/adapters/driven/postgres/outbox.rb +40 -2
  19. data/lib/hecks/adapters/driven/postgres/reconnect.rb +23 -7
  20. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +14 -14
  21. data/lib/hecks/adapters/driven/postgres.rb +175 -28
  22. data/lib/hecks/adapters/driven/prism.rb +4 -4
  23. data/lib/hecks/adapters/driven/sql_query_builder.rb +34 -22
  24. data/lib/hecks/adapters/driven/sqlite/codec.rb +38 -10
  25. data/lib/hecks/adapters/driven/sqlite/projection.rb +60 -32
  26. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +12 -12
  27. data/lib/hecks/adapters/driven/sqlite.rb +181 -21
  28. data/lib/hecks/adapters/driven.rb +4 -4
  29. data/lib/hecks/adapters/driving/github_webhook.rb +18 -18
  30. data/lib/hecks/behaviors/dsl.rb +2 -2
  31. data/lib/hecks/behaviors/expectations.rb +23 -23
  32. data/lib/hecks/behaviors/ir.rb +1 -1
  33. data/lib/hecks/behaviors/rspec.rb +1 -1
  34. data/lib/hecks/behaviors/runner.rb +2 -2
  35. data/lib/hecks/behaviors.rb +1 -1
  36. data/lib/hecks/bluebook/aggregate.rb +13 -13
  37. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +10 -10
  38. data/lib/hecks/bluebook/assembly/build.rb +1 -1
  39. data/lib/hecks/bluebook/assembly/contract.rb +39 -16
  40. data/lib/hecks/bluebook/assembly/contracts.rb +40 -38
  41. data/lib/hecks/bluebook/assembly/marks.rb +18 -18
  42. data/lib/hecks/bluebook/assembly/specializer.rb +19 -21
  43. data/lib/hecks/bluebook/assembly.rb +9 -9
  44. data/lib/hecks/bluebook/attribute.rb +9 -9
  45. data/lib/hecks/bluebook/behaviour/aggregate.rb +11 -11
  46. data/lib/hecks/bluebook/behaviour/attribute.rb +5 -5
  47. data/lib/hecks/bluebook/behaviour/chapter.rb +23 -5
  48. data/lib/hecks/bluebook/behaviour/command.rb +23 -23
  49. data/lib/hecks/bluebook/behaviour/domain_port.rb +7 -7
  50. data/lib/hecks/bluebook/behaviour/entity.rb +8 -8
  51. data/lib/hecks/bluebook/behaviour/hexagon.rb +4 -4
  52. data/lib/hecks/bluebook/behaviour/lifecycle.rb +5 -5
  53. data/lib/hecks/bluebook/behaviour/policy.rb +12 -12
  54. data/lib/hecks/bluebook/behaviour/process_manager.rb +7 -7
  55. data/lib/hecks/bluebook/behaviour/query.rb +1 -1
  56. data/lib/hecks/bluebook/behaviour/read_model.rb +8 -8
  57. data/lib/hecks/bluebook/behaviour/traits.rb +12 -12
  58. data/lib/hecks/bluebook/behaviour/value_object.rb +6 -6
  59. data/lib/hecks/bluebook/capabilities.rb +27 -0
  60. data/lib/hecks/bluebook/chapter.rb +28 -9
  61. data/lib/hecks/bluebook/command.rb +12 -12
  62. data/lib/hecks/bluebook/domain_port.rb +9 -9
  63. data/lib/hecks/bluebook/dsl/adapter_builder.rb +24 -0
  64. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +49 -49
  65. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +96 -96
  66. data/lib/hecks/bluebook/dsl/attribute_collector.rb +41 -41
  67. data/lib/hecks/bluebook/dsl/binding_proxy.rb +22 -2
  68. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +111 -74
  69. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +48 -30
  70. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +116 -0
  71. data/lib/hecks/bluebook/dsl/command_builder.rb +103 -103
  72. data/lib/hecks/bluebook/dsl/const_shim.rb +46 -15
  73. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +90 -25
  74. data/lib/hecks/bluebook/dsl/entity_builder.rb +56 -56
  75. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +148 -132
  76. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +89 -30
  77. data/lib/hecks/bluebook/dsl/identity_declaration.rb +17 -17
  78. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +27 -4
  79. data/lib/hecks/bluebook/dsl/policy_builder.rb +30 -21
  80. data/lib/hecks/bluebook/dsl/port_builder.rb +38 -7
  81. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +56 -22
  82. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +35 -35
  83. data/lib/hecks/bluebook/dsl/query_builder.rb +5 -5
  84. data/lib/hecks/bluebook/dsl/read_model_builder.rb +34 -34
  85. data/lib/hecks/bluebook/dsl/rule_reference.rb +41 -39
  86. data/lib/hecks/bluebook/dsl/translation_builder.rb +9 -9
  87. data/lib/hecks/bluebook/dsl/value_object_builder.rb +16 -16
  88. data/lib/hecks/bluebook/dsl/word_gate.rb +59 -53
  89. data/lib/hecks/bluebook/dsl/world_builder.rb +51 -8
  90. data/lib/hecks/bluebook/entity.rb +11 -11
  91. data/lib/hecks/bluebook/expression/ast_json.rb +20 -20
  92. data/lib/hecks/bluebook/expression/ast_reader.rb +3 -3
  93. data/lib/hecks/bluebook/expression/canonical_form.rb +9 -9
  94. data/lib/hecks/bluebook/expression/evaluator.rb +18 -18
  95. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +18 -18
  96. data/lib/hecks/bluebook/expression/resolver.rb +60 -62
  97. data/lib/hecks/bluebook/hexagon.rb +1 -1
  98. data/lib/hecks/bluebook/lifecycle.rb +1 -1
  99. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -1
  100. data/lib/hecks/bluebook/meta_validator/judge.rb +101 -87
  101. data/lib/hecks/bluebook/meta_validator/plan.rb +39 -39
  102. data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -2
  103. data/lib/hecks/bluebook/meta_validator/readings.rb +43 -43
  104. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +44 -37
  105. data/lib/hecks/bluebook/meta_validator/shapes.rb +25 -21
  106. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +145 -31
  107. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +6 -6
  108. data/lib/hecks/bluebook/meta_validator/world_judge.rb +5 -5
  109. data/lib/hecks/bluebook/meta_validator.rb +70 -70
  110. data/lib/hecks/bluebook/model_check.rb +170 -84
  111. data/lib/hecks/bluebook/pattern_subset.rb +9 -9
  112. data/lib/hecks/bluebook/policy.rb +15 -13
  113. data/lib/hecks/bluebook/process_manager.rb +14 -14
  114. data/lib/hecks/bluebook/project_register.rb +6 -6
  115. data/lib/hecks/bluebook/query.rb +4 -4
  116. data/lib/hecks/bluebook/read_model.rb +14 -14
  117. data/lib/hecks/bluebook/reference.rb +8 -8
  118. data/lib/hecks/bluebook/smoke_test.rb +19 -19
  119. data/lib/hecks/bluebook/synthesizer.rb +12 -12
  120. data/lib/hecks/bluebook/translation.rb +4 -4
  121. data/lib/hecks/bluebook/value_object.rb +6 -6
  122. data/lib/hecks/bluebook.rb +2 -2
  123. data/lib/hecks/codemod/legacy_dispatch_args.rb +299 -0
  124. data/lib/hecks/codemod/legacy_dispatch_recorder.rb +186 -0
  125. data/lib/hecks/codemod.rb +36 -35
  126. data/lib/hecks/construct.rb +6 -6
  127. data/lib/hecks/corpus.rb +317 -0
  128. data/lib/hecks/deprecation.rb +95 -0
  129. data/lib/hecks/doc/reference.rb +19 -19
  130. data/lib/hecks/embryonaut_bluebook.rb +11 -11
  131. data/lib/hecks/facade/cli_door.rb +69 -10
  132. data/lib/hecks/facade/cli_runner.rb +105 -24
  133. data/lib/hecks/facade/command_request.rb +23 -0
  134. data/lib/hecks/facade/handle.rb +79 -32
  135. data/lib/hecks/facade/json_door.rb +106 -25
  136. data/lib/hecks/facade/surface/aggregate_door.rb +42 -27
  137. data/lib/hecks/facade/surface/chapter.rb +26 -17
  138. data/lib/hecks/facade/surface.rb +16 -3
  139. data/lib/hecks/facade.rb +15 -4
  140. data/lib/hecks/forms/app.rb +46 -30
  141. data/lib/hecks/forms/command_form_renderer.rb +70 -9
  142. data/lib/hecks/forms/field_renderer.rb +142 -6
  143. data/lib/hecks/forms/field_shape.rb +180 -19
  144. data/lib/hecks/forms/html.rb +51 -7
  145. data/lib/hecks/forms/index_renderer.rb +14 -2
  146. data/lib/hecks/forms/params.rb +120 -23
  147. data/lib/hecks/forms/port_argument.rb +2 -2
  148. data/lib/hecks/forms/query_form_renderer.rb +2 -2
  149. data/lib/hecks/forms/record_renderer.rb +2 -2
  150. data/lib/hecks/forms/record_table.rb +1 -1
  151. data/lib/hecks/forms/value_object_shape.rb +3 -3
  152. data/lib/hecks/forms.rb +24 -4
  153. data/lib/hecks/fqn.rb +1 -1
  154. data/lib/hecks/framework/bluebook/governance.bluebook +9 -0
  155. data/lib/hecks/framework.rb +48 -17
  156. data/lib/hecks/freezer.rb +11 -11
  157. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +90 -90
  158. data/lib/hecks/fuzzing/combination_miner.rb +119 -0
  159. data/lib/hecks/fuzzing/concurrent_dispatch.rb +140 -45
  160. data/lib/hecks/fuzzing/coverage_campaign.rb +118 -0
  161. data/lib/hecks/fuzzing/differential.rb +158 -0
  162. data/lib/hecks/fuzzing/domain_generator.rb +694 -0
  163. data/lib/hecks/fuzzing/era_boundary.rb +37 -18
  164. data/lib/hecks/fuzzing/form_census.rb +35 -20
  165. data/lib/hecks/fuzzing/generated_domain_check.rb +95 -0
  166. data/lib/hecks/fuzzing/invalid_value_generator.rb +6 -6
  167. data/lib/hecks/fuzzing/isolated_boot.rb +62 -62
  168. data/lib/hecks/fuzzing/nondeterministic.rb +67 -0
  169. data/lib/hecks/fuzzing/persistence_parity.rb +19 -21
  170. data/lib/hecks/fuzzing/properties/corrections.rb +9 -9
  171. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +154 -49
  172. data/lib/hecks/fuzzing/properties/guards.rb +42 -42
  173. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +32 -32
  174. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +22 -35
  175. data/lib/hecks/fuzzing/properties/outbox.rb +24 -24
  176. data/lib/hecks/fuzzing/properties/querying.rb +17 -17
  177. data/lib/hecks/fuzzing/properties.rb +64 -40
  178. data/lib/hecks/fuzzing/qa_settings.rb +152 -0
  179. data/lib/hecks/fuzzing/replay.rb +114 -114
  180. data/lib/hecks/fuzzing/rotation_priority.rb +10 -10
  181. data/lib/hecks/fuzzing/rust_gap_manifest.rb +113 -0
  182. data/lib/hecks/fuzzing/self_consistency.rb +141 -112
  183. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +35 -35
  184. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +18 -11
  185. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +13 -12
  186. data/lib/hecks/fuzzing/sequence_generator/picker.rb +21 -12
  187. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +58 -31
  188. data/lib/hecks/fuzzing/sequence_generator.rb +111 -23
  189. data/lib/hecks/fuzzing/shrinker.rb +197 -0
  190. data/lib/hecks/fuzzing/structural_skips.rb +23 -130
  191. data/lib/hecks/fuzzing/sweep_depth.rb +4 -4
  192. data/lib/hecks/fuzzing/target_capabilities.rb +49 -18
  193. data/lib/hecks/fuzzing/value_generator.rb +14 -14
  194. data/lib/hecks/fuzzing.rb +5 -0
  195. data/lib/hecks/grammar/evolve.rb +10 -10
  196. data/lib/hecks/grammar.rb +7 -7
  197. data/lib/hecks/ir.rb +13 -13
  198. data/lib/hecks/language/bluebook/bluebook.bluebook +41 -0
  199. data/lib/hecks/language/bluebook/policy.bluebook +11 -1
  200. data/lib/hecks/language/bluebook/vocabulary.bluebook +348 -13
  201. data/lib/hecks/language/oidc.json +5 -0
  202. data/lib/hecks/literal.rb +9 -9
  203. data/lib/hecks/naming.rb +25 -25
  204. data/lib/hecks/ports/access_control.rb +58 -2
  205. data/lib/hecks/ports/agent/answers.rb +83 -6
  206. data/lib/hecks/ports/agent.rb +119 -35
  207. data/lib/hecks/ports/authentication.rb +44 -4
  208. data/lib/hecks/ports/authorization.rb +53 -11
  209. data/lib/hecks/ports/clock.rb +42 -23
  210. data/lib/hecks/ports/extraction.rb +16 -0
  211. data/lib/hecks/ports/identity_assignment.rb +24 -2
  212. data/lib/hecks/ports/identity_generation.rb +17 -3
  213. data/lib/hecks/ports/identity_resolution.rb +18 -1
  214. data/lib/hecks/ports/loading.rb +4 -0
  215. data/lib/hecks/ports/persistence/append_only.rb +172 -8
  216. data/lib/hecks/ports/persistence/binding_policy.rb +34 -0
  217. data/lib/hecks/ports/persistence/codec_boundary.rb +178 -0
  218. data/lib/hecks/ports/persistence/execution.rb +4 -0
  219. data/lib/hecks/ports/persistence/null_saga_store.rb +12 -1
  220. data/lib/hecks/ports/persistence/plugin.rb +42 -4
  221. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +218 -25
  222. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +77 -9
  223. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +81 -24
  224. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +29 -18
  225. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +144 -60
  226. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +103 -8
  227. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +98 -23
  228. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +282 -109
  229. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +63 -25
  230. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +118 -66
  231. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +51 -28
  232. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +28 -5
  233. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +25 -12
  234. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +129 -34
  235. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +51 -6
  236. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +33 -9
  237. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +16 -0
  238. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +57 -4
  239. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +25 -2
  240. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +314 -90
  241. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +68 -10
  242. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +9 -3
  243. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +9 -2
  244. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +42 -8
  245. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -1
  246. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +36 -5
  247. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +23 -3
  248. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -19
  249. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +5 -5
  250. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +1 -1
  251. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -2
  252. data/lib/hecks/ports/persistence/plugins/era.rb +12 -2
  253. data/lib/hecks/ports/persistence/remote_runtime.rb +9 -2
  254. data/lib/hecks/ports/persistence/repository_factory.rb +23 -3
  255. data/lib/hecks/ports/persistence/state_codec.rb +319 -0
  256. data/lib/hecks/ports/persistence.rb +36 -1
  257. data/lib/hecks/ports/projection.rb +61 -7
  258. data/lib/hecks/ports/query/in_memory.rb +3 -3
  259. data/lib/hecks/ports/query/ordering.rb +6 -6
  260. data/lib/hecks/ports/query.rb +35 -0
  261. data/lib/hecks/projections/bootstrap_table.rb +112 -0
  262. data/lib/hecks/projections/diagrams.rb +75 -75
  263. data/lib/hecks/projections/glossary/html.rb +3 -3
  264. data/lib/hecks/projections/glossary/markdown.rb +3 -3
  265. data/lib/hecks/projections/glossary/mermaid.rb +1 -1
  266. data/lib/hecks/projections/glossary/sections.rb +1 -1
  267. data/lib/hecks/projections/glossary/sentences.rb +5 -5
  268. data/lib/hecks/projections/glossary.rb +15 -15
  269. data/lib/hecks/projections/ir.rb +1 -1
  270. data/lib/hecks/projections/model/deviations.rb +18 -17
  271. data/lib/hecks/projections/model.rb +25 -21
  272. data/lib/hecks/projections/oidc.rb +7 -7
  273. data/lib/hecks/projections/parser_table.rb +5 -5
  274. data/lib/hecks/projections/reference.rb +3 -3
  275. data/lib/hecks/projections/rust_vocabulary.rb +443 -0
  276. data/lib/hecks/projections/shape.rb +2 -2
  277. data/lib/hecks/projections/statements.rb +11 -11
  278. data/lib/hecks/projections/vocabulary.rb +9 -9
  279. data/lib/hecks/projections.rb +5 -3
  280. data/lib/hecks/projector/cli_projector.rb +29 -29
  281. data/lib/hecks/projector/docs_projector.rb +13 -13
  282. data/lib/hecks/projector/exporter.rb +42 -21
  283. data/lib/hecks/projector/ir_projector.rb +1 -1
  284. data/lib/hecks/projector/narrate_projector.rb +11 -11
  285. data/lib/hecks/projector/target.rb +13 -13
  286. data/lib/hecks/projector.rb +15 -15
  287. data/lib/hecks/query_ir.rb +47 -47
  288. data/lib/hecks/query_specification/common/comparators.rb +19 -3
  289. data/lib/hecks/query_specification/common/comparison.rb +109 -27
  290. data/lib/hecks/query_specification/common/dsl.rb +65 -9
  291. data/lib/hecks/query_specification/common/null_policy.rb +57 -13
  292. data/lib/hecks/query_specification/common/null_semantics.rb +4 -0
  293. data/lib/hecks/query_specification/common/options.rb +25 -0
  294. data/lib/hecks/query_specification/field_path.rb +69 -15
  295. data/lib/hecks/query_specification/hop_path.rb +57 -20
  296. data/lib/hecks/query_specification/read_model/specification.rb +4 -0
  297. data/lib/hecks/rendering.rb +3 -3
  298. data/lib/hecks/router/namespace_installer.rb +3 -3
  299. data/lib/hecks/router.rb +1 -1
  300. data/lib/hecks/runtime/aggregate_lock.rb +11 -11
  301. data/lib/hecks/runtime/boot_gates.rb +3 -3
  302. data/lib/hecks/runtime/caller.rb +8 -8
  303. data/lib/hecks/runtime/capability_graph.rb +2 -2
  304. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +22 -25
  305. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +42 -63
  306. data/lib/hecks/runtime/command_interpreter.rb +159 -102
  307. data/lib/hecks/runtime/command_rules/admissibility.rb +69 -69
  308. data/lib/hecks/runtime/command_rules/arithmetic.rb +137 -91
  309. data/lib/hecks/runtime/command_rules/authorization.rb +38 -17
  310. data/lib/hecks/runtime/command_rules/emission.rb +18 -1
  311. data/lib/hecks/runtime/command_rules/references.rb +35 -35
  312. data/lib/hecks/runtime/command_rules.rb +3 -0
  313. data/lib/hecks/runtime/dependency_planning.rb +11 -11
  314. data/lib/hecks/runtime/dispatcher.rb +283 -90
  315. data/lib/hecks/runtime/entity_element.rb +151 -67
  316. data/lib/hecks/runtime/entity_interpreter.rb +108 -82
  317. data/lib/hecks/runtime/errors.rb +19 -19
  318. data/lib/hecks/runtime/event.rb +6 -6
  319. data/lib/hecks/runtime/identity.rb +22 -22
  320. data/lib/hecks/runtime/instance.rb +39 -14
  321. data/lib/hecks/runtime/interpreting.rb +12 -12
  322. data/lib/hecks/runtime/invocation.rb +276 -0
  323. data/lib/hecks/runtime/loader.rb +14 -14
  324. data/lib/hecks/runtime/outbox.rb +23 -23
  325. data/lib/hecks/runtime/policy_interpreter.rb +54 -54
  326. data/lib/hecks/runtime/port_operation_interpreter.rb +22 -19
  327. data/lib/hecks/runtime/query_interpreter.rb +55 -64
  328. data/lib/hecks/runtime/reaction_invocation.rb +20 -20
  329. data/lib/hecks/runtime/read_model_interpreter.rb +40 -40
  330. data/lib/hecks/runtime/rebuild_sweep.rb +4 -4
  331. data/lib/hecks/runtime/reference_hop.rb +6 -6
  332. data/lib/hecks/runtime/refusal_wording.rb +92 -115
  333. data/lib/hecks/runtime/registry/saga_persistence.rb +21 -21
  334. data/lib/hecks/runtime/registry/verification.rb +36 -26
  335. data/lib/hecks/runtime/registry.rb +45 -28
  336. data/lib/hecks/runtime/remote_dispatcher.rb +38 -23
  337. data/lib/hecks/runtime/routing.rb +10 -153
  338. data/lib/hecks/runtime/saga_interpreter/correlation.rb +17 -17
  339. data/lib/hecks/runtime/saga_interpreter.rb +64 -64
  340. data/lib/hecks/runtime/saga_pending_dispatch.rb +12 -12
  341. data/lib/hecks/runtime/tenant_check.rb +9 -9
  342. data/lib/hecks/runtime/tenant_scope.rb +5 -5
  343. data/lib/hecks/runtime/value/admission.rb +75 -30
  344. data/lib/hecks/runtime/value/coercion.rb +318 -127
  345. data/lib/hecks/runtime/value/entity_list_coercion.rb +34 -34
  346. data/lib/hecks/runtime/value.rb +21 -21
  347. data/lib/hecks/runtime.rb +7 -7
  348. data/lib/hecks/storehouse.rb +64 -64
  349. data/lib/hecks/version.rb +3 -3
  350. data/lib/hecks/vocabulary.rb +205 -4
  351. data/lib/hecks.rb +13 -11
  352. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +11 -11
  353. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +14 -12
  354. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +11 -11
  355. metadata +22 -2
@@ -3,14 +3,14 @@ require_relative "../../forms/html"
3
3
  module Hecks
4
4
  module Projections
5
5
  module Glossary
6
- # THE PAGE, RENDERED FROM THE MARKDOWN — `html/index.html` is
6
+ # **The page, rendered from the markdown** — `html/index.html` is
7
7
  # `glossary.md` read back and dressed: a navigation rail built from
8
8
  # its `##` headings, each `###` a term entry, every ```mermaid fence
9
9
  # a diagram, every `[x](#y)` an in-page link. Nothing here reads
10
10
  # the bluebook; if the page shows it, the Markdown says it, so the
11
11
  # two cannot drift.
12
12
  #
13
- # A SUBSET RENDERER, NOT A MARKDOWN LIBRARY — the projector emits
13
+ # A subset renderer, not a markdown library — the projector emits
14
14
  # a fixed handful of constructs (`Markdown`'s own header lists
15
15
  # them), and this reads exactly those. The Gemfile keeps every
16
16
  # dependency justified in its own comment; a full Markdown engine
@@ -89,7 +89,7 @@ module Hecks
89
89
  # The same slugs GitHub would give these headings, in the same
90
90
  # order — so the links the Markdown carries land here too.
91
91
  #
92
- # KEYED BY THE BLOCK ITSELF, NOT ITS VALUE — a Struct compares by
92
+ # Keyed by the block itself, not its value — a Struct compares by
93
93
  # members, so two "### Open" headings in different sections would
94
94
  # otherwise be one key, and the first would answer with the
95
95
  # second's "-1" slug, leaving `#open` with nothing to land on.
@@ -6,7 +6,7 @@ require_relative "../statements"
6
6
  module Hecks
7
7
  module Projections
8
8
  module Glossary
9
- # THE DOCUMENT ITSELF — `glossary.md`, the one source the page is
9
+ # **The document itself** — `glossary.md`, the one source the page is
10
10
  # rendered from. Written in the handful of Markdown constructs
11
11
  # GitHub renders as-is (headings, blockquotes, ```mermaid fences,
12
12
  # lists, in-page links), so the file is a complete, readable
@@ -62,7 +62,7 @@ module Hecks
62
62
  parts.join("\n\n")
63
63
  end
64
64
 
65
- # What an aggregate IS, what it can be, how it fits and moves,
65
+ # What an aggregate is, what it can be, how it fits and moves,
66
66
  # and what is always true of it — before a single term.
67
67
  def opening(aggregate, bluebook)
68
68
  parts = []
@@ -75,7 +75,7 @@ module Hecks
75
75
  parts
76
76
  end
77
77
 
78
- # THE STATEMENTS PROJECTION'S OWN SENTENCES, SPOKEN. An invariant
78
+ # The statements projection's own sentences, spoken. An invariant
79
79
  # is the author's words and stays exactly so. A relationship
80
80
  # sentence is built mechanically from construct names ("An
81
81
  # ATMCard references an Account."), and a construct name is the
@@ -3,7 +3,7 @@ require_relative "../../naming"
3
3
  module Hecks
4
4
  module Projections
5
5
  module Glossary
6
- # THE THREE PICTURES THE GLOSSARY DRAWS, each kept to the handful of
6
+ # The three pictures the glossary draws, each kept to the handful of
7
7
  # things that matter — Evans' "three to five objects central to the
8
8
  # issue at hand", never the whole model at once.
9
9
  #
@@ -1,7 +1,7 @@
1
1
  module Hecks
2
2
  module Projections
3
3
  module Glossary
4
- # THE THREE SECTIONS NOTHING HOMES TO ONE AGGREGATE. In their own
4
+ # The three sections nothing homes to one aggregate. In their own
5
5
  # file because `Markdown` reads them and loads before the
6
6
  # projector's own body does.
7
7
  ROLES = "Roles".freeze
@@ -4,7 +4,7 @@ require_relative "../statements"
4
4
  module Hecks
5
5
  module Projections
6
6
  module Glossary
7
- # EVERY SENTENCE THE GLOSSARY SAYS, AND THE RULE EACH ONE OBEYS.
7
+ # Every sentence the glossary says, and the rule each one obeys.
8
8
  #
9
9
  # Authored text is verbatim: an aggregate's `description`, a
10
10
  # command's `goal`, a query's `description`, an invariant's own
@@ -65,7 +65,7 @@ module Hecks
65
65
  [value_object_sentence(value_object, index, within), rules_line(rules)].compact
66
66
  end
67
67
 
68
- # A one-field object whose field is just "value" IS its type —
68
+ # A one-field object whose field is just "value" is its type —
69
69
  # "Text.", "A whole number." — the field name would add nothing.
70
70
  def value_object_sentence(value_object, index, within)
71
71
  return closed_set_sentence(value_object.members) if value_object.closed_set?
@@ -92,7 +92,7 @@ module Hecks
92
92
  field.list? ? "a list of #{inner}" : inner
93
93
  end
94
94
 
95
- # A CLOSED SET'S ROWS — a one-field set is its values; a set
95
+ # A closed set's rows — a one-field set is its values; a set
96
96
  # whose rows carry more (StatementFrequency's cadence plus a
97
97
  # retention and a fee) leads with the first field and keeps the
98
98
  # rest beside it, so no row loses what makes it distinct.
@@ -162,7 +162,7 @@ module Hecks
162
162
  sentence
163
163
  end
164
164
 
165
- # A NOUN LIST, DELIBERATELY — "Responsible for Credit and Debit",
165
+ # A noun list, deliberately — "Responsible for Credit and Debit",
166
166
  # never "Can credit and debit": banking's System role raises
167
167
  # `Debited` and `Credited`, and "can … debited" is a wrong
168
168
  # sentence. The headwords are already what people say.
@@ -170,7 +170,7 @@ module Hecks
170
170
  "Responsible for #{Naming.to_sentence_list(command_links(issues, index))}."
171
171
  end
172
172
 
173
- # THE SAME WORD FOR TWO DIFFERENT THINGS gets its holder beside it
173
+ # The same word for two different things gets its holder beside it
174
174
  # — a role responsible for CardPayment's Reverse and Transfer's
175
175
  # Reverse is responsible for "Reverse (card payment)" and
176
176
  # "Reverse (transfer)", not for "Reverse" twice.
@@ -9,15 +9,15 @@ require_relative "glossary/html"
9
9
 
10
10
  module Hecks
11
11
  module Projections
12
- # A CHAPTER, PROJECTED AS ITS UBIQUITOUS LANGUAGE — a glossary for the
13
- # whole team, in the sense Evans meant (DDD ch. 2): ONE language,
12
+ # A chapter, projected as its ubiquitous language — a glossary for the
13
+ # whole team, in the sense Evans meant (DDD ch. 2): one language,
14
14
  # shared by domain experts and developers, written the same way in
15
15
  # conversation, diagrams, documents and code, so that a subject-matter
16
16
  # expert can read the model and say "yes, that's how it works" or
17
17
  # "no, that's wrong". A banker, a support rep, the CEO and an engineer
18
18
  # read the same page.
19
19
  #
20
- # THREE THINGS FOLLOW FROM THAT AUDIENCE. First, no type jargon: a
20
+ # **Three things follow from that audience**. First, no type jargon: a
21
21
  # term is a term, not "an Aggregate" or "a Value Object", and every
22
22
  # identifier is spelled as a person says it (`Naming.words`: `ATMCard`
23
23
  # is "ATM card"). Second, nothing invented: every sentence is either
@@ -29,7 +29,7 @@ module Hecks
29
29
  # reader thinks "what does Account mean" before "what starts with A",
30
30
  # and once there reads the way a dictionary reads.
31
31
  #
32
- # TWO FILES FROM ONE SOURCE. `glossary.md` is the document — every
32
+ # **Two files from one source**. `glossary.md` is the document — every
33
33
  # construct in it renders on GitHub as-is (headings, blockquotes,
34
34
  # ```mermaid fences, lists, in-page links). `html/index.html` is that
35
35
  # exact Markdown string rendered into a page with a navigation rail;
@@ -72,7 +72,7 @@ module Hecks
72
72
  Document.new(bluebook: bluebook, sections: sections, index: Index.new(sections))
73
73
  end
74
74
 
75
- # AGGREGATES FIRST, A TO Z BY THEIR SPOKEN NAME ("Account" before
75
+ # Aggregates first, a to Z by their spoken name ("Account" before
76
76
  # "ATM card"), then the three groups nothing homes to one aggregate.
77
77
  def sections(bluebook, entries)
78
78
  grouped = entries.group_by(&:section)
@@ -87,7 +87,7 @@ module Hecks
87
87
  list
88
88
  end
89
89
 
90
- # A HEADWORD IS QUALIFIED ONLY WHEN IT WOULD REPEAT within its own
90
+ # A HEADWORD is qualified only when it would repeat within its own
91
91
  # section — "Open" the action and "Open (the list)" the question;
92
92
  # "Return (key issuance)" beside another Return — never numbered
93
93
  # (Chicago 18.9, MDN's disambiguation pages: qualify the headword).
@@ -111,14 +111,14 @@ module Hecks
111
111
 
112
112
  # ── gathering ────────────────────────────────────────────────────
113
113
 
114
- # AN ENTITY CAN CARRY ITS OWN COMMANDS AND QUERIES TOO — walked the
114
+ # An entity can carry its own commands and queries too — walked the
115
115
  # same one level down `DocsProjector` and `Projections::Diagrams`
116
116
  # already walk it.
117
117
  def holders(bluebook)
118
118
  bluebook.aggregates.flat_map { |aggregate| [aggregate, *aggregate.entities] }
119
119
  end
120
120
 
121
- # EVERY HOLDER'S OWN AGGREGATE, ONE HOP OR ZERO — an aggregate maps
121
+ # Every holder's own aggregate, one hop or zero — an aggregate maps
122
122
  # to itself, an entity to whichever aggregate declared it. The one
123
123
  # fact the grouping is built on.
124
124
  def holder_aggregate(bluebook)
@@ -128,8 +128,8 @@ module Hecks
128
128
  end
129
129
  end
130
130
 
131
- # EVERY EVENT'S RAISERS — an event is never declared, only emitted,
132
- # so its home is whichever aggregate the FIRST command that raises
131
+ # Every event's raisers — an event is never declared, only emitted,
132
+ # so its home is whichever aggregate the first command that raises
133
133
  # it belongs to; a policy or saga reacting to it inherits that home.
134
134
  def event_raisers(bluebook)
135
135
  holders(bluebook).each_with_object(Hash.new { |hash, key| hash[key] = [] }) do |holder, map|
@@ -165,7 +165,7 @@ module Hecks
165
165
  end
166
166
  end
167
167
 
168
- # AGGREGATES ONLY — an entity declares no value objects of its own
168
+ # Aggregates only — an entity declares no value objects of its own
169
169
  # (`Bluebook::Entity` deliberately does not answer `value_objects`).
170
170
  def value_object_entries(bluebook)
171
171
  bluebook.aggregates.flat_map do |aggregate|
@@ -213,7 +213,7 @@ module Hecks
213
213
  end
214
214
  end
215
215
 
216
- # CROSS-CUTTING BY NATURE — `System` and `Customer` issue commands
216
+ # Cross-cutting by nature — `System` and `Customer` issue commands
217
217
  # across half the aggregates here — so a role belongs to no single
218
218
  # one and gets its own section.
219
219
  def role_entries(bluebook)
@@ -236,7 +236,7 @@ module Hecks
236
236
 
237
237
  # ── anchors ──────────────────────────────────────────────────────
238
238
 
239
- # GITHUB'S OWN HEADING SLUGS, REPRODUCED — lowercase, punctuation
239
+ # **GitHub's own heading slugs, reproduced** — lowercase, punctuation
240
240
  # dropped, spaces to hyphens, a repeat gets "-1", "-2" in document
241
241
  # order. Computed here, once, in the order the headings will appear,
242
242
  # so a link written into the Markdown lands on the same heading
@@ -261,8 +261,8 @@ module Hecks
261
261
  end
262
262
  end
263
263
 
264
- # WHERE A DECLARED REFERENCE POINTS — keyed structurally (a command
265
- # by its holder AND name, an event by its bare name), never by
264
+ # **Where a declared reference points** — keyed structurally (a command
265
+ # by its holder and name, an event by its bare name), never by
266
266
  # searching prose for a matching word. Anything not declared here
267
267
  # (a cross-domain command like `Notifications.Send`) answers nil,
268
268
  # and the sentence says it in words with no link.
@@ -7,7 +7,7 @@ module Hecks
7
7
  # The canonical IR, as a constant. The implementation already existed
8
8
  # and is already golden-tested (`Projector::IRProjector`, registered
9
9
  # as `:ir`) — this only gives it the constant spelling every other
10
- # target has, by re-registering the SAME module under the same key.
10
+ # target has, by re-registering the same module under the same key.
11
11
  #
12
12
  # Deliberately not a new implementation: two things named `IR` that
13
13
  # each rendered IR their own way is exactly the drift this namespace
@@ -1,32 +1,19 @@
1
1
  module Hecks
2
2
  module Projections
3
3
  module Model
4
- # HOW THE MODEL'S SHAPE DIFFERS FROM THE LANGUAGE'S, and why.
4
+ # How the model's shape differs from the language's, and why.
5
5
  #
6
6
  # Every construct's `emits_ir` restates what the grammar declares —
7
7
  # and the two legitimately differ, in seven ways. These lived only
8
8
  # as prose in Ruby comments until spec/model_shape_conformance_spec
9
- # made them checkable; they live HERE so the generator and the gate
9
+ # made them checkable; they live here so the generator and the gate
10
10
  # read one source rather than two that must agree.
11
11
  #
12
12
  # A reason is carried beside each entry because the generated file
13
- # will CARRY it: a deviation is exactly the kind of thing whose
13
+ # will carry it: a deviation is exactly the kind of thing whose
14
14
  # explanation must survive regeneration, and the only way it can is
15
15
  # to be emitted rather than typed into the output.
16
16
  module Deviations
17
- # The grammar is relational — a Command points UP at its
18
- # Aggregate — where the model composes. An explicit `as:` still
19
- # keeps its `_id` (Command's own `entity_id`, kept as data); the
20
- # parent link itself mints bare now (ADR 0025) — `aggregate` or
21
- # `bluebook`, whichever this category's creating command declares
22
- # first — so both spellings are checked. Entity spells its own
23
- # (separate, non-colliding) text twin of the parent link `owner`.
24
- PARENT_REF = ->(field) { field.to_s.match?(/_id\z/) || %i[owner aggregate bluebook].include?(field) }
25
-
26
- # The judge's own field, never the model's — contracts.rb already
27
- # says so with `derived: { position: :walk }`.
28
- JUDGE_ONLY = %i[position].freeze
29
-
30
17
  # What the model holds that the grammar declares elsewhere: the
31
18
  # containment edges, stated in syntax.bluebook's Keyword rows as
32
19
  # `context` -> `opens`.
@@ -64,7 +51,7 @@ module Hecks
64
51
  "Policy" => { where_ast: "the structured form of `where`, derived from the same text at emission" }
65
52
  }.freeze
66
53
 
67
- # DECLARED, AND DELIBERATELY NOT EMITTED. The category that had no
54
+ # **Declared, and deliberately not emitted**. The category that had no
68
55
  # home anywhere before — each of these was a comment and nothing
69
56
  # more.
70
57
  OFF_THE_WIRE = {
@@ -85,6 +72,20 @@ module Hecks
85
72
 
86
73
  module_function
87
74
 
75
+ # The grammar is relational — a Command points up at its
76
+ # Aggregate — where the model composes. An explicit `as:` still
77
+ # keeps its `_id` (Command's own `entity_id`, kept as data); the
78
+ # parent link itself mints bare now (ADR 0025) — `aggregate` or
79
+ # `bluebook`, whichever this category's creating command declares
80
+ # first. Entity spells its own (separate, non-colliding) text twin
81
+ # of the parent link `owner`. Not restated here: the one list is
82
+ # `Assembly::PARENT_POINTERS`, which the assembly gate reads too.
83
+ def parent_ref?(field) = Hecks::Bluebook::Assembly.parent_pointer?(field)
84
+
85
+ # The judge's own fields, never the model's — read off the
86
+ # category's contract (`derived: { position: :walk }`), not restated.
87
+ def judge_only(name) = Hecks::Bluebook::Assembly.contract(name).walked
88
+
88
89
  # The tables that carry a reason answer with names only when the
89
90
  # caller wants the set rather than the explanations.
90
91
  def off_the_wire(name) = OFF_THE_WIRE.fetch(name, {}).keys
@@ -3,22 +3,22 @@ require_relative "../projector"
3
3
 
4
4
  module Hecks
5
5
  module Projections
6
- # THE MODEL CLASSES, PROJECTED FROM THE LANGUAGE THAT DECLARES THEM.
6
+ # The model classes, projected from the language that declares them.
7
7
  #
8
- # A construct's HOLDING half — its readers, its emission, a
8
+ # A construct's holding half — its readers, its emission, a
9
9
  # constructor that assigns declared fields and hands off — restates
10
10
  # what `bluebook.bluebook` already says, three times over in Ruby.
11
11
  # This renders it instead.
12
12
  #
13
- # ONLY THE HOLDING HALF. `Behaviour::X` is hand-written and permanent,
13
+ # **Only the holding half**. `Behaviour::X` is hand-written and permanent,
14
14
  # and `settle` is the seam: everything a declaration cannot state
15
15
  # lives behind it, so regenerating can never be lossy. That property
16
16
  # was established construct by construct before any of this was
17
17
  # written — the chapter looked generatable and was not, until its
18
18
  # `@hecks_root`, ports table and child stamping moved behind `settle`.
19
19
  #
20
- # THE HOST MANIFEST IS THE HONEST PART. The grammar states the fields;
21
- # it does not state which constructs are Ruby CLASSES rather than
20
+ # The HOST manifest is the honest part. The grammar states the fields;
21
+ # it does not state which constructs are Ruby classes rather than
22
22
  # instances, what a constructor's defaults are, or how a value is
23
23
  # coerced on the way in. Those are facts about Ruby, not about
24
24
  # bluebooks, so they are declared here rather than pretended into the
@@ -29,7 +29,7 @@ module Hecks
29
29
 
30
30
  projects_as :model, declares: "Bluebook", emits: :files
31
31
 
32
- # PER-CONSTRUCT RUBY FACTS. `coerce` is the only fiddly column: a
32
+ # **Per-construct Ruby facts**. `coerce` is the only fiddly column: a
33
33
  # declared field arrives as whatever the builder handed over, and
34
34
  # each construct has always normalised its own on the way in.
35
35
  HOST = {
@@ -37,21 +37,25 @@ module Hecks
37
37
  construct: "Policy",
38
38
  file: "policy.rb",
39
39
  behaviour: "Behaviour::Policy",
40
- readers: %i[name on_event trigger_command target_domain where for_each with_spec],
40
+ readers: %i[name on_event trigger_command target_domain expect_undelivered where for_each with_spec],
41
41
  accessors: %i[aggregate],
42
42
  defaults: { name: nil, on_event: "nil", trigger_command: "nil",
43
- target_domain: "nil", where: "nil", for_each: "nil",
43
+ target_domain: "nil", expect_undelivered: "false", where: "nil", for_each: "nil",
44
44
  with_spec: "[]", aggregate: "nil" },
45
- coerce: { name: ".to_s", aggregate: "&.to_s" },
46
- # A LIST OF BINDINGS IS NOT A SCALAR ON THE WIRE. Every other
45
+ # A flag on the wire is a boolean — the language holds it as
46
+ # text ("true"), the builder hands over `true`, and a
47
+ # reconstruction hands back whichever it read; all three land
48
+ # as the same `true`/`false`.
49
+ coerce: { name: ".to_s", aggregate: "&.to_s", expect_undelivered: ".to_s == \"true\"" },
50
+ # A list of bindings is not a scalar on the wire. Every other
47
51
  # field emits as itself; this one has to render the way
48
52
  # `DispatchSpec`'s own `with_spec` does — keys to strings, and
49
- # `render_value` KEEPING the leading colon on a Symbol, because
53
+ # `render_value` keeping the leading colon on a Symbol, because
50
54
  # a binding that reads an event field and one that supplies a
51
55
  # literal string are otherwise indistinguishable once written
52
56
  # down (see `MetaValidator::Readings`' own note on exactly that).
53
57
  renders: { with_spec: "-> { with_spec.map { |key, value| [key.to_s, Bluebook.render_value(value)] } }",
54
- # COMPUTED (Deviations::COMPUTED["Policy"]): the structured
58
+ # Computed (Deviations::COMPUTED["Policy"]): the structured
55
59
  # form of `where`, a pure function of that text, the same
56
60
  # `ast` every rule row carries beside its `canonical`.
57
61
  where_ast: "-> { where_ast }" },
@@ -67,8 +71,8 @@ module Hecks
67
71
 
68
72
  def render(bluebook, name, host)
69
73
  <<~RUBY
70
- # GENERATED — projected from the language's own #{name} aggregate.
71
- # DO NOT EDIT: the holding half is rendered, and #{host.fetch(:behaviour)}
74
+ # Generated — projected from the language's own #{name} aggregate.
75
+ # Do not edit: the holding half is rendered, and #{host.fetch(:behaviour)}
72
76
  # is where anything hand-written belongs.
73
77
  require_relative "behaviour/#{File.basename(host.fetch(:file), '.rb')}"
74
78
 
@@ -91,9 +95,9 @@ module Hecks
91
95
 
92
96
  # The emission, keyed as the model spells it and sourced as the
93
97
  # language declares it.
94
- # A COMPUTED field (Deviations::COMPUTED) is emitted too — it is
98
+ # A computed field (Deviations::COMPUTED) is emitted too — it is
95
99
  # model-only by definition, so it rides after the declared fields
96
- # and MUST have a `renders` entry, there being nothing to `send`.
100
+ # and must have a `renders` entry, there being nothing to `send`.
97
101
  def emits(bluebook, name)
98
102
  fields = emitted_fields(bluebook, name) + Deviations.computed(name)
99
103
  renders = HOST.fetch(name).fetch(:renders, {})
@@ -102,14 +106,14 @@ module Hecks
102
106
  "emits_ir(\n#{fields.map { |f| " #{"#{f}:".ljust(width + 1)} #{renders.fetch(f, ":#{f}")}" }.join(",\n")}\n)"
103
107
  end
104
108
 
105
- # WHAT THE CONSTRUCT EMITS: what the language declares, less every
109
+ # What the construct emits: what the language declares, less every
106
110
  # deviation the tables account for. The generator and
107
111
  # spec/model_shape_conformance_spec compute this the same way, from
108
112
  # the same tables, which is the point of the tables being in lib.
109
113
  def emitted_fields(bluebook, name)
110
114
  bluebook.aggregate(name).attributes.map(&:name)
111
- .reject { |f| Deviations::PARENT_REF.call(f) } -
112
- Deviations::JUDGE_ONLY -
115
+ .reject { |f| Deviations.parent_ref?(f) } -
116
+ Deviations.judge_only(name) -
113
117
  Deviations.off_the_wire(name) -
114
118
  Deviations.dynamic_tail(name) -
115
119
  Deviations.folded(name).values.flatten -
@@ -122,13 +126,13 @@ module Hecks
122
126
  return lines.join("\n") if accessors.empty?
123
127
 
124
128
  # A declared field the model deliberately does not emit still
125
- # needs a reader, and the REASON it is off the wire is carried
129
+ # needs a reader, and the reason it is off the wire is carried
126
130
  # here rather than typed in — a comment that survives
127
131
  # regeneration is one the generator writes.
128
132
  reasons = Deviations::OFF_THE_WIRE.fetch(host.fetch(:construct, ""), {})
129
133
  (lines + accessors.map do |a|
130
134
  why = reasons[a]
131
- (why ? "\n# #{a.upcase}, DECLARED AND DELIBERATELY OFF THE WIRE\n# #{wrap(why)}\n" : "") +
135
+ (why ? "\n# #{a.to_s.capitalize}, declared and deliberately off the wire\n# #{wrap(why)}\n" : "") +
132
136
  "attr_accessor :#{a}"
133
137
  end).join("\n")
134
138
  end
@@ -3,16 +3,16 @@ require_relative "../projector"
3
3
 
4
4
  module Hecks
5
5
  module Projections
6
- # AN OIDC CLIENT/SCOPE MANIFEST derived from a domain's own IR: what
6
+ # An OIDC client/scope manifest derived from a domain's own IR: what
7
7
  # an identity provider has to know about this domain before it can
8
8
  # issue a token that means anything here.
9
9
  #
10
- # THE ARTIFACT HALF OF SOMETHING ALREADY HALF-BUILT.
11
- # `spec/oidc_projection_spec.rb` covers the INTEGRATION half — verified
10
+ # The artifact half of something already half-built.
11
+ # `spec/oidc_projection_spec.rb` covers the integration half — verified
12
12
  # claims in, `IdentityResolution.resolve` → `Authorization.holds_role?`
13
13
  # → a dispatch scoped by `Hecks.as_caller(role:)`. That half enforces
14
14
  # a role per command. It just had no way to say, up front and as data,
15
- # WHICH role each command wants — every answer came from asking the
15
+ # which role each command wants — every answer came from asking the
16
16
  # live runtime one dispatch at a time.
17
17
  #
18
18
  # This is that catalogue, and the two are checked against each other
@@ -24,12 +24,12 @@ module Hecks
24
24
  # `Ports::Authorization.holds_role?` compares against a real
25
25
  # `Governance::RoleAssignment`.
26
26
  #
27
- # ROLES COME FROM THE COMMANDS, NOT FROM GOVERNANCE. A command's own
27
+ # Roles come from the commands, not from governance. A command's own
28
28
  # `role "Compliance officer"` is in the bluebook IR
29
29
  # (`Command#role`), whereas `uses_framework "Governance"` is
30
30
  # declared in the `.hecksagon` — which `call(bluebook:, options:)`
31
31
  # cannot see at all. Reading the commands is both the only thing
32
- # available here AND the more accurate source: it says what each
32
+ # available here and the more accurate source: it says what each
33
33
  # command actually demands, not merely which role vocabulary the
34
34
  # application happened to mount.
35
35
  #
@@ -93,7 +93,7 @@ module Hecks
93
93
  end
94
94
 
95
95
  # `banking:account.open` — the shape an OIDC scope is conventionally
96
- # spelled in, and snake_cased through the SAME `Naming.snake` the
96
+ # spelled in, and snake_cased through the same `Naming.snake` the
97
97
  # facade uses to name a command's own door method, so a scope and
98
98
  # the Ruby call that satisfies it cannot drift apart.
99
99
  def command_scopes(commands, verb_prefix, scope_prefix)
@@ -2,12 +2,12 @@ require_relative "../projector"
2
2
 
3
3
  module Hecks
4
4
  module Projections
5
- # THE RUST PARSER'S KEYWORD TABLE, projected from the chapter's own
6
- # Syntax aggregate — "the parser's grammar knowledge is DERIVED from
5
+ # The Rust parser's keyword table, projected from the chapter's own
6
+ # Syntax aggregate — "the parser's grammar knowledge is derived from
7
7
  # hecks's self-description, not hand-typed a second time", which
8
8
  # is the anti-drift idea the whole Rust-parser plan rests on.
9
9
  #
10
- # A REGISTERED TARGET NOW, rather than a module living inside its own
10
+ # A registered target now, rather than a module living inside its own
11
11
  # bin/ script. It was already a projection in everything but call
12
12
  # shape; this only stops it being a fifth way of spelling one.
13
13
  module ParserTable
@@ -20,7 +20,7 @@ module Hecks
20
20
 
21
21
  module_function
22
22
 
23
- # THE CHAPTER IS HANDED OVER, not reached for. This used to open the
23
+ # The chapter is handed over, not reached for. This used to open the
24
24
  # grammar registry itself, which meant the projection could only ever
25
25
  # project one chapter — the language's own. Taking it as an argument is
26
26
  # what the projector protocol asks for, and it costs nothing.
@@ -64,7 +64,7 @@ module Hecks
64
64
 
65
65
  # S14, ADR 0026 — Keyword/Argument are genuine entities of Syntax
66
66
  # now, dispatched (not merely declared) so their own `status`
67
- # really is a lifecycle. `SyntaxBoot.call` reads the STILL-STATIC
67
+ # really is a lifecycle. `SyntaxBoot.call` reads the still-static
68
68
  # seed rows (`KeywordSeed`/`ArgumentSeed`), dispatches each one
69
69
  # through the real admission/lifecycle door, and hands back the
70
70
  # exact same shape `rows` used to read straight off the closed set
@@ -3,18 +3,18 @@ require_relative "../projector"
3
3
 
4
4
  module Hecks
5
5
  module Projections
6
- # THE DSL REFERENCE PAGES, projected from the chapter's own Syntax
6
+ # The DSL reference pages, projected from the chapter's own Syntax
7
7
  # aggregate — the tables come from the declaration, the prose is
8
8
  # preserved from whatever is already committed.
9
9
  #
10
- # THE FIRST PROJECTION THAT EMITS A TREE. `emits: :files` says so,
10
+ # The first projection that emits a tree. `emits: :files` says so,
11
11
  # and the framework writes the map rather than inferring one: a Hash
12
12
  # of path => contents and a Hash that merely holds strings are the
13
13
  # same object to Ruby, so only the projection can know which it
14
14
  # meant. This is the case the output contract was designed for and
15
15
  # deliberately left unimplemented until something real needed it.
16
16
  #
17
- # NOT PURE, and it cannot be. `Doc::Reference.pages` READS the
17
+ # Not pure, and it cannot be. `Doc::Reference.pages` reads the
18
18
  # committed pages to harvest their prose, so the existing directory
19
19
  # is an input — passed as `from:` rather than assumed, so the
20
20
  # projection never reaches for a path of its own choosing.