hecks 3.0.5 → 3.1.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 (170) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +24 -12
  3. data/lib/hecks/adapters/driven/lambda/client.rb +1 -1
  4. data/lib/hecks/adapters/driven/lambda.rb +1 -1
  5. data/lib/hecks/adapters/driven/tenant_provisioner.rb +2 -2
  6. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +59 -32
  7. data/lib/hecks/bluebook/hexagon.rb +45 -25
  8. data/lib/hecks/bluebook/model_check.rb +7 -7
  9. data/lib/hecks/chapters.rb +32 -3
  10. data/lib/hecks/cli/check_era.rb +1 -1
  11. data/lib/hecks/cli/deploy_template_diff.rb +1 -1
  12. data/lib/hecks/cli/doc_coverage.rb +1 -1
  13. data/lib/hecks/cli/domain_stub.rb +128 -0
  14. data/lib/hecks/cli/domain_writer.rb +39 -0
  15. data/lib/hecks/cli/interview_agent.rb +59 -0
  16. data/lib/hecks/cli/interview_draft.rb +246 -0
  17. data/lib/hecks/cli/interview_run.rb +87 -0
  18. data/lib/hecks/cli/interview_session.rb +299 -0
  19. data/lib/hecks/cli/model_check.rb +1 -1
  20. data/lib/hecks/cli/project_cli.rb +51 -29
  21. data/lib/hecks/cli/reference.rb +2 -1
  22. data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +1 -1
  23. data/lib/hecks/cli/seed_semantics_corpus.rb +3 -3
  24. data/lib/hecks/cli/spec_example.rb +1 -1
  25. data/lib/hecks/cli/stress_concurrency_specs.rb +14 -5
  26. data/lib/hecks/corpus.rb +12 -8
  27. data/lib/hecks/deploy/bluebook/deploy.bluebook +85 -12
  28. data/lib/hecks/deploy/oidc.json +5 -0
  29. data/lib/hecks/doc/reference.rb +4 -3
  30. data/lib/hecks/doors/cli_door.rb +13 -13
  31. data/lib/hecks/doors/cli_runner.rb +53 -33
  32. data/lib/hecks/doors/launcher_options.rb +5 -5
  33. data/lib/hecks/doors/mcp_door.rb +40 -18
  34. data/lib/hecks/doors/mcp_door_scope.rb +244 -24
  35. data/lib/hecks/doors/usage_cache.rb +123 -0
  36. data/lib/hecks/doors.rb +1 -1
  37. data/lib/hecks/embryonaut_bluebook.rb +2 -2
  38. data/lib/hecks/forms/banking_presentation.rb +1 -1
  39. data/lib/hecks/framework/bluebook/compliance.bluebook +1 -1
  40. data/lib/hecks/framework/bluebook/console_settings.bluebook +1 -1
  41. data/lib/hecks/framework/bluebook/framework.hecksagon +4 -4
  42. data/lib/hecks/framework.rb +1 -1
  43. data/lib/hecks/fuzzing/combination_miner.rb +1 -1
  44. data/lib/hecks/fuzzing/concurrent_dispatch.rb +1 -1
  45. data/lib/hecks/fuzzing/differential.rb +4 -2
  46. data/lib/hecks/fuzzing/era_boundary.rb +1 -1
  47. data/lib/hecks/fuzzing/form_census.rb +2 -2
  48. data/lib/hecks/fuzzing/generated_domain_check.rb +1 -1
  49. data/lib/hecks/fuzzing/isolated_boot.rb +10 -3
  50. data/lib/hecks/fuzzing/persistence_parity.rb +2 -2
  51. data/lib/hecks/fuzzing/target_capabilities.rb +3 -3
  52. data/lib/hecks/gate/stages.yml +5 -5
  53. data/lib/hecks/grammar/grammar.hecksagon +2 -2
  54. data/lib/hecks/hecks/adapters/deploy_toolchain.rb +4 -4
  55. data/lib/hecks/hecks/adapters/finding_github.adapter +7 -0
  56. data/lib/hecks/hecks/adapters/finding_github.rb +114 -0
  57. data/lib/hecks/hecks/adapters/host_http.rb +4 -3
  58. data/lib/hecks/hecks/adapters/local_files.rb +59 -0
  59. data/lib/hecks/hecks/adapters/site_toolchain.adapter +7 -0
  60. data/lib/hecks/hecks/adapters/site_toolchain.rb +54 -0
  61. data/lib/hecks/hecks/adapters/terminal.rb +15 -0
  62. data/lib/hecks/hecks/codebase.bluebook +4 -3
  63. data/lib/hecks/hecks/context_map.hecksagon +2 -2
  64. data/lib/hecks/hecks/custodian.bluebook +81 -3
  65. data/lib/hecks/hecks/hecks.bluebook +18 -0
  66. data/lib/hecks/hecks/hecks.hecksagon +16 -4
  67. data/lib/hecks/hecks/hecks.world +7 -6
  68. data/lib/hecks/hecks/site.behaviors +17 -0
  69. data/lib/hecks/hecks/site.world +10 -0
  70. data/lib/hecks/language/bluebook/bluebook.hecksagon +1 -1
  71. data/lib/hecks/language/hecksagon/hecksagon.bluebook +24 -47
  72. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +4 -4
  73. data/lib/hecks/projections/deploy/box/settings.rb +324 -0
  74. data/lib/hecks/projections/deploy/box/templates/box.yaml.tmpl +268 -0
  75. data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +68 -0
  76. data/lib/hecks/projections/deploy/box/templates/fetch-secrets.sh +21 -0
  77. data/lib/hecks/projections/deploy/box/templates/rds.yaml.tmpl +181 -0
  78. data/lib/hecks/projections/deploy/box/templates/render-compose-taskdef.sh.tmpl +49 -0
  79. data/lib/hecks/projections/deploy/box/templates/render-compose.sh.tmpl +43 -0
  80. data/lib/hecks/projections/deploy/box/templates/restore-to-rds.sh.tmpl +91 -0
  81. data/lib/hecks/projections/deploy/box/templates/verify-copy.sh.tmpl +58 -0
  82. data/lib/hecks/projections/deploy/box.rb +553 -0
  83. data/lib/hecks/projections/deploy/fargate/cdn.rb +13 -1
  84. data/lib/hecks/projections/deploy/fargate.rb +1 -1
  85. data/lib/hecks/projections/deploy/lambda.rb +11 -10
  86. data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +1 -1
  87. data/lib/hecks/projections/diagrams.rb +2 -2
  88. data/lib/hecks/projections/site/edge/behaviours.rb +107 -0
  89. data/lib/hecks/projections/site/edge/checks.rb +137 -0
  90. data/lib/hecks/projections/site/edge/pattern.rb +50 -0
  91. data/lib/hecks/projections/site/edge/rules.rb +128 -0
  92. data/lib/hecks/projections/site/edge.rb +136 -0
  93. data/lib/hecks/projections/site/regions.rb +44 -0
  94. data/lib/hecks/projections/site/routes_ts.rb +284 -0
  95. data/lib/hecks/projections/site/site_cdn.rb +78 -0
  96. data/lib/hecks/projections/site/table/checks.rb +124 -0
  97. data/lib/hecks/projections/site/table/row_builder.rb +155 -0
  98. data/lib/hecks/projections/site/table.rb +98 -0
  99. data/lib/hecks/projections.rb +2 -0
  100. data/lib/hecks/projector/cli_projector.rb +153 -111
  101. data/lib/hecks/quality_control/adapters/agent.adapter +1 -1
  102. data/lib/hecks/quality_control/adapters/agent.rb +2 -2
  103. data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +3 -3
  104. data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +8 -8
  105. data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +3 -3
  106. data/lib/hecks/quality_control/cli/qa_generated_domains.rb +4 -4
  107. data/lib/hecks/quality_control/cli/qa_log_bug.rb +2 -2
  108. data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +6 -5
  109. data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +2 -2
  110. data/lib/hecks/quality_control/cli/qa_postgres_role.rb +5 -5
  111. data/lib/hecks/quality_control/cli/qa_pr_check.rb +3 -3
  112. data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +3 -3
  113. data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +2 -2
  114. data/lib/hecks/quality_control/cli/qa_sweep.rb +10 -9
  115. data/lib/hecks/quality_control/cli/qa_tick.rb +3 -3
  116. data/lib/hecks/quality_control/quality_control.bluebook +18 -18
  117. data/lib/hecks/quality_control/quality_control.hecksagon +1 -1
  118. data/lib/hecks/runtime/loader.rb +31 -8
  119. data/lib/hecks/runtime/registry/verification.rb +15 -29
  120. data/lib/hecks/runtime/registry.rb +14 -20
  121. data/lib/hecks/rust_build/append_optionals.rb +79 -0
  122. data/lib/hecks/rust_build/conformance_fuzz.rb +2 -1
  123. data/lib/hecks/rust_build/domain_name.rb +26 -0
  124. data/lib/hecks/rust_build/kernel_input.rb +58 -0
  125. data/lib/hecks/rust_build/project_rust/codegen_run.rb +143 -0
  126. data/lib/hecks/rust_build/project_rust/root_mod.rb +1 -1
  127. data/lib/hecks/rust_build/project_rust.rb +57 -24
  128. data/lib/hecks/rust_build/rust_literal.rb +33 -0
  129. data/lib/hecks/rust_build/write_if_changed.rb +86 -0
  130. data/lib/hecks/site/bluebook/site.bluebook +205 -0
  131. data/lib/hecks/site/bluebook/site.hecksagon +5 -0
  132. data/lib/hecks/site/bluebook/site.ports.hecksagon +15 -0
  133. data/lib/hecks/sme/bluebook/sme.bluebook +336 -0
  134. data/lib/hecks/sme/bluebook/sme.hecksagon +5 -0
  135. data/lib/hecks/storehouse.rb +37 -7
  136. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +1 -1
  137. data/lib/hecks/three_zero/forms.yml +88 -88
  138. data/lib/hecks/tickets/bluebook/tickets.bluebook +331 -0
  139. data/lib/hecks/tickets/bluebook/tickets.hecksagon +11 -0
  140. data/lib/hecks/tickets/bluebook/tickets.ports.hecksagon +26 -0
  141. data/lib/hecks/tools/ci_gates.rb +1 -1
  142. data/lib/hecks/tools/deploy_recipe.rb +14 -6
  143. data/lib/hecks/tools/oidc_manifests.rb +2 -1
  144. data/lib/hecks/tools/sequence_script.rb +2 -2
  145. data/lib/hecks/tools/site_routes.rb +152 -0
  146. data/lib/hecks/tools/tenant_provisioning.rb +1 -1
  147. data/lib/hecks/tools.rb +1 -0
  148. data/lib/hecks/version.rb +1 -1
  149. data/lib/hecks.rb +1 -0
  150. data/rust/build/src/cargo_sync.rs +1 -1
  151. data/rust/build/src/pipeline.rs +23 -16
  152. data/rust/build/src/resolve.rs +39 -6
  153. data/rust/codegen/src/json_codec.rs +3 -0
  154. data/rust/codegen/src/naming.rs +4 -0
  155. data/rust/codegen/src/types.rs +45 -0
  156. data/rust/host/HECKS_RELEASE +1 -1
  157. data/rust/host/src/api.rs +1 -1
  158. data/rust/host/src/dispatch.rs +87 -7
  159. data/rust/host/src/needs.rs +111 -0
  160. data/rust/parser/src/keywords.rs +7 -6
  161. data/rust/parser/src/main.rs +4 -3
  162. data/rust/parser/src/parse/chapter.rs +1 -1
  163. data/rust/parser/src/parse/hecksagon.rs +25 -10
  164. data/rust/project/mutations.rb +4 -30
  165. data/rust/project/naming.rb +8 -28
  166. data/rust/project/write_if_changed.rb +4 -80
  167. data/rust/project_rust_pipeline.rb +16 -12
  168. data/rust/src/kernel/cli.rs +2 -0
  169. data/rust/src/kernel/needs.rs +74 -1
  170. metadata +51 -2
@@ -1,127 +1,127 @@
1
1
  # Each bin/ script and exe/hecks route, and the hecks 3.0 form that replaces it: the verb spelling the
2
2
  # 3.0 launcher answers to (ADR 0080, section 7), with QualityControl verbs after `hecks quality_control`.
3
3
  ---
4
- argument_gate_matrix: hecks argument_gate_matrix [--confirm] (writes only with --confirm)
5
- backfill_era_projections: hecks backfill_projections <domain>
6
- behaviors: hecks run_behaviors subject=<path>
7
- bench: hecks bench [domains=pizzas,banking] [targets=] [iterations=1000] [warmup=200]
4
+ argument_gate_matrix: hecks conformance_run.argument_gate_matrix [--confirm] (writes only with --confirm)
5
+ backfill_era_projections: hecks era.backfill_projections <domain>
6
+ behaviors: hecks operation.run_behaviors subject=<path>
7
+ bench: hecks fuzz_run.bench [domains=pizzas,banking] [targets=] [iterations=1000] [warmup=200]
8
8
  [runs=3] [rust_binary=] [format=markdown] [output=]
9
- canonicalise: hecks canonicalise <file.json>
10
- check_engine_agreement: hecks check_engine_agreement
11
- check_era: hecks check_era <url> expected=era-file [timeout=10]
12
- codemod_hoist_local_givens: hecks hoist_local_givens --confirm
13
- codemod_implicit_append_fields: hecks drop_implicit_append_fields --confirm
14
- compact: hecks compact <domain> [aggregates=A,B] --confirm
9
+ canonicalise: hecks style_run.canonicalise <file.json>
10
+ check_engine_agreement: hecks conformance_run.check_engine_agreement
11
+ check_era: hecks host.check_era <url> expected=era-file [timeout=]
12
+ codemod_hoist_local_givens: hecks codemod_run.hoist_local_givens --confirm
13
+ codemod_implicit_append_fields: hecks codemod_run.drop_implicit_append_fields --confirm
14
+ compact: hecks era.compact <domain> [aggregates=A,B] --confirm
15
15
  console: hecks console [subject=<domain>]
16
- corpus: hecks rust_domains; hecks regen_order; hecks corpus_rust_coverage
17
- deploy_template_diff: hecks deploy diff before=a.yaml after=b.yaml [--json] [--strict]
18
- doc_coverage: hecks measure_doc_coverage
16
+ corpus: hecks corpus_run.rust_domains; hecks corpus_run.regen_order; hecks corpus_run.corpus_rust_coverage
17
+ deploy_template_diff: hecks deploy template_comparison.diff before=a.yaml after=b.yaml [--json] [--strict]
18
+ doc_coverage: hecks conformance_run.measure_doc_coverage
19
19
  docs: hecks docs [domain-path] [aggregate]
20
- evolve: hecks word_status; hecks propose <word> context=X [body=none] [inner=] [opens=]
21
- [fills=]; hecks admit|deprecate|retire <word> context=X; hecks rename <word> context=X
22
- new_name=Y; hecks propose_argument <word> context=X kind=K [required=false] [at=N]
23
- [named=] [fills=] [pairs_shape=]; hecks admit_argument|deprecate_argument|retire_argument
20
+ evolve: hecks language_run.word_status; hecks language_run.propose <word> context=X [body=none] [inner=] [opens=]
21
+ [fills=]; hecks language_run.admit|deprecate|retire <word> context=X; hecks language_run.rename <word> context=X
22
+ new_name=Y; hecks language_run.propose_argument <word> context=X kind=K [required=false] [at=N]
23
+ [named=] [fills=] [pairs_shape=]; hecks language_run.admit_argument|deprecate_argument|retire_argument
24
24
  <word> context=X [at=N] [named=]
25
- expression_projection: hecks project_expression_tables [--stdout]
26
- follow: hecks follow <domain> [aggregate=Name] [since=N] [interval=0.5] [wait=N] [--from-now] [--stream]
27
- fuzz: hecks fuzz [domain] [seeds=20] [steps=30] [workers=] [adapter=memory]
28
- generate: hecks generate_sequence <domain> [seed=1] [steps=30] [adversarial=0.0]
25
+ expression_projection: hecks language_run.project_expression_tables [--stdout]
26
+ follow: hecks operation.follow <domain> [aggregate=Name] [since=N] [interval=0.5] [wait=N] [--from-now] [--stream]
27
+ fuzz: hecks fuzz_run.fuzz [domain] [seeds=20] [steps=30] [workers=] [adapter=memory]
28
+ generate: hecks fuzz_run.generate_sequence <domain> [seed=1] [steps=30] [adversarial=0.0]
29
29
  hecks_mcp_door: hecks mcp [--stdio]
30
- hecks_query_ir_mcp: hecks serve_query_ir_mcp
31
- heki_compact: hecks compact_heki <domain> [aggregates=A,B] --confirm
32
- history: hecks history <domain>
30
+ hecks_query_ir_mcp: hecks corpus_run.serve_query_ir_mcp
31
+ heki_compact: hecks era.compact_heki <domain> [aggregates=A,B] --confirm
32
+ history: hecks introspection.history <domain>
33
33
  ir: hecks ir <domain> [--translations] | hecks ir --meta
34
- lint_deploy_recipes: hecks deploy lint [makefiles=a,b]
35
- merge_tail: hecks merge_tail <domain> winners=id:old,id:new --confirm
34
+ lint_deploy_recipes: hecks deploy makefile_check.lint [makefiles=a,b]
35
+ merge_tail: hecks era.merge_tail <domain> winners=id:old,id:new --confirm
36
36
  model_check: hecks model_check [--strict] [--profile client] [<domain> …]
37
37
  narrate: hecks narrate [domain-path] [aggregate]
38
- pattern-cases: hecks record_pattern_cases
39
- present: hecks present [port=4567]
40
- project: hecks refresh_projections subject=<domain>
41
- project_bootstrap_table: hecks project_bootstrap_table
38
+ pattern-cases: hecks test_suite_run.record_pattern_cases
39
+ present: hecks corpus_run.present [port=4567]
40
+ project: hecks operation.refresh_projections subject=<domain>
41
+ project_bootstrap_table: hecks language_run.project_bootstrap_table
42
42
  project_cli: hecks project_cli [domain-path …]
43
- project_deploy: hecks deploy project <domain> [tenant=] [schema=] [out=] [environment=]
43
+ project_deploy: hecks deploy recipe.project <domain> [tenant=] [schema=] [out=] [environment=]
44
44
  project_diagrams: hecks project_diagrams <domain-path> <ChapterName>
45
- project_field_hints: hecks project_field_hints
46
- project_glossary: hecks glossary <domain> chapter=Name
47
- project_kernel_capabilities: hecks project_kernel_capabilities
48
- project_model: hecks project_model
49
- project_oidc: hecks deploy project_oidc [domains=a,b]
50
- project_parser_table: hecks project_parser_table
51
- project_refusal_wording: hecks project_refusal_wording
52
- project_reserved_names: hecks project_reserved_names
53
- project_rust: hecks project_rust <domain>
54
- project_rust_vocabulary: hecks project_rust_vocabulary
55
- project_tenant: hecks deploy provision <domain_dir> slug=s domain= realm= schema=
56
- database= [adapter=PostgresEra]; hecks deploy reprovision <tenant> directory= database=
45
+ project_field_hints: hecks language_run.project_field_hints
46
+ project_glossary: hecks introspection.glossary <domain> chapter=Name
47
+ project_kernel_capabilities: hecks kernel_run.project_kernel_capabilities
48
+ project_model: hecks language_run.project_model
49
+ project_oidc: hecks deploy oidc_manifest.project_oidc [domains=a,b]
50
+ project_parser_table: hecks language_run.project_parser_table
51
+ project_refusal_wording: hecks language_run.project_refusal_wording
52
+ project_reserved_names: hecks language_run.project_reserved_names
53
+ project_rust: hecks build.project_rust <domain>
54
+ project_rust_vocabulary: hecks language_run.project_rust_vocabulary
55
+ project_tenant: hecks deploy tenant.provision <domain_dir> slug=s domain= realm= schema=
56
+ database= [adapter=PostgresEra]; hecks deploy tenant.reprovision <tenant> directory= database=
57
57
  [adapter=PostgresEra]
58
- project_vocabulary: hecks project_vocabulary
59
- project_wasm: hecks build_wasm <domain>
60
- project_wasm_browser: hecks build_browser_wasm <domain>
58
+ project_vocabulary: hecks language_run.project_vocabulary
59
+ project_wasm: hecks build.build_wasm <domain>
60
+ project_wasm_browser: hecks build.build_browser_wasm <domain>
61
61
  qa_concurrency_racer: not user-facing; ProcessPool starts it as hecks quality_control
62
- race domain= database= schema= verb= step_arguments=
63
- qa_discover_external_domains: hecks quality_control discover_external_domains [arguments="--projects-dir
62
+ sweep.race domain= database= schema= verb= step_arguments=
63
+ qa_discover_external_domains: hecks quality_control target.discover_external_domains [arguments="--projects-dir
64
64
  ~/Projects --max-depth 3 --known-path PATH …"]
65
- qa_domain_novelty: hecks quality_control judge_novelty <domain> [arguments="--against
65
+ qa_domain_novelty: hecks quality_control target.judge_novelty <domain> [arguments="--against
66
66
  PATH …"]
67
- qa_generated_domains: hecks quality_control check_generated_domains [arguments="--domains
67
+ qa_generated_domains: hecks quality_control target.check_generated_domains [arguments="--domains
68
68
  3 --start N --forms a,b --seeds 5 --steps 25 --adversarial 0.3 --rust --shrink-budget
69
69
  200 --domain-shrink-budget 40 --promote dir --name N --from-dials --blueprint F
70
70
  --source F"]
71
- qa_log_bug: hecks quality_control log sweep=<sweep id> reference= sequence=N title=
71
+ qa_log_bug: hecks quality_control bug.log sweep=<sweep id> reference= sequence=N title=
72
72
  demonstration= symptom= expectation= submitter= [tags=a,b] [name=] [reproduced=yes|no]
73
- qa_mine_combinations: hecks quality_control mine_combinations [arguments="--candidates
73
+ qa_mine_combinations: hecks quality_control target.mine_combinations [arguments="--candidates
74
74
  3 --rust --seeds 5 --steps 25 --adversarial 0.3 --repair-rounds 1 --agent CMD --from
75
75
  DIR --against PATH --brief"]
76
76
  qa_open_pr: hecks quality_control patch.open bug=BUG#n number=N url=… branch=… commit=SHA
77
77
  title=… [now=]; hecks quality_control improvement.open [angle=ANGLE-n] number=N
78
78
  url=… branch=… title=… [now=]
79
- qa_postgres_migrate: hecks quality_control migrate_ledger_from_heki domain=<domain_dir>
79
+ qa_postgres_migrate: hecks quality_control sweep.migrate_ledger_from_heki domain=<domain_dir>
80
80
  data=<heki_dir> [arguments="[aggregate …] --force"] (a dry run without --force)
81
- qa_postgres_role: hecks quality_control create_ledger_role <database> [role=hecks_qa]
82
- qa_pr_check: hecks quality_control check_pull_requests
81
+ qa_postgres_role: hecks quality_control sweep.create_ledger_role <database> [role=hecks_qa]
82
+ qa_pr_check: hecks quality_control clearance.check_pull_requests
83
83
  qa_seed_angles: hecks quality_control angle.seed
84
84
  qa_seed_targets: hecks quality_control target.seed
85
- qa_sweep: hecks quality_control ask run [target=] [arguments="--all --seeds N --steps
85
+ qa_sweep: hecks quality_control query sweep.run [target=] [arguments="--all --seeds N --steps
86
86
  N --adversarial F --role-draw F --dry-run F --self-consistency BOOL --modes a,b
87
- --persistence-parity --no-parity"]; hecks quality_control release <target> [now=]
87
+ --persistence-parity --no-parity"]; hecks quality_control target.release <target> [now=]
88
88
  [next_streak=] [capabilities=] [yield_score=]
89
- qa_tick: hecks quality_control tick
90
- query_ir: hecks ir_constructs [names=a,b]; hecks ir_duplicates [domains=a,b] [--meta];
91
- hecks ir_impact name=N field=F
92
- reattest_era: hecks reattest <domain> era=N --confirm
93
- reference: hecks project_reference
94
- refresh_rspec_runtime_baseline: hecks refresh_runtime_baseline [workers=6] [from_run=ID]
95
- regen_codegen_domains: hecks regenerate_corpus [--check]
96
- regenerate_persistence_legacy_fixtures: hecks regenerate_legacy_fixtures --confirm
97
- release: hecks publish [--gem-only] [--npm-only] [--npm-local] [--no-wait] --confirm
89
+ qa_tick: hecks quality_control sweep.tick
90
+ query_ir: hecks corpus_run.ir_constructs [names=a,b]; hecks corpus_run.ir_duplicates [domains=a,b] [--meta];
91
+ hecks corpus_run.ir_impact name=N field=F
92
+ reattest_era: hecks era.reattest <domain> era=N --confirm
93
+ reference: hecks language_run.project_reference
94
+ refresh_rspec_runtime_baseline: hecks test_suite_run.refresh_runtime_baseline [workers=] [from_run=ID]
95
+ regen_codegen_domains: hecks regeneration_run.regenerate_corpus [--check]
96
+ regenerate_persistence_legacy_fixtures: hecks test_suite_run.regenerate_legacy_fixtures --confirm
97
+ release: hecks publishing_run.publish [--gem-only] [--npm-only] [--npm-local] [--no-wait] --confirm
98
98
  (without --confirm, the old --dry-run)
99
- release_gem: hecks publish_gem --confirm
100
- rspec_io_parallel_files: hecks list_io_parallel_specs exclude=REGEX [tags=] [check=file];
101
- hecks write_io_parallel_spec_list exclude=REGEX [tags=] write=file --confirm
102
- rspec_shard_files: hecks shard_specs group=1 groups=N [runtime_log=]
99
+ release_gem: hecks publishing_run.publish_gem --confirm
100
+ rspec_io_parallel_files: hecks test_suite_run.list_io_parallel_specs exclude=REGEX [tags=] [check=file];
101
+ hecks test_suite_run.write_io_parallel_spec_list exclude=REGEX [tags=] write=file --confirm
102
+ rspec_shard_files: hecks test_suite_run.shard_specs group=1 groups=N [runtime_log=]
103
103
  run: hecks run [domain] <verb [name=value …] | script.json | - | '{"steps":[…]}'>
104
- rust_conformance: hecks check_conformance <domain> script=steps.json [artifact=native]
105
- rust_conformance_fuzz: hecks fuzz_conformance <domain> artifact=native [seeds=10]
104
+ rust_conformance: hecks build.check_conformance <domain> script=steps.json [artifact=native]
105
+ rust_conformance_fuzz: hecks build.fuzz_conformance <domain> artifact=native [seeds=10]
106
106
  [steps=25]
107
- rust_coverage: hecks rust_coverage <module> [codegen=ruby]; hecks check_coverage_allowlist
108
- rust_kernel_coverage: hecks measure_kernel_coverage
109
- scaffold_translation: hecks scaffold_translation <domain>
110
- seed_semantics_corpus: hecks seed_semantics_corpus [fixture=name]
111
- shape: hecks shape <domain>
112
- smoke_http: hecks smoke_http path=/p [url=] [header=] [scheme=timestamped]
107
+ rust_coverage: hecks build.rust_coverage <module> [codegen=ruby]; hecks build.check_coverage_allowlist
108
+ rust_kernel_coverage: hecks kernel_run.measure_kernel_coverage
109
+ scaffold_translation: hecks era.scaffold_translation <domain>
110
+ seed_semantics_corpus: hecks test_suite_run.seed_semantics_corpus [fixture=name]
111
+ shape: hecks introspection.shape <domain>
112
+ smoke_http: hecks operation.smoke_http path=/p [url=] [header=] [scheme=timestamped]
113
113
  [payload=] [payload_file=] [health_path=] [state_path=]
114
114
  smoke_test: hecks smoke_test [domain]
115
- spec_example: hecks run_spec_example file=path example=text
116
- standardize_comments: hecks report_comments paths=a,b [only=] [--json] [top=20]; hecks
117
- check_comments paths=…; hecks fix_comments paths=… --confirm; hecks write_comment_baseline
118
- --confirm; hecks check_comments_unchanged ref=REF
119
- standardize_comments_rust: hecks report_rust_comments paths=a,b [only=] [--json] [top=N];
120
- hecks check_rust_comments paths=… [only=]; hecks fix_rust_comments paths=… [only=]
115
+ spec_example: hecks test_suite_run.run_spec_example file=path example=text
116
+ standardize_comments: hecks style_run.report_comments paths=a,b [only=] [--json] [top=20]; hecks
117
+ style_run.check_comments paths=…; hecks style_run.fix_comments paths=… --confirm; hecks style_run.write_comment_baseline
118
+ --confirm; hecks style_run.check_comments_unchanged ref=REF
119
+ standardize_comments_rust: hecks style_run.report_rust_comments paths=a,b [only=] [--json] [top=N];
120
+ hecks style_run.check_rust_comments paths=… [only=]; hecks style_run.fix_rust_comments paths=… [only=]
121
121
  --confirm
122
- statements: hecks statements <domain> chapter=Name
122
+ statements: hecks introspection.statements <domain> chapter=Name
123
123
  stores: hecks stores <domain>
124
- stress_concurrency_specs: hecks stress_concurrency [runs=30] [parallel=] [seed_start=1]
125
- translation_audit: hecks audit_translation <domain>; hecks approve_translation <domain>
124
+ stress_concurrency_specs: hecks test_suite_run.stress_concurrency [runs=] [parallel=] [seed_start=]
125
+ translation_audit: hecks era.audit_translation <domain>; hecks era.approve_translation <domain>
126
126
  [snapshot=] [host_version=] [rehearsal=pass|fail] [rehearsed_at=] --confirm
127
- vendor_bluebook: hecks vendor <package[@version]> [from=path] [root=path]
127
+ vendor_bluebook: hecks package.vendor <package[@version]> [from=path] [root=path]
@@ -0,0 +1,331 @@
1
+ # The Tickets chapter: what a maintainer observed about Hecks that needs a decision or a fix, the
2
+ # and the decisions that settle them.
3
+ #
4
+ # QualityControl has its own Ticket, the issue raised for a Bug in an outside tracker, and the
5
+ # Hecks domain has its own Release, the record of a gem version. A Finding sits before both: it is
6
+ # any observation, not yet a proven bug, and it needs no sweep or failing test to be recorded.
7
+ #
8
+ # A Finding is the record. A gap, a parity divergence, a QA finding and an idea are kinds of it, not
9
+ # separate aggregates. Hecks owns the finding's state; GitHub is driven from it through the
10
+ # GitHubIssues port, which a hecksagon binds (nothing here reads GitHub back). A finding exists whether
11
+ # or not GitHub answers: each lifecycle event asks the port, and a refused ask is recorded on the
12
+ # finding as a sync failure that a later run retries.
13
+ #
14
+ # An Adr is a decision record with its own lifecycle, linked to the finding it settles.
15
+ Hecks.bluebook "Tickets" do
16
+ vision "Track what Hecks needs, decide it, ship it, and drive GitHub from the record."
17
+
18
+ aggregate "Finding" do
19
+ description "One thing observed about Hecks that needs a decision or a fix: reported, triaged, then resolved or dismissed."
20
+
21
+ attribute :finding, FindingKey
22
+ attribute :title, Title
23
+ attribute :body, Body, optional: true
24
+ attribute :kind, Kind, optional: true
25
+ attribute :severity, Severity, optional: true
26
+ attribute :source, Source
27
+ attribute :fingerprint, Fingerprint, optional: true
28
+ attribute :issue_number, Number, optional: true
29
+ attribute :fix_pr_number, Number, optional: true
30
+ attribute :dismissal, Body, optional: true
31
+ attribute :sync_failure, Body, optional: true
32
+ identified_by :finding
33
+
34
+ value_object "FindingKey" do
35
+ attribute :value, String, pattern: '[^ \t\n\r]'
36
+
37
+ invariant("a finding is named") { !value.to_s.empty? }
38
+ end
39
+
40
+ value_object "Title" do
41
+ attribute :value, String
42
+
43
+ invariant("a finding has a title") { !value.to_s.empty? }
44
+ end
45
+
46
+ value_object "Body" do
47
+ attribute :value, String
48
+ end
49
+
50
+ # What the finding is: a `gap` Hecks cannot yet express, a `parity` divergence between the Ruby
51
+ # and Rust runtimes, a `qa` finding from the QA loop, or an `idea`.
52
+ value_object "Kind" do
53
+ attribute :value, String, one_of: ["gap", "parity", "qa", "idea"]
54
+ end
55
+
56
+ value_object "Severity" do
57
+ attribute :value, String, one_of: ["low", "medium", "high"]
58
+ end
59
+
60
+ # Where it came from: the QA loop, work for a client, a parity check, or a maintainer by hand.
61
+ value_object "Source" do
62
+ attribute :value, String, one_of: ["qa_loop", "client_work", "parity_check", "maintainer"]
63
+ end
64
+
65
+ # The same finding refiled by the QA loop carries the same fingerprint, so a report of it while an
66
+ # open finding holds it changes nothing.
67
+ value_object "Fingerprint" do
68
+ attribute :value, String, pattern: '[^ \t\n\r]'
69
+ end
70
+
71
+ value_object "Number" do
72
+ attribute :value, Integer
73
+
74
+ invariant("a number is positive") { value.positive? }
75
+ end
76
+
77
+ lifecycle :status, default: "reported" do
78
+ transition "Triage" => "triaged", from: %w[reported triaged]
79
+ transition "Resolve" => "resolved", from: "triaged"
80
+ transition "Dismiss" => "dismissed", from: %w[reported triaged]
81
+ transition "Reopen" => "triaged", from: %w[resolved dismissed]
82
+ end
83
+
84
+ command "Report" do
85
+ goal "Record something observed about Hecks as a finding"
86
+
87
+ attribute :finding, FindingKey
88
+ attribute :title, Title
89
+ attribute :body, Body, optional: true
90
+ attribute :source, Source
91
+ attribute :fingerprint, Fingerprint, optional: true
92
+
93
+ sets :finding
94
+ sets :title
95
+ sets :body
96
+ sets :source
97
+ sets :fingerprint
98
+
99
+ emits "FindingReported"
100
+ end
101
+
102
+ # A failed Codebase run reports itself: the run's key names the finding and doubles as its
103
+ # fingerprint, so the same run failing again while its finding is open changes nothing.
104
+ command "ReportFailedRun" do
105
+ goal "Record a failed conformance or gate run as a finding"
106
+
107
+ attribute :finding, FindingKey
108
+ attribute :body, Body
109
+
110
+ sets :finding
111
+ sets :body
112
+ sets :fingerprint, to: "run"
113
+ sets :title, to: "A Codebase run failed"
114
+ sets :source, to: "qa_loop"
115
+
116
+ emits "RunFindingReported"
117
+ end
118
+
119
+ command "Triage" do
120
+ role "Maintainer"
121
+ goal "Give a finding its kind and severity"
122
+
123
+ reference_to Finding
124
+ attribute :kind, Kind
125
+ attribute :severity, Severity
126
+
127
+ sets :kind
128
+ sets :severity
129
+
130
+ emits "FindingTriaged"
131
+ end
132
+
133
+ command "LinkFix" do
134
+ role "Maintainer"
135
+ goal "Record the pull request that fixes a triaged finding"
136
+
137
+ reference_to Finding
138
+ attribute :fix_pr_number, Number
139
+
140
+ sets :fix_pr_number
141
+
142
+ emits "FixLinked"
143
+ end
144
+
145
+ command "Resolve" do
146
+ role "Maintainer"
147
+ goal "Close a triaged finding as resolved"
148
+
149
+ reference_to Finding
150
+
151
+ emits "FindingResolved"
152
+ end
153
+
154
+ command "Dismiss" do
155
+ role "Maintainer"
156
+ goal "Close a finding without a fix, with the reason"
157
+
158
+ reference_to Finding
159
+ attribute :dismissal, Body
160
+
161
+ sets :dismissal
162
+
163
+ emits "FindingDismissed"
164
+ end
165
+
166
+ command "Reopen" do
167
+ role "Maintainer"
168
+ goal "Take a resolved or dismissed finding back to triaged, as when a fix regresses"
169
+
170
+ reference_to Finding
171
+
172
+ emits "FindingReopened"
173
+ end
174
+
175
+ command "RecordIssue" do
176
+ goal "Record the GitHub issue number once the issue is opened"
177
+
178
+ reference_to Finding
179
+ attribute :issue_number, Number
180
+
181
+ sets :issue_number
182
+
183
+ emits "IssueRecorded"
184
+ end
185
+
186
+ command "RecordSyncFailure" do
187
+ goal "Record that GitHub could not be driven, so a later run retries"
188
+
189
+ reference_to Finding
190
+ attribute :sync_failure, Body
191
+
192
+ sets :sync_failure
193
+
194
+ emits "SyncFailed"
195
+ end
196
+
197
+ query "Open" do
198
+ description "Every finding not yet resolved or dismissed."
199
+ where(status: { in: "reported,triaged" })
200
+ order_by :finding
201
+ end
202
+ end
203
+
204
+ aggregate "Adr" do
205
+ description "A decision record: drafted, accepted, and possibly superseded, linked to the tickets it settles."
206
+
207
+ attribute :adr, AdrNumber
208
+ attribute :title, AdrTitle
209
+ attribute :supersedes, AdrNumber, optional: true
210
+ attribute :settles, FindingKey, optional: true
211
+ identified_by :adr
212
+
213
+ value_object "AdrNumber" do
214
+ attribute :value, String, pattern: '\A[0-9]{4}\z'
215
+ end
216
+
217
+ value_object "AdrTitle" do
218
+ attribute :value, String
219
+
220
+ invariant("a decision has a title") { !value.to_s.empty? }
221
+ end
222
+
223
+ value_object "FindingKey" do
224
+ attribute :value, String, pattern: '[^ \t\n\r]'
225
+ end
226
+
227
+ lifecycle :status, default: "draft" do
228
+ transition "Accept" => "accepted", from: "draft"
229
+ transition "Supersede" => "superseded", from: "accepted"
230
+ end
231
+
232
+ command "Draft" do
233
+ role "Maintainer"
234
+ goal "Open a decision record, optionally for the finding it settles"
235
+
236
+ attribute :adr, AdrNumber
237
+ attribute :title, AdrTitle
238
+ attribute :settles, FindingKey, optional: true
239
+
240
+ sets :adr
241
+ sets :title
242
+ sets :settles
243
+
244
+ emits "AdrDrafted"
245
+ end
246
+
247
+ command "Accept" do
248
+ role "Maintainer"
249
+ goal "Record that the decision was accepted"
250
+
251
+ reference_to Adr
252
+
253
+ emits "AdrAccepted"
254
+ end
255
+
256
+ command "Supersede" do
257
+ role "Maintainer"
258
+ goal "Record that a later decision replaces this one"
259
+
260
+ reference_to Adr
261
+ attribute :supersedes, AdrNumber
262
+
263
+ sets :supersedes
264
+
265
+ emits "AdrSuperseded"
266
+ end
267
+
268
+ query "Standing" do
269
+ description "Every decision that is accepted and not superseded."
270
+ where(status: "accepted")
271
+ order_by :adr
272
+ end
273
+ end
274
+
275
+ # Each lifecycle event drives GitHub. A finding's own state never waits on the answer.
276
+ policy "OpenIssueWhenReported" do
277
+ on "Finding.FindingReported"
278
+ trigger Finding::GitHubIssues::OpenIssue, with: { finding: :finding }
279
+ end
280
+
281
+ policy "OpenIssueWhenRunReported" do
282
+ on "Finding.RunFindingReported"
283
+ trigger Finding::GitHubIssues::OpenIssue, with: { finding: :finding }
284
+ end
285
+
286
+ policy "LabelIssueWhenTriaged" do
287
+ on "Finding.FindingTriaged"
288
+ trigger Finding::GitHubIssues::LabelIssue, with: { finding: :finding }
289
+ end
290
+
291
+ policy "CommentWhenFixLinked" do
292
+ on "Finding.FixLinked"
293
+ trigger Finding::GitHubIssues::CommentOnIssue, with: { finding: :finding }
294
+ end
295
+
296
+ policy "CloseIssueWhenResolved" do
297
+ on "Finding.FindingResolved"
298
+ trigger Finding::GitHubIssues::CloseIssue, with: { finding: :finding }
299
+ end
300
+
301
+ policy "CloseIssueWhenDismissed" do
302
+ on "Finding.FindingDismissed"
303
+ trigger Finding::GitHubIssues::CloseIssue, with: { finding: :finding }
304
+ end
305
+
306
+ policy "ReopenIssueWhenReopened" do
307
+ on "Finding.FindingReopened"
308
+ trigger Finding::GitHubIssues::ReopenIssue, with: { finding: :finding }
309
+ end
310
+
311
+ # A conformance or gate run that faults files its own finding.
312
+ policy "ReportWhenConformanceFaulted" do
313
+ on "ConformanceRun.ConformanceFaulted"
314
+ trigger Finding::ReportFailedRun, with: { finding: :run, body: :refusal }
315
+ end
316
+
317
+ policy "ReportWhenGateFaulted" do
318
+ on "GateRun.GateFaulted"
319
+ trigger Finding::ReportFailedRun, with: { finding: :run, body: :refusal }
320
+ end
321
+
322
+ policy "RecordTheIssue" do
323
+ on "Finding.IssueOpened"
324
+ trigger Finding::RecordIssue, with: { issue_number: :issue_number }
325
+ end
326
+
327
+ policy "RecordTheSyncFailure" do
328
+ on "Finding.GitHubRefused"
329
+ trigger Finding::RecordSyncFailure, with: { sync_failure: :refusal }
330
+ end
331
+ end
@@ -0,0 +1,11 @@
1
+ # The Tickets domain, bound so it boots standing alone (a fuzz or model_check boot of this
2
+ # directory). The GitHubIssues port every attaching hecksagon shares is in tickets.ports.hecksagon.
3
+ Hecks.hecksagon "Tickets" do
4
+ attaches "Governance"
5
+ persisted_by "Memory"
6
+ end
7
+
8
+ # The anti-corruption layer for Governance, which the chapter's roles are checked against.
9
+ Hecks.hecksagon "Governance" do
10
+ persisted_by "Memory"
11
+ end
@@ -0,0 +1,26 @@
1
+ # The port Tickets declares, for every hecksagon that attaches the chapter (`Chapters` loads this
2
+ # file with it). Each lifecycle event of a finding asks the GitHubIssues port, which the Hecks domain
3
+ # binds (lib/hecks/hecks/adapters/finding_github.rb): the outside a finding reaches. The ask is
4
+ # answered with the record's own arguments or refused with a reason, and a refusal is recorded on the
5
+ # finding and never blocks it. The port has to be declared even where no adapter binds it, so the
6
+ # policies have a target and model_check's deaf-policy check can see it.
7
+ #
8
+ # Only OpenIssue answers with the issue number, so only its answer is recorded on the finding; the
9
+ # other asks answer with a line saying what was done.
10
+ Hecks.hecksagon "Tickets" do
11
+ Tickets::Finding.port "GitHubIssues" do
12
+ asks "OpenIssue", to: Finding do
13
+ attribute :finding, FindingKey
14
+ answers "IssueOpened"
15
+ refuses "GitHubRefused"
16
+ end
17
+
18
+ %w[LabelIssue CommentOnIssue CloseIssue ReopenIssue].each do |ask|
19
+ asks ask, to: Finding do
20
+ attribute :finding, FindingKey
21
+ answers "GitHubAnswered"
22
+ refuses "GitHubRefused"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -102,7 +102,7 @@ module Hecks
102
102
  " - uses: ./.github/actions/hecks-environment",
103
103
  " - id: diff",
104
104
  " name: #{quoted(gate.fetch('label'))}",
105
- " run: bundle exec exe/hecks decide_ci_gate gate=#{name} --wait",
105
+ " run: bundle exec exe/hecks regeneration_run.decide_ci_gate gate=#{name} --wait",
106
106
  " # END GENERATED ci_gate #{name}"
107
107
  ].join("\n")
108
108
  end
@@ -11,7 +11,7 @@ module Hecks
11
11
  # target and dispatches to the matching `Projector` export, writing the recipe (template,
12
12
  # scripts and Makefile) under `deploy/<stack>/` of the checkout.
13
13
  #
14
- # hecks deploy project <domain> [--tenant=<slug>] [--schema=<name>]
14
+ # hecks deploy recipe.project <domain> [--tenant=<slug>] [--schema=<name>]
15
15
  # [--out=<dir>] [--environment=<name>]
16
16
  #
17
17
  # `--environment` layers an overlay `.world` file over the base one; a missing overlay is an
@@ -96,7 +96,7 @@ module Hecks
96
96
 
97
97
  File.exist?(world_file) or
98
98
  abort "#{world_file} does not exist — a domain needs a .world file to declare " \
99
- "deployed_to(\"AwsLambda\") or deployed_to(\"AwsFargate\")"
99
+ "deployed_to(\"AwsLambda\"), deployed_to(\"AwsFargate\") or deployed_to(\"AwsBox\")"
100
100
  world_file
101
101
  end
102
102
 
@@ -150,7 +150,7 @@ module Hecks
150
150
  # Loads the whole registry a domain boots with, not just its own `.bluebook`, because a
151
151
  # cross-domain invoke grant can live in any attached chapter. A domain with no bluebook of
152
152
  # its own (the QA ledger) gets its chapter from the hecksagon's `Chapters.load!`. `root:` is
153
- # required or `uses_embryonaut_bluebook` refuses with "needs a registry with a root to
153
+ # required or `attaches ... from: :vendor` refuses with "needs a registry with a root to
154
154
  # vendor from".
155
155
  #
156
156
  # @param domain [String] the domain directory
@@ -176,15 +176,16 @@ module Hecks
176
176
  # @param deploy_settings [Hash] the world's `deployed_to` settings
177
177
  # @param world_file [String] the `.world` file, named in the refusal
178
178
  # @param domain [String] the domain directory, named in the refusal
179
- # @return [Symbol] `:aws_lambda` or `:aws_fargate`
180
- # @raise [SystemExit] with an example block when the world declares neither
179
+ # @return [Symbol] `:aws_lambda`, `:aws_fargate` or `:aws_box`
180
+ # @raise [SystemExit] with an example block when the world declares none of them
181
181
  def target_key(deploy_settings, world_file, domain)
182
182
  case deploy_settings[:adapter]
183
183
  when "AwsLambda" then :aws_lambda
184
184
  when "AwsFargate" then :aws_fargate
185
+ when "AwsBox" then :aws_box
185
186
  else
186
187
  abort <<~MSG
187
- #{world_file} declares no deployed_to("AwsLambda") or deployed_to("AwsFargate") block. Add one, e.g.:
188
+ #{world_file} declares no deployed_to("AwsLambda"), deployed_to("AwsFargate") or deployed_to("AwsBox") block. Add one, e.g.:
188
189
 
189
190
  deployed_to("AwsLambda") do
190
191
  region "us-east-1"
@@ -201,6 +202,13 @@ module Hecks
201
202
  port 8080
202
203
  end
203
204
 
205
+ or:
206
+
207
+ deployed_to("AwsBox") do
208
+ region "us-east-1"
209
+ containers [{ name: "web", port: 8080 }]
210
+ end
211
+
204
212
  then re-run hecks deploy project #{domain}.
205
213
  MSG
206
214
  end