hecks 2.8.0 → 2.9.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 (404) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +4 -6
  3. data/lib/hecks/adapters/driven/claude_code.rb +4 -104
  4. data/lib/hecks/adapters/driven/d1.rb +44 -237
  5. data/lib/hecks/adapters/driven/folder.rb +17 -76
  6. data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
  7. data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
  8. data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
  9. data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
  10. data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
  11. data/lib/hecks/adapters/driven/heki.rb +13 -42
  12. data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
  13. data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
  14. data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
  15. data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
  16. data/lib/hecks/adapters/driven/lambda.rb +10 -84
  17. data/lib/hecks/adapters/driven/local_storage.rb +5 -40
  18. data/lib/hecks/adapters/driven/memory.rb +17 -98
  19. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
  20. data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
  21. data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
  22. data/lib/hecks/adapters/driven/postgres/reconnect.rb +4 -30
  23. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
  24. data/lib/hecks/adapters/driven/postgres.rb +145 -134
  25. data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
  26. data/lib/hecks/adapters/driven/prism.rb +7 -30
  27. data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
  28. data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
  29. data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
  30. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
  31. data/lib/hecks/adapters/driven/sqlite.rb +128 -65
  32. data/lib/hecks/adapters/driven/tenant_provisioner.rb +5 -48
  33. data/lib/hecks/adapters/driven.rb +5 -36
  34. data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
  35. data/lib/hecks/behaviors/dsl.rb +7 -25
  36. data/lib/hecks/behaviors/expectations.rb +31 -141
  37. data/lib/hecks/behaviors/ir.rb +7 -20
  38. data/lib/hecks/behaviors/rspec.rb +6 -17
  39. data/lib/hecks/behaviors/runner.rb +10 -34
  40. data/lib/hecks/behaviors.rb +4 -8
  41. data/lib/hecks/bluebook/aggregate.rb +9 -75
  42. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
  43. data/lib/hecks/bluebook/assembly/build.rb +4 -15
  44. data/lib/hecks/bluebook/assembly/contract.rb +15 -136
  45. data/lib/hecks/bluebook/assembly/contracts.rb +54 -174
  46. data/lib/hecks/bluebook/assembly/marks.rb +31 -223
  47. data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
  48. data/lib/hecks/bluebook/assembly.rb +6 -45
  49. data/lib/hecks/bluebook/attribute.rb +12 -61
  50. data/lib/hecks/bluebook/behaviour/aggregate.rb +10 -39
  51. data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
  52. data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
  53. data/lib/hecks/bluebook/behaviour/command.rb +14 -66
  54. data/lib/hecks/bluebook/behaviour/domain_port.rb +4 -20
  55. data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
  56. data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
  57. data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
  58. data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
  59. data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
  60. data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
  61. data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
  62. data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
  63. data/lib/hecks/bluebook/capabilities.rb +17 -49
  64. data/lib/hecks/bluebook/chapter.rb +10 -48
  65. data/lib/hecks/bluebook/command.rb +23 -81
  66. data/lib/hecks/bluebook/domain_port.rb +14 -63
  67. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
  68. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
  69. data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
  70. data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
  71. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +86 -708
  72. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +56 -170
  73. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +1 -0
  74. data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
  75. data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
  76. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +12 -87
  77. data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
  78. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
  79. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +26 -194
  80. data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
  81. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
  82. data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
  83. data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
  84. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
  85. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
  86. data/lib/hecks/bluebook/dsl/query_builder.rb +11 -42
  87. data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
  88. data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
  89. data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
  90. data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
  91. data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
  92. data/lib/hecks/bluebook/dsl/world_builder.rb +19 -111
  93. data/lib/hecks/bluebook/entity.rb +13 -71
  94. data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
  95. data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
  96. data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
  97. data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
  98. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
  99. data/lib/hecks/bluebook/expression/resolver.rb +37 -660
  100. data/lib/hecks/bluebook/hexagon.rb +5 -28
  101. data/lib/hecks/bluebook/lifecycle.rb +5 -16
  102. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
  103. data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
  104. data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
  105. data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
  106. data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
  107. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +24 -176
  108. data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
  109. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +43 -305
  110. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
  111. data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
  112. data/lib/hecks/bluebook/meta_validator.rb +79 -349
  113. data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
  114. data/lib/hecks/bluebook/model_check.rb +100 -597
  115. data/lib/hecks/bluebook/pattern_subset.rb +11 -69
  116. data/lib/hecks/bluebook/process_manager.rb +13 -83
  117. data/lib/hecks/bluebook/project_loader.rb +3 -39
  118. data/lib/hecks/bluebook/project_register.rb +12 -60
  119. data/lib/hecks/bluebook/query.rb +9 -48
  120. data/lib/hecks/bluebook/read_model.rb +57 -81
  121. data/lib/hecks/bluebook/reference.rb +7 -41
  122. data/lib/hecks/bluebook/smoke_test.rb +8 -98
  123. data/lib/hecks/bluebook/synthesizer.rb +13 -62
  124. data/lib/hecks/bluebook/translation.rb +26 -62
  125. data/lib/hecks/bluebook/value_object.rb +11 -36
  126. data/lib/hecks/bluebook.rb +5 -22
  127. data/lib/hecks/cache_dir.rb +4 -23
  128. data/lib/hecks/cli/document.rb +3 -21
  129. data/lib/hecks/cli/ir.rb +3 -5
  130. data/lib/hecks/cli/mcp.rb +2 -3
  131. data/lib/hecks/cli/mcp_door.rb +19 -114
  132. data/lib/hecks/cli/model_check.rb +18 -85
  133. data/lib/hecks/cli/project_cli.rb +7 -40
  134. data/lib/hecks/cli/project_diagrams.rb +0 -7
  135. data/lib/hecks/cli/run.rb +12 -58
  136. data/lib/hecks/cli/smoke_test.rb +2 -16
  137. data/lib/hecks/cli/stores.rb +1 -2
  138. data/lib/hecks/cli.rb +18 -24
  139. data/lib/hecks/construct.rb +8 -34
  140. data/lib/hecks/deploy/bluebook/deploy.bluebook +33 -142
  141. data/lib/hecks/deploy/bluebook/deploy.hecksagon +2 -9
  142. data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
  143. data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
  144. data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
  145. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
  146. data/lib/hecks/embryonaut_bluebook.rb +4 -71
  147. data/lib/hecks/facade/cli_door.rb +24 -106
  148. data/lib/hecks/facade/cli_runner.rb +28 -172
  149. data/lib/hecks/facade/command_request.rb +13 -33
  150. data/lib/hecks/facade/handle.rb +34 -121
  151. data/lib/hecks/facade/json_door.rb +31 -146
  152. data/lib/hecks/facade/surface/aggregate_door.rb +39 -104
  153. data/lib/hecks/facade/surface/chapter.rb +10 -54
  154. data/lib/hecks/facade/surface.rb +8 -23
  155. data/lib/hecks/facade.rb +10 -25
  156. data/lib/hecks/forms/app.rb +15 -70
  157. data/lib/hecks/forms/command_form_renderer.rb +10 -29
  158. data/lib/hecks/forms/field_renderer.rb +17 -156
  159. data/lib/hecks/forms/field_shape.rb +30 -222
  160. data/lib/hecks/forms/html.rb +12 -47
  161. data/lib/hecks/forms/index_renderer.rb +1 -4
  162. data/lib/hecks/forms/page.rb +3 -9
  163. data/lib/hecks/forms/params.rb +14 -60
  164. data/lib/hecks/forms/port_argument.rb +2 -19
  165. data/lib/hecks/forms/query_form_renderer.rb +4 -79
  166. data/lib/hecks/forms/record_renderer.rb +8 -75
  167. data/lib/hecks/forms/record_table.rb +7 -50
  168. data/lib/hecks/forms/reference_options.rb +3 -30
  169. data/lib/hecks/forms/value_object_shape.rb +8 -35
  170. data/lib/hecks/forms.rb +5 -33
  171. data/lib/hecks/fqn.rb +5 -12
  172. data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
  173. data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
  174. data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
  175. data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
  176. data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
  177. data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
  178. data/lib/hecks/framework.rb +11 -80
  179. data/lib/hecks/freezer.rb +5 -39
  180. data/lib/hecks/grammar/expression.bluebook +15 -40
  181. data/lib/hecks/grammar/translation.bluebook +3 -6
  182. data/lib/hecks/grammar.rb +16 -41
  183. data/lib/hecks/ir.rb +14 -83
  184. data/lib/hecks/language/adapter.bluebook +2 -7
  185. data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
  186. data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
  187. data/lib/hecks/language/bluebook/bluebook.bluebook +15 -83
  188. data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
  189. data/lib/hecks/language/bluebook/command.bluebook +27 -144
  190. data/lib/hecks/language/bluebook/entity.bluebook +24 -97
  191. data/lib/hecks/language/bluebook/policy.bluebook +16 -67
  192. data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
  193. data/lib/hecks/language/bluebook/projection.bluebook +126 -60
  194. data/lib/hecks/language/bluebook/query.bluebook +12 -43
  195. data/lib/hecks/language/bluebook/shape.bluebook +23 -73
  196. data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
  197. data/lib/hecks/language/bluebook/vocabulary.bluebook +82 -197
  198. data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
  199. data/lib/hecks/language/hecksagon/domain_port.bluebook +4 -19
  200. data/lib/hecks/language/hecksagon/hecksagon.bluebook +6 -25
  201. data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
  202. data/lib/hecks/language/oidc.json +35 -0
  203. data/lib/hecks/language/port.bluebook +4 -17
  204. data/lib/hecks/language/translation/translation.bluebook +3 -9
  205. data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
  206. data/lib/hecks/language/world/wiring.bluebook +1 -3
  207. data/lib/hecks/language/world/world.bluebook +5 -7
  208. data/lib/hecks/literal.rb +8 -50
  209. data/lib/hecks/mcp_door_scope.rb +9 -90
  210. data/lib/hecks/mcp_stdio_guard.rb +4 -41
  211. data/lib/hecks/naming.rb +29 -137
  212. data/lib/hecks/ports/access_control.rb +7 -23
  213. data/lib/hecks/ports/agent/answers.rb +5 -23
  214. data/lib/hecks/ports/agent.rb +47 -172
  215. data/lib/hecks/ports/authentication.rb +12 -39
  216. data/lib/hecks/ports/authorization.rb +16 -43
  217. data/lib/hecks/ports/clock.rb +5 -45
  218. data/lib/hecks/ports/extraction.rb +7 -12
  219. data/lib/hecks/ports/identity_assignment.rb +8 -29
  220. data/lib/hecks/ports/identity_generation.rb +6 -29
  221. data/lib/hecks/ports/identity_resolution.rb +2 -10
  222. data/lib/hecks/ports/key_vault.rb +9 -45
  223. data/lib/hecks/ports/persistence/append_only.rb +61 -64
  224. data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
  225. data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
  226. data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
  227. data/lib/hecks/ports/persistence/plugin.rb +13 -42
  228. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +38 -141
  229. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
  230. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +16 -84
  231. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
  232. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +3 -22
  233. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
  234. data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
  235. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
  236. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
  237. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
  238. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
  239. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
  240. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
  241. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +18 -75
  242. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
  243. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
  244. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
  245. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
  246. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
  247. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +14 -115
  248. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
  249. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +127 -554
  250. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
  251. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
  252. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
  253. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
  254. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
  255. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
  256. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +9 -25
  257. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
  258. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
  259. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
  260. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
  261. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
  262. data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
  263. data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
  264. data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
  265. data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
  266. data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
  267. data/lib/hecks/ports/persistence/state_codec.rb +23 -103
  268. data/lib/hecks/ports/persistence.rb +7 -14
  269. data/lib/hecks/ports/projection.rb +42 -84
  270. data/lib/hecks/ports/query/in_memory.rb +10 -58
  271. data/lib/hecks/ports/query/ordering.rb +11 -32
  272. data/lib/hecks/ports/query.rb +14 -37
  273. data/lib/hecks/ports.rb +2 -8
  274. data/lib/hecks/projections/bootstrap_table.rb +11 -43
  275. data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
  276. data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
  277. data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
  278. data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
  279. data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
  280. data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
  281. data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
  282. data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
  283. data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
  284. data/lib/hecks/projections/deploy/fargate.rb +35 -202
  285. data/lib/hecks/projections/deploy/lambda.rb +150 -678
  286. data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
  287. data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
  288. data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
  289. data/lib/hecks/projections/deploy/preview/script.rb +2 -14
  290. data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
  291. data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
  292. data/lib/hecks/projections/deploy/preview/template.rb +2 -58
  293. data/lib/hecks/projections/deploy/preview.rb +2 -67
  294. data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
  295. data/lib/hecks/projections/deploy/scripts.rb +4 -57
  296. data/lib/hecks/projections/deploy/shared.rb +47 -146
  297. data/lib/hecks/projections/deploy/smoke.rb +4 -61
  298. data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
  299. data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
  300. data/lib/hecks/projections/deploy/template_diff.rb +5 -57
  301. data/lib/hecks/projections/diagrams.rb +20 -582
  302. data/lib/hecks/projections/glossary/html.rb +14 -130
  303. data/lib/hecks/projections/glossary/markdown.rb +8 -69
  304. data/lib/hecks/projections/glossary/mermaid.rb +9 -66
  305. data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
  306. data/lib/hecks/projections/glossary/sentences.rb +14 -159
  307. data/lib/hecks/projections/glossary.rb +30 -222
  308. data/lib/hecks/projections/ir.rb +3 -10
  309. data/lib/hecks/projections/model/deviations.rb +15 -42
  310. data/lib/hecks/projections/model.rb +12 -51
  311. data/lib/hecks/projections/oidc.rb +12 -56
  312. data/lib/hecks/projections/parser_table.rb +9 -28
  313. data/lib/hecks/projections/reference.rb +2 -15
  314. data/lib/hecks/projections/rust_vocabulary.rb +12 -250
  315. data/lib/hecks/projections/shape.rb +3 -29
  316. data/lib/hecks/projections/statements.rb +7 -86
  317. data/lib/hecks/projections/vocabulary.rb +6 -22
  318. data/lib/hecks/projections.rb +2 -16
  319. data/lib/hecks/projector/cli_projector.rb +60 -375
  320. data/lib/hecks/projector/docs_projector.rb +10 -201
  321. data/lib/hecks/projector/exporter.rb +42 -134
  322. data/lib/hecks/projector/ir_projector.rb +2 -9
  323. data/lib/hecks/projector/narrate_projector.rb +15 -189
  324. data/lib/hecks/projector/target.rb +13 -76
  325. data/lib/hecks/projector.rb +30 -121
  326. data/lib/hecks/query_specification/common/comparators.rb +5 -26
  327. data/lib/hecks/query_specification/common/comparison.rb +35 -143
  328. data/lib/hecks/query_specification/common/dsl.rb +8 -24
  329. data/lib/hecks/query_specification/common/null_policy.rb +20 -70
  330. data/lib/hecks/query_specification/common/options.rb +2 -6
  331. data/lib/hecks/query_specification/common/where_clause.rb +2 -10
  332. data/lib/hecks/query_specification/field_path.rb +37 -77
  333. data/lib/hecks/query_specification/hop_path.rb +12 -76
  334. data/lib/hecks/release/gem_pin.rb +2 -26
  335. data/lib/hecks/release/runner/ci_publisher.rb +3 -6
  336. data/lib/hecks/release/runner/commands.rb +2 -4
  337. data/lib/hecks/release/runner/gem_publisher.rb +2 -3
  338. data/lib/hecks/release/runner/npm_publisher.rb +6 -20
  339. data/lib/hecks/release/runner/preflight.rb +4 -19
  340. data/lib/hecks/release/runner/tagger.rb +2 -9
  341. data/lib/hecks/release/runner.rb +3 -32
  342. data/lib/hecks/rendering.rb +4 -26
  343. data/lib/hecks/router/namespace_installer.rb +12 -36
  344. data/lib/hecks/router.rb +4 -8
  345. data/lib/hecks/runtime/aggregate_lock.rb +8 -33
  346. data/lib/hecks/runtime/boot_gates.rb +3 -18
  347. data/lib/hecks/runtime/caller.rb +19 -59
  348. data/lib/hecks/runtime/capability_graph.rb +5 -21
  349. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
  350. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +23 -160
  351. data/lib/hecks/runtime/command_interpreter.rb +124 -306
  352. data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
  353. data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
  354. data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
  355. data/lib/hecks/runtime/command_rules/emission.rb +8 -21
  356. data/lib/hecks/runtime/command_rules/references.rb +23 -202
  357. data/lib/hecks/runtime/dependency_planning.rb +30 -102
  358. data/lib/hecks/runtime/dispatcher.rb +82 -241
  359. data/lib/hecks/runtime/entity_element.rb +40 -462
  360. data/lib/hecks/runtime/entity_interpreter.rb +64 -219
  361. data/lib/hecks/runtime/errors.rb +32 -115
  362. data/lib/hecks/runtime/event.rb +3 -25
  363. data/lib/hecks/runtime/identity.rb +18 -154
  364. data/lib/hecks/runtime/instance.rb +18 -150
  365. data/lib/hecks/runtime/interpreting.rb +11 -70
  366. data/lib/hecks/runtime/invocation.rb +28 -164
  367. data/lib/hecks/runtime/loader.rb +48 -186
  368. data/lib/hecks/runtime/outbox.rb +38 -261
  369. data/lib/hecks/runtime/policy_interpreter.rb +38 -200
  370. data/lib/hecks/runtime/port_operation_interpreter.rb +26 -87
  371. data/lib/hecks/runtime/query_interpreter.rb +45 -187
  372. data/lib/hecks/runtime/reaction_invocation.rb +36 -138
  373. data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
  374. data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
  375. data/lib/hecks/runtime/reference_hop.rb +8 -81
  376. data/lib/hecks/runtime/refusal_wording.rb +8 -89
  377. data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
  378. data/lib/hecks/runtime/registry/verification.rb +52 -225
  379. data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
  380. data/lib/hecks/runtime/registry.rb +99 -244
  381. data/lib/hecks/runtime/remote_dispatcher.rb +37 -152
  382. data/lib/hecks/runtime/routing.rb +4 -15
  383. data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
  384. data/lib/hecks/runtime/saga_interpreter.rb +79 -263
  385. data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
  386. data/lib/hecks/runtime/tenant_check.rb +6 -68
  387. data/lib/hecks/runtime/tenant_scope.rb +3 -28
  388. data/lib/hecks/runtime/value/admission.rb +16 -67
  389. data/lib/hecks/runtime/value/coercion.rb +155 -641
  390. data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
  391. data/lib/hecks/runtime/value.rb +12 -84
  392. data/lib/hecks/runtime.rb +17 -65
  393. data/lib/hecks/storehouse.rb +141 -568
  394. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +8 -32
  395. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
  396. data/lib/hecks/vendoring/git_environment.rb +2 -8
  397. data/lib/hecks/vendoring/git_source.rb +4 -10
  398. data/lib/hecks/vendoring.rb +7 -46
  399. data/lib/hecks/version.rb +3 -14
  400. data/lib/hecks.rb +26 -81
  401. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
  402. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
  403. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
  404. metadata +3 -2
@@ -5,22 +5,9 @@ require_relative "sensitivity"
5
5
  module Hecks
6
6
  module Projections
7
7
  module Glossary
8
- # Every sentence the glossary says, and the rule each one obeys.
9
- #
10
- # Authored text is verbatim: an aggregate's `description`, a
11
- # command's `goal`, a query's `description`, an invariant's own
12
- # words. Derived text is mechanical, from one declared fact, in a
13
- # shape a reader outside engineering would say — "Recorded after
14
- # Freeze account", "Made up of an amount (a whole number) and a
15
- # currency (text)". Nothing is paraphrased and nothing is guessed:
16
- # a fact with no honest plain phrasing gets no sentence (the
17
- # `DocsProjector` rule — a wrong sentence is worse than none).
18
- #
19
- # Cross-references come only from declared structure (a command's
20
- # `emits:`, a policy's `on`/`trigger`), resolved through the
21
- # document's `Index`; free prose is never searched for words to
22
- # link. A reference the chapter does not declare (a cross-domain
23
- # command) is spoken as plain words.
8
+ # Every sentence the glossary says. Authored text is verbatim; derived text is built
9
+ # mechanically from one declared fact, and a fact with no plain phrasing gets none.
10
+ # Links come only from declared structure, never from searching prose.
24
11
  module Sentences
25
12
  TYPE_WORDS = {
26
13
  "Integer" => "a whole number", "Float" => "a number", "String" => "text",
@@ -29,13 +16,6 @@ module Hecks
29
16
 
30
17
  module_function
31
18
 
32
- # The paragraphs under a term's headword — the definition first,
33
- # then, when the term carries rules, one "Always true: …" line.
34
- #
35
- # @param entry [Glossary::Entry] the term to render
36
- # @param index [Glossary::Index] the document's link index
37
- # @return [Array<String>] one or more paragraphs, compacted of any that
38
- # have nothing to say (such as an entity with no lifecycle)
39
19
  def paragraphs(entry, index)
40
20
  facts = entry.facts
41
21
  case entry.kind
@@ -51,56 +31,24 @@ module Hecks
51
31
  end.compact
52
32
  end
53
33
 
54
- # An aggregate's lede or an entity's entry: what it is, then the
55
- # states it can be in.
56
- #
57
- # @param holder [Bluebook::Aggregate, Bluebook::Entity] the holder to describe
58
- # @return [Array<String>] `holder`'s description, then its lifecycle sentence;
59
- # either or both may be absent
60
34
  def holder_paragraphs(holder)
61
35
  [holder.description, holder.lifecycle && lifecycle_sentence(holder.lifecycle)].compact
62
36
  end
63
37
 
64
- # Describes a lifecycle's starting state and every state it can reach.
65
- #
66
- # @param lifecycle [Bluebook::Lifecycle] the state machine to describe
67
- # @return [String] what state it starts in and every state it can reach
68
38
  def lifecycle_sentence(lifecycle)
69
39
  states = ([lifecycle.default] + lifecycle.transitions.map { |_name, transition| transition.target }).uniq
70
40
  "Starts out #{spoken(lifecycle.default)}. " \
71
41
  "Can be #{Naming.to_sentence_list(states.map { |state| spoken(state) }, conj: 'or')}."
72
42
  end
73
43
 
74
- # A state name is spelled `awaiting_credit`; said, it is "awaiting credit".
75
- #
76
- # @param state [String, Symbol] a state name
77
- # @return [String] `state` with underscores turned to spaces
78
44
  def spoken(state) = state.to_s.tr("_", " ")
79
45
 
80
- # Renders a value object's definition, and its rules if it has any.
81
- #
82
- # @param value_object [Bluebook::ValueObject] the value object to describe
83
- # @param index [Glossary::Index] the document's link index
84
- # @param within [String, nil] the value object's own holder's name, for
85
- # resolving a nested value object's own type link
86
- # @param sensitive [Hash{String => Hash{Symbol => String}}] each marked field's
87
- # name, mapped to its marking (as `Sensitivity.for_value_object` builds)
88
- # @return [Array<String>] the value object's definition sentence, then its
89
- # "Always true: …" rules line; the rules line is absent when it has none
90
46
  def value_object_paragraphs(value_object, index, within, sensitive = {})
91
47
  rules = value_object.invariants.map { |invariant| Statements.invariant_statement(invariant) }
92
48
  [value_object_sentence(value_object, index, within, sensitive), rules_line(rules)].compact
93
49
  end
94
50
 
95
- # A one-field object whose field is just "value" is its type —
96
- # "Text.", "A whole number." — the field name would add nothing.
97
- #
98
- # @param value_object [Bluebook::ValueObject] the value object to describe
99
- # @param index [Glossary::Index] the document's link index
100
- # @param within [String, nil] the value object's own holder's name
101
- # @param sensitive [Hash{String => Hash{Symbol => String}}] each marked field's
102
- # name, mapped to its marking
103
- # @return [String] the value object's definition sentence
51
+ # A one-field object whose field is just "value" reads as its type ("Text.").
104
52
  def value_object_sentence(value_object, index, within, sensitive = {})
105
53
  return closed_set_sentence(value_object.members) if value_object.closed_set?
106
54
  return "A marker with no details of its own." if value_object.attributes.empty?
@@ -114,41 +62,20 @@ module Hecks
114
62
  "Made up of #{Naming.to_sentence_list(fields)}."
115
63
  end
116
64
 
117
- # "amount (a whole number)" — the field as the author named it,
118
- # then what kind of thing goes in it, then the tag of any marking
119
- # that flags it sensitive: "medications (text, PHI)".
120
- #
121
- # @param field [Bluebook::Attribute] the field to describe
122
- # @param index [Glossary::Index] the document's link index
123
- # @param within [String, nil] the field's own holder's name
124
- # @param marking [Hash{Symbol => String}, nil] the marking that flags `field`
125
- # sensitive, if any
126
- # @return [String] the field's name, spoken, with its type (and tag) in parentheses
65
+ # "amount (a whole number)", or "medications (text, PHI)" when marked sensitive.
127
66
  def field_phrase(field, index, within, marking = nil)
128
67
  detail = [type_words(field, index, within), (Sensitivity.tag(marking) if marking)].compact.join(", ")
129
68
  "#{Naming.words(field.name).downcase} (#{detail})"
130
69
  end
131
70
 
132
- # Describes one field's type in plain words.
133
- #
134
- # @param field [Bluebook::Attribute] the field to describe
135
- # @param index [Glossary::Index] the document's link index
136
- # @param within [String, nil] the field's own holder's name
137
- # @return [String] the field's type in plain words, or a link to its value
138
- # object's own headword; "a list of …" when the field is a list
139
71
  def type_words(field, index, within)
140
72
  type = field.type.to_s
141
73
  inner = TYPE_WORDS[type] || index.link(:value_object, type, within: within)
142
74
  field.list? ? "a list of #{inner}" : inner
143
75
  end
144
76
 
145
- # A closed set's rows — a one-field set is its values; a set
146
- # whose rows carry more (StatementFrequency's cadence plus a
147
- # retention and a fee) leads with the first field and keeps the
148
- # rest beside it, so no row loses what makes it distinct.
149
- #
150
- # @param members [Array<Hash{Symbol => Object}>] the closed set's member rows
151
- # @return [String] "One of: …" (multi-field rows) or "One of …" (single-field)
77
+ # A multi-field row leads with its first field and keeps the rest beside it,
78
+ # so no row loses what makes it distinct.
152
79
  def closed_set_sentence(members)
153
80
  if members.first && members.first.size > 1
154
81
  rows = members.map do |row|
@@ -161,14 +88,7 @@ module Hecks
161
88
  end
162
89
  end
163
90
 
164
- # "Always true: an amount is positive; a currency is a three-letter
165
- # code." — the rules as their author wrote them, kept out of the
166
- # definition sentence (a rule hidden inside a definition is a rule
167
- # a reader misses).
168
- #
169
- # @param rules [Array<String>] rendered invariant sentences
170
- # @return [String, nil] "Always true: …" joining every rule, or nil if
171
- # `rules` is empty
91
+ # Kept apart from the definition sentence, where a reader would miss a rule.
172
92
  def rules_line(rules)
173
93
  return nil if rules.empty?
174
94
 
@@ -176,11 +96,6 @@ module Hecks
176
96
  "Always true: #{clauses.join('; ')}."
177
97
  end
178
98
 
179
- # Describes a command's goal and who does it.
180
- #
181
- # @param command [Bluebook::Command] the command to describe
182
- # @return [String, nil] the command's goal and/or its role sentence, or nil
183
- # if it declares neither
184
99
  def command_sentence(command)
185
100
  parts = []
186
101
  parts << with_period(command.goal) if command.goal
@@ -188,14 +103,6 @@ module Hecks
188
103
  parts.empty? ? nil : parts.join(" ")
189
104
  end
190
105
 
191
- # Describes when an event is recorded and what it prompts.
192
- #
193
- # @param facts [Hash{Symbol => Object}] an `:event`-kind entry's facts:
194
- # `:raised_by` (`Array<Array(Bluebook::Aggregate, Bluebook::Command)>`) and
195
- # `:policies` (`Array<Bluebook::Policy>`)
196
- # @param index [Glossary::Index] the document's link index
197
- # @return [String] which commands record the event, and, when any policy
198
- # reacts to it, which ones it prompts
199
106
  def event_sentence(facts, index)
200
107
  raisers = command_links(facts[:raised_by], index)
201
108
  sentence = "Recorded after #{Naming.to_sentence_list(raisers, conj: 'or')}."
@@ -204,14 +111,8 @@ module Hecks
204
111
  sentence
205
112
  end
206
113
 
207
- # "When Customer suspended happens, Account is asked to Freeze
208
- # account, once for each row of Open for customer." — a
209
- # cross-domain trigger (`across "Compliance"`) is spoken as words
210
- # with the domain named, since nothing here to link to exists.
211
- #
212
- # @param policy [Bluebook::Policy] the policy to describe
213
- # @param index [Glossary::Index] the document's link index
214
- # @return [String] when the policy fires and what it asks for
114
+ # A cross-domain trigger (`across "Compliance"`) is spoken as words with the
115
+ # domain named, since there is nothing here to link to.
215
116
  def policy_sentence(policy, index)
216
117
  holder, command = split_trigger(policy.trigger_command)
217
118
  asked = if policy.target_domain
@@ -228,13 +129,6 @@ module Hecks
228
129
  "#{sentence}."
229
130
  end
230
131
 
231
- # Describes when a saga begins and ends, and its states along the way.
232
- #
233
- # @param shape [Hash{Symbol => Object}] a process manager's `to_h`, read for
234
- # `:starts_on`, `:ends_on`, and `:states`
235
- # @param index [Glossary::Index] the document's link index
236
- # @return [String] when the saga begins and ends, and, when it declares any,
237
- # the states it can be in along the way
238
132
  def saga_sentence(shape, index)
239
133
  sentence = "Begins when #{index.link(:event, bare(shape[:starts_on]))} happens " \
240
134
  "and ends when #{index.link(:event, bare(shape[:ends_on]))} happens."
@@ -243,29 +137,14 @@ module Hecks
243
137
  sentence
244
138
  end
245
139
 
246
- # A noun list, deliberately — "Responsible for Credit and Debit",
247
- # never "Can credit and debit": banking's System role raises
248
- # `Debited` and `Credited`, and "can … debited" is a wrong
249
- # sentence. The headwords are already what people say.
250
- #
251
- # @param issues [Array<Array(Bluebook::Aggregate, Bluebook::Command)>] the
252
- # role's own `[holder, command]` pairs
253
- # @param index [Glossary::Index] the document's link index
254
- # @return [String] "Responsible for …", naming every command
140
+ # A noun list, not "Can credit and debit": a role that raises `Debited` would
141
+ # read "can … debited", which is wrong.
255
142
  def role_sentence(issues, index)
256
143
  "Responsible for #{Naming.to_sentence_list(command_links(issues, index))}."
257
144
  end
258
145
 
259
- # The same word for two different things gets its holder beside it
260
- # — a role responsible for CardPayment's Reverse and Transfer's
261
- # Reverse is responsible for "Reverse (card payment)" and
262
- # "Reverse (transfer)", not for "Reverse" twice.
263
- #
264
- # @param issues [Array<Array(Bluebook::Aggregate, Bluebook::Command)>] each
265
- # `[holder, command]` pair to link
266
- # @param index [Glossary::Index] the document's link index
267
- # @return [Array<String>] one Markdown link per distinct `[holder, command]`
268
- # pair, qualified with the holder's name when the command name repeats
146
+ # A command name shared by two holders gets its holder beside it:
147
+ # "Reverse (card payment)" and "Reverse (transfer)", not "Reverse" twice.
269
148
  def command_links(issues, index)
270
149
  issues = issues.uniq { |holder, command| [holder.hecks_name, command.hecks_name] }
271
150
  repeated = issues.map { |_holder, command| command.hecks_name }.tally.select { |_name, count| count > 1 }
@@ -277,41 +156,17 @@ module Hecks
277
156
  end
278
157
  end
279
158
 
280
- # ── small carpentry ─────────────────────────────────────────────
281
-
282
- # Splits a dotted `Holder.command` trigger into its two parts.
283
- #
284
- # @param dotted [String, Symbol] a `"Holder.command"` reference
285
- # @return [Array(String, String)] `[holder, command]`
286
159
  def split_trigger(dotted)
287
160
  holder, _dot, command = dotted.to_s.rpartition(".")
288
161
  [holder, command]
289
162
  end
290
163
 
291
- # Strips a dotted name down to its last segment.
292
- #
293
- # @param qualified [String, Symbol] a dotted or bare name, such as
294
- # `"Handler.Dispatch"` or `"Freeze"`
295
- # @return [String] the name after the last `.`, or the whole name if it has none
296
164
  def bare(qualified) = qualified.to_s.split(".").last
297
165
 
298
- # Ensures text ends in sentence-ending punctuation.
299
- #
300
- # @param text [String, Symbol, nil] the text to punctuate
301
- # @return [String] `text`, stripped, with a trailing `.` added if it has no
302
- # sentence-ending punctuation already
303
166
  def with_period(text) = text.to_s.strip.end_with?(".", "!", "?") ? text.to_s.strip : "#{text.to_s.strip}."
304
167
 
305
- # Lowercases a leading capital letter.
306
- #
307
- # @param text [String] the text to adjust
308
- # @return [String] `text` with a leading uppercase letter lowercased
309
168
  def lower_first(text) = text.sub(/\A[[:upper:]]/, &:downcase)
310
169
 
311
- # Uppercases a leading lowercase letter.
312
- #
313
- # @param text [String] the text to adjust
314
- # @return [String] `text` with a leading lowercase letter uppercased
315
170
  def upper_first(text) = text.sub(/\A[[:lower:]]/, &:upcase)
316
171
  end
317
172
  end