hecks 0.2.0 → 0.3.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 (408) 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 +403 -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 +62 -0
  12. data/lib/hecks/adapters/driven/heki/journal.rb +51 -0
  13. data/lib/hecks/adapters/driven/heki/saga_store.rb +0 -0
  14. data/lib/hecks/adapters/driven/heki/snapshot.rb +38 -0
  15. data/lib/hecks/adapters/driven/heki.adapter +4 -0
  16. data/lib/hecks/adapters/driven/heki.rb +148 -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 +131 -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 +80 -0
  28. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +168 -0
  29. data/lib/hecks/adapters/driven/postgres.adapter +5 -0
  30. data/lib/hecks/adapters/driven/postgres.rb +391 -0
  31. data/lib/hecks/adapters/driven/postgres_era/lineage/era_store.rb +171 -0
  32. data/lib/hecks/adapters/driven/postgres_era/lineage/field_cache.rb +190 -0
  33. data/lib/hecks/adapters/driven/postgres_era/lineage/head_compiler.rb +429 -0
  34. data/lib/hecks/adapters/driven/postgres_era/lineage/mint_transaction.rb +166 -0
  35. data/lib/hecks/adapters/driven/postgres_era/lineage/provisioning.rb +286 -0
  36. data/lib/hecks/adapters/driven/postgres_era/lineage/resumable_backfill.rb +168 -0
  37. data/lib/hecks/adapters/driven/postgres_era/lineage/tail_merge.rb +163 -0
  38. data/lib/hecks/adapters/driven/postgres_era/lineage/transform_installer.rb +114 -0
  39. data/lib/hecks/adapters/driven/postgres_era/lineage.rb +137 -0
  40. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb +89 -0
  41. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolver.rb +82 -0
  42. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/merge_coordinator.rb +43 -0
  43. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/minter.rb +132 -0
  44. data/lib/hecks/adapters/driven/postgres_era/lineage_manager.rb +74 -0
  45. data/lib/hecks/adapters/driven/postgres_era.adapter +6 -0
  46. data/lib/hecks/adapters/driven/postgres_era.rb +671 -0
  47. data/lib/hecks/adapters/driven/prism.adapter +3 -0
  48. data/lib/hecks/adapters/driven/prism.rb +80 -0
  49. data/lib/hecks/adapters/driven/secure_random_identity.adapter +3 -0
  50. data/lib/hecks/adapters/driven/secure_random_identity.rb +14 -0
  51. data/lib/hecks/adapters/driven/sql_query_builder.rb +221 -0
  52. data/lib/hecks/adapters/driven/sqlite/codec.rb +63 -0
  53. data/lib/hecks/adapters/driven/sqlite/projection.rb +105 -0
  54. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +180 -0
  55. data/lib/hecks/adapters/driven/sqlite.adapter +9 -0
  56. data/lib/hecks/adapters/driven/sqlite.rb +285 -0
  57. data/lib/hecks/adapters/driven/system_clock.adapter +3 -0
  58. data/lib/hecks/adapters/driven/system_clock.rb +14 -0
  59. data/lib/hecks/adapters/driven.rb +36 -0
  60. data/lib/hecks/adapters.rb +6 -0
  61. data/lib/hecks/behaviors/dsl.rb +96 -0
  62. data/lib/hecks/behaviors/expectations.rb +280 -0
  63. data/lib/hecks/behaviors/ir.rb +31 -0
  64. data/lib/hecks/behaviors/rspec.rb +42 -0
  65. data/lib/hecks/behaviors/runner.rb +96 -0
  66. data/lib/hecks/behaviors.rb +25 -0
  67. data/lib/hecks/bluebook/aggregate.rb +108 -0
  68. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +134 -0
  69. data/lib/hecks/bluebook/assembly/build.rb +48 -0
  70. data/lib/hecks/bluebook/assembly/contract.rb +112 -0
  71. data/lib/hecks/bluebook/assembly/contracts.rb +409 -0
  72. data/lib/hecks/bluebook/assembly/marks.rb +227 -0
  73. data/lib/hecks/bluebook/assembly/specializer.rb +70 -0
  74. data/lib/hecks/bluebook/assembly.rb +78 -0
  75. data/lib/hecks/bluebook/attribute.rb +96 -0
  76. data/lib/hecks/bluebook/behaviour/aggregate.rb +83 -0
  77. data/lib/hecks/bluebook/behaviour/attribute.rb +27 -0
  78. data/lib/hecks/bluebook/behaviour/chapter.rb +72 -0
  79. data/lib/hecks/bluebook/behaviour/command.rb +116 -0
  80. data/lib/hecks/bluebook/behaviour/domain_port.rb +25 -0
  81. data/lib/hecks/bluebook/behaviour/entity.rb +59 -0
  82. data/lib/hecks/bluebook/behaviour/hexagon.rb +50 -0
  83. data/lib/hecks/bluebook/behaviour/lifecycle.rb +51 -0
  84. data/lib/hecks/bluebook/behaviour/policy.rb +52 -0
  85. data/lib/hecks/bluebook/behaviour/process_manager.rb +38 -0
  86. data/lib/hecks/bluebook/behaviour/query.rb +10 -0
  87. data/lib/hecks/bluebook/behaviour/read_model.rb +29 -0
  88. data/lib/hecks/bluebook/behaviour/traits.rb +81 -0
  89. data/lib/hecks/bluebook/behaviour/value_object.rb +33 -0
  90. data/lib/hecks/bluebook/chapter.rb +68 -0
  91. data/lib/hecks/bluebook/command.rb +124 -0
  92. data/lib/hecks/bluebook/domain_port.rb +102 -0
  93. data/lib/hecks/bluebook/dsl/adapter_builder.rb +34 -0
  94. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +906 -0
  95. data/lib/hecks/bluebook/dsl/attribute_collector.rb +327 -0
  96. data/lib/hecks/bluebook/dsl/binding_proxy.rb +71 -0
  97. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +1018 -0
  98. data/lib/hecks/bluebook/dsl/command_builder.rb +626 -0
  99. data/lib/hecks/bluebook/dsl/const_shim.rb +81 -0
  100. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +79 -0
  101. data/lib/hecks/bluebook/dsl/entity_builder.rb +305 -0
  102. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +366 -0
  103. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +163 -0
  104. data/lib/hecks/bluebook/dsl/identity_declaration.rb +191 -0
  105. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +44 -0
  106. data/lib/hecks/bluebook/dsl/malformed.rb +7 -0
  107. data/lib/hecks/bluebook/dsl/policy_builder.rb +120 -0
  108. data/lib/hecks/bluebook/dsl/port_builder.rb +30 -0
  109. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +142 -0
  110. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +207 -0
  111. data/lib/hecks/bluebook/dsl/query_builder.rb +113 -0
  112. data/lib/hecks/bluebook/dsl/read_model_builder.rb +233 -0
  113. data/lib/hecks/bluebook/dsl/rule_reference.rb +172 -0
  114. data/lib/hecks/bluebook/dsl/translation_builder.rb +243 -0
  115. data/lib/hecks/bluebook/dsl/value_object_builder.rb +178 -0
  116. data/lib/hecks/bluebook/dsl/word_gate.rb +221 -0
  117. data/lib/hecks/bluebook/dsl/world_builder.rb +77 -0
  118. data/lib/hecks/bluebook/dsl.rb +45 -0
  119. data/lib/hecks/bluebook/entity.rb +103 -0
  120. data/lib/hecks/bluebook/expression/canonical_form.rb +55 -0
  121. data/lib/hecks/bluebook/expression/evaluator.rb +261 -0
  122. data/lib/hecks/bluebook/expression/projection.json +170 -0
  123. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +233 -0
  124. data/lib/hecks/bluebook/expression/resolver.rb +630 -0
  125. data/lib/hecks/bluebook/expression.rb +13 -0
  126. data/lib/hecks/bluebook/hexagon.rb +60 -0
  127. data/lib/hecks/bluebook/lifecycle.rb +42 -0
  128. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +54 -0
  129. data/lib/hecks/bluebook/meta_validator/judge.rb +559 -0
  130. data/lib/hecks/bluebook/meta_validator/plan.rb +332 -0
  131. data/lib/hecks/bluebook/meta_validator/port_judge.rb +47 -0
  132. data/lib/hecks/bluebook/meta_validator/readings.rb +350 -0
  133. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +312 -0
  134. data/lib/hecks/bluebook/meta_validator/shapes.rb +246 -0
  135. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +255 -0
  136. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +138 -0
  137. data/lib/hecks/bluebook/meta_validator/world_judge.rb +78 -0
  138. data/lib/hecks/bluebook/meta_validator.rb +452 -0
  139. data/lib/hecks/bluebook/model_check.rb +318 -0
  140. data/lib/hecks/bluebook/pattern_subset.rb +120 -0
  141. data/lib/hecks/bluebook/policy.rb +41 -0
  142. data/lib/hecks/bluebook/process_manager.rb +86 -0
  143. data/lib/hecks/bluebook/project_discovery.rb +30 -0
  144. data/lib/hecks/bluebook/project_loader.rb +40 -0
  145. data/lib/hecks/bluebook/project_register.rb +82 -0
  146. data/lib/hecks/bluebook/query.rb +61 -0
  147. data/lib/hecks/bluebook/read_model.rb +109 -0
  148. data/lib/hecks/bluebook/reference.rb +74 -0
  149. data/lib/hecks/bluebook/smoke_test.rb +166 -0
  150. data/lib/hecks/bluebook/synthesizer.rb +95 -0
  151. data/lib/hecks/bluebook/translation.rb +92 -0
  152. data/lib/hecks/bluebook/value_object.rb +58 -0
  153. data/lib/hecks/bluebook.rb +74 -0
  154. data/lib/hecks/codemod.rb +342 -0
  155. data/lib/hecks/construct.rb +71 -0
  156. data/lib/hecks/deploy/bluebook/deploy.bluebook +219 -0
  157. data/lib/hecks/deploy/bluebook/deploy.hecksagon +4 -0
  158. data/lib/hecks/deploy/oidc.json +18 -0
  159. data/lib/hecks/doc/reference.rb +389 -0
  160. data/lib/hecks/embryonaut_bluebook.rb +75 -0
  161. data/lib/hecks/facade/cli_door.rb +116 -0
  162. data/lib/hecks/facade/cli_runner.rb +190 -0
  163. data/lib/hecks/facade/command_request.rb +105 -0
  164. data/lib/hecks/facade/handle.rb +173 -0
  165. data/lib/hecks/facade/json_door.rb +154 -0
  166. data/lib/hecks/facade/surface/aggregate_door.rb +185 -0
  167. data/lib/hecks/facade/surface/chapter.rb +107 -0
  168. data/lib/hecks/facade/surface.rb +48 -0
  169. data/lib/hecks/facade.rb +44 -0
  170. data/lib/hecks/forms/app.rb +300 -0
  171. data/lib/hecks/forms/command_form_renderer.rb +113 -0
  172. data/lib/hecks/forms/examples/banking_console.bluebook +3 -0
  173. data/lib/hecks/forms/field_renderer.rb +170 -0
  174. data/lib/hecks/forms/field_shape.rb +232 -0
  175. data/lib/hecks/forms/html.rb +53 -0
  176. data/lib/hecks/forms/index_renderer.rb +35 -0
  177. data/lib/hecks/forms/page.rb +157 -0
  178. data/lib/hecks/forms/params.rb +132 -0
  179. data/lib/hecks/forms/query_form_renderer.rb +114 -0
  180. data/lib/hecks/forms/record_renderer.rb +115 -0
  181. data/lib/hecks/forms/record_table.rb +63 -0
  182. data/lib/hecks/forms/reference_options.rb +30 -0
  183. data/lib/hecks/forms/value_object_shape.rb +46 -0
  184. data/lib/hecks/forms.rb +54 -0
  185. data/lib/hecks/fqn.rb +94 -0
  186. data/lib/hecks/framework/bluebook/compliance.bluebook +1 -0
  187. data/lib/hecks/framework/bluebook/console_settings.bluebook +489 -0
  188. data/lib/hecks/framework/bluebook/framework.hecksagon +32 -0
  189. data/lib/hecks/framework/bluebook/governance.bluebook +130 -0
  190. data/lib/hecks/framework/bluebook/identity.bluebook +90 -0
  191. data/lib/hecks/framework/oidc.json +39 -0
  192. data/lib/hecks/framework.rb +90 -0
  193. data/lib/hecks/freezer.rb +67 -0
  194. data/lib/hecks/fuzzing/invalid_value_generator.rb +86 -0
  195. data/lib/hecks/fuzzing/isolated_boot.rb +92 -0
  196. data/lib/hecks/fuzzing/properties.rb +1146 -0
  197. data/lib/hecks/fuzzing/replay.rb +635 -0
  198. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +93 -0
  199. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +54 -0
  200. data/lib/hecks/fuzzing/sequence_generator/picker.rb +96 -0
  201. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +185 -0
  202. data/lib/hecks/fuzzing/sequence_generator.rb +130 -0
  203. data/lib/hecks/fuzzing/value_generator.rb +177 -0
  204. data/lib/hecks/fuzzing.rb +12 -0
  205. data/lib/hecks/grammar/evolve.rb +291 -0
  206. data/lib/hecks/grammar/expression.bluebook +417 -0
  207. data/lib/hecks/grammar/expression_operators.json +1152 -0
  208. data/lib/hecks/grammar/grammar.hecksagon +20 -0
  209. data/lib/hecks/grammar/oidc.json +69 -0
  210. data/lib/hecks/grammar/translation.bluebook +203 -0
  211. data/lib/hecks/grammar.rb +178 -0
  212. data/lib/hecks/ir.rb +126 -0
  213. data/lib/hecks/language/adapter.bluebook +116 -0
  214. data/lib/hecks/language/bluebook/aggregate.bluebook +581 -0
  215. data/lib/hecks/language/bluebook/attaches/paging.bluebook +76 -0
  216. data/lib/hecks/language/bluebook/bluebook.bluebook +256 -0
  217. data/lib/hecks/language/bluebook/bluebook.hecksagon +24 -0
  218. data/lib/hecks/language/bluebook/command.bluebook +437 -0
  219. data/lib/hecks/language/bluebook/entity.bluebook +316 -0
  220. data/lib/hecks/language/bluebook/policy.bluebook +172 -0
  221. data/lib/hecks/language/bluebook/process_manager.bluebook +264 -0
  222. data/lib/hecks/language/bluebook/projection.bluebook +267 -0
  223. data/lib/hecks/language/bluebook/query.bluebook +245 -0
  224. data/lib/hecks/language/bluebook/shape.bluebook +292 -0
  225. data/lib/hecks/language/bluebook/syntax.bluebook +447 -0
  226. data/lib/hecks/language/bluebook/vocabulary.bluebook +364 -0
  227. data/lib/hecks/language/hecksagon/adapter_binding.bluebook +51 -0
  228. data/lib/hecks/language/hecksagon/domain_port.bluebook +76 -0
  229. data/lib/hecks/language/hecksagon/hecksagon.bluebook +131 -0
  230. data/lib/hecks/language/hecksagon/port_operation.bluebook +102 -0
  231. data/lib/hecks/language/oidc.json +313 -0
  232. data/lib/hecks/language/port.bluebook +92 -0
  233. data/lib/hecks/language/translation/translation.bluebook +110 -0
  234. data/lib/hecks/language/translation/translation_aggregate.bluebook +267 -0
  235. data/lib/hecks/language/world/wiring.bluebook +62 -0
  236. data/lib/hecks/language/world/world.bluebook +84 -0
  237. data/lib/hecks/literal.rb +125 -0
  238. data/lib/hecks/naming.rb +121 -0
  239. data/lib/hecks/ports/access_control.port +4 -0
  240. data/lib/hecks/ports/access_control.rb +62 -0
  241. data/lib/hecks/ports/agent/answers.rb +104 -0
  242. data/lib/hecks/ports/agent.port +4 -0
  243. data/lib/hecks/ports/agent.rb +167 -0
  244. data/lib/hecks/ports/authentication.port +4 -0
  245. data/lib/hecks/ports/authentication.rb +50 -0
  246. data/lib/hecks/ports/authorization.port +4 -0
  247. data/lib/hecks/ports/authorization.rb +59 -0
  248. data/lib/hecks/ports/clock.port +4 -0
  249. data/lib/hecks/ports/clock.rb +62 -0
  250. data/lib/hecks/ports/extraction.port +4 -0
  251. data/lib/hecks/ports/extraction.rb +37 -0
  252. data/lib/hecks/ports/identity_assignment.port +4 -0
  253. data/lib/hecks/ports/identity_assignment.rb +45 -0
  254. data/lib/hecks/ports/identity_generation.port +4 -0
  255. data/lib/hecks/ports/identity_generation.rb +49 -0
  256. data/lib/hecks/ports/identity_resolution.port +4 -0
  257. data/lib/hecks/ports/identity_resolution.rb +40 -0
  258. data/lib/hecks/ports/loading.port +4 -0
  259. data/lib/hecks/ports/loading.rb +13 -0
  260. data/lib/hecks/ports/persistence/append_only.rb +102 -0
  261. data/lib/hecks/ports/persistence/binding_policy.rb +56 -0
  262. data/lib/hecks/ports/persistence/execution.rb +18 -0
  263. data/lib/hecks/ports/persistence/lineage.rb +277 -0
  264. data/lib/hecks/ports/persistence/null_saga_store.rb +25 -0
  265. data/lib/hecks/ports/persistence/remote_runtime.rb +42 -0
  266. data/lib/hecks/ports/persistence/repository_factory.rb +30 -0
  267. data/lib/hecks/ports/persistence.port +4 -0
  268. data/lib/hecks/ports/persistence.rb +39 -0
  269. data/lib/hecks/ports/projection.port +4 -0
  270. data/lib/hecks/ports/projection.rb +76 -0
  271. data/lib/hecks/ports/query/in_memory.rb +60 -0
  272. data/lib/hecks/ports/query/ordering.rb +41 -0
  273. data/lib/hecks/ports/query.rb +36 -0
  274. data/lib/hecks/ports.rb +27 -0
  275. data/lib/hecks/projections/diagrams.rb +413 -0
  276. data/lib/hecks/projections/ir.rb +18 -0
  277. data/lib/hecks/projections/model/deviations.rb +98 -0
  278. data/lib/hecks/projections/model.rb +145 -0
  279. data/lib/hecks/projections/oidc.rb +110 -0
  280. data/lib/hecks/projections/parser_table.rb +159 -0
  281. data/lib/hecks/projections/reference.rb +38 -0
  282. data/lib/hecks/projections/shape.rb +31 -0
  283. data/lib/hecks/projections/statements.rb +110 -0
  284. data/lib/hecks/projections/vocabulary.rb +100 -0
  285. data/lib/hecks/projections.rb +32 -0
  286. data/lib/hecks/projector/cli_projector.rb +437 -0
  287. data/lib/hecks/projector/docs_projector.rb +321 -0
  288. data/lib/hecks/projector/exporter.rb +141 -0
  289. data/lib/hecks/projector/ir_projector.rb +18 -0
  290. data/lib/hecks/projector/narrate_projector.rb +243 -0
  291. data/lib/hecks/projector/target.rb +97 -0
  292. data/lib/hecks/projector.rb +186 -0
  293. data/lib/hecks/query_ir.rb +392 -0
  294. data/lib/hecks/query_specification/common/authorization_spec.rb +9 -0
  295. data/lib/hecks/query_specification/common/comparators.rb +25 -0
  296. data/lib/hecks/query_specification/common/comparison.rb +174 -0
  297. data/lib/hecks/query_specification/common/cursor_spec.rb +9 -0
  298. data/lib/hecks/query_specification/common/dsl.rb +58 -0
  299. data/lib/hecks/query_specification/common/inspection_spec.rb +9 -0
  300. data/lib/hecks/query_specification/common/limit_spec.rb +9 -0
  301. data/lib/hecks/query_specification/common/null_policy.rb +80 -0
  302. data/lib/hecks/query_specification/common/null_semantics.rb +11 -0
  303. data/lib/hecks/query_specification/common/offset_spec.rb +9 -0
  304. data/lib/hecks/query_specification/common/options.rb +32 -0
  305. data/lib/hecks/query_specification/common/order_by.rb +9 -0
  306. data/lib/hecks/query_specification/common/specification.rb +10 -0
  307. data/lib/hecks/query_specification/common/where_clause.rb +9 -0
  308. data/lib/hecks/query_specification/field_path.rb +89 -0
  309. data/lib/hecks/query_specification/hop_path.rb +130 -0
  310. data/lib/hecks/query_specification/read_model/specification.rb +18 -0
  311. data/lib/hecks/query_specification.rb +14 -0
  312. data/lib/hecks/rendering.rb +48 -0
  313. data/lib/hecks/router/namespace_installer.rb +157 -0
  314. data/lib/hecks/router.rb +70 -0
  315. data/lib/hecks/runtime/caller.rb +50 -0
  316. data/lib/hecks/runtime/capability_graph.rb +44 -0
  317. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +124 -0
  318. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +248 -0
  319. data/lib/hecks/runtime/command_interpreter.rb +413 -0
  320. data/lib/hecks/runtime/command_rules/admissibility.rb +307 -0
  321. data/lib/hecks/runtime/command_rules/arithmetic.rb +254 -0
  322. data/lib/hecks/runtime/command_rules/authorization.rb +64 -0
  323. data/lib/hecks/runtime/command_rules/emission.rb +34 -0
  324. data/lib/hecks/runtime/command_rules/references.rb +181 -0
  325. data/lib/hecks/runtime/command_rules.rb +28 -0
  326. data/lib/hecks/runtime/dependency_planning.rb +231 -0
  327. data/lib/hecks/runtime/dispatcher.rb +286 -0
  328. data/lib/hecks/runtime/entity_element.rb +253 -0
  329. data/lib/hecks/runtime/entity_interpreter.rb +228 -0
  330. data/lib/hecks/runtime/era_check.rb +136 -0
  331. data/lib/hecks/runtime/era_guard/shape_diff.rb +128 -0
  332. data/lib/hecks/runtime/era_guard.rb +193 -0
  333. data/lib/hecks/runtime/era_tamper.rb +61 -0
  334. data/lib/hecks/runtime/errors.rb +100 -0
  335. data/lib/hecks/runtime/event.rb +51 -0
  336. data/lib/hecks/runtime/identity.rb +128 -0
  337. data/lib/hecks/runtime/instance.rb +120 -0
  338. data/lib/hecks/runtime/interpreting.rb +69 -0
  339. data/lib/hecks/runtime/loader.rb +143 -0
  340. data/lib/hecks/runtime/policy_interpreter.rb +366 -0
  341. data/lib/hecks/runtime/port_operation_interpreter.rb +210 -0
  342. data/lib/hecks/runtime/query_interpreter.rb +254 -0
  343. data/lib/hecks/runtime/reaction_invocation.rb +245 -0
  344. data/lib/hecks/runtime/read_model_interpreter.rb +266 -0
  345. data/lib/hecks/runtime/rebuild_sweep.rb +74 -0
  346. data/lib/hecks/runtime/reference_hop.rb +99 -0
  347. data/lib/hecks/runtime/refusal_wording.rb +124 -0
  348. data/lib/hecks/runtime/registry/saga_persistence.rb +70 -0
  349. data/lib/hecks/runtime/registry/verification.rb +158 -0
  350. data/lib/hecks/runtime/registry.rb +218 -0
  351. data/lib/hecks/runtime/remote_dispatcher.rb +143 -0
  352. data/lib/hecks/runtime/routing.rb +96 -0
  353. data/lib/hecks/runtime/saga_interpreter/correlation.rb +97 -0
  354. data/lib/hecks/runtime/saga_interpreter.rb +301 -0
  355. data/lib/hecks/runtime/storage_shape.rb +120 -0
  356. data/lib/hecks/runtime/tenant_check.rb +84 -0
  357. data/lib/hecks/runtime/tenant_scope.rb +55 -0
  358. data/lib/hecks/runtime/value/admission.rb +112 -0
  359. data/lib/hecks/runtime/value/coercion.rb +500 -0
  360. data/lib/hecks/runtime/value/invariant_violation.rb +5 -0
  361. data/lib/hecks/runtime/value.rb +125 -0
  362. data/lib/hecks/runtime.rb +95 -0
  363. data/lib/hecks/translation/audit/approval_digest.rb +31 -0
  364. data/lib/hecks/translation/audit/layer_one.rb +37 -0
  365. data/lib/hecks/translation/audit/layer_two.rb +77 -0
  366. data/lib/hecks/translation/audit/unfed_report.rb +42 -0
  367. data/lib/hecks/translation/audit.rb +70 -0
  368. data/lib/hecks/translation/reattest.rb +72 -0
  369. data/lib/hecks/translation/rule_compiler.rb +120 -0
  370. data/lib/hecks/translation/scaffold/differ.rb +183 -0
  371. data/lib/hecks/translation/scaffold/renderer.rb +41 -0
  372. data/lib/hecks/translation/scaffold/writer.rb +28 -0
  373. data/lib/hecks/translation/scaffold.rb +30 -0
  374. data/lib/hecks/translation.rb +11 -0
  375. data/lib/hecks/version.rb +16 -0
  376. data/lib/hecks/vocabulary.rb +213 -0
  377. data/lib/hecks.rb +118 -6
  378. metadata +401 -222
  379. data/bin/hecks +0 -7
  380. data/bin/hecks-package +0 -65
  381. data/bin/hecks_console +0 -12
  382. data/bin/hecks_serverless +0 -6
  383. data/lib/cli/build.rb +0 -14
  384. data/lib/cli/command_runner.rb +0 -28
  385. data/lib/cli/console.rb +0 -10
  386. data/lib/cli/generate.rb +0 -37
  387. data/lib/cli/hecks-cli.rb +0 -27
  388. data/lib/cli/test.rb +0 -57
  389. data/lib/console/commands.rb +0 -8
  390. data/lib/console/hecks-console.rb +0 -1
  391. data/lib/packager/README.md +0 -0
  392. data/lib/packager/app_runner.rb +0 -21
  393. data/lib/packager/args.rb +0 -26
  394. data/lib/packager/compatibility/fixnum.rb +0 -6
  395. data/lib/packager/hecks.rb +0 -39
  396. data/lib/packager/query_runner.rb +0 -21
  397. data/lib/packager/resources/Dockerfile +0 -11
  398. data/lib/packager/resources/app_binary +0 -7
  399. data/lib/packager/resources/bundle_config +0 -3
  400. data/lib/packager/resources/traveling-ruby-20150715-2.2.2-linux-x86_64.tar.gz +0 -0
  401. data/lib/packager/resources/traveling-ruby-20150715-2.2.2-osx.tar.gz +0 -0
  402. data/lib/serverless/Domain +0 -32
  403. data/lib/serverless/cli.rb +0 -75
  404. data/lib/serverless/resources/command_name.js +0 -5
  405. data/lib/serverless/resources/environment.js +0 -7
  406. data/lib/serverless/resources/handler.js.tt +0 -28
  407. data/lib/serverless/resources/run_binary.js +0 -22
  408. data/lib/serverless/resources/serverless.yml +0 -20
@@ -0,0 +1,316 @@
1
+ Hecks.bluebook "Bluebook" do
2
+ aggregate "Entity" do
3
+ description "One entity inside an aggregate — an element with its own identity, state machine, commands and queries. Its own root because it repeats the aggregate's whole shape one level down."
4
+
5
+ reference_to Aggregate
6
+
7
+ # THE AGGREGATE IT IS IN, AND ITS NAME. Note this is the identity of the RECORD
8
+ # describing a piece, which is a different thing from the identity that piece
9
+ # itself declares (`identified_by`, the list below).
10
+ identified_by :aggregate, :name
11
+
12
+ attribute :owner, EntityText
13
+ attribute :name, EntityName
14
+ attribute :description, EntityName
15
+ # SEVERAL PATHS, joined — a piece spells an identity exactly as a head does,
16
+ # which is the whole point of it being its own root.
17
+ attribute :identified_by, list_of(IdentityPath)
18
+ attribute :attributes, list_of(PieceField)
19
+ # ADR 0028 — A PRECONDITION SHARED ACROSS THIS PIECE'S OWN COMMANDS,
20
+ # DECLARED ONCE — the SAME Rule shape Aggregate's own `preconditions`
21
+ # already carries (that file's own comment on why it's declared
22
+ # again here rather than shared: a value object is aggregate-scoped
23
+ # in this self-hosting domain).
24
+ attribute :preconditions, list_of(Rule)
25
+ # A PIECE'S OWN SHAPE RULE — the SAME Rule shape, checked (round 7)
26
+ # against EVERY INSTANCE this piece's own aggregate holds, not the
27
+ # aggregate's own flat state — `ValueObject#invariants`'s own
28
+ # relationship to ITS OWN instances, one construct over.
29
+ attribute :invariants, list_of(Rule)
30
+ attribute :state_field, EntityText, optional: true
31
+ attribute :state_start, EntityText, optional: true
32
+ attribute :transitions, list_of(PieceTransition)
33
+
34
+ value_object "EntityName" do
35
+ attribute :value, String
36
+ invariant("an entity is named") { !value.to_s.empty? }
37
+ end
38
+
39
+ value_object "EntityText" do
40
+ attribute :value, String
41
+ end
42
+
43
+ # See Aggregate's own "Rule" value object — the identical shape,
44
+ # declared again here rather than shared (that file's own comment
45
+ # on why).
46
+ value_object "Rule" do
47
+ attribute :description, String
48
+ attribute :canonical, String
49
+ end
50
+
51
+ # A piece's identity is made of parts the same way a head's is, so it holds
52
+ # the same shape. Declared here rather than shared because a value object
53
+ # belongs to the aggregate that uses it.
54
+ value_object "IdentityPath" do
55
+ attribute :value, String
56
+ end
57
+
58
+ value_object "PieceField" do
59
+ attribute :name, String
60
+ attribute :type, String
61
+ attribute :list, String
62
+ attribute :optional, String, optional: true
63
+ attribute :pattern, String, optional: true
64
+ attribute :default, String
65
+ # The closed set this value must belong to — see Aggregate::Field.
66
+ attribute :admits, String, optional: true
67
+ attribute :relationship, String, optional: true
68
+ end
69
+
70
+ value_object "PieceTransition" do
71
+ attribute :command, String
72
+ attribute :from_state, String
73
+ attribute :to_state, String
74
+ end
75
+
76
+ # The way back: everything DECLARED IN the aggregate above. The parent
77
+ # reference IS the query.
78
+ # WHERE IT SITS AMONG ITS SIBLINGS. Declaration order is a FACT ABOUT THE
79
+ # SOURCE — the IR is a contract read straight from this file,
80
+ # field for field AND INDEX FOR INDEX. So the language HOLDS it, instead of
81
+ # inheriting it from whatever order a store happens to iterate: an ask that
82
+ # does not say how it is ordered is answered in identity order, which is
83
+ # right for every other ask and fatal for the one that is the SOURCE.
84
+ value_object "Position" do
85
+ attribute :value, Integer
86
+ end
87
+
88
+ attribute :position, Position
89
+
90
+ query "DeclaredIn" do
91
+ attribute :aggregate, EntityText
92
+ where(aggregate: :aggregate)
93
+ order_by :position
94
+ end
95
+ command "Declare" do
96
+ role "Language"
97
+ goal "Open an entity inside an aggregate"
98
+
99
+ reference_to Aggregate
100
+ attribute :owner, EntityText
101
+ attribute :name, EntityName
102
+ attribute :description, EntityName, optional: true
103
+
104
+ attribute :position, Position, optional: true
105
+ sets :aggregate
106
+ sets :owner
107
+ sets :name
108
+ sets :description
109
+ sets :position
110
+ emits "PieceDeclared"
111
+ end
112
+
113
+ # ONE PART OF THE PIECE'S IDENTITY, attached exactly as an aggregate's is.
114
+ #
115
+ # A PIECE MUST SAY WHAT IT IS KNOWN BY — the rule, where the language keeps
116
+ # its rules. An entity is an element with an identity of ITS OWN ; that is
117
+ # the whole difference between a piece and a value object, so a command
118
+ # acting on one must be able to say which one. Undeclared, every reader
119
+ # has to invent its own answer — fall through to nothing, or assume
120
+ # `id` — and inventions agree only because every entity in the corpus happened
121
+ # to declare it: a divergence the
122
+ # declaration was masking. Requiring it removes the default there was to
123
+ # disagree about. That requirement now sits on Seal, where a whole-document
124
+ # rule belongs ; what stays here is the shape of each part.
125
+ command "Identify" do
126
+ role "Language"
127
+ goal "Attach one part of the entity's identity"
128
+
129
+ attribute :path, IdentityPath
130
+
131
+ # See Aggregate.Identify, where the same rule is written out in full —
132
+ # the builder resolves the real shape (dotted-unwrap, reference, or
133
+ # bare scalar) before a part ever reaches here.
134
+ given("an identity part names something") { !path.value.to_s.empty? }
135
+
136
+ sets :identified_by, append: { value: :path }
137
+ emits "PieceIdentified"
138
+ end
139
+
140
+ command "Seal" do
141
+ role "Language"
142
+ goal "Close an entity — the checks that need every declaration present"
143
+
144
+ # A piece gets the whole-document shape a head has, for the same reason :
145
+ # "it said SOMETHING" cannot be asked while the parts are still arriving.
146
+
147
+ given("an entity says what it is known by") { !identified_by.empty? }
148
+
149
+ emits "PieceSealed"
150
+ end
151
+
152
+ command "Attribute" do
153
+ role "Language"
154
+ goal "Attach one attribute to the entity"
155
+
156
+ attribute :name, EntityText
157
+ attribute :type, EntityText
158
+ attribute :list, EntityText
159
+ attribute :optional, EntityText, optional: true
160
+ attribute :pattern, EntityText, optional: true
161
+ attribute :default, EntityText, optional: true
162
+ attribute :admits, EntityText, optional: true
163
+ attribute :relationship, EntityText, optional: true
164
+
165
+ sets :attributes, append: { name: :name, type: :type, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
166
+
167
+ emits "PieceAttributeAttached"
168
+ end
169
+
170
+
171
+ # A PRECONDITION SHARED ACROSS THIS PIECE'S OWN COMMANDS, DECLARED
172
+ # ONCE (ADR 0028) — see Aggregate.Precondition, the identical shape
173
+ # one level down: the piece's own named `given`, referenced back by
174
+ # one of its own commands rather than re-typed.
175
+ command "Precondition" do
176
+ role "Language"
177
+ goal "Declare one precondition this piece's own commands can reference by name"
178
+
179
+ attribute :description, EntityText, optional: true
180
+ attribute :canonical, EntityText
181
+
182
+ given("a rule says what it means") { !description.value.to_s.empty? }
183
+ given("a rule survives extraction") { !canonical.value.to_s.empty? }
184
+
185
+ sets :preconditions, append: { description: :description, canonical: :canonical }
186
+
187
+ emits "PiecePreconditionAttached"
188
+ end
189
+
190
+ # A PIECE'S OWN SHAPE RULE, DECLARED ONCE (round 7) — see
191
+ # Aggregate.Invariant, the identical shape one level down: checked
192
+ # against every instance of this piece, not this ONE aggregate's
193
+ # own flat state.
194
+ command "Invariant" do
195
+ role "Language"
196
+ goal "Attach one shape rule this piece's own instances must hold"
197
+
198
+ attribute :description, EntityText, optional: true
199
+ attribute :canonical, EntityText
200
+
201
+ given("a rule says what it means") { !description.value.to_s.empty? }
202
+ given("a rule survives extraction") { !canonical.value.to_s.empty? }
203
+
204
+ sets :invariants, append: { description: :description, canonical: :canonical }
205
+
206
+ emits "PieceInvariantAttached"
207
+ end
208
+
209
+ command "Lifecycle" do
210
+ role "Language"
211
+ goal "Name the field this entity's state machine runs on"
212
+
213
+
214
+ sets :state_field
215
+ sets :state_start
216
+
217
+ emits "PieceLifecycleNamed"
218
+ end
219
+
220
+ command "Transition" do
221
+ role "Language"
222
+ goal "Attach one transition to the entity's state machine"
223
+
224
+ attribute :command, EntityText
225
+ attribute :from_state, EntityText, optional: true
226
+ attribute :to_state, EntityText
227
+
228
+ sets :transitions, append: { command: :command, from_state: :from_state, to_state: :to_state }
229
+
230
+ emits "PieceTransitionAttached"
231
+ end
232
+
233
+ # HOW ENTITY IS SPELLED. These rows live with the concept
234
+ # they describe; SyntaxBoot discovers every aggregate-local seed table.
235
+ # Contexts represented here: Entity.
236
+ value_object "KeywordSeed" do
237
+ attribute :word, String
238
+ attribute :context, String, admits: "Syntax::Context"
239
+ attribute :body, String, admits: "Syntax::Body"
240
+ attribute :inner, String
241
+ attribute :opens, String
242
+ attribute :fills, String
243
+ attribute :status, String, default: "admitted", admits: "Syntax::Status"
244
+ attribute :was, String
245
+ attribute :resolves_via, String, default: "", admits: "Syntax::ResolutionScope"
246
+ attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
247
+
248
+ member word: "description", context: "Entity", body: "none", inner: "", opens: "", fills: "description"
249
+ member word: "identified_by", context: "Entity", body: "keywords", inner: "ValueObject", opens: "ValueObject", fills: "identified_by", calls: "identified_by_impl"
250
+ member word: "identified_by", context: "Entity", body: "none", inner: "", opens: "", fills: "identified_by", calls: "identified_by_impl"
251
+ member word: "given", context: "Entity", body: "source", inner: "", opens: "", fills: "preconditions", calls: "given_impl"
252
+ member word: "invariant", context: "Entity", body: "source", inner: "", opens: "", fills: "invariants", calls: "invariant_impl"
253
+ member word: "command", context: "Entity", body: "keywords", inner: "Command", opens: "Command", fills: "", calls: "command_impl"
254
+ member word: "query", context: "Entity", body: "keywords", inner: "Query", opens: "Query", fills: "", calls: "query_impl"
255
+ member word: "lifecycle", context: "Entity", body: "keywords", inner: "Lifecycle", opens: "", fills: "state_field", calls: "lifecycle_impl"
256
+ member word: "attribute", context: "Entity", body: "none", inner: "", opens: "", fills: "attributes", calls: "attribute_impl"
257
+ member word: "reference_to", context: "Entity", body: "none", inner: "", opens: "", fills: "attributes", calls: "reference_to_impl"
258
+ member word: "has_many", context: "Entity", body: "none", inner: "", opens: "", fills: "attributes", calls: "has_many_impl"
259
+ member word: "has_one", context: "Entity", body: "none", inner: "", opens: "", fills: "attributes", calls: "has_one_impl"
260
+ member word: "belongs_to", context: "Entity", body: "none", inner: "", opens: "", fills: "attributes", calls: "belongs_to_impl"
261
+ member word: "entity", context: "Entity", body: "keywords", inner: "Entity", opens: "Entity", fills: "", calls: "entity_impl"
262
+
263
+ end
264
+
265
+ value_object "ArgumentSeed" do
266
+ attribute :keyword, String
267
+ attribute :context, String, admits: "Syntax::Context"
268
+ attribute :at, String
269
+ attribute :named, String
270
+ attribute :kind, String, admits: "Syntax::ArgumentKind"
271
+ attribute :required, String
272
+ attribute :fills, String
273
+ attribute :selects, String
274
+ attribute :pair_key_fills, String
275
+ attribute :pair_value_fills, String
276
+ attribute :pairs_shape, String, admits: "Syntax::PairsShape"
277
+ attribute :status, String, default: "admitted", admits: "Syntax::Status"
278
+ attribute :variadic, String
279
+ attribute :minimum, String
280
+ attribute :coerce, String
281
+ attribute :blank_message, String
282
+
283
+ member keyword: "description", context: "Entity", at: "1", named: "", kind: "text", required: "true", fills: "description", coerce: "false"
284
+ member keyword: "given", context: "Entity", at: "1", named: "", kind: "text", required: "true", fills: "description"
285
+ member keyword: "invariant", context: "Entity", at: "1", named: "", kind: "text", required: "true", fills: "description"
286
+ member keyword: "identified_by", context: "Entity", at: "1", named: "", kind: "symbol", required: "false", fills: "identified_by", variadic: "true", minimum: "2"
287
+ member keyword: "identified_by", context: "Entity", at: "1", named: "", kind: "constant", required: "false", fills: "type"
288
+ member keyword: "identified_by", context: "Entity", at: "", named: "as", kind: "symbol", required: "false", fills: "name"
289
+ member keyword: "command", context: "Entity", at: "1", named: "", kind: "text", required: "true", fills: "name"
290
+ member keyword: "command", context: "Entity", at: "", named: "from", kind: "literal", required: "false", fills: "from"
291
+ member keyword: "query", context: "Entity", at: "1", named: "", kind: "text", required: "true", fills: "name"
292
+ member keyword: "entity", context: "Entity", at: "1", named: "", kind: "text", required: "true", fills: "name"
293
+ member keyword: "lifecycle", context: "Entity", at: "1", named: "", kind: "symbol", required: "true", fills: "state_field"
294
+ member keyword: "lifecycle", context: "Entity", at: "", named: "default", kind: "literal", required: "true", fills: "state_start"
295
+ member keyword: "attribute", context: "Entity", at: "1", named: "", kind: "symbol", required: "true", fills: "name"
296
+ member keyword: "attribute", context: "Entity", at: "2", named: "", kind: "constant", required: "true", fills: "type"
297
+ member keyword: "attribute", context: "Entity", at: "", named: "default", kind: "literal", required: "false", fills: "default"
298
+ member keyword: "attribute", context: "Entity", at: "", named: "optional", kind: "flag", required: "false", fills: "optional"
299
+ member keyword: "attribute", context: "Entity", at: "", named: "pattern", kind: "text", required: "false", fills: "pattern"
300
+ member keyword: "attribute", context: "Entity", at: "", named: "admits", kind: "text", required: "false", fills: "admits"
301
+ member keyword: "attribute", context: "Entity", at: "", named: "one_of", kind: "list", required: "false", fills: "one_of"
302
+ member keyword: "reference_to", context: "Entity", at: "1", named: "", kind: "constant", required: "true", fills: "type"
303
+ member keyword: "reference_to", context: "Entity", at: "", named: "as", kind: "symbol", required: "false", fills: "name"
304
+ member keyword: "reference_to", context: "Entity", at: "", named: "optional", kind: "flag", required: "false", fills: "optional"
305
+ member keyword: "has_many", context: "Entity", at: "1", named: "", kind: "constant", required: "true", fills: "type"
306
+ member keyword: "has_many", context: "Entity", at: "", named: "as", kind: "symbol", required: "false", fills: "name"
307
+ member keyword: "has_one", context: "Entity", at: "1", named: "", kind: "constant", required: "true", fills: "type"
308
+ member keyword: "has_one", context: "Entity", at: "", named: "as", kind: "symbol", required: "false", fills: "name"
309
+ member keyword: "has_one", context: "Entity", at: "", named: "optional", kind: "flag", required: "false", fills: "optional"
310
+ member keyword: "belongs_to", context: "Entity", at: "1", named: "", kind: "constant", required: "true", fills: "type"
311
+ member keyword: "belongs_to", context: "Entity", at: "", named: "as", kind: "symbol", required: "false", fills: "name"
312
+ member keyword: "belongs_to", context: "Entity", at: "", named: "optional", kind: "flag", required: "false", fills: "optional"
313
+
314
+ end
315
+ end
316
+ end
@@ -0,0 +1,172 @@
1
+ Hecks.bluebook "Bluebook" do
2
+ aggregate "Policy" do
3
+ description "One policy — the event it watches, the command it fires, and the domain that command belongs to."
4
+
5
+ reference_to Bluebook
6
+
7
+ # THE CHAPTER IT IS IN, AND ITS NAME. A policy hangs off the chapter rather
8
+ # than an aggregate, so the chapter is the part above it.
9
+ identified_by :bluebook, :name
10
+
11
+ attribute :name, PolicyName
12
+ # WHICH HEAD DECLARED IT, empty for a reaction the chapter owns.
13
+ #
14
+ # A policy written inside an aggregate is hoisted onto the chapter by the
15
+ # builder, and the chapter is where the runtime reads it — so nothing was ever
16
+ # lost at runtime. What was lost is where it was WRITTEN, which is a fact about
17
+ # the source, and facts about the source are what this language holds.
18
+ # `Aggregate#to_h` does not carry it and does not need to: the wire format is
19
+ # a contract, and the language may hold more than it.
20
+ attribute :aggregate, PolicyText
21
+ attribute :on_event, PolicyText
22
+ attribute :trigger_command, PolicyText
23
+ attribute :target_domain, PolicyText
24
+ # THE GUARD, CARRIED AS TEXT — same discipline `Command.givens`
25
+ # already holds: the block that wrote it is never called at
26
+ # runtime, only its EXTRACTED SOURCE is (Ports::Extraction), so
27
+ # what the language holds is the string, not a live Proc no wire
28
+ # format could carry. Optional — most policies fire unconditionally.
29
+ attribute :where, PolicyText, optional: true
30
+ # THE FAN-OUT SOURCE — a query verb ("Aggregate.query_name" or
31
+ # "Domain::Aggregate.query_name"), same text shape as
32
+ # `trigger_command`/`target_domain` beside it. Optional — most
33
+ # policies fire once, not once per row.
34
+ attribute :for_each, PolicyText, optional: true
35
+ # WHAT THE TRIGGER IS GIVEN, when the event's own shape is not it.
36
+ # Empty means the whole payload forwards verbatim — what every policy
37
+ # did before this existed, and still the right default for a trigger
38
+ # shaped like its event.
39
+ #
40
+ # The same `Binding` list a saga's own `Dispatch` carries, for the
41
+ # same reason: a reaction crosses an aggregate boundary, and the
42
+ # event on one side is under no obligation to be shaped like the
43
+ # command on the other. Without it the target has to declare every
44
+ # field the event happens to carry — banking's own `FreezeAccount`
45
+ # grew an attribute it never reads, and Account grew two duplicated
46
+ # value objects to type it, before this word existed.
47
+ attribute :with_spec, list_of(Binding)
48
+
49
+ value_object "PolicyName" do
50
+ attribute :value, String
51
+ invariant("a policy is named") { !value.to_s.empty? }
52
+ end
53
+
54
+ value_object "PolicyText" do
55
+ attribute :value, String
56
+ end
57
+
58
+ # DECLARED HERE RATHER THAN SHARED WITH `Dispatch`'s own — a value
59
+ # object belongs to the aggregate that uses it, and everything that
60
+ # walks an aggregate's own scope has nowhere else to look.
61
+ value_object "Binding" do
62
+ attribute :key, String
63
+ attribute :value, String
64
+ end
65
+
66
+ # The way back: everything DECLARED IN the chapter above. The parent
67
+ # reference IS the query.
68
+ # WHERE IT SITS AMONG ITS SIBLINGS. Declaration order is a FACT ABOUT THE
69
+ # SOURCE — the IR is a contract read straight from this file,
70
+ # field for field AND INDEX FOR INDEX. So the language HOLDS it, instead of
71
+ # inheriting it from whatever order a store happens to iterate: an ask that
72
+ # does not say how it is ordered is answered in identity order, which is
73
+ # right for every other ask and fatal for the one that is the SOURCE.
74
+ value_object "Position" do
75
+ attribute :value, Integer
76
+ end
77
+
78
+ attribute :position, Position
79
+
80
+ query "DeclaredIn" do
81
+ attribute :bluebook, PolicyText
82
+ where(bluebook: :bluebook)
83
+ order_by :position
84
+ end
85
+ command "Declare" do
86
+ role "Language"
87
+ goal "Declare a policy on a chapter"
88
+
89
+ reference_to Bluebook
90
+ attribute :name, PolicyName
91
+ attribute :aggregate, PolicyText, optional: true
92
+ attribute :on_event, PolicyText
93
+ attribute :trigger_command, PolicyText
94
+ attribute :target_domain, PolicyText, optional: true
95
+ attribute :where, PolicyText, optional: true
96
+ attribute :for_each, PolicyText, optional: true
97
+
98
+ attribute :position, Position, optional: true
99
+ sets :bluebook
100
+ sets :name
101
+ sets :aggregate
102
+ sets :on_event
103
+ sets :trigger_command
104
+ sets :target_domain
105
+ sets :where
106
+ sets :for_each
107
+ sets :position
108
+ emits "ReactionDeclared"
109
+ end
110
+
111
+ command "Bind" do
112
+ role "Language"
113
+ goal "Bind one argument of the triggered command"
114
+
115
+ attribute :key, PolicyText
116
+ attribute :value, PolicyText
117
+
118
+ sets :with_spec, append: { key: :key, value: :value }
119
+
120
+ emits "TriggerBindingAttached"
121
+ end
122
+
123
+ # HOW POLICY IS SPELLED. These rows live with the concept
124
+ # they describe; SyntaxBoot discovers every aggregate-local seed table.
125
+ # Contexts represented here: Policy.
126
+ value_object "KeywordSeed" do
127
+ attribute :word, String
128
+ attribute :context, String, admits: "Syntax::Context"
129
+ attribute :body, String, admits: "Syntax::Body"
130
+ attribute :inner, String
131
+ attribute :opens, String
132
+ attribute :fills, String
133
+ attribute :status, String, default: "admitted", admits: "Syntax::Status"
134
+ attribute :was, String
135
+ attribute :resolves_via, String, default: "", admits: "Syntax::ResolutionScope"
136
+ attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
137
+
138
+ member word: "on", context: "Policy", body: "none", inner: "", opens: "", fills: "on_event"
139
+ member word: "trigger", context: "Policy", body: "none", inner: "", opens: "", fills: "trigger_command", calls: "trigger_impl"
140
+ member word: "across", context: "Policy", body: "none", inner: "", opens: "", fills: "target_domain"
141
+ member word: "where", context: "Policy", body: "source", inner: "", opens: "", fills: "where"
142
+ member word: "for_each", context: "Policy", body: "none", inner: "", opens: "", fills: "for_each"
143
+
144
+ end
145
+
146
+ value_object "ArgumentSeed" do
147
+ attribute :keyword, String
148
+ attribute :context, String, admits: "Syntax::Context"
149
+ attribute :at, String
150
+ attribute :named, String
151
+ attribute :kind, String, admits: "Syntax::ArgumentKind"
152
+ attribute :required, String
153
+ attribute :fills, String
154
+ attribute :selects, String
155
+ attribute :pair_key_fills, String
156
+ attribute :pair_value_fills, String
157
+ attribute :pairs_shape, String, admits: "Syntax::PairsShape"
158
+ attribute :status, String, default: "admitted", admits: "Syntax::Status"
159
+ attribute :variadic, String
160
+ attribute :coerce, String
161
+ attribute :blank_message, String
162
+
163
+ member keyword: "on", context: "Policy", at: "1", named: "", kind: "text", required: "true", fills: "on_event"
164
+ member keyword: "trigger", context: "Policy", at: "1", named: "", kind: "constant", required: "true", fills: "trigger_command"
165
+ member keyword: "trigger", context: "Policy", at: "1", named: "", kind: "text", required: "true", fills: "trigger_command"
166
+ member keyword: "across", context: "Policy", at: "1", named: "", kind: "text", required: "true", fills: "target_domain"
167
+ member keyword: "for_each", context: "Policy", at: "1", named: "", kind: "text", required: "true", fills: "for_each"
168
+ member keyword: "trigger", context: "Policy", at: "", named: "with", kind: "pairs", required: "false", fills: "with_spec", pairs_shape: "verbatim"
169
+
170
+ end
171
+ end
172
+ end