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
|
@@ -35,7 +35,7 @@ module Hecks
|
|
|
35
35
|
def merge_chain(registry, bluebook, held)
|
|
36
36
|
raise Runtime::WiringError, "nothing to merge — #{bluebook.name} stands at era 1" if held.size < 2
|
|
37
37
|
|
|
38
|
-
edge_chain(registry, bluebook, held[0..-2], held.last[:label])
|
|
38
|
+
edge_chain(registry, bluebook, held[0..-2], held.last[:label], target: held.last)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
# The audit the merge runs over the merged heads, answering every violation found.
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
require_relative "../../../../ports/persistence/plugins/era/translation/implicit_edge"
|
|
2
|
+
require_relative "../../../../ports/persistence/plugins/era/translation/scaffold"
|
|
3
|
+
require_relative "../../../../ports/persistence/plugins/era/storage_shape"
|
|
4
|
+
require_relative "../../../../shape_ledger"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module Adapters
|
|
8
|
+
class PostgresEra
|
|
9
|
+
module LineageManager
|
|
10
|
+
# The decision a mint and a rehearsal both make: which translation edge leads the held era
|
|
11
|
+
# to the current shape, and whether a mint would go ahead on it. It reads only what its
|
|
12
|
+
# caller hands it and writes nothing, so the same inputs reach the same verdict on either
|
|
13
|
+
# path.
|
|
14
|
+
module MintDecision
|
|
15
|
+
# The implicit moves the framework keeps beside its shape ledger. A bluebook the framework
|
|
16
|
+
# holds, such as QualityControl, has its moves recorded here, not beside its own files.
|
|
17
|
+
FRAMEWORK_MOVES = File.join(File.expand_path("../../../../hecks", __dir__),
|
|
18
|
+
ShapeLedger::IMPLICIT_FILE).freeze
|
|
19
|
+
|
|
20
|
+
# What a decision concludes. `verdict` is `would_mint`, `needs_edge` (the change needs
|
|
21
|
+
# a rule) or `refused`; `reason` names why it is not `would_mint`; `edge` is the edge a
|
|
22
|
+
# mint would use and is nil unless `would_mint`; `source` is `file` or `implicit`; `edges`
|
|
23
|
+
# lists the edges that lead the held era to the current shape; `diff` is the shape diff;
|
|
24
|
+
# `watermark` is the one decided at.
|
|
25
|
+
Verdict = Data.define(:verdict, :reason, :edge, :edges, :source, :diff, :watermark)
|
|
26
|
+
|
|
27
|
+
module_function
|
|
28
|
+
|
|
29
|
+
# @param held [Array<Hash>] the held eras, oldest first; the last is the era a mint
|
|
30
|
+
# leaves.
|
|
31
|
+
# Each carries `label` and `declaration`, the storage shape it holds as a bluebook view
|
|
32
|
+
# (see `held_for_decision`)
|
|
33
|
+
# @param bluebook [Bluebook::Declaration] the current bluebook
|
|
34
|
+
# @param edge_source [Hash] `translations`, the loaded edges, and `recorded`, the recorded
|
|
35
|
+
# implicit moves as `[from, to]` pairs (see `recorded_moves`)
|
|
36
|
+
# @param watermark [Integer] the ledger watermark the decision reads
|
|
37
|
+
# @param rows [Array<String>] the refusals an audit ran over the decided edge; empty when
|
|
38
|
+
# none, or when no audit has run yet
|
|
39
|
+
# @return [Verdict]
|
|
40
|
+
def decide(held:, bluebook:, edge_source:, watermark:, rows:)
|
|
41
|
+
latest = held.last
|
|
42
|
+
edges = leading(edge_source[:translations], bluebook, latest[:label])
|
|
43
|
+
found = if edges.empty?
|
|
44
|
+
implicit(latest, bluebook, edge_source[:recorded], watermark)
|
|
45
|
+
else
|
|
46
|
+
written(edges, latest, bluebook, watermark)
|
|
47
|
+
end
|
|
48
|
+
rows.empty? ? found : audit_refusal(found)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# The decision for the era a mint would leave, reading the held era's stored shape here,
|
|
52
|
+
# so a caller holding only the era's record reaches the same verdict as a mint does.
|
|
53
|
+
#
|
|
54
|
+
# @param latest [Hash] the held era, as `Lineage#eras` answers it
|
|
55
|
+
# @param bluebook [Bluebook::Declaration] the current bluebook
|
|
56
|
+
# @param translations [Array<Object>] the edges the registry loaded
|
|
57
|
+
# @param directory [String, nil] the domain's bluebook directory
|
|
58
|
+
# @param watermark [Integer] the ledger watermark the decision reads
|
|
59
|
+
# @return [Verdict]
|
|
60
|
+
def decide_latest(latest, bluebook:, translations:, directory:, watermark:)
|
|
61
|
+
decide(held: [held_for_decision(latest)], bluebook: bluebook, watermark: watermark, rows: [],
|
|
62
|
+
edge_source: { translations: translations, recorded: recorded_moves(bluebook.name, directory) })
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# A held era as the decision reads it: with `declaration`, the storage shape it holds as a
|
|
66
|
+
# bluebook view (LineageManager::HeldEra). Its held text is not read.
|
|
67
|
+
#
|
|
68
|
+
# @param era [Hash] an era as `Lineage#eras` answers it
|
|
69
|
+
# @return [Hash] the era with `declaration`, a `Runtime::ProjectedBluebook`
|
|
70
|
+
# @raise [Runtime::WiringError] naming the era, when its shape cannot be known
|
|
71
|
+
def held_for_decision(era) = era.merge(declaration: LineageManager.held_bluebook(era))
|
|
72
|
+
|
|
73
|
+
# The implicit moves a domain has recorded: beside its own bluebooks, when a directory is
|
|
74
|
+
# given, and in the framework's record. This is the only read the decision's inputs need.
|
|
75
|
+
#
|
|
76
|
+
# @param domain [String] the bluebook name the moves are recorded under
|
|
77
|
+
# @param directory [String, nil] the domain's bluebook directory
|
|
78
|
+
# @return [Array<Array(String, String)>] each recorded move as `[from, to]`
|
|
79
|
+
def recorded_moves(domain, directory)
|
|
80
|
+
paths = [directory && File.join(directory, ShapeLedger::IMPLICIT_FILE), FRAMEWORK_MOVES].compact
|
|
81
|
+
paths.flat_map { |path| ShapeLedger.pairs_of(ShapeLedger.implicit_moves(path).fetch(domain, [])) }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Whether the move from the held era is breaking and nothing covers it: the decision needs
|
|
85
|
+
# an edge, and the change is not provably additive. A move a mint would go ahead on, or a
|
|
86
|
+
# decision already refused for another reason, is not this. An edge from the held shape
|
|
87
|
+
# covers it even when the held era has not been named yet.
|
|
88
|
+
#
|
|
89
|
+
# @return [Boolean]
|
|
90
|
+
def breaking?(latest, bluebook, verdict, translations)
|
|
91
|
+
return false unless verdict.verdict == "needs_edge"
|
|
92
|
+
return false unless leading(translations, bluebook, held_label_of(latest)).empty?
|
|
93
|
+
|
|
94
|
+
!additive?(verdict.diff, held_for_decision(latest), bluebook)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @return [String] the stored label of a held era, or the one its shape would be named
|
|
98
|
+
def held_label_of(era)
|
|
99
|
+
era[:label] || LineageManager.held_hash(era)[0, Runtime::StorageShape::LABEL_LENGTH]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# The shape label a storage shape of this bluebook carries.
|
|
103
|
+
#
|
|
104
|
+
# @return [String]
|
|
105
|
+
def label_of(bluebook) = Runtime::StorageShape.mint_hash(bluebook)[0, Runtime::StorageShape::LABEL_LENGTH]
|
|
106
|
+
|
|
107
|
+
# The edges the domain loads that lead the held era straight to the current shape. An edge
|
|
108
|
+
# from the held era to any other shape plays no part: the translation is from the held
|
|
109
|
+
# shape to the current one, so other edges neither fork the decision nor make it stale.
|
|
110
|
+
#
|
|
111
|
+
# @return [Array<Object>] the edges from `from` to the bluebook's current label
|
|
112
|
+
def leading(translations, bluebook, from)
|
|
113
|
+
to = label_of(bluebook)
|
|
114
|
+
translations.select { |edge| edge.domain == bluebook.name && edge.from == from && edge.to == to }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# The implicit empty edge: the recorded moves must reach the shape from the held label,
|
|
118
|
+
# and the change must qualify as additive by `Translation::ImplicitEdge.qualifies?`.
|
|
119
|
+
def implicit(latest, bluebook, recorded, watermark)
|
|
120
|
+
diff = diff_of(latest, bluebook)
|
|
121
|
+
to = label_of(bluebook)
|
|
122
|
+
return verdict_of("needs_edge", diff, watermark, reason: :unrecorded) unless reachable?(latest, to, recorded)
|
|
123
|
+
return verdict_of("needs_edge", diff, watermark, reason: :non_qualifying) unless additive?(diff, latest, bluebook)
|
|
124
|
+
|
|
125
|
+
edge = Translation::ImplicitEdge.new(domain: bluebook.name, from: latest[:label], to: to)
|
|
126
|
+
verdict_of("would_mint", diff, watermark, edge: edge, edges: [], source: "implicit")
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# @return [Hash] the scaffold's diff of the held era against the current bluebook
|
|
130
|
+
def diff_of(latest, bluebook) = Translation::Scaffold.diff(latest[:declaration], bluebook)
|
|
131
|
+
|
|
132
|
+
# @return [Boolean] whether the recorded moves chain from the held label to `to`
|
|
133
|
+
def reachable?(latest, to, recorded) = ShapeLedger.reachable?(latest[:label], to, recorded)
|
|
134
|
+
|
|
135
|
+
# @return [Boolean] whether the change qualifies as additive by the implicit edge's rule
|
|
136
|
+
def additive?(diff, latest, bluebook) = Translation::ImplicitEdge.qualifies?(diff, latest[:declaration], bluebook)
|
|
137
|
+
|
|
138
|
+
# A written edge from the held shape to the current one leads on. Two files declaring that
|
|
139
|
+
# same pair disagree about one translation, so neither is taken.
|
|
140
|
+
def written(edges, latest, bluebook, watermark)
|
|
141
|
+
diff = diff_of(latest, bluebook)
|
|
142
|
+
return verdict_of("refused", diff, watermark, reason: :duplicate_edge, edges: edges) if edges.size > 1
|
|
143
|
+
|
|
144
|
+
verdict_of("would_mint", diff, watermark, edge: edges.first, edges: edges, source: "file")
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# An audit's refusals turn a would_mint into a refusal that names the audit.
|
|
148
|
+
def audit_refusal(found)
|
|
149
|
+
return found unless found.verdict == "would_mint"
|
|
150
|
+
|
|
151
|
+
verdict_of("refused", found.diff, found.watermark, reason: :audit, edges: found.edges)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# @return [Verdict] a verdict of `kind`, with the fields it carries and none it does not
|
|
155
|
+
def verdict_of(kind, diff, watermark, **attributes)
|
|
156
|
+
Verdict.new(verdict: kind, reason: nil, edge: nil, edges: [], source: nil, diff: diff,
|
|
157
|
+
watermark: watermark, **attributes)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Adapters
|
|
3
|
+
class PostgresEra
|
|
4
|
+
module LineageManager
|
|
5
|
+
# The request a mint carries into the era check: whether the mint was confirmed, the verdict
|
|
6
|
+
# the rehearsal of that same era reached, and the ledger watermark the rehearsal read. Only the
|
|
7
|
+
# Maintenance mint path builds one; a boot has none, so a boot that would mint refuses.
|
|
8
|
+
MintRequest = Data.define(:confirm, :verdict, :watermark) do
|
|
9
|
+
# Reads the request out of a settings hash, spelled with symbol or string keys.
|
|
10
|
+
#
|
|
11
|
+
# @param settings [Hash] the settings the era check was booted with
|
|
12
|
+
# @return [MintRequest, nil] the request, or nil when the settings carry none
|
|
13
|
+
def self.from(settings)
|
|
14
|
+
raw = PostgresEra.setting(settings, :mint_request)
|
|
15
|
+
return nil if raw.nil?
|
|
16
|
+
|
|
17
|
+
raw = raw.transform_keys(&:to_sym)
|
|
18
|
+
new(confirm: raw[:confirm] == true, verdict: raw[:verdict].to_s, watermark: raw[:watermark].to_i)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -4,6 +4,8 @@ require_relative "../../../../ports/persistence/plugins/era/translation/audit"
|
|
|
4
4
|
require_relative "../../../../ports/persistence/plugins/era/translation/scaffold"
|
|
5
5
|
require_relative "context"
|
|
6
6
|
require_relative "refusals"
|
|
7
|
+
require_relative "mint_decision"
|
|
8
|
+
require_relative "era_resolution"
|
|
7
9
|
|
|
8
10
|
module Hecks
|
|
9
11
|
module Adapters
|
|
@@ -19,25 +21,30 @@ module Hecks
|
|
|
19
21
|
# @param context [Context] the era check so far; `latest` is the latest held era, named
|
|
20
22
|
# here if it has no name yet
|
|
21
23
|
# @return [Integer] the ordinal of the era minted
|
|
22
|
-
# @raise [Runtime::WiringError] if the
|
|
24
|
+
# @raise [Runtime::WiringError] if a held era already holds the shape, or the edge, its
|
|
25
|
+
# coverage or its audit refuses
|
|
23
26
|
def mint!(context)
|
|
27
|
+
refuse_held_shape!(context)
|
|
28
|
+
refuse_unrehearsed_mint!(context)
|
|
24
29
|
ensure_named!(context.lineage, context.latest)
|
|
25
30
|
context = context.with(latest: context.held_eras.last)
|
|
31
|
+
decided_at = context.watermark
|
|
26
32
|
edge = verified_edge!(context)
|
|
27
33
|
refuse_unpermitted_mint!(context) unless context.mint_permitted
|
|
28
34
|
chain = audited_chain!(context, edge)
|
|
29
|
-
|
|
35
|
+
refuse_moved_watermark!(context, decided_at)
|
|
36
|
+
commit_era!(context, chain, edge)
|
|
30
37
|
end
|
|
31
38
|
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
39
|
+
# The edge a mint leaves the held era by, as `MintDecision` decides it. A refusal the
|
|
40
|
+
# decision names is raised by name; a change that needs a rule refuses toward the
|
|
41
|
+
# scaffold.
|
|
35
42
|
def resolve_edge!(context)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
verdict = decide!(context)
|
|
44
|
+
return verdict.edge if verdict.verdict == "would_mint"
|
|
45
|
+
return refuse_toward_the_scaffold!(context) if verdict.verdict == "needs_edge"
|
|
46
|
+
|
|
47
|
+
refuse_refused_verdict!(context, verdict)
|
|
41
48
|
end
|
|
42
49
|
|
|
43
50
|
# Diffs the held era against the current shape and writes the edge file —
|
|
@@ -46,7 +53,7 @@ module Hecks
|
|
|
46
53
|
ensure_named!(lineage, latest)
|
|
47
54
|
latest = lineage.eras.last
|
|
48
55
|
label = Runtime::StorageShape.mint_hash(bluebook)[0, Runtime::StorageShape::LABEL_LENGTH]
|
|
49
|
-
diffed = Translation::Scaffold.diff(
|
|
56
|
+
diffed = Translation::Scaffold.diff(held_bluebook(latest), bluebook)
|
|
50
57
|
edge = Translation::Scaffold::Edge.new(
|
|
51
58
|
domain: bluebook.name, from: latest[:label], to: label, ordinal: latest[:ordinal] + 1,
|
|
52
59
|
label: label, aggregates: diffed[:aggregates], retired: diffed[:retired]
|
|
@@ -60,23 +67,40 @@ module Hecks
|
|
|
60
67
|
def ensure_named!(lineage, era)
|
|
61
68
|
return if era[:hash]
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
hash = Runtime::StorageShape.mint_hash(held_bluebook)
|
|
70
|
+
hash = held_hash(era)
|
|
65
71
|
lineage.mint_name!(era[:ordinal], hash, hash[0, Runtime::StorageShape::LABEL_LENGTH])
|
|
66
72
|
end
|
|
67
73
|
|
|
68
74
|
private
|
|
69
75
|
|
|
70
|
-
|
|
76
|
+
# Refuses a mint of a shape a held era already holds, by the match the boot resolves with.
|
|
77
|
+
def refuse_held_shape!(context)
|
|
78
|
+
held = EraResolution.matching_era(context.held_eras, context.bluebook) or return
|
|
79
|
+
|
|
80
|
+
raise Runtime::WiringError,
|
|
81
|
+
"cannot mint #{context.domain_name}: era #{held[:ordinal]} already holds the current shape"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# The verdict `MintDecision` reaches for the held era the mint leaves, read at the
|
|
85
|
+
# watermark the context holds now.
|
|
86
|
+
def decide!(context)
|
|
87
|
+
MintDecision.decide(held: [MintDecision.held_for_decision(context.latest)], bluebook: context.bluebook,
|
|
88
|
+
edge_source: edge_source_of(context), watermark: context.watermark, rows: [])
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def edge_source_of(context)
|
|
71
92
|
registry = context.registry
|
|
72
|
-
registry.translations
|
|
73
|
-
|
|
74
|
-
end
|
|
93
|
+
{ translations: registry.translations,
|
|
94
|
+
recorded: MintDecision.recorded_moves(context.domain_name, context.directory) }
|
|
75
95
|
end
|
|
76
96
|
|
|
97
|
+
# The refusal a decided edge stands for: two files declaring the one translation.
|
|
98
|
+
def refuse_refused_verdict!(context, verdict) = refuse_duplicate_edges!(context, verdict.edges)
|
|
99
|
+
|
|
77
100
|
# The edge chain to the current shape, after its audit passes.
|
|
78
101
|
def audited_chain!(context, edge)
|
|
79
|
-
chain = edge_chain(context.registry, context.bluebook, context.held_eras, context.label
|
|
102
|
+
chain = edge_chain(context.registry, context.bluebook, context.held_eras, context.label,
|
|
103
|
+
target: minted_record(edge))
|
|
80
104
|
audit!(context.bluebook, context.lineage, chain, context.ordinal, edge)
|
|
81
105
|
chain
|
|
82
106
|
end
|
|
@@ -84,17 +108,31 @@ module Hecks
|
|
|
84
108
|
# The edge leaving the held era, once resolved and found to cover the diff.
|
|
85
109
|
def verified_edge!(context)
|
|
86
110
|
edge = resolve_edge!(context)
|
|
87
|
-
check_coverage!(context.registry, context.bluebook,
|
|
111
|
+
check_coverage!(context.registry, context.bluebook, held_bluebook(context.latest), edge)
|
|
88
112
|
edge
|
|
89
113
|
end
|
|
90
114
|
|
|
91
|
-
|
|
115
|
+
# The journal record of the era a mint reaches, when the edge is implicit; nil when a
|
|
116
|
+
# written edge file leads there.
|
|
117
|
+
#
|
|
118
|
+
# @return [Hash, nil] the era record `edge_chain` reads as its last step
|
|
119
|
+
def minted_record(edge)
|
|
120
|
+
edge.is_a?(Translation::ImplicitEdge) ? edge.record : nil
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# @return [Hash, nil] the `edge` column of the minted era: the implicit marker, or nil
|
|
124
|
+
def implicit_record(edge)
|
|
125
|
+
edge.is_a?(Translation::ImplicitEdge) ? Translation::ImplicitEdge::RECORD : nil
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def commit_era!(context, chain, edge)
|
|
92
129
|
hash = context.shape_hash
|
|
93
130
|
bluebook = context.bluebook
|
|
94
131
|
context.lineage.mint_era!(
|
|
95
132
|
ordinal: context.ordinal, hash: hash, label: hash[0, Runtime::StorageShape::LABEL_LENGTH],
|
|
96
133
|
held_text: context.current_text, aggregates: bluebook.aggregates, edges: chain,
|
|
97
|
-
role: context.role, projection: Runtime::StorageShape.project(context.bluebook)
|
|
134
|
+
role: context.role, projection: Runtime::StorageShape.project(context.bluebook),
|
|
135
|
+
edge: implicit_record(edge)
|
|
98
136
|
)
|
|
99
137
|
context.ordinal
|
|
100
138
|
end
|
|
@@ -32,21 +32,34 @@ module Hecks
|
|
|
32
32
|
"persisted_by block of its world", minting: false)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
# Refuses a mint that the rehearsal does not back: not confirmed, not a would_mint verdict, or a
|
|
36
|
+
# ledger watermark that moved since the rehearsal read it.
|
|
37
|
+
def refuse_unrehearsed_mint!(context)
|
|
38
|
+
request = context.mint_request
|
|
39
|
+
raise era_refusal(context, "the mint was not confirmed") unless request.confirm
|
|
40
|
+
unless request.verdict == "would_mint"
|
|
41
|
+
raise era_refusal(context, "the rehearsal's verdict was #{request.verdict}, not would_mint; " \
|
|
42
|
+
"rehearse again")
|
|
43
|
+
end
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
latest = context.latest
|
|
39
|
-
raise era_refusal(context, "#{edges.size} translation edges leave era #{latest[:ordinal]} " \
|
|
40
|
-
"(#{latest[:label]}) — eras fork mechanically; keep one edge per source shape",
|
|
41
|
-
minting: false)
|
|
45
|
+
refuse_moved_watermark!(context, request.watermark)
|
|
42
46
|
end
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def refuse_moved_watermark!(context, watermark)
|
|
51
|
+
current = context.watermark
|
|
52
|
+
return if current == watermark
|
|
53
|
+
|
|
54
|
+
raise era_refusal(context, "the ledger watermark moved from #{watermark} to #{current} since the " \
|
|
55
|
+
"rehearsal; rehearse again")
|
|
56
|
+
end
|
|
46
57
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
def refuse_duplicate_edges!(context, edges)
|
|
59
|
+
latest = context.latest
|
|
60
|
+
raise era_refusal(context, "#{edges.size} translation edges lead era #{latest[:ordinal]} " \
|
|
61
|
+
"(#{latest[:label]}) to the current shape #{context.label}; keep one",
|
|
62
|
+
minting: false)
|
|
50
63
|
end
|
|
51
64
|
|
|
52
65
|
# Builds the refusal; a mint's own refusals say "cannot mint era N of X", the
|
|
@@ -4,6 +4,7 @@ require_relative "lineage_manager/era_resolver"
|
|
|
4
4
|
require_relative "lineage_manager/minter"
|
|
5
5
|
require_relative "lineage_manager/merge_coordinator"
|
|
6
6
|
require_relative "lineage_manager/coverage_check"
|
|
7
|
+
require_relative "lineage_manager/held_era"
|
|
7
8
|
require_relative "../../../ports/persistence/plugins/era/era_guard"
|
|
8
9
|
require_relative "../../../runtime/registry"
|
|
9
10
|
|
|
@@ -17,6 +18,7 @@ module Hecks
|
|
|
17
18
|
extend Minter
|
|
18
19
|
extend MergeCoordinator
|
|
19
20
|
extend CoverageCheck
|
|
21
|
+
extend HeldEra
|
|
20
22
|
|
|
21
23
|
module_function
|
|
22
24
|
|
|
@@ -27,25 +29,57 @@ module Hecks
|
|
|
27
29
|
# @param bluebook [Bluebook::Declaration] the domain; only edges for its name count
|
|
28
30
|
# @param eras [Array<Hash>] the ancestor eras in order, as `Lineage#eras` returns them
|
|
29
31
|
# @param current_label [String] the shape label the last step must lead to
|
|
32
|
+
# @param target [Hash, nil] the era record the last step reaches when it is not in `eras`
|
|
33
|
+
# (the held era of a settled chain, or the era a mint is about to write)
|
|
30
34
|
# @return [Array<Hash>] one `{ translation: edge }` per step, in mint order
|
|
31
|
-
# @raise [Runtime::WiringError] if no loaded translation
|
|
32
|
-
|
|
35
|
+
# @raise [Runtime::WiringError] if no loaded translation or journal record leads a label
|
|
36
|
+
# to the next one
|
|
37
|
+
def edge_chain(registry, bluebook, eras, current_label, target: nil)
|
|
33
38
|
labels = eras.map { |era| era[:label] } + [current_label]
|
|
34
|
-
labels.each_cons(2).with_index.
|
|
35
|
-
|
|
39
|
+
labels.each_cons(2).with_index.filter_map do |(from, to), index|
|
|
40
|
+
next if same_shape?(from, to)
|
|
41
|
+
|
|
42
|
+
step = edge_between(registry, bluebook, from, to) ||
|
|
43
|
+
recorded_edge(bluebook, from, to, eras[index + 1] || target)
|
|
36
44
|
refuse_broken_chain!(bluebook, index, from, to) unless step
|
|
37
45
|
{ translation: step }
|
|
38
46
|
end
|
|
39
47
|
end
|
|
40
48
|
|
|
41
|
-
#
|
|
49
|
+
# Whether two shape labels name the same shape. A same-shape step is current, not a change,
|
|
50
|
+
# so it needs no edge and `edge_chain` skips it.
|
|
51
|
+
#
|
|
52
|
+
# @param from [String] the shape label the step leaves
|
|
53
|
+
# @param to [String] the shape label the step reaches
|
|
54
|
+
# @return [Boolean] true when both labels are the same shape
|
|
55
|
+
def same_shape?(from, to) = from == to
|
|
56
|
+
|
|
57
|
+
# The implicit edge a journal record names for the step that reached its era, or nil.
|
|
58
|
+
#
|
|
59
|
+
# @param bluebook [Bluebook::Declaration] the domain the edge belongs to
|
|
60
|
+
# @param from [String] the shape label the step leaves
|
|
61
|
+
# @param to [String] the shape label the step reaches
|
|
62
|
+
# @param record [Hash, nil] the era record the step reaches
|
|
63
|
+
# @return [Translation::ImplicitEdge, nil]
|
|
64
|
+
def recorded_edge(bluebook, from, to, record)
|
|
65
|
+
return unless record && record[:label] == to && record[:edge] == Translation::ImplicitEdge::RECORD
|
|
66
|
+
|
|
67
|
+
Translation::ImplicitEdge.new(domain: bluebook.name, from: from, to: to)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Finds the loaded translation that leads one shape label to the next. A same-shape pair
|
|
71
|
+
# has no edge to find: it answers nil without searching, and `edge_chain` treats it as
|
|
72
|
+
# current.
|
|
42
73
|
#
|
|
43
74
|
# @param registry [Runtime::Registry] the registry whose `translations` are searched
|
|
44
75
|
# @param bluebook [Bluebook::Declaration] the domain; only edges for its name count
|
|
45
76
|
# @param from [String] the shape label the edge leaves
|
|
46
77
|
# @param to [String] the shape label the edge reaches
|
|
47
|
-
# @return [Bluebook::Translation, nil] the edge, or nil when none is loaded
|
|
78
|
+
# @return [Bluebook::Translation, nil] the edge, or nil when none is loaded, or the shapes
|
|
79
|
+
# match
|
|
48
80
|
def edge_between(registry, bluebook, from, to)
|
|
81
|
+
return nil if same_shape?(from, to)
|
|
82
|
+
|
|
49
83
|
registry.translations.find { |t| t.domain == bluebook.name && t.from == from && t.to == to }
|
|
50
84
|
end
|
|
51
85
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require_relative "events"
|
|
2
|
+
require_relative "sagas"
|
|
3
|
+
require_relative "../postgres/outbox"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module Adapters
|
|
7
|
+
class PostgresEra
|
|
8
|
+
# The event, saga and outbox tables a database shares across its domains. Only the mint path
|
|
9
|
+
# creates them, through `Lineage#ensure_base!`; a boot reads them and never provisions them.
|
|
10
|
+
class SharedTables
|
|
11
|
+
include Events
|
|
12
|
+
include Sagas
|
|
13
|
+
include PostgresOutbox
|
|
14
|
+
|
|
15
|
+
# @param db [PG::Connection] the owner connection the mint path holds
|
|
16
|
+
def initialize(db)
|
|
17
|
+
@db = db
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Creates each shared table that is missing. Every statement is idempotent.
|
|
21
|
+
#
|
|
22
|
+
# @return [void]
|
|
23
|
+
# @raise [PG::Error] if Postgres refuses a statement
|
|
24
|
+
def provision!
|
|
25
|
+
create_event_table!
|
|
26
|
+
create_saga_table!
|
|
27
|
+
create_outbox_table!
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -5,6 +5,9 @@ Hecks.adapter "PostgresEra" do
|
|
|
5
5
|
field :database
|
|
6
6
|
field :role
|
|
7
7
|
field :schema
|
|
8
|
+
# The name this domain's history is held under until `era.rename_domain` moves it: `formerly "Old"`.
|
|
9
|
+
# A storage fact, so the world says it and the bluebook's `formerly_known_as` is the fallback.
|
|
10
|
+
field :formerly
|
|
8
11
|
# Opt-in to boot over a superuser or BYPASSRLS role, which the era write fence cannot
|
|
9
12
|
# bite. Refused by default; see `Lineage#check_fence_applies!`.
|
|
10
13
|
field :allow_superuser
|
|
@@ -12,6 +15,15 @@ Hecks.adapter "PostgresEra" do
|
|
|
12
15
|
# next era through a translation edge. `false` refuses; unset follows
|
|
13
16
|
# `LineageManager::EraResolver::MINT_BY_DEFAULT`; see `Refusals#refuse_unpermitted_mint!`.
|
|
14
17
|
field :mint_eras
|
|
18
|
+
# Declares the store a disposable tooling ledger: a shape change needs no era, edge or mint, an
|
|
19
|
+
# additive one is applied in place, any other archives the aggregate's rows under a dated name
|
|
20
|
+
# and starts it empty, and a boot never refuses as unminted or superseded. Unset or `false`
|
|
21
|
+
# keeps the era guard; see `LineageManager::DisposableLedger`. Never for client data.
|
|
22
|
+
field :disposable_ledger
|
|
23
|
+
# The commands whose own record an unminted boot may write: `mints_era "Maintenance.MintEra"`, one
|
|
24
|
+
# `Aggregate.Command` name or a list. This is where the allowance is declared; a command's own
|
|
25
|
+
# `mints_era true` is a fallback that must agree. See `Ports::Persistence::MintDoor`.
|
|
26
|
+
field :mints_era
|
|
15
27
|
# Rewrites every row of an aggregate in one statement, on the same SQL path as Postgres.
|
|
16
28
|
provides "set_transform"
|
|
17
29
|
end
|
|
@@ -63,22 +63,22 @@ module Hecks
|
|
|
63
63
|
def self.tenant_capable? = true
|
|
64
64
|
|
|
65
65
|
# Joins the process's shared connection for the declared database and schema, so every
|
|
66
|
-
# aggregate of a domain runs on one connection, then
|
|
67
|
-
#
|
|
68
|
-
#
|
|
66
|
+
# aggregate of a domain runs on one connection, then resolves the era it reads and the field
|
|
67
|
+
# caches that era holds. Reads only: the lineage, head and cache tables are provisioned by the
|
|
68
|
+
# mint path, and a database no mint has provisioned refuses by name.
|
|
69
69
|
#
|
|
70
70
|
# @param settings [Hash{Symbol, String => Object}] world settings plus what
|
|
71
71
|
# `RepositoryFactory.build` merges in: `domain`, `era` and `superseded_by`
|
|
72
|
-
# @raise [Runtime::WiringError] if `database` is missing
|
|
72
|
+
# @raise [Runtime::WiringError] if `database` is missing, the connection is refused, or the
|
|
73
|
+
# database holds no era
|
|
73
74
|
def initialize(aggregate:, settings: {}, root: nil)
|
|
74
75
|
@aggregate = aggregate
|
|
75
76
|
@settings = settings
|
|
76
|
-
@db = PostgresSharedConnection.for(aggregate.name, settings, connector:
|
|
77
|
+
@db = PostgresSharedConnection.for(aggregate.name, settings, connector: ReadConnector)
|
|
77
78
|
@domain = journal_domain(aggregate, settings)
|
|
78
|
-
@lineage = Lineage.new(@db, @domain)
|
|
79
|
-
@lineage.ensure_base!
|
|
79
|
+
@lineage = Lineage.new(@db, @domain, reading: true)
|
|
80
80
|
resolve_era!(settings)
|
|
81
|
-
|
|
81
|
+
@field_caches = existing_field_caches
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
# Names this aggregate in storage: the journal's `aggregate` value and the stem of its
|
|
@@ -87,6 +87,16 @@ module Hecks
|
|
|
87
87
|
# @return [String] the aggregate's snake_case storage name
|
|
88
88
|
def table = @aggregate.storage_name
|
|
89
89
|
|
|
90
|
+
# Whether this binding's `mints_era` names the command: its own record may be journaled
|
|
91
|
+
# through a boot whose shape no era holds yet.
|
|
92
|
+
#
|
|
93
|
+
# @param aggregate_name [String] the aggregate the command belongs to
|
|
94
|
+
# @param command_name [String] the command
|
|
95
|
+
# @return [Boolean]
|
|
96
|
+
def mints_era_declared?(aggregate_name, command_name)
|
|
97
|
+
Ports::Persistence::MintDoor.declared?(@settings, aggregate_name, command_name)
|
|
98
|
+
end
|
|
99
|
+
|
|
90
100
|
# Reads one record's current state through the head view, translated to the current shape.
|
|
91
101
|
#
|
|
92
102
|
# @param id [String, Object] the record's identity, compared as `id.to_s`
|
|
@@ -151,7 +161,12 @@ module Hecks
|
|
|
151
161
|
# @yield the dispatch order; an exception rolls the transaction back
|
|
152
162
|
# @return [Object] the block's own value
|
|
153
163
|
# @raise [PG::ConnectionBad] if the connection dropped; it reconnects, then re-raises
|
|
154
|
-
def with_write_lock(&)
|
|
164
|
+
def with_write_lock(&)
|
|
165
|
+
transaction do
|
|
166
|
+
lock_writes!
|
|
167
|
+
yield
|
|
168
|
+
end
|
|
169
|
+
end
|
|
155
170
|
|
|
156
171
|
# Builds the instance an entry describes, writing nothing; the head is derived, so
|
|
157
172
|
# projecting is reading.
|
|
@@ -183,7 +198,7 @@ module Hecks
|
|
|
183
198
|
# @param id [String, Object] the record's identity, journaled as `id.to_s`
|
|
184
199
|
# @return [true] always
|
|
185
200
|
# @raise [Runtime::WiringError] if this boot's era has been superseded by a mint
|
|
186
|
-
def delete(id)
|
|
201
|
+
def delete(id)
|
|
187
202
|
entry = Ports::Persistence::Entry.new(operation: "delete", id: id.to_s, state: nil)
|
|
188
203
|
append(entry)
|
|
189
204
|
true
|
|
@@ -10,7 +10,6 @@ module Hecks
|
|
|
10
10
|
# Not frozen — a real cache, keyed by file path and mutated by
|
|
11
11
|
# #tree_for below (`TREES[file] ||= ...`) and #forget/#forget_all.
|
|
12
12
|
# False positive for Style/MutableConstant.
|
|
13
|
-
# rubocop:disable-next Style/MutableConstant
|
|
14
13
|
TREES = {}
|
|
15
14
|
|
|
16
15
|
# The first block node starting on each line, per parsed tree (by identity), built by one
|
|
@@ -40,6 +40,7 @@ module Hecks
|
|
|
40
40
|
# @raise [ArgumentError] if a where clause uses an operator this builder cannot compile,
|
|
41
41
|
# or `contains` targets a list of a value object with more than one field
|
|
42
42
|
def query(declared, args = {}, context: {})
|
|
43
|
+
Runtime::Value.check_query_arguments!(@aggregate, declared, args)
|
|
43
44
|
return in_memory_answer(declared, args, context) if in_memory?(declared)
|
|
44
45
|
|
|
45
46
|
sql = "SELECT #{select_list} FROM #{from_relation}"
|
|
@@ -17,7 +17,7 @@ module Hecks
|
|
|
17
17
|
# @param key [String] the dispatch key a saga leg stamped on the command
|
|
18
18
|
# @return [Boolean] true when the key was new and is now held; false when already held
|
|
19
19
|
# @raise [SQLite3::Exception] if the insert fails
|
|
20
|
-
def dispatch_claim(key)
|
|
20
|
+
def dispatch_claim(key)
|
|
21
21
|
@db.execute("INSERT OR IGNORE INTO hecks_dispatch_claims (claim_key, claimed_at) VALUES (?, ?)",
|
|
22
22
|
[key, Time.now.utc.iso8601])
|
|
23
23
|
@db.changes.positive?
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require_relative "../../../ports/persistence/stored_name_guard"
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Adapters
|
|
5
|
+
class Sqlite
|
|
6
|
+
# Reads how many rows a table holds before any table is created, for the stored-name guard.
|
|
7
|
+
module NameGuard
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def refuse_orphaned_rows!
|
|
11
|
+
Ports::Persistence::StoredNameGuard.check!(@aggregate, row_count: method(:rows_under))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def rows_under(name)
|
|
15
|
+
[name, "#{name}_entries"].sum { |table| table_rows(table) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def table_rows(table)
|
|
19
|
+
exists = @db.get_first_value("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?", [table])
|
|
20
|
+
exists ? @db.get_first_value("SELECT COUNT(*) FROM #{quote_ident(table)}").to_i : 0
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|