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,112 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "table/rows"
|
|
4
|
+
require_relative "table/checks"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module Projections
|
|
8
|
+
module CiPipeline
|
|
9
|
+
# A client's workflow rows, read from its bluebook and checked against the CiPipeline
|
|
10
|
+
# bluebook's vocabulary.
|
|
11
|
+
#
|
|
12
|
+
# The rows are the `member` lines of the value objects `Workflow`, `Trigger`, `Secret`,
|
|
13
|
+
# `Job`, `Need`, `Output`, `Env`, `Step` and `StepInput` in any bluebook of the project (the
|
|
14
|
+
# CiPipeline bluebook's Workflow, JobSpec and Step aggregates name the fields and the closed
|
|
15
|
+
# sets). This class joins them by workflow and job name into one tree and refuses a table that
|
|
16
|
+
# contradicts itself, naming every problem at once, each on the row it concerns.
|
|
17
|
+
class Table
|
|
18
|
+
# A table the projection refuses; the message lists each problem on its own line.
|
|
19
|
+
class Invalid < ArgumentError; end
|
|
20
|
+
|
|
21
|
+
# The name of the bluebook that declares the shape of a row.
|
|
22
|
+
BLUEBOOK = "CiPipeline"
|
|
23
|
+
|
|
24
|
+
# The value object whose member rows mark a bluebook as the client's.
|
|
25
|
+
MARKER = "Workflow"
|
|
26
|
+
|
|
27
|
+
# @return [Array<Tree::Workflow>] the workflows, in the order the client declared them
|
|
28
|
+
attr_reader :workflows
|
|
29
|
+
|
|
30
|
+
# Finds the one bluebook of a project that declares workflow rows.
|
|
31
|
+
#
|
|
32
|
+
# @param registry [Runtime::Registry] the registry the project booted into
|
|
33
|
+
# @return [Bluebook::Declaration] the bluebook holding `Workflow` rows
|
|
34
|
+
# @raise [Invalid] when no bluebook, or more than one, declares one
|
|
35
|
+
def self.bluebook(registry)
|
|
36
|
+
claimed = holders(registry)
|
|
37
|
+
raise Invalid, "no bluebook declares a value_object \"#{MARKER}\" with member rows" if claimed.empty?
|
|
38
|
+
return claimed.first if claimed.one?
|
|
39
|
+
|
|
40
|
+
raise Invalid, "#{claimed.size} bluebooks declare a value_object \"#{MARKER}\": " \
|
|
41
|
+
"#{claimed.map(&:name).join(", ")}; a project has one set of workflow rows"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @return [Array<Bluebook::Declaration>] the project's bluebooks that declare `Workflow` rows
|
|
45
|
+
def self.holders(registry)
|
|
46
|
+
clients = registry.bluebooks.values.reject { |bluebook| bluebook.name == BLUEBOOK }
|
|
47
|
+
clients.select { |bluebook| rows_of(bluebook, MARKER).any? }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Reads and checks one bluebook's workflow rows.
|
|
51
|
+
#
|
|
52
|
+
# @param bluebook [Bluebook::Declaration] the bluebook that declares the rows
|
|
53
|
+
# @param registry [Runtime::Registry] the registry the project booted into, which holds the
|
|
54
|
+
# CiPipeline bluebook
|
|
55
|
+
# @return [Table] the checked table
|
|
56
|
+
# @raise [Invalid] when the CiPipeline bluebook is not attached or a row is refused
|
|
57
|
+
def self.read(bluebook, registry:)
|
|
58
|
+
rows = Typing::SHAPES.keys.to_h { |object| [object, rows_of(bluebook, object)] }
|
|
59
|
+
new(rows, vocabulary: vocabulary(registry))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @param registry [Runtime::Registry] a registry holding the CiPipeline bluebook
|
|
63
|
+
# @return [Hash{Symbol => Object}] `:trigger` and `:uses`, the closed sets, as arrays of
|
|
64
|
+
# members, and `:patterns`, each named field to the regexp its bluebook value object holds
|
|
65
|
+
# @raise [Invalid] when the registry does not hold the CiPipeline bluebook
|
|
66
|
+
def self.vocabulary(registry)
|
|
67
|
+
pipeline = registry.bluebook(BLUEBOOK) or
|
|
68
|
+
raise Invalid, "the project does not attach the #{BLUEBOOK} bluebook (attaches \"#{BLUEBOOK}\")"
|
|
69
|
+
{ trigger: members(pipeline, "Workflow", "Trigger"),
|
|
70
|
+
uses: members(pipeline, "JobSpec", "ActionRef").reject(&:empty?),
|
|
71
|
+
patterns: Rows::PATTERNS.transform_values { |(aggregate, object)| pattern(pipeline, aggregate, object) } }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# @param bluebook [Bluebook::Declaration] a bluebook to search
|
|
75
|
+
# @param object [String] the name of the value object whose rows are wanted
|
|
76
|
+
# @return [Array<Hash{Symbol => Object}>] the member rows of its value objects of that name
|
|
77
|
+
def self.rows_of(bluebook, object)
|
|
78
|
+
objects = bluebook.aggregates.flat_map(&:value_objects)
|
|
79
|
+
objects.select { |candidate| candidate.hecks_name == object }.flat_map(&:members)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @return [Array<String>] the members of a closed set held as a value object of an aggregate
|
|
83
|
+
def self.members(bluebook, aggregate, object)
|
|
84
|
+
held(bluebook, aggregate, object).members.map { |member| member.fetch(:value) }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# @return [Regexp] the pattern of a value object's one attribute
|
|
88
|
+
def self.pattern(bluebook, aggregate, object)
|
|
89
|
+
Regexp.new(held(bluebook, aggregate, object).attributes.first.pattern)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @return [Bluebook::ValueObject] a value object of an aggregate of the bluebook
|
|
93
|
+
def self.held(bluebook, aggregate, object)
|
|
94
|
+
bluebook.aggregate(aggregate).value_objects.find { |candidate| candidate.hecks_name == object }
|
|
95
|
+
end
|
|
96
|
+
private_class_method :holders, :members, :pattern, :held
|
|
97
|
+
|
|
98
|
+
# @param rows [Hash{String => Array<Hash{Symbol => Object}>}] each object's declared rows
|
|
99
|
+
# @param vocabulary [Hash{Symbol => Object}] the closed sets and patterns
|
|
100
|
+
# @raise [Invalid] when a row is refused
|
|
101
|
+
def initialize(rows, vocabulary:)
|
|
102
|
+
problems = []
|
|
103
|
+
@workflows = Rows.new(rows, vocabulary, problems).workflows
|
|
104
|
+
Checks.new(@workflows, vocabulary, problems).call
|
|
105
|
+
return if problems.empty?
|
|
106
|
+
|
|
107
|
+
raise Invalid, "the workflow rows are refused:\n#{problems.map { |line| " - #{line}" }.join("\n")}"
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../projector"
|
|
4
|
+
require_relative "table"
|
|
5
|
+
require_relative "yaml_text"
|
|
6
|
+
|
|
7
|
+
module Hecks
|
|
8
|
+
module Projections
|
|
9
|
+
module CiPipeline
|
|
10
|
+
# A client's workflow rows as GitHub Actions workflow files, one per `Workflow` row.
|
|
11
|
+
#
|
|
12
|
+
# The text is a pure function of the rows: workflows, jobs and steps keep the order the client
|
|
13
|
+
# declared them in, and nothing in it names a time or a machine, so regenerating from the same
|
|
14
|
+
# rows changes nothing. A modeled `note` is written as the comment above what it belongs to.
|
|
15
|
+
module Workflows
|
|
16
|
+
extend Projector::Target
|
|
17
|
+
|
|
18
|
+
projects_as :ci_workflows, emits: :files
|
|
19
|
+
|
|
20
|
+
# Where the files go, relative to the checkout.
|
|
21
|
+
DIRECTORY = ".github/workflows"
|
|
22
|
+
|
|
23
|
+
# The banner every generated file starts with.
|
|
24
|
+
BANNER = "# Generated by hecks regeneration_run.project_ci_pipeline!. Do not edit; change the workflow rows."
|
|
25
|
+
|
|
26
|
+
# What each event of the bluebook's `Trigger` set is written as under `on:`.
|
|
27
|
+
EVENTS = { "push_main" => ["push:", " branches: [main]"], "pull_request" => ["pull_request:"],
|
|
28
|
+
"workflow_dispatch" => ["workflow_dispatch:"] }.freeze
|
|
29
|
+
|
|
30
|
+
module_function
|
|
31
|
+
|
|
32
|
+
# Renders each workflow of a table of rows.
|
|
33
|
+
#
|
|
34
|
+
# @param bluebook [Bluebook::Declaration] the bluebook that declares the rows
|
|
35
|
+
# @param options [Hash{Symbol => Object}] `:registry` (Runtime::Registry) the project booted
|
|
36
|
+
# into, which holds the CiPipeline bluebook; `:table` (Table) a table already read
|
|
37
|
+
# @return [Hash{String => String}] each file's path under the checkout to its text; empty
|
|
38
|
+
# when the bluebook declares no `Workflow` rows, as a site's root files are
|
|
39
|
+
# @raise [Table::Invalid] when the rows are refused
|
|
40
|
+
def call(bluebook:, options: {})
|
|
41
|
+
table = options[:table] || read(bluebook, options)
|
|
42
|
+
return {} unless table
|
|
43
|
+
|
|
44
|
+
table.workflows.to_h { |workflow| ["#{DIRECTORY}/#{workflow.name}", render(workflow)] }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @return [Table, nil] the bluebook's rows checked against the registry's CiPipeline
|
|
48
|
+
# bluebook, or nil when the bluebook holds none, which needs no registry to say
|
|
49
|
+
def read(bluebook, options)
|
|
50
|
+
return if Table.rows_of(bluebook, Table::MARKER).empty?
|
|
51
|
+
|
|
52
|
+
Table.read(bluebook, registry: options.fetch(:registry))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @param workflow [Table::Rows::Workflow] a checked workflow
|
|
56
|
+
# @return [String] the file's text, ending in a newline
|
|
57
|
+
def render(workflow)
|
|
58
|
+
sections = [[BANNER], ["name: #{YamlText.scalar(workflow.display_name)}"], note(workflow.note),
|
|
59
|
+
triggers(workflow), concurrency(workflow), jobs(workflow)]
|
|
60
|
+
"#{sections.reject(&:empty?).map { |lines| lines.join("\n") }.join("\n\n")}\n"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def note(text) = text.empty? ? [] : YamlText.comment(text)
|
|
64
|
+
|
|
65
|
+
def triggers(workflow)
|
|
66
|
+
["on:", *YamlText.indent(workflow.triggers.flat_map { |event| event_lines(event, workflow) }, 2)]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def event_lines(event, workflow)
|
|
70
|
+
return EVENTS.fetch(event) unless event == "workflow_call"
|
|
71
|
+
|
|
72
|
+
["workflow_call:", *YamlText.indent(secrets(workflow), 2)]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def secrets(workflow)
|
|
76
|
+
return [] if workflow.secrets.empty?
|
|
77
|
+
|
|
78
|
+
["secrets:", *YamlText.indent(workflow.secrets.flat_map { |secret| secret_lines(secret) }, 2)]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def secret_lines(secret)
|
|
82
|
+
["#{YamlText.key(secret.name)}:", " required: #{secret.required}"]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def concurrency(workflow)
|
|
86
|
+
return [] if workflow.concurrency_group.empty?
|
|
87
|
+
|
|
88
|
+
["concurrency:", " group: #{YamlText.scalar(workflow.concurrency_group)}",
|
|
89
|
+
" cancel-in-progress: #{workflow.cancel_in_progress}"]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def jobs(workflow)
|
|
93
|
+
blocks = workflow.jobs.map { |job| YamlText.indent([*note(job.note), *job_lines(job)], 2) }
|
|
94
|
+
["jobs:", *blocks.flat_map { |lines| [*lines, ""] }[0...-1]]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def job_lines(job)
|
|
98
|
+
body = [*headline(job), *needs(job), *condition(job), *strategy(job), *pairs("outputs", job.outputs),
|
|
99
|
+
*pairs("env", job.env), *steps(job)]
|
|
100
|
+
["#{YamlText.key(job.name)}:", *YamlText.indent(body, 2)]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def headline(job)
|
|
104
|
+
["runs-on: #{YamlText.scalar(job.runner)}", "timeout-minutes: #{job.timeout_minutes}", *permissions(job)]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def permissions(job)
|
|
108
|
+
return [] if job.permissions.empty?
|
|
109
|
+
|
|
110
|
+
["permissions:", *job.permissions.split(", ").map { |scope| " #{scope}" }]
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def needs(job)
|
|
114
|
+
return [] if job.needs.empty?
|
|
115
|
+
return ["needs: #{YamlText.scalar(job.needs.first)}"] if job.needs.one?
|
|
116
|
+
|
|
117
|
+
["needs: [#{job.needs.map { |name| YamlText.scalar(name) }.join(", ")}]"]
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def condition(job) = job.condition.empty? ? [] : YamlText.folded("if", job.condition)
|
|
121
|
+
|
|
122
|
+
# A sharded job runs one leg for each number up to its total, and no leg cancels another.
|
|
123
|
+
def strategy(job)
|
|
124
|
+
return [] unless job.shard_total > 1
|
|
125
|
+
|
|
126
|
+
["strategy:", " fail-fast: false", " matrix:",
|
|
127
|
+
" #{YamlText.key(job.shard_axis)}: [#{(1..job.shard_total).to_a.join(", ")}]"]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def pairs(key, entries)
|
|
131
|
+
return [] if entries.empty?
|
|
132
|
+
|
|
133
|
+
["#{key}:", *entries.map { |pair| " #{YamlText.key(pair.key)}: #{YamlText.scalar(pair.value)}" }]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def steps(job)
|
|
137
|
+
lines = job.steps.each_with_index.flat_map do |step, index|
|
|
138
|
+
separator = index.positive? && !step.note.empty? ? [""] : []
|
|
139
|
+
[*separator, *note(step.note), *step_lines(step, job)]
|
|
140
|
+
end
|
|
141
|
+
["steps:", *YamlText.indent(lines, 2)]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def step_lines(step, job)
|
|
145
|
+
fields = [*scalar_field("name", step.title), *scalar_field("id", step.id), *condition_of(step),
|
|
146
|
+
*scalar_field("uses", step.uses), *pairs("with", step.inputs), *command(step, job)]
|
|
147
|
+
fields.each_with_index.map { |line, index| index.zero? ? "- #{line}" : " #{line}" }
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def scalar_field(key, text) = text.empty? ? [] : ["#{key}: #{YamlText.scalar(text)}"]
|
|
151
|
+
|
|
152
|
+
def condition_of(step) = step.condition.empty? ? [] : YamlText.folded("if", step.condition)
|
|
153
|
+
|
|
154
|
+
def command(step, job)
|
|
155
|
+
return [] if step.run.empty?
|
|
156
|
+
|
|
157
|
+
YamlText.literal("run", step.run.gsub(Table::Checks::SHARD_TOKEN, job.shard_total.to_s))
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "psych"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module Projections
|
|
8
|
+
module CiPipeline
|
|
9
|
+
# The few shapes of YAML text a workflow needs: a scalar quoted only where YAML needs it, a
|
|
10
|
+
# comment, a literal block for a command and a folded block for a long condition.
|
|
11
|
+
#
|
|
12
|
+
# A scalar is written as the row spells it, so `14` and `false` stay a number and a boolean
|
|
13
|
+
# and any other text is the string, in double quotes when plain text would read as something
|
|
14
|
+
# else. Every function answers lines without a trailing newline.
|
|
15
|
+
module YamlText
|
|
16
|
+
# The longest a `key: value` line may be before a condition folds onto its own lines.
|
|
17
|
+
WIDTH = 100
|
|
18
|
+
|
|
19
|
+
# A character that makes plain text mean something other than a string when it comes first.
|
|
20
|
+
INDICATOR = /\A[-?:,\[\]{}#&*!|>'"%@`]/
|
|
21
|
+
|
|
22
|
+
# Text plain YAML cannot carry as it stands: padding, a colon, a comment, a line break.
|
|
23
|
+
UNPLAIN = /\A\s|\s\z|: | #|\n/
|
|
24
|
+
|
|
25
|
+
# Text that would not survive being folded at its spaces: a line break or padding.
|
|
26
|
+
UNFOLDABLE = /\n|\A\s|\s\z|\s\s/
|
|
27
|
+
|
|
28
|
+
# The line breaks that end a command.
|
|
29
|
+
TRAILING_BREAKS = /\n+\z/
|
|
30
|
+
|
|
31
|
+
# A key YAML takes bare.
|
|
32
|
+
BARE_KEY = /\A[A-Za-z_][\w.-]*\z/
|
|
33
|
+
|
|
34
|
+
# What a literal block's header says about the breaks that end it: none, one or all.
|
|
35
|
+
KEEP = { 0 => "-", 1 => "" }.freeze
|
|
36
|
+
|
|
37
|
+
module_function
|
|
38
|
+
|
|
39
|
+
# @param text [String] a key
|
|
40
|
+
# @return [String] the key, quoted when it is not a plain word
|
|
41
|
+
def key(text) = BARE_KEY.match?(text) ? text : JSON.generate(text)
|
|
42
|
+
|
|
43
|
+
# @param value [String, Integer, Boolean] a row's value
|
|
44
|
+
# @return [String] the scalar as YAML text
|
|
45
|
+
def scalar(value)
|
|
46
|
+
return value.to_s unless value.is_a?(String)
|
|
47
|
+
|
|
48
|
+
plain?(value) ? value : JSON.generate(value)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @param text [String] some text
|
|
52
|
+
# @return [Boolean] whether plain YAML reads it back as a scalar that spells the same text
|
|
53
|
+
def plain?(text)
|
|
54
|
+
return false if text.empty? || text.match?(INDICATOR) || text.match?(UNPLAIN)
|
|
55
|
+
|
|
56
|
+
read = Psych.safe_load("v: #{text}").fetch("v")
|
|
57
|
+
!read.is_a?(Hash) && !read.is_a?(Array) && read.to_s == text
|
|
58
|
+
rescue Psych::Exception
|
|
59
|
+
false
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @param text [String] a note, one line per line of text
|
|
63
|
+
# @return [Array<String>] the comment lines, a blank line as a bare `#`
|
|
64
|
+
def comment(text)
|
|
65
|
+
text.split("\n", -1).map { |line| line.empty? ? "#" : "# #{line}" }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @param key [String] the key the value belongs to
|
|
69
|
+
# @param text [String] a condition
|
|
70
|
+
# @return [Array<String>] one line, or the key and a folded block when the line is long
|
|
71
|
+
def folded(key, text)
|
|
72
|
+
line = "#{key}: #{scalar(text)}"
|
|
73
|
+
return [line] if line.length <= WIDTH || text.match?(UNFOLDABLE)
|
|
74
|
+
|
|
75
|
+
["#{key}: >-", *wrap(text).map { |row| " #{row}" }]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @param key [String] the key the value belongs to
|
|
79
|
+
# @param text [String] a command
|
|
80
|
+
# @return [Array<String>] one line for a one-line command, else the key and a literal block
|
|
81
|
+
def literal(key, text)
|
|
82
|
+
return ["#{key}: #{scalar(text)}"] unless text.include?("\n")
|
|
83
|
+
|
|
84
|
+
body = text.sub(TRAILING_BREAKS, "")
|
|
85
|
+
breaks = text.length - body.length
|
|
86
|
+
rows = body.split("\n", -1).map { |row| row.empty? ? "" : " #{row}" }
|
|
87
|
+
["#{key}: |#{KEEP.fetch(breaks, "+")}", *rows, *[""] * [breaks - 1, 0].max]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# @param lines [Array<String>] lines
|
|
91
|
+
# @param width [Integer] how many spaces to put before each non-empty one
|
|
92
|
+
# @return [Array<String>] the indented lines
|
|
93
|
+
def indent(lines, width) = lines.map { |line| line.empty? ? line : "#{" " * width}#{line}" }
|
|
94
|
+
|
|
95
|
+
# @return [Array<String>] the words of the text packed into lines of at most the width
|
|
96
|
+
def wrap(text)
|
|
97
|
+
text.split.each_with_object([]) do |word, rows|
|
|
98
|
+
rows.empty? || rows.last.length + 1 + word.length > WIDTH - 6 ? rows << word.dup : rows.last << " #{word}"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -60,7 +60,7 @@ module Hecks
|
|
|
60
60
|
args = "service=$(SERVICE) $(if $(EXISTING_TAG),existing_tag=$(EXISTING_TAG)) " \
|
|
61
61
|
"$(if $(LOCAL_IMAGE),local_image=$(LOCAL_IMAGE))"
|
|
62
62
|
direct = "bash ./deploy-service.sh $(SERVICE)"
|
|
63
|
-
Box::RollRecipe.call(command: "service_roll.run", args: args, direct: direct)
|
|
63
|
+
Box::RollRecipe.call(command: "service_roll.run!", args: args, direct: direct)
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
# @param plan [Settings::Plan] the resolved settings
|
|
@@ -20,7 +20,7 @@ module Hecks
|
|
|
20
20
|
args = plan.task_definition ? "$(if $(TASKDEF),taskdef=$(TASKDEF))" : "$(if $(TAGS),tags=\"$(TAGS)\")"
|
|
21
21
|
direct = "bash ./deploy-box.sh $(#{variable})"
|
|
22
22
|
direct += " || exit $$?; TASKDEF=\"$(TASKDEF)\" bash ./smoke-after-deploy.sh" if plan.hosting
|
|
23
|
-
"\t#{call(command: "box_roll.run", args: args, direct: direct)}"
|
|
23
|
+
"\t#{call(command: "box_roll.run!", args: args, direct: direct)}"
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
# @param command [String] the Deploy command, such as `box_roll.run`
|
|
@@ -117,7 +117,7 @@ module Hecks
|
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
def health_probe(label, args, wanted)
|
|
120
|
-
write_out = '-w "%{http_code}"'
|
|
120
|
+
write_out = '-w "%{http_code}"'
|
|
121
121
|
<<~SH.chomp
|
|
122
122
|
code=$(curl -s -o /dev/null #{write_out} --max-time 40 localhost/#{args})
|
|
123
123
|
#{wanted} && echo "ok #{label} -> $code" || { echo "FAIL #{label} -> $code"; BAD=1; }
|
|
@@ -62,7 +62,7 @@ module Hecks
|
|
|
62
62
|
# exits non-zero (24 when the smoke passed).
|
|
63
63
|
SMOKE_RECIPE = [
|
|
64
64
|
"@err=$$(mktemp); \\",
|
|
65
|
-
'$(HECKS) deploy smoke_run.run project="$(CURDIR)" --wait $(if $(TASKDEF),taskdef=$(TASKDEF)) 2>"$$err"; rc=$$?; \\',
|
|
65
|
+
'$(HECKS) deploy smoke_run.run! project="$(CURDIR)" --wait $(if $(TASKDEF),taskdef=$(TASKDEF)) 2>"$$err"; rc=$$?; \\',
|
|
66
66
|
'if [ $$rc -ne 0 ] && grep -q \'^cannot open Hecks\' "$$err"; then \\',
|
|
67
67
|
' echo "==> the deploy record was NOT written: $$(grep -m1 \'^cannot open Hecks\' "$$err")" >&2; \\',
|
|
68
68
|
*NO_DATABASE_ADVICE,
|
|
@@ -35,7 +35,7 @@ build:
|
|
|
35
35
|
# generator the Lambda deploy path already uses to produce
|
|
36
36
|
# rust/dist/@@domain_name@@.wasm/.ir.json from this domain's own
|
|
37
37
|
# .bluebook.
|
|
38
|
-
cd $(ROOT) && HECKS_ENVIRONMENT=memory ruby exe/hecks build.build_wasm domain=$(DOMAIN) --wait
|
|
38
|
+
cd $(ROOT) && HECKS_ENVIRONMENT=memory ruby exe/hecks build.build_wasm! domain=$(DOMAIN) --wait
|
|
39
39
|
cd $(HOST_DIR) && CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc rustup run stable cargo build --release --target aarch64-unknown-linux-gnu --bin bootstrap
|
|
40
40
|
cp $(HOST_DIR)/target/aarch64-unknown-linux-gnu/release/bootstrap @@domain_name@@-host
|
|
41
41
|
cp $(ROOT)/rust/dist/@@domain_name@@.wasm @@domain_name@@.wasm
|
|
@@ -27,7 +27,7 @@ build-@@logical_id@@:
|
|
|
27
27
|
# field). `hecks build_wasm` recompiles fast enough that "always
|
|
28
28
|
# rebuild" is the safe default, matching rust/host's own bootstrap
|
|
29
29
|
# build just below, which was never guarded this way to begin with.
|
|
30
|
-
cd @@root@@ && HECKS_ENVIRONMENT=memory ruby exe/hecks build.build_wasm domain=@@domain@@ --wait
|
|
30
|
+
cd @@root@@ && HECKS_ENVIRONMENT=memory ruby exe/hecks build.build_wasm! domain=@@domain@@ --wait
|
|
31
31
|
@rustup target list --installed 2>/dev/null | grep -qx aarch64-unknown-linux-gnu || rustup target add aarch64-unknown-linux-gnu
|
|
32
32
|
# `rustup run stable`, not a bare `cargo lambda` — same reasoning
|
|
33
33
|
# `hecks build_wasm`'s own Makefile-equivalent line holds itself to: a
|
|
@@ -129,12 +129,12 @@ restore-@@logical_id@@-build:
|
|
|
129
129
|
.PHONY: verify-parity-@@logical_id@@
|
|
130
130
|
verify-parity-@@logical_id@@:
|
|
131
131
|
@if [ -f @@root@@/spec/corpus/@@domain_name@@.json ]; then \
|
|
132
|
-
cd @@root@@ && HECKS_ENVIRONMENT=memory ruby exe/hecks build.check_conformance domain=@@domain@@ script=spec/corpus/@@domain_name@@.json artifact=$(WASM) --wait; \
|
|
132
|
+
cd @@root@@ && HECKS_ENVIRONMENT=memory ruby exe/hecks build.check_conformance! domain=@@domain@@ script=spec/corpus/@@domain_name@@.json artifact=$(WASM) --wait; \
|
|
133
133
|
else \
|
|
134
134
|
echo "verify-parity-@@logical_id@@: no spec/corpus/@@domain_name@@.json -- SKIPPING the pre-deploy Ruby/Rust parity check, nothing to compare $(WASM) against. Write one (hecks fuzz/hecks run's own script shape) before this domain's next deploy."; \
|
|
135
135
|
fi
|
|
136
136
|
@echo "verify-parity-@@logical_id@@: fuzzing $(WASM) against generated sequences (ADR 0037's bridge, WARN-ONLY -- see this target's own comment)..."
|
|
137
|
-
-@cd @@root@@ && HECKS_ENVIRONMENT=memory ruby exe/hecks build.fuzz_conformance domain=@@domain@@ artifact=$(WASM) --wait
|
|
137
|
+
-@cd @@root@@ && HECKS_ENVIRONMENT=memory ruby exe/hecks build.fuzz_conformance! domain=@@domain@@ artifact=$(WASM) --wait
|
|
138
138
|
|
|
139
139
|
# `make mint-era` — takes @@stack_name@@'s RDS instance from freshly
|
|
140
140
|
# created to "era 1 minted, ready for HECKS_DOMAIN/HECKS_ERA to
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require_relative "../projector"
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Projections
|
|
5
|
+
# The command that undoes a declared command, read from the bluebook's compensations: a
|
|
6
|
+
# process manager's dispatch that names a `compensates` for the command. Answers "none
|
|
7
|
+
# declared" when no compensation is declared, and never invents one.
|
|
8
|
+
#
|
|
9
|
+
# Projector.call(:undo, bluebook: bluebook, options: { command: "Account.Debit" })
|
|
10
|
+
module Undo
|
|
11
|
+
extend Hecks::Projector::Target
|
|
12
|
+
|
|
13
|
+
projects_as :undo
|
|
14
|
+
|
|
15
|
+
module_function
|
|
16
|
+
|
|
17
|
+
# @param bluebook [Bluebook::Declaration] the bluebook holding the process managers
|
|
18
|
+
# @param options [Hash{Symbol => Object}] `command:`, the command's verb form, e.g. "Account.Debit"
|
|
19
|
+
# @return [Array<String>] one sentence: the undoing command, or that none is declared
|
|
20
|
+
def call(bluebook:, options: {})
|
|
21
|
+
command = options.fetch(:command)
|
|
22
|
+
compensation = compensation_for(bluebook, command)
|
|
23
|
+
return ["#{command} has no undo declared: its bluebook names no compensating command."] unless compensation
|
|
24
|
+
|
|
25
|
+
["#{command} is undone by #{compensation}, a compensation the bluebook declares."]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The name of the command that undoes the named one, or nil.
|
|
29
|
+
#
|
|
30
|
+
# @return [String, nil]
|
|
31
|
+
def compensation_for(bluebook, command)
|
|
32
|
+
dispatch = bluebook.process_managers
|
|
33
|
+
.flat_map { |manager| manager.handlers.flat_map(&:dispatches) }
|
|
34
|
+
.find { |candidate| same_command?(candidate.command_name, command) && candidate.compensates }
|
|
35
|
+
compensation = dispatch&.compensates
|
|
36
|
+
compensation&.command_name
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Whether two command names are the same command, in either the `::` or the `.` spelling.
|
|
40
|
+
def same_command?(left, right)
|
|
41
|
+
normal = ->(name) { name.to_s.gsub("::", ".") }
|
|
42
|
+
normal.call(left) == normal.call(right)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/hecks/projections.rb
CHANGED
|
@@ -20,6 +20,7 @@ require_relative "projections/reference"
|
|
|
20
20
|
require_relative "projections/model"
|
|
21
21
|
require_relative "projections/diagrams"
|
|
22
22
|
require_relative "projections/statements"
|
|
23
|
+
require_relative "projections/undo"
|
|
23
24
|
require_relative "projections/context_relationships"
|
|
24
25
|
require_relative "projections/world_skeleton"
|
|
25
26
|
require_relative "projections/glossary"
|
|
@@ -32,4 +33,5 @@ require_relative "projections/deploy/vercel"
|
|
|
32
33
|
require_relative "projections/deploy/smoke"
|
|
33
34
|
require_relative "projections/deploy/template_diff"
|
|
34
35
|
require_relative "projections/site/routes_ts"
|
|
36
|
+
require_relative "projections/ci_pipeline/workflows"
|
|
35
37
|
require_relative "projections/rails_app"
|
|
@@ -108,14 +108,25 @@ module Hecks
|
|
|
108
108
|
|
|
109
109
|
# Maps every accepted spelling (full name, `:short` and a renamed command's old name)
|
|
110
110
|
# to the full name.
|
|
111
|
+
LEAD_SEGMENT = /\A[^.]+/
|
|
112
|
+
|
|
111
113
|
def aliases(specs)
|
|
112
114
|
specs.each_with_object({}) do |(name, spec), map|
|
|
113
115
|
map[name] = name
|
|
114
116
|
map[spec[:short]] = name
|
|
115
117
|
map[spec[:short_was]] = name if spec[:short_was]
|
|
118
|
+
map[former_key(name, spec)] ||= name if spec[:formerly]
|
|
116
119
|
end
|
|
117
120
|
end
|
|
118
121
|
|
|
122
|
+
# The spelling a command had while its aggregate carried its former name, such as
|
|
123
|
+
# `old_name.board` for `new_name.board`; it resolves to the command, with a note.
|
|
124
|
+
#
|
|
125
|
+
# @return [String] the command's name with its aggregate's first segment replaced
|
|
126
|
+
def former_key(name, spec)
|
|
127
|
+
name.sub(LEAD_SEGMENT, Naming.snake(spec[:formerly]))
|
|
128
|
+
end
|
|
129
|
+
|
|
119
130
|
# Stores `spec` under `name`, refusing a second claim rather than silently
|
|
120
131
|
# keeping whichever command was walked first.
|
|
121
132
|
#
|
|
@@ -19,7 +19,12 @@ module Hecks
|
|
|
19
19
|
out << "dispatches #{spec[:command]}" if spec[:kind] == :command
|
|
20
20
|
out << "reads #{spec[:command]}" if spec[:kind] == :query
|
|
21
21
|
out << "issued by #{spec[:role]}" if spec[:role]
|
|
22
|
-
out
|
|
22
|
+
out.concat(command_help_audience_lines(spec))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# The audiences a command declares it is listed for, or nothing when it declares none.
|
|
26
|
+
def command_help_audience_lines(spec)
|
|
27
|
+
Array(spec[:audience]).any? ? ["listed for #{spec[:audience].join(", ")}"] : []
|
|
23
28
|
end
|
|
24
29
|
|
|
25
30
|
# The example call with every argument as `path=…`.
|
|
@@ -52,10 +52,20 @@ module Hecks
|
|
|
52
52
|
# What the command declares about itself, apart from its arguments.
|
|
53
53
|
def command_facts(aggregate, command)
|
|
54
54
|
{ summary: command.goal, role: command.role, role_gated: !command.role.to_s.empty?,
|
|
55
|
-
group: aggregate.hecks_name, internal: command
|
|
55
|
+
group: aggregate.hecks_name, internal: internal?(command), audience: command.audience,
|
|
56
|
+
formerly: aggregate.former_name,
|
|
56
57
|
creates: command.creates? }
|
|
57
58
|
end
|
|
58
59
|
|
|
60
|
+
# Whether the default listing leaves the command out. A declared audience decides: the
|
|
61
|
+
# listing is for a person. A command that declares none is a run's own bookkeeping when
|
|
62
|
+
# its role is `System`, else listed.
|
|
63
|
+
def internal?(command)
|
|
64
|
+
return command.role.to_s == "System" if command.audience.empty?
|
|
65
|
+
|
|
66
|
+
!command.audience.include?("person")
|
|
67
|
+
end
|
|
68
|
+
|
|
59
69
|
# The receiver entries of a spec. `id=...` is still accepted for aggregate receivers but
|
|
60
70
|
# hidden from help, which teaches only `to=...`.
|
|
61
71
|
def receiver_facts(receiver)
|