hecks 6.0.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/exe/hecks +19 -12
- data/lib/hecks/adapters/driven/claude_code.rb +2 -2
- data/lib/hecks/adapters/driven/folder.rb +10 -1
- data/lib/hecks/adapters/driven/folder_overlay.rb +15 -0
- data/lib/hecks/adapters/driven/heki.rb +1 -1
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +1 -1
- data/lib/hecks/adapters/driven/memory/outbox_rows.rb +2 -2
- data/lib/hecks/adapters/driven/postgres/name_guard.rb +25 -0
- data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -3
- data/lib/hecks/adapters/driven/postgres/repository.rb +1 -1
- data/lib/hecks/adapters/driven/postgres/shared_connection.rb +1 -1
- data/lib/hecks/adapters/driven/postgres.rb +3 -0
- data/lib/hecks/adapters/driven/postgres_era/boot.rb +28 -16
- data/lib/hecks/adapters/driven/postgres_era/class_methods.rb +27 -7
- data/lib/hecks/adapters/driven/postgres_era/dialect.rb +10 -5
- data/lib/hecks/adapters/driven/postgres_era/field_cache_provisioner.rb +39 -0
- data/lib/hecks/adapters/driven/postgres_era/journal.rb +52 -13
- data/lib/hecks/adapters/driven/postgres_era/lineage/chain_sql.rb +29 -49
- data/lib/hecks/adapters/driven/postgres_era/lineage/direct_sql.rb +73 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/direct_verified.json +10 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/direct_verified.rb +65 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/domain_rename.rb +77 -25
- data/lib/hecks/adapters/driven/postgres_era/lineage/domain_rename_state.rb +108 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/era_integrity.rb +11 -6
- data/lib/hecks/adapters/driven/postgres_era/lineage/era_store.rb +63 -5
- data/lib/hecks/adapters/driven/postgres_era/lineage/layered_sql.rb +64 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/ledger_reset.rb +150 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/mint_provisioning.rb +85 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/mint_transaction.rb +11 -7
- data/lib/hecks/adapters/driven/postgres_era/lineage/provisioning.rb +11 -5
- data/lib/hecks/adapters/driven/postgres_era/lineage/split_sql.rb +76 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/sql_templates.rb +9 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage.rb +10 -2
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/context.rb +23 -3
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb +3 -1
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/disposable_ledger.rb +119 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolution.rb +219 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolver.rb +68 -71
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/held_era.rb +68 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/ledger_change.rb +63 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/merge_coordinator.rb +1 -1
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/mint_decision.rb +163 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/mint_request.rb +24 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/minter.rb +59 -21
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/refusals.rb +24 -11
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager.rb +40 -6
- data/lib/hecks/adapters/driven/postgres_era/shared_tables.rb +32 -0
- data/lib/hecks/adapters/driven/postgres_era.adapter +12 -0
- data/lib/hecks/adapters/driven/postgres_era.rb +25 -10
- data/lib/hecks/adapters/driven/prism.rb +0 -1
- data/lib/hecks/adapters/driven/sql_query_builder.rb +1 -0
- data/lib/hecks/adapters/driven/sqlite/dispatch_claims.rb +1 -1
- data/lib/hecks/adapters/driven/sqlite/name_guard.rb +25 -0
- data/lib/hecks/adapters/driven/sqlite/outbox.rb +2 -2
- data/lib/hecks/adapters/driven/sqlite/repository.rb +1 -1
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +20 -0
- data/lib/hecks/adapters/driven/sqlite.rb +9 -1
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +1 -1
- data/lib/hecks/adapters/driven/worktree_overlay.rb +117 -0
- data/lib/hecks/adapters/driving/cli/shorthand.rb +5 -1
- data/lib/hecks/adapters/driving/cli.rb +1 -1
- data/lib/hecks/adapters/driving/cli_runner/answers.rb +77 -22
- data/lib/hecks/adapters/driving/cli_runner/bang_rule.rb +35 -0
- data/lib/hecks/adapters/driving/cli_runner/completion_words.rb +36 -0
- data/lib/hecks/adapters/driving/cli_runner/json_words.rb +55 -0
- data/lib/hecks/adapters/driving/cli_runner/name_index.rb +63 -0
- data/lib/hecks/adapters/driving/cli_runner/read_context.rb +32 -0
- data/lib/hecks/adapters/driving/cli_runner/renamed_names.rb +49 -0
- data/lib/hecks/adapters/driving/cli_runner/resolution.rb +43 -17
- data/lib/hecks/adapters/driving/cli_runner/resume_words.rb +63 -0
- data/lib/hecks/adapters/driving/cli_runner/run_reference.rb +66 -0
- data/lib/hecks/adapters/driving/cli_runner/run_replay.rb +118 -0
- data/lib/hecks/adapters/driving/cli_runner/search_words.rb +35 -0
- data/lib/hecks/adapters/driving/cli_runner/settling.rb +6 -5
- data/lib/hecks/adapters/driving/cli_runner/streaming.rb +11 -10
- data/lib/hecks/adapters/driving/cli_runner/suggestions.rb +1 -1
- data/lib/hecks/adapters/driving/cli_runner/tour_words.rb +77 -0
- data/lib/hecks/adapters/driving/cli_runner/verb_names.rb +36 -4
- data/lib/hecks/adapters/driving/cli_runner/verbosity.rb +75 -0
- data/lib/hecks/adapters/driving/cli_runner.rb +106 -7
- data/lib/hecks/adapters/driving/context_line.rb +85 -0
- data/lib/hecks/adapters/driving/exit_status.rb +31 -0
- data/lib/hecks/adapters/driving/launcher_options.rb +7 -5
- data/lib/hecks/adapters/driving/mcp/progress_sink.rb +45 -0
- data/lib/hecks/adapters/driving/mcp/tool_calls.rb +7 -5
- data/lib/hecks/adapters/driving/mcp.rb +25 -5
- data/lib/hecks/adapters/driving/mcp_scope/argument_policy.rb +40 -7
- data/lib/hecks/adapters/driving/mcp_scope.rb +8 -7
- data/lib/hecks/adapters/driving/ruby/aggregate_module/hooks.rb +154 -0
- data/lib/hecks/adapters/driving/ruby/aggregate_module.rb +64 -93
- data/lib/hecks/adapters/driving/usage_log.rb +146 -0
- data/lib/hecks/adapters/driving/write_guard.rb +55 -0
- data/lib/hecks/adapters/driving.rb +0 -1
- data/lib/hecks/behaviors/dsl.rb +5 -1
- data/lib/hecks/behaviors/expectations/boot.rb +0 -1
- data/lib/hecks/bluebook/acknowledgements.rb +1 -1
- data/lib/hecks/bluebook/aggregate.rb +21 -18
- data/lib/hecks/bluebook/assembly/contracts/sagas.rb +2 -0
- data/lib/hecks/bluebook/assembly/contracts/structure.rb +18 -13
- data/lib/hecks/bluebook/behaviour/aggregate.rb +27 -3
- data/lib/hecks/bluebook/command.rb +16 -5
- data/lib/hecks/bluebook/declaration.rb +32 -4
- data/lib/hecks/bluebook/domain_port.rb +7 -3
- data/lib/hecks/bluebook/dsl/aggregate_builder/relationships.rb +0 -2
- data/lib/hecks/bluebook/dsl/aggregate_builder/renaming.rb +25 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +3 -0
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +0 -1
- data/lib/hecks/bluebook/dsl/audience_word.rb +40 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/metadata.rb +56 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/modules.rb +80 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/correlation_keys.rb +51 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +1 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +17 -34
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +8 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +13 -3
- data/lib/hecks/bluebook/dsl/entity_builder.rb +0 -2
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +6 -4
- data/lib/hecks/bluebook/dsl/kinds.rb +53 -0
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +9 -2
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +25 -15
- data/lib/hecks/bluebook/dsl/translation_builder.rb +16 -1
- data/lib/hecks/bluebook/dsl/word_gate.rb +1 -1
- data/lib/hecks/bluebook/dsl.rb +1 -0
- data/lib/hecks/bluebook/meta_validator/judge/identity.rb +9 -4
- data/lib/hecks/bluebook/meta_validator/plan/category.rb +10 -2
- data/lib/hecks/bluebook/meta_validator/plan/verbs.rb +9 -0
- data/lib/hecks/bluebook/meta_validator/plan.rb +2 -1
- data/lib/hecks/bluebook/meta_validator/reconstruction/heads.rb +3 -1
- data/lib/hecks/bluebook/meta_validator/reconstruction/reading.rb +7 -0
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +7 -2
- data/lib/hecks/bluebook/meta_validator/shapes.rb +3 -0
- data/lib/hecks/bluebook/meta_validator/syntax_boot/disk_cache.rb +1 -1
- data/lib/hecks/bluebook/model_check/aggregate_checks.rb +27 -0
- data/lib/hecks/bluebook/model_check/ask_checks.rb +25 -0
- data/lib/hecks/bluebook/model_check/reaction_chains.rb +114 -0
- data/lib/hecks/bluebook/model_check/reaction_cycles.rb +53 -0
- data/lib/hecks/bluebook/model_check/reaction_depth_checks.rb +58 -0
- data/lib/hecks/bluebook/model_check/reaction_walk.rb +62 -0
- data/lib/hecks/bluebook/model_check.rb +5 -27
- data/lib/hecks/bluebook/process_manager.rb +20 -3
- data/lib/hecks/bluebook/translation.rb +5 -3
- data/lib/hecks/bluebook/translation_plan.rb +9 -2
- data/lib/hecks/ci_pipeline/adapters/ci_cache.adapter +7 -0
- data/lib/hecks/ci_pipeline/adapters/ci_cache.rb +39 -0
- data/lib/hecks/ci_pipeline/adapters/ci_runner.adapter +7 -0
- data/lib/hecks/ci_pipeline/adapters/ci_runner.rb +55 -0
- data/lib/hecks/ci_pipeline/ci_pipeline.behaviors +322 -0
- data/lib/hecks/ci_pipeline/ci_pipeline.bluebook +938 -0
- data/lib/hecks/ci_pipeline/ci_pipeline.hecksagon +12 -0
- data/lib/hecks/ci_pipeline/ci_pipeline.ports.hecksagon +16 -0
- data/lib/hecks/ci_speed/adapters/ci_reader.adapter +7 -0
- data/lib/hecks/ci_speed/adapters/ci_reader.rb +141 -0
- data/lib/hecks/ci_speed/adapters/local_runner/answer.rb +41 -0
- data/lib/hecks/ci_speed/adapters/local_runner/catalog.rb +89 -0
- data/lib/hecks/ci_speed/adapters/local_runner/checkouts.rb +89 -0
- data/lib/hecks/ci_speed/adapters/local_runner/launcher.rb +69 -0
- data/lib/hecks/ci_speed/adapters/local_runner/load_average.rb +38 -0
- data/lib/hecks/ci_speed/adapters/local_runner/refs.rb +39 -0
- data/lib/hecks/ci_speed/adapters/local_runner/refused.rb +11 -0
- data/lib/hecks/ci_speed/adapters/local_runner/verdict.rb +71 -0
- data/lib/hecks/ci_speed/adapters/local_runner.adapter +7 -0
- data/lib/hecks/ci_speed/adapters/local_runner.rb +168 -0
- data/lib/hecks/ci_speed/adapters/replayed_runner.rb +39 -0
- data/lib/hecks/ci_speed/ci_speed.behaviors +341 -0
- data/lib/hecks/ci_speed/ci_speed.bluebook +1073 -0
- data/lib/hecks/ci_speed/ci_speed.hecksagon +11 -0
- data/lib/hecks/ci_speed/ci_speed.ports.hecksagon +21 -0
- data/lib/hecks/ci_workflows/ci_workflows.behaviors +13 -0
- data/lib/hecks/ci_workflows/ci_workflows.bluebook +173 -0
- data/lib/hecks/ci_workflows/ci_workflows.hecksagon +15 -0
- data/lib/hecks/coder/coder.bluebook +385 -0
- data/lib/hecks/coder/coder.hecksagon +12 -0
- data/lib/hecks/command_names/check.rb +39 -0
- data/lib/hecks/command_names/extractor.rb +67 -0
- data/lib/hecks/command_names/index.rb +40 -0
- data/lib/hecks/command_names/resolution.rb +81 -0
- data/lib/hecks/command_names/scan.rb +54 -0
- data/lib/hecks/command_names/sources.rb +73 -0
- data/lib/hecks/command_names.rb +26 -0
- data/lib/hecks/composer/jobs.rb +1 -1
- data/lib/hecks/composer/toolbox.rb +8 -1
- data/lib/hecks/corpus/generated_key.rb +205 -0
- data/lib/hecks/corpus/listing.rb +34 -0
- data/lib/hecks/corpus/rust.rb +27 -11
- data/lib/hecks/corpus/sources.rb +2 -1
- data/lib/hecks/corpus.rb +37 -42
- data/lib/hecks/deprecation.rb +23 -0
- data/lib/hecks/doc/reference/readme.rb +1 -1
- data/lib/hecks/doc/reference/rendering.rb +2 -2
- data/lib/hecks/doc/reference.rb +1 -1
- data/lib/hecks/embryonaut_bluebook/manifest.rb +1 -1
- data/lib/hecks/fixer/fixer.bluebook +240 -0
- data/lib/hecks/fixer/fixer.hecksagon +17 -0
- data/lib/hecks/framework_bluebooks.rb +32 -7
- data/lib/hecks/fuzzing/concurrent_dispatch/world_copy.rb +1 -0
- data/lib/hecks/fuzzing/isolated_boot/postgres_scratch.rb +11 -12
- data/lib/hecks/fuzzing/isolated_boot/worlds.rb +23 -5
- data/lib/hecks/fuzzing/isolated_boot.rb +1 -1
- data/lib/hecks/fuzzing/mutation/checks.rb +3 -3
- data/lib/hecks/grammar/translation.bluebook +1 -1
- data/lib/hecks/grammar/translation_rules.json +64 -0
- data/lib/hecks/hecks/adapter_words.json +7 -0
- data/lib/hecks/hecks/adapters/area_overlap.rb +156 -0
- data/lib/hecks/hecks/adapters/claude_agents.rb +8 -3
- data/lib/hecks/hecks/adapters/codebase/batch_runs.rb +60 -0
- data/lib/hecks/hecks/adapters/codebase/changed_specs.rb +52 -0
- data/lib/hecks/hecks/adapters/codebase/codemods.rb +3 -2
- data/lib/hecks/hecks/adapters/codebase/conformance.rb +14 -1
- data/lib/hecks/hecks/adapters/codebase/corpus_queries.rb +53 -0
- data/lib/hecks/hecks/adapters/codebase/generated_keys.rb +31 -0
- data/lib/hecks/hecks/adapters/codebase/impacted_specs.rb +110 -0
- data/lib/hecks/hecks/adapters/codebase/language.rb +2 -2
- data/lib/hecks/hecks/adapters/codebase/launcher_text.rb +39 -0
- data/lib/hecks/hecks/adapters/codebase/minitest_runs.rb +52 -0
- data/lib/hecks/hecks/adapters/codebase/regeneration.rb +51 -8
- data/lib/hecks/hecks/adapters/codebase/run_options.rb +35 -0
- data/lib/hecks/hecks/adapters/codebase/scripting.rb +39 -0
- data/lib/hecks/hecks/adapters/codebase/search.rb +1 -1
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +79 -51
- data/lib/hecks/hecks/adapters/codebase/spec_files/report.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/spec_files/shared_run.rb +73 -0
- data/lib/hecks/hecks/adapters/codebase/spec_files.rb +95 -0
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +53 -4
- data/lib/hecks/hecks/adapters/codebase/test_scope.rb +105 -0
- data/lib/hecks/hecks/adapters/codebase/test_suite.rb +48 -34
- data/lib/hecks/hecks/adapters/console_capture.rb +1 -1
- data/lib/hecks/hecks/adapters/cost_explorer.rb +9 -1
- data/lib/hecks/hecks/adapters/dispatching/brief_text.rb +51 -0
- data/lib/hecks/hecks/adapters/dispatching/launcher.rb +97 -0
- data/lib/hecks/hecks/adapters/dispatching/plan.rb +82 -0
- data/lib/hecks/hecks/adapters/dispatching/rows.rb +66 -0
- data/lib/hecks/hecks/adapters/dispatching/settings.rb +81 -0
- data/lib/hecks/hecks/adapters/dispatching/settler.rb +40 -0
- data/lib/hecks/hecks/adapters/dispatching.adapter +7 -0
- data/lib/hecks/hecks/adapters/dispatching.rb +93 -0
- data/lib/hecks/hecks/adapters/doctor_reading/report.rb +27 -0
- data/lib/hecks/hecks/adapters/doctor_reading.adapter +7 -0
- data/lib/hecks/hecks/adapters/doctor_reading.rb +161 -0
- data/lib/hecks/hecks/adapters/git_checkout.rb +1 -1
- data/lib/hecks/hecks/adapters/git_commit.adapter +7 -0
- data/lib/hecks/hecks/adapters/git_commit.rb +61 -0
- data/lib/hecks/hecks/adapters/git_landing/finisher.rb +82 -0
- data/lib/hecks/hecks/adapters/git_landing/foreign_hold.rb +111 -0
- data/lib/hecks/hecks/adapters/git_landing/line.rb +171 -0
- data/lib/hecks/hecks/adapters/git_landing/lineup.rb +98 -0
- data/lib/hecks/hecks/adapters/git_landing/merger.rb +1 -1
- data/lib/hecks/hecks/adapters/git_landing/numbering.rb +54 -0
- data/lib/hecks/hecks/adapters/git_landing/rivals.rb +59 -0
- data/lib/hecks/hecks/adapters/git_landing/ticket.rb +156 -0
- data/lib/hecks/hecks/adapters/git_landing/tidy.rb +147 -0
- data/lib/hecks/hecks/adapters/git_landing/train.rb +104 -0
- data/lib/hecks/hecks/adapters/git_landing/verdict.rb +64 -0
- data/lib/hecks/hecks/adapters/git_landing/waiting.rb +120 -0
- data/lib/hecks/hecks/adapters/git_landing.rb +106 -20
- data/lib/hecks/hecks/adapters/git_main_pull.rb +99 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/bench.rb +82 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/due.rb +84 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/impacted/skips.rb +47 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/impacted/spec_run.rb +75 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/impacted.rb +181 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/line.rb +76 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/reading.rb +24 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/record.rb +146 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/spec_map/corpus.rb +25 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/spec_map/needles.rb +61 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/spec_map.rb +105 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/stages.rb +118 -0
- data/lib/hecks/hecks/adapters/git_rehearsal.adapter +7 -0
- data/lib/hecks/hecks/adapters/git_rehearsal.rb +141 -0
- data/lib/hecks/hecks/adapters/git_train/bench.rb +15 -15
- data/lib/hecks/hecks/adapters/git_train/branch_guard.rb +62 -0
- data/lib/hecks/hecks/adapters/git_train/carriage.rb +27 -28
- data/lib/hecks/hecks/adapters/git_train/launcher_shape.rb +75 -0
- data/lib/hecks/hecks/adapters/git_train/mint_step.rb +47 -0
- data/lib/hecks/hecks/adapters/git_train/settlement.rb +167 -0
- data/lib/hecks/hecks/adapters/git_train.rb +73 -15
- data/lib/hecks/hecks/adapters/git_worktree_add.adapter +7 -0
- data/lib/hecks/hecks/adapters/git_worktree_add.rb +68 -0
- data/lib/hecks/hecks/adapters/github_pull_requests.adapter +7 -0
- data/lib/hecks/hecks/adapters/github_pull_requests.rb +109 -0
- data/lib/hecks/hecks/adapters/host_http.rb +6 -6
- data/lib/hecks/hecks/adapters/in_process_boot.rb +10 -8
- data/lib/hecks/hecks/adapters/in_process_operations.rb +11 -17
- data/lib/hecks/hecks/adapters/in_process_undo.rb +17 -0
- data/lib/hecks/hecks/adapters/journal_store/changes.rb +13 -4
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +28 -15
- data/lib/hecks/hecks/adapters/journal_store/examination.rb +17 -1
- data/lib/hecks/hecks/adapters/journal_store/held_domain/renaming.rb +45 -0
- data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +31 -5
- data/lib/hecks/hecks/adapters/journal_store/held_mint.rb +128 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/attestation.rb +1 -1
- data/lib/hecks/hecks/adapters/journal_store/readings/boot_status.rb +58 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/composition.rb +39 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/outcomes.rb +76 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/postgres_reader.rb +44 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/reader.rb +64 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/report.rb +102 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/sqlite_reader.rb +43 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/stores.rb +80 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/subscribers.rb +72 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/summary.rb +39 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace.rb +39 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/command_line.rb +57 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/edge_guards.rb +107 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/inspection.rb +94 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/plan.rb +66 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/report.rb +72 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/store.rb +34 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/watermark_guards.rb +86 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/world.rb +66 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan.rb +36 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/projection_audit.rb +64 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/scaffolding.rb +3 -3
- data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status/database_reading.rb +113 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status/read_only.rb +33 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status.rb +32 -0
- data/lib/hecks/hecks/adapters/journal_store/readings.rb +13 -1
- data/lib/hecks/hecks/adapters/journal_store/reconcile_report.rb +60 -0
- data/lib/hecks/hecks/adapters/journal_store/reconciliation.rb +121 -0
- data/lib/hecks/hecks/adapters/journal_store/translation_write/shape_edge.rb +59 -0
- data/lib/hecks/hecks/adapters/journal_store/translation_write.rb +123 -0
- data/lib/hecks/hecks/adapters/journal_store.rb +16 -0
- data/lib/hecks/hecks/adapters/landed_work.adapter +7 -0
- data/lib/hecks/hecks/adapters/landed_work.rb +52 -0
- data/lib/hecks/hecks/adapters/local_files.rb +6 -6
- data/lib/hecks/hecks/adapters/process_pool.rb +3 -2
- data/lib/hecks/hecks/adapters/push_size.rb +57 -0
- data/lib/hecks/hecks/adapters/qa_quiescing.adapter +7 -0
- data/lib/hecks/hecks/adapters/qa_quiescing.rb +57 -0
- data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +30 -3
- data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +63 -3
- data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +29 -6
- data/lib/hecks/hecks/adapters/rehearsal/subject.rb +11 -5
- data/lib/hecks/hecks/adapters/rust_toolchain.rb +10 -1
- data/lib/hecks/hecks/adapters/rust_workspace.rb +1 -1
- data/lib/hecks/hecks/adapters/settings_reading/disposable_ledger.rb +32 -0
- data/lib/hecks/hecks/adapters/settings_reading/push_nudge.rb +26 -0
- data/lib/hecks/hecks/adapters/settings_reading/stores.rb +76 -0
- data/lib/hecks/hecks/adapters/settings_reading/test_scope.rb +28 -0
- data/lib/hecks/hecks/adapters/settings_reading.rb +28 -2
- data/lib/hecks/hecks/adapters/started_work.rb +42 -0
- data/lib/hecks/hecks/adapters/terminal.rb +12 -10
- data/lib/hecks/hecks/adapters/where_reading.adapter +7 -0
- data/lib/hecks/hecks/adapters/where_reading.rb +64 -0
- data/lib/hecks/hecks/adapters/work_areas.rb +57 -0
- data/lib/hecks/hecks/adapters/work_limits.rb +57 -0
- data/lib/hecks/hecks/build/build.bluebook +576 -0
- data/lib/hecks/hecks/check/check.bluebook +966 -0
- data/lib/hecks/hecks/codebase.behaviors +61 -5
- data/lib/hecks/hecks/composer.behaviors +1 -1
- data/lib/hecks/hecks/context_map.hecksagon +1 -1
- data/lib/hecks/hecks/custodian.behaviors +33 -7
- data/lib/hecks/hecks/delegate/delegate.bluebook +355 -0
- data/lib/hecks/hecks/deliver/deliver.bluebook +945 -0
- data/lib/hecks/hecks/deploy.behaviors +1 -1
- data/lib/hecks/hecks/evolve/evolve.bluebook +788 -0
- data/lib/hecks/hecks/find/find.bluebook +81 -0
- data/lib/hecks/hecks/hecks.behaviors +1 -1
- data/lib/hecks/hecks/hecks.bluebook +0 -133
- data/lib/hecks/hecks/hecks.contextmap +2 -0
- data/lib/hecks/hecks/hecks.hecksagon +185 -29
- data/lib/hecks/hecks/hecks.world +35 -9
- data/lib/hecks/hecks/implicit_moves.json +24 -0
- data/lib/hecks/hecks/migrate/migrate.bluebook +1066 -0
- data/lib/hecks/hecks/operate/operate.bluebook +695 -0
- data/lib/hecks/hecks/quiesce/quiesce.bluebook +117 -0
- data/lib/hecks/hecks/rehearse/rehearse.bluebook +133 -0
- data/lib/hecks/hecks/release/release.bluebook +916 -0
- data/lib/hecks/hecks/serve/serve.bluebook +134 -0
- data/lib/hecks/hecks/shapes.json +1 -15
- data/lib/hecks/hecks/site.behaviors +1 -1
- data/lib/hecks/hecks/start/start.bluebook +194 -0
- data/lib/hecks/hecks/test/test.bluebook +638 -0
- data/lib/hecks/hecks/tickets.world +14 -0
- data/lib/hecks/language/bluebook/aggregate.bluebook +22 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +34 -0
- data/lib/hecks/language/bluebook/command.bluebook +35 -0
- data/lib/hecks/language/bluebook/process_manager.bluebook +14 -1
- data/lib/hecks/language/bluebook/vocabulary.bluebook +174 -54
- data/lib/hecks/language/hecksagon/domain_port.bluebook +1 -0
- data/lib/hecks/language/hecksagon/port_operation.bluebook +14 -0
- data/lib/hecks/language/kinds/run.kind +120 -0
- data/lib/hecks/language/oidc.json +10 -0
- data/lib/hecks/language/translation/translation_aggregate.bluebook +24 -0
- data/lib/hecks/module_folders.rb +31 -0
- data/lib/hecks/ports/key_vault.rb +1 -1
- data/lib/hecks/ports/persistence/append_only.rb +26 -8
- data/lib/hecks/ports/persistence/binding_policy.rb +3 -1
- data/lib/hecks/ports/persistence/codec_boundary.rb +1 -1
- data/lib/hecks/ports/persistence/mint_door.rb +74 -0
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +6 -5
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +5 -1
- data/lib/hecks/ports/persistence/plugins/era/era_status.rb +48 -0
- data/lib/hecks/ports/persistence/plugins/era/projected_bluebook.rb +127 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/additive_shape.rb +107 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/compose.rb +155 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/compose_render.rb +79 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/edge_files.rb +49 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/edge_route.rb +61 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/implicit_edge.rb +67 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/reconcile.rb +130 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/reconcile_files.rb +35 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +13 -5
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +5 -0
- data/lib/hecks/ports/persistence/plugins/era.rb +1 -0
- data/lib/hecks/ports/persistence/repository_factory.rb +11 -3
- data/lib/hecks/ports/persistence/stored_name_guard.rb +36 -0
- data/lib/hecks/ports/persistence.rb +2 -0
- data/lib/hecks/projections/ci_pipeline/table/checks.rb +137 -0
- data/lib/hecks/projections/ci_pipeline/table/lookup.rb +59 -0
- data/lib/hecks/projections/ci_pipeline/table/refusals.rb +58 -0
- data/lib/hecks/projections/ci_pipeline/table/rows.rb +119 -0
- data/lib/hecks/projections/ci_pipeline/table/tree.rb +30 -0
- data/lib/hecks/projections/ci_pipeline/table/typing.rb +92 -0
- data/lib/hecks/projections/ci_pipeline/table.rb +112 -0
- data/lib/hecks/projections/ci_pipeline/workflows.rb +162 -0
- data/lib/hecks/projections/ci_pipeline/yaml_text.rb +104 -0
- data/lib/hecks/projections/deploy/box/hosting.rb +1 -1
- data/lib/hecks/projections/deploy/box/roll_recipe.rb +1 -1
- data/lib/hecks/projections/deploy/box/roll_scripts.rb +1 -1
- data/lib/hecks/projections/deploy/box.rb +1 -1
- data/lib/hecks/projections/deploy/templates/fargate/Makefile.tmpl +1 -1
- data/lib/hecks/projections/deploy/templates/lambda/Makefile.tmpl +3 -3
- data/lib/hecks/projections/undo.rb +46 -0
- data/lib/hecks/projections.rb +2 -0
- data/lib/hecks/projector/cli_projector/claims.rb +11 -0
- data/lib/hecks/projector/cli_projector/command_help.rb +6 -1
- data/lib/hecks/projector/cli_projector/command_specs.rb +11 -1
- data/lib/hecks/projector/cli_projector/completion.rb +87 -0
- data/lib/hecks/projector/cli_projector/everyday.rb +40 -0
- data/lib/hecks/projector/cli_projector/json_listing.rb +77 -0
- data/lib/hecks/projector/cli_projector/listing.rb +1 -1
- data/lib/hecks/projector/cli_projector/modules.rb +39 -0
- data/lib/hecks/projector/cli_projector/query_specs.rb +1 -0
- data/lib/hecks/projector/cli_projector/renames.rb +58 -0
- data/lib/hecks/projector/cli_projector/search.rb +74 -0
- data/lib/hecks/projector/cli_projector/usage.rb +23 -6
- data/lib/hecks/projector/cli_projector.rb +24 -1
- data/lib/hecks/quality_control/adapters/ci_head.adapter +8 -0
- data/lib/hecks/quality_control/adapters/image_roll.adapter +9 -0
- data/lib/hecks/quality_control/adapters/image_roll.rb +158 -0
- data/lib/hecks/quality_control/adapters/main_maintenance.adapter +8 -0
- data/lib/hecks/quality_control/adapters/main_maintenance.rb +275 -0
- data/lib/hecks/quality_control/adapters/pump_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/pump_tools.rb +18 -0
- data/lib/hecks/quality_control/adapters/push_due_reader.adapter +8 -0
- data/lib/hecks/quality_control/adapters/push_due_reader.rb +99 -0
- data/lib/hecks/quality_control/adapters/qa_auto_mint.rb +183 -0
- data/lib/hecks/quality_control/adapters/qa_era_mint.rb +94 -0
- data/lib/hecks/quality_control/adapters/qa_quiesce_marker.rb +126 -0
- data/lib/hecks/quality_control/adapters/run_keys.rb +36 -0
- data/lib/hecks/quality_control/adapters/run_reader.adapter +7 -0
- data/lib/hecks/quality_control/adapters/run_reader.rb +188 -0
- data/lib/hecks/quality_control/cli/child.rb +1 -0
- data/lib/hecks/quality_control/cli/qa_discover_external_domains/scanning.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +3 -3
- data/lib/hecks/quality_control/cli/qa_event_pump/attached.rb +67 -0
- data/lib/hecks/quality_control/cli/qa_event_pump/consumer.rb +103 -0
- data/lib/hecks/quality_control/cli/qa_event_pump/cursors.rb +60 -0
- data/lib/hecks/quality_control/cli/qa_event_pump/reactions.rb +46 -0
- data/lib/hecks/quality_control/cli/qa_event_pump/reader.rb +30 -0
- data/lib/hecks/quality_control/cli/qa_event_pump.rb +76 -0
- data/lib/hecks/quality_control/cli/qa_fix_main_bug/publishing.rb +79 -0
- data/lib/hecks/quality_control/cli/qa_fix_main_bug.rb +167 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains/evaluation.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_generated_domains/promotion.rb +3 -3
- data/lib/hecks/quality_control/cli/qa_main_gate/gate_run.rb +52 -0
- data/lib/hecks/quality_control/cli/qa_main_gate/logging.rb +70 -0
- data/lib/hecks/quality_control/cli/qa_main_gate/shell.rb +47 -0
- data/lib/hecks/quality_control/cli/qa_main_gate/sweeping.rb +59 -0
- data/lib/hecks/quality_control/cli/qa_main_gate/worktree.rb +62 -0
- data/lib/hecks/quality_control/cli/qa_main_gate.rb +135 -0
- data/lib/hecks/quality_control/cli/qa_postgres_role.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_pr_check/checking.rb +2 -3
- data/lib/hecks/quality_control/cli/qa_push_nudge.rb +48 -0
- data/lib/hecks/quality_control/cli/qa_seed_angles/seed.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_sweep/seat.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_tick/event_pump_step.rb +34 -0
- data/lib/hecks/quality_control/cli/qa_tick/output.rb +16 -1
- data/lib/hecks/quality_control/cli/qa_tick/push_nudge_step.rb +28 -0
- data/lib/hecks/quality_control/cli/qa_tick/quiesce_guard.rb +51 -0
- data/lib/hecks/quality_control/cli/qa_tick.rb +36 -8
- data/lib/hecks/quality_control/quality_control.behaviors +65 -0
- data/lib/hecks/quality_control/quality_control.bluebook +1131 -11
- data/lib/hecks/quality_control/quality_control.hecksagon +11 -0
- data/lib/hecks/quality_control/quality_control.ports.hecksagon +138 -0
- data/lib/hecks/query_ir/touchpoints.rb +5 -7
- data/lib/hecks/refused.rb +21 -0
- data/lib/hecks/release/approval.rb +6 -3
- data/lib/hecks/release/conditions.rb +46 -0
- data/lib/hecks/release/runner/gem_publisher.rb +4 -4
- data/lib/hecks/release/version_commit.rb +48 -0
- data/lib/hecks/runtime/command_interpreter/hydration.rb +5 -4
- data/lib/hecks/runtime/command_interpreter/persisting.rb +11 -3
- data/lib/hecks/runtime/command_interpreter.rb +2 -2
- data/lib/hecks/runtime/command_rules/admissibility.rb +0 -2
- data/lib/hecks/runtime/command_rules/emission.rb +0 -1
- data/lib/hecks/runtime/dependency_planning/expression_reads.rb +0 -1
- data/lib/hecks/runtime/dispatcher/planning.rb +24 -0
- data/lib/hecks/runtime/dispatcher/routing.rb +6 -0
- data/lib/hecks/runtime/dispatcher/value_routing.rb +54 -0
- data/lib/hecks/runtime/dispatcher.rb +7 -1
- data/lib/hecks/runtime/dry_run_plan.rb +60 -0
- data/lib/hecks/runtime/entity_element/location.rb +0 -1
- data/lib/hecks/runtime/entity_element/mutations.rb +0 -1
- data/lib/hecks/runtime/entity_interpreter/locating.rb +5 -0
- data/lib/hecks/runtime/entity_interpreter.rb +0 -1
- data/lib/hecks/runtime/errors.rb +26 -0
- data/lib/hecks/runtime/instance.rb +0 -1
- data/lib/hecks/runtime/invocation_builder.rb +0 -1
- data/lib/hecks/runtime/outbox/consumer_runner.rb +9 -1
- data/lib/hecks/runtime/outbox/relay.rb +25 -4
- data/lib/hecks/runtime/outbox/runnable.rb +3 -1
- data/lib/hecks/runtime/outbox.rb +6 -2
- data/lib/hecks/runtime/policy_interpreter/fan_out.rb +18 -2
- data/lib/hecks/runtime/policy_interpreter.rb +17 -9
- data/lib/hecks/runtime/port_operation_interpreter.rb +21 -7
- data/lib/hecks/runtime/query_interpreter/arguments.rb +6 -5
- data/lib/hecks/runtime/reaction_invocation.rb +0 -1
- data/lib/hecks/runtime/refusal_wording.rb +12 -1
- data/lib/hecks/runtime/registry/context_maps.rb +1 -5
- data/lib/hecks/runtime/registry/declarations.rb +34 -4
- data/lib/hecks/runtime/registry/hecksagon_rules.rb +15 -1
- data/lib/hecks/runtime/registry/runtime_state.rb +10 -0
- data/lib/hecks/runtime/registry/world_defaults.rb +24 -2
- data/lib/hecks/runtime/registry/world_names.rb +99 -0
- data/lib/hecks/runtime/registry.rb +33 -27
- data/lib/hecks/runtime/saga_interpreter/compensation.rb +10 -0
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +29 -3
- data/lib/hecks/runtime/saga_interpreter/delivery.rb +0 -1
- data/lib/hecks/runtime/saga_interpreter/lifecycle.rb +1 -1
- data/lib/hecks/runtime/saga_interpreter.rb +46 -2
- data/lib/hecks/runtime/value/coercion.rb +36 -8
- data/lib/hecks/rust_build/conformance.rb +16 -5
- data/lib/hecks/rust_build/parser.rb +25 -0
- data/lib/hecks/rust_build/project_rust/codegen_run.rb +45 -12
- data/lib/hecks/rust_build/project_rust/declared.rb +80 -0
- data/lib/hecks/rust_build/project_rust/features_header.rb +22 -0
- data/lib/hecks/rust_build/project_rust/manifest.rb +96 -0
- data/lib/hecks/rust_build/project_rust/meta.rb +36 -0
- data/lib/hecks/rust_build/project_rust.rb +28 -90
- data/lib/hecks/rust_build/write_if_changed.rb +19 -4
- data/lib/hecks/rust_build.rb +2 -1
- data/lib/hecks/rust_format.rb +32 -2
- data/lib/hecks/secrets.rb +111 -0
- data/lib/hecks/shape_ledger/edge_hygiene.rb +170 -0
- data/lib/hecks/shape_ledger/scope.rb +51 -0
- data/lib/hecks/shape_ledger/status.rb +89 -0
- data/lib/hecks/shape_ledger.rb +78 -33
- data/lib/hecks/site/bluebook/site.bluebook +1 -0
- data/lib/hecks/storehouse/audit.rb +34 -4
- data/lib/hecks/storehouse/callers.rb +8 -0
- data/lib/hecks/storehouse/dispatching.rb +14 -3
- data/lib/hecks/storehouse/identity.rb +41 -0
- data/lib/hecks/storehouse/querying.rb +7 -7
- data/lib/hecks/storehouse.rb +28 -10
- data/lib/hecks/tickets/bluebook/adapters/work_areas.adapter +7 -0
- data/lib/hecks/tickets/bluebook/adapters/work_limits.adapter +7 -0
- data/lib/hecks/tickets/bluebook/tickets.behaviors +70 -0
- data/lib/hecks/tickets/bluebook/tickets.bluebook +323 -28
- data/lib/hecks/tickets/bluebook/tickets.hecksagon +7 -0
- data/lib/hecks/tickets/bluebook/tickets.ports.hecksagon +17 -0
- data/lib/hecks/{cli → tools}/behaviors.rb +1 -1
- data/lib/hecks/{cli → tools}/canonicalise.rb +1 -1
- data/lib/hecks/{cli → tools}/check_engine_agreement.rb +1 -1
- data/lib/hecks/{cli → tools}/check_era.rb +6 -6
- data/lib/hecks/tools/ci_gates.rb +8 -2
- data/lib/hecks/tools/ci_workflows.rb +98 -0
- data/lib/hecks/{cli → tools}/console.rb +1 -1
- data/lib/hecks/{cli → tools}/deploy_template_diff.rb +1 -1
- data/lib/hecks/{cli → tools}/doc_coverage.rb +2 -2
- data/lib/hecks/{cli → tools}/document.rb +1 -1
- data/lib/hecks/{cli → tools}/domain_stub.rb +1 -1
- data/lib/hecks/{cli → tools}/domain_writer.rb +1 -1
- data/lib/hecks/tools/downstream_model_check.rb +122 -0
- data/lib/hecks/tools/evolve_run.rb +2 -2
- data/lib/hecks/{cli → tools}/expected_era.rb +1 -1
- data/lib/hecks/{cli → tools}/expression_projection.rb +1 -1
- data/lib/hecks/{cli → tools}/follow.rb +1 -1
- data/lib/hecks/tools/fuzz_sweep/options.rb +40 -5
- data/lib/hecks/tools/fuzz_sweep/pool.rb +12 -1
- data/lib/hecks/tools/fuzz_sweep/shards.rb +155 -0
- data/lib/hecks/tools/fuzz_sweep.rb +11 -5
- data/lib/hecks/tools/gate.rb +38 -29
- data/lib/hecks/tools/gate_memo/local_files.rb +33 -0
- data/lib/hecks/tools/gate_memo/rehearsal.rb +54 -0
- data/lib/hecks/tools/gate_memo/ruby_files.rb +152 -0
- data/lib/hecks/tools/gate_memo/session.rb +114 -0
- data/lib/hecks/tools/gate_memo/standalone.rb +67 -0
- data/lib/hecks/tools/gate_memo.rb +196 -0
- data/lib/hecks/tools/gate_report.rb +56 -0
- data/lib/hecks/{cli → tools}/history.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_agent.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_aggregate.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_draft.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_record.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_run.rb +2 -2
- data/lib/hecks/{cli → tools}/interview_session/agent_state.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_session/catalog.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_session/manual_findings.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_session/proposals.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_session.rb +2 -2
- data/lib/hecks/{cli → tools}/interview_shape/lifecycle.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_shape.rb +1 -1
- data/lib/hecks/{cli → tools}/ir.rb +1 -1
- data/lib/hecks/tools/lanes/files.rb +1 -1
- data/lib/hecks/tools/lanes/watch_workflow.rb +6 -8
- data/lib/hecks/tools/lanes/workflow.rb +1 -1
- data/lib/hecks/tools/lanes.rb +1 -1
- data/lib/hecks/{cli → tools}/mcp.rb +1 -1
- data/lib/hecks/{cli → tools}/model_check/examination.rb +1 -1
- data/lib/hecks/{cli → tools}/model_check/sources.rb +1 -1
- data/lib/hecks/{cli → tools}/model_check.rb +1 -1
- data/lib/hecks/tools/move_disables/reasons.rb +35 -0
- data/lib/hecks/tools/move_disables.rb +211 -0
- data/lib/hecks/tools/move_former_name.rb +105 -0
- data/lib/hecks/{cli → tools}/pattern_cases.rb +1 -1
- data/lib/hecks/{cli → tools}/persistence_notice.rb +1 -1
- data/lib/hecks/{cli → tools}/present.rb +1 -1
- data/lib/hecks/{cli → tools}/project_cli/launcher_source.rb +32 -22
- data/lib/hecks/{cli → tools}/project_cli/templates.rb +22 -15
- data/lib/hecks/{cli → tools}/project_cli.rb +11 -7
- data/lib/hecks/{cli → tools}/project_diagrams.rb +3 -3
- data/lib/hecks/{cli → tools}/project_glossary.rb +2 -2
- data/lib/hecks/{cli → tools}/reference.rb +2 -2
- data/lib/hecks/{cli → tools}/refresh_projections.rb +1 -1
- data/lib/hecks/{cli → tools}/refresh_rspec_runtime_baseline.rb +1 -1
- data/lib/hecks/tools/regeneration_run/pool.rb +148 -0
- data/lib/hecks/tools/regeneration_run/scratch.rb +76 -0
- data/lib/hecks/tools/regeneration_run.rb +125 -103
- data/lib/hecks/{cli → tools}/release.rb +1 -1
- data/lib/hecks/{cli → tools}/release_gem.rb +1 -1
- data/lib/hecks/{cli → tools}/rspec_io_parallel_files.rb +1 -1
- data/lib/hecks/{cli → tools}/rspec_shard_files.rb +1 -1
- data/lib/hecks/{cli → tools}/run.rb +9 -2
- data/lib/hecks/{cli → tools}/run_expectations.rb +1 -1
- data/lib/hecks/{cli → tools}/seed_semantics_corpus.rb +4 -4
- data/lib/hecks/{cli → tools}/serve_query_ir_mcp.rb +1 -1
- data/lib/hecks/{cli → tools}/shape.rb +3 -2
- data/lib/hecks/{cli → tools}/smoke_http/checks.rb +1 -1
- data/lib/hecks/{cli → tools}/smoke_http/settings.rb +1 -1
- data/lib/hecks/{cli → tools}/smoke_http/transport.rb +1 -1
- data/lib/hecks/{cli → tools}/smoke_http.rb +1 -1
- data/lib/hecks/{cli → tools}/smoke_test.rb +1 -1
- data/lib/hecks/{cli → tools}/spec_example.rb +1 -1
- data/lib/hecks/tools/stage_progress.rb +54 -0
- data/lib/hecks/{cli → tools}/statements.rb +1 -1
- data/lib/hecks/{cli → tools}/stores.rb +1 -1
- data/lib/hecks/{cli → tools}/stress_concurrency_specs/reporting.rb +1 -1
- data/lib/hecks/{cli → tools}/stress_concurrency_specs/usage.rb +4 -4
- data/lib/hecks/{cli → tools}/stress_concurrency_specs.rb +3 -3
- data/lib/hecks/tools/tenant_provisioning.rb +23 -0
- data/lib/hecks/tools/tools_doc.rb +10 -8
- data/lib/hecks/tools/translation_audit/edges.rb +21 -16
- data/lib/hecks/tools/translation_audit/verdicts.rb +1 -1
- data/lib/hecks/tools/translation_audit.rb +1 -1
- data/lib/hecks/tools/translation_scaffold.rb +1 -1
- data/lib/hecks/tools.rb +4 -1
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks/vocabulary.rb +61 -31
- data/lib/hecks/workflow_pagination/judge.rb +48 -0
- data/lib/hecks/workflow_pagination/statement.rb +50 -0
- data/lib/hecks/workflow_pagination.rb +58 -0
- data/lib/hecks.rb +2 -0
- data/lib/rubocop/cop/hecks/bare_event_and_query_names.rb +58 -0
- data/lib/rubocop/cop/hecks/correlates_by_aggregate.rb +39 -0
- data/lib/rubocop/cop/hecks/creating_command_sets.rb +75 -0
- data/lib/rubocop/cop/hecks/invariant_expression_language.rb +47 -0
- data/lib/rubocop/cop/hecks/lifecycle_needs_attribute.rb +58 -0
- data/lib/rubocop/cop/hecks/no_id_string_attribute.rb +49 -0
- data/lib/rubocop/cop/hecks/one_terminal_mark_per_lifecycle.rb +47 -0
- data/lib/rubocop/cop/hecks/value_object_shorthand.rb +56 -0
- data/prebuilt/13c04bdc5970295b310f0a980d397ba722232c8da99cc1a0cdb383249921e871.marshal +0 -0
- data/prebuilt/e3857b77f47d9ecc1787b2e1f5136364f3cb3444ef4aea5479f3b98167affea2.marshal +0 -0
- data/qa/settings.yml +23 -0
- data/rust/.gitignore +0 -6
- data/rust/Cargo.toml +2 -1
- data/rust/build/Cargo.toml +1 -1
- data/rust/build/src/binding_pass.rs +57 -4
- data/rust/build/src/pipeline.rs +6 -4
- data/rust/build/src/resolve.rs +1 -0
- data/rust/codegen/Cargo.toml +1 -1
- data/rust/codegen/src/domain_generator.rs +3 -0
- data/rust/codegen/src/json_codec.rs +182 -23
- data/rust/codegen/src/one_of_references.rs +1 -0
- data/rust/codegen/src/queries.rs +20 -2
- data/rust/codegen/src/registry.rs +21 -5
- data/rust/expr/Cargo.toml +1 -1
- data/rust/host/Cargo.toml +1 -1
- data/rust/host/HECKS_RELEASE +1 -1
- data/rust/host/core/Cargo.toml +1 -1
- data/rust/host/src/bin/mint_harness.rs +1 -0
- data/rust/host/src/boot.rs +1 -0
- data/rust/host/src/store/mint.rs +40 -6
- data/rust/lsp/Cargo.toml +1 -1
- data/rust/parser/Cargo.toml +1 -1
- data/rust/parser/src/build/correlation_keys.rs +125 -0
- data/rust/parser/src/build/mod.rs +1 -0
- data/rust/parser/src/emit.rs +55 -3
- data/rust/parser/src/ir.rs +33 -1
- data/rust/parser/src/keywords.rs +289 -1
- data/rust/parser/src/main.rs +2 -0
- data/rust/parser/src/parse/aggregate.rs +10 -1
- data/rust/parser/src/parse/audience.rs +65 -0
- data/rust/parser/src/parse/command.rs +14 -0
- data/rust/parser/src/parse/declaration.rs +97 -0
- data/rust/parser/src/parse/domain_port.rs +6 -0
- data/rust/parser/src/parse/mod.rs +1 -0
- data/rust/parser/src/parse/process_manager.rs +17 -10
- data/rust/parser/src/parse/world.rs +12 -8
- data/rust/parser/src/render_ruby.rs +9 -0
- data/rust/parser/src/sentence/format.rs +3 -0
- data/rust/parser/src/sentence/process.rs +6 -2
- data/rust/src/exemplar/json.rs +17 -0
- data/rust/src/kernel/cli.rs +27 -3
- data/rust/src/kernel/dispatch.rs +4 -2
- data/rust/src/kernel/json.rs +62 -0
- data/rust/src/kernel/orchestrate.rs +28 -3
- data/rust/src/kernel/orchestrate_guard_tests.rs +12 -12
- data/rust/web/Cargo.toml +1 -1
- metadata +389 -96
- data/lib/hecks/cli/command_table.rb +0 -72
- data/lib/hecks/cli/launcher_words.rb +0 -168
- data/lib/hecks/cli.rb +0 -133
- data/lib/hecks/hecks/agents.bluebook +0 -246
- data/lib/hecks/hecks/codebase.bluebook +0 -3209
- data/lib/hecks/hecks/custodian.bluebook +0 -1300
- data/lib/hecks/hecks/ledger.bluebook +0 -190
- data/lib/hecks/hecks/rehearsal.bluebook +0 -437
- data/lib/hecks/hecks/tooling.bluebook +0 -1234
- data/lib/hecks/hecks/translations/2-148748.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-15a2e4.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-1b447c.bluebook +0 -5
- data/lib/hecks/hecks/translations/2-240474.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-44446d.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-46ca26.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-473eab.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-75cc28.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-781c07.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-84c18b.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-aa5fff.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-bfdb48.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-cd96d8.bluebook +0 -10
- data/lib/hecks/hecks/translations/2-d43f71.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-eea577.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-f53248.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-fbb677.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-ffdf12.bluebook +0 -6
- data/lib/hecks/quality_control/adapters/clearance_recorder.rb +0 -36
- data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +0 -56
- data/prebuilt/31cf81e12f16236ad26249be590cfea3799c9db67432e6a4ef54b801c355b6ae.marshal +0 -0
- data/prebuilt/68ecb2bd3abb1a221007db4f2b0375834c13aaccac8f2b99778e8517f11aa113.marshal +0 -0
- data/prebuilt/verdicts-0328c2403383837d780ad5ed81d1da351c56436b894cf9015b5d56b8f1f1bf10.json +0 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require_relative "workflow_pagination/statement"
|
|
2
|
+
require_relative "workflow_pagination/judge"
|
|
3
|
+
|
|
4
|
+
module Hecks
|
|
5
|
+
# Finds the GitHub list calls in a workflow that count or wait for items and read only the first
|
|
6
|
+
# page of them.
|
|
7
|
+
#
|
|
8
|
+
# The artifact wait of a CI run counted four named artifacts among a run's list, and went on
|
|
9
|
+
# waiting its full time once the run held 35, because the list pages at 30 and the fourth sat on
|
|
10
|
+
# the second page.
|
|
11
|
+
#
|
|
12
|
+
# @example
|
|
13
|
+
# WorkflowPagination.check(root: ".")
|
|
14
|
+
module WorkflowPagination
|
|
15
|
+
# The files that hold workflow steps.
|
|
16
|
+
GLOBS = %w[.github/workflows/*.yml .github/workflows/*.yaml .github/actions/**/*.yml .github/actions/**/*.yaml].freeze
|
|
17
|
+
|
|
18
|
+
# The clean verdict.
|
|
19
|
+
CLEAN = "no workflow counts a GitHub list from its first page".freeze
|
|
20
|
+
|
|
21
|
+
# The words that start an API call in a step.
|
|
22
|
+
CALL = /gh api|api\.github\.com/
|
|
23
|
+
|
|
24
|
+
# Raised with every finding.
|
|
25
|
+
class Failure < StandardError; end
|
|
26
|
+
|
|
27
|
+
module_function
|
|
28
|
+
|
|
29
|
+
# @param root [String] the checkout
|
|
30
|
+
# @return [String] the clean verdict
|
|
31
|
+
# @raise [Failure] with a line for each call that reads one page
|
|
32
|
+
def check(root:)
|
|
33
|
+
found = findings(root)
|
|
34
|
+
raise Failure, found.join("\n") unless found.empty?
|
|
35
|
+
|
|
36
|
+
CLEAN
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @return [Array<String>] `file:line: fault` for each call that reads one page
|
|
40
|
+
def findings(root)
|
|
41
|
+
GLOBS.flat_map { |glob| Dir.glob(File.join(root, glob)) }.sort.flat_map do |file|
|
|
42
|
+
faults(file).map { |line, fault| "#{file.delete_prefix("#{root}/")}:#{line}: #{fault}" }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @return [Array<Array(Integer, String)>] the line and the fault of each bad call in a file
|
|
47
|
+
def faults(file)
|
|
48
|
+
lines = File.readlines(file, encoding: "UTF-8")
|
|
49
|
+
lines.each_index.filter_map do |index|
|
|
50
|
+
next if lines[index].lstrip.start_with?("#") || !lines[index].match?(CALL)
|
|
51
|
+
|
|
52
|
+
call = Statement.new(lines, index)
|
|
53
|
+
fault = Judge.fault(call)
|
|
54
|
+
[call.line, fault] if fault
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/hecks.rb
CHANGED
|
@@ -4,6 +4,7 @@ require_relative "hecks/version"
|
|
|
4
4
|
# them are read while a bluebook is still being parsed.
|
|
5
5
|
require_relative "hecks/vocabulary"
|
|
6
6
|
require_relative "hecks/rendering"
|
|
7
|
+
require_relative "hecks/secrets"
|
|
7
8
|
require_relative "hecks/naming"
|
|
8
9
|
require_relative "hecks/text"
|
|
9
10
|
require_relative "hecks/fqn"
|
|
@@ -31,6 +32,7 @@ require_relative "hecks/projections"
|
|
|
31
32
|
# After `Projector`, which dispatches against the `:cli` projection.
|
|
32
33
|
require_relative "hecks/adapters/driving/cli"
|
|
33
34
|
require_relative "hecks/adapters/driving/usage_cache"
|
|
35
|
+
require_relative "hecks/adapters/driving/usage_log"
|
|
34
36
|
require_relative "hecks/adapters/driving/cli_runner"
|
|
35
37
|
require_relative "hecks/storehouse"
|
|
36
38
|
require_relative "hecks/mcp_stdio_guard"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module RuboCop
|
|
2
|
+
module Cop
|
|
3
|
+
module Hecks
|
|
4
|
+
# Flags a quoted event or query name where its constant belongs: `starts_on "Message.Sent"`,
|
|
5
|
+
# `on "Sent"`, `trigger`, `for_each`, or a transition key `"Churn" => "churned"`. The constant
|
|
6
|
+
# fails when the bluebook loads; the string fails only at run time.
|
|
7
|
+
#
|
|
8
|
+
# Quoted state names stay quoted: a transition target and a `from:` name a state.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# starts_on "Message.Sent" # bad
|
|
12
|
+
# starts_on Message::Sent # good
|
|
13
|
+
# transition "Churn" => "churned", from: "active" # bad: the key names a command
|
|
14
|
+
# transition Churn => "churned", from: "active" # good
|
|
15
|
+
class BareEventAndQueryNames < Base
|
|
16
|
+
MSG = "`\"%<name>s\"` names an event or query by its string. Name it by its constant, " \
|
|
17
|
+
"`%<const>s`, so a misspelling fails at load.".freeze
|
|
18
|
+
|
|
19
|
+
STRING_NAMED_CALLS = %i[starts_on on trigger for_each].freeze
|
|
20
|
+
# `Message.Sent` (Aggregate.Name) or a bare `Sent`: a capitalised event or query name.
|
|
21
|
+
EVENT_NAME = /\A(?:[A-Z]\w*\.)?[A-Z]\w*\z/
|
|
22
|
+
|
|
23
|
+
# Flags a quoted event or query name passed to a call that takes one, or as a key.
|
|
24
|
+
#
|
|
25
|
+
# @param node [RuboCop::AST::SendNode] the call being visited
|
|
26
|
+
# @return [void]
|
|
27
|
+
def on_send(node)
|
|
28
|
+
return unless node.receiver.nil?
|
|
29
|
+
|
|
30
|
+
if STRING_NAMED_CALLS.include?(node.method_name)
|
|
31
|
+
flag_string_arguments(node)
|
|
32
|
+
elsif node.method_name == :transition
|
|
33
|
+
flag_transition_keys(node)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def flag_string_arguments(node)
|
|
40
|
+
node.arguments.each { |argument| flag_name(argument) if argument.str_type? }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def flag_transition_keys(node)
|
|
44
|
+
node.arguments.select(&:hash_type?).each do |hash|
|
|
45
|
+
hash.pairs.each { |pair| flag_name(pair.key) if pair.key.str_type? }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def flag_name(node)
|
|
50
|
+
name = node.value
|
|
51
|
+
return unless EVENT_NAME.match?(name)
|
|
52
|
+
|
|
53
|
+
add_offense(node, message: format(MSG, name: name, const: name.split(".").join("::")))
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module RuboCop
|
|
2
|
+
module Cop
|
|
3
|
+
module Hecks
|
|
4
|
+
# Flags `correlates_by "Message.id"` (or `:"Message.id"`) where the bare aggregate name
|
|
5
|
+
# `correlates_by Message` says the same thing. A bare name correlates by the aggregate's
|
|
6
|
+
# identity, so the dotted path only repeats it.
|
|
7
|
+
#
|
|
8
|
+
# A dotted path into a field (`:"widget.id"`, a lowercase head) is a field path, not an
|
|
9
|
+
# aggregate's identity, and is left alone.
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# correlates_by "Message.id" # bad
|
|
13
|
+
# correlates_by Message # good
|
|
14
|
+
# correlates_by :"widget.id" # good: a field path
|
|
15
|
+
class CorrelatesByAggregate < Base
|
|
16
|
+
MSG = "`correlates_by \"%<key>s\"` names the aggregate's id by a dotted path. A bare aggregate " \
|
|
17
|
+
"name correlates by its identity, so write `correlates_by %<name>s`.".freeze
|
|
18
|
+
|
|
19
|
+
AGGREGATE_ID = /\A([A-Z]\w*)\.id\z/
|
|
20
|
+
|
|
21
|
+
# Flags an aggregate's id named by a dotted path when the bare aggregate name would do.
|
|
22
|
+
#
|
|
23
|
+
# @param node [RuboCop::AST::SendNode] the `correlates_by` call being visited
|
|
24
|
+
# @return [void]
|
|
25
|
+
def on_send(node)
|
|
26
|
+
return unless node.receiver.nil? && node.method_name == :correlates_by
|
|
27
|
+
|
|
28
|
+
key = node.first_argument
|
|
29
|
+
return unless key && (key.str_type? || key.sym_type?)
|
|
30
|
+
|
|
31
|
+
match = AGGREGATE_ID.match(key.value.to_s)
|
|
32
|
+
return unless match
|
|
33
|
+
|
|
34
|
+
add_offense(key, message: format(MSG, key: key.value, name: match[1]))
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module RuboCop
|
|
2
|
+
module Cop
|
|
3
|
+
module Hecks
|
|
4
|
+
# Flags a creating command's attribute that no `sets` copies onto the aggregate. A command
|
|
5
|
+
# with no `reference_to` to its own aggregate creates one, so each attribute must be set.
|
|
6
|
+
#
|
|
7
|
+
# @example
|
|
8
|
+
# command "Print" do
|
|
9
|
+
# attribute :ref, StickerRef # bad unless `sets :ref`
|
|
10
|
+
# end
|
|
11
|
+
class CreatingCommandSets < Base
|
|
12
|
+
MSG = "Command `%<command>s` creates its aggregate, so its attribute `%<name>s` must be set " \
|
|
13
|
+
"onto it. Add `sets :%<name>s`.".freeze
|
|
14
|
+
|
|
15
|
+
# Flags each attribute of a creating command with no matching `sets`.
|
|
16
|
+
#
|
|
17
|
+
# @param node [RuboCop::AST::BlockNode] the command block being visited
|
|
18
|
+
# @return [void]
|
|
19
|
+
def on_block(node)
|
|
20
|
+
return unless node.send_node.receiver.nil? && node.method_name == :command
|
|
21
|
+
|
|
22
|
+
aggregate = owner_aggregate(node)
|
|
23
|
+
return unless aggregate
|
|
24
|
+
return if references_own_aggregate?(node, aggregate.send_node.first_argument.value)
|
|
25
|
+
|
|
26
|
+
unset_attributes(node).each { |statement, name| flag(statement, node, name) }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def owner_aggregate(node)
|
|
32
|
+
node.each_ancestor(:block).find { |block| block.method_name == :aggregate }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def flag(statement, node, name)
|
|
36
|
+
command = node.send_node.first_argument.value
|
|
37
|
+
add_offense(statement, message: format(MSG, command: command, name: name))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Each `attribute :x` of the command whose `sets :x` is missing, with its name.
|
|
41
|
+
def unset_attributes(node)
|
|
42
|
+
statements = direct_statements(node)
|
|
43
|
+
sets = statements.filter_map { |statement| symbol_argument(statement, :sets) }
|
|
44
|
+
statements.filter_map do |statement|
|
|
45
|
+
name = symbol_argument(statement, :attribute)
|
|
46
|
+
[statement, name] if name && !sets.include?(name)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def references_own_aggregate?(node, aggregate_name)
|
|
51
|
+
direct_statements(node).any? do |statement|
|
|
52
|
+
statement.send_type? && statement.method_name == :reference_to &&
|
|
53
|
+
statement.first_argument&.const_type? &&
|
|
54
|
+
statement.first_argument.const_name == aggregate_name
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# The symbol a one-argument call names, as in `sets :ref` or `attribute :ref, Type`.
|
|
59
|
+
def symbol_argument(statement, method)
|
|
60
|
+
return unless statement.send_type? && statement.method_name == method
|
|
61
|
+
return unless statement.first_argument&.sym_type?
|
|
62
|
+
|
|
63
|
+
statement.first_argument.value
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def direct_statements(block)
|
|
67
|
+
body = block.body
|
|
68
|
+
return [] unless body
|
|
69
|
+
|
|
70
|
+
body.begin_type? ? body.children : [body]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module RuboCop
|
|
2
|
+
module Cop
|
|
3
|
+
module Hecks
|
|
4
|
+
# Flags a call the bluebook expression language cannot evaluate, inside an `invariant` or
|
|
5
|
+
# `given` block. The language refuses these with "the expression language cannot evaluate",
|
|
6
|
+
# so the bluebook fails at boot, not where the check was written.
|
|
7
|
+
#
|
|
8
|
+
# The language compares with `==`, `!=` and `>=`, joined by `||` and `&&`.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# invariant("a flag is yes or no") { value.include?("yes") } # bad
|
|
12
|
+
# invariant("a flag is yes or no") { value == "yes" || value == "no" } # good
|
|
13
|
+
# invariant("a name is present") { name.empty? } # bad
|
|
14
|
+
# invariant("a name is present") { name != "" } # good
|
|
15
|
+
class InvariantExpressionLanguage < Base
|
|
16
|
+
MSG = "`%<source>s` is outside the expression language, which cannot evaluate it. Spell the " \
|
|
17
|
+
"test out: `==` joined by `||` for a set of values, or `!= \"\"` for a non-empty test.".freeze
|
|
18
|
+
|
|
19
|
+
CHECKED_BLOCKS = %i[invariant given].freeze
|
|
20
|
+
UNSUPPORTED_CALLS = %i[include? length to_s empty? between?].freeze
|
|
21
|
+
|
|
22
|
+
# Flags an unsupported call or a `%w[...]` list in an `invariant` or `given` block.
|
|
23
|
+
#
|
|
24
|
+
# @param node [RuboCop::AST::BlockNode] the block being visited
|
|
25
|
+
# @return [void]
|
|
26
|
+
def on_block(node)
|
|
27
|
+
return unless node.send_node.receiver.nil? && CHECKED_BLOCKS.include?(node.method_name)
|
|
28
|
+
return unless node.body
|
|
29
|
+
|
|
30
|
+
node.body.each_node(:send, :array) do |child|
|
|
31
|
+
next unless unsupported?(child)
|
|
32
|
+
|
|
33
|
+
add_offense(child, message: format(MSG, source: child.source))
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def unsupported?(node)
|
|
40
|
+
return node.source.start_with?("%w") if node.array_type?
|
|
41
|
+
|
|
42
|
+
node.send_type? && UNSUPPORTED_CALLS.include?(node.method_name)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module RuboCop
|
|
2
|
+
module Cop
|
|
3
|
+
module Hecks
|
|
4
|
+
# Flags a `lifecycle :x` whose owner (the nearest `aggregate` or `entity`) declares no
|
|
5
|
+
# `attribute :x`. A lifecycle moves a value that its owner must hold.
|
|
6
|
+
#
|
|
7
|
+
# @example
|
|
8
|
+
# lifecycle :status, default: "open" do # bad unless `attribute :status`
|
|
9
|
+
# end
|
|
10
|
+
class LifecycleNeedsAttribute < Base
|
|
11
|
+
MSG = "`lifecycle :%<name>s` has no state to hold: `%<owner>s` declares no " \
|
|
12
|
+
"`attribute :%<name>s`. Declare the attribute the lifecycle tracks.".freeze
|
|
13
|
+
OWNERS = %i[aggregate entity].freeze
|
|
14
|
+
|
|
15
|
+
# Flags a lifecycle whose owner declares no attribute of the same name.
|
|
16
|
+
#
|
|
17
|
+
# @param node [RuboCop::AST::SendNode] the `lifecycle` call being visited
|
|
18
|
+
# @return [void]
|
|
19
|
+
def on_send(node)
|
|
20
|
+
return unless node.receiver.nil? && node.method_name == :lifecycle
|
|
21
|
+
return unless node.first_argument&.sym_type?
|
|
22
|
+
|
|
23
|
+
owner = owner_block(node)
|
|
24
|
+
return unless owner
|
|
25
|
+
|
|
26
|
+
name = node.first_argument.value
|
|
27
|
+
return if attribute_names(owner).include?(name)
|
|
28
|
+
|
|
29
|
+
add_offense(node, message: format(MSG, name: name, owner: owner.send_node.first_argument.value))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def owner_block(node)
|
|
35
|
+
node.each_ancestor(:block).find do |block|
|
|
36
|
+
OWNERS.include?(block.method_name) && block.send_node.receiver.nil?
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def attribute_names(owner)
|
|
41
|
+
direct_statements(owner).filter_map do |statement|
|
|
42
|
+
next unless statement.send_type? && statement.method_name == :attribute
|
|
43
|
+
next unless statement.first_argument&.sym_type?
|
|
44
|
+
|
|
45
|
+
statement.first_argument.value
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def direct_statements(block)
|
|
50
|
+
body = block.body
|
|
51
|
+
return [] unless body
|
|
52
|
+
|
|
53
|
+
body.begin_type? ? body.children : [body]
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module RuboCop
|
|
2
|
+
module Cop
|
|
3
|
+
module Hecks
|
|
4
|
+
# Flags a plain-string attribute that holds another record's id, such as
|
|
5
|
+
# `attribute :teacher_id, String`. Declare `reference_to` so the domain holds the record.
|
|
6
|
+
# A query's argument is exempt: `attribute :author_id, String` names a caller's value.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# attribute :teacher_id, String # bad
|
|
10
|
+
# reference_to Person, as: :teacher # good
|
|
11
|
+
#
|
|
12
|
+
# query "ByAuthor" do
|
|
13
|
+
# attribute :author_id, String # good: a caller's argument
|
|
14
|
+
# where author: :author_id
|
|
15
|
+
# end
|
|
16
|
+
class NoIdStringAttribute < Base
|
|
17
|
+
MSG = "`%<name>s` stores another record's id as a string. Declare `reference_to %<target>s, as: :%<role>s` " \
|
|
18
|
+
"so the domain holds the reference, and let the adapter map the school's ids.".freeze
|
|
19
|
+
|
|
20
|
+
# @!method id_string_attribute?(node)
|
|
21
|
+
def_node_matcher :id_string_attribute?, <<~PATTERN
|
|
22
|
+
(send nil? :attribute $(sym _) (const nil? :String))
|
|
23
|
+
PATTERN
|
|
24
|
+
|
|
25
|
+
# Flags an `attribute :x_id, String` declared outside a `query`.
|
|
26
|
+
#
|
|
27
|
+
# @param node [RuboCop::AST::SendNode] the call being visited
|
|
28
|
+
# @return [void]
|
|
29
|
+
def on_send(node)
|
|
30
|
+
id_string_attribute?(node) do |name_node|
|
|
31
|
+
name = name_node.value.to_s
|
|
32
|
+
return unless name.end_with?("_id")
|
|
33
|
+
return if inside_query?(node)
|
|
34
|
+
|
|
35
|
+
role = name.delete_suffix("_id")
|
|
36
|
+
add_offense(node, message: format(MSG, name: name, target: role.capitalize, role: role))
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
# True when the attribute sits in a `query` block, at any depth.
|
|
43
|
+
def inside_query?(node)
|
|
44
|
+
node.each_ancestor(:block).any? { |block| block.method_name == :query }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module RuboCop
|
|
2
|
+
module Cop
|
|
3
|
+
module Hecks
|
|
4
|
+
# Flags a second `mark :terminal` line in one lifecycle. A lifecycle names its terminal states
|
|
5
|
+
# once, on one line, so the set reads in one place and a state cannot be left out of it.
|
|
6
|
+
#
|
|
7
|
+
# @example
|
|
8
|
+
# lifecycle :status, default: "open" do
|
|
9
|
+
# mark :terminal, "closed"
|
|
10
|
+
# mark :terminal, "void" # bad
|
|
11
|
+
# end
|
|
12
|
+
#
|
|
13
|
+
# lifecycle :status, default: "open" do
|
|
14
|
+
# mark :terminal, "closed", "void" # good
|
|
15
|
+
# end
|
|
16
|
+
class OneTerminalMarkPerLifecycle < Base
|
|
17
|
+
MSG = "A lifecycle takes one `mark :terminal` line. Name every terminal state on that line, as " \
|
|
18
|
+
"`mark :terminal, \"a\", \"b\"`.".freeze
|
|
19
|
+
|
|
20
|
+
# Flags every `mark :terminal` after the first in a lifecycle block.
|
|
21
|
+
#
|
|
22
|
+
# @param node [RuboCop::AST::BlockNode] the lifecycle block being visited
|
|
23
|
+
# @return [void]
|
|
24
|
+
def on_block(node)
|
|
25
|
+
return unless node.send_node.receiver.nil? && node.method_name == :lifecycle
|
|
26
|
+
|
|
27
|
+
marks = direct_statements(node).select { |statement| terminal_mark?(statement) }
|
|
28
|
+
marks.drop(1).each { |mark| add_offense(mark, message: MSG) }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def terminal_mark?(node)
|
|
34
|
+
node.send_type? && node.method_name == :mark &&
|
|
35
|
+
node.first_argument&.sym_type? && node.first_argument.value == :terminal
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def direct_statements(block)
|
|
39
|
+
body = block.body
|
|
40
|
+
return [] unless body
|
|
41
|
+
|
|
42
|
+
body.begin_type? ? body.children : [body]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module RuboCop
|
|
2
|
+
module Cop
|
|
3
|
+
module Hecks
|
|
4
|
+
# Flags a value object block that only wraps one `value` attribute with no invariant.
|
|
5
|
+
# The shorthand says the same thing in one line: `value_object "Name", Type`.
|
|
6
|
+
#
|
|
7
|
+
# A block with an invariant, or with any other attribute, is left alone: the block is the
|
|
8
|
+
# only place an invariant can go.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# value_object "EmailAddress" do # bad
|
|
12
|
+
# attribute :value, String
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# value_object "EmailAddress", String # good
|
|
16
|
+
class ValueObjectShorthand < Base
|
|
17
|
+
MSG = "`value_object \"%<name>s\"` holds one value with no invariant, so declare it as " \
|
|
18
|
+
"`value_object \"%<name>s\", %<type>s`.".freeze
|
|
19
|
+
|
|
20
|
+
# Flags a `value_object` block whose whole body is `attribute :value, Type`.
|
|
21
|
+
#
|
|
22
|
+
# @param node [RuboCop::AST::BlockNode] the block being visited
|
|
23
|
+
# @return [void]
|
|
24
|
+
def on_block(node)
|
|
25
|
+
return unless value_object_block?(node)
|
|
26
|
+
return unless single_value_attribute?(node.body)
|
|
27
|
+
|
|
28
|
+
send = node.send_node
|
|
29
|
+
add_offense(send, message: offense_message(send, node.body))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
# A `value_object "Name"` call with no receiver and a string name.
|
|
35
|
+
def value_object_block?(node)
|
|
36
|
+
send = node.send_node
|
|
37
|
+
send.receiver.nil? && send.method_name == :value_object && send.first_argument&.str_type?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def offense_message(send, body)
|
|
41
|
+
type = body.arguments.last.const_name || body.arguments.last.source
|
|
42
|
+
format(MSG, name: send.first_argument.value, type: type)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# The body is exactly one `attribute :value, Type` call.
|
|
46
|
+
def single_value_attribute?(body)
|
|
47
|
+
return false unless body&.send_type?
|
|
48
|
+
return false unless body.method_name == :attribute && body.arguments.size == 2
|
|
49
|
+
|
|
50
|
+
name, type = body.arguments
|
|
51
|
+
name.sym_type? && name.value == :value && type.const_type?
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
Binary file
|
|
Binary file
|
data/qa/settings.yml
CHANGED
|
@@ -61,6 +61,29 @@ generated_domains_per_tick: 2
|
|
|
61
61
|
generated_domains_rust: true
|
|
62
62
|
generated_domain_seeds: 5
|
|
63
63
|
|
|
64
|
+
# The quick gate on local main, the tick's last finding step: each red check becomes a bug, and a
|
|
65
|
+
# self-contained one is fixed, gated, landed and pushed.
|
|
66
|
+
red_main_check: true
|
|
67
|
+
|
|
68
|
+
# The event pump, the tick's last step: each attached domain's policies react to the events past their
|
|
69
|
+
# cursors. `hecks quality_control event_pump.pump!` runs it by hand whatever this says.
|
|
70
|
+
event_pump: true
|
|
71
|
+
|
|
72
|
+
# The push check, once per tick: a push of local main that is due beyond the QualityControl world's
|
|
73
|
+
# `push_nudge` thresholds is one `push-due` Work row, revised while due and finished when not. It reads
|
|
74
|
+
# refs git already holds and pushes nothing.
|
|
75
|
+
push_nudge: true
|
|
76
|
+
|
|
77
|
+
# A quiet tick for a mint window: true makes every step print `quiesced: skipped <step>` and the tick exit 0.
|
|
78
|
+
# A running tick also stops at the marker `hecks qa_quiesce.hold!` writes (a stale one is ignored), so prefer that
|
|
79
|
+
# for a window; this dial is for a standing pause.
|
|
80
|
+
quiesced: false
|
|
81
|
+
|
|
82
|
+
# The main-maintenance chain after the red-main step: the quick gate on main, the reconcile plan, and the push
|
|
83
|
+
# through the train when origin is behind. `maintenance_confirm` lets the reconcile write; false keeps it a dry run.
|
|
84
|
+
main_maintenance: true
|
|
85
|
+
maintenance_confirm: false
|
|
86
|
+
|
|
64
87
|
# The Rust kernel's mutation test, run by each tick after the generated domains (about 8 minutes).
|
|
65
88
|
# The two equivalents compare positions where `<` and `<=` cannot differ.
|
|
66
89
|
mutation_files:
|
data/rust/.gitignore
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
1
|
/target
|
|
2
2
|
/dist
|
|
3
|
-
|
|
4
|
-
# Generated from the bluebooks by `hecks regeneration_run.regenerate_corpus --confirm`; mod.rs and the
|
|
5
|
-
# Cargo features stay tracked. pizzas stays committed: its translations carry SQL only the Ruby
|
|
6
|
-
# toolchain compiles, so hecks-build cannot reproduce it.
|
|
7
|
-
/src/generated/*/
|
|
8
|
-
!/src/generated/pizzas/
|
data/rust/Cargo.toml
CHANGED
|
@@ -45,6 +45,7 @@ roster = []
|
|
|
45
45
|
meta = []
|
|
46
46
|
pizzas = []
|
|
47
47
|
banking = []
|
|
48
|
+
echo = []
|
|
48
49
|
|
|
49
50
|
[package]
|
|
50
51
|
name = "rust"
|
|
@@ -72,7 +73,7 @@ path = "src/main.rs"
|
|
|
72
73
|
debug = 0
|
|
73
74
|
|
|
74
75
|
# Clippy beyond its defaults: pedantic and nursery, plus the restriction lints that keep a panic
|
|
75
|
-
# out of library code. `hecks gate_run.gate stage=ci only=rust_clippy` makes each of these an error.
|
|
76
|
+
# out of library code. `hecks gate_run.gate! stage=ci only=rust_clippy` makes each of these an error.
|
|
76
77
|
# The same table is in every crate's Cargo.toml; change them together.
|
|
77
78
|
[lints.clippy]
|
|
78
79
|
pedantic = { level = "warn", priority = -1 }
|
data/rust/build/Cargo.toml
CHANGED
|
@@ -19,7 +19,7 @@ path = "src/main.rs"
|
|
|
19
19
|
debug = 0
|
|
20
20
|
|
|
21
21
|
# Clippy beyond its defaults: pedantic and nursery, plus the restriction lints that keep a panic
|
|
22
|
-
# out of library code. `hecks gate_run.gate stage=ci only=rust_clippy` makes each of these an error.
|
|
22
|
+
# out of library code. `hecks gate_run.gate! stage=ci only=rust_clippy` makes each of these an error.
|
|
23
23
|
# The same table is in every crate's Cargo.toml; change them together.
|
|
24
24
|
[lints.clippy]
|
|
25
25
|
pedantic = { level = "warn", priority = -1 }
|
|
@@ -77,7 +77,7 @@ fn persistence(
|
|
|
77
77
|
let text = read(path)?;
|
|
78
78
|
(
|
|
79
79
|
lineage_pass::persistence_binds(&text),
|
|
80
|
-
domain_default(&text, declaration)
|
|
80
|
+
domain_default(&text, declaration)?,
|
|
81
81
|
)
|
|
82
82
|
}
|
|
83
83
|
None => (HashMap::new(), None),
|
|
@@ -115,7 +115,11 @@ fn persistence(
|
|
|
115
115
|
|
|
116
116
|
// The bare `persisted_by "X"` line of the bluebook's own `Hecks.hecksagon` block: every aggregate
|
|
117
117
|
// without a bind of its own inherits it. The last one in the block wins.
|
|
118
|
-
|
|
118
|
+
//
|
|
119
|
+
// The line is read as text, not evaluated, so anything after the adapter's name (a guard such as
|
|
120
|
+
// `if ENV[...]`, or an option) cannot be honored here. Such a line is refused rather than read as
|
|
121
|
+
// an unconditional bind, because the build and the Ruby loader would then disagree on the adapter.
|
|
122
|
+
fn domain_default(text: &str, declaration: &str) -> Result<Option<String>, String> {
|
|
119
123
|
let mut in_bluebook = false;
|
|
120
124
|
let mut found = None;
|
|
121
125
|
for line in text.lines() {
|
|
@@ -130,11 +134,60 @@ fn domain_default(text: &str, declaration: &str) -> Option<String> {
|
|
|
130
134
|
continue;
|
|
131
135
|
};
|
|
132
136
|
let quoted = &rest[open + 1..];
|
|
133
|
-
|
|
137
|
+
let Some(close) = quoted.find('"') else {
|
|
138
|
+
found = None;
|
|
139
|
+
continue;
|
|
140
|
+
};
|
|
141
|
+
let after = quoted[close + 1..].trim();
|
|
142
|
+
if !after.is_empty() && !after.starts_with('#') {
|
|
143
|
+
return Err(format!(
|
|
144
|
+
"{declaration}'s hecksagon has `persisted_by` with `{after}` after the adapter; \
|
|
145
|
+
the build cannot evaluate that, so the bind is refused. Remove the condition, \
|
|
146
|
+
or wire the adapter in a hecksagon that applies to it."
|
|
147
|
+
));
|
|
148
|
+
}
|
|
149
|
+
found = Some(quoted[..close].to_string());
|
|
134
150
|
}
|
|
135
|
-
found
|
|
151
|
+
Ok(found)
|
|
136
152
|
}
|
|
137
153
|
|
|
138
154
|
fn read(path: &Path) -> Result<String, String> {
|
|
139
155
|
std::fs::read_to_string(path).map_err(|e| format!("reading {}: {e}", path.display()))
|
|
140
156
|
}
|
|
157
|
+
|
|
158
|
+
#[cfg(test)]
|
|
159
|
+
mod tests {
|
|
160
|
+
use super::domain_default;
|
|
161
|
+
|
|
162
|
+
#[test]
|
|
163
|
+
fn a_bare_bind_names_the_domain_default() {
|
|
164
|
+
let text = "Hecks.hecksagon \"Miette\" do\n persisted_by \"PostgresEra\"\nend\n";
|
|
165
|
+
assert_eq!(
|
|
166
|
+
domain_default(text, "Miette"),
|
|
167
|
+
Ok(Some("PostgresEra".to_string()))
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
#[test]
|
|
172
|
+
fn a_trailing_comment_is_not_a_condition() {
|
|
173
|
+
let text = "Hecks.hecksagon \"Miette\" do\n persisted_by \"Memory\" # in-memory by default\nend\n";
|
|
174
|
+
assert_eq!(
|
|
175
|
+
domain_default(text, "Miette"),
|
|
176
|
+
Ok(Some("Memory".to_string()))
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
#[test]
|
|
181
|
+
fn a_guarded_bind_is_refused_not_read_as_unconditional() {
|
|
182
|
+
let text = "Hecks.hecksagon \"Miette\" do\n persisted_by \"PostgresEra\" if ENV[\"MIETTE_LOCAL\"]\nend\n";
|
|
183
|
+
let err = domain_default(text, "Miette").unwrap_err();
|
|
184
|
+
assert!(err.contains("`if ENV[\"MIETTE_LOCAL\"]`"), "{err}");
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
#[test]
|
|
188
|
+
fn a_bind_in_another_bluebook_is_ignored() {
|
|
189
|
+
let text =
|
|
190
|
+
"Hecks.hecksagon \"Other\" do\n persisted_by \"PostgresEra\" if ENV[\"X\"]\nend\n";
|
|
191
|
+
assert_eq!(domain_default(text, "Miette"), Ok(None));
|
|
192
|
+
}
|
|
193
|
+
}
|