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,264 @@
1
+ Hecks.bluebook "Bluebook" do
2
+ aggregate "ProcessManager" do
3
+ description "One process manager — what correlates its instances, what starts and ends it, and the states it moves through."
4
+
5
+ reference_to Bluebook
6
+
7
+ # THE CHAPTER IT IS IN, AND ITS NAME — the same shape a policy takes, and for
8
+ # the same reason.
9
+ identified_by :bluebook, :name
10
+
11
+ attribute :name, ProcessManagerName
12
+ attribute :correlates_by, ProcessManagerText
13
+ attribute :starts_on, ProcessManagerText
14
+ attribute :ends_on, ProcessManagerText
15
+ attribute :states, list_of(SagaState)
16
+ # S17, ADR 0026 — Handler nested here (see `entity "Handler"`, below),
17
+ # an entity rather than its own root aggregate. `list_of(Handler)`
18
+ # forward-references it the same way banking's own `attribute :ledger,
19
+ # list_of(LedgerEntry)` names LedgerEntry before it is declared.
20
+ attribute :handlers, list_of(Handler)
21
+
22
+ value_object "ProcessManagerName" do
23
+ attribute :value, String
24
+ invariant("a process manager is named") { !value.to_s.empty? }
25
+ end
26
+
27
+ value_object "ProcessManagerText" do
28
+ attribute :value, String
29
+ end
30
+
31
+ value_object "SagaState" do
32
+ attribute :name, String
33
+ end
34
+
35
+ # S17, ADR 0026 — HandlerText/DispatchText/Binding, hoisted up from
36
+ # the old standalone `aggregate "Handler"`/`aggregate "Dispatch"`. An
37
+ # entity cannot declare its own `value_object` (EntityBuilder has no
38
+ # such method — a piece borrows its owning aggregate's, the same way
39
+ # LedgerEntry borrows Account's Money), so these live here now, at
40
+ # the ROOT, where BOTH `entity "Handler"` and its own nested `entity
41
+ # "Dispatch"` can still reach them — a piece mints no value objects
42
+ # of its own AT ANY DEPTH, so there is exactly one pool however deep
43
+ # the nesting goes (`EntityBuilder#entity`'s own comment).
44
+ value_object "HandlerText" do
45
+ attribute :value, String
46
+ end
47
+
48
+ value_object "DispatchText" do
49
+ attribute :value, String
50
+ end
51
+
52
+ value_object "Binding" do
53
+ attribute :key, String
54
+ attribute :value, String
55
+ end
56
+
57
+ # The way back: everything DECLARED IN the chapter above. The parent
58
+ # reference IS the query.
59
+ # WHERE IT SITS AMONG ITS SIBLINGS. Declaration order is a FACT ABOUT THE
60
+ # SOURCE — the IR is a contract read straight from this file,
61
+ # field for field AND INDEX FOR INDEX. So the language HOLDS it, instead of
62
+ # inheriting it from whatever order a store happens to iterate: an ask that
63
+ # does not say how it is ordered is answered in identity order, which is
64
+ # right for every other ask and fatal for the one that is the SOURCE.
65
+ value_object "Position" do
66
+ attribute :value, Integer
67
+ end
68
+
69
+ attribute :position, Position
70
+
71
+ query "DeclaredIn" do
72
+ attribute :bluebook, ProcessManagerText
73
+ where(bluebook: :bluebook)
74
+ order_by :position
75
+ end
76
+ command "Declare" do
77
+ role "Language"
78
+ goal "Open a process manager on a chapter"
79
+
80
+ reference_to Bluebook
81
+ attribute :name, ProcessManagerName
82
+ attribute :correlates_by, ProcessManagerText
83
+ attribute :starts_on, ProcessManagerText
84
+ # A PROCEDURE NEED NOT DECLARE AN ENDING. The runtime has always held
85
+ # this optional — ProcessManagerBuilder defaults `@ends_on` to nil,
86
+ # validates only correlates_by/starts_on/states/handlers,
87
+ # and fills it only if the line is written. The
88
+ # language was the one saying it was required, and nothing in the corpus
89
+ # had to disagree because every procedure in it happens to end.
90
+ attribute :ends_on, ProcessManagerText, optional: true
91
+
92
+ attribute :position, Position, optional: true
93
+ sets :bluebook
94
+ sets :name
95
+ sets :correlates_by
96
+ sets :starts_on
97
+ sets :ends_on
98
+ sets :position
99
+ emits "SagaDeclared"
100
+ end
101
+
102
+ command "State" do
103
+ role "Language"
104
+ goal "Attach one state to the process manager"
105
+
106
+ attribute :name, ProcessManagerText
107
+
108
+ sets :states, append: { name: :name }
109
+
110
+ emits "SagaStateAttached"
111
+ end
112
+
113
+ # THE HANDLER'S OWN CREATION. S17, ADR 0026 — Handler is a genuine
114
+ # ENTITY now (`entity "Handler"`, below), and an entity is never
115
+ # created through its own dotted verb — banking's own LedgerEntry is
116
+ # created by `Account.LogEntry`, an ordinary append on the OWNER,
117
+ # never by a `LedgerEntry.Declare` of its own
118
+ # (`EntityInterpreter#element_of` only LOCATES an element already on
119
+ # the list — it has no path that creates one). So Handler's creation
120
+ # moved here, onto ProcessManager, mirroring `State` beside it: a
121
+ # bare, aggregate-level append.
122
+ command "Handler" do
123
+ role "Language"
124
+ goal "Open a handler inside a process manager"
125
+
126
+ attribute :event_type, HandlerText
127
+ # A LEG ALWAYS SAYS WHERE IT MOVES FROM. There is no wildcard leg to be
128
+ # optional for: `on "Event", transition: { from => to }` is the only
129
+ # spelling the runtime reads, and it refuses anything else —
130
+ # `single_transition` raises unless the hash holds exactly one from => to
131
+ # pair, so a leg without one
132
+ # is never built at all. `optional: true` here was
133
+ # the language admitting a leg the runtime cannot parse.
134
+ attribute :from_state, HandlerText
135
+ attribute :to_state, HandlerText
136
+
137
+ sets :handlers, append: { event_type: :event_type, from_state: :from_state, to_state: :to_state }
138
+
139
+ emits "LegDeclared"
140
+ end
141
+
142
+ # S17, ADR 0026 — ONE HANDLER, nested rather than its own root
143
+ # aggregate. No `saga` field. It named the old word for a process
144
+ # manager, held nothing — ProcessManagerHandler has no such reader,
145
+ # so every Handler record's saga was empty — and repeated the parent
146
+ # that its own containment already carries. A field that names the
147
+ # wrong thing, holds nothing, and duplicates the reference beside it.
148
+ #
149
+ # `event_type` is an event name, or one of the Trigger vocabulary's
150
+ # members when the leg answers something no aggregate announces — and
151
+ # is Handler's own real, non-positional identity now : a saga answers
152
+ # each event ONCE, so the event names the leg, and the process
153
+ # manager it belongs to is structural (which list this element sits
154
+ # in), not a stored field any more.
155
+ entity "Handler" do
156
+ description "One handler inside a process manager — the event it answers, the state move it makes, and the commands it sends. Nested under the process manager because a handler holds nested dispatches, which hold nested bindings."
157
+
158
+ identified_by HandlerText, as: :event_type
159
+
160
+ attribute :from_state, HandlerText
161
+ attribute :to_state, HandlerText
162
+ # S17, ADR 0026 — Dispatch nested here too (see `entity "Dispatch"`,
163
+ # below), one level further in than Handler itself.
164
+ attribute :dispatches, list_of(Dispatch)
165
+
166
+ # THE DISPATCH'S OWN CREATION — same reason Handler's own creation
167
+ # lives on ProcessManager, one level up: an entity is never created
168
+ # through its own dotted verb. Reached as a DOTTED verb itself
169
+ # (`ProcessManager.Handler.Dispatch`) since Handler, the owner
170
+ # doing the creating here, is an entity too, not a real aggregate
171
+ # with a bare verb of its own to dispatch into.
172
+ command "Dispatch" do
173
+ role "Language"
174
+ goal "Open a dispatch inside a handler"
175
+
176
+ attribute :command_name, DispatchText
177
+
178
+ sets :dispatches, append: { command_name: :command_name }
179
+
180
+ emits "SendDeclared"
181
+ end
182
+
183
+ # S17, ADR 0026 — ONE COMMAND A HANDLER DISPATCHES, nested two
184
+ # levels in rather than its own root aggregate — "no life outside
185
+ # its Handler" (the ADR's own words). The bindings are an open
186
+ # map, which no value object can hold — that was always a reason
187
+ # it could not be one, never a reason it could not be an entity.
188
+ # `command_name` is Dispatch's own real, non-positional identity,
189
+ # the same shape Handler's own `event_type` just took one level up.
190
+ entity "Dispatch" do
191
+ description "One command a handler dispatches, with the arguments it binds. Nested under the handler because the bindings are an open map, which no value object can hold."
192
+
193
+ identified_by DispatchText, as: :command_name
194
+
195
+ attribute :with_spec, list_of(Binding)
196
+
197
+ command "Bind" do
198
+ role "Language"
199
+ goal "Bind one argument of the dispatched command"
200
+
201
+ attribute :key, DispatchText
202
+ attribute :value, DispatchText
203
+
204
+ sets :with_spec, append: { key: :key, value: :value }
205
+
206
+ emits "BindingAttached"
207
+ end
208
+ end
209
+ end
210
+
211
+ # HOW PROCESSMANAGER IS SPELLED. These rows live with the concept
212
+ # they describe; SyntaxBoot discovers every aggregate-local seed table.
213
+ # Contexts represented here: ProcessManager, Handler.
214
+ value_object "KeywordSeed" do
215
+ attribute :word, String
216
+ attribute :context, String, admits: "Syntax::Context"
217
+ attribute :body, String, admits: "Syntax::Body"
218
+ attribute :inner, String
219
+ attribute :opens, String
220
+ attribute :fills, String
221
+ attribute :status, String, default: "admitted", admits: "Syntax::Status"
222
+ attribute :was, String
223
+ attribute :resolves_via, String, default: "", admits: "Syntax::ResolutionScope"
224
+ attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
225
+
226
+ member word: "correlates_by", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "correlates_by"
227
+ member word: "starts_on", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "starts_on"
228
+ member word: "ends_on", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "ends_on"
229
+ member word: "transition", context: "ProcessManager", body: "keywords", inner: "Handler", opens: "Handler", fills: "", calls: "transition_impl"
230
+ member word: "transition", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "", calls: "transition_impl"
231
+ member word: "dispatch", context: "Handler", body: "none", inner: "", opens: "Dispatch", fills: "", calls: "dispatch_impl"
232
+
233
+ end
234
+
235
+ value_object "ArgumentSeed" do
236
+ attribute :keyword, String
237
+ attribute :context, String, admits: "Syntax::Context"
238
+ attribute :at, String
239
+ attribute :named, String
240
+ attribute :kind, String, admits: "Syntax::ArgumentKind"
241
+ attribute :required, String
242
+ attribute :fills, String
243
+ attribute :selects, String
244
+ attribute :pair_key_fills, String
245
+ attribute :pair_value_fills, String
246
+ attribute :pairs_shape, String, admits: "Syntax::PairsShape"
247
+ attribute :status, String, default: "admitted", admits: "Syntax::Status"
248
+ attribute :variadic, String
249
+ attribute :coerce, String
250
+ attribute :blank_message, String
251
+
252
+ member keyword: "correlates_by", context: "ProcessManager", at: "1", named: "", kind: "symbol", required: "true", fills: "correlates_by"
253
+ member keyword: "starts_on", context: "ProcessManager", at: "1", named: "", kind: "text", required: "true", fills: "starts_on"
254
+ member keyword: "ends_on", context: "ProcessManager", at: "1", named: "", kind: "text", required: "true", fills: "ends_on"
255
+ member keyword: "transition", context: "ProcessManager", at: "1", named: "", kind: "pairs", required: "true", fills: "", pair_key_fills: "event_type", pair_value_fills: "to_state", pairs_shape: "fields"
256
+ member keyword: "transition", context: "ProcessManager", at: "", named: "from", kind: "text", required: "true", fills: "from_state"
257
+ member keyword: "transition", context: "ProcessManager", at: "", named: "from", kind: "list", required: "false", fills: "from_state"
258
+ member keyword: "dispatch", context: "Handler", at: "1", named: "", kind: "constant", required: "true", fills: "command_name"
259
+ member keyword: "dispatch", context: "Handler", at: "1", named: "", kind: "text", required: "true", fills: "command_name"
260
+ member keyword: "dispatch", context: "Handler", at: "", named: "with", kind: "pairs", required: "false", fills: "with_spec", pairs_shape: "verbatim"
261
+
262
+ end
263
+ end
264
+ end
@@ -0,0 +1,267 @@
1
+ Hecks.bluebook "Bluebook" do
2
+ aggregate "ReadModel" do
3
+ description "One read model — the aggregate heads it gathers and the reference it hangs from."
4
+
5
+ reference_to Bluebook
6
+
7
+ # THE CHAPTER IT IS IN, AND ITS NAME.
8
+ identified_by :bluebook, :name
9
+
10
+ attribute :name, ReadModelName
11
+ attribute :description, ProjectionPurpose
12
+ attribute :query_name, ReadModelText
13
+ attribute :reference_name, ReadModelText
14
+ attribute :reference_target, ReadModelText
15
+ attribute :aggregate_heads, list_of(Head)
16
+ # The same open map a query carries — see Query's AskOption. A read model
17
+ # inherits every specification option an ask has, so it holds them the same way.
18
+ attribute :options, list_of(ProjectionOption)
19
+ # WHICH of the eligible head's own fields to nest its rows under, in
20
+ # declared order. Rows, not a single value object with N fields — an
21
+ # arbitrary NUMBER of fields, the same reason `aggregate_heads`/
22
+ # `options` are lists rather than fixed attributes.
23
+ attribute :group_by, list_of(GroupByField)
24
+ # `count`/`median_field` are the OTHER two reductions a read model
25
+ # may declare over its one eligible head, siblings of `group_by`
26
+ # rather than of `options` — same permissive `ReadModelText` shape,
27
+ # and the same UNmarked-optional spelling `reference_name`/
28
+ # `reference_target` already use just above (permissiveness lives
29
+ # in `ReadModelText`'s own lack of an invariant, not in an
30
+ # `optional:` flag this chapter's aggregate-level attributes never
31
+ # carry) — "true"/"" for `count`, a field name or "" for
32
+ # `median_field`, both legitimately absent on a read model that
33
+ # declares neither.
34
+ attribute :count, ReadModelText, optional: true
35
+ attribute :median_field, ReadModelText, optional: true
36
+
37
+ value_object "ReadModelName" do
38
+ attribute :value, String
39
+ invariant("a read model is named") { !value.to_s.empty? }
40
+ end
41
+
42
+ value_object "ReadModelText" do
43
+ # deliberately permissive : query_name / ref_name / ref_target are
44
+ # legitimately empty on a read model that has not named them yet
45
+ attribute :value, String
46
+ end
47
+
48
+ value_object "ProjectionPurpose" do
49
+ attribute :value, String
50
+ invariant("a description says something") { !value.to_s.empty? }
51
+ end
52
+
53
+ value_object "Head" do
54
+ attribute :aggregate, String
55
+ attribute :as, String
56
+ attribute :many, String
57
+ end
58
+
59
+ value_object "ProjectionOption" do
60
+ attribute :option, String
61
+ attribute :key, String
62
+ attribute :value, String
63
+ attribute :at, String
64
+ end
65
+
66
+ value_object "GroupByField" do
67
+ attribute :field, String
68
+ invariant("a group_by field is named") { !field.to_s.empty? }
69
+ end
70
+
71
+ # The way back: everything DECLARED IN the chapter above. The parent
72
+ # reference IS the query.
73
+ # WHERE IT SITS AMONG ITS SIBLINGS. Declaration order is a FACT ABOUT THE
74
+ # SOURCE — the IR is a contract read straight from this file,
75
+ # field for field AND INDEX FOR INDEX. So the language HOLDS it, instead of
76
+ # inheriting it from whatever order a store happens to iterate: an ask that
77
+ # does not say how it is ordered is answered in identity order, which is
78
+ # right for every other ask and fatal for the one that is the SOURCE.
79
+ value_object "Position" do
80
+ attribute :value, Integer
81
+ end
82
+
83
+ attribute :position, Position
84
+
85
+ query "DeclaredIn" do
86
+ attribute :bluebook, ReadModelText
87
+ where(bluebook: :bluebook)
88
+ order_by :position
89
+ end
90
+ command "Declare" do
91
+ role "Language"
92
+ goal "Open a read model on a chapter"
93
+
94
+ reference_to Bluebook
95
+ attribute :name, ReadModelName
96
+ attribute :description, ProjectionPurpose, optional: true
97
+ attribute :query_name, ReadModelText
98
+ # Both optional now — a ROOTLESS read model (no `reference_to`
99
+ # declared at all) has neither. Permanently empty, not "not yet
100
+ # set" — see Gather's own comment below for why that distinction
101
+ # matters.
102
+ attribute :reference_name, ReadModelText, optional: true
103
+ attribute :reference_target, ReadModelText, optional: true
104
+
105
+ attribute :position, Position, optional: true
106
+ sets :bluebook
107
+ sets :name
108
+ sets :description
109
+ sets :query_name
110
+ sets :reference_name
111
+ sets :reference_target
112
+ sets :position
113
+ emits "ProjectionDeclared"
114
+ end
115
+
116
+ command "Gather" do
117
+ role "Language"
118
+ goal "Attach one aggregate head to the read model"
119
+
120
+ # A HEAD IS THE AGGREGATE IT NAMES. There is no head with nothing gathered:
121
+ # `add_aggregate_head` is only ever reached from an `include Target`,
122
+ # so the builder cannot produce one
123
+ # without it — the field is a plain
124
+ # required, non-empty name. `as` and
125
+ # `many` are both DERIVED from it when the author does not spell them, which
126
+ # is the clearest statement that it is the part that cannot be missing.
127
+ attribute :aggregate, ReadModelText
128
+ attribute :as, ReadModelText
129
+ attribute :many, ReadModelText
130
+
131
+ # NOT "reference_target must already be set" anymore — reference_target
132
+ # is fixed forever at Declare time (nothing ever changes it later), so
133
+ # that rule was really "this read model must have SOME reference, ever"
134
+ # — exactly the constraint a ROOTLESS read model (bulk, no root,
135
+ # `group_by`'s own real use) deliberately doesn't meet, permanently,
136
+ # on purpose, not by omission. Removed rather than relaxed: there is
137
+ # no runtime fact left here that distinguishes "forgot to declare a
138
+ # reference" from "declared rootless on purpose" — both look
139
+ # identical (`reference_target` empty) by the time Gather is judged.
140
+
141
+ sets :aggregate_heads, append: { aggregate: :aggregate, as: :as, many: :many }
142
+
143
+ emits "HeadGathered"
144
+ end
145
+
146
+ command "GroupBy" do
147
+ role "Language"
148
+ goal "Nest one collection's own rows by one of its own fields"
149
+
150
+ attribute :field, ReadModelText
151
+
152
+ given("a group_by field is named") { !field.value.to_s.empty? }
153
+
154
+ sets :group_by, append: { field: :field }
155
+
156
+ emits "GroupByFieldAdded"
157
+ end
158
+
159
+ # `count`/`median` are LATE-SET scalars, the same shape `Lifecycle`'s
160
+ # own `state_field`/`state_start` already are on `Aggregate`
161
+ # (aggregate.bluebook) — a command carrying its own value and a bare
162
+ # `sets field, to: field` copying it onto the record, rather
163
+ # than an `append:` (they are not lists, and there is only ever one
164
+ # of each). `count`/`median_field` are declared here, not folded
165
+ # into `Declare`, for the same reason `GroupBy` is its own command
166
+ # above: neither is known until the DSL body runs past `include`.
167
+ command "Count" do
168
+ role "Language"
169
+ goal "Mark the read model as a bare row count over its one eligible collection"
170
+
171
+
172
+ sets :count
173
+
174
+ emits "CountDeclared"
175
+ end
176
+
177
+ command "Median" do
178
+ role "Language"
179
+ goal "Mark the read model as the median of one numeric field across its one eligible collection"
180
+
181
+
182
+ given("a median field is named") { !median_field.value.to_s.empty? }
183
+
184
+ sets :median_field
185
+
186
+ emits "MedianFieldSet"
187
+ end
188
+
189
+ command "Option" do
190
+ role "Language"
191
+ goal "Attach one part of one specification option to the read model"
192
+
193
+ attribute :option, ReadModelText
194
+ attribute :key, ReadModelText
195
+ # Same reading as Query.Option above — an option key may stand alone.
196
+ attribute :value, ReadModelText, optional: true
197
+ attribute :at, ReadModelText, optional: true
198
+
199
+ given("an option is named") { !option.value.to_s.empty? }
200
+
201
+ sets :options, append: { option: :option, key: :key, value: :value, at: :at }
202
+
203
+ emits "OptionAttached"
204
+ end
205
+
206
+ # HOW READMODEL IS SPELLED. These rows live with the concept
207
+ # they describe; SyntaxBoot discovers every aggregate-local seed table.
208
+ # Contexts represented here: ReadModel.
209
+ value_object "KeywordSeed" do
210
+ attribute :word, String
211
+ attribute :context, String, admits: "Syntax::Context"
212
+ attribute :body, String, admits: "Syntax::Body"
213
+ attribute :inner, String
214
+ attribute :opens, String
215
+ attribute :fills, String
216
+ attribute :status, String, default: "admitted", admits: "Syntax::Status"
217
+ attribute :was, String
218
+ attribute :resolves_via, String, default: "", admits: "Syntax::ResolutionScope"
219
+ attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
220
+
221
+ member word: "description", context: "ReadModel", body: "none", inner: "", opens: "", fills: "description"
222
+ member word: "reference_to", context: "ReadModel", body: "none", inner: "", opens: "", fills: "reference_target", calls: "reference_to_impl"
223
+ member word: "include", context: "ReadModel", body: "none", inner: "", opens: "", fills: "aggregate_heads", calls: "include_impl"
224
+ member word: "group_by", context: "ReadModel", body: "none", inner: "", opens: "", fills: "group_by", calls: "group_by_impl"
225
+ member word: "count", context: "ReadModel", body: "none", inner: "", opens: "", fills: "count"
226
+ member word: "median", context: "ReadModel", body: "none", inner: "", opens: "", fills: "median_field"
227
+ member word: "where", context: "ReadModel", body: "none", inner: "", opens: "", fills: "options", calls: "where_impl"
228
+ member word: "order_by", context: "ReadModel", body: "none", inner: "", opens: "", fills: "options", calls: "order_by_impl"
229
+ member word: "authorize", context: "ReadModel", body: "none", inner: "", opens: "", fills: "options", calls: "authorize_impl"
230
+ member word: "inspect_query", context: "ReadModel", body: "none", inner: "", opens: "", fills: "options"
231
+
232
+ end
233
+
234
+ value_object "ArgumentSeed" do
235
+ attribute :keyword, String
236
+ attribute :context, String, admits: "Syntax::Context"
237
+ attribute :at, String
238
+ attribute :named, String
239
+ attribute :kind, String, admits: "Syntax::ArgumentKind"
240
+ attribute :required, String
241
+ attribute :fills, String
242
+ attribute :selects, String
243
+ attribute :pair_key_fills, String
244
+ attribute :pair_value_fills, String
245
+ attribute :pairs_shape, String, admits: "Syntax::PairsShape"
246
+ attribute :status, String, default: "admitted", admits: "Syntax::Status"
247
+ attribute :variadic, String
248
+ attribute :coerce, String
249
+ attribute :blank_message, String
250
+
251
+ member keyword: "description", context: "ReadModel", at: "1", named: "", kind: "text", required: "true", fills: "description", coerce: "false"
252
+ member keyword: "reference_to", context: "ReadModel", at: "1", named: "", kind: "constant", required: "true", fills: "reference_target"
253
+ member keyword: "reference_to", context: "ReadModel", at: "", named: "as", kind: "symbol", required: "false", fills: "reference_name"
254
+ member keyword: "include", context: "ReadModel", at: "1", named: "", kind: "constant", required: "true", fills: "aggregate"
255
+ member keyword: "include", context: "ReadModel", at: "", named: "as", kind: "symbol", required: "false", fills: "as"
256
+ member keyword: "group_by", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "group_by", variadic: "true"
257
+ member keyword: "median", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "median_field"
258
+ member keyword: "where", context: "ReadModel", at: "1", named: "", kind: "pairs", required: "true", fills: ""
259
+ member keyword: "order_by", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "field"
260
+ member keyword: "order_by", context: "ReadModel", at: "2", named: "", kind: "symbol", required: "false", fills: "direction"
261
+ member keyword: "authorize", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "policy"
262
+ member keyword: "authorize", context: "ReadModel", at: "", named: "tenant", kind: "symbol", required: "false", fills: "tenant"
263
+ member keyword: "inspect_query", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "false", fills: "mode"
264
+
265
+ end
266
+ end
267
+ end