hecks 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. checksums.yaml +5 -5
  2. data/lib/hecks/adapters/driven/claude_code.adapter +3 -0
  3. data/lib/hecks/adapters/driven/claude_code.rb +127 -0
  4. data/lib/hecks/adapters/driven/d1.adapter +12 -0
  5. data/lib/hecks/adapters/driven/d1.rb +427 -0
  6. data/lib/hecks/adapters/driven/folder.adapter +3 -0
  7. data/lib/hecks/adapters/driven/folder.rb +199 -0
  8. data/lib/hecks/adapters/driven/google_authentication.adapter +3 -0
  9. data/lib/hecks/adapters/driven/google_authentication.rb +100 -0
  10. data/lib/hecks/adapters/driven/governance_authorization.adapter +3 -0
  11. data/lib/hecks/adapters/driven/governance_authorization.rb +101 -0
  12. data/lib/hecks/adapters/driven/heki/journal.rb +56 -0
  13. data/lib/hecks/adapters/driven/heki/saga_store.rb +99 -0
  14. data/lib/hecks/adapters/driven/heki/snapshot.rb +65 -0
  15. data/lib/hecks/adapters/driven/heki.adapter +4 -0
  16. data/lib/hecks/adapters/driven/heki.rb +179 -0
  17. data/lib/hecks/adapters/driven/identity_registry.adapter +3 -0
  18. data/lib/hecks/adapters/driven/identity_registry.rb +26 -0
  19. data/lib/hecks/adapters/driven/in_memory_ordering.rb +51 -0
  20. data/lib/hecks/adapters/driven/lambda/client.rb +63 -0
  21. data/lib/hecks/adapters/driven/lambda.adapter +4 -0
  22. data/lib/hecks/adapters/driven/lambda.rb +145 -0
  23. data/lib/hecks/adapters/driven/memory.adapter +3 -0
  24. data/lib/hecks/adapters/driven/memory.rb +103 -0
  25. data/lib/hecks/adapters/driven/mock_stripe_adapter.adapter +3 -0
  26. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +28 -0
  27. data/lib/hecks/adapters/driven/postgres/codec.rb +88 -0
  28. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +207 -0
  29. data/lib/hecks/adapters/driven/postgres.adapter +5 -0
  30. data/lib/hecks/adapters/driven/postgres.rb +438 -0
  31. data/lib/hecks/adapters/driven/postgres_era.adapter +17 -0
  32. data/lib/hecks/adapters/driven/prism.adapter +3 -0
  33. data/lib/hecks/adapters/driven/prism.rb +80 -0
  34. data/lib/hecks/adapters/driven/secure_random_identity.adapter +3 -0
  35. data/lib/hecks/adapters/driven/secure_random_identity.rb +14 -0
  36. data/lib/hecks/adapters/driven/sql_query_builder.rb +221 -0
  37. data/lib/hecks/adapters/driven/sqlite/codec.rb +80 -0
  38. data/lib/hecks/adapters/driven/sqlite/projection.rb +172 -0
  39. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +192 -0
  40. data/lib/hecks/adapters/driven/sqlite.adapter +9 -0
  41. data/lib/hecks/adapters/driven/sqlite.rb +306 -0
  42. data/lib/hecks/adapters/driven/system_clock.adapter +3 -0
  43. data/lib/hecks/adapters/driven/system_clock.rb +14 -0
  44. data/lib/hecks/adapters/driven.rb +54 -0
  45. data/lib/hecks/adapters.rb +6 -0
  46. data/lib/hecks/behaviors/dsl.rb +125 -0
  47. data/lib/hecks/behaviors/expectations.rb +340 -0
  48. data/lib/hecks/behaviors/ir.rb +31 -0
  49. data/lib/hecks/behaviors/rspec.rb +42 -0
  50. data/lib/hecks/behaviors/runner.rb +96 -0
  51. data/lib/hecks/behaviors.rb +25 -0
  52. data/lib/hecks/bluebook/aggregate.rb +108 -0
  53. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +134 -0
  54. data/lib/hecks/bluebook/assembly/build.rb +48 -0
  55. data/lib/hecks/bluebook/assembly/contract.rb +112 -0
  56. data/lib/hecks/bluebook/assembly/contracts.rb +438 -0
  57. data/lib/hecks/bluebook/assembly/marks.rb +228 -0
  58. data/lib/hecks/bluebook/assembly/specializer.rb +70 -0
  59. data/lib/hecks/bluebook/assembly.rb +91 -0
  60. data/lib/hecks/bluebook/attribute.rb +96 -0
  61. data/lib/hecks/bluebook/behaviour/aggregate.rb +83 -0
  62. data/lib/hecks/bluebook/behaviour/attribute.rb +27 -0
  63. data/lib/hecks/bluebook/behaviour/chapter.rb +72 -0
  64. data/lib/hecks/bluebook/behaviour/command.rb +116 -0
  65. data/lib/hecks/bluebook/behaviour/domain_port.rb +25 -0
  66. data/lib/hecks/bluebook/behaviour/entity.rb +59 -0
  67. data/lib/hecks/bluebook/behaviour/hexagon.rb +50 -0
  68. data/lib/hecks/bluebook/behaviour/lifecycle.rb +68 -0
  69. data/lib/hecks/bluebook/behaviour/policy.rb +52 -0
  70. data/lib/hecks/bluebook/behaviour/process_manager.rb +51 -0
  71. data/lib/hecks/bluebook/behaviour/query.rb +10 -0
  72. data/lib/hecks/bluebook/behaviour/read_model.rb +29 -0
  73. data/lib/hecks/bluebook/behaviour/traits.rb +81 -0
  74. data/lib/hecks/bluebook/behaviour/value_object.rb +33 -0
  75. data/lib/hecks/bluebook/chapter.rb +78 -0
  76. data/lib/hecks/bluebook/command.rb +124 -0
  77. data/lib/hecks/bluebook/domain_port.rb +102 -0
  78. data/lib/hecks/bluebook/dsl/adapter_builder.rb +34 -0
  79. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +1018 -0
  80. data/lib/hecks/bluebook/dsl/attribute_collector.rb +348 -0
  81. data/lib/hecks/bluebook/dsl/binding_proxy.rb +71 -0
  82. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +1087 -0
  83. data/lib/hecks/bluebook/dsl/command_builder.rb +714 -0
  84. data/lib/hecks/bluebook/dsl/const_shim.rb +81 -0
  85. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +79 -0
  86. data/lib/hecks/bluebook/dsl/entity_builder.rb +430 -0
  87. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +366 -0
  88. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +163 -0
  89. data/lib/hecks/bluebook/dsl/identity_declaration.rb +191 -0
  90. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +44 -0
  91. data/lib/hecks/bluebook/dsl/malformed.rb +7 -0
  92. data/lib/hecks/bluebook/dsl/policy_builder.rb +135 -0
  93. data/lib/hecks/bluebook/dsl/port_builder.rb +39 -0
  94. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +142 -0
  95. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +306 -0
  96. data/lib/hecks/bluebook/dsl/query_builder.rb +113 -0
  97. data/lib/hecks/bluebook/dsl/read_model_builder.rb +233 -0
  98. data/lib/hecks/bluebook/dsl/rule_reference.rb +173 -0
  99. data/lib/hecks/bluebook/dsl/translation_builder.rb +243 -0
  100. data/lib/hecks/bluebook/dsl/value_object_builder.rb +178 -0
  101. data/lib/hecks/bluebook/dsl/word_gate.rb +228 -0
  102. data/lib/hecks/bluebook/dsl/world_builder.rb +117 -0
  103. data/lib/hecks/bluebook/dsl.rb +45 -0
  104. data/lib/hecks/bluebook/entity.rb +103 -0
  105. data/lib/hecks/bluebook/expression/canonical_form.rb +123 -0
  106. data/lib/hecks/bluebook/expression/evaluator.rb +304 -0
  107. data/lib/hecks/bluebook/expression/projection.json +218 -0
  108. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +233 -0
  109. data/lib/hecks/bluebook/expression/resolver.rb +781 -0
  110. data/lib/hecks/bluebook/expression.rb +13 -0
  111. data/lib/hecks/bluebook/hexagon.rb +60 -0
  112. data/lib/hecks/bluebook/lifecycle.rb +42 -0
  113. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +54 -0
  114. data/lib/hecks/bluebook/meta_validator/judge.rb +621 -0
  115. data/lib/hecks/bluebook/meta_validator/plan.rb +332 -0
  116. data/lib/hecks/bluebook/meta_validator/port_judge.rb +51 -0
  117. data/lib/hecks/bluebook/meta_validator/readings.rb +360 -0
  118. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +351 -0
  119. data/lib/hecks/bluebook/meta_validator/shapes.rb +266 -0
  120. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +255 -0
  121. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +138 -0
  122. data/lib/hecks/bluebook/meta_validator/world_judge.rb +78 -0
  123. data/lib/hecks/bluebook/meta_validator.rb +542 -0
  124. data/lib/hecks/bluebook/model_check.rb +445 -0
  125. data/lib/hecks/bluebook/pattern_subset.rb +184 -0
  126. data/lib/hecks/bluebook/policy.rb +41 -0
  127. data/lib/hecks/bluebook/process_manager.rb +128 -0
  128. data/lib/hecks/bluebook/project_discovery.rb +30 -0
  129. data/lib/hecks/bluebook/project_loader.rb +40 -0
  130. data/lib/hecks/bluebook/project_register.rb +82 -0
  131. data/lib/hecks/bluebook/query.rb +61 -0
  132. data/lib/hecks/bluebook/read_model.rb +109 -0
  133. data/lib/hecks/bluebook/reference.rb +74 -0
  134. data/lib/hecks/bluebook/smoke_test.rb +166 -0
  135. data/lib/hecks/bluebook/synthesizer.rb +95 -0
  136. data/lib/hecks/bluebook/translation.rb +92 -0
  137. data/lib/hecks/bluebook/value_object.rb +66 -0
  138. data/lib/hecks/bluebook.rb +74 -0
  139. data/lib/hecks/codemod.rb +342 -0
  140. data/lib/hecks/construct.rb +71 -0
  141. data/lib/hecks/deploy/bluebook/deploy.bluebook +219 -0
  142. data/lib/hecks/deploy/bluebook/deploy.hecksagon +4 -0
  143. data/lib/hecks/deploy/oidc.json +18 -0
  144. data/lib/hecks/doc/reference.rb +410 -0
  145. data/lib/hecks/embryonaut_bluebook.rb +75 -0
  146. data/lib/hecks/facade/cli_door.rb +119 -0
  147. data/lib/hecks/facade/cli_runner.rb +190 -0
  148. data/lib/hecks/facade/command_request.rb +105 -0
  149. data/lib/hecks/facade/handle.rb +173 -0
  150. data/lib/hecks/facade/json_door.rb +166 -0
  151. data/lib/hecks/facade/surface/aggregate_door.rb +185 -0
  152. data/lib/hecks/facade/surface/chapter.rb +107 -0
  153. data/lib/hecks/facade/surface.rb +48 -0
  154. data/lib/hecks/facade.rb +44 -0
  155. data/lib/hecks/forms/app.rb +341 -0
  156. data/lib/hecks/forms/command_form_renderer.rb +113 -0
  157. data/lib/hecks/forms/examples/banking_console.bluebook +3 -0
  158. data/lib/hecks/forms/field_renderer.rb +177 -0
  159. data/lib/hecks/forms/field_shape.rb +232 -0
  160. data/lib/hecks/forms/html.rb +84 -0
  161. data/lib/hecks/forms/index_renderer.rb +35 -0
  162. data/lib/hecks/forms/page.rb +157 -0
  163. data/lib/hecks/forms/params.rb +161 -0
  164. data/lib/hecks/forms/port_argument.rb +46 -0
  165. data/lib/hecks/forms/query_form_renderer.rb +114 -0
  166. data/lib/hecks/forms/record_renderer.rb +119 -0
  167. data/lib/hecks/forms/record_table.rb +68 -0
  168. data/lib/hecks/forms/reference_options.rb +30 -0
  169. data/lib/hecks/forms/value_object_shape.rb +46 -0
  170. data/lib/hecks/forms.rb +54 -0
  171. data/lib/hecks/fqn.rb +94 -0
  172. data/lib/hecks/framework/bluebook/compliance.bluebook +1 -0
  173. data/lib/hecks/framework/bluebook/console_settings.bluebook +489 -0
  174. data/lib/hecks/framework/bluebook/framework.hecksagon +32 -0
  175. data/lib/hecks/framework/bluebook/governance.bluebook +145 -0
  176. data/lib/hecks/framework/bluebook/identity.bluebook +90 -0
  177. data/lib/hecks/framework/oidc.json +39 -0
  178. data/lib/hecks/framework.rb +90 -0
  179. data/lib/hecks/freezer.rb +67 -0
  180. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +527 -0
  181. data/lib/hecks/fuzzing/invalid_value_generator.rb +86 -0
  182. data/lib/hecks/fuzzing/isolated_boot.rb +286 -0
  183. data/lib/hecks/fuzzing/properties.rb +1192 -0
  184. data/lib/hecks/fuzzing/replay.rb +668 -0
  185. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +93 -0
  186. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +80 -0
  187. data/lib/hecks/fuzzing/sequence_generator/picker.rb +96 -0
  188. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +250 -0
  189. data/lib/hecks/fuzzing/sequence_generator.rb +131 -0
  190. data/lib/hecks/fuzzing/value_generator.rb +200 -0
  191. data/lib/hecks/fuzzing.rb +12 -0
  192. data/lib/hecks/grammar/evolve.rb +324 -0
  193. data/lib/hecks/grammar/expression.bluebook +420 -0
  194. data/lib/hecks/grammar/expression_operators.json +1648 -0
  195. data/lib/hecks/grammar/grammar.hecksagon +20 -0
  196. data/lib/hecks/grammar/oidc.json +69 -0
  197. data/lib/hecks/grammar/translation.bluebook +203 -0
  198. data/lib/hecks/grammar.rb +178 -0
  199. data/lib/hecks/ir.rb +126 -0
  200. data/lib/hecks/language/adapter.bluebook +116 -0
  201. data/lib/hecks/language/bluebook/aggregate.bluebook +581 -0
  202. data/lib/hecks/language/bluebook/attaches/paging.bluebook +76 -0
  203. data/lib/hecks/language/bluebook/bluebook.bluebook +256 -0
  204. data/lib/hecks/language/bluebook/bluebook.hecksagon +24 -0
  205. data/lib/hecks/language/bluebook/command.bluebook +471 -0
  206. data/lib/hecks/language/bluebook/entity.bluebook +392 -0
  207. data/lib/hecks/language/bluebook/policy.bluebook +189 -0
  208. data/lib/hecks/language/bluebook/process_manager.bluebook +381 -0
  209. data/lib/hecks/language/bluebook/projection.bluebook +267 -0
  210. data/lib/hecks/language/bluebook/query.bluebook +245 -0
  211. data/lib/hecks/language/bluebook/shape.bluebook +292 -0
  212. data/lib/hecks/language/bluebook/syntax.bluebook +448 -0
  213. data/lib/hecks/language/bluebook/vocabulary.bluebook +379 -0
  214. data/lib/hecks/language/hecksagon/adapter_binding.bluebook +51 -0
  215. data/lib/hecks/language/hecksagon/domain_port.bluebook +76 -0
  216. data/lib/hecks/language/hecksagon/hecksagon.bluebook +131 -0
  217. data/lib/hecks/language/hecksagon/port_operation.bluebook +102 -0
  218. data/lib/hecks/language/oidc.json +333 -0
  219. data/lib/hecks/language/port.bluebook +120 -0
  220. data/lib/hecks/language/translation/translation.bluebook +110 -0
  221. data/lib/hecks/language/translation/translation_aggregate.bluebook +267 -0
  222. data/lib/hecks/language/world/wiring.bluebook +62 -0
  223. data/lib/hecks/language/world/world.bluebook +84 -0
  224. data/lib/hecks/literal.rb +125 -0
  225. data/lib/hecks/naming.rb +174 -0
  226. data/lib/hecks/ports/access_control.port +9 -0
  227. data/lib/hecks/ports/access_control.rb +62 -0
  228. data/lib/hecks/ports/agent/answers.rb +104 -0
  229. data/lib/hecks/ports/agent.port +8 -0
  230. data/lib/hecks/ports/agent.rb +167 -0
  231. data/lib/hecks/ports/authentication.port +6 -0
  232. data/lib/hecks/ports/authentication.rb +50 -0
  233. data/lib/hecks/ports/authorization.port +7 -0
  234. data/lib/hecks/ports/authorization.rb +62 -0
  235. data/lib/hecks/ports/clock.port +5 -0
  236. data/lib/hecks/ports/clock.rb +62 -0
  237. data/lib/hecks/ports/extraction.port +5 -0
  238. data/lib/hecks/ports/extraction.rb +37 -0
  239. data/lib/hecks/ports/identity_assignment.port +5 -0
  240. data/lib/hecks/ports/identity_assignment.rb +45 -0
  241. data/lib/hecks/ports/identity_generation.port +5 -0
  242. data/lib/hecks/ports/identity_generation.rb +49 -0
  243. data/lib/hecks/ports/identity_resolution.port +5 -0
  244. data/lib/hecks/ports/identity_resolution.rb +40 -0
  245. data/lib/hecks/ports/loading.port +4 -0
  246. data/lib/hecks/ports/loading.rb +13 -0
  247. data/lib/hecks/ports/persistence/append_only.rb +138 -0
  248. data/lib/hecks/ports/persistence/binding_policy.rb +56 -0
  249. data/lib/hecks/ports/persistence/execution.rb +23 -0
  250. data/lib/hecks/ports/persistence/null_saga_store.rb +25 -0
  251. data/lib/hecks/ports/persistence/plugin.rb +54 -0
  252. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +169 -0
  253. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +128 -0
  254. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +161 -0
  255. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +61 -0
  256. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +304 -0
  257. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +171 -0
  258. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +190 -0
  259. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +478 -0
  260. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +166 -0
  261. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +314 -0
  262. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +168 -0
  263. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +170 -0
  264. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +134 -0
  265. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +137 -0
  266. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +89 -0
  267. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +85 -0
  268. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +43 -0
  269. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +132 -0
  270. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +74 -0
  271. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +758 -0
  272. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +120 -0
  273. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +31 -0
  274. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +46 -0
  275. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +102 -0
  276. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +46 -0
  277. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +70 -0
  278. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +72 -0
  279. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +120 -0
  280. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +183 -0
  281. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +41 -0
  282. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +28 -0
  283. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +30 -0
  284. data/lib/hecks/ports/persistence/plugins/era/translation.rb +11 -0
  285. data/lib/hecks/ports/persistence/plugins/era.rb +48 -0
  286. data/lib/hecks/ports/persistence/remote_runtime.rb +42 -0
  287. data/lib/hecks/ports/persistence/repository_factory.rb +30 -0
  288. data/lib/hecks/ports/persistence.port +4 -0
  289. data/lib/hecks/ports/persistence.rb +39 -0
  290. data/lib/hecks/ports/projection.port +4 -0
  291. data/lib/hecks/ports/projection.rb +96 -0
  292. data/lib/hecks/ports/query/in_memory.rb +60 -0
  293. data/lib/hecks/ports/query/ordering.rb +41 -0
  294. data/lib/hecks/ports/query.rb +36 -0
  295. data/lib/hecks/ports.rb +27 -0
  296. data/lib/hecks/projections/diagrams.rb +642 -0
  297. data/lib/hecks/projections/ir.rb +18 -0
  298. data/lib/hecks/projections/model/deviations.rb +98 -0
  299. data/lib/hecks/projections/model.rb +145 -0
  300. data/lib/hecks/projections/oidc.rb +110 -0
  301. data/lib/hecks/projections/parser_table.rb +159 -0
  302. data/lib/hecks/projections/reference.rb +38 -0
  303. data/lib/hecks/projections/shape.rb +44 -0
  304. data/lib/hecks/projections/statements.rb +110 -0
  305. data/lib/hecks/projections/vocabulary.rb +100 -0
  306. data/lib/hecks/projections.rb +32 -0
  307. data/lib/hecks/projector/cli_projector.rb +446 -0
  308. data/lib/hecks/projector/docs_projector.rb +321 -0
  309. data/lib/hecks/projector/exporter.rb +158 -0
  310. data/lib/hecks/projector/ir_projector.rb +18 -0
  311. data/lib/hecks/projector/narrate_projector.rb +243 -0
  312. data/lib/hecks/projector/target.rb +97 -0
  313. data/lib/hecks/projector.rb +186 -0
  314. data/lib/hecks/query_ir.rb +411 -0
  315. data/lib/hecks/query_specification/common/authorization_spec.rb +9 -0
  316. data/lib/hecks/query_specification/common/comparators.rb +25 -0
  317. data/lib/hecks/query_specification/common/comparison.rb +174 -0
  318. data/lib/hecks/query_specification/common/cursor_spec.rb +9 -0
  319. data/lib/hecks/query_specification/common/dsl.rb +58 -0
  320. data/lib/hecks/query_specification/common/inspection_spec.rb +9 -0
  321. data/lib/hecks/query_specification/common/limit_spec.rb +9 -0
  322. data/lib/hecks/query_specification/common/null_policy.rb +92 -0
  323. data/lib/hecks/query_specification/common/null_semantics.rb +11 -0
  324. data/lib/hecks/query_specification/common/offset_spec.rb +9 -0
  325. data/lib/hecks/query_specification/common/options.rb +32 -0
  326. data/lib/hecks/query_specification/common/order_by.rb +9 -0
  327. data/lib/hecks/query_specification/common/specification.rb +10 -0
  328. data/lib/hecks/query_specification/common/where_clause.rb +9 -0
  329. data/lib/hecks/query_specification/field_path.rb +107 -0
  330. data/lib/hecks/query_specification/hop_path.rb +132 -0
  331. data/lib/hecks/query_specification/read_model/specification.rb +18 -0
  332. data/lib/hecks/query_specification.rb +14 -0
  333. data/lib/hecks/rendering.rb +48 -0
  334. data/lib/hecks/router/namespace_installer.rb +157 -0
  335. data/lib/hecks/router.rb +70 -0
  336. data/lib/hecks/runtime/aggregate_lock.rb +45 -0
  337. data/lib/hecks/runtime/boot_gates.rb +41 -0
  338. data/lib/hecks/runtime/caller.rb +66 -0
  339. data/lib/hecks/runtime/capability_graph.rb +44 -0
  340. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +135 -0
  341. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +260 -0
  342. data/lib/hecks/runtime/command_interpreter.rb +497 -0
  343. data/lib/hecks/runtime/command_rules/admissibility.rb +357 -0
  344. data/lib/hecks/runtime/command_rules/arithmetic.rb +260 -0
  345. data/lib/hecks/runtime/command_rules/authorization.rb +65 -0
  346. data/lib/hecks/runtime/command_rules/emission.rb +34 -0
  347. data/lib/hecks/runtime/command_rules/references.rb +189 -0
  348. data/lib/hecks/runtime/command_rules.rb +28 -0
  349. data/lib/hecks/runtime/dependency_planning.rb +245 -0
  350. data/lib/hecks/runtime/dispatcher.rb +301 -0
  351. data/lib/hecks/runtime/entity_element.rb +253 -0
  352. data/lib/hecks/runtime/entity_interpreter.rb +299 -0
  353. data/lib/hecks/runtime/errors.rb +122 -0
  354. data/lib/hecks/runtime/event.rb +51 -0
  355. data/lib/hecks/runtime/identity.rb +156 -0
  356. data/lib/hecks/runtime/instance.rb +175 -0
  357. data/lib/hecks/runtime/interpreting.rb +90 -0
  358. data/lib/hecks/runtime/loader.rb +184 -0
  359. data/lib/hecks/runtime/policy_interpreter.rb +366 -0
  360. data/lib/hecks/runtime/port_operation_interpreter.rb +210 -0
  361. data/lib/hecks/runtime/query_interpreter.rb +286 -0
  362. data/lib/hecks/runtime/reaction_invocation.rb +253 -0
  363. data/lib/hecks/runtime/read_model_interpreter.rb +341 -0
  364. data/lib/hecks/runtime/rebuild_sweep.rb +74 -0
  365. data/lib/hecks/runtime/reference_hop.rb +99 -0
  366. data/lib/hecks/runtime/refusal_wording.rb +126 -0
  367. data/lib/hecks/runtime/registry/saga_persistence.rb +142 -0
  368. data/lib/hecks/runtime/registry/verification.rb +246 -0
  369. data/lib/hecks/runtime/registry.rb +279 -0
  370. data/lib/hecks/runtime/remote_dispatcher.rb +143 -0
  371. data/lib/hecks/runtime/routing.rb +96 -0
  372. data/lib/hecks/runtime/saga_interpreter/correlation.rb +97 -0
  373. data/lib/hecks/runtime/saga_interpreter.rb +503 -0
  374. data/lib/hecks/runtime/saga_pending_dispatch.rb +45 -0
  375. data/lib/hecks/runtime/tenant_check.rb +84 -0
  376. data/lib/hecks/runtime/tenant_scope.rb +55 -0
  377. data/lib/hecks/runtime/value/admission.rb +130 -0
  378. data/lib/hecks/runtime/value/coercion.rb +565 -0
  379. data/lib/hecks/runtime/value/invariant_violation.rb +5 -0
  380. data/lib/hecks/runtime/value.rb +125 -0
  381. data/lib/hecks/runtime.rb +107 -0
  382. data/lib/hecks/storehouse.rb +632 -0
  383. data/lib/hecks/version.rb +16 -0
  384. data/lib/hecks/vocabulary.rb +218 -0
  385. data/lib/hecks.rb +123 -6
  386. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +90 -0
  387. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +128 -0
  388. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +160 -0
  389. metadata +412 -222
  390. data/bin/hecks +0 -7
  391. data/bin/hecks-package +0 -65
  392. data/bin/hecks_console +0 -12
  393. data/bin/hecks_serverless +0 -6
  394. data/lib/cli/build.rb +0 -14
  395. data/lib/cli/command_runner.rb +0 -28
  396. data/lib/cli/console.rb +0 -10
  397. data/lib/cli/generate.rb +0 -37
  398. data/lib/cli/hecks-cli.rb +0 -27
  399. data/lib/cli/test.rb +0 -57
  400. data/lib/console/commands.rb +0 -8
  401. data/lib/console/hecks-console.rb +0 -1
  402. data/lib/packager/README.md +0 -0
  403. data/lib/packager/app_runner.rb +0 -21
  404. data/lib/packager/args.rb +0 -26
  405. data/lib/packager/compatibility/fixnum.rb +0 -6
  406. data/lib/packager/hecks.rb +0 -39
  407. data/lib/packager/query_runner.rb +0 -21
  408. data/lib/packager/resources/Dockerfile +0 -11
  409. data/lib/packager/resources/app_binary +0 -7
  410. data/lib/packager/resources/bundle_config +0 -3
  411. data/lib/packager/resources/traveling-ruby-20150715-2.2.2-linux-x86_64.tar.gz +0 -0
  412. data/lib/packager/resources/traveling-ruby-20150715-2.2.2-osx.tar.gz +0 -0
  413. data/lib/serverless/Domain +0 -32
  414. data/lib/serverless/cli.rb +0 -75
  415. data/lib/serverless/resources/command_name.js +0 -5
  416. data/lib/serverless/resources/environment.js +0 -7
  417. data/lib/serverless/resources/handler.js.tt +0 -28
  418. data/lib/serverless/resources/run_binary.js +0 -22
  419. data/lib/serverless/resources/serverless.yml +0 -20
@@ -0,0 +1,448 @@
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", "Dispatch", "ReadModel", "Type",
90
+ "Hecksagon", "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: `given` on Aggregate,
256
+ # and `given` on Entity, one level down — chapter-wide sharing at
257
+ # each scope it has grown to).
258
+ attribute :disambiguator, KeywordSeedText, admits: "Syntax::Disambiguator", optional: true
259
+ # THE ESCAPE HATCH — item #13's full metaprogrammed dispatch (slice
260
+ # 3, whole-project table-unification survey). BLANK for every word
261
+ # `GenericDispatch` fills/opens/zero-args directly off `fills:`/
262
+ # `opens:`. NON-EMPTY names a real Ruby method this word's whole
263
+ # call (args, kwargs, block, untouched) forwards to instead — for
264
+ # words whose own logic is genuinely too complex to re-derive from
265
+ # argument shape alone (`attribute`'s own type-quoting/closed-set-
266
+ # synthesis/pattern validation). The method itself stays exactly
267
+ # what it always was, hand-written, unchanged — this column only
268
+ # says WHICH one answers the word, the same way `resolves_via`
269
+ # already names which shared primitive a bare reference resolves
270
+ # through, one level up. Read DURING bootstrap too (`WordGate`'s
271
+ # own `BOOTSTRAP_CALLS_FALLBACK`, a small explicit table naming
272
+ # the SAME (context, word) -> method pairs this column would say,
273
+ # since the real table doesn't exist yet at that point) — the one
274
+ # place in this whole arc a bootstrap fallback was worth building,
275
+ # because it duplicates NO logic, only a method NAME.
276
+ attribute :calls, KeywordSeedText, optional: true
277
+
278
+ lifecycle :status, default: "admitted" do
279
+ # NOT `proposed` : nothing in the real table is ever declared
280
+ # proposed today, and the lifecycle's own default has to stay
281
+ # "admitted" to match every existing row's own implicit status —
282
+ # changing it would make every one of the ~106 rows silently
283
+ # start "proposed" instead. Declaring `proposed` as a state
284
+ # reachable from nowhere would be exactly the kind of decorative,
285
+ # unused declaration this whole ADR series exists to catch — so
286
+ # it is left out, honestly, rather than declared and unreachable.
287
+ transition "Deprecate" => "deprecated", from: "admitted"
288
+ transition "Retire" => "retired", from: ["admitted", "deprecated"]
289
+ end
290
+
291
+ command "Deprecate" do
292
+ role "Language"
293
+ goal "Mark a word as on its way out, still read"
294
+
295
+ emits KeywordDeprecated
296
+ end
297
+
298
+ command "Retire" do
299
+ role "Language"
300
+ goal "Remove a word from every generated parser table"
301
+
302
+ emits KeywordRetired
303
+ end
304
+ end
305
+
306
+ # S14, ADR 0026 — same reason Keyword's own is, one construct over.
307
+ # `identified_by :position` — positional, the SAME field name as
308
+ # Keyword's own on purpose: an Argument row's identity is never
309
+ # compared against a Keyword row's, so the shared name costs nothing
310
+ # and names the same fact both times.
311
+ value_object "ArgumentPosition" do
312
+ attribute :value, Integer
313
+ end
314
+
315
+ entity "Argument" do
316
+ 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)."
317
+
318
+ identified_by ArgumentPosition, as: :position
319
+
320
+ attribute :keyword, ArgumentSeedText
321
+ attribute :context, ArgumentSeedText, admits: "Syntax::Context"
322
+ attribute :at, ArgumentSeedText, optional: true
323
+ attribute :named, ArgumentSeedText, optional: true
324
+ attribute :kind, ArgumentSeedText, admits: "Syntax::ArgumentKind"
325
+ attribute :required, ArgumentSeedText
326
+ attribute :fills, ArgumentSeedText
327
+ attribute :selects, ArgumentSeedText, optional: true
328
+ attribute :pair_key_fills, ArgumentSeedText, optional: true
329
+ attribute :pair_value_fills, ArgumentSeedText, optional: true
330
+ attribute :pairs_shape, ArgumentSeedText, optional: true
331
+ attribute :variadic, ArgumentSeedText, optional: true
332
+ # Minimum positional count for a variadic form. `identified_by` uses
333
+ # two so one symbol can retire without retiring compound keys.
334
+ attribute :minimum, ArgumentSeedText, optional: true
335
+ # ABSENT means "apply the uniform, kind-driven coercion" (text ->
336
+ # .to_s, symbol -> .to_sym) — item #13's full metaprogrammed
337
+ # dispatch (slice 1, whole-project table-unification survey) reads
338
+ # this to decide whether a GENERATED fill method may coerce its own
339
+ # argument before storing it. `"false"` marks the six real
340
+ # exceptions a full builder-method audit found (read the real Ruby
341
+ # source, not inferred): `vision`/`description`(x4)/`goal` all
342
+ # store a `kind: "text"` argument RAW, with no `.to_s` at all —
343
+ # `.to_s` on an actual String is a same-object no-op for every real
344
+ # corpus use, but a direct Ruby API call passing something else
345
+ # (`vision(42)`) would see genuinely different stored behavior, so
346
+ # this couldn't be assumed uniform across every text-kind row the
347
+ # way it turned out to genuinely be for every OTHER text-kind
348
+ # argument in the whole grammar.
349
+ attribute :coerce, ArgumentSeedText, optional: true
350
+ # ABSENT means "an empty value is stored same as any other" — item
351
+ # #13's full metaprogrammed dispatch (slice 2, whole-project
352
+ # table-unification survey). NON-EMPTY names the exact Malformed
353
+ # message a real word's own hand-written method raised on a blank
354
+ # value BEFORE storing it (`Translation#retired`: "a retired needs
355
+ # an aggregate name"; `TranslationAggregate#drop`: "a drop needs a
356
+ # name") — `required: "true"` alone only gates Ruby's own ARITY
357
+ # (an argument omitted entirely), never a present-but-blank one,
358
+ # so this is a genuinely separate fact the table did not already
359
+ # carry. Most `required: "true"` rows do NOT raise on blank
360
+ # (confirmed by reading every one migrated in slice 1 —
361
+ # `Policy#on`/`ProcessManager#correlates_by`/etc. all accept and
362
+ # store an empty string same as any other), so this could not be
363
+ # assumed uniform from `required:` either. Carries the REAL text
364
+ # rather than a generated one — refusal wording is itself a
365
+ # checked contract in this codebase (item #2, whole-project
366
+ # table-unification survey, `RefusalWording::TEMPLATES`), not
367
+ # throwaway UX text a generic template could safely replace.
368
+ attribute :blank_message, ArgumentSeedText, optional: true
369
+
370
+ lifecycle :status, default: "admitted" do
371
+ transition "Deprecate" => "deprecated", from: "admitted"
372
+ transition "Retire" => "retired", from: ["admitted", "deprecated"]
373
+ end
374
+
375
+ command "Deprecate" do
376
+ role "Language"
377
+ goal "Mark an argument as on its way out, still read"
378
+
379
+ emits ArgumentDeprecated
380
+ end
381
+
382
+ command "Retire" do
383
+ role "Language"
384
+ goal "Remove an argument from every generated parser table"
385
+
386
+ emits ArgumentRetired
387
+ end
388
+ end
389
+
390
+ value_object "KeywordSeedText" do
391
+ attribute :value, String
392
+ end
393
+
394
+ value_object "ArgumentSeedText" do
395
+ attribute :value, String
396
+ end
397
+
398
+ # THE SYNTAX RECORD ITSELF. There is only ever one — the language
399
+ # describes its own single surface, not several — so unlike every
400
+ # other aggregate's own creating command, this carries no `position`:
401
+ # there are no siblings to order among.
402
+ command "Declare" do
403
+ role "Language"
404
+ goal "Open the language's own syntax table"
405
+
406
+ attribute :bluebook, BluebookName
407
+ attribute :name, SyntaxName
408
+
409
+ sets :bluebook
410
+ sets :name
411
+
412
+ emits SyntaxDeclared
413
+ end
414
+
415
+ # THE KEYWORD'S OWN CREATION. An entity is never created through its
416
+ # own dotted verb (S17's own finding, EntityInterpreter#element_of
417
+ # only LOCATES) — so, mirroring `ValueObject.Member`/`ProcessManager.
418
+ # Handler`, this is a bare, aggregate-level append. `position` is
419
+ # minted by `SyntaxBoot` as the seed row's own index — the same walk-
420
+ # index convention Member's own `position` already uses.
421
+ command "Keyword" do
422
+ role "Language"
423
+ goal "Admit one word the bluebook surface accepts"
424
+
425
+
426
+ sets :keywords, append: { position: :position, word: :word, context: :context, body: :body,
427
+ inner: :inner, opens: :opens, fills: :fills, was: :was,
428
+ resolves_via: :resolves_via, disambiguator: :disambiguator, calls: :calls }
429
+
430
+ emits KeywordAdmitted
431
+ end
432
+
433
+ command "Argument" do
434
+ role "Language"
435
+ goal "Admit one argument a keyword takes"
436
+
437
+
438
+ sets :arguments, append: { position: :position, keyword: :keyword, context: :context, at: :at,
439
+ named: :named, kind: :kind, required: :required, fills: :fills,
440
+ selects: :selects, pair_key_fills: :pair_key_fills,
441
+ pair_value_fills: :pair_value_fills, pairs_shape: :pairs_shape,
442
+ variadic: :variadic, minimum: :minimum,
443
+ coerce: :coerce, blank_message: :blank_message }
444
+
445
+ emits ArgumentAdmitted
446
+ end
447
+ end
448
+ end