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,304 @@
1
+ require "json"
2
+ require_relative "../../vocabulary"
3
+
4
+ module Hecks
5
+ module Bluebook
6
+ module Expression
7
+ module Evaluator
8
+ Operator = Struct.new(:symbol, :compares_less_than, :compares_equal, :negated, keyword_init: true)
9
+
10
+ # Six operators, reduced to two primitives (less_than, equal) combined
11
+ # with a small boolean algebra: compares_less_than/compares_equal choose
12
+ # which primitive(s) OR together, negated inverts the result.
13
+ #
14
+ # READ, NOT RESTATED. This table is the checked-in projection of the
15
+ # grammar chapter's admitted set (bin/expression_projection), joined with
16
+ # the algebra Vocabulary::Comparison declares. The evaluator cannot
17
+ # boot the chapter that configures it — the Prism adapter normalises
18
+ # every predicate through CanonicalForm while a bluebook loads — so
19
+ # the projection is how the domain reaches here: regenerated when the
20
+ # ledger changes, held fresh by spec/operators_export_spec.rb, and
21
+ # held to the live machinery by spec/operator_conformance_spec.rb.
22
+ PROJECTION = JSON.parse(
23
+ File.read(File.join(__dir__, "projection.json")), symbolize_names: true
24
+ ).freeze
25
+
26
+ OPERATORS = PROJECTION.fetch(:operators)
27
+ .select { |row| row[:category] == "comparison" }
28
+ .map { |row| Operator.new(**row.slice(:symbol, :compares_less_than, :compares_equal, :negated)) }
29
+ .freeze
30
+
31
+ COMPARISONS = OPERATORS.map(&:symbol).freeze
32
+
33
+ # The boolean/comparison grammar an expression parses into. Leaf nodes
34
+ # (Compare/Include/Resolve) hold already-parsed Resolver ASTs, not raw
35
+ # strings — which branch a leaf's grammar takes is, like the boolean/
36
+ # comparison grammar above it, a pure function of the string. Only the
37
+ # final state/attrs dictionary read, inside Resolver.interpret, varies
38
+ # per call. Parsing the whole tree once and caching it (ast_cache,
39
+ # below) is what makes that safe.
40
+ Or = Struct.new(:left, :right, keyword_init: true)
41
+ And = Struct.new(:left, :right, keyword_init: true)
42
+ Not = Struct.new(:node, keyword_init: true)
43
+ Compare = Struct.new(:operator, :left, :right, keyword_init: true)
44
+ Include = Struct.new(:haystack, :needle, keyword_init: true)
45
+ Resolve = Struct.new(:expr, keyword_init: true)
46
+
47
+ module_function
48
+
49
+ # Keyed by the exact string `call` receives. Canonical text is already
50
+ # normalised at DSL-build time, so the same given/invariant's text is
51
+ # byte-identical across every dispatch that evaluates it — parsed once
52
+ # here, interpreted fresh against each call's own state/attrs. Matches
53
+ # MetaValidator.verdicts' unsynchronized `||= {}` idiom : redundant
54
+ # parse work under real parallelism, never corruption.
55
+ def ast_cache = @ast_cache ||= {}
56
+
57
+ def call(expr, state, attrs = {})
58
+ interpret(ast_cache[expr] ||= parse(expr), state, attrs)
59
+ end
60
+
61
+ def parse(expr)
62
+ expr = strip_parens(expr.to_s.strip)
63
+
64
+ left, right = split_top_level(expr, "||")
65
+ return Or.new(left: parse(left), right: parse(right)) if left
66
+
67
+ left, right = split_top_level(expr, "&&")
68
+ return And.new(left: parse(left), right: parse(right)) if left
69
+
70
+ # Tried BEFORE `.include?`/comparisons, not after — `!` negates
71
+ # the WHOLE boolean expression that follows it (`!names.include?(x)`
72
+ # means `!(names.include?(x))`, never "call .include? on the negated
73
+ # receiver"), so the leading marker has to be stripped and the
74
+ # remainder re-parsed before anything downstream gets a chance to
75
+ # mis-scan across it. It used to sit after `match_include`, whose
76
+ # naive `rindex(".include?(")` has no concept of a leading `!` —
77
+ # for `!names.include?(x)` it swallowed the `!` straight into the
78
+ # haystack text ("!names"), which `Resolver.parse` cannot resolve,
79
+ # so every spelling of negated membership raised instead of
80
+ # evaluating. Moving the check here fixes both the bare prefix
81
+ # (`!names.include?(x)`) and the parenthesized form
82
+ # (`!(names.include?(x))`) — the recursive `parse` call sees the
83
+ # clean remainder and correctly finds the `.include?` (or `&&`/`||`)
84
+ # inside it.
85
+ return Not.new(node: parse(Regexp.last_match(1))) if expr =~ /\A!(.+)\z/
86
+
87
+ membership = match_include(expr)
88
+ return Include.new(haystack: Resolver.parse(membership[0]), needle: Resolver.parse(membership[1])) if membership
89
+
90
+ OPERATORS.each do |op|
91
+ left, right = split_comparison(expr, op.symbol)
92
+ return Compare.new(operator: op, left: Resolver.parse(left), right: Resolver.parse(right)) if left
93
+ end
94
+
95
+ Resolve.new(expr: Resolver.parse(expr))
96
+ end
97
+
98
+ def interpret(node, state, attrs)
99
+ case node
100
+ when Or then interpret(node.left, state, attrs) || interpret(node.right, state, attrs)
101
+ when And then interpret(node.left, state, attrs) && interpret(node.right, state, attrs)
102
+ when Not then !interpret(node.node, state, attrs)
103
+ when Compare then compare(node.operator, node.left, node.right, state, attrs)
104
+ when Include then includes?([node.haystack, node.needle], state, attrs)
105
+ when Resolve then truthy?(Resolver.interpret(node.expr, state, attrs))
106
+ else
107
+ # Every node `parse` can produce has a `when` above — a
108
+ # backstop against the day this grammar grows a new node
109
+ # type and `interpret` doesn't grow to match it. A missing
110
+ # arm here used to return bare `nil`, and `Or`/`And` fold
111
+ # that straight into the boolean algebra as ordinary falsy
112
+ # — reading exactly like "the rule legitimately does not
113
+ # hold" rather than "the runtime cannot evaluate this rule
114
+ # at all", the one silent no-op this language otherwise
115
+ # refuses.
116
+ raise EvaluationError, "no interpreter handles #{node.class} — add a case before parse can produce it"
117
+ end
118
+ end
119
+
120
+ def compare(op, left, right, state, attrs)
121
+ lhs = Resolver.interpret(left, state, attrs)
122
+ rhs = Resolver.interpret(right, state, attrs)
123
+
124
+ apply(op, lhs, rhs)
125
+ end
126
+
127
+ # The algebra itself, on values already resolved — split out so a sign
128
+ # test (SignTest#compares_via names an Operator symbol) can apply the
129
+ # SAME primitives compare() uses against the literal 0, rather than
130
+ # re-deriving positive?/negative?/zero? by hand a second time.
131
+ def apply(op, lhs, rhs)
132
+ result = (op.compares_less_than && less_than(lhs, rhs)) ||
133
+ (op.compares_equal && equal?(lhs, rhs))
134
+ op.negated ? !result : result
135
+ end
136
+
137
+ def less_than(lhs, rhs)
138
+ left = Resolver.numeric(lhs)
139
+ right = Resolver.numeric(rhs)
140
+ return left < right if left && right
141
+ return lhs < rhs if lhs.is_a?(String) && rhs.is_a?(String)
142
+
143
+ raise EvaluationError,
144
+ "comparison of #{class_of(lhs)} with #{Resolver.describe(rhs)} failed"
145
+ end
146
+
147
+ def equal?(lhs, rhs)
148
+ left = Resolver.numeric(lhs)
149
+ right = Resolver.numeric(rhs)
150
+ return left == right if left && right
151
+
152
+ lhs == rhs
153
+ end
154
+
155
+ def truthy?(value)
156
+ !value.nil? && value != false
157
+ end
158
+
159
+ def class_of(value)
160
+ value.nil? ? "nil" : value.class.name
161
+ end
162
+
163
+ # THE SAME MIS-SPLIT `Resolver.match_call` had (its own comment
164
+ # has the full story), found here too by the same generator: a
165
+ # `.include?` needle can itself be — or contain — ANOTHER
166
+ # `.include?` call (`"".include?(arr.all? { |el| "".include?("")
167
+ # }.to_s)`, a String built via `.to_s` off a block predicate
168
+ # whose own body happens to include one) — `rindex` finds the
169
+ # INNERMOST occurrence, not the outermost this split actually
170
+ # needs. Fixed identically: try each occurrence left to right,
171
+ # keep the first whose own balanced-paren match reaches the
172
+ # string's last character — `Resolver.matching_paren` is reused
173
+ # directly rather than duplicated, the same depth-tracking rule
174
+ # either grammar layer needs here.
175
+ def match_include(expr)
176
+ start = 0
177
+ marker = ".include?("
178
+ while (index = expr.index(marker, start))
179
+ close = Resolver.matching_paren(expr, index + marker.length)
180
+ return [expr[0...index], expr[(index + marker.length)...close]] if close == expr.length - 1
181
+
182
+ start = index + 1
183
+ end
184
+ nil
185
+ end
186
+
187
+ # Declared the same way in Vocabulary::IncludeHaystack
188
+ # (language/bluebook/vocabulary.bluebook) — spec/vocabulary_conformance_spec
189
+ # holds this equal to the language, so the set of haystack types
190
+ # `.include?` supports cannot drift from what the language says it
191
+ # does.
192
+ INCLUDE_HAYSTACKS = Hecks::Vocabulary.fetch("IncludeHaystack")
193
+
194
+ def includes?(parts, state, attrs)
195
+ haystack, needle = parts
196
+ wanted = Resolver.interpret(needle, state, attrs)
197
+
198
+ case (found = Resolver.interpret(haystack, state, attrs))
199
+ when Array then found.any? { |item| equal?(item, wanted) }
200
+ when String
201
+ unless wanted.is_a?(String)
202
+ raise EvaluationError, "no implicit conversion of #{class_of(wanted)} into String"
203
+ end
204
+
205
+ found.include?(wanted)
206
+ else false
207
+ end
208
+ end
209
+
210
+ def strip_parens(expr)
211
+ return expr unless expr.start_with?("(") && expr.end_with?(")")
212
+
213
+ depth = 0
214
+ expr.each_char.with_index do |char, index|
215
+ depth += 1 if char == "("
216
+ depth -= 1 if char == ")"
217
+ return expr if depth.zero? && index < expr.length - 1
218
+ end
219
+ strip_parens(expr[1..-2].strip)
220
+ end
221
+
222
+ def split_top_level(expr, operator)
223
+ index = top_level_index(expr, operator)
224
+ return nil unless index
225
+
226
+ [expr[0...index].strip, expr[(index + operator.length)..].strip]
227
+ end
228
+
229
+ def split_comparison(expr, operator)
230
+ index = top_level_index(expr, operator) { |at| !part_of_longer?(expr, at, operator) }
231
+ return nil unless index
232
+
233
+ [expr[0...index].strip, expr[(index + operator.length)..].strip]
234
+ end
235
+
236
+ def part_of_longer?(expr, index, operator)
237
+ after = expr[index + operator.length]
238
+ before = index.positive? ? expr[index - 1] : nil
239
+
240
+ return true if after == "=" && !operator.end_with?("=")
241
+ return true if ["<", ">", "!", "="].include?(before) && operator.start_with?("=")
242
+
243
+ false
244
+ end
245
+
246
+ def top_level_index(expr, operator)
247
+ depth = 0
248
+ quote = nil
249
+ index = 0
250
+
251
+ while index < expr.length
252
+ char = expr[index]
253
+
254
+ if quote
255
+ quote = nil if char == quote
256
+ elsif ['"', "'"].include?(char)
257
+ quote = char
258
+ # `{`/`}` depth -- vendored addition, not (yet) upstream
259
+ # hecks (migration plan task 9): this method already
260
+ # treats `(`/`)` as a grouping construct so an operator
261
+ # INSIDE a call's parens is never mistaken for a top-level
262
+ # split point ; `{`/`}` needed the identical treatment the
263
+ # moment `Bluebook::Expression::Resolver` grew block-taking
264
+ # `.all?`/`.any?`/`.none? { |s| PREDICATE }` support (see
265
+ # resolver.rb's own `BlockPredicate` addition) -- without
266
+ # this, an operator INSIDE the block's own predicate (e.g.
267
+ # `s.length > 0`) reads as a top-level split of the WHOLE
268
+ # `value.split("::").all? { |s| s.length > 0 }` expression,
269
+ # confirmed live via `Lexicon::Lexicon.Lookup`/`Query::Query.
270
+ # Run` (the exact `Phrase` invariant this gap was found
271
+ # against) : the stray `>` split the expression in half
272
+ # before `Resolver.parse` ever saw the block as one atomic
273
+ # leaf, and the two halves then failed independently with
274
+ # the same raw `TypeError` the block-predicate fix was
275
+ # built to close. `{`/`}` cannot legitimately appear inside
276
+ # a quoted literal either, so this sits beside the existing
277
+ # paren-depth branch, not instead of it.
278
+ #
279
+ # `[`/`]` -- the identical lesson a THIRD time (found live via
280
+ # the type-directed bounded-exhaustive expression generator,
281
+ # Phase 7 of the equivalence-gap plan): `Resolver::ArrayLiteral`
282
+ # (`[a, b]`) can appear as a general sub-expression, not only
283
+ # as `.include?`'s own haystack, the moment an array-typed
284
+ # attribute or a synthesized literal is embedded anywhere else
285
+ # -- and an element containing a top-level `+`/comparison of
286
+ # its own (`[0, 0 + 0]`) used to read as a split point for
287
+ # THIS expression's own boolean/comparison grammar, exactly
288
+ # the way an un-tracked `{`/`}` once did for block predicates.
289
+ elsif char == "(" || char == "{" || char == "["
290
+ depth += 1
291
+ elsif char == ")" || char == "}" || char == "]"
292
+ depth -= 1
293
+ elsif depth.zero? && expr[index, operator.length] == operator
294
+ return index if !block_given? || yield(index)
295
+ end
296
+
297
+ index += 1
298
+ end
299
+ nil
300
+ end
301
+ end
302
+ end
303
+ end
304
+ end
@@ -0,0 +1,218 @@
1
+ {
2
+ "operators": [
3
+ {
4
+ "symbol": "||",
5
+ "category": "logical",
6
+ "precedence": 1,
7
+ "arity": 2
8
+ },
9
+ {
10
+ "symbol": "&&",
11
+ "category": "logical",
12
+ "precedence": 2,
13
+ "arity": 2
14
+ },
15
+ {
16
+ "symbol": ".include?",
17
+ "category": "membership",
18
+ "precedence": 3,
19
+ "arity": 2
20
+ },
21
+ {
22
+ "symbol": ">=",
23
+ "category": "comparison",
24
+ "precedence": 4,
25
+ "arity": 2,
26
+ "compares_less_than": true,
27
+ "compares_equal": false,
28
+ "negated": true
29
+ },
30
+ {
31
+ "symbol": "<=",
32
+ "category": "comparison",
33
+ "precedence": 4,
34
+ "arity": 2,
35
+ "compares_less_than": true,
36
+ "compares_equal": true,
37
+ "negated": false
38
+ },
39
+ {
40
+ "symbol": "<",
41
+ "category": "comparison",
42
+ "precedence": 4,
43
+ "arity": 2,
44
+ "compares_less_than": true,
45
+ "compares_equal": false,
46
+ "negated": false
47
+ },
48
+ {
49
+ "symbol": ">",
50
+ "category": "comparison",
51
+ "precedence": 4,
52
+ "arity": 2,
53
+ "compares_less_than": true,
54
+ "compares_equal": true,
55
+ "negated": true
56
+ },
57
+ {
58
+ "symbol": "==",
59
+ "category": "comparison",
60
+ "precedence": 4,
61
+ "arity": 2,
62
+ "compares_less_than": false,
63
+ "compares_equal": true,
64
+ "negated": false
65
+ },
66
+ {
67
+ "symbol": "!=",
68
+ "category": "comparison",
69
+ "precedence": 4,
70
+ "arity": 2,
71
+ "compares_less_than": false,
72
+ "compares_equal": true,
73
+ "negated": true
74
+ },
75
+ {
76
+ "symbol": "!",
77
+ "category": "logical",
78
+ "precedence": 5,
79
+ "arity": 1
80
+ },
81
+ {
82
+ "symbol": "+",
83
+ "category": "arithmetic",
84
+ "precedence": 6,
85
+ "arity": 2
86
+ },
87
+ {
88
+ "symbol": ".modulo",
89
+ "category": "arithmetic",
90
+ "precedence": 6,
91
+ "arity": 2
92
+ },
93
+ {
94
+ "symbol": ".positive?",
95
+ "category": "sign_test",
96
+ "precedence": 7,
97
+ "arity": 1
98
+ },
99
+ {
100
+ "symbol": ".negative?",
101
+ "category": "sign_test",
102
+ "precedence": 7,
103
+ "arity": 1
104
+ },
105
+ {
106
+ "symbol": ".zero?",
107
+ "category": "sign_test",
108
+ "precedence": 7,
109
+ "arity": 1
110
+ },
111
+ {
112
+ "symbol": ".empty?",
113
+ "category": "sized",
114
+ "precedence": 8,
115
+ "arity": 1
116
+ },
117
+ {
118
+ "symbol": ".to_s",
119
+ "category": "to_string",
120
+ "precedence": 9,
121
+ "arity": 1
122
+ },
123
+ {
124
+ "symbol": ".size",
125
+ "category": "sized",
126
+ "precedence": 8,
127
+ "arity": 1
128
+ },
129
+ {
130
+ "symbol": ".any?",
131
+ "category": "enumeration",
132
+ "precedence": 10,
133
+ "arity": 2
134
+ },
135
+ {
136
+ "symbol": ".none?",
137
+ "category": "enumeration",
138
+ "precedence": 10,
139
+ "arity": 2
140
+ },
141
+ {
142
+ "symbol": ".all?",
143
+ "category": "enumeration",
144
+ "precedence": 10,
145
+ "arity": 2
146
+ },
147
+ {
148
+ "symbol": ".find",
149
+ "category": "enumeration",
150
+ "precedence": 10,
151
+ "arity": 2
152
+ },
153
+ {
154
+ "symbol": ".match?",
155
+ "category": "pattern_match",
156
+ "precedence": 7,
157
+ "arity": 2
158
+ },
159
+ {
160
+ "symbol": ".present?",
161
+ "category": "presence",
162
+ "precedence": 7,
163
+ "arity": 1
164
+ },
165
+ {
166
+ "symbol": ".blank?",
167
+ "category": "presence",
168
+ "precedence": 7,
169
+ "arity": 1
170
+ },
171
+ {
172
+ "symbol": ".split",
173
+ "category": "text",
174
+ "precedence": 7,
175
+ "arity": 2
176
+ },
177
+ {
178
+ "symbol": ".start_with?",
179
+ "category": "text",
180
+ "precedence": 7,
181
+ "arity": 2
182
+ },
183
+ {
184
+ "symbol": ".end_with?",
185
+ "category": "text",
186
+ "precedence": 7,
187
+ "arity": 2
188
+ },
189
+ {
190
+ "symbol": ".first",
191
+ "category": "positional",
192
+ "precedence": 7,
193
+ "arity": 1
194
+ },
195
+ {
196
+ "symbol": ".last",
197
+ "category": "positional",
198
+ "precedence": 7,
199
+ "arity": 1
200
+ }
201
+ ],
202
+ "normalisations": [
203
+ {
204
+ "strategy": "collapse_whitespace",
205
+ "source_token": "",
206
+ "replacement": "",
207
+ "boundary": "none",
208
+ "position": 1
209
+ },
210
+ {
211
+ "strategy": "replace",
212
+ "source_token": ".length",
213
+ "replacement": ".size",
214
+ "boundary": "word",
215
+ "position": 2
216
+ }
217
+ ]
218
+ }