hecks 0.2.0 → 1.0.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 (419) hide show
  1. checksums.yaml +5 -5
  2. data/lib/hecks/adapters/driven/claude_code.adapter +3 -0
  3. data/lib/hecks/adapters/driven/claude_code.rb +127 -0
  4. data/lib/hecks/adapters/driven/d1.adapter +12 -0
  5. data/lib/hecks/adapters/driven/d1.rb +427 -0
  6. data/lib/hecks/adapters/driven/folder.adapter +3 -0
  7. data/lib/hecks/adapters/driven/folder.rb +199 -0
  8. data/lib/hecks/adapters/driven/google_authentication.adapter +3 -0
  9. data/lib/hecks/adapters/driven/google_authentication.rb +100 -0
  10. data/lib/hecks/adapters/driven/governance_authorization.adapter +3 -0
  11. data/lib/hecks/adapters/driven/governance_authorization.rb +101 -0
  12. data/lib/hecks/adapters/driven/heki/journal.rb +56 -0
  13. data/lib/hecks/adapters/driven/heki/saga_store.rb +99 -0
  14. data/lib/hecks/adapters/driven/heki/snapshot.rb +65 -0
  15. data/lib/hecks/adapters/driven/heki.adapter +4 -0
  16. data/lib/hecks/adapters/driven/heki.rb +179 -0
  17. data/lib/hecks/adapters/driven/identity_registry.adapter +3 -0
  18. data/lib/hecks/adapters/driven/identity_registry.rb +26 -0
  19. data/lib/hecks/adapters/driven/in_memory_ordering.rb +51 -0
  20. data/lib/hecks/adapters/driven/lambda/client.rb +63 -0
  21. data/lib/hecks/adapters/driven/lambda.adapter +4 -0
  22. data/lib/hecks/adapters/driven/lambda.rb +145 -0
  23. data/lib/hecks/adapters/driven/memory.adapter +3 -0
  24. data/lib/hecks/adapters/driven/memory.rb +103 -0
  25. data/lib/hecks/adapters/driven/mock_stripe_adapter.adapter +3 -0
  26. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +28 -0
  27. data/lib/hecks/adapters/driven/postgres/codec.rb +88 -0
  28. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +207 -0
  29. data/lib/hecks/adapters/driven/postgres.adapter +5 -0
  30. data/lib/hecks/adapters/driven/postgres.rb +438 -0
  31. data/lib/hecks/adapters/driven/postgres_era.adapter +17 -0
  32. data/lib/hecks/adapters/driven/prism.adapter +3 -0
  33. data/lib/hecks/adapters/driven/prism.rb +80 -0
  34. data/lib/hecks/adapters/driven/secure_random_identity.adapter +3 -0
  35. data/lib/hecks/adapters/driven/secure_random_identity.rb +14 -0
  36. data/lib/hecks/adapters/driven/sql_query_builder.rb +221 -0
  37. data/lib/hecks/adapters/driven/sqlite/codec.rb +80 -0
  38. data/lib/hecks/adapters/driven/sqlite/projection.rb +172 -0
  39. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +192 -0
  40. data/lib/hecks/adapters/driven/sqlite.adapter +9 -0
  41. data/lib/hecks/adapters/driven/sqlite.rb +306 -0
  42. data/lib/hecks/adapters/driven/system_clock.adapter +3 -0
  43. data/lib/hecks/adapters/driven/system_clock.rb +14 -0
  44. data/lib/hecks/adapters/driven.rb +54 -0
  45. data/lib/hecks/adapters.rb +6 -0
  46. data/lib/hecks/behaviors/dsl.rb +125 -0
  47. data/lib/hecks/behaviors/expectations.rb +340 -0
  48. data/lib/hecks/behaviors/ir.rb +31 -0
  49. data/lib/hecks/behaviors/rspec.rb +42 -0
  50. data/lib/hecks/behaviors/runner.rb +96 -0
  51. data/lib/hecks/behaviors.rb +25 -0
  52. data/lib/hecks/bluebook/aggregate.rb +108 -0
  53. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +134 -0
  54. data/lib/hecks/bluebook/assembly/build.rb +48 -0
  55. data/lib/hecks/bluebook/assembly/contract.rb +112 -0
  56. data/lib/hecks/bluebook/assembly/contracts.rb +438 -0
  57. data/lib/hecks/bluebook/assembly/marks.rb +228 -0
  58. data/lib/hecks/bluebook/assembly/specializer.rb +70 -0
  59. data/lib/hecks/bluebook/assembly.rb +91 -0
  60. data/lib/hecks/bluebook/attribute.rb +96 -0
  61. data/lib/hecks/bluebook/behaviour/aggregate.rb +83 -0
  62. data/lib/hecks/bluebook/behaviour/attribute.rb +27 -0
  63. data/lib/hecks/bluebook/behaviour/chapter.rb +72 -0
  64. data/lib/hecks/bluebook/behaviour/command.rb +116 -0
  65. data/lib/hecks/bluebook/behaviour/domain_port.rb +25 -0
  66. data/lib/hecks/bluebook/behaviour/entity.rb +59 -0
  67. data/lib/hecks/bluebook/behaviour/hexagon.rb +50 -0
  68. data/lib/hecks/bluebook/behaviour/lifecycle.rb +68 -0
  69. data/lib/hecks/bluebook/behaviour/policy.rb +52 -0
  70. data/lib/hecks/bluebook/behaviour/process_manager.rb +51 -0
  71. data/lib/hecks/bluebook/behaviour/query.rb +10 -0
  72. data/lib/hecks/bluebook/behaviour/read_model.rb +29 -0
  73. data/lib/hecks/bluebook/behaviour/traits.rb +81 -0
  74. data/lib/hecks/bluebook/behaviour/value_object.rb +33 -0
  75. data/lib/hecks/bluebook/chapter.rb +78 -0
  76. data/lib/hecks/bluebook/command.rb +124 -0
  77. data/lib/hecks/bluebook/domain_port.rb +102 -0
  78. data/lib/hecks/bluebook/dsl/adapter_builder.rb +34 -0
  79. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +1018 -0
  80. data/lib/hecks/bluebook/dsl/attribute_collector.rb +348 -0
  81. data/lib/hecks/bluebook/dsl/binding_proxy.rb +71 -0
  82. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +1087 -0
  83. data/lib/hecks/bluebook/dsl/command_builder.rb +714 -0
  84. data/lib/hecks/bluebook/dsl/const_shim.rb +81 -0
  85. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +79 -0
  86. data/lib/hecks/bluebook/dsl/entity_builder.rb +430 -0
  87. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +366 -0
  88. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +163 -0
  89. data/lib/hecks/bluebook/dsl/identity_declaration.rb +191 -0
  90. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +44 -0
  91. data/lib/hecks/bluebook/dsl/malformed.rb +7 -0
  92. data/lib/hecks/bluebook/dsl/policy_builder.rb +135 -0
  93. data/lib/hecks/bluebook/dsl/port_builder.rb +39 -0
  94. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +142 -0
  95. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +306 -0
  96. data/lib/hecks/bluebook/dsl/query_builder.rb +113 -0
  97. data/lib/hecks/bluebook/dsl/read_model_builder.rb +233 -0
  98. data/lib/hecks/bluebook/dsl/rule_reference.rb +173 -0
  99. data/lib/hecks/bluebook/dsl/translation_builder.rb +243 -0
  100. data/lib/hecks/bluebook/dsl/value_object_builder.rb +178 -0
  101. data/lib/hecks/bluebook/dsl/word_gate.rb +228 -0
  102. data/lib/hecks/bluebook/dsl/world_builder.rb +117 -0
  103. data/lib/hecks/bluebook/dsl.rb +45 -0
  104. data/lib/hecks/bluebook/entity.rb +103 -0
  105. data/lib/hecks/bluebook/expression/canonical_form.rb +123 -0
  106. data/lib/hecks/bluebook/expression/evaluator.rb +304 -0
  107. data/lib/hecks/bluebook/expression/projection.json +218 -0
  108. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +233 -0
  109. data/lib/hecks/bluebook/expression/resolver.rb +781 -0
  110. data/lib/hecks/bluebook/expression.rb +13 -0
  111. data/lib/hecks/bluebook/hexagon.rb +60 -0
  112. data/lib/hecks/bluebook/lifecycle.rb +42 -0
  113. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +54 -0
  114. data/lib/hecks/bluebook/meta_validator/judge.rb +621 -0
  115. data/lib/hecks/bluebook/meta_validator/plan.rb +332 -0
  116. data/lib/hecks/bluebook/meta_validator/port_judge.rb +51 -0
  117. data/lib/hecks/bluebook/meta_validator/readings.rb +360 -0
  118. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +351 -0
  119. data/lib/hecks/bluebook/meta_validator/shapes.rb +266 -0
  120. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +255 -0
  121. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +138 -0
  122. data/lib/hecks/bluebook/meta_validator/world_judge.rb +78 -0
  123. data/lib/hecks/bluebook/meta_validator.rb +542 -0
  124. data/lib/hecks/bluebook/model_check.rb +445 -0
  125. data/lib/hecks/bluebook/pattern_subset.rb +184 -0
  126. data/lib/hecks/bluebook/policy.rb +41 -0
  127. data/lib/hecks/bluebook/process_manager.rb +128 -0
  128. data/lib/hecks/bluebook/project_discovery.rb +30 -0
  129. data/lib/hecks/bluebook/project_loader.rb +40 -0
  130. data/lib/hecks/bluebook/project_register.rb +82 -0
  131. data/lib/hecks/bluebook/query.rb +61 -0
  132. data/lib/hecks/bluebook/read_model.rb +109 -0
  133. data/lib/hecks/bluebook/reference.rb +74 -0
  134. data/lib/hecks/bluebook/smoke_test.rb +166 -0
  135. data/lib/hecks/bluebook/synthesizer.rb +95 -0
  136. data/lib/hecks/bluebook/translation.rb +92 -0
  137. data/lib/hecks/bluebook/value_object.rb +66 -0
  138. data/lib/hecks/bluebook.rb +74 -0
  139. data/lib/hecks/codemod.rb +342 -0
  140. data/lib/hecks/construct.rb +71 -0
  141. data/lib/hecks/deploy/bluebook/deploy.bluebook +219 -0
  142. data/lib/hecks/deploy/bluebook/deploy.hecksagon +4 -0
  143. data/lib/hecks/deploy/oidc.json +18 -0
  144. data/lib/hecks/doc/reference.rb +410 -0
  145. data/lib/hecks/embryonaut_bluebook.rb +75 -0
  146. data/lib/hecks/facade/cli_door.rb +119 -0
  147. data/lib/hecks/facade/cli_runner.rb +190 -0
  148. data/lib/hecks/facade/command_request.rb +105 -0
  149. data/lib/hecks/facade/handle.rb +173 -0
  150. data/lib/hecks/facade/json_door.rb +166 -0
  151. data/lib/hecks/facade/surface/aggregate_door.rb +185 -0
  152. data/lib/hecks/facade/surface/chapter.rb +107 -0
  153. data/lib/hecks/facade/surface.rb +48 -0
  154. data/lib/hecks/facade.rb +44 -0
  155. data/lib/hecks/forms/app.rb +341 -0
  156. data/lib/hecks/forms/command_form_renderer.rb +113 -0
  157. data/lib/hecks/forms/examples/banking_console.bluebook +3 -0
  158. data/lib/hecks/forms/field_renderer.rb +177 -0
  159. data/lib/hecks/forms/field_shape.rb +232 -0
  160. data/lib/hecks/forms/html.rb +84 -0
  161. data/lib/hecks/forms/index_renderer.rb +35 -0
  162. data/lib/hecks/forms/page.rb +157 -0
  163. data/lib/hecks/forms/params.rb +161 -0
  164. data/lib/hecks/forms/port_argument.rb +46 -0
  165. data/lib/hecks/forms/query_form_renderer.rb +114 -0
  166. data/lib/hecks/forms/record_renderer.rb +119 -0
  167. data/lib/hecks/forms/record_table.rb +68 -0
  168. data/lib/hecks/forms/reference_options.rb +30 -0
  169. data/lib/hecks/forms/value_object_shape.rb +46 -0
  170. data/lib/hecks/forms.rb +54 -0
  171. data/lib/hecks/fqn.rb +94 -0
  172. data/lib/hecks/framework/bluebook/compliance.bluebook +1 -0
  173. data/lib/hecks/framework/bluebook/console_settings.bluebook +489 -0
  174. data/lib/hecks/framework/bluebook/framework.hecksagon +32 -0
  175. data/lib/hecks/framework/bluebook/governance.bluebook +145 -0
  176. data/lib/hecks/framework/bluebook/identity.bluebook +90 -0
  177. data/lib/hecks/framework/oidc.json +39 -0
  178. data/lib/hecks/framework.rb +90 -0
  179. data/lib/hecks/freezer.rb +67 -0
  180. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +527 -0
  181. data/lib/hecks/fuzzing/invalid_value_generator.rb +86 -0
  182. data/lib/hecks/fuzzing/isolated_boot.rb +286 -0
  183. data/lib/hecks/fuzzing/properties.rb +1192 -0
  184. data/lib/hecks/fuzzing/replay.rb +668 -0
  185. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +93 -0
  186. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +80 -0
  187. data/lib/hecks/fuzzing/sequence_generator/picker.rb +96 -0
  188. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +250 -0
  189. data/lib/hecks/fuzzing/sequence_generator.rb +131 -0
  190. data/lib/hecks/fuzzing/value_generator.rb +200 -0
  191. data/lib/hecks/fuzzing.rb +12 -0
  192. data/lib/hecks/grammar/evolve.rb +324 -0
  193. data/lib/hecks/grammar/expression.bluebook +420 -0
  194. data/lib/hecks/grammar/expression_operators.json +1648 -0
  195. data/lib/hecks/grammar/grammar.hecksagon +20 -0
  196. data/lib/hecks/grammar/oidc.json +69 -0
  197. data/lib/hecks/grammar/translation.bluebook +203 -0
  198. data/lib/hecks/grammar.rb +178 -0
  199. data/lib/hecks/ir.rb +126 -0
  200. data/lib/hecks/language/adapter.bluebook +116 -0
  201. data/lib/hecks/language/bluebook/aggregate.bluebook +581 -0
  202. data/lib/hecks/language/bluebook/attaches/paging.bluebook +76 -0
  203. data/lib/hecks/language/bluebook/bluebook.bluebook +256 -0
  204. data/lib/hecks/language/bluebook/bluebook.hecksagon +24 -0
  205. data/lib/hecks/language/bluebook/command.bluebook +471 -0
  206. data/lib/hecks/language/bluebook/entity.bluebook +392 -0
  207. data/lib/hecks/language/bluebook/policy.bluebook +189 -0
  208. data/lib/hecks/language/bluebook/process_manager.bluebook +381 -0
  209. data/lib/hecks/language/bluebook/projection.bluebook +267 -0
  210. data/lib/hecks/language/bluebook/query.bluebook +245 -0
  211. data/lib/hecks/language/bluebook/shape.bluebook +292 -0
  212. data/lib/hecks/language/bluebook/syntax.bluebook +448 -0
  213. data/lib/hecks/language/bluebook/vocabulary.bluebook +379 -0
  214. data/lib/hecks/language/hecksagon/adapter_binding.bluebook +51 -0
  215. data/lib/hecks/language/hecksagon/domain_port.bluebook +76 -0
  216. data/lib/hecks/language/hecksagon/hecksagon.bluebook +131 -0
  217. data/lib/hecks/language/hecksagon/port_operation.bluebook +102 -0
  218. data/lib/hecks/language/oidc.json +333 -0
  219. data/lib/hecks/language/port.bluebook +120 -0
  220. data/lib/hecks/language/translation/translation.bluebook +110 -0
  221. data/lib/hecks/language/translation/translation_aggregate.bluebook +267 -0
  222. data/lib/hecks/language/world/wiring.bluebook +62 -0
  223. data/lib/hecks/language/world/world.bluebook +84 -0
  224. data/lib/hecks/literal.rb +125 -0
  225. data/lib/hecks/naming.rb +174 -0
  226. data/lib/hecks/ports/access_control.port +9 -0
  227. data/lib/hecks/ports/access_control.rb +62 -0
  228. data/lib/hecks/ports/agent/answers.rb +104 -0
  229. data/lib/hecks/ports/agent.port +8 -0
  230. data/lib/hecks/ports/agent.rb +167 -0
  231. data/lib/hecks/ports/authentication.port +6 -0
  232. data/lib/hecks/ports/authentication.rb +50 -0
  233. data/lib/hecks/ports/authorization.port +7 -0
  234. data/lib/hecks/ports/authorization.rb +62 -0
  235. data/lib/hecks/ports/clock.port +5 -0
  236. data/lib/hecks/ports/clock.rb +62 -0
  237. data/lib/hecks/ports/extraction.port +5 -0
  238. data/lib/hecks/ports/extraction.rb +37 -0
  239. data/lib/hecks/ports/identity_assignment.port +5 -0
  240. data/lib/hecks/ports/identity_assignment.rb +45 -0
  241. data/lib/hecks/ports/identity_generation.port +5 -0
  242. data/lib/hecks/ports/identity_generation.rb +49 -0
  243. data/lib/hecks/ports/identity_resolution.port +5 -0
  244. data/lib/hecks/ports/identity_resolution.rb +40 -0
  245. data/lib/hecks/ports/loading.port +4 -0
  246. data/lib/hecks/ports/loading.rb +13 -0
  247. data/lib/hecks/ports/persistence/append_only.rb +138 -0
  248. data/lib/hecks/ports/persistence/binding_policy.rb +56 -0
  249. data/lib/hecks/ports/persistence/execution.rb +23 -0
  250. data/lib/hecks/ports/persistence/null_saga_store.rb +25 -0
  251. data/lib/hecks/ports/persistence/plugin.rb +54 -0
  252. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +169 -0
  253. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +128 -0
  254. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +161 -0
  255. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +61 -0
  256. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +304 -0
  257. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +171 -0
  258. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +190 -0
  259. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +478 -0
  260. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +166 -0
  261. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +314 -0
  262. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +168 -0
  263. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +170 -0
  264. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +134 -0
  265. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +137 -0
  266. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +89 -0
  267. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +85 -0
  268. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +43 -0
  269. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +132 -0
  270. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +74 -0
  271. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +758 -0
  272. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +120 -0
  273. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +31 -0
  274. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +46 -0
  275. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +102 -0
  276. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +46 -0
  277. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +70 -0
  278. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +72 -0
  279. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +120 -0
  280. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +183 -0
  281. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +41 -0
  282. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +28 -0
  283. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +30 -0
  284. data/lib/hecks/ports/persistence/plugins/era/translation.rb +11 -0
  285. data/lib/hecks/ports/persistence/plugins/era.rb +48 -0
  286. data/lib/hecks/ports/persistence/remote_runtime.rb +42 -0
  287. data/lib/hecks/ports/persistence/repository_factory.rb +30 -0
  288. data/lib/hecks/ports/persistence.port +4 -0
  289. data/lib/hecks/ports/persistence.rb +39 -0
  290. data/lib/hecks/ports/projection.port +4 -0
  291. data/lib/hecks/ports/projection.rb +96 -0
  292. data/lib/hecks/ports/query/in_memory.rb +60 -0
  293. data/lib/hecks/ports/query/ordering.rb +41 -0
  294. data/lib/hecks/ports/query.rb +36 -0
  295. data/lib/hecks/ports.rb +27 -0
  296. data/lib/hecks/projections/diagrams.rb +642 -0
  297. data/lib/hecks/projections/ir.rb +18 -0
  298. data/lib/hecks/projections/model/deviations.rb +98 -0
  299. data/lib/hecks/projections/model.rb +145 -0
  300. data/lib/hecks/projections/oidc.rb +110 -0
  301. data/lib/hecks/projections/parser_table.rb +159 -0
  302. data/lib/hecks/projections/reference.rb +38 -0
  303. data/lib/hecks/projections/shape.rb +44 -0
  304. data/lib/hecks/projections/statements.rb +110 -0
  305. data/lib/hecks/projections/vocabulary.rb +100 -0
  306. data/lib/hecks/projections.rb +32 -0
  307. data/lib/hecks/projector/cli_projector.rb +446 -0
  308. data/lib/hecks/projector/docs_projector.rb +321 -0
  309. data/lib/hecks/projector/exporter.rb +158 -0
  310. data/lib/hecks/projector/ir_projector.rb +18 -0
  311. data/lib/hecks/projector/narrate_projector.rb +243 -0
  312. data/lib/hecks/projector/target.rb +97 -0
  313. data/lib/hecks/projector.rb +186 -0
  314. data/lib/hecks/query_ir.rb +411 -0
  315. data/lib/hecks/query_specification/common/authorization_spec.rb +9 -0
  316. data/lib/hecks/query_specification/common/comparators.rb +25 -0
  317. data/lib/hecks/query_specification/common/comparison.rb +174 -0
  318. data/lib/hecks/query_specification/common/cursor_spec.rb +9 -0
  319. data/lib/hecks/query_specification/common/dsl.rb +58 -0
  320. data/lib/hecks/query_specification/common/inspection_spec.rb +9 -0
  321. data/lib/hecks/query_specification/common/limit_spec.rb +9 -0
  322. data/lib/hecks/query_specification/common/null_policy.rb +92 -0
  323. data/lib/hecks/query_specification/common/null_semantics.rb +11 -0
  324. data/lib/hecks/query_specification/common/offset_spec.rb +9 -0
  325. data/lib/hecks/query_specification/common/options.rb +32 -0
  326. data/lib/hecks/query_specification/common/order_by.rb +9 -0
  327. data/lib/hecks/query_specification/common/specification.rb +10 -0
  328. data/lib/hecks/query_specification/common/where_clause.rb +9 -0
  329. data/lib/hecks/query_specification/field_path.rb +107 -0
  330. data/lib/hecks/query_specification/hop_path.rb +132 -0
  331. data/lib/hecks/query_specification/read_model/specification.rb +18 -0
  332. data/lib/hecks/query_specification.rb +14 -0
  333. data/lib/hecks/rendering.rb +48 -0
  334. data/lib/hecks/router/namespace_installer.rb +157 -0
  335. data/lib/hecks/router.rb +70 -0
  336. data/lib/hecks/runtime/aggregate_lock.rb +45 -0
  337. data/lib/hecks/runtime/boot_gates.rb +41 -0
  338. data/lib/hecks/runtime/caller.rb +66 -0
  339. data/lib/hecks/runtime/capability_graph.rb +44 -0
  340. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +135 -0
  341. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +260 -0
  342. data/lib/hecks/runtime/command_interpreter.rb +497 -0
  343. data/lib/hecks/runtime/command_rules/admissibility.rb +357 -0
  344. data/lib/hecks/runtime/command_rules/arithmetic.rb +260 -0
  345. data/lib/hecks/runtime/command_rules/authorization.rb +65 -0
  346. data/lib/hecks/runtime/command_rules/emission.rb +34 -0
  347. data/lib/hecks/runtime/command_rules/references.rb +189 -0
  348. data/lib/hecks/runtime/command_rules.rb +28 -0
  349. data/lib/hecks/runtime/dependency_planning.rb +245 -0
  350. data/lib/hecks/runtime/dispatcher.rb +301 -0
  351. data/lib/hecks/runtime/entity_element.rb +253 -0
  352. data/lib/hecks/runtime/entity_interpreter.rb +299 -0
  353. data/lib/hecks/runtime/errors.rb +122 -0
  354. data/lib/hecks/runtime/event.rb +51 -0
  355. data/lib/hecks/runtime/identity.rb +156 -0
  356. data/lib/hecks/runtime/instance.rb +175 -0
  357. data/lib/hecks/runtime/interpreting.rb +90 -0
  358. data/lib/hecks/runtime/loader.rb +184 -0
  359. data/lib/hecks/runtime/policy_interpreter.rb +366 -0
  360. data/lib/hecks/runtime/port_operation_interpreter.rb +210 -0
  361. data/lib/hecks/runtime/query_interpreter.rb +286 -0
  362. data/lib/hecks/runtime/reaction_invocation.rb +253 -0
  363. data/lib/hecks/runtime/read_model_interpreter.rb +341 -0
  364. data/lib/hecks/runtime/rebuild_sweep.rb +74 -0
  365. data/lib/hecks/runtime/reference_hop.rb +99 -0
  366. data/lib/hecks/runtime/refusal_wording.rb +126 -0
  367. data/lib/hecks/runtime/registry/saga_persistence.rb +142 -0
  368. data/lib/hecks/runtime/registry/verification.rb +246 -0
  369. data/lib/hecks/runtime/registry.rb +279 -0
  370. data/lib/hecks/runtime/remote_dispatcher.rb +143 -0
  371. data/lib/hecks/runtime/routing.rb +96 -0
  372. data/lib/hecks/runtime/saga_interpreter/correlation.rb +97 -0
  373. data/lib/hecks/runtime/saga_interpreter.rb +503 -0
  374. data/lib/hecks/runtime/saga_pending_dispatch.rb +45 -0
  375. data/lib/hecks/runtime/tenant_check.rb +84 -0
  376. data/lib/hecks/runtime/tenant_scope.rb +55 -0
  377. data/lib/hecks/runtime/value/admission.rb +130 -0
  378. data/lib/hecks/runtime/value/coercion.rb +565 -0
  379. data/lib/hecks/runtime/value/invariant_violation.rb +5 -0
  380. data/lib/hecks/runtime/value.rb +125 -0
  381. data/lib/hecks/runtime.rb +107 -0
  382. data/lib/hecks/storehouse.rb +632 -0
  383. data/lib/hecks/version.rb +16 -0
  384. data/lib/hecks/vocabulary.rb +218 -0
  385. data/lib/hecks.rb +123 -6
  386. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +90 -0
  387. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +128 -0
  388. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +160 -0
  389. metadata +412 -222
  390. data/bin/hecks +0 -7
  391. data/bin/hecks-package +0 -65
  392. data/bin/hecks_console +0 -12
  393. data/bin/hecks_serverless +0 -6
  394. data/lib/cli/build.rb +0 -14
  395. data/lib/cli/command_runner.rb +0 -28
  396. data/lib/cli/console.rb +0 -10
  397. data/lib/cli/generate.rb +0 -37
  398. data/lib/cli/hecks-cli.rb +0 -27
  399. data/lib/cli/test.rb +0 -57
  400. data/lib/console/commands.rb +0 -8
  401. data/lib/console/hecks-console.rb +0 -1
  402. data/lib/packager/README.md +0 -0
  403. data/lib/packager/app_runner.rb +0 -21
  404. data/lib/packager/args.rb +0 -26
  405. data/lib/packager/compatibility/fixnum.rb +0 -6
  406. data/lib/packager/hecks.rb +0 -39
  407. data/lib/packager/query_runner.rb +0 -21
  408. data/lib/packager/resources/Dockerfile +0 -11
  409. data/lib/packager/resources/app_binary +0 -7
  410. data/lib/packager/resources/bundle_config +0 -3
  411. data/lib/packager/resources/traveling-ruby-20150715-2.2.2-linux-x86_64.tar.gz +0 -0
  412. data/lib/packager/resources/traveling-ruby-20150715-2.2.2-osx.tar.gz +0 -0
  413. data/lib/serverless/Domain +0 -32
  414. data/lib/serverless/cli.rb +0 -75
  415. data/lib/serverless/resources/command_name.js +0 -5
  416. data/lib/serverless/resources/environment.js +0 -7
  417. data/lib/serverless/resources/handler.js.tt +0 -28
  418. data/lib/serverless/resources/run_binary.js +0 -22
  419. data/lib/serverless/resources/serverless.yml +0 -20
@@ -0,0 +1,255 @@
1
+ module Hecks
2
+ module Bluebook
3
+ module MetaValidator
4
+ # S14, ADR 0026 — DISPATCHES THE LANGUAGE'S OWN GRAMMAR TABLE INTO
5
+ # ITSELF, once, so `Keyword`/`Argument`'s own `status` genuinely IS a
6
+ # lifecycle — checked at real dispatch time (the same admission/
7
+ # coercion/lifecycle-guard door every other command goes through),
8
+ # not merely declared and never exercised.
9
+ #
10
+ # THE SOURCE STAYS STATIC. Aggregate-local `KeywordSeed`/
11
+ # `ArgumentSeed` value objects (still hand-written `member` rows —
12
+ # now beside the concepts they spell) are what gets WRITTEN ; this
13
+ # is what turns them into what gets READ. `Judge`/`Reconstruction`
14
+ # already draw exactly this line everywhere else in the meta-domain
15
+ # (a chapter's own DECLARATIONS versus what gets DISPATCHED from
16
+ # them) — this runs the same distinction one level further out, for
17
+ # the language's own grammar table.
18
+ #
19
+ # A DEDICATED RUNTIME, not `MetaValidator.fresh_runtime`. That one
20
+ # is reserved for `Judge`'s own bootstrap (dispatching a CHAPTER's
21
+ # declarations INTO the meta-domain's grammar) — a different act
22
+ # from this one (dispatching the meta-domain's OWN grammar table
23
+ # data into a live "Bluebook" domain instance). Sharing the runtime
24
+ # would let one boot's own repository state leak into the other's.
25
+ #
26
+ # Usage:
27
+ #
28
+ # MetaValidator.syntax_table # => { keywords: [...], arguments: [...] }
29
+ #
30
+ # each row a plain Hash, string values, `status` included — the
31
+ # exact shape `ParserTable`/`syntax_conformance_spec` already read
32
+ # off the OLD closed-set members, so neither consumer had to change
33
+ # what it does with a row, only where the row comes from.
34
+ module SyntaxBoot
35
+ module_function
36
+
37
+ # Memoized the same way `MetaValidator.grammar_registry` itself
38
+ # is — the ~284-command dispatch sequence below is real work, not
39
+ # something three separate callers (ParserTable, syntax_
40
+ # conformance_spec, bin/reference) should each pay for on every
41
+ # call.
42
+ #
43
+ # KEYED BY THE GRAMMAR REGISTRY'S OWN CHAPTER SET, not by a
44
+ # "ready" flag. `boot` reads exactly two things: the registry's
45
+ # "Bluebook" chapter (the core seed rows) and every chapter in the
46
+ # registry that `attaches_to` a core context (Paging's rows). So
47
+ # the table is a pure function of which chapter OBJECTS the
48
+ # registry holds — and that is the cache key: the same chapters,
49
+ # by identity, mean the same table; a chapter replaced (the
50
+ # fixpoint judge swapping a raw chapter for its assembled self)
51
+ # or added (`load_attached_grammar_into`) means a fresh boot.
52
+ #
53
+ # WHY NOT THE EARLIER `grammar_registry_ready?` GUARD. That guard
54
+ # was right about the hazard — a snapshot taken mid-build, before
55
+ # Paging attached, would be missing limit/offset/cursor/nulls
56
+ # forever — and wrong about the cost of its cure. It refused to
57
+ # cache ANYTHING until the whole grammar registry had finished
58
+ # building, calling that window "narrow" and recomputing in it
59
+ # "cheap". Measured (hecks_ai_training, a six-entity chess domain,
60
+ # 2026-08-22): every `word_gate_dispatch` landing in that window
61
+ # re-ran the full ~284-dispatch boot at ~0.76s each — 42 times per
62
+ # process, 32 of a 35-second `Hecks.boot`, 95% of which had
63
+ # nothing to do with the domain being booted. Keying on the
64
+ # chapter set closes the same hazard by construction (a snapshot
65
+ # can only be served while the chapters it was read from are
66
+ # still the chapters the registry holds) and lets the window's
67
+ # own repeated, identical calls share one boot. A registry reset
68
+ # (fixpoint_spec's own `@grammar_registry = nil`) yields new
69
+ # chapter objects, so it invalidates this the same way it always
70
+ # invalidated `grammar_registry_ready?`.
71
+ #
72
+ # `equal?`, NOT `==`, on the chapters — identity is the fact being
73
+ # tracked. Holding the chapter objects themselves (not their ids)
74
+ # in the key also means a collected chapter can never hand its id
75
+ # to a newcomer behind this cache's back.
76
+ def call
77
+ chapters = MetaValidator.grammar_registry.bluebooks.to_a
78
+ return @call if @call && same_chapters?(@call_chapters, chapters)
79
+
80
+ result = boot
81
+ @call = result
82
+ @call_chapters = chapters
83
+ result
84
+ end
85
+
86
+ def same_chapters?(cached, current)
87
+ cached.size == current.size &&
88
+ cached.zip(current).all? { |(cached_name, cached_chapter), (name, chapter)| cached_name == name && cached_chapter.equal?(chapter) }
89
+ end
90
+
91
+ def boot
92
+ bluebook = MetaValidator.grammar_registry.bluebook("Bluebook")
93
+ # `MetaValidator.fresh_runtime`, not a brand-new `Runtime::
94
+ # Registry` — the grammar registry's own copy already has
95
+ # "Bluebook" registered (`grammar_registry`'s own boot already
96
+ # ran `registry.add_bluebook`) AND its adapter ports already
97
+ # loaded ; a standalone registry would need both wired by hand.
98
+ # `fresh_runtime` resets `@repositories` on the SAME registry —
99
+ # the identical isolation `Judge.new` already relies on for
100
+ # every real domain it judges, proven safe by every dispatch
101
+ # this session has ever made.
102
+ runtime = MetaValidator.fresh_runtime
103
+
104
+ declare_syntax(runtime, bluebook)
105
+ admit_keywords(runtime, bluebook)
106
+ admit_arguments(runtime, bluebook)
107
+
108
+ read_back(runtime, bluebook)
109
+ end
110
+
111
+ # An Integer stays an Integer — `position` is `Position`-typed
112
+ # (`attribute :value, Integer`), so stringifying it fails the type
113
+ # gate rather than feeding it, the same reading `Judge#v` gives.
114
+ def v(text)
115
+ return { value: text } if text.is_a?(Integer)
116
+
117
+ { value: text.to_s }
118
+ end
119
+
120
+ # ABSENT STAYS ABSENT. A seed row's own optional columns ("was",
121
+ # "at", "named", ...) are empty strings, not nil — `Literal`/CSV-
122
+ # shaped grammar data has no `nil` to write — so this is the one
123
+ # place that decides "" means "not given" for the purpose of an
124
+ # `optional: true` command argument, the same reading `Judge#v`
125
+ # makes for the meta-domain's own dispatches.
126
+ def optional(text)
127
+ return nil if text.nil? || text.to_s.empty?
128
+
129
+ v(text)
130
+ end
131
+
132
+ # `Syntax.Declare`'s own `reference_to Bluebook` names the CHAPTER
133
+ # it belongs to — the same fact every other top-level aggregate's
134
+ # own creating command carries (`ProcessManager.Declare`,
135
+ # `Policy.Declare`, ...). This fresh runtime holds no chapter
136
+ # record of its own yet (nothing else here needs one), so one is
137
+ # declared first, named after the real chapter, purely to satisfy
138
+ # the reference — its own vision/classification are never read
139
+ # by anything this boot does.
140
+ def declare_syntax(runtime, bluebook)
141
+ syntax = bluebook.aggregate("Syntax")
142
+ runtime.dispatch("Bluebook::Bluebook.Declare", name: v(bluebook.hecks_name),
143
+ vision: v("the language's own grammar table, dispatched into itself"),
144
+ classification: v("core"))
145
+ runtime.dispatch("Bluebook::Syntax.Declare", bluebook: bluebook.hecks_name, name: v(syntax.hecks_name))
146
+ end
147
+
148
+ # `to: "Syntax"` NAMES THE RECORD ALREADY OPENED BY `declare_syntax`
149
+ # ABOVE — an append onto an existing aggregate, not a second creation
150
+ # of it. This used to smuggle `name: v("Syntax")` into the payload
151
+ # instead, the pre-routing convention `Judge#appends` (the same
152
+ # append shape, for `ValueObject.Member`/`ProcessManager.Handler`)
153
+ # already left behind for `to:`/`with:` — carrying the receiver in
154
+ # the payload made `Syntax.Keyword`'s own `command.creates?` (true:
155
+ # it declares no `reference_to`) look like a fresh identity to mint,
156
+ # which collided with the very "Syntax" row `declare_syntax` had
157
+ # just opened.
158
+ def admit_keywords(runtime, bluebook)
159
+ all_rows(bluebook, "KeywordSeed").each_with_index do |row, index|
160
+ runtime.dispatch("Bluebook::Syntax.Keyword", to: "Syntax",
161
+ with: { position: v(index),
162
+ word: v(row[:word]), context: v(row[:context]), body: v(row[:body]),
163
+ inner: v(row[:inner]), opens: v(row[:opens]), fills: v(row[:fills]),
164
+ was: optional(row[:was]),
165
+ resolves_via: optional(row[:resolves_via]),
166
+ disambiguator: optional(row[:disambiguator]),
167
+ calls: optional(row[:calls]) })
168
+
169
+ next unless row[:status].to_s == "deprecated"
170
+
171
+ runtime.dispatch("Bluebook::Syntax.Keyword.Deprecate", to: { aggregate: "Syntax", entity: index.to_s })
172
+ end
173
+ end
174
+
175
+ def admit_arguments(runtime, bluebook)
176
+ all_rows(bluebook, "ArgumentSeed").each_with_index do |row, index|
177
+ runtime.dispatch("Bluebook::Syntax.Argument", to: "Syntax",
178
+ with: { position: v(index),
179
+ keyword: v(row[:keyword]), context: v(row[:context]),
180
+ at: optional(row[:at]), named: optional(row[:named]),
181
+ kind: v(row[:kind]), required: v(row[:required]), fills: v(row[:fills]),
182
+ selects: optional(row[:selects]), pair_key_fills: optional(row[:pair_key_fills]),
183
+ pair_value_fills: optional(row[:pair_value_fills]),
184
+ pairs_shape: optional(row[:pairs_shape]), variadic: optional(row[:variadic]),
185
+ minimum: optional(row[:minimum]),
186
+ coerce: optional(row[:coerce]), blank_message: optional(row[:blank_message]) })
187
+
188
+ next unless row[:status].to_s == "deprecated"
189
+
190
+ runtime.dispatch("Bluebook::Syntax.Argument.Deprecate", to: { aggregate: "Syntax", entity: index.to_s })
191
+ end
192
+ end
193
+
194
+ # EVERY AGGREGATE-LOCAL TABLE IN EVERY LOADED LANGUAGE CHAPTER.
195
+ # The table's presence is the registration: no chapter, aggregate,
196
+ # filename, or context catalog is maintained here. This finds the core
197
+ # Bluebook concepts, the sibling artifact languages (World, Hecksagon,
198
+ # Port, Adapter, Translation), and attached sub-languages alike.
199
+ # Concatenated into ONE sequence because `position` is minted from the
200
+ # walk index and must not collide across concepts.
201
+ def all_rows(bluebook, name)
202
+ seed_chapters(bluebook).flat_map { |chapter| rows(chapter, name) }
203
+ end
204
+
205
+ # Keep the core chapter first, then registry insertion order for every
206
+ # sibling/extension. The name rejection avoids reading the same core
207
+ # object twice without relying on object identity across fixpoint
208
+ # assembly.
209
+ def seed_chapters(bluebook)
210
+ [bluebook] + MetaValidator.grammar_registry.bluebooks.values.reject { |chapter| chapter.name == bluebook.name }
211
+ end
212
+
213
+ # The seed rows themselves — plain hashes, string values, read from
214
+ # every aggregate that owns a same-named local value object. Repeating
215
+ # the value-object shape is deliberate: each concept remains readable
216
+ # by itself, while this discovery is the only grouping mechanism.
217
+ def rows(bluebook, name)
218
+ bluebook.aggregates.flat_map do |aggregate|
219
+ value_object = aggregate.value_objects.find { |vo| vo.hecks_name == name }
220
+ next [] unless value_object
221
+
222
+ value_object.members.map { |row| row.to_h.transform_values(&:to_s) }
223
+ end
224
+ end
225
+
226
+ # Reads the dispatched result back into the SAME shape `rows`
227
+ # above hands the seed data in as — plain hashes, string values,
228
+ # `status` included — so `ParserTable`/`syntax_conformance_spec`
229
+ # need not know or care that a real dispatch happened in between.
230
+ def read_back(runtime, bluebook)
231
+ syntax = bluebook.aggregate("Syntax")
232
+ repository = runtime.registry.repository("Bluebook", syntax)
233
+ instance = repository.find(Naming.identity([syntax.hecks_name]))
234
+
235
+ {
236
+ keywords: Array(instance[:keywords]).map { |row| stringify(row) },
237
+ arguments: Array(instance[:arguments]).map { |row| stringify(row) }
238
+ }
239
+ end
240
+
241
+ def stringify(row)
242
+ row.to_h.each_with_object({}) do |(key, cell), out|
243
+ out[key] = scalar(cell).to_s
244
+ end
245
+ end
246
+
247
+ def scalar(cell)
248
+ return cell.to_h.values.first if cell.respond_to?(:to_h) && !cell.is_a?(String)
249
+
250
+ cell
251
+ end
252
+ end
253
+ end
254
+ end
255
+ end
@@ -0,0 +1,138 @@
1
+ module Hecks
2
+ module Bluebook
3
+ module MetaValidator
4
+ # Offers a built translation (a `translations/*.bluebook` edge,
5
+ # `Hecks.data_translation`'s own real, established file convention —
6
+ # there is no separate `.translation` extension) to the language
7
+ # that describes translations.
8
+ #
9
+ # A sibling of a bluebook again, the same shape PortJudge/
10
+ # AdapterJudge already are — its own file, its own door, judged
11
+ # through its own self-hosted language (translation.bluebook)
12
+ # rather than left as plain Ruby structs nothing checks. Walks the
13
+ # WHOLE built translation in one pass — the top-level Declare/
14
+ # Retire commands, then every nested aggregate's own Declare plus
15
+ # one Add* command per rule it carries — the same "one judge, every
16
+ # nested record" shape WorldJudge already gives Wiring. Field names
17
+ # throughout read lib/hecks/bluebook/translation.rb's own real
18
+ # struct/class definitions directly, not the DSL builder's own
19
+ # local parameter names (`move(old_path, to:)`'s `old_path` reads
20
+ # back as the struct's own `from`). Whole-project table-
21
+ # unification survey, item #13's remaining builders.
22
+ class TranslationJudge
23
+ attr_reader :refusals
24
+
25
+ def initialize(translation)
26
+ @translation = translation
27
+ @refusals = []
28
+ @runtime = MetaValidator.fresh_runtime
29
+ judge!
30
+ end
31
+
32
+ private
33
+
34
+ def v(text) = text.nil? ? nil : { value: text.to_s }
35
+
36
+ def args(pairs) = pairs.compact
37
+
38
+ # `Runtime::AlreadyExists` is rescued HERE but not by World/Port/
39
+ # Adapter's own sibling judges — found live, not by inspection.
40
+ # Those three each judge a SINGLE aggregate per build (Port/Adapter)
41
+ # or a Hash keyed by verb (World's own settings, deduped by
42
+ # construction), so a duplicate-identity Declare can never reach
43
+ # their own runtime. `TranslationBuilder#aggregate` appends every
44
+ # block to a plain Array (`@aggregates << builder.build`) with no
45
+ # dedup — two `aggregate "Account" do ... end` blocks in the same
46
+ # translation are syntactically legal and reach here for real. Left
47
+ # unrescued, the second Declare's `AlreadyExists` crashed straight
48
+ # through `call_translation` instead of becoming a clean refusal —
49
+ # confirmed via direct dispatch before this fix.
50
+ def offer(label)
51
+ yield
52
+ rescue Runtime::GivenNotMet, Runtime::InvariantViolation, Runtime::TypeMismatch,
53
+ Runtime::NotFound, Runtime::AlreadyExists => e
54
+ @refusals << "#{label}: #{e.message}"
55
+ rescue Runtime::UnknownVerb
56
+ nil
57
+ end
58
+
59
+ def send_to(verb, label, to: nil, with: {})
60
+ offer(label) { @runtime.dispatch(verb, to: to, with: args(with)) }
61
+ end
62
+
63
+ def judge!
64
+ t = @translation
65
+ send_to("Translation::Translation.Declare", t.domain,
66
+ with: { domain: v(t.domain), from: v(t.from), to: v(t.to) })
67
+
68
+ # `id:`, computed the SAME way — `Naming.identity([domain, from,
69
+ # to])` — Translation's own identity is COMPOSITE
70
+ # (`identified_by :domain, :from, :to`), the same reason
71
+ # `Wiring.Set`'s own self-reference dispatch (world.bluebook,
72
+ # `WorldJudge#judge_wiring`) needs a computed `id:` rather than
73
+ # a bare field value — a single-field identity (TranslationAggregate's
74
+ # own `name`) is the ONE case where the bare value itself IS the
75
+ # id, confirmed live via direct dispatch testing, not assumed.
76
+ translation_id = Naming.identity([t.domain, t.from, t.to])
77
+ Array(t.retired).each do |name|
78
+ send_to("Translation::Translation.Retire", t.domain, to: translation_id,
79
+ with: { value: v(name) })
80
+ end
81
+
82
+ Array(t.aggregates).each { |aggregate| judge_aggregate(t, aggregate) }
83
+ end
84
+
85
+ def judge_aggregate(translation, aggregate)
86
+ name = aggregate.name
87
+ parent = {
88
+ domain: v(translation.domain),
89
+ from: v(translation.from),
90
+ to: v(translation.to)
91
+ }
92
+ send_to("Translation::TranslationAggregate.Declare", name,
93
+ with: { translation_ref: parent, name: v(name), was: v(aggregate.was) })
94
+
95
+ Hash(aggregate.renames).each do |from, to|
96
+ send_to("Translation::TranslationAggregate.AddRename", name, to: name,
97
+ with: { from: v(from), to: v(to) })
98
+ end
99
+
100
+ Array(aggregate.moves).each do |move|
101
+ send_to("Translation::TranslationAggregate.AddMove", name, to: name,
102
+ with: { from: v(move.from), to: v(move.to) })
103
+ end
104
+
105
+ Array(aggregate.converts).each do |convert|
106
+ send_to("Translation::TranslationAggregate.AddConvert", name, to: name,
107
+ with: { from: v(convert.from), to: v(convert.to), values: v(convert.values.inspect) })
108
+ end
109
+
110
+ Array(aggregate.drops).each do |dropped|
111
+ send_to("Translation::TranslationAggregate.AddDrop", name, to: name,
112
+ with: { value: v(dropped) })
113
+ end
114
+
115
+ Array(aggregate.retypes).each do |retype|
116
+ send_to("Translation::TranslationAggregate.AddRetype", name, to: name,
117
+ with: { from: v(retype.from), to: v(retype.to) })
118
+ end
119
+
120
+ Array(aggregate.computes).each do |compute|
121
+ send_to("Translation::TranslationAggregate.AddCompute", name, to: name,
122
+ with: { from: v(compute.from), to: v(compute.to), sql: v(compute.sql) })
123
+ end
124
+
125
+ Array(aggregate.rekeys).each do |rekey|
126
+ send_to("Translation::TranslationAggregate.AddRekey", name, to: name,
127
+ with: { sql: v(rekey.sql) })
128
+ end
129
+
130
+ Array(aggregate.backfills).each do |backfill|
131
+ send_to("Translation::TranslationAggregate.AddBackfill", name, to: name,
132
+ with: { name: v(backfill.name), default: v(backfill.default.inspect) })
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,78 @@
1
+ module Hecks
2
+ module Bluebook
3
+ module MetaValidator
4
+ # Offers a built .world to the language that describes worlds.
5
+ #
6
+ # A world is a SIBLING of a bluebook — the same domain runs in many of
7
+ # them — so it is judged through its own door, against its own language
8
+ # file, and its settings normalise the same way a mutation's fields do:
9
+ # an open map becomes one Wiring per verb and one Setting row per value.
10
+ class WorldJudge
11
+ attr_reader :refusals
12
+
13
+ def initialize(world)
14
+ @world = world
15
+ @refusals = []
16
+ @runtime = MetaValidator.fresh_runtime
17
+ judge!
18
+ end
19
+
20
+ private
21
+
22
+ def v(text) = text.nil? ? nil : { value: text.to_s }
23
+
24
+ def args(pairs) = pairs.reject { |_, value| value.nil? }
25
+
26
+ def offer(label)
27
+ yield
28
+ rescue Runtime::GivenNotMet, Runtime::InvariantViolation,
29
+ Runtime::TypeMismatch, Runtime::NotFound => e
30
+ @refusals << "#{label}: #{e.message}"
31
+ rescue Runtime::UnknownVerb
32
+ nil
33
+ end
34
+
35
+ def send_to(verb, label, to: nil, **payload)
36
+ offer(label) { @runtime.dispatch(verb, to: to, with: args(payload)) }
37
+ end
38
+
39
+ def judge!
40
+ domain = @world.domain
41
+ send_to("World::World.Declare", domain, domain: v(domain),
42
+ realm: v(@world.realm), latest: v(@world.latest))
43
+
44
+ Hash(@world.settings).each do |verb, values|
45
+ # the DSL records each binding twice — once by verb, once by
46
+ # "verb:adapter" — so only the plain verb is offered
47
+ next if verb.to_s.include?(":")
48
+
49
+ judge_wiring(domain, verb, values)
50
+ end
51
+ end
52
+
53
+ def judge_wiring(domain, verb, values)
54
+ # THE SAME JOIN THE LANGUAGE ITSELF DERIVES. Wiring is
55
+ # `identified_by do world; verb.value end` — `Wiring.Declare`
56
+ # (a creating command) ignores this `id:` entirely and computes its OWN
57
+ # from `world`/`verb`, so a locally minted "#{domain}.#{verb}" named a
58
+ # record `Wiring.Set` could never find : the id passed here has to be
59
+ # the SAME derivation, not a second guess at what it must be.
60
+ id = Naming.identity([domain, verb])
61
+ # `world_ref` is the WORLD's id and goes bare, the way every reference
62
+ # does now ; the language gives it that explicit `as:` because `world`
63
+ # beside it is an ordinary text attribute that happens to hold the same
64
+ # string, and stays a value object. The two look alike and are not —
65
+ # which is exactly why the judge asks the type rather than the name.
66
+ send_to("World::Wiring.Declare", id, world_ref: v(domain),
67
+ world: v(domain), verb: v(verb), adapter: v(Hash(values)[:adapter]))
68
+
69
+ Hash(values).each do |key, value|
70
+ next if key.to_sym == :adapter
71
+
72
+ send_to("World::Wiring.Set", id, to: id, key: v(key), value: v(value))
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end