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,447 @@
1
+ Hecks.bluebook "Bluebook" do
2
+ aggregate "Syntax" do
3
+ # HOW A BLUEBOOK IS SPELLED — the layer the language did not have.
4
+ #
5
+ # Every other file in this directory declares SHAPE. `Aggregate` has an
6
+ # `identified_by` that is a `list_of(IdentityPath)` ; `Field` has a name, a
7
+ # type and a cardinality. Nothing anywhere said that the field is SPELLED
8
+ # `identified_by`, that a block opens with `do`, or that a symbol argument
9
+ # starts with `:`. Grep this directory for keyword, token or syntax before
10
+ # this file existed and the only hit was a comment.
11
+ #
12
+ # That gap is why the parser could not be projected, and it is also where the
13
+ # bugs were. When `identified_by` became `list_of(IdentityPath)` the projected
14
+ # struct regenerated to a list of strings with nobody touching it, and was
15
+ # correct. The HAND-WRITTEN halves broke : a hand-written parser could not read
16
+ # `identified_by do` at all and swallowed whole aggregate bodies in silence,
17
+ # and a dispatcher that read the field as a scalar got nothing on an array
18
+ # and fell through to a minted `"id"`. The declared half survived. The
19
+ # undeclared halves did not.
20
+ #
21
+ # DECLARATIONS, NOT RUNTIME STATE — the same reading as Vocabulary beside it,
22
+ # and no commands for the same reason. A domain does not declare its own
23
+ # syntax ; the syntax is fixed when the language is defined. Nothing
24
+ # dispatches this, `Plan` skips it by construction (a category with nothing
25
+ # to offer contributes nothing), and `spec/syntax_conformance_spec` READS it
26
+ # from the IR and holds each builder to it in both directions.
27
+ #
28
+ # WHY THE KEYWORD BELONGS TO THE CATEGORY AND NOT TO A RECORD. The word
29
+ # `aggregate` is a fact about the Aggregate CATEGORY, not about
30
+ # `Pizzas::Pizza` — and the meta-domain's records are instances. So there is
31
+ # nothing for a dispatched syntax to hang off, and this is a closed set.
32
+ #
33
+ # WHAT IS NOT HERE. Only the `.bluebook` surface. `.port`, `.adapter`,
34
+ # `.hecksagon`, `.world` and `translations/*.bluebook` are SIBLING artifacts
35
+ # with their own builders and their own files ; a parser projected from this
36
+ # reads bluebooks, and half-covering the siblings would say less than naming
37
+ # the exclusion does.
38
+ #
39
+ # THIS IS ALSO WHY THE GENERIC-BLUEBOOK-READER ARC STOPS HERE.
40
+ # A generic reader driven by THIS table
41
+ # covers every keyword whose argument-binding this table can
42
+ # express (M1-M7), down to `member`'s and `sets`' pairs, which turned out
43
+ # to need a schema correction rather than new machinery. What stays
44
+ # outside the table either isn't ONE shape a bigger table
45
+ # would close (`attribute`, three separate irregularities) or isn't
46
+ # covered by this table AT ALL : `.hecksagon`/`.world`'s open adapter-verb
47
+ # vocabulary is the one truly PERMANENT exclusion, for the same reason
48
+ # named above — a verb's schema is not even contained in the file being
49
+ # parsed, registered instead by host application code
50
+ # (`Hecks.port("post") { verb "posted_by" }`), so no table this file
51
+ # could hold would ever be enough.
52
+ description "How a bluebook is SPELLED — every word the surface admits, the body it may open, and the field it fills. The layer every other file in this directory does not have."
53
+
54
+ belongs_to Bluebook
55
+
56
+ # ITS NAME, and nothing else — a syntax hangs under no other thing, exactly
57
+ # as a vocabulary does.
58
+ identified_by SyntaxName, as: :name
59
+
60
+ # S14, ADR 0026 — Keyword/Argument nested here (see `entity
61
+ # "Keyword"`/`entity "Argument"`, below), entities rather than
62
+ # closed-set value-object members. `list_of(...)` forward-references
63
+ # them the same way banking's own `attribute :ledger,
64
+ # list_of(LedgerEntry)` names LedgerEntry before it is declared.
65
+ attribute :keywords, list_of(Keyword)
66
+ attribute :arguments, list_of(Argument)
67
+
68
+ value_object "SyntaxName" do
69
+ attribute :value, String
70
+ invariant("a syntax is named") { !value.to_s.empty? }
71
+ end
72
+
73
+ # WHERE A WORD MAY BE TYPED. Mostly a category, but not always : `OneOf`,
74
+ # `Lifecycle` and `Type` are bodies with no category of their own, and `File`
75
+ # is the outside of every body. A context is not the same question as a
76
+ # category, which is why this is its own set rather than a list of the
77
+ # thirteen.
78
+ #
79
+ # `Lifecycle` is a DECLARED FOLD — contracts.rb folds state_field,
80
+ # state_start and transitions onto whichever of Aggregate or Entity opened
81
+ # it — so a word typed there fills a field of the ENCLOSING category, not of
82
+ # a Lifecycle that does not exist.
83
+ #
84
+ # `Type` is the second argument of `attribute`, which is a place words are
85
+ # spelled (`list_of`, `one_of`) and so is a context like any other.
86
+ value_object "Context" do
87
+ attribute :name, String,
88
+ one_of: ["File", "Bluebook", "Aggregate", "Entity", "Command", "Query", "ValueObject", "OneOf",
89
+ "Lifecycle", "Policy", "ProcessManager", "Handler", "ReadModel", "Type", "Hecksagon",
90
+ "World", "DomainPort", "PortOperation", "Port", "Adapter", "Translation",
91
+ "TranslationAggregate"]
92
+ end
93
+
94
+ # WHAT A WORD'S BLOCK IS, and the three answers are genuinely different
95
+ # things to a parser :
96
+ #
97
+ # keywords a nested body of more words — `aggregate "X" do … end`
98
+ # source a block that is NEVER CALLED. Its text is the declaration —
99
+ # `given("…") { balance >= amount }`, `identified_by :name`.
100
+ # Recovered through Ports::Extraction, which is why `number.value`
101
+ # needs no method called `number` to exist.
102
+ # rows a body of `member` rows and nothing else — `one_of do … end`
103
+ # none no block at all
104
+ #
105
+ # A `source` body IS the thing the word declares : `given`'s body is the
106
+ # rule's canonical text, `identified_by`'s body is the identity paths. A
107
+ # `keywords` or `rows` body fills the record the word opens.
108
+ value_object "Body" do
109
+ attribute :name, String, one_of: ["none", "keywords", "source", "rows"]
110
+ end
111
+
112
+ # WHERE A WORD STANDS IN ITS OWN LIFE. The same shape the expression
113
+ # grammar's Operator carries (proposed → admitted → retired), plus
114
+ # `deprecated` — a word still read but on its way out, which an operator
115
+ # never needed because nothing outside this repo writes expressions yet.
116
+ # A row DEFAULTS to admitted, so the table below stays a table of words
117
+ # rather than a table of words-with-ceremony; only a word entering or
118
+ # leaving the language spells its status. The projections read this:
119
+ # a proposed or retired word reaches no generated parser table, so to
120
+ # every projected reader it simply does not exist — the operator rule,
121
+ # at the syntax layer.
122
+ value_object "Status" do
123
+ attribute :name, String, one_of: ["proposed", "admitted", "deprecated", "retired"]
124
+ end
125
+
126
+ # WHICH OF THE THREE SHARED RESOLUTION PRIMITIVES (Hecks::
127
+ # Bluebook::DSL::RuleReference — a "declared once, referenced by
128
+ # name" family word's own bare form resolves through, once it has
129
+ # one: `hash_chain` (an ordered chain of flat pools, first match
130
+ # wins — `given` on Command), `owner_keyed` (one pool keyed by
131
+ # declaring owner, needing `disambiguator` below to pick among more
132
+ # than one candidate — `given` on Aggregate), `sibling_scan` (a
133
+ # live scan over already-built sibling objects, no separate pool at
134
+ # all — `invariant` on ValueObject). BLANK for every OTHER word —
135
+ # most of the language declares once and is never referenced back,
136
+ # so `Keyword#resolves_via` stays optional rather than forcing every
137
+ # existing row to spell "none."
138
+ value_object "ResolutionScope" do
139
+ attribute :name, String, one_of: ["hash_chain", "owner_keyed", "sibling_scan"]
140
+ end
141
+
142
+ # WHICH DISAMBIGUATOR KEYWORD a bare reference may supply when its
143
+ # own `resolves_via` is `owner_keyed` and more than one candidate is
144
+ # registered — `declared_by:` is the only one that exists today
145
+ # (`AggregateBuilder#given`'s own chapter-wide sharing,
146
+ # docs/implemented/resolution-rules/chapter-given.md). A closed set of one,
147
+ # deliberately, not a boolean flag — the SAME reason `Body`/`Status`
148
+ # above are closed sets rather than booleans even where today's
149
+ # count is small: a second disambiguator kind, if this family ever
150
+ # grows one, is a new MEMBER of this set, not a second attribute.
151
+ value_object "Disambiguator" do
152
+ attribute :name, String, one_of: ["declared_by"]
153
+ end
154
+
155
+ # WHAT AN ARGUMENT LOOKS LIKE WHEN IT IS TYPED. Lexical, not semantic — two
156
+ # arguments of the same kind are read the same way and mean whatever the
157
+ # field they fill means.
158
+ #
159
+ # `literal` is the widest : a default is written so its TYPE survives — `0`
160
+ # rather than `"0"`, `0.0` rather than `"0.0"` — which is what LiteralText is
161
+ # about, and why it is not `text`.
162
+ value_object "ArgumentKind" do
163
+ attribute :name, String,
164
+ one_of: ["text", "symbol", "number", "flag", "literal", "constant", "pairs", "list"]
165
+ end
166
+
167
+ # WHAT A `pairs` ARGUMENT'S OWN PAIR(S) DO. Found by tracing every real
168
+ # `pairs` reader (parse_where_line, parse_pm_handler, parse_lifecycle,
169
+ # parse_with_hash, `one_of`'s member builder, `sets`' append: builder) —
170
+ # four genuinely different shapes were hiding under one `kind`:
171
+ #
172
+ # fields ONE pair, contributing two NAMED SUB-FIELDS to the single
173
+ # compound this keyword invocation is already building — the
174
+ # same role a positional argument plays, just sourced from a
175
+ # pair instead of a bare token. `on`'s `transition:` sets
176
+ # `from_state`/`to_state` on the ProcessManagerHandler its
177
+ # OWN `event_type` argument is also filling ; Lifecycle's
178
+ # `transition` sets `command`/`to_state` on the Transition
179
+ # its own `from:` argument also fills.
180
+ # elements EACH pair independently becomes a NEW compound, appended to
181
+ # the keyword's own list field (`where`'s own `fills:
182
+ # "wheres"`, declared at the Keyword level, same as
183
+ # `attribute`'s). `where(balance: {gte: 100}, status: "open")`
184
+ # is two WhereClauses from one line, not one.
185
+ # verbatim each pair is captured as-is, key and value both left as
186
+ # text — `dispatch`'s `with:` : resolution (`:name` reference
187
+ # vs literal) happens at DISPATCH time, not parse time, so
188
+ # there is nothing to interpret here at all.
189
+ # sibling the pair's KEY names a field of an ALREADY-DECLARED sibling
190
+ # construct — `member`'s keys are the enclosing value
191
+ # object's own attributes ; `sets`' `append:` keys are the
192
+ # target entity/value-object's own attributes. Not a static
193
+ # fact this table can enumerate (the valid keys differ per
194
+ # domain) — named here so a reader knows to resolve
195
+ # dynamically rather than assume an omission.
196
+ value_object "PairsShape" do
197
+ attribute :name, String, one_of: ["fields", "elements", "verbatim", "sibling"]
198
+ end
199
+
200
+ # THE SPELLINGS LIVE WITH THEIR DOMAIN CONCEPTS. Each aggregate declares
201
+ # its own KeywordSeed and ArgumentSeed value objects beside the behavior
202
+ # those rows describe. SyntaxBoot discovers and combines those local tables
203
+ # automatically; this aggregate owns only the live Keyword/Argument records
204
+ # and the genuinely shared lexical vocabulary below.
205
+
206
+
207
+ # S14, ADR 0026 — "`Status` becomes a real `lifecycle` with declared
208
+ # transitions, so the ordering is enforced by declaration and the
209
+ # model checker can finally see it" (the ADR's own words). A value
210
+ # object has no identity, so it cannot transition — it can only be
211
+ # replaced wholesale (this file's own prior header, before this
212
+ # slice) — so Keyword and Argument become genuine ENTITIES of
213
+ # Syntax, each carrying a real `lifecycle :status`.
214
+ #
215
+ # THE REAL RECORD, not the source. The aggregate-local `KeywordSeed` rows
216
+ # are what get WRITTEN — hand-typed grammar data, still the
217
+ # natural way to spell ~106 static facts. `Keyword` is what gets
218
+ # READ : `SyntaxBoot` (meta_validator/syntax_boot.rb) dispatches one
219
+ # `Syntax.Keyword` per seed row, once, at boot, into a REAL "Bluebook"
220
+ # domain runtime — the same distinction `Reconstruction`/`Judge`
221
+ # already draw everywhere else between what a chapter DECLARES and
222
+ # what gets DISPATCHED from it, just run once more, for the
223
+ # language's own grammar table this time.
224
+ #
225
+ # `identified_by :position` — POSITIONAL, the same reason Member's
226
+ # own is (S17): a keyword row has no other field guaranteed unique on
227
+ # its own (the same word is legitimately admitted in more than one
228
+ # context), and declaration order is a fact about the SOURCE the
229
+ # language already holds deliberately elsewhere.
230
+ value_object "KeywordPosition" do
231
+ attribute :value, Integer
232
+ end
233
+
234
+ entity "Keyword" do
235
+ description "One word the bluebook surface admits — the body it may open, and the field it fills. Nested under Syntax because it is now the LANGUAGE'S OWN data, not merely its declaration : a word's own status is a real fact that moves, not a string replaced wholesale."
236
+
237
+ identified_by KeywordPosition, as: :position
238
+
239
+ attribute :word, KeywordSeedText
240
+ attribute :context, KeywordSeedText, admits: "Syntax::Context"
241
+ attribute :body, KeywordSeedText, admits: "Syntax::Body"
242
+ attribute :inner, KeywordSeedText
243
+ attribute :opens, KeywordSeedText
244
+ attribute :fills, KeywordSeedText
245
+ attribute :was, KeywordSeedText, optional: true
246
+ # WHICH SHARED PRIMITIVE (Hecks::Bluebook::DSL::
247
+ # RuleReference) this word's own bare form resolves through, once
248
+ # it has one — see `ResolutionScope`'s own comment, above, for the
249
+ # three real values and which existing word declares each.
250
+ # BLANK for every other word.
251
+ attribute :resolves_via, KeywordSeedText, admits: "Syntax::ResolutionScope", optional: true
252
+ # WHICH DISAMBIGUATOR keyword argument a bare reference may supply
253
+ # when `resolves_via` is `owner_keyed` — see `Disambiguator`'s own
254
+ # comment. BLANK unless `resolves_via` is `owner_keyed` AND more
255
+ # than one candidate can register (today: only `given` on
256
+ # Aggregate).
257
+ attribute :disambiguator, KeywordSeedText, admits: "Syntax::Disambiguator", optional: true
258
+ # THE ESCAPE HATCH — item #13's full metaprogrammed dispatch (slice
259
+ # 3, whole-project table-unification survey). BLANK for every word
260
+ # `GenericDispatch` fills/opens/zero-args directly off `fills:`/
261
+ # `opens:`. NON-EMPTY names a real Ruby method this word's whole
262
+ # call (args, kwargs, block, untouched) forwards to instead — for
263
+ # words whose own logic is genuinely too complex to re-derive from
264
+ # argument shape alone (`attribute`'s own type-quoting/closed-set-
265
+ # synthesis/pattern validation). The method itself stays exactly
266
+ # what it always was, hand-written, unchanged — this column only
267
+ # says WHICH one answers the word, the same way `resolves_via`
268
+ # already names which shared primitive a bare reference resolves
269
+ # through, one level up. Read DURING bootstrap too (`WordGate`'s
270
+ # own `BOOTSTRAP_CALLS_FALLBACK`, a small explicit table naming
271
+ # the SAME (context, word) -> method pairs this column would say,
272
+ # since the real table doesn't exist yet at that point) — the one
273
+ # place in this whole arc a bootstrap fallback was worth building,
274
+ # because it duplicates NO logic, only a method NAME.
275
+ attribute :calls, KeywordSeedText, optional: true
276
+
277
+ lifecycle :status, default: "admitted" do
278
+ # NOT `proposed` : nothing in the real table is ever declared
279
+ # proposed today, and the lifecycle's own default has to stay
280
+ # "admitted" to match every existing row's own implicit status —
281
+ # changing it would make every one of the ~106 rows silently
282
+ # start "proposed" instead. Declaring `proposed` as a state
283
+ # reachable from nowhere would be exactly the kind of decorative,
284
+ # unused declaration this whole ADR series exists to catch — so
285
+ # it is left out, honestly, rather than declared and unreachable.
286
+ transition "Deprecate" => "deprecated", from: "admitted"
287
+ transition "Retire" => "retired", from: ["admitted", "deprecated"]
288
+ end
289
+
290
+ command "Deprecate" do
291
+ role "Language"
292
+ goal "Mark a word as on its way out, still read"
293
+
294
+ emits "KeywordDeprecated"
295
+ end
296
+
297
+ command "Retire" do
298
+ role "Language"
299
+ goal "Remove a word from every generated parser table"
300
+
301
+ emits "KeywordRetired"
302
+ end
303
+ end
304
+
305
+ # S14, ADR 0026 — same reason Keyword's own is, one construct over.
306
+ # `identified_by :position` — positional, the SAME field name as
307
+ # Keyword's own on purpose: an Argument row's identity is never
308
+ # compared against a Keyword row's, so the shared name costs nothing
309
+ # and names the same fact both times.
310
+ value_object "ArgumentPosition" do
311
+ attribute :value, Integer
312
+ end
313
+
314
+ entity "Argument" do
315
+ description "One argument a keyword takes, typed. Nested under Syntax (a SIBLING of Keyword, not nested inside it — `keyword`/`context` name which Keyword row it belongs to, carried as ordinary fields rather than through containment, because the language reads Argument rows independently of any one Keyword element)."
316
+
317
+ identified_by ArgumentPosition, as: :position
318
+
319
+ attribute :keyword, ArgumentSeedText
320
+ attribute :context, ArgumentSeedText, admits: "Syntax::Context"
321
+ attribute :at, ArgumentSeedText, optional: true
322
+ attribute :named, ArgumentSeedText, optional: true
323
+ attribute :kind, ArgumentSeedText, admits: "Syntax::ArgumentKind"
324
+ attribute :required, ArgumentSeedText
325
+ attribute :fills, ArgumentSeedText
326
+ attribute :selects, ArgumentSeedText, optional: true
327
+ attribute :pair_key_fills, ArgumentSeedText, optional: true
328
+ attribute :pair_value_fills, ArgumentSeedText, optional: true
329
+ attribute :pairs_shape, ArgumentSeedText, optional: true
330
+ attribute :variadic, ArgumentSeedText, optional: true
331
+ # Minimum positional count for a variadic form. `identified_by` uses
332
+ # two so one symbol can retire without retiring compound keys.
333
+ attribute :minimum, ArgumentSeedText, optional: true
334
+ # ABSENT means "apply the uniform, kind-driven coercion" (text ->
335
+ # .to_s, symbol -> .to_sym) — item #13's full metaprogrammed
336
+ # dispatch (slice 1, whole-project table-unification survey) reads
337
+ # this to decide whether a GENERATED fill method may coerce its own
338
+ # argument before storing it. `"false"` marks the six real
339
+ # exceptions a full builder-method audit found (read the real Ruby
340
+ # source, not inferred): `vision`/`description`(x4)/`goal` all
341
+ # store a `kind: "text"` argument RAW, with no `.to_s` at all —
342
+ # `.to_s` on an actual String is a same-object no-op for every real
343
+ # corpus use, but a direct Ruby API call passing something else
344
+ # (`vision(42)`) would see genuinely different stored behavior, so
345
+ # this couldn't be assumed uniform across every text-kind row the
346
+ # way it turned out to genuinely be for every OTHER text-kind
347
+ # argument in the whole grammar.
348
+ attribute :coerce, ArgumentSeedText, optional: true
349
+ # ABSENT means "an empty value is stored same as any other" — item
350
+ # #13's full metaprogrammed dispatch (slice 2, whole-project
351
+ # table-unification survey). NON-EMPTY names the exact Malformed
352
+ # message a real word's own hand-written method raised on a blank
353
+ # value BEFORE storing it (`Translation#retired`: "a retired needs
354
+ # an aggregate name"; `TranslationAggregate#drop`: "a drop needs a
355
+ # name") — `required: "true"` alone only gates Ruby's own ARITY
356
+ # (an argument omitted entirely), never a present-but-blank one,
357
+ # so this is a genuinely separate fact the table did not already
358
+ # carry. Most `required: "true"` rows do NOT raise on blank
359
+ # (confirmed by reading every one migrated in slice 1 —
360
+ # `Policy#on`/`ProcessManager#correlates_by`/etc. all accept and
361
+ # store an empty string same as any other), so this could not be
362
+ # assumed uniform from `required:` either. Carries the REAL text
363
+ # rather than a generated one — refusal wording is itself a
364
+ # checked contract in this codebase (item #2, whole-project
365
+ # table-unification survey, `RefusalWording::TEMPLATES`), not
366
+ # throwaway UX text a generic template could safely replace.
367
+ attribute :blank_message, ArgumentSeedText, optional: true
368
+
369
+ lifecycle :status, default: "admitted" do
370
+ transition "Deprecate" => "deprecated", from: "admitted"
371
+ transition "Retire" => "retired", from: ["admitted", "deprecated"]
372
+ end
373
+
374
+ command "Deprecate" do
375
+ role "Language"
376
+ goal "Mark an argument as on its way out, still read"
377
+
378
+ emits "ArgumentDeprecated"
379
+ end
380
+
381
+ command "Retire" do
382
+ role "Language"
383
+ goal "Remove an argument from every generated parser table"
384
+
385
+ emits "ArgumentRetired"
386
+ end
387
+ end
388
+
389
+ value_object "KeywordSeedText" do
390
+ attribute :value, String
391
+ end
392
+
393
+ value_object "ArgumentSeedText" do
394
+ attribute :value, String
395
+ end
396
+
397
+ # THE SYNTAX RECORD ITSELF. There is only ever one — the language
398
+ # describes its own single surface, not several — so unlike every
399
+ # other aggregate's own creating command, this carries no `position`:
400
+ # there are no siblings to order among.
401
+ command "Declare" do
402
+ role "Language"
403
+ goal "Open the language's own syntax table"
404
+
405
+ attribute :bluebook, BluebookName
406
+ attribute :name, SyntaxName
407
+
408
+ sets :bluebook
409
+ sets :name
410
+
411
+ emits "SyntaxDeclared"
412
+ end
413
+
414
+ # THE KEYWORD'S OWN CREATION. An entity is never created through its
415
+ # own dotted verb (S17's own finding, EntityInterpreter#element_of
416
+ # only LOCATES) — so, mirroring `ValueObject.Member`/`ProcessManager.
417
+ # Handler`, this is a bare, aggregate-level append. `position` is
418
+ # minted by `SyntaxBoot` as the seed row's own index — the same walk-
419
+ # index convention Member's own `position` already uses.
420
+ command "Keyword" do
421
+ role "Language"
422
+ goal "Admit one word the bluebook surface accepts"
423
+
424
+
425
+ sets :keywords, append: { position: :position, word: :word, context: :context, body: :body,
426
+ inner: :inner, opens: :opens, fills: :fills, was: :was,
427
+ resolves_via: :resolves_via, disambiguator: :disambiguator, calls: :calls }
428
+
429
+ emits "KeywordAdmitted"
430
+ end
431
+
432
+ command "Argument" do
433
+ role "Language"
434
+ goal "Admit one argument a keyword takes"
435
+
436
+
437
+ sets :arguments, append: { position: :position, keyword: :keyword, context: :context, at: :at,
438
+ named: :named, kind: :kind, required: :required, fills: :fills,
439
+ selects: :selects, pair_key_fills: :pair_key_fills,
440
+ pair_value_fills: :pair_value_fills, pairs_shape: :pairs_shape,
441
+ variadic: :variadic, minimum: :minimum,
442
+ coerce: :coerce, blank_message: :blank_message }
443
+
444
+ emits "ArgumentAdmitted"
445
+ end
446
+ end
447
+ end