hecks 2.9.0 → 3.0.1

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 (600) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +51 -6
  3. data/lib/hecks/adapters/driven/heki/journal.rb +1 -1
  4. data/lib/hecks/adapters/driven/lambda/client.rb +1 -1
  5. data/lib/hecks/adapters/driven/lambda.rb +1 -1
  6. data/lib/hecks/adapters/driven/memory.rb +16 -3
  7. data/lib/hecks/adapters/driven/postgres/reconnect.rb +6 -2
  8. data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
  9. data/lib/hecks/adapters/driven/postgres.rb +13 -4
  10. data/lib/hecks/adapters/driven/prism.rb +41 -8
  11. data/lib/hecks/adapters/driven/tenant_provisioner.rb +73 -16
  12. data/lib/hecks/behaviors/expectations.rb +1 -1
  13. data/lib/hecks/behaviors.rb +1 -1
  14. data/lib/hecks/bench/cli.rb +62 -0
  15. data/lib/hecks/bench/environment.rb +71 -0
  16. data/lib/hecks/bench/postgres_probe.rb +30 -0
  17. data/lib/hecks/bench/report.rb +76 -0
  18. data/lib/hecks/bench/ruby_runner.rb +93 -0
  19. data/lib/hecks/bench/run.rb +55 -0
  20. data/lib/hecks/bench/rust_runner.rb +101 -0
  21. data/lib/hecks/bench/stats.rb +46 -0
  22. data/lib/hecks/bench/suite.rb +98 -0
  23. data/lib/hecks/bench/workload.rb +89 -0
  24. data/lib/hecks/bench.rb +17 -0
  25. data/lib/hecks/bluebook/assembly/contracts.rb +2 -0
  26. data/lib/hecks/bluebook/attribute.rb +1 -1
  27. data/lib/hecks/bluebook/behaviour/aggregate.rb +30 -1
  28. data/lib/hecks/bluebook/behaviour/domain_port.rb +7 -0
  29. data/lib/hecks/bluebook/chapter.rb +6 -2
  30. data/lib/hecks/bluebook/domain_port.rb +36 -5
  31. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +10 -0
  32. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +8 -0
  33. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -1
  34. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +31 -3
  35. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +122 -3
  36. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +1 -1
  37. data/lib/hecks/bluebook/dsl/query_builder.rb +27 -1
  38. data/lib/hecks/bluebook/dsl/rule_reference.rb +1 -1
  39. data/lib/hecks/bluebook/dsl/world_builder.rb +29 -2
  40. data/lib/hecks/bluebook/expression/canonical_form.rb +1 -1
  41. data/lib/hecks/bluebook/expression/resolver.rb +3 -2
  42. data/lib/hecks/bluebook/hexagon.rb +13 -5
  43. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +1 -0
  44. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +4 -1
  45. data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
  46. data/lib/hecks/bluebook/meta_validator.rb +9 -4
  47. data/lib/hecks/bluebook/model_check.rb +23 -0
  48. data/lib/hecks/bluebook/pattern_subset.rb +38 -0
  49. data/lib/hecks/bluebook/query.rb +20 -5
  50. data/lib/hecks/bluebook/smoke_test.rb +1 -1
  51. data/lib/hecks/canonical_json.rb +30 -0
  52. data/lib/hecks/chapters.rb +102 -0
  53. data/lib/hecks/cli/behaviors.rb +61 -0
  54. data/lib/hecks/cli/canonicalise.rb +25 -0
  55. data/lib/hecks/cli/check_engine_agreement.rb +32 -0
  56. data/lib/hecks/cli/check_era.rb +88 -0
  57. data/lib/hecks/cli/console.rb +66 -0
  58. data/lib/hecks/cli/deploy_template_diff.rb +40 -0
  59. data/lib/hecks/cli/doc_coverage.rb +32 -0
  60. data/lib/hecks/cli/document.rb +2 -2
  61. data/lib/hecks/cli/expression_projection.rb +41 -0
  62. data/lib/hecks/cli/follow.rb +88 -0
  63. data/lib/hecks/cli/history.rb +44 -0
  64. data/lib/hecks/cli/ir.rb +1 -1
  65. data/lib/hecks/cli/mcp.rb +3 -3
  66. data/lib/hecks/cli/model_check.rb +15 -8
  67. data/lib/hecks/cli/pattern_cases.rb +47 -0
  68. data/lib/hecks/cli/present.rb +39 -0
  69. data/lib/hecks/cli/project_cli.rb +224 -32
  70. data/lib/hecks/cli/project_diagrams.rb +4 -3
  71. data/lib/hecks/cli/project_glossary.rb +44 -0
  72. data/lib/hecks/cli/reference.rb +46 -0
  73. data/lib/hecks/cli/refresh_projections.rb +44 -0
  74. data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +150 -0
  75. data/lib/hecks/cli/release.rb +70 -0
  76. data/lib/hecks/cli/release_gem.rb +59 -0
  77. data/lib/hecks/cli/rspec_io_parallel_files.rb +137 -0
  78. data/lib/hecks/cli/rspec_shard_files.rb +66 -0
  79. data/lib/hecks/cli/run.rb +3 -3
  80. data/lib/hecks/cli/seed_semantics_corpus.rb +71 -0
  81. data/lib/hecks/cli/serve_query_ir_mcp.rb +30 -0
  82. data/lib/hecks/cli/shape.rb +70 -0
  83. data/lib/hecks/cli/smoke_http.rb +230 -0
  84. data/lib/hecks/cli/smoke_test.rb +5 -3
  85. data/lib/hecks/cli/spec_example.rb +27 -0
  86. data/lib/hecks/cli/statements.rb +32 -0
  87. data/lib/hecks/cli/stores.rb +4 -5
  88. data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
  89. data/lib/hecks/cli.rb +201 -52
  90. data/lib/hecks/codemod.rb +324 -0
  91. data/lib/hecks/corpus.rb +423 -0
  92. data/lib/hecks/deploy/bluebook/deploy.bluebook +591 -23
  93. data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -4
  94. data/lib/hecks/deploy/oidc.json +82 -2
  95. data/lib/hecks/doc/reference.rb +351 -0
  96. data/lib/hecks/doors/cli_door.rb +196 -0
  97. data/lib/hecks/doors/cli_runner.rb +297 -0
  98. data/lib/hecks/{facade → doors}/command_request.rb +1 -1
  99. data/lib/hecks/{facade → doors}/handle.rb +2 -2
  100. data/lib/hecks/{facade → doors}/json_door.rb +4 -4
  101. data/lib/hecks/doors/launcher_options.rb +129 -0
  102. data/lib/hecks/{cli → doors}/mcp_door.rb +7 -7
  103. data/lib/hecks/doors/mcp_door_scope.rb +97 -0
  104. data/lib/hecks/{facade/surface → doors/ruby_door}/aggregate_door.rb +8 -3
  105. data/lib/hecks/{facade/surface → doors/ruby_door}/chapter.rb +3 -3
  106. data/lib/hecks/{facade/surface.rb → doors/ruby_door.rb} +36 -5
  107. data/lib/hecks/doors.rb +61 -0
  108. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +1 -1
  109. data/lib/hecks/embryonaut_bluebook.rb +1 -1
  110. data/lib/hecks/engine_agreement.rb +156 -0
  111. data/lib/hecks/facade.rb +24 -37
  112. data/lib/hecks/forms/app.rb +6 -6
  113. data/lib/hecks/forms/banking_presentation.rb +50 -0
  114. data/lib/hecks/forms/field_shape.rb +2 -1
  115. data/lib/hecks/forms/port_argument.rb +1 -1
  116. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +393 -0
  117. data/lib/hecks/fuzzing/combination_miner.rb +86 -0
  118. data/lib/hecks/fuzzing/concurrent_dispatch.rb +214 -0
  119. data/lib/hecks/fuzzing/coverage_campaign.rb +143 -0
  120. data/lib/hecks/fuzzing/differential.rb +156 -0
  121. data/lib/hecks/fuzzing/domain_generator.rb +615 -0
  122. data/lib/hecks/fuzzing/era_boundary.rb +71 -0
  123. data/lib/hecks/fuzzing/form_census.rb +136 -0
  124. data/lib/hecks/fuzzing/generated_domain_check.rb +93 -0
  125. data/lib/hecks/fuzzing/invalid_value_generator.rb +64 -0
  126. data/lib/hecks/fuzzing/isolated_boot.rb +301 -0
  127. data/lib/hecks/fuzzing/nondeterministic.rb +51 -0
  128. data/lib/hecks/fuzzing/outside_world.rb +45 -0
  129. data/lib/hecks/fuzzing/persistence_parity.rb +102 -0
  130. data/lib/hecks/fuzzing/properties/corrections.rb +88 -0
  131. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +314 -0
  132. data/lib/hecks/fuzzing/properties/guards.rb +190 -0
  133. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +300 -0
  134. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +93 -0
  135. data/lib/hecks/fuzzing/properties/outbox.rb +89 -0
  136. data/lib/hecks/fuzzing/properties/querying.rb +175 -0
  137. data/lib/hecks/fuzzing/properties.rb +162 -0
  138. data/lib/hecks/fuzzing/qa_settings.rb +123 -0
  139. data/lib/hecks/fuzzing/replay.rb +505 -0
  140. data/lib/hecks/fuzzing/rotation_priority.rb +48 -0
  141. data/lib/hecks/fuzzing/rust_gap_manifest.rb +108 -0
  142. data/lib/hecks/fuzzing/self_consistency.rb +339 -0
  143. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +385 -0
  144. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +132 -0
  145. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +95 -0
  146. data/lib/hecks/fuzzing/sequence_generator/picker.rb +77 -0
  147. data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +109 -0
  148. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +237 -0
  149. data/lib/hecks/fuzzing/sequence_generator.rb +189 -0
  150. data/lib/hecks/fuzzing/shrinker.rb +166 -0
  151. data/lib/hecks/fuzzing/structural_skips.rb +33 -0
  152. data/lib/hecks/fuzzing/sweep_depth.rb +43 -0
  153. data/lib/hecks/fuzzing/target_capabilities.rb +163 -0
  154. data/lib/hecks/fuzzing/value_generator.rb +216 -0
  155. data/lib/hecks/fuzzing.rb +23 -0
  156. data/lib/hecks/grammar/evolve.rb +336 -0
  157. data/lib/hecks/hecks/adapters/codebase/codemods.rb +45 -0
  158. data/lib/hecks/hecks/adapters/codebase/conformance.rb +71 -0
  159. data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +202 -0
  160. data/lib/hecks/hecks/adapters/codebase/gem_registry.rb +80 -0
  161. data/lib/hecks/hecks/adapters/codebase/kernel_tables.rb +54 -0
  162. data/lib/hecks/hecks/adapters/codebase/language.rb +240 -0
  163. data/lib/hecks/hecks/adapters/codebase/npm_registry.rb +102 -0
  164. data/lib/hecks/hecks/adapters/codebase/publishing.rb +142 -0
  165. data/lib/hecks/hecks/adapters/codebase/regeneration.rb +67 -0
  166. data/lib/hecks/hecks/adapters/codebase/release_facts.rb +90 -0
  167. data/lib/hecks/hecks/adapters/codebase/ruby_child.rb +83 -0
  168. data/lib/hecks/hecks/adapters/codebase/secret_vault.rb +36 -0
  169. data/lib/hecks/hecks/adapters/codebase/source_tree.adapter +7 -0
  170. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +189 -0
  171. data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +71 -0
  172. data/lib/hecks/hecks/adapters/codebase/style.rb +171 -0
  173. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +55 -0
  174. data/lib/hecks/hecks/adapters/codebase/test_suite.rb +165 -0
  175. data/lib/hecks/hecks/adapters/codebase/tree.rb +111 -0
  176. data/lib/hecks/hecks/adapters/console_capture.rb +79 -0
  177. data/lib/hecks/hecks/adapters/deploy_toolchain.adapter +7 -0
  178. data/lib/hecks/hecks/adapters/deploy_toolchain.rb +108 -0
  179. data/lib/hecks/hecks/adapters/git.adapter +7 -0
  180. data/lib/hecks/hecks/adapters/git.rb +102 -0
  181. data/lib/hecks/hecks/adapters/host_http.adapter +7 -0
  182. data/lib/hecks/hecks/adapters/host_http.rb +65 -0
  183. data/lib/hecks/hecks/adapters/in_process_boot.adapter +7 -0
  184. data/lib/hecks/hecks/adapters/in_process_boot.rb +197 -0
  185. data/lib/hecks/hecks/adapters/in_process_operations.rb +202 -0
  186. data/lib/hecks/hecks/adapters/journal_store/changes.rb +143 -0
  187. data/lib/hecks/hecks/adapters/journal_store/compaction.rb +145 -0
  188. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +132 -0
  189. data/lib/hecks/hecks/adapters/journal_store/examination.rb +135 -0
  190. data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +163 -0
  191. data/lib/hecks/hecks/adapters/journal_store/readings.rb +187 -0
  192. data/lib/hecks/hecks/adapters/journal_store.adapter +7 -0
  193. data/lib/hecks/hecks/adapters/journal_store.rb +64 -0
  194. data/lib/hecks/hecks/adapters/local_files.adapter +7 -0
  195. data/lib/hecks/hecks/adapters/local_files.rb +46 -0
  196. data/lib/hecks/hecks/adapters/pg_admin.adapter +7 -0
  197. data/lib/hecks/hecks/adapters/pg_admin.rb +245 -0
  198. data/lib/hecks/hecks/adapters/process_pool.adapter +7 -0
  199. data/lib/hecks/hecks/adapters/process_pool.rb +119 -0
  200. data/lib/hecks/hecks/adapters/rust_toolchain.adapter +7 -0
  201. data/lib/hecks/hecks/adapters/rust_toolchain.rb +179 -0
  202. data/lib/hecks/hecks/adapters/rust_workspace.rb +150 -0
  203. data/lib/hecks/hecks/adapters/shell.adapter +7 -0
  204. data/lib/hecks/hecks/adapters/shell.rb +49 -0
  205. data/lib/hecks/hecks/adapters/terminal.adapter +7 -0
  206. data/lib/hecks/hecks/adapters/terminal.rb +74 -0
  207. data/lib/hecks/hecks/codebase.behaviors +172 -0
  208. data/lib/hecks/hecks/codebase.bluebook +2453 -0
  209. data/lib/hecks/hecks/context_map.hecksagon +13 -0
  210. data/lib/hecks/hecks/custodian.behaviors +179 -0
  211. data/lib/hecks/hecks/custodian.bluebook +1847 -0
  212. data/lib/hecks/hecks/deploy.behaviors +74 -0
  213. data/lib/hecks/hecks/deploy.world +12 -0
  214. data/lib/hecks/hecks/environments/memory.world +10 -0
  215. data/lib/hecks/hecks/governance.world +7 -0
  216. data/lib/hecks/hecks/hecks.behaviors +62 -0
  217. data/lib/hecks/hecks/hecks.bluebook +124 -0
  218. data/lib/hecks/hecks/hecks.hecksagon +390 -0
  219. data/lib/hecks/hecks/hecks.world +42 -0
  220. data/lib/hecks/kernel_capabilities.rb +194 -0
  221. data/lib/hecks/language/bluebook/bluebook.bluebook +11 -0
  222. data/lib/hecks/language/bluebook/query.bluebook +7 -0
  223. data/lib/hecks/language/bluebook/vocabulary.bluebook +4 -4
  224. data/lib/hecks/language/hecksagon/domain_port.bluebook +10 -0
  225. data/lib/hecks/language/hecksagon/hecksagon.bluebook +20 -0
  226. data/lib/hecks/mcp_stdio_guard.rb +2 -2
  227. data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
  228. data/lib/hecks/persistence_legacy_fixture.rb +113 -0
  229. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +8 -5
  230. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +4 -1
  231. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +15 -2
  232. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +1 -1
  233. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +1 -1
  234. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +1 -1
  235. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +32 -15
  236. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +15 -5
  237. data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +227 -0
  238. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +1 -1
  239. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +43 -24
  240. data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
  241. data/lib/hecks/ports/persistence/state_codec.rb +24 -5
  242. data/lib/hecks/projection_files.rb +285 -0
  243. data/lib/hecks/projections/bootstrap_table.rb +1 -1
  244. data/lib/hecks/projections/deploy/fargate.rb +5 -5
  245. data/lib/hecks/projections/deploy/lambda.rb +43 -32
  246. data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
  247. data/lib/hecks/projections/deploy/preview/template.rb +1 -1
  248. data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +1 -1
  249. data/lib/hecks/projections/deploy/scripts/expected-era.header +1 -1
  250. data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +3 -3
  251. data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
  252. data/lib/hecks/projections/deploy/shared.rb +1 -1
  253. data/lib/hecks/projections/diagrams.rb +3 -3
  254. data/lib/hecks/projections/model/deviations.rb +1 -1
  255. data/lib/hecks/projections/parser_table.rb +4 -4
  256. data/lib/hecks/projections/reference.rb +2 -3
  257. data/lib/hecks/projections/rust_vocabulary.rb +1 -1
  258. data/lib/hecks/projector/cli_projector.rb +106 -37
  259. data/lib/hecks/projector.rb +1 -1
  260. data/lib/hecks/quality_control/adapters/agent.adapter +7 -0
  261. data/lib/hecks/quality_control/adapters/agent.rb +58 -0
  262. data/lib/hecks/quality_control/adapters/angle_tools.adapter +7 -0
  263. data/lib/hecks/quality_control/adapters/angle_tools.rb +15 -0
  264. data/lib/hecks/quality_control/adapters/clearance_recorder.rb +36 -0
  265. data/lib/hecks/quality_control/adapters/clearance_tools.adapter +7 -0
  266. data/lib/hecks/quality_control/adapters/clearance_tools.rb +17 -0
  267. data/lib/hecks/quality_control/adapters/git_pr.adapter +7 -0
  268. data/lib/hecks/quality_control/adapters/git_pr.rb +226 -0
  269. data/lib/hecks/quality_control/adapters/github_checks.adapter +9 -0
  270. data/lib/hecks/quality_control/adapters/github_checks.rb +83 -0
  271. data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +56 -0
  272. data/lib/hecks/quality_control/adapters/github_issues.adapter +7 -0
  273. data/lib/hecks/quality_control/adapters/github_issues.rb +49 -0
  274. data/lib/hecks/quality_control/adapters/qa_tool.rb +59 -0
  275. data/lib/hecks/quality_control/adapters/sweep_tools.adapter +7 -0
  276. data/lib/hecks/quality_control/adapters/sweep_tools.rb +51 -0
  277. data/lib/hecks/quality_control/adapters/target_tools.adapter +7 -0
  278. data/lib/hecks/quality_control/adapters/target_tools.rb +43 -0
  279. data/lib/hecks/quality_control/cli/child.rb +45 -0
  280. data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +45 -0
  281. data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +248 -0
  282. data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +163 -0
  283. data/lib/hecks/quality_control/cli/qa_generated_domains.rb +450 -0
  284. data/lib/hecks/quality_control/cli/qa_log_bug.rb +195 -0
  285. data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +220 -0
  286. data/lib/hecks/quality_control/cli/qa_open_pr.rb +305 -0
  287. data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +154 -0
  288. data/lib/hecks/quality_control/cli/qa_postgres_role.rb +159 -0
  289. data/lib/hecks/quality_control/cli/qa_pr_check.rb +232 -0
  290. data/lib/hecks/quality_control/cli/qa_seed_angles.rb +142 -0
  291. data/lib/hecks/quality_control/cli/qa_seed_targets.rb +69 -0
  292. data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +280 -0
  293. data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +329 -0
  294. data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +92 -0
  295. data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +117 -0
  296. data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +175 -0
  297. data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +60 -0
  298. data/lib/hecks/quality_control/cli/qa_sweep.rb +611 -0
  299. data/lib/hecks/quality_control/cli/qa_tick.rb +274 -0
  300. data/lib/hecks/quality_control/quality_control.bluebook +2224 -0
  301. data/lib/hecks/quality_control/quality_control.hecksagon +13 -0
  302. data/lib/hecks/quality_control/quality_control.ports.hecksagon +54 -0
  303. data/lib/hecks/query_ir.rb +346 -0
  304. data/lib/hecks/query_ir_mcp.rb +198 -0
  305. data/lib/hecks/release/runner/ci_publisher.rb +2 -2
  306. data/lib/hecks/release/runner/clean_tree.rb +42 -0
  307. data/lib/hecks/release/runner/console.rb +6 -0
  308. data/lib/hecks/release/runner/gem_publisher.rb +14 -7
  309. data/lib/hecks/release/runner/npm_publisher.rb +6 -36
  310. data/lib/hecks/release/runner/preflight.rb +26 -2
  311. data/lib/hecks/release/runner/published.rb +8 -26
  312. data/lib/hecks/release/runner/tagger.rb +30 -15
  313. data/lib/hecks/release/runner.rb +57 -6
  314. data/lib/hecks/router/namespace_installer.rb +3 -3
  315. data/lib/hecks/runtime/adapter_lookup.rb +124 -0
  316. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +4 -0
  317. data/lib/hecks/runtime/dependency_planning.rb +20 -2
  318. data/lib/hecks/runtime/dispatcher.rb +53 -3
  319. data/lib/hecks/runtime/interpreting.rb +3 -0
  320. data/lib/hecks/runtime/loader.rb +65 -12
  321. data/lib/hecks/runtime/outbox.rb +1 -1
  322. data/lib/hecks/runtime/policy_interpreter.rb +5 -2
  323. data/lib/hecks/runtime/port_operation_interpreter.rb +2 -10
  324. data/lib/hecks/runtime/query_interpreter.rb +77 -0
  325. data/lib/hecks/runtime/reaction_outcome.rb +89 -0
  326. data/lib/hecks/runtime/refusal_wording.rb +23 -1
  327. data/lib/hecks/runtime/registry/verification.rb +163 -4
  328. data/lib/hecks/runtime/registry.rb +57 -3
  329. data/lib/hecks/runtime/remote_dispatcher.rb +31 -2
  330. data/lib/hecks/runtime/value/coercion.rb +23 -135
  331. data/lib/hecks/runtime/value/field_checks.rb +172 -0
  332. data/lib/hecks/runtime/value.rb +4 -1
  333. data/lib/hecks/runtime.rb +20 -6
  334. data/lib/hecks/rust_build/conformance.rb +158 -0
  335. data/lib/hecks/rust_build/conformance_fuzz.rb +71 -0
  336. data/lib/hecks/rust_build/coverage.rb +218 -0
  337. data/lib/hecks/rust_build/native_build.rb +124 -0
  338. data/lib/hecks/rust_build/project_rust/root_mod.rb +120 -0
  339. data/lib/hecks/rust_build/project_rust.rb +332 -0
  340. data/lib/hecks/rust_build/wasm.rb +105 -0
  341. data/lib/hecks/rust_build/wasm_browser.rb +113 -0
  342. data/lib/hecks/rust_build.rb +144 -0
  343. data/lib/hecks/storehouse.rb +16 -16
  344. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +2 -2
  345. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +1 -1
  346. data/lib/hecks/three_zero/forms.yml +127 -0
  347. data/lib/hecks/three_zero.rb +12 -0
  348. data/lib/hecks/tools/argument_gate_matrix.rb +316 -0
  349. data/lib/hecks/tools/comment_style.rb +1070 -0
  350. data/lib/hecks/tools/corpus_report.rb +87 -0
  351. data/lib/hecks/tools/deploy_recipe.rb +255 -0
  352. data/lib/hecks/tools/deploy_recipe_lint.rb +282 -0
  353. data/lib/hecks/tools/drop_implicit_append_fields.rb +95 -0
  354. data/lib/hecks/tools/era_projection_backfill.rb +94 -0
  355. data/lib/hecks/tools/era_reattest.rb +146 -0
  356. data/lib/hecks/tools/evolve_run.rb +189 -0
  357. data/lib/hecks/tools/fuzz_sweep.rb +373 -0
  358. data/lib/hecks/tools/heki_compaction.rb +100 -0
  359. data/lib/hecks/tools/hoist_local_givens.rb +246 -0
  360. data/lib/hecks/tools/journal_compaction.rb +89 -0
  361. data/lib/hecks/tools/oidc_manifests.rb +70 -0
  362. data/lib/hecks/tools/query_ir_run.rb +81 -0
  363. data/lib/hecks/tools/regeneration_run.rb +166 -0
  364. data/lib/hecks/tools/rust_comment_style.rb +642 -0
  365. data/lib/hecks/tools/sequence_script.rb +62 -0
  366. data/lib/hecks/tools/tail_merge.rb +117 -0
  367. data/lib/hecks/tools/tenant_provisioning.rb +142 -0
  368. data/lib/hecks/tools/translation_audit.rb +208 -0
  369. data/lib/hecks/tools/translation_scaffold.rb +131 -0
  370. data/lib/hecks/tools.rb +86 -0
  371. data/lib/hecks/version.rb +1 -1
  372. data/lib/hecks.rb +32 -15
  373. data/qa/settings.yml +66 -0
  374. data/rust/.cargo/config.toml +6 -0
  375. data/rust/.gitignore +2 -0
  376. data/rust/Cargo.lock +54 -0
  377. data/rust/Cargo.toml +61 -0
  378. data/rust/build/.cargo/config.toml +3 -0
  379. data/rust/build/.gitignore +1 -0
  380. data/rust/build/Cargo.lock +7 -0
  381. data/rust/build/Cargo.toml +19 -0
  382. data/rust/build/src/build_artifact.rs +47 -0
  383. data/rust/build/src/cargo_sync.rs +248 -0
  384. data/rust/build/src/json.rs +421 -0
  385. data/rust/build/src/lineage_pass.rs +285 -0
  386. data/rust/build/src/main.rs +51 -0
  387. data/rust/build/src/optional_pass.rs +150 -0
  388. data/rust/build/src/pipeline.rs +264 -0
  389. data/rust/build/src/reserved_names.rs +76 -0
  390. data/rust/build/src/resolve.rs +124 -0
  391. data/rust/build/src/root.rs +25 -0
  392. data/rust/build/src/sidecars.rs +73 -0
  393. data/rust/build/src/subprocess.rs +51 -0
  394. data/rust/build/src/tmp.rs +31 -0
  395. data/rust/codegen/.cargo/config.toml +3 -0
  396. data/rust/codegen/.gitignore +1 -0
  397. data/rust/codegen/Cargo.lock +7 -0
  398. data/rust/codegen/Cargo.toml +20 -0
  399. data/rust/codegen/src/attr.rs +32 -0
  400. data/rust/codegen/src/bridging.rs +481 -0
  401. data/rust/codegen/src/commands.rs +1226 -0
  402. data/rust/codegen/src/constraints.rs +109 -0
  403. data/rust/codegen/src/dependency_planning.rs +209 -0
  404. data/rust/codegen/src/domain_generator.rs +1288 -0
  405. data/rust/codegen/src/exemplar.rs +230 -0
  406. data/rust/codegen/src/expr_emitter.rs +87 -0
  407. data/rust/codegen/src/fielded.rs +192 -0
  408. data/rust/codegen/src/hecks_naming.rs +33 -0
  409. data/rust/codegen/src/json.rs +335 -0
  410. data/rust/codegen/src/json_codec.rs +697 -0
  411. data/rust/codegen/src/literal.rs +207 -0
  412. data/rust/codegen/src/main.rs +290 -0
  413. data/rust/codegen/src/manifest.rs +227 -0
  414. data/rust/codegen/src/mutations.rs +784 -0
  415. data/rust/codegen/src/naming.rs +286 -0
  416. data/rust/codegen/src/ports.rs +208 -0
  417. data/rust/codegen/src/prelude.rs +116 -0
  418. data/rust/codegen/src/queries.rs +786 -0
  419. data/rust/codegen/src/reactions.rs +532 -0
  420. data/rust/codegen/src/read_models.rs +697 -0
  421. data/rust/codegen/src/reference_specs.rs +40 -0
  422. data/rust/codegen/src/registry.rs +966 -0
  423. data/rust/codegen/src/reserved_names.rs +76 -0
  424. data/rust/codegen/src/shared.rs +93 -0
  425. data/rust/codegen/src/skip_reason.rs +25 -0
  426. data/rust/codegen/src/types.rs +362 -0
  427. data/rust/host/.cargo/config.toml +3 -0
  428. data/rust/host/.gitignore +1 -0
  429. data/rust/host/Cargo.lock +4297 -0
  430. data/rust/host/Cargo.toml +61 -0
  431. data/rust/host/HECKS_RELEASE +1 -0
  432. data/rust/host/rds-ca-bundle.pem +2736 -0
  433. data/rust/host/src/api.rs +1596 -0
  434. data/rust/host/src/approval.rs +652 -0
  435. data/rust/host/src/auth.rs +1287 -0
  436. data/rust/host/src/bin/expr_harness.rs +46 -0
  437. data/rust/host/src/bin/lineage_harness.rs +119 -0
  438. data/rust/host/src/bin/mint_harness.rs +135 -0
  439. data/rust/host/src/checkout.rs +265 -0
  440. data/rust/host/src/dispatch.rs +1443 -0
  441. data/rust/host/src/expr_json.rs +1117 -0
  442. data/rust/host/src/field_hints.rs +52 -0
  443. data/rust/host/src/ir.rs +733 -0
  444. data/rust/host/src/journal.rs +874 -0
  445. data/rust/host/src/lambda_client.rs +378 -0
  446. data/rust/host/src/log.rs +147 -0
  447. data/rust/host/src/main.rs +474 -0
  448. data/rust/host/src/mint.rs +1865 -0
  449. data/rust/host/src/payments/keystore.rs +330 -0
  450. data/rust/host/src/payments/tests.rs +1400 -0
  451. data/rust/host/src/payments.rs +767 -0
  452. data/rust/host/src/presentation.rs +698 -0
  453. data/rust/host/src/presentation_write.rs +1431 -0
  454. data/rust/host/src/query_step.rs +149 -0
  455. data/rust/host/src/rate_limit.rs +904 -0
  456. data/rust/host/src/reference_transform.rs +241 -0
  457. data/rust/host/src/reference_validate.rs +338 -0
  458. data/rust/host/src/resend.rs +296 -0
  459. data/rust/host/src/secrets.rs +106 -0
  460. data/rust/host/src/server.rs +663 -0
  461. data/rust/host/src/storage_shape.rs +175 -0
  462. data/rust/host/src/test_pg.rs +40 -0
  463. data/rust/host/src/ui_schema.rs +1351 -0
  464. data/rust/host/src/wasm_runner.rs +191 -0
  465. data/rust/host/src/web/newsletter/cooldown.rs +126 -0
  466. data/rust/host/src/web/newsletter/tests.rs +104 -0
  467. data/rust/host/src/web/newsletter.rs +310 -0
  468. data/rust/host/src/web/newsletter_send.rs +357 -0
  469. data/rust/host/src/web/registrations.rs +1505 -0
  470. data/rust/host/src/web.rs +2937 -0
  471. data/rust/lsp/.gitignore +1 -0
  472. data/rust/lsp/Cargo.lock +7 -0
  473. data/rust/lsp/Cargo.toml +16 -0
  474. data/rust/lsp/README.md +133 -0
  475. data/rust/lsp/src/diagnostics.rs +165 -0
  476. data/rust/lsp/src/json.rs +385 -0
  477. data/rust/lsp/src/main.rs +399 -0
  478. data/rust/lsp/src/outline.rs +177 -0
  479. data/rust/lsp/src/rpc.rs +67 -0
  480. data/rust/parser/.cargo/config.toml +5 -0
  481. data/rust/parser/.gitignore +1 -0
  482. data/rust/parser/Cargo.lock +7 -0
  483. data/rust/parser/Cargo.toml +21 -0
  484. data/rust/parser/src/build/closed_sets.rs +27 -0
  485. data/rust/parser/src/build/identity.rs +276 -0
  486. data/rust/parser/src/build/mod.rs +12 -0
  487. data/rust/parser/src/build/naming.rs +141 -0
  488. data/rust/parser/src/build/pattern_subset.rs +161 -0
  489. data/rust/parser/src/build/query_derive.rs +72 -0
  490. data/rust/parser/src/build/query_inference.rs +269 -0
  491. data/rust/parser/src/build/query_options.rs +100 -0
  492. data/rust/parser/src/build/read_model.rs +94 -0
  493. data/rust/parser/src/build/references.rs +32 -0
  494. data/rust/parser/src/canonical.rs +114 -0
  495. data/rust/parser/src/diag.rs +55 -0
  496. data/rust/parser/src/emit.rs +953 -0
  497. data/rust/parser/src/expr/ast_json.rs +147 -0
  498. data/rust/parser/src/expr/evaluator.rs +81 -0
  499. data/rust/parser/src/expr/mod.rs +84 -0
  500. data/rust/parser/src/expr/resolver.rs +497 -0
  501. data/rust/parser/src/ir.rs +387 -0
  502. data/rust/parser/src/keywords.rs +585 -0
  503. data/rust/parser/src/lex.rs +662 -0
  504. data/rust/parser/src/main.rs +252 -0
  505. data/rust/parser/src/parse/aggregate.rs +612 -0
  506. data/rust/parser/src/parse/chapter.rs +517 -0
  507. data/rust/parser/src/parse/command.rs +637 -0
  508. data/rust/parser/src/parse/domain_port.rs +127 -0
  509. data/rust/parser/src/parse/entity.rs +527 -0
  510. data/rust/parser/src/parse/file.rs +67 -0
  511. data/rust/parser/src/parse/hecksagon.rs +231 -0
  512. data/rust/parser/src/parse/lifecycle.rs +162 -0
  513. data/rust/parser/src/parse/mod.rs +1262 -0
  514. data/rust/parser/src/parse/policy.rs +87 -0
  515. data/rust/parser/src/parse/process_manager.rs +305 -0
  516. data/rust/parser/src/parse/query.rs +100 -0
  517. data/rust/parser/src/parse/read_model.rs +214 -0
  518. data/rust/parser/src/parse/value_object.rs +250 -0
  519. data/rust/parser/src/ruby_value.rs +422 -0
  520. data/rust/project/bridging.rb +257 -0
  521. data/rust/project/commands.rb +877 -0
  522. data/rust/project/constraints.rb +86 -0
  523. data/rust/project/dependency_planning.rb +178 -0
  524. data/rust/project/domain_generator.rb +980 -0
  525. data/rust/project/exemplar.rb +148 -0
  526. data/rust/project/expr_emitter.rb +72 -0
  527. data/rust/project/fielded.rb +141 -0
  528. data/rust/project/json_codec.rb +641 -0
  529. data/rust/project/mutations.rb +721 -0
  530. data/rust/project/naming.rb +205 -0
  531. data/rust/project/ports.rb +65 -0
  532. data/rust/project/queries.rb +493 -0
  533. data/rust/project/reactions.rb +317 -0
  534. data/rust/project/read_models.rb +690 -0
  535. data/rust/project/reference_specs.rb +27 -0
  536. data/rust/project/registry.rb +396 -0
  537. data/rust/project/skip_reason.rb +29 -0
  538. data/rust/project/types.rb +225 -0
  539. data/rust/project/write_if_changed.rb +83 -0
  540. data/rust/project.rb +30 -0
  541. data/rust/project_rust_pipeline.rb +383 -0
  542. data/rust/src/exemplar/commands.rs +279 -0
  543. data/rust/src/exemplar/constraints.rs +18 -0
  544. data/rust/src/exemplar/fielded.rs +280 -0
  545. data/rust/src/exemplar/json.rs +277 -0
  546. data/rust/src/exemplar/mod.rs +17 -0
  547. data/rust/src/exemplar/mutations.rs +80 -0
  548. data/rust/src/exemplar/queries.rs +33 -0
  549. data/rust/src/exemplar/reactions.rs +88 -0
  550. data/rust/src/exemplar/read_models.rs +48 -0
  551. data/rust/src/exemplar/registry.rs +166 -0
  552. data/rust/src/exemplar/types.rs +44 -0
  553. data/rust/src/kernel/attribute_shapes/composite.rs +88 -0
  554. data/rust/src/kernel/attribute_shapes/list.rs +18 -0
  555. data/rust/src/kernel/attribute_shapes/mod.rs +44 -0
  556. data/rust/src/kernel/attribute_shapes/optional.rs +9 -0
  557. data/rust/src/kernel/attribute_shapes/scalar.rs +39 -0
  558. data/rust/src/kernel/cli.rs +585 -0
  559. data/rust/src/kernel/dispatch.rs +1090 -0
  560. data/rust/src/kernel/expr.rs +458 -0
  561. data/rust/src/kernel/expression_operators/arithmetic.rs +128 -0
  562. data/rust/src/kernel/expression_operators/comparison.rs +48 -0
  563. data/rust/src/kernel/expression_operators/enumeration.rs +232 -0
  564. data/rust/src/kernel/expression_operators/logical.rs +13 -0
  565. data/rust/src/kernel/expression_operators/membership.rs +18 -0
  566. data/rust/src/kernel/expression_operators/mod.rs +68 -0
  567. data/rust/src/kernel/expression_operators/pattern_match.rs +73 -0
  568. data/rust/src/kernel/expression_operators/positional.rs +126 -0
  569. data/rust/src/kernel/expression_operators/presence.rs +101 -0
  570. data/rust/src/kernel/expression_operators/sign_test.rs +16 -0
  571. data/rust/src/kernel/expression_operators/sized.rs +35 -0
  572. data/rust/src/kernel/expression_operators/text.rs +79 -0
  573. data/rust/src/kernel/expression_operators/to_string.rs +18 -0
  574. data/rust/src/kernel/json.rs +779 -0
  575. data/rust/src/kernel/mod.rs +133 -0
  576. data/rust/src/kernel/named_query.rs +219 -0
  577. data/rust/src/kernel/orchestrate.rs +1810 -0
  578. data/rust/src/kernel/pattern.rs +307 -0
  579. data/rust/src/kernel/query_comparators.rs +206 -0
  580. data/rust/src/kernel/query_ordering.rs +103 -0
  581. data/rust/src/kernel/read_model.rs +914 -0
  582. data/rust/src/kernel/reference_lookup.rs +149 -0
  583. data/rust/src/kernel/repository.rs +468 -0
  584. data/rust/src/kernel/routing.rs +612 -0
  585. data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +118 -0
  586. data/rust/src/kernel/vocab/entity_dispatch_order.rs +114 -0
  587. data/rust/src/kernel/vocab/field_hint.rs +70 -0
  588. data/rust/src/kernel/vocab/mod.rs +20 -0
  589. data/rust/src/kernel/vocab/query_comparator.rs +65 -0
  590. data/rust/src/kernel/vocab/refusal_template.rs +1592 -0
  591. data/rust/src/lib.rs +8 -0
  592. data/rust/src/main.rs +16 -0
  593. data/rust/web/.gitignore +1 -0
  594. data/rust/web/Cargo.lock +119 -0
  595. data/rust/web/Cargo.toml +18 -0
  596. data/rust/web/src/lib.rs +8 -0
  597. metadata +477 -12
  598. data/lib/hecks/facade/cli_door.rb +0 -96
  599. data/lib/hecks/facade/cli_runner.rb +0 -127
  600. data/lib/hecks/mcp_door_scope.rb +0 -95
@@ -0,0 +1,1592 @@
1
+ // GENERATED by hecks project_rust_vocabulary (Hecks::Projections::RustVocabulary,
2
+ // lib/hecks/projections/rust_vocabulary.rb) from Vocabulary::RefusalTemplate
3
+ // (lib/hecks/language/bluebook/vocabulary.bluebook).
4
+ // Do not hand-edit — re-run hecks project_rust_vocabulary instead.
5
+
6
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7
+ pub enum RefusalSite {
8
+ NotFoundCreatingNoIdentity,
9
+ AlreadyExistsCreatingDuplicate,
10
+ AlreadyExistsEntityDuplicate,
11
+ NotFoundActingNoIdentity,
12
+ NotFoundRecordMissing,
13
+ NotFoundEntityParentNoIdentity,
14
+ UnknownVerbEntityUnknown,
15
+ NotFoundEntityElementNoIdentity,
16
+ NotFoundEntityElementMissing,
17
+ NotFoundReferenceTargetMissing,
18
+ NotFoundReadModelReferenceMissing,
19
+ TypeMismatchReadModelObjectReference,
20
+ UnknownVerbNoQuery,
21
+ UnknownVerbEntityQueryMissing,
22
+ UnknownVerbEntityHoldsNoList,
23
+ UnknownVerbEntityNoCommand,
24
+ UnknownVerbAggregateNoCommand,
25
+ UnknownVerbPortNoOperation,
26
+ UnknownVerbNoDomain,
27
+ UnknownVerbNoReadModel,
28
+ UnknownVerbNotFullyQualified,
29
+ UnknownVerbNoAggregate,
30
+ LifecycleRefusedTransitionBlocked,
31
+ TypeMismatchValueObjectShape,
32
+ TypeMismatchReferenceWrongShape,
33
+ TypeMismatchMultiFieldScalar,
34
+ TypeMismatchCompositeIdentity,
35
+ TypeMismatchNumericField,
36
+ TypeMismatchNonFiniteField,
37
+ TypeMismatchIntegerRange,
38
+ TypeMismatchPatternMismatch,
39
+ TypeMismatchArithmeticAmount,
40
+ TypeMismatchArithmeticCurrent,
41
+ TypeMismatchArithmeticSharedField,
42
+ UnknownArgumentUnknownArgs,
43
+ AbsentArgumentAbsentArgs,
44
+ InvariantViolationClosedSetMember,
45
+ InvariantViolationValueObjectInvariant,
46
+ InvariantViolationAdmitsDeclaredSet,
47
+ InvariantViolationUndeclaredSet,
48
+ InvariantViolationGroupByCollision,
49
+ UnauthorizedTenantRequired,
50
+ UnauthorizedRoleMismatch,
51
+ UnauthorizedCrossTenantReference,
52
+ AttributeAbsentAbsentRead,
53
+ ProjectionAbsentAbsentRead,
54
+ }
55
+
56
+ impl RefusalSite {
57
+ /// Every row, in declared order.
58
+ pub const ALL: &'static [RefusalSite] = &[
59
+ RefusalSite::NotFoundCreatingNoIdentity,
60
+ RefusalSite::AlreadyExistsCreatingDuplicate,
61
+ RefusalSite::AlreadyExistsEntityDuplicate,
62
+ RefusalSite::NotFoundActingNoIdentity,
63
+ RefusalSite::NotFoundRecordMissing,
64
+ RefusalSite::NotFoundEntityParentNoIdentity,
65
+ RefusalSite::UnknownVerbEntityUnknown,
66
+ RefusalSite::NotFoundEntityElementNoIdentity,
67
+ RefusalSite::NotFoundEntityElementMissing,
68
+ RefusalSite::NotFoundReferenceTargetMissing,
69
+ RefusalSite::NotFoundReadModelReferenceMissing,
70
+ RefusalSite::TypeMismatchReadModelObjectReference,
71
+ RefusalSite::UnknownVerbNoQuery,
72
+ RefusalSite::UnknownVerbEntityQueryMissing,
73
+ RefusalSite::UnknownVerbEntityHoldsNoList,
74
+ RefusalSite::UnknownVerbEntityNoCommand,
75
+ RefusalSite::UnknownVerbAggregateNoCommand,
76
+ RefusalSite::UnknownVerbPortNoOperation,
77
+ RefusalSite::UnknownVerbNoDomain,
78
+ RefusalSite::UnknownVerbNoReadModel,
79
+ RefusalSite::UnknownVerbNotFullyQualified,
80
+ RefusalSite::UnknownVerbNoAggregate,
81
+ RefusalSite::LifecycleRefusedTransitionBlocked,
82
+ RefusalSite::TypeMismatchValueObjectShape,
83
+ RefusalSite::TypeMismatchReferenceWrongShape,
84
+ RefusalSite::TypeMismatchMultiFieldScalar,
85
+ RefusalSite::TypeMismatchCompositeIdentity,
86
+ RefusalSite::TypeMismatchNumericField,
87
+ RefusalSite::TypeMismatchNonFiniteField,
88
+ RefusalSite::TypeMismatchIntegerRange,
89
+ RefusalSite::TypeMismatchPatternMismatch,
90
+ RefusalSite::TypeMismatchArithmeticAmount,
91
+ RefusalSite::TypeMismatchArithmeticCurrent,
92
+ RefusalSite::TypeMismatchArithmeticSharedField,
93
+ RefusalSite::UnknownArgumentUnknownArgs,
94
+ RefusalSite::AbsentArgumentAbsentArgs,
95
+ RefusalSite::InvariantViolationClosedSetMember,
96
+ RefusalSite::InvariantViolationValueObjectInvariant,
97
+ RefusalSite::InvariantViolationAdmitsDeclaredSet,
98
+ RefusalSite::InvariantViolationUndeclaredSet,
99
+ RefusalSite::InvariantViolationGroupByCollision,
100
+ RefusalSite::UnauthorizedTenantRequired,
101
+ RefusalSite::UnauthorizedRoleMismatch,
102
+ RefusalSite::UnauthorizedCrossTenantReference,
103
+ RefusalSite::AttributeAbsentAbsentRead,
104
+ RefusalSite::ProjectionAbsentAbsentRead,
105
+ ];
106
+
107
+ /// The row's declared `refusal`.
108
+ pub fn refusal_class(&self) -> &'static str {
109
+ match self {
110
+ RefusalSite::NotFoundCreatingNoIdentity => "NotFound",
111
+ RefusalSite::AlreadyExistsCreatingDuplicate => "AlreadyExists",
112
+ RefusalSite::AlreadyExistsEntityDuplicate => "AlreadyExists",
113
+ RefusalSite::NotFoundActingNoIdentity => "NotFound",
114
+ RefusalSite::NotFoundRecordMissing => "NotFound",
115
+ RefusalSite::NotFoundEntityParentNoIdentity => "NotFound",
116
+ RefusalSite::UnknownVerbEntityUnknown => "UnknownVerb",
117
+ RefusalSite::NotFoundEntityElementNoIdentity => "NotFound",
118
+ RefusalSite::NotFoundEntityElementMissing => "NotFound",
119
+ RefusalSite::NotFoundReferenceTargetMissing => "NotFound",
120
+ RefusalSite::NotFoundReadModelReferenceMissing => "NotFound",
121
+ RefusalSite::TypeMismatchReadModelObjectReference => "TypeMismatch",
122
+ RefusalSite::UnknownVerbNoQuery => "UnknownVerb",
123
+ RefusalSite::UnknownVerbEntityQueryMissing => "UnknownVerb",
124
+ RefusalSite::UnknownVerbEntityHoldsNoList => "UnknownVerb",
125
+ RefusalSite::UnknownVerbEntityNoCommand => "UnknownVerb",
126
+ RefusalSite::UnknownVerbAggregateNoCommand => "UnknownVerb",
127
+ RefusalSite::UnknownVerbPortNoOperation => "UnknownVerb",
128
+ RefusalSite::UnknownVerbNoDomain => "UnknownVerb",
129
+ RefusalSite::UnknownVerbNoReadModel => "UnknownVerb",
130
+ RefusalSite::UnknownVerbNotFullyQualified => "UnknownVerb",
131
+ RefusalSite::UnknownVerbNoAggregate => "UnknownVerb",
132
+ RefusalSite::LifecycleRefusedTransitionBlocked => "LifecycleRefused",
133
+ RefusalSite::TypeMismatchValueObjectShape => "TypeMismatch",
134
+ RefusalSite::TypeMismatchReferenceWrongShape => "TypeMismatch",
135
+ RefusalSite::TypeMismatchMultiFieldScalar => "TypeMismatch",
136
+ RefusalSite::TypeMismatchCompositeIdentity => "TypeMismatch",
137
+ RefusalSite::TypeMismatchNumericField => "TypeMismatch",
138
+ RefusalSite::TypeMismatchNonFiniteField => "TypeMismatch",
139
+ RefusalSite::TypeMismatchIntegerRange => "TypeMismatch",
140
+ RefusalSite::TypeMismatchPatternMismatch => "TypeMismatch",
141
+ RefusalSite::TypeMismatchArithmeticAmount => "TypeMismatch",
142
+ RefusalSite::TypeMismatchArithmeticCurrent => "TypeMismatch",
143
+ RefusalSite::TypeMismatchArithmeticSharedField => "TypeMismatch",
144
+ RefusalSite::UnknownArgumentUnknownArgs => "UnknownArgument",
145
+ RefusalSite::AbsentArgumentAbsentArgs => "AbsentArgument",
146
+ RefusalSite::InvariantViolationClosedSetMember => "InvariantViolation",
147
+ RefusalSite::InvariantViolationValueObjectInvariant => "InvariantViolation",
148
+ RefusalSite::InvariantViolationAdmitsDeclaredSet => "InvariantViolation",
149
+ RefusalSite::InvariantViolationUndeclaredSet => "InvariantViolation",
150
+ RefusalSite::InvariantViolationGroupByCollision => "InvariantViolation",
151
+ RefusalSite::UnauthorizedTenantRequired => "Unauthorized",
152
+ RefusalSite::UnauthorizedRoleMismatch => "Unauthorized",
153
+ RefusalSite::UnauthorizedCrossTenantReference => "Unauthorized",
154
+ RefusalSite::AttributeAbsentAbsentRead => "AttributeAbsent",
155
+ RefusalSite::ProjectionAbsentAbsentRead => "ProjectionAbsent",
156
+ }
157
+ }
158
+
159
+ /// The row's declared `site`.
160
+ pub fn site(&self) -> &'static str {
161
+ match self {
162
+ RefusalSite::NotFoundCreatingNoIdentity => "creating_no_identity",
163
+ RefusalSite::AlreadyExistsCreatingDuplicate => "creating_duplicate",
164
+ RefusalSite::AlreadyExistsEntityDuplicate => "entity_duplicate",
165
+ RefusalSite::NotFoundActingNoIdentity => "acting_no_identity",
166
+ RefusalSite::NotFoundRecordMissing => "record_missing",
167
+ RefusalSite::NotFoundEntityParentNoIdentity => "entity_parent_no_identity",
168
+ RefusalSite::UnknownVerbEntityUnknown => "entity_unknown",
169
+ RefusalSite::NotFoundEntityElementNoIdentity => "entity_element_no_identity",
170
+ RefusalSite::NotFoundEntityElementMissing => "entity_element_missing",
171
+ RefusalSite::NotFoundReferenceTargetMissing => "reference_target_missing",
172
+ RefusalSite::NotFoundReadModelReferenceMissing => "read_model_reference_missing",
173
+ RefusalSite::TypeMismatchReadModelObjectReference => "read_model_object_reference",
174
+ RefusalSite::UnknownVerbNoQuery => "no_query",
175
+ RefusalSite::UnknownVerbEntityQueryMissing => "entity_query_missing",
176
+ RefusalSite::UnknownVerbEntityHoldsNoList => "entity_holds_no_list",
177
+ RefusalSite::UnknownVerbEntityNoCommand => "entity_no_command",
178
+ RefusalSite::UnknownVerbAggregateNoCommand => "aggregate_no_command",
179
+ RefusalSite::UnknownVerbPortNoOperation => "port_no_operation",
180
+ RefusalSite::UnknownVerbNoDomain => "no_domain",
181
+ RefusalSite::UnknownVerbNoReadModel => "no_read_model",
182
+ RefusalSite::UnknownVerbNotFullyQualified => "not_fully_qualified",
183
+ RefusalSite::UnknownVerbNoAggregate => "no_aggregate",
184
+ RefusalSite::LifecycleRefusedTransitionBlocked => "transition_blocked",
185
+ RefusalSite::TypeMismatchValueObjectShape => "value_object_shape",
186
+ RefusalSite::TypeMismatchReferenceWrongShape => "reference_wrong_shape",
187
+ RefusalSite::TypeMismatchMultiFieldScalar => "multi_field_scalar",
188
+ RefusalSite::TypeMismatchCompositeIdentity => "composite_identity",
189
+ RefusalSite::TypeMismatchNumericField => "numeric_field",
190
+ RefusalSite::TypeMismatchNonFiniteField => "non_finite_field",
191
+ RefusalSite::TypeMismatchIntegerRange => "integer_range",
192
+ RefusalSite::TypeMismatchPatternMismatch => "pattern_mismatch",
193
+ RefusalSite::TypeMismatchArithmeticAmount => "arithmetic_amount",
194
+ RefusalSite::TypeMismatchArithmeticCurrent => "arithmetic_current",
195
+ RefusalSite::TypeMismatchArithmeticSharedField => "arithmetic_shared_field",
196
+ RefusalSite::UnknownArgumentUnknownArgs => "unknown_args",
197
+ RefusalSite::AbsentArgumentAbsentArgs => "absent_args",
198
+ RefusalSite::InvariantViolationClosedSetMember => "closed_set_member",
199
+ RefusalSite::InvariantViolationValueObjectInvariant => "value_object_invariant",
200
+ RefusalSite::InvariantViolationAdmitsDeclaredSet => "admits_declared_set",
201
+ RefusalSite::InvariantViolationUndeclaredSet => "undeclared_set",
202
+ RefusalSite::InvariantViolationGroupByCollision => "group_by_collision",
203
+ RefusalSite::UnauthorizedTenantRequired => "tenant_required",
204
+ RefusalSite::UnauthorizedRoleMismatch => "role_mismatch",
205
+ RefusalSite::UnauthorizedCrossTenantReference => "cross_tenant_reference",
206
+ RefusalSite::AttributeAbsentAbsentRead => "absent_read",
207
+ RefusalSite::ProjectionAbsentAbsentRead => "absent_read",
208
+ }
209
+ }
210
+
211
+ /// The row's declared `template`.
212
+ pub fn template(&self) -> &'static str {
213
+ match self {
214
+ RefusalSite::NotFoundCreatingNoIdentity => "{command} creates a {aggregate} — pass {identity}:",
215
+ RefusalSite::AlreadyExistsCreatingDuplicate => "{command} creates a {aggregate} that already exists — {identity} {offered}",
216
+ RefusalSite::AlreadyExistsEntityDuplicate => "a {entity} already exists on {aggregate} — {identity} {offered}",
217
+ RefusalSite::NotFoundActingNoIdentity => "{command} acts on an existing {aggregate} — pass {identity}:",
218
+ RefusalSite::NotFoundRecordMissing => "no {aggregate} with {identity} {offered}",
219
+ RefusalSite::NotFoundEntityParentNoIdentity => "{command} acts on a {aggregate}'s {entity} — pass {identity}:",
220
+ RefusalSite::UnknownVerbEntityUnknown => "{aggregate} has no entity {entity}",
221
+ RefusalSite::NotFoundEntityElementNoIdentity => "{command} acts on one {entity} — pass {identity}:",
222
+ RefusalSite::NotFoundEntityElementMissing => "no {entity} with {identity} {wants} on {aggregate} {parent_id}",
223
+ RefusalSite::NotFoundReferenceTargetMissing => "no {target} with {heads} {key}",
224
+ RefusalSite::NotFoundReadModelReferenceMissing => "no {aggregate} with reference {offered}",
225
+ RefusalSite::TypeMismatchReadModelObjectReference => "{query} refused — a reference is an id, and {field} arrived as an object",
226
+ RefusalSite::UnknownVerbNoQuery => "{aggregate} has no query {query}",
227
+ RefusalSite::UnknownVerbEntityQueryMissing => "{entity} has no query {query}",
228
+ RefusalSite::UnknownVerbEntityHoldsNoList => "{aggregate} holds no list of {entity}",
229
+ RefusalSite::UnknownVerbEntityNoCommand => "{entity} has no command {command}",
230
+ RefusalSite::UnknownVerbAggregateNoCommand => "{aggregate} has no command {command}",
231
+ RefusalSite::UnknownVerbPortNoOperation => "{port} has no operation {operation}",
232
+ RefusalSite::UnknownVerbNoDomain => "no domain {domain} loaded (verb {verb})",
233
+ RefusalSite::UnknownVerbNoReadModel => "{domain} has no read model {query}",
234
+ RefusalSite::UnknownVerbNotFullyQualified => "{verb} is not a fully-qualified verb (Domain::Aggregate.Command)",
235
+ RefusalSite::UnknownVerbNoAggregate => "{domain} has no aggregate {aggregate}",
236
+ RefusalSite::LifecycleRefusedTransitionBlocked => "{command} refused — {field} is {current}, and {command} moves it only from {allowed}",
237
+ RefusalSite::TypeMismatchValueObjectShape => "{name} is a {type} — pass its fields as an object, not {offered}",
238
+ RefusalSite::TypeMismatchReferenceWrongShape => "{command} refused — a reference is an id, and {attribute} arrived as {offered}{known_by}",
239
+ RefusalSite::TypeMismatchMultiFieldScalar => "{type} has multiple fields and cannot stand in for a scalar",
240
+ RefusalSite::TypeMismatchCompositeIdentity => "{type} is a composite identity — an identity must have exactly one field",
241
+ RefusalSite::TypeMismatchNumericField => "{type}.{field} expects {expected}, got {offered}",
242
+ RefusalSite::TypeMismatchNonFiniteField => "{type}.{field} must be a finite number, got {offered}",
243
+ RefusalSite::TypeMismatchIntegerRange => "{type}.{field} must fit in a 64-bit integer, got {offered}",
244
+ RefusalSite::TypeMismatchPatternMismatch => "{type}.{field} must match {pattern}, got {offered}",
245
+ RefusalSite::TypeMismatchArithmeticAmount => "{op} of {target} needs an Integer, got {offered}",
246
+ RefusalSite::TypeMismatchArithmeticCurrent => "{op} of {target} needs an Integer {target}, got {offered}",
247
+ RefusalSite::TypeMismatchArithmeticSharedField => "{op} of {target} needs a value object with one shared Integer field",
248
+ RefusalSite::UnknownArgumentUnknownArgs => "{command} does not declare {unknown} — it takes {declared}",
249
+ RefusalSite::AbsentArgumentAbsentArgs => "{command} was not given {absent} — it takes {declared}",
250
+ RefusalSite::InvariantViolationClosedSetMember => "{type} admits {admitted} — got {offered}",
251
+ RefusalSite::InvariantViolationValueObjectInvariant => "{name} invariant violated — {description} (given {offered})",
252
+ RefusalSite::InvariantViolationAdmitsDeclaredSet => "{name} admits {admits} — {admitted} — got {offered}",
253
+ RefusalSite::InvariantViolationUndeclaredSet => "{name} admits {admits}, which this chapter does not declare — a closed set is named Aggregate::SetName, and it must be one the bluebook actually holds",
254
+ RefusalSite::InvariantViolationGroupByCollision => "{read_model} groups by {fields}, but rows {ids} share {key} — a group_by leaf holds one row; add a field that tells them apart",
255
+ RefusalSite::UnauthorizedTenantRequired => "{query} declares authorize with tenant: {field} — pass {field}: to name which {field} this ask is scoped to",
256
+ RefusalSite::UnauthorizedRoleMismatch => "{command} refused — role: {role}, and the caller stated {caller_role}",
257
+ RefusalSite::UnauthorizedCrossTenantReference => "{aggregate} {field} is {tenant}, but {attribute} names a {target} whose own {target_field} is {other} — a cross-tenant reference",
258
+ RefusalSite::AttributeAbsentAbsentRead => "{aggregate} {field} is absent on this record — declared, not optional, and added since it was written. Backfill it in a translation (backfill :{field}, default: ...), or declare it optional: true",
259
+ RefusalSite::ProjectionAbsentAbsentRead => "{aggregate} {field} is not yet projected on this record — declared via projects :{field}, but no rebuild sweep has populated it. Run the sweep, or read {reference}.{remote_field} directly if this rule cannot wait",
260
+ }
261
+ }
262
+
263
+ /// The row whose `site` is `name`, if any.
264
+ pub fn from_name(name: &str) -> Option<RefusalSite> {
265
+ RefusalSite::ALL.iter().copied().find(|row| row.site() == name)
266
+ }
267
+
268
+ /// `RefusalWording.substitute`: replace every `{key}` marker, in the
269
+ /// order given. A template is read, never evaluated. Private: call
270
+ /// sites go through a site's typed `<Variant>Args::render_args`,
271
+ /// which formats and supplies every declared argument.
272
+ fn render(&self, values: &[(&str, &str)]) -> String {
273
+ let mut text = self.template().to_string();
274
+ for (key, value) in values {
275
+ text = text.replace(&format!("{{{key}}}"), value);
276
+ }
277
+ text
278
+ }
279
+ }
280
+
281
+ /// Ruby's `#inspect` of a name, as a refusal quotes it: `{:?}` on a
282
+ /// `&str`, the quoting every kernel call site used before
283
+ /// RefusalSiteArgument existed.
284
+ fn quoted(text: &str) -> String {
285
+ format!("{text:?}")
286
+ }
287
+
288
+ /// A list argument, written the way its RefusalSiteArgument row says:
289
+ /// sorted first (before quoting), each item quoted, then joined; an
290
+ /// empty list reads `when_empty`.
291
+ fn list(items: &[&str], sorted: bool, inspect: bool, separator: &str, when_empty: &str) -> String {
292
+ let mut items = items.to_vec();
293
+ if sorted {
294
+ items.sort_unstable();
295
+ }
296
+ if items.is_empty() {
297
+ return when_empty.to_string();
298
+ }
299
+ let write = |item: &&str| if inspect { quoted(item) } else { item.to_string() };
300
+ items.iter().map(write).collect::<Vec<_>>().join(separator)
301
+ }
302
+
303
+ /// `RefusalSite::NotFoundCreatingNoIdentity`'s arguments — `RefusalWording.render_site("NotFound", "creating_no_identity", ...)`.
304
+ #[derive(Debug, Clone, Copy)]
305
+ pub struct NotFoundCreatingNoIdentityArgs<'a> {
306
+ /// scalar
307
+ pub command: &'a str,
308
+ /// scalar
309
+ pub aggregate: &'a str,
310
+ /// scalar
311
+ pub identity: &'a str,
312
+ }
313
+
314
+ impl NotFoundCreatingNoIdentityArgs<'_> {
315
+ /// The site's wording, every argument formatted by its declared row.
316
+ pub fn render_args(&self) -> String {
317
+ RefusalSite::NotFoundCreatingNoIdentity.render(&[
318
+ ("command", self.command),
319
+ ("aggregate", self.aggregate),
320
+ ("identity", self.identity),
321
+ ])
322
+ }
323
+ }
324
+
325
+ /// `RefusalSite::AlreadyExistsCreatingDuplicate`'s arguments — `RefusalWording.render_site("AlreadyExists", "creating_duplicate", ...)`.
326
+ #[derive(Debug, Clone, Copy)]
327
+ pub struct AlreadyExistsCreatingDuplicateArgs<'a> {
328
+ /// scalar
329
+ pub command: &'a str,
330
+ /// scalar
331
+ pub aggregate: &'a str,
332
+ /// scalar
333
+ pub identity: &'a str,
334
+ /// scalar
335
+ pub offered: &'a str,
336
+ }
337
+
338
+ impl AlreadyExistsCreatingDuplicateArgs<'_> {
339
+ /// The site's wording, every argument formatted by its declared row.
340
+ pub fn render_args(&self) -> String {
341
+ RefusalSite::AlreadyExistsCreatingDuplicate.render(&[
342
+ ("command", self.command),
343
+ ("aggregate", self.aggregate),
344
+ ("identity", self.identity),
345
+ ("offered", self.offered),
346
+ ])
347
+ }
348
+ }
349
+
350
+ /// `RefusalSite::AlreadyExistsEntityDuplicate`'s arguments — `RefusalWording.render_site("AlreadyExists", "entity_duplicate", ...)`.
351
+ #[derive(Debug, Clone, Copy)]
352
+ pub struct AlreadyExistsEntityDuplicateArgs<'a> {
353
+ /// scalar
354
+ pub entity: &'a str,
355
+ /// scalar
356
+ pub aggregate: &'a str,
357
+ /// scalar
358
+ pub identity: &'a str,
359
+ /// list, joined ", ", empty reads ""
360
+ pub offered: &'a [&'a str],
361
+ }
362
+
363
+ impl AlreadyExistsEntityDuplicateArgs<'_> {
364
+ /// The site's wording, every argument formatted by its declared row.
365
+ pub fn render_args(&self) -> String {
366
+ let offered_text = list(self.offered, false, false, ", ", "");
367
+ RefusalSite::AlreadyExistsEntityDuplicate.render(&[
368
+ ("entity", self.entity),
369
+ ("aggregate", self.aggregate),
370
+ ("identity", self.identity),
371
+ ("offered", offered_text.as_str()),
372
+ ])
373
+ }
374
+ }
375
+
376
+ /// `RefusalSite::NotFoundActingNoIdentity`'s arguments — `RefusalWording.render_site("NotFound", "acting_no_identity", ...)`.
377
+ #[derive(Debug, Clone, Copy)]
378
+ pub struct NotFoundActingNoIdentityArgs<'a> {
379
+ /// scalar
380
+ pub command: &'a str,
381
+ /// scalar
382
+ pub aggregate: &'a str,
383
+ /// scalar
384
+ pub identity: &'a str,
385
+ }
386
+
387
+ impl NotFoundActingNoIdentityArgs<'_> {
388
+ /// The site's wording, every argument formatted by its declared row.
389
+ pub fn render_args(&self) -> String {
390
+ RefusalSite::NotFoundActingNoIdentity.render(&[
391
+ ("command", self.command),
392
+ ("aggregate", self.aggregate),
393
+ ("identity", self.identity),
394
+ ])
395
+ }
396
+ }
397
+
398
+ /// `RefusalSite::NotFoundRecordMissing`'s arguments — `RefusalWording.render_site("NotFound", "record_missing", ...)`.
399
+ #[derive(Debug, Clone, Copy)]
400
+ pub struct NotFoundRecordMissingArgs<'a> {
401
+ /// scalar
402
+ pub aggregate: &'a str,
403
+ /// scalar
404
+ pub identity: &'a str,
405
+ /// scalar
406
+ pub offered: &'a str,
407
+ }
408
+
409
+ impl NotFoundRecordMissingArgs<'_> {
410
+ /// The site's wording, every argument formatted by its declared row.
411
+ pub fn render_args(&self) -> String {
412
+ RefusalSite::NotFoundRecordMissing.render(&[
413
+ ("aggregate", self.aggregate),
414
+ ("identity", self.identity),
415
+ ("offered", self.offered),
416
+ ])
417
+ }
418
+ }
419
+
420
+ /// `RefusalSite::NotFoundEntityParentNoIdentity`'s arguments — `RefusalWording.render_site("NotFound", "entity_parent_no_identity", ...)`.
421
+ #[derive(Debug, Clone, Copy)]
422
+ pub struct NotFoundEntityParentNoIdentityArgs<'a> {
423
+ /// scalar
424
+ pub command: &'a str,
425
+ /// scalar
426
+ pub aggregate: &'a str,
427
+ /// scalar
428
+ pub entity: &'a str,
429
+ /// scalar
430
+ pub identity: &'a str,
431
+ }
432
+
433
+ impl NotFoundEntityParentNoIdentityArgs<'_> {
434
+ /// The site's wording, every argument formatted by its declared row.
435
+ pub fn render_args(&self) -> String {
436
+ RefusalSite::NotFoundEntityParentNoIdentity.render(&[
437
+ ("command", self.command),
438
+ ("aggregate", self.aggregate),
439
+ ("entity", self.entity),
440
+ ("identity", self.identity),
441
+ ])
442
+ }
443
+ }
444
+
445
+ /// `RefusalSite::UnknownVerbEntityUnknown`'s arguments — `RefusalWording.render_site("UnknownVerb", "entity_unknown", ...)`.
446
+ #[derive(Debug, Clone, Copy)]
447
+ pub struct UnknownVerbEntityUnknownArgs<'a> {
448
+ /// scalar
449
+ pub aggregate: &'a str,
450
+ /// scalar, quoted
451
+ pub entity: &'a str,
452
+ }
453
+
454
+ impl UnknownVerbEntityUnknownArgs<'_> {
455
+ /// The site's wording, every argument formatted by its declared row.
456
+ pub fn render_args(&self) -> String {
457
+ let entity_text = quoted(self.entity);
458
+ RefusalSite::UnknownVerbEntityUnknown.render(&[
459
+ ("aggregate", self.aggregate),
460
+ ("entity", entity_text.as_str()),
461
+ ])
462
+ }
463
+ }
464
+
465
+ /// `RefusalSite::NotFoundEntityElementNoIdentity`'s arguments — `RefusalWording.render_site("NotFound", "entity_element_no_identity", ...)`.
466
+ #[derive(Debug, Clone, Copy)]
467
+ pub struct NotFoundEntityElementNoIdentityArgs<'a> {
468
+ /// scalar
469
+ pub command: &'a str,
470
+ /// scalar
471
+ pub entity: &'a str,
472
+ /// scalar
473
+ pub identity: &'a str,
474
+ }
475
+
476
+ impl NotFoundEntityElementNoIdentityArgs<'_> {
477
+ /// The site's wording, every argument formatted by its declared row.
478
+ pub fn render_args(&self) -> String {
479
+ RefusalSite::NotFoundEntityElementNoIdentity.render(&[
480
+ ("command", self.command),
481
+ ("entity", self.entity),
482
+ ("identity", self.identity),
483
+ ])
484
+ }
485
+ }
486
+
487
+ /// `RefusalSite::NotFoundEntityElementMissing`'s arguments — `RefusalWording.render_site("NotFound", "entity_element_missing", ...)`.
488
+ #[derive(Debug, Clone, Copy)]
489
+ pub struct NotFoundEntityElementMissingArgs<'a> {
490
+ /// scalar
491
+ pub entity: &'a str,
492
+ /// scalar
493
+ pub identity: &'a str,
494
+ /// scalar
495
+ pub wants: &'a str,
496
+ /// scalar
497
+ pub aggregate: &'a str,
498
+ /// scalar
499
+ pub parent_id: &'a str,
500
+ }
501
+
502
+ impl NotFoundEntityElementMissingArgs<'_> {
503
+ /// The site's wording, every argument formatted by its declared row.
504
+ pub fn render_args(&self) -> String {
505
+ RefusalSite::NotFoundEntityElementMissing.render(&[
506
+ ("entity", self.entity),
507
+ ("identity", self.identity),
508
+ ("wants", self.wants),
509
+ ("aggregate", self.aggregate),
510
+ ("parent_id", self.parent_id),
511
+ ])
512
+ }
513
+ }
514
+
515
+ /// `RefusalSite::NotFoundReferenceTargetMissing`'s arguments — `RefusalWording.render_site("NotFound", "reference_target_missing", ...)`.
516
+ #[derive(Debug, Clone, Copy)]
517
+ pub struct NotFoundReferenceTargetMissingArgs<'a> {
518
+ /// scalar
519
+ pub target: &'a str,
520
+ /// scalar
521
+ pub heads: &'a str,
522
+ /// scalar, quoted
523
+ pub key: &'a str,
524
+ }
525
+
526
+ impl NotFoundReferenceTargetMissingArgs<'_> {
527
+ /// The site's wording, every argument formatted by its declared row.
528
+ pub fn render_args(&self) -> String {
529
+ let key_text = quoted(self.key);
530
+ RefusalSite::NotFoundReferenceTargetMissing.render(&[
531
+ ("target", self.target),
532
+ ("heads", self.heads),
533
+ ("key", key_text.as_str()),
534
+ ])
535
+ }
536
+ }
537
+
538
+ /// `RefusalSite::NotFoundReadModelReferenceMissing`'s arguments — `RefusalWording.render_site("NotFound", "read_model_reference_missing", ...)`.
539
+ #[derive(Debug, Clone, Copy)]
540
+ pub struct NotFoundReadModelReferenceMissingArgs<'a> {
541
+ /// scalar
542
+ pub aggregate: &'a str,
543
+ /// scalar
544
+ pub offered: &'a str,
545
+ }
546
+
547
+ impl NotFoundReadModelReferenceMissingArgs<'_> {
548
+ /// The site's wording, every argument formatted by its declared row.
549
+ pub fn render_args(&self) -> String {
550
+ RefusalSite::NotFoundReadModelReferenceMissing.render(&[
551
+ ("aggregate", self.aggregate),
552
+ ("offered", self.offered),
553
+ ])
554
+ }
555
+ }
556
+
557
+ /// `RefusalSite::TypeMismatchReadModelObjectReference`'s arguments — `RefusalWording.render_site("TypeMismatch", "read_model_object_reference", ...)`.
558
+ #[derive(Debug, Clone, Copy)]
559
+ pub struct TypeMismatchReadModelObjectReferenceArgs<'a> {
560
+ /// scalar
561
+ pub query: &'a str,
562
+ /// scalar
563
+ pub field: &'a str,
564
+ }
565
+
566
+ impl TypeMismatchReadModelObjectReferenceArgs<'_> {
567
+ /// The site's wording, every argument formatted by its declared row.
568
+ pub fn render_args(&self) -> String {
569
+ RefusalSite::TypeMismatchReadModelObjectReference.render(&[
570
+ ("query", self.query),
571
+ ("field", self.field),
572
+ ])
573
+ }
574
+ }
575
+
576
+ /// `RefusalSite::UnknownVerbNoQuery`'s arguments — `RefusalWording.render_site("UnknownVerb", "no_query", ...)`.
577
+ #[derive(Debug, Clone, Copy)]
578
+ pub struct UnknownVerbNoQueryArgs<'a> {
579
+ /// scalar
580
+ pub aggregate: &'a str,
581
+ /// scalar, quoted
582
+ pub query: &'a str,
583
+ }
584
+
585
+ impl UnknownVerbNoQueryArgs<'_> {
586
+ /// The site's wording, every argument formatted by its declared row.
587
+ pub fn render_args(&self) -> String {
588
+ let query_text = quoted(self.query);
589
+ RefusalSite::UnknownVerbNoQuery.render(&[
590
+ ("aggregate", self.aggregate),
591
+ ("query", query_text.as_str()),
592
+ ])
593
+ }
594
+ }
595
+
596
+ /// `RefusalSite::UnknownVerbEntityQueryMissing`'s arguments — `RefusalWording.render_site("UnknownVerb", "entity_query_missing", ...)`.
597
+ #[derive(Debug, Clone, Copy)]
598
+ pub struct UnknownVerbEntityQueryMissingArgs<'a> {
599
+ /// scalar
600
+ pub entity: &'a str,
601
+ /// scalar, quoted
602
+ pub query: &'a str,
603
+ }
604
+
605
+ impl UnknownVerbEntityQueryMissingArgs<'_> {
606
+ /// The site's wording, every argument formatted by its declared row.
607
+ pub fn render_args(&self) -> String {
608
+ let query_text = quoted(self.query);
609
+ RefusalSite::UnknownVerbEntityQueryMissing.render(&[
610
+ ("entity", self.entity),
611
+ ("query", query_text.as_str()),
612
+ ])
613
+ }
614
+ }
615
+
616
+ /// `RefusalSite::UnknownVerbEntityHoldsNoList`'s arguments — `RefusalWording.render_site("UnknownVerb", "entity_holds_no_list", ...)`.
617
+ #[derive(Debug, Clone, Copy)]
618
+ pub struct UnknownVerbEntityHoldsNoListArgs<'a> {
619
+ /// scalar
620
+ pub aggregate: &'a str,
621
+ /// scalar
622
+ pub entity: &'a str,
623
+ }
624
+
625
+ impl UnknownVerbEntityHoldsNoListArgs<'_> {
626
+ /// The site's wording, every argument formatted by its declared row.
627
+ pub fn render_args(&self) -> String {
628
+ RefusalSite::UnknownVerbEntityHoldsNoList.render(&[
629
+ ("aggregate", self.aggregate),
630
+ ("entity", self.entity),
631
+ ])
632
+ }
633
+ }
634
+
635
+ /// `RefusalSite::UnknownVerbEntityNoCommand`'s arguments — `RefusalWording.render_site("UnknownVerb", "entity_no_command", ...)`.
636
+ #[derive(Debug, Clone, Copy)]
637
+ pub struct UnknownVerbEntityNoCommandArgs<'a> {
638
+ /// scalar
639
+ pub entity: &'a str,
640
+ /// scalar, quoted
641
+ pub command: &'a str,
642
+ }
643
+
644
+ impl UnknownVerbEntityNoCommandArgs<'_> {
645
+ /// The site's wording, every argument formatted by its declared row.
646
+ pub fn render_args(&self) -> String {
647
+ let command_text = quoted(self.command);
648
+ RefusalSite::UnknownVerbEntityNoCommand.render(&[
649
+ ("entity", self.entity),
650
+ ("command", command_text.as_str()),
651
+ ])
652
+ }
653
+ }
654
+
655
+ /// `RefusalSite::UnknownVerbAggregateNoCommand`'s arguments — `RefusalWording.render_site("UnknownVerb", "aggregate_no_command", ...)`.
656
+ #[derive(Debug, Clone, Copy)]
657
+ pub struct UnknownVerbAggregateNoCommandArgs<'a> {
658
+ /// scalar
659
+ pub aggregate: &'a str,
660
+ /// scalar, quoted
661
+ pub command: &'a str,
662
+ }
663
+
664
+ impl UnknownVerbAggregateNoCommandArgs<'_> {
665
+ /// The site's wording, every argument formatted by its declared row.
666
+ pub fn render_args(&self) -> String {
667
+ let command_text = quoted(self.command);
668
+ RefusalSite::UnknownVerbAggregateNoCommand.render(&[
669
+ ("aggregate", self.aggregate),
670
+ ("command", command_text.as_str()),
671
+ ])
672
+ }
673
+ }
674
+
675
+ /// `RefusalSite::UnknownVerbPortNoOperation`'s arguments — `RefusalWording.render_site("UnknownVerb", "port_no_operation", ...)`.
676
+ #[derive(Debug, Clone, Copy)]
677
+ pub struct UnknownVerbPortNoOperationArgs<'a> {
678
+ /// scalar
679
+ pub port: &'a str,
680
+ /// scalar, quoted
681
+ pub operation: &'a str,
682
+ }
683
+
684
+ impl UnknownVerbPortNoOperationArgs<'_> {
685
+ /// The site's wording, every argument formatted by its declared row.
686
+ pub fn render_args(&self) -> String {
687
+ let operation_text = quoted(self.operation);
688
+ RefusalSite::UnknownVerbPortNoOperation.render(&[
689
+ ("port", self.port),
690
+ ("operation", operation_text.as_str()),
691
+ ])
692
+ }
693
+ }
694
+
695
+ /// `RefusalSite::UnknownVerbNoDomain`'s arguments — `RefusalWording.render_site("UnknownVerb", "no_domain", ...)`.
696
+ #[derive(Debug, Clone, Copy)]
697
+ pub struct UnknownVerbNoDomainArgs<'a> {
698
+ /// scalar, quoted
699
+ pub domain: &'a str,
700
+ /// scalar
701
+ pub verb: &'a str,
702
+ }
703
+
704
+ impl UnknownVerbNoDomainArgs<'_> {
705
+ /// The site's wording, every argument formatted by its declared row.
706
+ pub fn render_args(&self) -> String {
707
+ let domain_text = quoted(self.domain);
708
+ RefusalSite::UnknownVerbNoDomain.render(&[
709
+ ("domain", domain_text.as_str()),
710
+ ("verb", self.verb),
711
+ ])
712
+ }
713
+ }
714
+
715
+ /// `RefusalSite::UnknownVerbNoReadModel`'s arguments — `RefusalWording.render_site("UnknownVerb", "no_read_model", ...)`.
716
+ #[derive(Debug, Clone, Copy)]
717
+ pub struct UnknownVerbNoReadModelArgs<'a> {
718
+ /// scalar
719
+ pub domain: &'a str,
720
+ /// scalar, quoted
721
+ pub query: &'a str,
722
+ }
723
+
724
+ impl UnknownVerbNoReadModelArgs<'_> {
725
+ /// The site's wording, every argument formatted by its declared row.
726
+ pub fn render_args(&self) -> String {
727
+ let query_text = quoted(self.query);
728
+ RefusalSite::UnknownVerbNoReadModel.render(&[
729
+ ("domain", self.domain),
730
+ ("query", query_text.as_str()),
731
+ ])
732
+ }
733
+ }
734
+
735
+ /// `RefusalSite::UnknownVerbNotFullyQualified`'s arguments — `RefusalWording.render_site("UnknownVerb", "not_fully_qualified", ...)`.
736
+ #[derive(Debug, Clone, Copy)]
737
+ pub struct UnknownVerbNotFullyQualifiedArgs<'a> {
738
+ /// scalar, quoted
739
+ pub verb: &'a str,
740
+ }
741
+
742
+ impl UnknownVerbNotFullyQualifiedArgs<'_> {
743
+ /// The site's wording, every argument formatted by its declared row.
744
+ pub fn render_args(&self) -> String {
745
+ let verb_text = quoted(self.verb);
746
+ RefusalSite::UnknownVerbNotFullyQualified.render(&[
747
+ ("verb", verb_text.as_str()),
748
+ ])
749
+ }
750
+ }
751
+
752
+ /// `RefusalSite::UnknownVerbNoAggregate`'s arguments — `RefusalWording.render_site("UnknownVerb", "no_aggregate", ...)`.
753
+ #[derive(Debug, Clone, Copy)]
754
+ pub struct UnknownVerbNoAggregateArgs<'a> {
755
+ /// scalar
756
+ pub domain: &'a str,
757
+ /// scalar, quoted
758
+ pub aggregate: &'a str,
759
+ }
760
+
761
+ impl UnknownVerbNoAggregateArgs<'_> {
762
+ /// The site's wording, every argument formatted by its declared row.
763
+ pub fn render_args(&self) -> String {
764
+ let aggregate_text = quoted(self.aggregate);
765
+ RefusalSite::UnknownVerbNoAggregate.render(&[
766
+ ("domain", self.domain),
767
+ ("aggregate", aggregate_text.as_str()),
768
+ ])
769
+ }
770
+ }
771
+
772
+ /// `RefusalSite::LifecycleRefusedTransitionBlocked`'s arguments — `RefusalWording.render_site("LifecycleRefused", "transition_blocked", ...)`.
773
+ #[derive(Debug, Clone, Copy)]
774
+ pub struct LifecycleRefusedTransitionBlockedArgs<'a> {
775
+ /// scalar
776
+ pub command: &'a str,
777
+ /// scalar
778
+ pub field: &'a str,
779
+ /// scalar
780
+ pub current: &'a str,
781
+ /// list, quoted, joined " or ", empty reads ""
782
+ pub allowed: &'a [&'a str],
783
+ }
784
+
785
+ impl LifecycleRefusedTransitionBlockedArgs<'_> {
786
+ /// The site's wording, every argument formatted by its declared row.
787
+ pub fn render_args(&self) -> String {
788
+ let allowed_text = list(self.allowed, false, true, " or ", "");
789
+ RefusalSite::LifecycleRefusedTransitionBlocked.render(&[
790
+ ("command", self.command),
791
+ ("field", self.field),
792
+ ("current", self.current),
793
+ ("allowed", allowed_text.as_str()),
794
+ ])
795
+ }
796
+ }
797
+
798
+ /// `RefusalSite::TypeMismatchValueObjectShape`'s arguments — `RefusalWording.render_site("TypeMismatch", "value_object_shape", ...)`.
799
+ #[derive(Debug, Clone, Copy)]
800
+ pub struct TypeMismatchValueObjectShapeArgs<'a> {
801
+ /// scalar
802
+ pub name: &'a str,
803
+ /// scalar
804
+ pub r#type: &'a str,
805
+ /// scalar
806
+ pub offered: &'a str,
807
+ }
808
+
809
+ impl TypeMismatchValueObjectShapeArgs<'_> {
810
+ /// The site's wording, every argument formatted by its declared row.
811
+ pub fn render_args(&self) -> String {
812
+ RefusalSite::TypeMismatchValueObjectShape.render(&[
813
+ ("name", self.name),
814
+ ("type", self.r#type),
815
+ ("offered", self.offered),
816
+ ])
817
+ }
818
+ }
819
+
820
+ /// `RefusalSite::TypeMismatchReferenceWrongShape`'s arguments — `RefusalWording.render_site("TypeMismatch", "reference_wrong_shape", ...)`.
821
+ #[derive(Debug, Clone, Copy)]
822
+ pub struct TypeMismatchReferenceWrongShapeArgs<'a> {
823
+ /// scalar
824
+ pub command: &'a str,
825
+ /// scalar
826
+ pub attribute: &'a str,
827
+ /// scalar
828
+ pub offered: &'a str,
829
+ /// scalar
830
+ pub known_by: &'a str,
831
+ }
832
+
833
+ impl TypeMismatchReferenceWrongShapeArgs<'_> {
834
+ /// The site's wording, every argument formatted by its declared row.
835
+ pub fn render_args(&self) -> String {
836
+ RefusalSite::TypeMismatchReferenceWrongShape.render(&[
837
+ ("command", self.command),
838
+ ("attribute", self.attribute),
839
+ ("offered", self.offered),
840
+ ("known_by", self.known_by),
841
+ ])
842
+ }
843
+ }
844
+
845
+ /// `RefusalSite::TypeMismatchMultiFieldScalar`'s arguments — `RefusalWording.render_site("TypeMismatch", "multi_field_scalar", ...)`.
846
+ #[derive(Debug, Clone, Copy)]
847
+ pub struct TypeMismatchMultiFieldScalarArgs<'a> {
848
+ /// scalar
849
+ pub r#type: &'a str,
850
+ }
851
+
852
+ impl TypeMismatchMultiFieldScalarArgs<'_> {
853
+ /// The site's wording, every argument formatted by its declared row.
854
+ pub fn render_args(&self) -> String {
855
+ RefusalSite::TypeMismatchMultiFieldScalar.render(&[
856
+ ("type", self.r#type),
857
+ ])
858
+ }
859
+ }
860
+
861
+ /// `RefusalSite::TypeMismatchCompositeIdentity`'s arguments — `RefusalWording.render_site("TypeMismatch", "composite_identity", ...)`.
862
+ #[derive(Debug, Clone, Copy)]
863
+ pub struct TypeMismatchCompositeIdentityArgs<'a> {
864
+ /// scalar
865
+ pub r#type: &'a str,
866
+ }
867
+
868
+ impl TypeMismatchCompositeIdentityArgs<'_> {
869
+ /// The site's wording, every argument formatted by its declared row.
870
+ pub fn render_args(&self) -> String {
871
+ RefusalSite::TypeMismatchCompositeIdentity.render(&[
872
+ ("type", self.r#type),
873
+ ])
874
+ }
875
+ }
876
+
877
+ /// `RefusalSite::TypeMismatchNumericField`'s arguments — `RefusalWording.render_site("TypeMismatch", "numeric_field", ...)`.
878
+ #[derive(Debug, Clone, Copy)]
879
+ pub struct TypeMismatchNumericFieldArgs<'a> {
880
+ /// scalar
881
+ pub r#type: &'a str,
882
+ /// scalar
883
+ pub field: &'a str,
884
+ /// scalar
885
+ pub expected: &'a str,
886
+ /// scalar
887
+ pub offered: &'a str,
888
+ }
889
+
890
+ impl TypeMismatchNumericFieldArgs<'_> {
891
+ /// The site's wording, every argument formatted by its declared row.
892
+ pub fn render_args(&self) -> String {
893
+ RefusalSite::TypeMismatchNumericField.render(&[
894
+ ("type", self.r#type),
895
+ ("field", self.field),
896
+ ("expected", self.expected),
897
+ ("offered", self.offered),
898
+ ])
899
+ }
900
+ }
901
+
902
+ /// `RefusalSite::TypeMismatchNonFiniteField`'s arguments — `RefusalWording.render_site("TypeMismatch", "non_finite_field", ...)`.
903
+ #[derive(Debug, Clone, Copy)]
904
+ pub struct TypeMismatchNonFiniteFieldArgs<'a> {
905
+ /// scalar
906
+ pub r#type: &'a str,
907
+ /// scalar
908
+ pub field: &'a str,
909
+ /// scalar
910
+ pub offered: &'a str,
911
+ }
912
+
913
+ impl TypeMismatchNonFiniteFieldArgs<'_> {
914
+ /// The site's wording, every argument formatted by its declared row.
915
+ pub fn render_args(&self) -> String {
916
+ RefusalSite::TypeMismatchNonFiniteField.render(&[
917
+ ("type", self.r#type),
918
+ ("field", self.field),
919
+ ("offered", self.offered),
920
+ ])
921
+ }
922
+ }
923
+
924
+ /// `RefusalSite::TypeMismatchIntegerRange`'s arguments — `RefusalWording.render_site("TypeMismatch", "integer_range", ...)`.
925
+ #[derive(Debug, Clone, Copy)]
926
+ pub struct TypeMismatchIntegerRangeArgs<'a> {
927
+ /// scalar
928
+ pub r#type: &'a str,
929
+ /// scalar
930
+ pub field: &'a str,
931
+ /// scalar
932
+ pub offered: &'a str,
933
+ }
934
+
935
+ impl TypeMismatchIntegerRangeArgs<'_> {
936
+ /// The site's wording, every argument formatted by its declared row.
937
+ pub fn render_args(&self) -> String {
938
+ RefusalSite::TypeMismatchIntegerRange.render(&[
939
+ ("type", self.r#type),
940
+ ("field", self.field),
941
+ ("offered", self.offered),
942
+ ])
943
+ }
944
+ }
945
+
946
+ /// `RefusalSite::TypeMismatchPatternMismatch`'s arguments — `RefusalWording.render_site("TypeMismatch", "pattern_mismatch", ...)`.
947
+ #[derive(Debug, Clone, Copy)]
948
+ pub struct TypeMismatchPatternMismatchArgs<'a> {
949
+ /// scalar
950
+ pub r#type: &'a str,
951
+ /// scalar
952
+ pub field: &'a str,
953
+ /// scalar
954
+ pub pattern: &'a str,
955
+ /// scalar
956
+ pub offered: &'a str,
957
+ }
958
+
959
+ impl TypeMismatchPatternMismatchArgs<'_> {
960
+ /// The site's wording, every argument formatted by its declared row.
961
+ pub fn render_args(&self) -> String {
962
+ RefusalSite::TypeMismatchPatternMismatch.render(&[
963
+ ("type", self.r#type),
964
+ ("field", self.field),
965
+ ("pattern", self.pattern),
966
+ ("offered", self.offered),
967
+ ])
968
+ }
969
+ }
970
+
971
+ /// `RefusalSite::TypeMismatchArithmeticAmount`'s arguments — `RefusalWording.render_site("TypeMismatch", "arithmetic_amount", ...)`.
972
+ #[derive(Debug, Clone, Copy)]
973
+ pub struct TypeMismatchArithmeticAmountArgs<'a> {
974
+ /// scalar
975
+ pub op: &'a str,
976
+ /// scalar
977
+ pub target: &'a str,
978
+ /// scalar
979
+ pub offered: &'a str,
980
+ }
981
+
982
+ impl TypeMismatchArithmeticAmountArgs<'_> {
983
+ /// The site's wording, every argument formatted by its declared row.
984
+ pub fn render_args(&self) -> String {
985
+ RefusalSite::TypeMismatchArithmeticAmount.render(&[
986
+ ("op", self.op),
987
+ ("target", self.target),
988
+ ("offered", self.offered),
989
+ ])
990
+ }
991
+ }
992
+
993
+ /// `RefusalSite::TypeMismatchArithmeticCurrent`'s arguments — `RefusalWording.render_site("TypeMismatch", "arithmetic_current", ...)`.
994
+ #[derive(Debug, Clone, Copy)]
995
+ pub struct TypeMismatchArithmeticCurrentArgs<'a> {
996
+ /// scalar
997
+ pub op: &'a str,
998
+ /// scalar
999
+ pub target: &'a str,
1000
+ /// scalar
1001
+ pub offered: &'a str,
1002
+ }
1003
+
1004
+ impl TypeMismatchArithmeticCurrentArgs<'_> {
1005
+ /// The site's wording, every argument formatted by its declared row.
1006
+ pub fn render_args(&self) -> String {
1007
+ RefusalSite::TypeMismatchArithmeticCurrent.render(&[
1008
+ ("op", self.op),
1009
+ ("target", self.target),
1010
+ ("offered", self.offered),
1011
+ ])
1012
+ }
1013
+ }
1014
+
1015
+ /// `RefusalSite::TypeMismatchArithmeticSharedField`'s arguments — `RefusalWording.render_site("TypeMismatch", "arithmetic_shared_field", ...)`.
1016
+ #[derive(Debug, Clone, Copy)]
1017
+ pub struct TypeMismatchArithmeticSharedFieldArgs<'a> {
1018
+ /// scalar
1019
+ pub op: &'a str,
1020
+ /// scalar
1021
+ pub target: &'a str,
1022
+ }
1023
+
1024
+ impl TypeMismatchArithmeticSharedFieldArgs<'_> {
1025
+ /// The site's wording, every argument formatted by its declared row.
1026
+ pub fn render_args(&self) -> String {
1027
+ RefusalSite::TypeMismatchArithmeticSharedField.render(&[
1028
+ ("op", self.op),
1029
+ ("target", self.target),
1030
+ ])
1031
+ }
1032
+ }
1033
+
1034
+ /// `RefusalSite::UnknownArgumentUnknownArgs`'s arguments — `RefusalWording.render_site("UnknownArgument", "unknown_args", ...)`.
1035
+ #[derive(Debug, Clone, Copy)]
1036
+ pub struct UnknownArgumentUnknownArgsArgs<'a> {
1037
+ /// scalar
1038
+ pub command: &'a str,
1039
+ /// list, sorted, joined ", ", empty reads ""
1040
+ pub unknown: &'a [&'a str],
1041
+ /// list, joined ", ", empty reads "none"
1042
+ pub declared: &'a [&'a str],
1043
+ }
1044
+
1045
+ impl UnknownArgumentUnknownArgsArgs<'_> {
1046
+ /// The site's wording, every argument formatted by its declared row.
1047
+ pub fn render_args(&self) -> String {
1048
+ let unknown_text = list(self.unknown, true, false, ", ", "");
1049
+ let declared_text = list(self.declared, false, false, ", ", "none");
1050
+ RefusalSite::UnknownArgumentUnknownArgs.render(&[
1051
+ ("command", self.command),
1052
+ ("unknown", unknown_text.as_str()),
1053
+ ("declared", declared_text.as_str()),
1054
+ ])
1055
+ }
1056
+ }
1057
+
1058
+ /// `RefusalSite::AbsentArgumentAbsentArgs`'s arguments — `RefusalWording.render_site("AbsentArgument", "absent_args", ...)`.
1059
+ #[derive(Debug, Clone, Copy)]
1060
+ pub struct AbsentArgumentAbsentArgsArgs<'a> {
1061
+ /// scalar
1062
+ pub command: &'a str,
1063
+ /// list, sorted, joined ", ", empty reads ""
1064
+ pub absent: &'a [&'a str],
1065
+ /// list, joined ", ", empty reads "none"
1066
+ pub declared: &'a [&'a str],
1067
+ }
1068
+
1069
+ impl AbsentArgumentAbsentArgsArgs<'_> {
1070
+ /// The site's wording, every argument formatted by its declared row.
1071
+ pub fn render_args(&self) -> String {
1072
+ let absent_text = list(self.absent, true, false, ", ", "");
1073
+ let declared_text = list(self.declared, false, false, ", ", "none");
1074
+ RefusalSite::AbsentArgumentAbsentArgs.render(&[
1075
+ ("command", self.command),
1076
+ ("absent", absent_text.as_str()),
1077
+ ("declared", declared_text.as_str()),
1078
+ ])
1079
+ }
1080
+ }
1081
+
1082
+ /// `RefusalSite::InvariantViolationClosedSetMember`'s arguments — `RefusalWording.render_site("InvariantViolation", "closed_set_member", ...)`.
1083
+ #[derive(Debug, Clone, Copy)]
1084
+ pub struct InvariantViolationClosedSetMemberArgs<'a> {
1085
+ /// scalar
1086
+ pub r#type: &'a str,
1087
+ /// list, quoted, joined ", ", empty reads ""
1088
+ pub admitted: &'a [&'a str],
1089
+ /// scalar
1090
+ pub offered: &'a str,
1091
+ }
1092
+
1093
+ impl InvariantViolationClosedSetMemberArgs<'_> {
1094
+ /// The site's wording, every argument formatted by its declared row.
1095
+ pub fn render_args(&self) -> String {
1096
+ let admitted_text = list(self.admitted, false, true, ", ", "");
1097
+ RefusalSite::InvariantViolationClosedSetMember.render(&[
1098
+ ("type", self.r#type),
1099
+ ("admitted", admitted_text.as_str()),
1100
+ ("offered", self.offered),
1101
+ ])
1102
+ }
1103
+ }
1104
+
1105
+ /// `RefusalSite::InvariantViolationValueObjectInvariant`'s arguments — `RefusalWording.render_site("InvariantViolation", "value_object_invariant", ...)`.
1106
+ #[derive(Debug, Clone, Copy)]
1107
+ pub struct InvariantViolationValueObjectInvariantArgs<'a> {
1108
+ /// scalar
1109
+ pub name: &'a str,
1110
+ /// scalar
1111
+ pub description: &'a str,
1112
+ /// scalar
1113
+ pub offered: &'a str,
1114
+ }
1115
+
1116
+ impl InvariantViolationValueObjectInvariantArgs<'_> {
1117
+ /// The site's wording, every argument formatted by its declared row.
1118
+ pub fn render_args(&self) -> String {
1119
+ RefusalSite::InvariantViolationValueObjectInvariant.render(&[
1120
+ ("name", self.name),
1121
+ ("description", self.description),
1122
+ ("offered", self.offered),
1123
+ ])
1124
+ }
1125
+ }
1126
+
1127
+ /// `RefusalSite::InvariantViolationAdmitsDeclaredSet`'s arguments — `RefusalWording.render_site("InvariantViolation", "admits_declared_set", ...)`.
1128
+ #[derive(Debug, Clone, Copy)]
1129
+ pub struct InvariantViolationAdmitsDeclaredSetArgs<'a> {
1130
+ /// scalar
1131
+ pub name: &'a str,
1132
+ /// scalar
1133
+ pub admits: &'a str,
1134
+ /// list, quoted, joined ", ", empty reads ""
1135
+ pub admitted: &'a [&'a str],
1136
+ /// scalar
1137
+ pub offered: &'a str,
1138
+ }
1139
+
1140
+ impl InvariantViolationAdmitsDeclaredSetArgs<'_> {
1141
+ /// The site's wording, every argument formatted by its declared row.
1142
+ pub fn render_args(&self) -> String {
1143
+ let admitted_text = list(self.admitted, false, true, ", ", "");
1144
+ RefusalSite::InvariantViolationAdmitsDeclaredSet.render(&[
1145
+ ("name", self.name),
1146
+ ("admits", self.admits),
1147
+ ("admitted", admitted_text.as_str()),
1148
+ ("offered", self.offered),
1149
+ ])
1150
+ }
1151
+ }
1152
+
1153
+ /// `RefusalSite::InvariantViolationUndeclaredSet`'s arguments — `RefusalWording.render_site("InvariantViolation", "undeclared_set", ...)`.
1154
+ #[derive(Debug, Clone, Copy)]
1155
+ pub struct InvariantViolationUndeclaredSetArgs<'a> {
1156
+ /// scalar
1157
+ pub name: &'a str,
1158
+ /// scalar
1159
+ pub admits: &'a str,
1160
+ }
1161
+
1162
+ impl InvariantViolationUndeclaredSetArgs<'_> {
1163
+ /// The site's wording, every argument formatted by its declared row.
1164
+ pub fn render_args(&self) -> String {
1165
+ RefusalSite::InvariantViolationUndeclaredSet.render(&[
1166
+ ("name", self.name),
1167
+ ("admits", self.admits),
1168
+ ])
1169
+ }
1170
+ }
1171
+
1172
+ /// `RefusalSite::InvariantViolationGroupByCollision`'s arguments — `RefusalWording.render_site("InvariantViolation", "group_by_collision", ...)`.
1173
+ #[derive(Debug, Clone, Copy)]
1174
+ pub struct InvariantViolationGroupByCollisionArgs<'a> {
1175
+ /// scalar
1176
+ pub read_model: &'a str,
1177
+ /// list, joined ", ", empty reads ""
1178
+ pub fields: &'a [&'a str],
1179
+ /// list, sorted, quoted, joined ", ", empty reads ""
1180
+ pub ids: &'a [&'a str],
1181
+ /// scalar
1182
+ pub key: &'a str,
1183
+ }
1184
+
1185
+ impl InvariantViolationGroupByCollisionArgs<'_> {
1186
+ /// The site's wording, every argument formatted by its declared row.
1187
+ pub fn render_args(&self) -> String {
1188
+ let fields_text = list(self.fields, false, false, ", ", "");
1189
+ let ids_text = list(self.ids, true, true, ", ", "");
1190
+ RefusalSite::InvariantViolationGroupByCollision.render(&[
1191
+ ("read_model", self.read_model),
1192
+ ("fields", fields_text.as_str()),
1193
+ ("ids", ids_text.as_str()),
1194
+ ("key", self.key),
1195
+ ])
1196
+ }
1197
+ }
1198
+
1199
+ /// `RefusalSite::UnauthorizedTenantRequired`'s arguments — `RefusalWording.render_site("Unauthorized", "tenant_required", ...)`.
1200
+ #[derive(Debug, Clone, Copy)]
1201
+ pub struct UnauthorizedTenantRequiredArgs<'a> {
1202
+ /// scalar
1203
+ pub query: &'a str,
1204
+ /// scalar
1205
+ pub field: &'a str,
1206
+ }
1207
+
1208
+ impl UnauthorizedTenantRequiredArgs<'_> {
1209
+ /// The site's wording, every argument formatted by its declared row.
1210
+ pub fn render_args(&self) -> String {
1211
+ RefusalSite::UnauthorizedTenantRequired.render(&[
1212
+ ("query", self.query),
1213
+ ("field", self.field),
1214
+ ])
1215
+ }
1216
+ }
1217
+
1218
+ /// `RefusalSite::UnauthorizedRoleMismatch`'s arguments — `RefusalWording.render_site("Unauthorized", "role_mismatch", ...)`.
1219
+ #[derive(Debug, Clone, Copy)]
1220
+ pub struct UnauthorizedRoleMismatchArgs<'a> {
1221
+ /// scalar
1222
+ pub command: &'a str,
1223
+ /// scalar
1224
+ pub role: &'a str,
1225
+ /// scalar
1226
+ pub caller_role: &'a str,
1227
+ }
1228
+
1229
+ impl UnauthorizedRoleMismatchArgs<'_> {
1230
+ /// The site's wording, every argument formatted by its declared row.
1231
+ pub fn render_args(&self) -> String {
1232
+ RefusalSite::UnauthorizedRoleMismatch.render(&[
1233
+ ("command", self.command),
1234
+ ("role", self.role),
1235
+ ("caller_role", self.caller_role),
1236
+ ])
1237
+ }
1238
+ }
1239
+
1240
+ /// `RefusalSite::UnauthorizedCrossTenantReference`'s arguments — `RefusalWording.render_site("Unauthorized", "cross_tenant_reference", ...)`.
1241
+ #[derive(Debug, Clone, Copy)]
1242
+ pub struct UnauthorizedCrossTenantReferenceArgs<'a> {
1243
+ /// scalar
1244
+ pub aggregate: &'a str,
1245
+ /// scalar
1246
+ pub field: &'a str,
1247
+ /// scalar
1248
+ pub tenant: &'a str,
1249
+ /// scalar
1250
+ pub attribute: &'a str,
1251
+ /// scalar
1252
+ pub target: &'a str,
1253
+ /// scalar
1254
+ pub target_field: &'a str,
1255
+ /// scalar
1256
+ pub other: &'a str,
1257
+ }
1258
+
1259
+ impl UnauthorizedCrossTenantReferenceArgs<'_> {
1260
+ /// The site's wording, every argument formatted by its declared row.
1261
+ pub fn render_args(&self) -> String {
1262
+ RefusalSite::UnauthorizedCrossTenantReference.render(&[
1263
+ ("aggregate", self.aggregate),
1264
+ ("field", self.field),
1265
+ ("tenant", self.tenant),
1266
+ ("attribute", self.attribute),
1267
+ ("target", self.target),
1268
+ ("target_field", self.target_field),
1269
+ ("other", self.other),
1270
+ ])
1271
+ }
1272
+ }
1273
+
1274
+ /// `RefusalSite::AttributeAbsentAbsentRead`'s arguments — `RefusalWording.render_site("AttributeAbsent", "absent_read", ...)`.
1275
+ #[derive(Debug, Clone, Copy)]
1276
+ pub struct AttributeAbsentAbsentReadArgs<'a> {
1277
+ /// scalar
1278
+ pub aggregate: &'a str,
1279
+ /// scalar
1280
+ pub field: &'a str,
1281
+ }
1282
+
1283
+ impl AttributeAbsentAbsentReadArgs<'_> {
1284
+ /// The site's wording, every argument formatted by its declared row.
1285
+ pub fn render_args(&self) -> String {
1286
+ RefusalSite::AttributeAbsentAbsentRead.render(&[
1287
+ ("aggregate", self.aggregate),
1288
+ ("field", self.field),
1289
+ ])
1290
+ }
1291
+ }
1292
+
1293
+ /// `RefusalSite::ProjectionAbsentAbsentRead`'s arguments — `RefusalWording.render_site("ProjectionAbsent", "absent_read", ...)`.
1294
+ #[derive(Debug, Clone, Copy)]
1295
+ pub struct ProjectionAbsentAbsentReadArgs<'a> {
1296
+ /// scalar
1297
+ pub aggregate: &'a str,
1298
+ /// scalar
1299
+ pub field: &'a str,
1300
+ /// scalar
1301
+ pub reference: &'a str,
1302
+ /// scalar
1303
+ pub remote_field: &'a str,
1304
+ }
1305
+
1306
+ impl ProjectionAbsentAbsentReadArgs<'_> {
1307
+ /// The site's wording, every argument formatted by its declared row.
1308
+ pub fn render_args(&self) -> String {
1309
+ RefusalSite::ProjectionAbsentAbsentRead.render(&[
1310
+ ("aggregate", self.aggregate),
1311
+ ("field", self.field),
1312
+ ("reference", self.reference),
1313
+ ("remote_field", self.remote_field),
1314
+ ])
1315
+ }
1316
+ }
1317
+
1318
+ #[cfg(test)]
1319
+ mod tests {
1320
+ use super::*;
1321
+
1322
+ #[test]
1323
+ fn every_site_renders_with_no_leftover_placeholder() {
1324
+ for site in RefusalSite::ALL {
1325
+ let template = site.template();
1326
+ let mut keys: Vec<String> = Vec::new();
1327
+ let mut current: Option<String> = None;
1328
+ for ch in template.chars() {
1329
+ match (ch, current.as_mut()) {
1330
+ ('{', _) => current = Some(String::new()),
1331
+ ('}', Some(key)) => {
1332
+ keys.push(key.clone());
1333
+ current = None;
1334
+ }
1335
+ (_, Some(key)) => key.push(ch),
1336
+ (_, None) => {}
1337
+ }
1338
+ }
1339
+ let dummies: Vec<(String, String)> = keys.iter().map(|k| (k.clone(), format!("<{k}>"))).collect();
1340
+ let pairs: Vec<(&str, &str)> = dummies.iter().map(|(k, v)| (k.as_str(), v.as_str())).collect();
1341
+ let rendered = site.render(&pairs);
1342
+ assert!(
1343
+ !rendered.contains('{') && !rendered.contains('}'),
1344
+ "{site:?} left an unrendered placeholder behind: {rendered:?}"
1345
+ );
1346
+ }
1347
+ }
1348
+
1349
+ #[test]
1350
+ fn render_args_matches_ruby_render_site() {
1351
+ assert_eq!(
1352
+ NotFoundCreatingNoIdentityArgs { command: "command \"x\"", aggregate: "aggregate \"x\"", identity: "identity \"x\"" }.render_args(),
1353
+ "command \"x\" creates a aggregate \"x\" — pass identity \"x\":"
1354
+ );
1355
+ assert_eq!(
1356
+ AlreadyExistsCreatingDuplicateArgs { command: "command \"x\"", aggregate: "aggregate \"x\"", identity: "identity \"x\"", offered: "offered \"x\"" }.render_args(),
1357
+ "command \"x\" creates a aggregate \"x\" that already exists — identity \"x\" offered \"x\""
1358
+ );
1359
+ assert_eq!(
1360
+ AlreadyExistsEntityDuplicateArgs { entity: "entity \"x\"", aggregate: "aggregate \"x\"", identity: "identity \"x\"", offered: &[] }.render_args(),
1361
+ "a entity \"x\" already exists on aggregate \"x\" — identity \"x\" "
1362
+ );
1363
+ assert_eq!(
1364
+ AlreadyExistsEntityDuplicateArgs { entity: "entity \"x\"", aggregate: "aggregate \"x\"", identity: "identity \"x\"", offered: &["only \"one\""] }.render_args(),
1365
+ "a entity \"x\" already exists on aggregate \"x\" — identity \"x\" only \"one\""
1366
+ );
1367
+ assert_eq!(
1368
+ AlreadyExistsEntityDuplicateArgs { entity: "entity \"x\"", aggregate: "aggregate \"x\"", identity: "identity \"x\"", offered: &["zeta", "alpha", "mid"] }.render_args(),
1369
+ "a entity \"x\" already exists on aggregate \"x\" — identity \"x\" zeta, alpha, mid"
1370
+ );
1371
+ assert_eq!(
1372
+ NotFoundActingNoIdentityArgs { command: "command \"x\"", aggregate: "aggregate \"x\"", identity: "identity \"x\"" }.render_args(),
1373
+ "command \"x\" acts on an existing aggregate \"x\" — pass identity \"x\":"
1374
+ );
1375
+ assert_eq!(
1376
+ NotFoundRecordMissingArgs { aggregate: "aggregate \"x\"", identity: "identity \"x\"", offered: "offered \"x\"" }.render_args(),
1377
+ "no aggregate \"x\" with identity \"x\" offered \"x\""
1378
+ );
1379
+ assert_eq!(
1380
+ NotFoundEntityParentNoIdentityArgs { command: "command \"x\"", aggregate: "aggregate \"x\"", entity: "entity \"x\"", identity: "identity \"x\"" }.render_args(),
1381
+ "command \"x\" acts on a aggregate \"x\"'s entity \"x\" — pass identity \"x\":"
1382
+ );
1383
+ assert_eq!(
1384
+ UnknownVerbEntityUnknownArgs { aggregate: "aggregate \"x\"", entity: "entity \"x\"" }.render_args(),
1385
+ "aggregate \"x\" has no entity \"entity \\\"x\\\"\""
1386
+ );
1387
+ assert_eq!(
1388
+ NotFoundEntityElementNoIdentityArgs { command: "command \"x\"", entity: "entity \"x\"", identity: "identity \"x\"" }.render_args(),
1389
+ "command \"x\" acts on one entity \"x\" — pass identity \"x\":"
1390
+ );
1391
+ assert_eq!(
1392
+ NotFoundEntityElementMissingArgs { entity: "entity \"x\"", identity: "identity \"x\"", wants: "wants \"x\"", aggregate: "aggregate \"x\"", parent_id: "parent_id \"x\"" }.render_args(),
1393
+ "no entity \"x\" with identity \"x\" wants \"x\" on aggregate \"x\" parent_id \"x\""
1394
+ );
1395
+ assert_eq!(
1396
+ NotFoundReferenceTargetMissingArgs { target: "target \"x\"", heads: "heads \"x\"", key: "key \"x\"" }.render_args(),
1397
+ "no target \"x\" with heads \"x\" \"key \\\"x\\\"\""
1398
+ );
1399
+ assert_eq!(
1400
+ NotFoundReadModelReferenceMissingArgs { aggregate: "aggregate \"x\"", offered: "offered \"x\"" }.render_args(),
1401
+ "no aggregate \"x\" with reference offered \"x\""
1402
+ );
1403
+ assert_eq!(
1404
+ TypeMismatchReadModelObjectReferenceArgs { query: "query \"x\"", field: "field \"x\"" }.render_args(),
1405
+ "query \"x\" refused — a reference is an id, and field \"x\" arrived as an object"
1406
+ );
1407
+ assert_eq!(
1408
+ UnknownVerbNoQueryArgs { aggregate: "aggregate \"x\"", query: "query \"x\"" }.render_args(),
1409
+ "aggregate \"x\" has no query \"query \\\"x\\\"\""
1410
+ );
1411
+ assert_eq!(
1412
+ UnknownVerbEntityQueryMissingArgs { entity: "entity \"x\"", query: "query \"x\"" }.render_args(),
1413
+ "entity \"x\" has no query \"query \\\"x\\\"\""
1414
+ );
1415
+ assert_eq!(
1416
+ UnknownVerbEntityHoldsNoListArgs { aggregate: "aggregate \"x\"", entity: "entity \"x\"" }.render_args(),
1417
+ "aggregate \"x\" holds no list of entity \"x\""
1418
+ );
1419
+ assert_eq!(
1420
+ UnknownVerbEntityNoCommandArgs { entity: "entity \"x\"", command: "command \"x\"" }.render_args(),
1421
+ "entity \"x\" has no command \"command \\\"x\\\"\""
1422
+ );
1423
+ assert_eq!(
1424
+ UnknownVerbAggregateNoCommandArgs { aggregate: "aggregate \"x\"", command: "command \"x\"" }.render_args(),
1425
+ "aggregate \"x\" has no command \"command \\\"x\\\"\""
1426
+ );
1427
+ assert_eq!(
1428
+ UnknownVerbPortNoOperationArgs { port: "port \"x\"", operation: "operation \"x\"" }.render_args(),
1429
+ "port \"x\" has no operation \"operation \\\"x\\\"\""
1430
+ );
1431
+ assert_eq!(
1432
+ UnknownVerbNoDomainArgs { domain: "domain \"x\"", verb: "verb \"x\"" }.render_args(),
1433
+ "no domain \"domain \\\"x\\\"\" loaded (verb verb \"x\")"
1434
+ );
1435
+ assert_eq!(
1436
+ UnknownVerbNoReadModelArgs { domain: "domain \"x\"", query: "query \"x\"" }.render_args(),
1437
+ "domain \"x\" has no read model \"query \\\"x\\\"\""
1438
+ );
1439
+ assert_eq!(
1440
+ UnknownVerbNotFullyQualifiedArgs { verb: "verb \"x\"" }.render_args(),
1441
+ "\"verb \\\"x\\\"\" is not a fully-qualified verb (Domain::Aggregate.Command)"
1442
+ );
1443
+ assert_eq!(
1444
+ UnknownVerbNoAggregateArgs { domain: "domain \"x\"", aggregate: "aggregate \"x\"" }.render_args(),
1445
+ "domain \"x\" has no aggregate \"aggregate \\\"x\\\"\""
1446
+ );
1447
+ assert_eq!(
1448
+ LifecycleRefusedTransitionBlockedArgs { command: "command \"x\"", field: "field \"x\"", current: "current \"x\"", allowed: &[] }.render_args(),
1449
+ "command \"x\" refused — field \"x\" is current \"x\", and command \"x\" moves it only from "
1450
+ );
1451
+ assert_eq!(
1452
+ LifecycleRefusedTransitionBlockedArgs { command: "command \"x\"", field: "field \"x\"", current: "current \"x\"", allowed: &["only \"one\""] }.render_args(),
1453
+ "command \"x\" refused — field \"x\" is current \"x\", and command \"x\" moves it only from \"only \\\"one\\\"\""
1454
+ );
1455
+ assert_eq!(
1456
+ LifecycleRefusedTransitionBlockedArgs { command: "command \"x\"", field: "field \"x\"", current: "current \"x\"", allowed: &["zeta", "alpha", "mid"] }.render_args(),
1457
+ "command \"x\" refused — field \"x\" is current \"x\", and command \"x\" moves it only from \"zeta\" or \"alpha\" or \"mid\""
1458
+ );
1459
+ assert_eq!(
1460
+ TypeMismatchValueObjectShapeArgs { name: "name \"x\"", r#type: "type \"x\"", offered: "offered \"x\"" }.render_args(),
1461
+ "name \"x\" is a type \"x\" — pass its fields as an object, not offered \"x\""
1462
+ );
1463
+ assert_eq!(
1464
+ TypeMismatchReferenceWrongShapeArgs { command: "command \"x\"", attribute: "attribute \"x\"", offered: "offered \"x\"", known_by: "known_by \"x\"" }.render_args(),
1465
+ "command \"x\" refused — a reference is an id, and attribute \"x\" arrived as offered \"x\"known_by \"x\""
1466
+ );
1467
+ assert_eq!(
1468
+ TypeMismatchMultiFieldScalarArgs { r#type: "type \"x\"" }.render_args(),
1469
+ "type \"x\" has multiple fields and cannot stand in for a scalar"
1470
+ );
1471
+ assert_eq!(
1472
+ TypeMismatchCompositeIdentityArgs { r#type: "type \"x\"" }.render_args(),
1473
+ "type \"x\" is a composite identity — an identity must have exactly one field"
1474
+ );
1475
+ assert_eq!(
1476
+ TypeMismatchNumericFieldArgs { r#type: "type \"x\"", field: "field \"x\"", expected: "expected \"x\"", offered: "offered \"x\"" }.render_args(),
1477
+ "type \"x\".field \"x\" expects expected \"x\", got offered \"x\""
1478
+ );
1479
+ assert_eq!(
1480
+ TypeMismatchNonFiniteFieldArgs { r#type: "type \"x\"", field: "field \"x\"", offered: "offered \"x\"" }.render_args(),
1481
+ "type \"x\".field \"x\" must be a finite number, got offered \"x\""
1482
+ );
1483
+ assert_eq!(
1484
+ TypeMismatchIntegerRangeArgs { r#type: "type \"x\"", field: "field \"x\"", offered: "offered \"x\"" }.render_args(),
1485
+ "type \"x\".field \"x\" must fit in a 64-bit integer, got offered \"x\""
1486
+ );
1487
+ assert_eq!(
1488
+ TypeMismatchPatternMismatchArgs { r#type: "type \"x\"", field: "field \"x\"", pattern: "pattern \"x\"", offered: "offered \"x\"" }.render_args(),
1489
+ "type \"x\".field \"x\" must match pattern \"x\", got offered \"x\""
1490
+ );
1491
+ assert_eq!(
1492
+ TypeMismatchArithmeticAmountArgs { op: "op \"x\"", target: "target \"x\"", offered: "offered \"x\"" }.render_args(),
1493
+ "op \"x\" of target \"x\" needs an Integer, got offered \"x\""
1494
+ );
1495
+ assert_eq!(
1496
+ TypeMismatchArithmeticCurrentArgs { op: "op \"x\"", target: "target \"x\"", offered: "offered \"x\"" }.render_args(),
1497
+ "op \"x\" of target \"x\" needs an Integer target \"x\", got offered \"x\""
1498
+ );
1499
+ assert_eq!(
1500
+ TypeMismatchArithmeticSharedFieldArgs { op: "op \"x\"", target: "target \"x\"" }.render_args(),
1501
+ "op \"x\" of target \"x\" needs a value object with one shared Integer field"
1502
+ );
1503
+ assert_eq!(
1504
+ UnknownArgumentUnknownArgsArgs { command: "command \"x\"", unknown: &[], declared: &[] }.render_args(),
1505
+ "command \"x\" does not declare — it takes none"
1506
+ );
1507
+ assert_eq!(
1508
+ UnknownArgumentUnknownArgsArgs { command: "command \"x\"", unknown: &["only \"one\""], declared: &["only \"one\""] }.render_args(),
1509
+ "command \"x\" does not declare only \"one\" — it takes only \"one\""
1510
+ );
1511
+ assert_eq!(
1512
+ UnknownArgumentUnknownArgsArgs { command: "command \"x\"", unknown: &["zeta", "alpha", "mid"], declared: &["zeta", "alpha", "mid"] }.render_args(),
1513
+ "command \"x\" does not declare alpha, mid, zeta — it takes zeta, alpha, mid"
1514
+ );
1515
+ assert_eq!(
1516
+ AbsentArgumentAbsentArgsArgs { command: "command \"x\"", absent: &[], declared: &[] }.render_args(),
1517
+ "command \"x\" was not given — it takes none"
1518
+ );
1519
+ assert_eq!(
1520
+ AbsentArgumentAbsentArgsArgs { command: "command \"x\"", absent: &["only \"one\""], declared: &["only \"one\""] }.render_args(),
1521
+ "command \"x\" was not given only \"one\" — it takes only \"one\""
1522
+ );
1523
+ assert_eq!(
1524
+ AbsentArgumentAbsentArgsArgs { command: "command \"x\"", absent: &["zeta", "alpha", "mid"], declared: &["zeta", "alpha", "mid"] }.render_args(),
1525
+ "command \"x\" was not given alpha, mid, zeta — it takes zeta, alpha, mid"
1526
+ );
1527
+ assert_eq!(
1528
+ InvariantViolationClosedSetMemberArgs { r#type: "type \"x\"", admitted: &[], offered: "offered \"x\"" }.render_args(),
1529
+ "type \"x\" admits — got offered \"x\""
1530
+ );
1531
+ assert_eq!(
1532
+ InvariantViolationClosedSetMemberArgs { r#type: "type \"x\"", admitted: &["only \"one\""], offered: "offered \"x\"" }.render_args(),
1533
+ "type \"x\" admits \"only \\\"one\\\"\" — got offered \"x\""
1534
+ );
1535
+ assert_eq!(
1536
+ InvariantViolationClosedSetMemberArgs { r#type: "type \"x\"", admitted: &["zeta", "alpha", "mid"], offered: "offered \"x\"" }.render_args(),
1537
+ "type \"x\" admits \"zeta\", \"alpha\", \"mid\" — got offered \"x\""
1538
+ );
1539
+ assert_eq!(
1540
+ InvariantViolationValueObjectInvariantArgs { name: "name \"x\"", description: "description \"x\"", offered: "offered \"x\"" }.render_args(),
1541
+ "name \"x\" invariant violated — description \"x\" (given offered \"x\")"
1542
+ );
1543
+ assert_eq!(
1544
+ InvariantViolationAdmitsDeclaredSetArgs { name: "name \"x\"", admits: "admits \"x\"", admitted: &[], offered: "offered \"x\"" }.render_args(),
1545
+ "name \"x\" admits admits \"x\" — — got offered \"x\""
1546
+ );
1547
+ assert_eq!(
1548
+ InvariantViolationAdmitsDeclaredSetArgs { name: "name \"x\"", admits: "admits \"x\"", admitted: &["only \"one\""], offered: "offered \"x\"" }.render_args(),
1549
+ "name \"x\" admits admits \"x\" — \"only \\\"one\\\"\" — got offered \"x\""
1550
+ );
1551
+ assert_eq!(
1552
+ InvariantViolationAdmitsDeclaredSetArgs { name: "name \"x\"", admits: "admits \"x\"", admitted: &["zeta", "alpha", "mid"], offered: "offered \"x\"" }.render_args(),
1553
+ "name \"x\" admits admits \"x\" — \"zeta\", \"alpha\", \"mid\" — got offered \"x\""
1554
+ );
1555
+ assert_eq!(
1556
+ InvariantViolationUndeclaredSetArgs { name: "name \"x\"", admits: "admits \"x\"" }.render_args(),
1557
+ "name \"x\" admits admits \"x\", which this chapter does not declare — a closed set is named Aggregate::SetName, and it must be one the bluebook actually holds"
1558
+ );
1559
+ assert_eq!(
1560
+ InvariantViolationGroupByCollisionArgs { read_model: "read_model \"x\"", fields: &[], ids: &[], key: "key \"x\"" }.render_args(),
1561
+ "read_model \"x\" groups by , but rows share key \"x\" — a group_by leaf holds one row; add a field that tells them apart"
1562
+ );
1563
+ assert_eq!(
1564
+ InvariantViolationGroupByCollisionArgs { read_model: "read_model \"x\"", fields: &["only \"one\""], ids: &["only \"one\""], key: "key \"x\"" }.render_args(),
1565
+ "read_model \"x\" groups by only \"one\", but rows \"only \\\"one\\\"\" share key \"x\" — a group_by leaf holds one row; add a field that tells them apart"
1566
+ );
1567
+ assert_eq!(
1568
+ InvariantViolationGroupByCollisionArgs { read_model: "read_model \"x\"", fields: &["zeta", "alpha", "mid"], ids: &["zeta", "alpha", "mid"], key: "key \"x\"" }.render_args(),
1569
+ "read_model \"x\" groups by zeta, alpha, mid, but rows \"alpha\", \"mid\", \"zeta\" share key \"x\" — a group_by leaf holds one row; add a field that tells them apart"
1570
+ );
1571
+ assert_eq!(
1572
+ UnauthorizedTenantRequiredArgs { query: "query \"x\"", field: "field \"x\"" }.render_args(),
1573
+ "query \"x\" declares authorize with tenant: field \"x\" — pass field \"x\": to name which field \"x\" this ask is scoped to"
1574
+ );
1575
+ assert_eq!(
1576
+ UnauthorizedRoleMismatchArgs { command: "command \"x\"", role: "role \"x\"", caller_role: "caller_role \"x\"" }.render_args(),
1577
+ "command \"x\" refused — role: role \"x\", and the caller stated caller_role \"x\""
1578
+ );
1579
+ assert_eq!(
1580
+ UnauthorizedCrossTenantReferenceArgs { aggregate: "aggregate \"x\"", field: "field \"x\"", tenant: "tenant \"x\"", attribute: "attribute \"x\"", target: "target \"x\"", target_field: "target_field \"x\"", other: "other \"x\"" }.render_args(),
1581
+ "aggregate \"x\" field \"x\" is tenant \"x\", but attribute \"x\" names a target \"x\" whose own target_field \"x\" is other \"x\" — a cross-tenant reference"
1582
+ );
1583
+ assert_eq!(
1584
+ AttributeAbsentAbsentReadArgs { aggregate: "aggregate \"x\"", field: "field \"x\"" }.render_args(),
1585
+ "aggregate \"x\" field \"x\" is absent on this record — declared, not optional, and added since it was written. Backfill it in a translation (backfill :field \"x\", default: ...), or declare it optional: true"
1586
+ );
1587
+ assert_eq!(
1588
+ ProjectionAbsentAbsentReadArgs { aggregate: "aggregate \"x\"", field: "field \"x\"", reference: "reference \"x\"", remote_field: "remote_field \"x\"" }.render_args(),
1589
+ "aggregate \"x\" field \"x\" is not yet projected on this record — declared via projects :field \"x\", but no rebuild sweep has populated it. Run the sweep, or read reference \"x\".remote_field \"x\" directly if this rule cannot wait"
1590
+ );
1591
+ }
1592
+ }