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
@@ -14,11 +14,11 @@ module Hecks
14
14
  # (#check_piece_invariants, #eligible_rows, #nest_rows,
15
15
  # #recompute_median) each leans on.
16
16
  module InvariantsAndAggregation
17
- # EVERY STORED RECORD STILL SATISFIES ITS OWN AGGREGATE'S DECLARED
18
- # INVARIANTS — Admissibility#enforce_invariants (command_rules/
19
- # admissibility.rb) checks these AFTER every command's mutations,
20
- # BEFORE save, the same point `ensures` is checked. Nothing until
21
- # now re-checked a record AFTER a whole replay finished, independent
17
+ # Every stored record still satisfies its own aggregate's declared
18
+ # invariants — Admissibility#enforce_invariants (command_rules/
19
+ # admissibility.rb) checks these after every command's mutations,
20
+ # before save, the same point `ensures` is checked. Nothing until
21
+ # now re-checked a record after a whole replay finished, independent
22
22
  # of whichever call site was supposed to have refused a violation
23
23
  # in the first place — a record failing its own declared invariant
24
24
  # here is proof a violating write landed anyway: the call site
@@ -27,9 +27,9 @@ module Hecks
27
27
  #
28
28
  # `history[:instances]` entries are already plain, symbol-keyed
29
29
  # state Hashes (Replay.call's own `record.state`) — called against
30
- # Evaluator.call the SAME way ValueObject::Builder#build already
30
+ # Evaluator.call the same way ValueObject::Builder#build already
31
31
  # does for a VO's own invariants (value/coercion.rb), no GuardState
32
- # wrapper needed the way enforce_invariants' own LIVE call uses one
32
+ # wrapper needed the way enforce_invariants' own live call uses one
33
33
  # (GuardState exists for `parent.`/projected-field dereferencing
34
34
  # mid-dispatch; a stored record's own scalar fields need none of
35
35
  # that to re-check a same-aggregate invariant against itself).
@@ -39,8 +39,8 @@ module Hecks
39
39
  #
40
40
  # Entity#invariants (round 7) closes here too, not for free —
41
41
  # `stored_records_satisfy_declared_invariants` only ever checked
42
- # the AGGREGATE's own flat state; a piece's own invariant is
43
- # checked against every ELEMENT of a `list_of` field, a genuinely
42
+ # the aggregate's own flat state; a piece's own invariant is
43
+ # checked against every element of a `list_of` field, a genuinely
44
44
  # different walk `check_piece_invariants` below makes,
45
45
  # independently of `Admissibility#check_entity_invariants` (the
46
46
  # live enforcement path this property exists to catch drifting
@@ -70,11 +70,11 @@ module Hecks
70
70
  offenders.empty? || offenders.join("; ")
71
71
  end
72
72
 
73
- # A PIECE'S OWN INVARIANT, checked against every element a
74
- # `list_of` field holds — the SAME lookup `Admissibility#
73
+ # A piece's own invariant, checked against every element a
74
+ # `list_of` field holds — the same lookup `Admissibility#
75
75
  # check_entity_invariants` makes (`owner.attributes.find { |a|
76
76
  # a.list? && a.type.to_s == entity.hecks_name }`), independently
77
- # reapplied here against a STORED record's own plain Hash state
77
+ # reapplied here against a stored record's own plain Hash state
78
78
  # rather than a live `Instance`.
79
79
  def check_piece_invariants(owner_construct, owner_state, key)
80
80
  owner_construct.entities.each do |entity|
@@ -99,23 +99,23 @@ module Hecks
99
99
  nil
100
100
  end
101
101
 
102
- # A SAGA INSTANCE'S OWN CHECKPOINT SURVIVES BEING WRITTEN AND READ
103
- # BACK — the durability contract `SagaInterpreter#checkpoint` makes
102
+ # A saga instance's own checkpoint survives being written and read
103
+ # back — the durability contract `SagaInterpreter#checkpoint` makes
104
104
  # (`state:` plus a `deep_copy`d `memory:`, handed to whatever
105
105
  # adapter answers `save_saga`) and `Registry#rehydrate_sagas!`
106
106
  # promises to restore on the next boot (`each_saga` yielding
107
107
  # `[pm, correlation, state, memory]` back into `saga_instances`).
108
- # `Replay` captures the LIVE store already materialised the same
108
+ # `Replay` captures the live store already materialised the same
109
109
  # way `checkpoint` itself does (`Value.materialize`, not raw
110
110
  # `Runtime::Value`s — see its own comment); this property pushes
111
- # that captured memory through the SAME `JSON.generate` then
111
+ # that captured memory through the same `JSON.generate` then
112
112
  # `JSON.parse(symbolize_names: true)` round-trip `checkpoint`'s own
113
113
  # `deep_copy` performs (mirrored here rather than called — a
114
114
  # private instance method with no registry to hand it) and checks
115
115
  # it comes back byte-identical. A memory holding anything that
116
116
  # round-trip cannot carry faithfully — a bare Symbol leaf, a
117
117
  # non-JSON type a future field introduces — is corruption the
118
- # durable path would introduce on a REAL restart, caught here
118
+ # durable path would introduce on a real restart, caught here
119
119
  # without needing one.
120
120
  #
121
121
  # `declares_state?` (Behaviour::ProcessManager) is the other half:
@@ -150,11 +150,11 @@ module Hecks
150
150
  offenders.empty? || offenders.join("; ")
151
151
  end
152
152
 
153
- # A `for_each` POLICY DISPATCHES EXACTLY ONCE PER ROW ITS DECLARED
154
- # QUERY ANSWERS — never once for the triggering event regardless of
153
+ # A `for_each` policy dispatches exactly once per row its declared
154
+ # query answers — never once for the triggering event regardless of
155
155
  # row count, never skipping a matched row, never firing on a row a
156
- # concurrent mutation only made match AFTER the fact. `Replay`
157
- # computes the expected row-id set INDEPENDENTLY, at the same
156
+ # concurrent mutation only made match after the fact. `Replay`
157
+ # computes the expected row-id set independently, at the same
158
158
  # instant the real dispatch runs (`Replay.expected_fan_out_rows`,
159
159
  # the query oracle's own shape aimed at fan-out: two engines
160
160
  # compared, never one graded against itself), and records it
@@ -183,21 +183,21 @@ module Hecks
183
183
  offenders.empty? || offenders.join("; ")
184
184
  end
185
185
 
186
- # A `count`/`median` REPORT'S REDUCED SCALAR MATCHES THE SAME
187
- # REDUCTION DONE INDEPENDENTLY, over the SAME eligible rows —
186
+ # A `count`/`median` report's reduced scalar matches the same
187
+ # reduction done independently, over the same eligible rows —
188
188
  # `ReadModelInterpreter#project`'s own FK-join (root first, then
189
189
  # each many-side head matched against it) and `#median` (odd →
190
190
  # the true middle, even → the average of the two middles as a
191
191
  # Float, empty → `nil`; `count` is the filtered length, empty →
192
192
  # `0`), reproduced here in plain Ruby against `history[:instances]`
193
193
  # rather than a live registry — `FieldPath.dig` +
194
- # `Ports::Query::InMemory.comparable`/`.holds?` are the SAME two
194
+ # `Ports::Query::InMemory.comparable`/`.holds?` are the same two
195
195
  # calls the interpreter itself makes to read a field and judge a
196
196
  # `where`, called here rather than re-derived, so this oracle
197
197
  # cannot drift from what "read a field" or "a clause holds" mean
198
198
  # without the interpreter drifting the identical way.
199
199
  #
200
- # Only a report whose `:query` is answered by the SAME bluebook
200
+ # Only a report whose `:query` is answered by the same bluebook
201
201
  # `history[:bluebook]` carries (the bare `Domain.report_name`
202
202
  # form, `domain == bluebook.name`) is checked — the same "only
203
203
  # what we have the grammar for" scope `lifecycle_values_are_declared`
@@ -206,7 +206,7 @@ module Hecks
206
206
  # ("only a report answered by this bluebook, only a count/median
207
207
  # report, only one with a reduced many-side head") each gating the
208
208
  # next, ending in one independent recomputation compared against
209
- # the live answer. The guards are what make this oracle SCOPED
209
+ # the live answer. The guards are what make this oracle scoped
210
210
  # correctly, not incidental complexity — narrower than "every
211
211
  # branch reads as its own precondition."
212
212
  # rubocop:disable-next Metrics/CyclomaticComplexity
@@ -239,14 +239,14 @@ module Hecks
239
239
  end
240
240
 
241
241
  # `aggregation_matches_recompute`'s own shape, extended from
242
- # reducing a many-side head to a scalar (count/median) to NESTING
242
+ # reducing a many-side head to a scalar (count/median) to nesting
243
243
  # it — `ReadModelInterpreter#group_by_target`/`#nest`, reproduced
244
244
  # here in plain Ruby against `history[:instances]` the same way
245
245
  # `eligible_rows` already reproduces the FK-join and `where`
246
246
  # narrowing count/median share. `Value.materialize_unwrapped` is
247
- # the SAME call `#project` makes before nesting (a single-field
247
+ # the same call `#project` makes before nesting (a single-field
248
248
  # value object recurses to its bare scalar — a real grouping key
249
- # has to BE one) — called here rather than re-derived, so this
249
+ # has to be one) — called here rather than re-derived, so this
250
250
  # oracle cannot drift from what "the group key" means without the
251
251
  # interpreter drifting the identical way.
252
252
  #
@@ -298,17 +298,17 @@ module Hecks
298
298
  end
299
299
  end
300
300
 
301
- # THE ELIGIBLE ROWS a `count`/`median` head reduces — every
301
+ # The eligible rows a `count`/`median` head reduces — every
302
302
  # instance of the reduced head's own aggregate, FK-matched against
303
303
  # the report's root reference (if it has one; a rootless report has
304
304
  # none to match) exactly the way `ReadModelInterpreter#reference_fields`
305
305
  # finds the matching attribute, then narrowed by the report's own
306
- # `where` clauses via the SAME `InMemory.holds?` the interpreter's
306
+ # `where` clauses via the same `InMemory.holds?` the interpreter's
307
307
  # `execute` calls.
308
308
  def eligible_rows(bluebook, instances, domain, model, reduced_head, args)
309
309
  aggregate = bluebook.aggregate(reduced_head[:aggregate])
310
310
  prefix = "#{domain}::#{reduced_head[:aggregate]}#"
311
- # `id:` MERGED IN, the same `record.to_h` (`@state.merge(id:
311
+ # `id:` merged in, the same `record.to_h` (`@state.merge(id:
312
312
  # @id)`) every live head row carries — count/median never read
313
313
  # it, but group_by_matches_recompute's own independent nesting
314
314
  # does, the same way ReadModelInterpreter#row(record) = record.
@@ -1,3 +1,5 @@
1
+ require_relative "../nondeterministic"
2
+
1
3
  module Hecks
2
4
  module Fuzzing
3
5
  module Properties
@@ -12,11 +14,11 @@ module Hecks
12
14
  # trustworthy in the first place.
13
15
  module LifecycleAndReplay
14
16
  # Every lifecycle field a replay leaves an instance holding is one
15
- # of the aggregate's OWN declared states — the full set, not just
17
+ # of the aggregate's own declared states — the full set, not just
16
18
  # `Lifecycle#states`' default+targets (see ModelCheck.full_states'
17
19
  # own comment on that hole). The tie to M2 is direct: the model
18
- # checker proves which states a domain's OWN declarations can ever
19
- # produce ; this proves a REAL RUN never produced anything else —
20
+ # checker proves which states a domain's own declarations can ever
21
+ # produce ; this proves a real run never produced anything else —
20
22
  # a coercion bug, a stale string surviving a rename, a default
21
23
  # that drifted from the declared set, would all show up here as a
22
24
  # value nothing upstream would have predicted.
@@ -44,10 +46,10 @@ module Hecks
44
46
  end
45
47
 
46
48
  # Every saga advance a replay actually logged moved along an edge
47
- # the process manager DECLARED — `(from, to)` pairs that appear in
49
+ # the process manager declared — `(from, to)` pairs that appear in
48
50
  # `saga_log` with `advanced: true` must be a `(handler.from_state,
49
51
  # handler.to_state)` pair some handler on that PM declares
50
- # (compensation edges included ; a REFUSED-triggered advance is a
52
+ # (compensation edges included ; a refused-triggered advance is a
51
53
  # handler like any other). A saga that advanced along a pair no
52
54
  # handler names would mean the runtime moved state the language
53
55
  # never authorized — the same trust ModelCheck's static reachability
@@ -72,56 +74,41 @@ module Hecks
72
74
  offenders.empty? || offenders.join("; ")
73
75
  end
74
76
 
75
- # THE FOUNDATIONAL ONE. `Hecks::Runtime` mints nothing — every
77
+ # The foundational one. `Hecks::Runtime` mints nothing — every
76
78
  # identity is declared and derived, never invented (see
77
- # command_interpreter.rb's own "NOTHING IS MINTED" — a random hex,
79
+ # command_interpreter.rb's own "nothing is minted" — a random hex,
78
80
  # a counter, anything not reproducible from the payload, was
79
81
  # refused out of the runtime specifically because it broke this).
80
- # So the SAME steps, replayed against a FRESH boot, must produce
81
- # BYTE-IDENTICAL events, refusals, and instances — any drift here
82
+ # So the same steps, replayed against a fresh boot, must produce
83
+ # byte-identical events, refusals, and instances — any drift here
82
84
  # is nondeterminism the runtime promised not to have: a wall-clock
83
85
  # read that leaked into compared state, a Hash iteration order a
84
86
  # comparison depended on, anything. Two independent replays, not a
85
- # cached one compared to itself, so a bug that corrupts the FIRST
87
+ # cached one compared to itself, so a bug that corrupts the first
86
88
  # run's own bookkeeping cannot pass by agreeing with itself.
87
89
  def replay_is_deterministic(domain_path, steps, adapter: :memory)
88
90
  first = Replay.call(domain_path, steps, adapter: adapter)
89
91
  second = Replay.call(domain_path, steps, adapter: adapter)
90
92
 
91
- # `:event_uid`/`:delivery_id` `Runtime::Outbox::Fanout#rows_for`'s
92
- # OWN `SecureRandom.uuid`, minted fresh per enqueue specifically so
93
- # it stays OFF `Event#to_h` (that file's own comment: the domain's
94
- # own events stay mintless; this is Ruby-only relay bookkeeping,
95
- # never part of what a replay claims the DOMAIN produced) so two
96
- # otherwise-identical replays legitimately carry two different
97
- # uuids here, the same reason `:bluebook`/`:bluebooks` (live
98
- # object identities, not values) are excluded below.
99
- #
100
- # `row[:event][:occurred_at]` — the outbox row's own `event:` field
101
- # is `Outbox.serialize_event`'s `event.to_h.merge(correlation:...)`,
102
- # the FULL `Event#to_h`, unlike `history[:events]` (this file's own
103
- # `events = runtime.events.map { {name:, aggregate:, id:, payload:}
104
- # }`, above) which has ALWAYS deliberately left `occurred_at` OFF
105
- # the compared surface for exactly this reason: a wall-clock read,
106
- # never reproducible byte-for-byte between two independent
107
- # replaying processes a second apart. Stripped here the same way,
108
- # for the one place it newly reappears.
109
- #
110
- # Both stripped from each `outbox_traces` row before comparing
111
- # rather than dropping `outbox_traces` wholesale: everything else
112
- # on a row (status, consumer, kind, the event's own name/
113
- # aggregate/id/payload) IS reproducible from the steps alone and
93
+ # What leaves this comparison, and why, is declared once in
94
+ # `Nondeterministic::FIELDS`: the `outbox_row` group (per-enqueue
95
+ # uuids), the `event` group on each row's full `Event#to_h`
96
+ # (`occurred_at`, which `history[:events]` never carried), and the
97
+ # `history` group (live IR objects). Stripped per `outbox_traces`
98
+ # row rather than dropping `outbox_traces` wholesale: everything
99
+ # else on a row (status, consumer, kind, the event's own name/
100
+ # aggregate/id/payload) is reproducible from the steps alone and
114
101
  # stays checked.
115
102
  strip_outbox_nondeterminism = lambda do |history|
116
103
  traces = Array(history[:outbox_traces]).map do |trace|
117
104
  trace.merge(rows: trace[:rows].map do |row|
118
- row.except(:event_uid, :delivery_id).merge(event: row[:event].except(:occurred_at))
105
+ Nondeterministic.strip(row, :outbox_row).merge(event: Nondeterministic.strip(row[:event], :event))
119
106
  end)
120
107
  end
121
108
  history.merge(outbox_traces: traces)
122
109
  end
123
110
 
124
- comparable = ->(history) { strip_outbox_nondeterminism.call(history).except(:bluebook, :bluebooks) }
111
+ comparable = ->(history) { Nondeterministic.strip(strip_outbox_nondeterminism.call(history), :history) }
125
112
  return true if comparable.call(first) == comparable.call(second)
126
113
 
127
114
  "two replays of the same #{steps.length} steps produced different histories"
@@ -3,61 +3,61 @@ require_relative "../../bluebook/expression/evaluator"
3
3
  module Hecks
4
4
  module Fuzzing
5
5
  module Properties
6
- # THE TRANSACTIONAL OUTBOX'S OWN CONTRACT (`Runtime::Outbox`, that
6
+ # The transactional outbox's own contract (`Runtime::Outbox`, that
7
7
  # file's own header), held to the history a replay actually produced
8
8
  # rather than trusted. Two facts, each independently checkable from
9
9
  # `history[:outbox_traces]` (`Replay#call`'s own before/after
10
10
  # capture, one entry per step whose dispatch enqueued at least one
11
11
  # row):
12
12
  #
13
- # 1. "DELIVERY IS INLINE BY DEFAULT" — a row THIS replay's own
13
+ # 1. "delivery is inline by default" — a row this replay's own
14
14
  # dispatch enqueued must not still be `pending`/`claimed` once
15
- # that SAME call returns (nothing here ever simulates a
15
+ # that same call returns (nothing here ever simulates a
16
16
  # crash), and must not be `failed` either — `deliver_row`'s
17
17
  # own rescue only reaches `failed` for a genuine defect in the
18
- # RELAY's own consumer resolution (a row naming a policy/
18
+ # relay's own consumer resolution (a row naming a policy/
19
19
  # process_manager `run_consumer`'s own independent registry
20
20
  # lookup cannot find — `WiringError`), never an ordinary
21
21
  # domain refusal (`PolicyInterpreter#deliver`/`SagaInterpreter#
22
- # advance` both rescue those THEMSELVES, recording `delivered:
22
+ # advance` both rescue those themselves, recording `delivered:
23
23
  # false` on the reaction/saga log and letting `run_consumer`
24
24
  # return normally). Both checked for every row, `saga:` and
25
25
  # `policy:` alike.
26
26
  #
27
- # 2. A `policy:` ROW SPECIFICALLY — `PolicyInterpreter#deliver`
27
+ # 2. A `policy:` row specifically — `PolicyInterpreter#deliver`
28
28
  # returns `nil` (no `reaction_log` entry appended at all)
29
- # EXACTLY when its own `where` (or, for a fan-out policy, the
30
- # SAME `where`, gating the whole `for_each`) does not hold;
31
- # every OTHER outcome (delivered, refused, a defect,
29
+ # exactly when its own `where` (or, for a fan-out policy, the
30
+ # same `where`, gating the whole `for_each`) does not hold;
31
+ # every other outcome (delivered, refused, a defect,
32
32
  # reaction-depth-reached) is still a non-nil record `#react`
33
- # appends. So a `delivered` policy row with NO matching
34
- # `reaction_log` entry is legitimate ONLY when that policy's
35
- # own `where`, independently RE-EVALUATED here against the
33
+ # appends. So a `delivered` policy row with no matching
34
+ # `reaction_log` entry is legitimate only when that policy's
35
+ # own `where`, independently re-evaluated here against the
36
36
  # row's own recorded event, genuinely does not hold. A
37
- # `for_each` policy's own fan-out correctness (how MANY rows
37
+ # `for_each` policy's own fan-out correctness (how many rows
38
38
  # it should have dispatched to) is `fanout_dispatches_once_
39
39
  # per_matching_row`'s job, not this one's.
40
40
  #
41
- # A `saga:` ROW HAS NO EQUIVALENT SECOND CHECK, DELIBERATELY — this
42
- # was the first shape this property shipped with, and it was WRONG,
41
+ # A `saga:` row has no equivalent second check, deliberately — this
42
+ # was the first shape this property shipped with, and it was wrong,
43
43
  # caught live against `examples/banking` before this comment
44
44
  # existed: `Fanout.sagas`' own `listens?` (starts_on/ends_on/
45
- # handler_for matching the event NAME alone) says nothing about
46
- # whether a CORRELATION resolves or a LIVE INSTANCE exists, and
45
+ # handler_for matching the event name alone) says nothing about
46
+ # whether a correlation resolves or a live instance exists, and
47
47
  # `begin_saga`/`end_saga` (saga_interpreter.rb) both have silent,
48
- # perfectly ordinary no-op paths that append NOTHING to `saga_log`
48
+ # perfectly ordinary no-op paths that append nothing to `saga_log`
49
49
  # — `begin_saga` when an instance under that correlation already
50
- # exists, `end_saga` when NO live instance exists to end (an
50
+ # exists, `end_saga` when no live instance exists to end (an
51
51
  # `AccountOpened` fired by opening an account directly, bypassing
52
52
  # the onboarding flow whose `ends_on` names that same event,
53
53
  # reproduces this exactly: `Fanout.listens?` enqueues the row
54
- # because the event NAME matches `ends_on`, `end_saga` finds
54
+ # because the event name matches `ends_on`, `end_saga` finds
55
55
  # nothing under that correlation to delete, and neither logs a
56
56
  # word). A `saga:` row draining to `delivered` with zero matching
57
- # `saga_log` entries is therefore NOT a finding — only check 1
57
+ # `saga_log` entries is therefore not a finding — only check 1
58
58
  # applies to it.
59
59
  #
60
- # NOT A GRAMMAR CONSTRUCT — `FEATURE_COVERAGE`'s own `dry_runs_
60
+ # **Not a grammar construct** — `FEATURE_COVERAGE`'s own `dry_runs_
61
61
  # leave_no_trace` precedent: the outbox is a runtime door
62
62
  # (`Runtime::Outbox`), not a word a bluebook declares, so there is
63
63
  # no feature string here to claim.
@@ -117,14 +117,14 @@ module Hecks
117
117
  # with itself (the same rule `resolve_dispatch_binding`'s own
118
118
  # comment states). `Evaluator.call` (the raw-string entry, parsed
119
119
  # and cached — never `call_rule`, which needs the policy's own
120
- # BUILD-TIME `where_rule` AST, an object this history has no
120
+ # build-time `where_rule` AST, an object this history has no
121
121
  # reason to carry) is the exact same call `Replay#fan_out_finding`
122
122
  # already makes for the identical fact one property over
123
123
  # (`policy.where.to_s.empty? || Evaluator.call(policy.where, {},
124
124
  # payload)`), reused rather than re-derived a second, slightly
125
125
  # different way. `rescue`d to `nil`, not `false`: a where clause
126
126
  # that cannot be re-evaluated from the row's own recorded payload
127
- # alone is INCONCLUSIVE, not proof either way — the same "never a
127
+ # alone is inconclusive, not proof either way — the same "never a
128
128
  # claimed pass or a claimed mismatch from a resolution this replay
129
129
  # cannot actually reproduce" discipline `build_guard_check`'s own
130
130
  # rescue clause already follows.
@@ -10,7 +10,7 @@ module Hecks
10
10
  # (#query_for_verb, #query_eligible_rows, #resolve_hop_clause) other
11
11
  # property modules in this directory also call.
12
12
  module Querying
13
- # THE QUERY ORACLE — differential testing within the one runtime,
13
+ # The query oracle — differential testing within the one runtime,
14
14
  # the shape the retired cross-runtime harness should always have
15
15
  # been. Every generated ask was answered twice at the same instant
16
16
  # (Replay records both): once through whatever the aggregate is
@@ -18,17 +18,17 @@ module Hecks
18
18
  # a SQL binding would compile it), once through the reference
19
19
  # interpreter's own evaluation. The two are separate, live
20
20
  # implementations of the same comparator vocabulary, and they have
21
- # drifted before — an adapter that ACCEPTS what the reference says
21
+ # drifted before — an adapter that accepts what the reference says
22
22
  # matches nothing, or orders what it refuses to order, shows up
23
23
  # here as a finding no self-referential adapter spec could see.
24
24
  # M23 — `Replay` now runs the native and reference engines
25
- # INDEPENDENTLY (each in its own begin/rescue — see that file's own
25
+ # independently (each in its own begin/rescue — see that file's own
26
26
  # comment at the capture site), so this property can tell apart what
27
27
  # used to be indistinguishable: "both engines refused" (fine — the
28
28
  # ask was genuinely bad, nothing to compare) from "one refused and
29
29
  # the other did not" (a real divergence — the two engines disagree
30
- # about whether the ask was even VALID, never mind what it answers).
31
- # `native_refused`/`reference_refused` are read by KEY PRESENCE, not
30
+ # about whether the ask was even valid, never mind what it answers).
31
+ # `native_refused`/`reference_refused` are read by key presence, not
32
32
  # truthiness — `Replay` only ever adds `:error`/`:reference_error`
33
33
  # to an entry when that side actually raised, so an absent key is an
34
34
  # unambiguous "this side answered." A read-model ask (no reference
@@ -59,16 +59,16 @@ module Hecks
59
59
  offenders.empty? || offenders.join("; ")
60
60
  end
61
61
 
62
- # THE SAME "TWO ENGINES, COMPARED" SHAPE query_answers_match_reference
62
+ # The same "two engines, compared" shape query_answers_match_reference
63
63
  # already uses, aimed squarely at Query#options' offset/limit pair —
64
- # but recomputed from history[:instances] directly, a THIRD,
64
+ # but recomputed from history[:instances] directly, a third,
65
65
  # independent computation, rather than comparing QueryInterpreter's
66
66
  # own native and reference paths against each other (which could
67
67
  # share the identical bug neither implementation happened to hit —
68
- # see #4's own fix, which touched BOTH #interpret and
68
+ # see #4's own fix, which touched both #interpret and
69
69
  # #reference_interpret at once). `order_by` declared alongside
70
70
  # `offset` or `limit` names a genuinely paged query. Ports::Query::
71
- # Ordering.apply is the SAME engine QueryInterpreter#ordered calls,
71
+ # Ordering.apply is the same engine QueryInterpreter#ordered calls,
72
72
  # reused here rather than re-derived, so this oracle cannot drift
73
73
  # from what "in order" means without the interpreter drifting the
74
74
  # identical way — only the offset-then-limit .drop/.first slice
@@ -112,7 +112,7 @@ module Hecks
112
112
  offenders.empty? || offenders.join("; ")
113
113
  end
114
114
 
115
- # THE DECLARED Query ITSELF, resolved from a replayed verb — the
115
+ # The declared Query itself, resolved from a replayed verb — the
116
116
  # same shape #command_for_verb resolves a command by, one
117
117
  # construct over. Entity-level queries (a dotted query_path) are
118
118
  # out of scope here — paging on an entity's own list has no real
@@ -128,24 +128,24 @@ module Hecks
128
128
  aggregate&.query(query_path)
129
129
  end
130
130
 
131
- # A QUERY'S OWN ROWS — unlike #eligible_rows (a ReadModel's
131
+ # A query's own rows — unlike #eligible_rows (a ReadModel's
132
132
  # reduced/grouped many-side head, possibly FK-joined against a
133
- # root), a Query always asks about its OWN owning aggregate
133
+ # root), a Query always asks about its own owning aggregate
134
134
  # directly ; no join, no reference_target. `id:` merged in the
135
135
  # same way #eligible_rows' own rows are, since a stable sort
136
136
  # (Ordering.apply's own `identity:`) and the real answer's own
137
137
  # `record.state.merge(id: record.id)` both need it.
138
- # `bluebooks:` — needed ONLY to recognise and resolve a `/` HOP
138
+ # `bluebooks:` — needed only to recognise and resolve a `/` hop
139
139
  # clause (`engagement/client/status`, hop_chain.bluebook's own
140
- # PricedAboveViaEngagement): a hop's head names one of the OWNING
140
+ # PricedAboveViaEngagement): a hop's head names one of the owning
141
141
  # aggregate's declared references, and only the declaration graph
142
142
  # can say which attribute that is and which aggregate it targets.
143
143
  # A local clause never consults it. Latent gap this closed, found
144
144
  # by the fuzzer itself the first time a generated sequence ever
145
- # built a full hop chain AND had its paged query answer a row
145
+ # built a full hop chain and had its paged query answer a row
146
146
  # (seed 1, the moment scalar_value_objects.bluebook joined the
147
147
  # fixtures corpus and shifted every seeded draw): the recompute
148
- # dug `engagement/client/status` as a LOCAL dotted path, found
148
+ # dug `engagement/client/status` as a local dotted path, found
149
149
  # nil, and declared every genuinely-eligible row ineligible — a
150
150
  # false property violation against a correct runtime answer,
151
151
  # reproducible on an untouched main with this same 4-step script.
@@ -173,7 +173,7 @@ module Hecks
173
173
  # would be checking the runtime against itself). One hop peels
174
174
  # off the head (`HopPath.next_hop`, the identical one-step
175
175
  # primitive the live fold uses), the inner clause recurses
176
- # through `query_eligible_rows` against the TARGET's own
176
+ # through `query_eligible_rows` against the target's own
177
177
  # snapshot rows (so a multi-hop tail resolves hop by hop, exactly
178
178
  # as the live path's own recursion does), and the ids that
179
179
  # answered fold back as the same local `in` membership clause the