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,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Runtime
|
|
5
|
+
# What an in-memory dispatch would have written and announced, collected while the dispatch
|
|
6
|
+
# runs. The command interpreter reports each save and each emitted event here when it runs
|
|
7
|
+
# in dry mode, so every command gets a plan from the same seam with no per-command code.
|
|
8
|
+
module DryRunPlan
|
|
9
|
+
KEY = :hecks_dry_run_plan
|
|
10
|
+
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
# Runs the block and returns the lines it would have produced.
|
|
14
|
+
#
|
|
15
|
+
# @yield the in-memory dispatch
|
|
16
|
+
# @return [Array<String>] one `would …` line per write or event, in order
|
|
17
|
+
def collect
|
|
18
|
+
previous = Thread.current[KEY]
|
|
19
|
+
Thread.current[KEY] = []
|
|
20
|
+
yield
|
|
21
|
+
Thread.current[KEY]
|
|
22
|
+
ensure
|
|
23
|
+
Thread.current[KEY] = previous
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Records one write the dispatch would make.
|
|
27
|
+
#
|
|
28
|
+
# @param aggregate [Bluebook::Aggregate] the aggregate the record belongs to
|
|
29
|
+
# @param instance [Runtime::Instance] the record the dispatch would write
|
|
30
|
+
# @return [void]
|
|
31
|
+
def write(aggregate, instance)
|
|
32
|
+
record("would write #{aggregate.hecks_name} #{instance.id}")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Records one event the dispatch would announce.
|
|
36
|
+
#
|
|
37
|
+
# @param name [String] the event's name
|
|
38
|
+
# @return [void]
|
|
39
|
+
def emit(name)
|
|
40
|
+
record("would emit #{name}")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Records each event a command announces.
|
|
44
|
+
#
|
|
45
|
+
# @param command [Bluebook::Command] the command the dispatch runs
|
|
46
|
+
# @return [void]
|
|
47
|
+
def emits(command)
|
|
48
|
+
command.emits.each { |name| emit(name) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Appends a line when a plan is being collected; otherwise does nothing.
|
|
52
|
+
#
|
|
53
|
+
# @param line [String]
|
|
54
|
+
# @return [void]
|
|
55
|
+
def record(line)
|
|
56
|
+
Thread.current[KEY]&.push(line)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -26,7 +26,6 @@ module Hecks
|
|
|
26
26
|
# Walks `chain` one hop at a time and returns the located element (or `instance`
|
|
27
27
|
# itself when `chain` is empty). `route`, when given, offers each hop's identity
|
|
28
28
|
# before falling back to `args`.
|
|
29
|
-
# rubocop:disable-next Metrics/ParameterLists -- the positional entry point EntityInterpreter and delegation call
|
|
30
29
|
def locate_chain(root_aggregate, chain, instance, args, command_name, route = nil)
|
|
31
30
|
container = instance
|
|
32
31
|
owner = root_aggregate
|
|
@@ -37,7 +37,6 @@ module Hecks
|
|
|
37
37
|
# Applies one declared mutation to an entity element, in place. `pre` is the
|
|
38
38
|
# element as it stood before this command: every read goes through it, every
|
|
39
39
|
# write lands on `element`.
|
|
40
|
-
# rubocop:disable-next Metrics/ParameterLists -- the positional signature callers (and specs) wrap
|
|
41
40
|
def apply_to_element(rules, aggregate, entity, element, mutation, args, pre = element)
|
|
42
41
|
handler = OP_HANDLERS.fetch(mutation.op) do
|
|
43
42
|
# Backstop: an unhandled op must refuse, not silently apply nothing.
|
|
@@ -19,7 +19,12 @@ module Hecks
|
|
|
19
19
|
ctx.instance = step(:hydrate_parent) { parent_record(ctx) }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
# A validation records `hydrate_parent`'s refusal and goes on within the stage, so the
|
|
23
|
+
# parent may be missing here: then there is nothing to locate in, and the one refusal
|
|
24
|
+
# already recorded is the answer a dispatch raises.
|
|
22
25
|
def step_locate_element(ctx)
|
|
26
|
+
return unless ctx.instance
|
|
27
|
+
|
|
23
28
|
ctx.element = step(:locate_element) do
|
|
24
29
|
EntityElement.locate_chain(ctx.aggregate, ctx.chain, ctx.instance, ctx.args, ctx.command_name, ctx.route)
|
|
25
30
|
end
|
|
@@ -48,7 +48,6 @@ module Hecks
|
|
|
48
48
|
# `element`/`view` are the entity piece itself, pre- and
|
|
49
49
|
# post-mutation. `:chain` intentionally shadows Enumerable#chain —
|
|
50
50
|
# every read is the struct field, never enumerable-combining.
|
|
51
|
-
# rubocop:disable-next Lint/StructNewOverride
|
|
52
51
|
Context = Struct.new(:domain, :aggregate, :entity, :entity_name, :command, :command_name,
|
|
53
52
|
:args, :repository, :instance, :chain, :element, :view, :transition,
|
|
54
53
|
:old_element, :result, :route, :plan, :persistence_outcome, :dry_run, :outbox_rows,
|
data/lib/hecks/runtime/errors.rb
CHANGED
|
@@ -88,5 +88,31 @@ module Hecks
|
|
|
88
88
|
# Names come from the language; resolving them here fails at load if one is undefined.
|
|
89
89
|
# Each is a `Hecks::Refused`, and nothing else is, so rescuing either catches the same set.
|
|
90
90
|
DOMAIN_REFUSALS = Hecks::Vocabulary.fetch("DomainRefusal").map { |name| const_get(name) }.freeze
|
|
91
|
+
|
|
92
|
+
# The errors that mean the code is wrong, not that the outside world said no: a name that
|
|
93
|
+
# does not resolve (`NameError`, and `NoMethodError` under it), a value of the wrong class
|
|
94
|
+
# (`TypeError`), a write to a frozen value (`FrozenError`), and code that would not load
|
|
95
|
+
# (`ScriptError`: `LoadError`, `NotImplementedError`, `SyntaxError`). An ask that meets one
|
|
96
|
+
# raises it instead of announcing its `refuses` event, so the defect is seen where it happens.
|
|
97
|
+
#
|
|
98
|
+
# `ArgumentError` is left out on purpose: adapters raise its subclasses to refuse input they
|
|
99
|
+
# were handed (`TenantProvisioner::Refused`, `Composer::Workspace::OutsideWorkspace`), and
|
|
100
|
+
# parsing outside data raises it (`Integer("x")`, `Date::Error`), so it is the world saying no
|
|
101
|
+
# as often as it is a wrong call.
|
|
102
|
+
PROGRAMMING_ERRORS = [NameError, TypeError, FrozenError, ScriptError].freeze
|
|
103
|
+
|
|
104
|
+
# @param error [Exception] the error an adapter raised
|
|
105
|
+
# @return [Boolean] whether `error` is a defect in the code rather than a refusal
|
|
106
|
+
def self.programming_error?(error) = PROGRAMMING_ERRORS.any? { |kind| error.is_a?(kind) }
|
|
107
|
+
|
|
108
|
+
# The refusal text of a failure an ask records: its class and message. An error raised with no
|
|
109
|
+
# message still names its class, so a refusal never arrives empty.
|
|
110
|
+
#
|
|
111
|
+
# @param error [Exception] the error an adapter raised
|
|
112
|
+
# @return [String] `"Class: message"`, never blank
|
|
113
|
+
def self.failure_reason(error)
|
|
114
|
+
message = error.message.to_s.strip
|
|
115
|
+
"#{error.class}: #{message.empty? ? "raised with no message" : message}"
|
|
116
|
+
end
|
|
91
117
|
end
|
|
92
118
|
end
|
|
@@ -19,7 +19,6 @@ module Hecks
|
|
|
19
19
|
# `hydrate_with:` replaces the default hydration with a callable that takes the given
|
|
20
20
|
# state and answers the hydrated one (defaults filled), for an adapter that can reuse
|
|
21
21
|
# work across saves.
|
|
22
|
-
# rubocop:disable-next Metrics/ParameterLists -- the public keyword constructor every caller spells out
|
|
23
22
|
def initialize(aggregate:, id:, state: nil, args: nil, hydrate: true, hydrate_with: nil)
|
|
24
23
|
@aggregate = aggregate
|
|
25
24
|
@id = id
|
|
@@ -21,7 +21,6 @@ module Hecks
|
|
|
21
21
|
# :entity, :port). Each checks its own parts in a fixed order, because
|
|
22
22
|
# a malformed call's refusal depends on that order; `declaring` is
|
|
23
23
|
# called exactly once, at that shape's point in the order below.
|
|
24
|
-
# rubocop:disable-next Metrics/ParameterLists -- the public keyword entry point every dispatch calls
|
|
25
24
|
def from_call(verb, to:, with:, flat:, receiver: :aggregate, entity_depth: 0, aggregate: nil, &declaring)
|
|
26
25
|
call = Call.new(verb, to, with, flat, entity_depth, aggregate, declaring)
|
|
27
26
|
case receiver
|
|
@@ -15,7 +15,7 @@ module Hecks
|
|
|
15
15
|
kind, fqn = row.consumer.split(":", 2)
|
|
16
16
|
home, name = fqn.split("::", 2)
|
|
17
17
|
case kind
|
|
18
|
-
when "policy" then run_policy(row, event, fqn, home, name)
|
|
18
|
+
when "policy" then refusal_reason(run_policy(row, event, fqn, home, name))
|
|
19
19
|
when "saga" then run_saga(row, event, fqn, home, name)
|
|
20
20
|
else
|
|
21
21
|
raise WiringError, "outbox row #{row.delivery_id} has an unknown consumer kind #{kind.inspect}"
|
|
@@ -28,11 +28,19 @@ module Hecks
|
|
|
28
28
|
@policies.react(event, row.domain, only: [policy, home], event_uid: row.event_uid)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# The reason the domain refused a policy's reaction, nil when none was refused. A defect
|
|
32
|
+
# is not a refusal: it is warned where it happens and the row settles as before.
|
|
33
|
+
def refusal_reason(records)
|
|
34
|
+
refused = Array(records).find { |record| record[:delivered] == false && !record[:defect] }
|
|
35
|
+
refused && (refused[:reason].to_s.empty? ? "refused (no reason given)" : refused[:reason].to_s)
|
|
36
|
+
end
|
|
37
|
+
|
|
31
38
|
def run_saga(row, event, fqn, home, name)
|
|
32
39
|
process_manager = @registry.bluebook(home)&.process_managers&.find { |candidate| candidate.name == name } ||
|
|
33
40
|
raise(WiringError,
|
|
34
41
|
"outbox row #{row.delivery_id} names process_manager #{fqn}, which no bluebook declares")
|
|
35
42
|
@sagas.advance(event, row.domain, only: process_manager)
|
|
43
|
+
nil
|
|
36
44
|
end
|
|
37
45
|
end
|
|
38
46
|
end
|
|
@@ -31,6 +31,26 @@ module Hecks
|
|
|
31
31
|
|
|
32
32
|
def attached? = !@policies.nil?
|
|
33
33
|
|
|
34
|
+
# Runs one policy's reaction to `event`, as a row's delivery runs it: its outcome is
|
|
35
|
+
# recorded on the registry's reaction log, a refusal included, and nothing is raised.
|
|
36
|
+
#
|
|
37
|
+
# @param event [Runtime::Event] the event the policy reacts to
|
|
38
|
+
# @param policy [Bluebook::Policy] the policy to run
|
|
39
|
+
# @param home [String] the bluebook the policy is declared in
|
|
40
|
+
# @param domain [String] the domain the event came from
|
|
41
|
+
# @param event_uid [String] the identity the reaction log records for the event
|
|
42
|
+
# @return [void]
|
|
43
|
+
def react_policy(event, policy:, home:, domain:, event_uid:)
|
|
44
|
+
@policies.react(event, domain, only: [policy, home], event_uid: event_uid)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Answers the policies `event` triggers in `domain`, as `[policy, home]` pairs.
|
|
48
|
+
#
|
|
49
|
+
# @param event [Runtime::Event] the event to react to
|
|
50
|
+
# @param domain [String] the domain the event came from
|
|
51
|
+
# @return [Array(Bluebook::Policy, String)]
|
|
52
|
+
def policies_for(event, domain) = @policies.policies_for(event, domain)
|
|
53
|
+
|
|
34
54
|
# Forgets every delivery the relay recorded, as a fresh boot starts with none.
|
|
35
55
|
#
|
|
36
56
|
# @return [void]
|
|
@@ -82,11 +102,12 @@ module Hecks
|
|
|
82
102
|
private
|
|
83
103
|
|
|
84
104
|
def settle_delivery(row, repository)
|
|
85
|
-
run_consumer(row)
|
|
86
|
-
|
|
87
|
-
row.status
|
|
105
|
+
reason = run_consumer(row)
|
|
106
|
+
row.status = reason ? "refused" : "delivered"
|
|
107
|
+
repository.outbox_settle(row.id, status: row.status, error: reason)
|
|
108
|
+
row.error = reason
|
|
88
109
|
true
|
|
89
|
-
rescue StandardError => e
|
|
110
|
+
rescue StandardError, ScriptError => e
|
|
90
111
|
settle_failed(row, repository, e)
|
|
91
112
|
false
|
|
92
113
|
end
|
|
@@ -48,7 +48,9 @@ module Hecks
|
|
|
48
48
|
def ask_target(row)
|
|
49
49
|
kind, fqn = row.consumer.split(":", 2)
|
|
50
50
|
home, name = fqn.split("::", 2)
|
|
51
|
-
|
|
51
|
+
return nil unless kind == "policy"
|
|
52
|
+
|
|
53
|
+
policy = @registry.bluebook(home)&.policies&.find { |candidate| candidate.name == name }
|
|
52
54
|
return nil unless policy&.asks?
|
|
53
55
|
|
|
54
56
|
aggregate_and_port, operation = policy.trigger_command.split(".", 2)
|
data/lib/hecks/runtime/outbox.rb
CHANGED
|
@@ -10,8 +10,11 @@ module Hecks
|
|
|
10
10
|
# A durable outbox (ADR 0053): one row per (event, consumer), written in
|
|
11
11
|
# the same transaction as the aggregate save so a reaction is never lost.
|
|
12
12
|
module Outbox
|
|
13
|
-
# pending -> claimed -> delivered | failed
|
|
14
|
-
|
|
13
|
+
# pending -> claimed -> delivered | failed | refused. A reaction the domain refused (its
|
|
14
|
+
# trigger was declined, its `with:` read a key the event lacked, the cascade was too deep)
|
|
15
|
+
# is settled `refused` with the reason in `error`: it ran and said no, which is neither
|
|
16
|
+
# delivery nor a defect, and a trace reads it back.
|
|
17
|
+
STATUSES = %w[pending claimed delivered failed refused].freeze
|
|
15
18
|
|
|
16
19
|
# How long a row stays claimed before it counts as stalled: a claim that old was left by a
|
|
17
20
|
# process that is gone, where a younger one is a reaction running in another process. Ten
|
|
@@ -26,6 +29,7 @@ module Hecks
|
|
|
26
29
|
def claimed? = status == "claimed"
|
|
27
30
|
def delivered? = status == "delivered"
|
|
28
31
|
def failed? = status == "failed"
|
|
32
|
+
def refused? = status == "refused"
|
|
29
33
|
|
|
30
34
|
# A claimed row is stalled when its age is unknown or past `STALLED_AFTER`; a younger one is
|
|
31
35
|
# a reaction still running.
|
|
@@ -7,6 +7,9 @@ module Hecks
|
|
|
7
7
|
# A `for_each` policy: asks a query which rows the event concerns, and fires the trigger
|
|
8
8
|
# once per row through the {RowSweep} a bulk run shares. Mixed into {PolicyInterpreter}.
|
|
9
9
|
module FanOut
|
|
10
|
+
# The bare scalar types a `for_each` query may declare as an argument.
|
|
11
|
+
SCALAR_ARGUMENT_TYPES = %w[String Integer Float].freeze
|
|
12
|
+
|
|
10
13
|
private
|
|
11
14
|
|
|
12
15
|
# Runs the `for_each` query against the event payload and fires the trigger once
|
|
@@ -45,9 +48,22 @@ module Hecks
|
|
|
45
48
|
def for_each_query_args(query, event)
|
|
46
49
|
args = event.payload.transform_keys(&:to_sym)
|
|
47
50
|
construct = query && emitting_construct(event)
|
|
48
|
-
|
|
51
|
+
lent_attributes(query, construct, args).each { |attribute| args[attribute.name] = event.id } if construct
|
|
52
|
+
unwrap_scalar_arguments(query, args)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# A bare-scalar query argument takes the one value its single-field value object carries:
|
|
56
|
+
# the payload hands over the object, but the query declares the scalar, and a query's
|
|
57
|
+
# argument is shape-checked against its declared type.
|
|
58
|
+
def unwrap_scalar_arguments(query, args)
|
|
59
|
+
return args unless query
|
|
49
60
|
|
|
50
|
-
|
|
61
|
+
query.attributes.each do |attribute|
|
|
62
|
+
value = args[attribute.name]
|
|
63
|
+
next unless value.is_a?(Hash) && value.size == 1 && SCALAR_ARGUMENT_TYPES.include?(attribute.type.to_s)
|
|
64
|
+
|
|
65
|
+
args[attribute.name] = value.values.first
|
|
66
|
+
end
|
|
51
67
|
args
|
|
52
68
|
end
|
|
53
69
|
|
|
@@ -36,23 +36,27 @@ module Hecks
|
|
|
36
36
|
# @param only [Array(Bluebook::Policy, String), nil] one `[policy, home_domain]`
|
|
37
37
|
# pair to run exactly (the outbox relay's consumer), instead of scanning every
|
|
38
38
|
# loaded bluebook for candidates
|
|
39
|
-
# @param event_uid [String, nil] the outbox uid every consumer of this event shares
|
|
40
|
-
#
|
|
41
|
-
# @return [
|
|
39
|
+
# @param event_uid [String, nil] the outbox uid every consumer of this event shares; the
|
|
40
|
+
# reaction identity only when the event has no id
|
|
41
|
+
# @return [Array<Hash>] the reactions recorded, one per delivery attempted
|
|
42
42
|
def react(event, domain, only: nil, event_uid: nil)
|
|
43
43
|
selected = only ? [only] : policies_for(event, domain)
|
|
44
|
-
selected.
|
|
44
|
+
selected.flat_map do |policy, home_domain|
|
|
45
45
|
result = deliver(policy, event, home_domain)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
(result.is_a?(Array) ? result : [result]).each { |record| @registry.log_reaction(record, event: identity) }
|
|
46
|
+
# A for_each policy answers an array; Array(...) would explode a record Hash. The identity
|
|
47
|
+
# is the event's own id: a later run recognises the reaction, whichever path ran it.
|
|
48
|
+
records = result.is_a?(Array) ? result : [result].compact
|
|
49
|
+
records.each { |record| @registry.log_reaction(record, event: reaction_identity(event, event_uid)) }
|
|
51
50
|
end
|
|
52
51
|
end
|
|
53
52
|
|
|
54
53
|
private
|
|
55
54
|
|
|
55
|
+
# The identity a reaction is logged under: the event's own id, so a later run can recognise
|
|
56
|
+
# the reaction whichever path delivered the event; the outbox uid or the object when the event
|
|
57
|
+
# has no id.
|
|
58
|
+
def reaction_identity(event, event_uid) = event.id || event_uid || event.object_id
|
|
59
|
+
|
|
56
60
|
# Scans every loaded bluebook, since a policy commonly lives in a different
|
|
57
61
|
# domain than the event it reacts to. Returns [policy, home_domain] pairs: the
|
|
58
62
|
# home domain is the fallback for a bare trigger or for_each route. Order is the
|
|
@@ -69,6 +73,10 @@ module Hecks
|
|
|
69
73
|
end
|
|
70
74
|
end
|
|
71
75
|
|
|
76
|
+
# Answers the policies `event` triggers in `domain`, as `[policy, home_domain]` pairs, in
|
|
77
|
+
# the order a delivery tries them. The event pump reads this, then runs one of them at a time.
|
|
78
|
+
public :policies_for
|
|
79
|
+
|
|
72
80
|
# Evaluated against the event payload alone (a policy has no aggregate state).
|
|
73
81
|
# Not rescued here: an EvaluationError must reach `deliver`'s defect rescue, not
|
|
74
82
|
# read as a policy that declined to fire.
|
|
@@ -86,9 +86,11 @@ module Hecks
|
|
|
86
86
|
ctx.result = step(:emit) { ctx.operation.outbound? ? ask(ctx) : emit(ctx) }
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
# The domain calling out.
|
|
90
|
-
# adapter
|
|
91
|
-
#
|
|
89
|
+
# The domain calling out. A failure of the outside world (timeout, bad credential, missing
|
|
90
|
+
# adapter, the adapter's own refusal) becomes the `refuses` event rather than a raise, so a
|
|
91
|
+
# policy can react to it. A defect in the code (`Runtime::PROGRAMMING_ERRORS`) is raised:
|
|
92
|
+
# read as a refusal, it hides its cause behind a domain event. The adapter is found by port
|
|
93
|
+
# name across the adapters this boot loaded.
|
|
92
94
|
#
|
|
93
95
|
# Unlike an inbound operation, an ask is handed the record's held state: the adapter
|
|
94
96
|
# needs data that lives on the record, and an event payload carries only arguments.
|
|
@@ -96,10 +98,21 @@ module Hecks
|
|
|
96
98
|
def ask(ctx)
|
|
97
99
|
operation = ctx.operation
|
|
98
100
|
announce(ctx, operation.answers, ctx.args.merge(spread(adapter_answer(ctx))))
|
|
101
|
+
rescue Interrupt
|
|
102
|
+
refuse_ask(ctx, operation, interrupted(ctx))
|
|
99
103
|
rescue StandardError => e
|
|
100
|
-
|
|
104
|
+
raise if Runtime.programming_error?(e)
|
|
105
|
+
|
|
106
|
+
refuse_ask(ctx, operation, Runtime.failure_reason(e))
|
|
101
107
|
end
|
|
102
108
|
|
|
109
|
+
# Announces an ask's refusal with the text it failed with.
|
|
110
|
+
def refuse_ask(ctx, operation, text) = announce(ctx, operation.refuses, ctx.args.merge(refusal: { value: text }))
|
|
111
|
+
|
|
112
|
+
# The refusal an interrupted ask records: the operation it was in and that it was not
|
|
113
|
+
# finished, so the run ends faulted with the stage it reached, not open with no record.
|
|
114
|
+
def interrupted(ctx) = "interrupted during #{ctx.operation_hecks_name}: the run stopped before it finished"
|
|
115
|
+
|
|
103
116
|
def adapter_answer(ctx)
|
|
104
117
|
payload = held_state(ctx).merge(materialise(ctx.args))
|
|
105
118
|
adapter = adapter_for(ctx)
|
|
@@ -117,11 +130,12 @@ module Hecks
|
|
|
117
130
|
end
|
|
118
131
|
|
|
119
132
|
# The record, if there is one. A missing record is not an error here: the ask still
|
|
120
|
-
# goes with only its arguments, since `resolve_references` already checked existence.
|
|
133
|
+
# goes with only its arguments, since `resolve_references` already checked existence. A
|
|
134
|
+
# defect in reading the state is raised, as an adapter's is.
|
|
121
135
|
def held_state(ctx)
|
|
122
136
|
ctx.instance ? Value.materialize(ctx.state) : {}
|
|
123
|
-
rescue StandardError
|
|
124
|
-
{}
|
|
137
|
+
rescue StandardError => e
|
|
138
|
+
Runtime.programming_error?(e) ? raise : {}
|
|
125
139
|
end
|
|
126
140
|
|
|
127
141
|
# The port this operation belongs to, found through the aggregate rather than
|
|
@@ -9,10 +9,11 @@ module Hecks
|
|
|
9
9
|
module Arguments
|
|
10
10
|
private
|
|
11
11
|
|
|
12
|
-
# Coerces
|
|
13
|
-
#
|
|
14
|
-
# argument, which
|
|
15
|
-
#
|
|
12
|
+
# Coerces a query's arguments exactly as a command's are: a bare scalar of the wrong
|
|
13
|
+
# type refuses with TypeMismatch before any store is read, and so does a nil for a
|
|
14
|
+
# required value-object-typed argument, which would otherwise run an unfiltered query
|
|
15
|
+
# (a Ruby/Rust divergence). The Postgres query builder checks the same shapes
|
|
16
|
+
# (`Value.check_query_arguments!`), so both engines refuse the same way.
|
|
16
17
|
#
|
|
17
18
|
# It does not use `Value::Coercion#nil_argument`, which builds a null value object
|
|
18
19
|
# from field defaults and only refuses when a field has none. `null_vo_argument!`
|
|
@@ -29,7 +30,7 @@ module Hecks
|
|
|
29
30
|
def coerce_argument(aggregate, attribute, value)
|
|
30
31
|
return null_vo_argument!(aggregate, attribute) if checked_vo?(aggregate, attribute, value)
|
|
31
32
|
|
|
32
|
-
Value.for_attribute(aggregate, attribute, value
|
|
33
|
+
Value.for_attribute(aggregate, attribute, value)
|
|
33
34
|
end
|
|
34
35
|
|
|
35
36
|
def checked_vo?(aggregate, attribute, value)
|
|
@@ -93,7 +93,6 @@ module Hecks
|
|
|
93
93
|
# @raise [Runtime::UnknownVerb] if `verb` does not resolve (only when `explicit`)
|
|
94
94
|
# @raise [Runtime::TypeMismatch] if no receiver identity resolves for an explicit target
|
|
95
95
|
# @raise [Runtime::UnknownArgument] if an explicit projection has an undeclared fact
|
|
96
|
-
# rubocop:disable-next Metrics/ParameterLists -- the keyword entry point both interpreters call
|
|
97
96
|
def build(registry:, verb:, projected:, explicit:, passthrough: [], source_receiver: nil)
|
|
98
97
|
args = projected.transform_keys(&:to_sym)
|
|
99
98
|
return forwarded(registry, verb, args, source_receiver) unless explicit
|
|
@@ -55,6 +55,15 @@ module Hecks
|
|
|
55
55
|
render_with(template(refusal, site), specs, arguments)
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
+
# Appends the command that creates an aggregate's records, when the bluebook declares one.
|
|
59
|
+
# The message is returned unchanged for an aggregate that declares no creator.
|
|
60
|
+
def with_creator_hint(message, aggregate)
|
|
61
|
+
creator = aggregate.created_by
|
|
62
|
+
return message if creator.nil? || creator.to_s.empty?
|
|
63
|
+
|
|
64
|
+
"#{message}: run #{creator} first"
|
|
65
|
+
end
|
|
66
|
+
|
|
58
67
|
def refuse_wrong_arguments!(refusal, site, declared, offered)
|
|
59
68
|
missing = declared - offered
|
|
60
69
|
extra = offered - declared
|
|
@@ -84,8 +93,10 @@ module Hecks
|
|
|
84
93
|
items.empty? ? spec.fetch("when_empty") : items.join(spec.fetch("separator"))
|
|
85
94
|
end
|
|
86
95
|
|
|
96
|
+
# The block form inserts each value as written: a replacement string would have `gsub` read
|
|
97
|
+
# its `\\`, `\0` and `\&` as escapes, so a quoted value's own backslash would collapse.
|
|
87
98
|
def substitute(template, values)
|
|
88
|
-
values.reduce(template) { |text, (key, value)| text.gsub("{#{key}}"
|
|
99
|
+
values.reduce(template) { |text, (key, value)| text.gsub("{#{key}}") { value.to_s } }
|
|
89
100
|
end
|
|
90
101
|
|
|
91
102
|
def template(refusal, site)
|
|
@@ -5,16 +5,12 @@ module Hecks
|
|
|
5
5
|
module ContextMaps
|
|
6
6
|
# Boot-time-only, single-threaded: it runs from Hecks.collect while a `.contextmap` file is
|
|
7
7
|
# being Kernel.loaded, before the registry reaches a live, multi-threaded caller.
|
|
8
|
-
# rubocop:disable Hecks/ThreadSharedIvarMutation
|
|
9
8
|
# Registers a declared context map under its system's name, a later one of the same name
|
|
10
9
|
# replacing the earlier (a map is one declaration, not a layered overlay).
|
|
11
10
|
#
|
|
12
11
|
# @param item [Bluebook::ContextMap] the declared map
|
|
13
12
|
# @return [Bluebook::ContextMap] the map
|
|
14
|
-
def add_context_map(item)
|
|
15
|
-
@declared.context_maps[item.name] = item
|
|
16
|
-
end
|
|
17
|
-
# rubocop:enable Hecks/ThreadSharedIvarMutation
|
|
13
|
+
def add_context_map(item) = @declared.store(:context_maps, item.name, item)
|
|
18
14
|
|
|
19
15
|
# Finds a system's declared context map by name.
|
|
20
16
|
#
|
|
@@ -3,16 +3,46 @@ module Hecks
|
|
|
3
3
|
class Registry
|
|
4
4
|
# What a boot gathers while the `.bluebook`, `.hecksagon`, `.world` and `.contextmap` files
|
|
5
5
|
# load: the bluebooks and their builders, the wiring, ports, adapters, worlds, translations,
|
|
6
|
-
# context maps, the eras the boot gate resolved,
|
|
7
|
-
#
|
|
6
|
+
# context maps, the eras the boot gate resolved, the domains whose booted shape no era holds
|
|
7
|
+
# yet, the domains whose unheld shape one recorded move leads to, and the privacy markings
|
|
8
|
+
# still to be dispatched.
|
|
8
9
|
Declarations = Struct.new(:bluebooks, :bluebook_sources, :hecksagons, :bounded_bluebooks, :ports,
|
|
9
10
|
:adapters, :worlds, :translations, :bluebook_builders,
|
|
10
11
|
:pending_privacy_markings, :resolved_eras, :superseded_eras,
|
|
11
|
-
:context_maps) do
|
|
12
|
+
:context_maps, :unminted_eras, :behind_eras) do
|
|
12
13
|
# @return [Declarations] every collection empty
|
|
13
14
|
def self.empty
|
|
14
|
-
new({}, {}, {}, {}, {}, {}, {}, [], {}, [], {}, {}, {})
|
|
15
|
+
new({}, {}, {}, {}, {}, {}, {}, [], {}, [], {}, {}, {}, {}, {})
|
|
15
16
|
end
|
|
17
|
+
|
|
18
|
+
# Stores a value under a key in a keyed collection, and answers the value.
|
|
19
|
+
#
|
|
20
|
+
# @param collection [Symbol] the member holding the keyed collection
|
|
21
|
+
# @param key [Object] the key
|
|
22
|
+
# @param value [Object] the value to store
|
|
23
|
+
# @return [Object] `value`
|
|
24
|
+
def store(collection, key, value) = self[collection][key] = value
|
|
25
|
+
|
|
26
|
+
# Removes a key from a keyed collection.
|
|
27
|
+
#
|
|
28
|
+
# @param collection [Symbol] the member holding the keyed collection
|
|
29
|
+
# @param key [Object] the key to remove
|
|
30
|
+
# @return [Object, nil] the value removed, or nil when the key was absent
|
|
31
|
+
def remove(collection, key) = self[collection].delete(key)
|
|
32
|
+
|
|
33
|
+
# Appends a value to a list collection.
|
|
34
|
+
#
|
|
35
|
+
# @param collection [Symbol] the member holding the list
|
|
36
|
+
# @param value [Object] the value to append
|
|
37
|
+
# @return [Array] the list, `value` last
|
|
38
|
+
def append(collection, value) = self[collection] << value
|
|
39
|
+
|
|
40
|
+
# Records that a `.bluebook` file contributed to a bluebook name.
|
|
41
|
+
#
|
|
42
|
+
# @param name [String] the bluebook name
|
|
43
|
+
# @param path [String] the file that declared it
|
|
44
|
+
# @return [Array<String>] every path recorded for that name, `path` last
|
|
45
|
+
def record_source(name, path) = (bluebook_sources[name] ||= []) << path
|
|
16
46
|
end
|
|
17
47
|
end
|
|
18
48
|
end
|
|
@@ -44,18 +44,32 @@ module Hecks
|
|
|
44
44
|
def refuse_unwired_attachments!(hecksagon)
|
|
45
45
|
hecksagon.attachments.each do |attachment|
|
|
46
46
|
next if hecksagon(attachment.declaration_name)
|
|
47
|
+
next if contextmap_declares?(hecksagon, attachment)
|
|
47
48
|
|
|
48
49
|
raise WiringError, unwired_attachment_message(hecksagon, attachment)
|
|
49
50
|
end
|
|
50
51
|
end
|
|
51
52
|
|
|
53
|
+
# A gem bluebook that the system's `.contextmap` names as a context needs no sibling
|
|
54
|
+
# hecksagon: its wiring is the attach itself. A vendored package still needs one, since
|
|
55
|
+
# its persistence and `translates` ACL can only be written there.
|
|
56
|
+
#
|
|
57
|
+
# @return [Boolean] true if the system's context map names the attached gem bluebook
|
|
58
|
+
def contextmap_declares?(hecksagon, attachment)
|
|
59
|
+
return false if attachment.vendor?
|
|
60
|
+
|
|
61
|
+
map = context_map(hecksagon.domain)
|
|
62
|
+
!map.nil? && map.context_names.include?(attachment.declaration_name.to_s)
|
|
63
|
+
end
|
|
64
|
+
|
|
52
65
|
def unwired_attachment_message(hecksagon, attachment)
|
|
53
66
|
declaration_name = attachment.declaration_name
|
|
54
67
|
what = attachment.vendor? ? "vendored bluebook #{attachment.name.inspect}" : declaration_name.inspect
|
|
55
68
|
"#{hecksagon.domain} attaches #{what} " \
|
|
56
69
|
"(bounded context #{declaration_name}) but never declared " \
|
|
57
70
|
"Hecks.hecksagon #{declaration_name.inspect} — put that sibling " \
|
|
58
|
-
"(and any `translates` ACL) in context_map.hecksagon
|
|
71
|
+
"(and any `translates` ACL) in context_map.hecksagon, or name the context in " \
|
|
72
|
+
"#{hecksagon.domain}'s `.contextmap` (gem bluebooks only); " \
|
|
59
73
|
"same-name blocks merge, order-independent."
|
|
60
74
|
end
|
|
61
75
|
|
|
@@ -22,6 +22,16 @@ module Hecks
|
|
|
22
22
|
def clear
|
|
23
23
|
to_a.each(&:clear)
|
|
24
24
|
end
|
|
25
|
+
|
|
26
|
+
# Logs one reaction's outcome, and the event instance it answered when known.
|
|
27
|
+
#
|
|
28
|
+
# @param record [Hash{Symbol => Object}] the reaction's outcome
|
|
29
|
+
# @param event [String, Integer, nil] the event instance, or nil when not known
|
|
30
|
+
# @return [void]
|
|
31
|
+
def log_reaction(record, event)
|
|
32
|
+
reaction_log << record
|
|
33
|
+
reaction_events[record] = event if event
|
|
34
|
+
end
|
|
25
35
|
end
|
|
26
36
|
end
|
|
27
37
|
end
|
|
@@ -8,9 +8,31 @@ module Hecks
|
|
|
8
8
|
AGGREGATE_PLACEHOLDER = /\{(name|storage_name)\}/
|
|
9
9
|
|
|
10
10
|
# The default database only reaches a persistence bind whose adapter declares a
|
|
11
|
-
# `database` field; a `database` the bluebook's own settings name always wins.
|
|
11
|
+
# `database` field; a `database` the bluebook's own settings name always wins. Every
|
|
12
|
+
# value the adapter declares as a secret is held by `Secrets` on the way, so no text the
|
|
13
|
+
# launcher prints can carry it.
|
|
12
14
|
def binding_settings(domain, verb, adapter)
|
|
13
15
|
declared = world(domain)&.for_binding(verb, adapter) || {}
|
|
16
|
+
settings = with_world_mint_names(domain, verb, adapter, with_default_database(domain, verb, adapter, declared))
|
|
17
|
+
Secrets.register_settings(@declared.adapters[adapter.to_s], settings)
|
|
18
|
+
settings
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# The commands a world names at its top level (`minting commands: [...]`) join the names a
|
|
22
|
+
# persistence block gives, for an adapter that declares `mints_era`: a domain whose binding
|
|
23
|
+
# lives in uncommitted local files still has a committed place to say them.
|
|
24
|
+
def with_world_mint_names(domain, verb, adapter, settings)
|
|
25
|
+
return settings unless mint_names_apply?(verb, adapter)
|
|
26
|
+
|
|
27
|
+
named = Array(world(domain)&.for_verb("minting")&.fetch(:commands, nil)).map(&:to_s)
|
|
28
|
+
named.empty? ? settings : settings.merge(mints_era: (Ports::Persistence::MintDoor.names(settings) + named).uniq)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def mint_names_apply?(verb, adapter)
|
|
32
|
+
verb.to_s == Ports::Persistence::VERB && @declared.adapters[adapter.to_s]&.declares?(:mints_era)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def with_default_database(domain, verb, adapter, declared)
|
|
14
36
|
database = default_database_for(domain)
|
|
15
37
|
return declared unless database && default_database_applies?(verb, adapter)
|
|
16
38
|
|
|
@@ -28,7 +50,7 @@ module Hecks
|
|
|
28
50
|
|
|
29
51
|
verify_default_adapter_named!(declared.domain, name)
|
|
30
52
|
end
|
|
31
|
-
|
|
53
|
+
apply_world_names!
|
|
32
54
|
end
|
|
33
55
|
|
|
34
56
|
# The defaults an adapter's `.adapter` declares for its fields, with each `{name}` or
|