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,938 @@
|
|
|
1
|
+
# CI pipeline: the GitHub Actions workflows under .github/workflows are a projection of
|
|
2
|
+
# this bluebook, as generated Rust is a projection of a domain. A workflow file, its jobs
|
|
3
|
+
# and their steps, the gates that skip work, the edges that order jobs, the corpus the
|
|
4
|
+
# jobs share, and the build that passes or fails are written down here. The projector
|
|
5
|
+
# reads these rows and writes the YAML; a check compares the committed file with the rows.
|
|
6
|
+
#
|
|
7
|
+
# Nothing here runs a job or reads GitHub. The Runner port answers what happened in a
|
|
8
|
+
# build, and the Cache port answers whether a corpus is held. Both are declared in
|
|
9
|
+
# ci_pipeline.ports.hecksagon.
|
|
10
|
+
#
|
|
11
|
+
# A client declares its workflows as `member` rows of value objects in its own bluebook, as a
|
|
12
|
+
# site declares its routes (the Site bluebook): a `Workflow` row per file, then a `Trigger`, a
|
|
13
|
+
# `Secret`, a `Job`, a `Need`, an `Output`, an `Env`, a `Step` and a `StepInput` row each, all
|
|
14
|
+
# flat and joined by workflow and job name. The Workflow, JobSpec and Step aggregates below name
|
|
15
|
+
# the fields those rows carry and the closed sets their values come from. `hecks
|
|
16
|
+
# regeneration_run.project_ci_pipeline` reads the rows and writes the files.
|
|
17
|
+
#
|
|
18
|
+
# A job's `needs:` is a `Need` row. The policies at the end of this bluebook are the same edges as
|
|
19
|
+
# a build sees them, as events: they decide when a job in one build queues, and write nothing.
|
|
20
|
+
#
|
|
21
|
+
# CiSpeed's Run and JobTiming record what this bluebook's Build and Job already know. When
|
|
22
|
+
# CiSpeed reads them, the Runner port answers from these rows, not from a second record.
|
|
23
|
+
|
|
24
|
+
Hecks.bluebook "CiPipeline" do
|
|
25
|
+
vision "A workflow file is what its rows say: a job runs after what it needs, a skipped gate leaves its dependents runnable, a build passes only when every required job settled, and a corpus is regenerated once and shared."
|
|
26
|
+
|
|
27
|
+
supporting
|
|
28
|
+
|
|
29
|
+
# One workflow file under .github/workflows. The file name is its identity. `reusable` means the
|
|
30
|
+
# file is called by other workflows, so the projector writes `workflow_call`; a Workflow row
|
|
31
|
+
# carries no such flag, because its `workflow_call` Trigger row says the same. A `Secret` row
|
|
32
|
+
# names one secret a called workflow takes and whether the caller must pass it. `note` is the
|
|
33
|
+
# comment the file opens with, one line per line of text.
|
|
34
|
+
aggregate "Workflow" do
|
|
35
|
+
description "One workflow file: its name, the events that start it, concurrency, whether other workflows call it, and the secrets it takes."
|
|
36
|
+
|
|
37
|
+
identified_by :name
|
|
38
|
+
|
|
39
|
+
attribute :name, WorkflowName
|
|
40
|
+
attribute :display_name, WorkflowText
|
|
41
|
+
attribute :note, WorkflowText, optional: true
|
|
42
|
+
attribute :concurrency_group, WorkflowText, optional: true
|
|
43
|
+
attribute :cancel_in_progress, Switch, optional: true
|
|
44
|
+
attribute :reusable, Switch
|
|
45
|
+
attribute :triggers, list_of(Trigger)
|
|
46
|
+
attribute :secrets, list_of(SecretName)
|
|
47
|
+
attribute :check, Switch, optional: true
|
|
48
|
+
|
|
49
|
+
value_object "WorkflowName" do
|
|
50
|
+
# The file name under .github/workflows, such as `ci-rspec.yml`.
|
|
51
|
+
attribute :value, String, pattern: '^[a-z][a-z0-9-]*[.]yml$'
|
|
52
|
+
invariant("a workflow is named by its file") { !value.to_s.empty? }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
value_object "WorkflowText" do
|
|
56
|
+
attribute :value, String
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# The events the projector writes under `on:`. `schedule` is not here: its cron text is not
|
|
60
|
+
# expressible yet, so the scheduled workflows stay hand-written.
|
|
61
|
+
value_object "Trigger" do
|
|
62
|
+
attribute :value, String, one_of: %w[push_main pull_request workflow_call workflow_dispatch]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
value_object "SecretName" do
|
|
66
|
+
# A repository secret the file passes in, such as HECKS_CI_ATTEST_KEY.
|
|
67
|
+
attribute :value, String, pattern: '^[A-Z][A-Z0-9_]*$'
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
value_object "Switch" do
|
|
71
|
+
attribute :value, Boolean
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# A digest of the projected YAML, or of the committed file: a hex SHA-256.
|
|
75
|
+
value_object "ProjectionDigest" do
|
|
76
|
+
attribute :value, String, pattern: '^[0-9a-f]{64}$'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
command "Declare" do
|
|
80
|
+
role "CI engineer"
|
|
81
|
+
goal "Write down one workflow file: its name, whether other workflows call it, and its concurrency"
|
|
82
|
+
|
|
83
|
+
attribute :name, WorkflowName
|
|
84
|
+
attribute :display_name, WorkflowText
|
|
85
|
+
attribute :concurrency_group, WorkflowText, optional: true
|
|
86
|
+
attribute :cancel_in_progress, Switch, optional: true
|
|
87
|
+
attribute :reusable, Switch
|
|
88
|
+
|
|
89
|
+
sets :name
|
|
90
|
+
sets :display_name
|
|
91
|
+
sets :concurrency_group
|
|
92
|
+
sets :cancel_in_progress
|
|
93
|
+
sets :reusable
|
|
94
|
+
|
|
95
|
+
emits "WorkflowDeclared"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
command "Trigger" do
|
|
99
|
+
role "CI engineer"
|
|
100
|
+
goal "Name one event that starts this workflow"
|
|
101
|
+
|
|
102
|
+
reference_to Workflow
|
|
103
|
+
attribute :event, Trigger
|
|
104
|
+
|
|
105
|
+
sets :triggers, append: { value: :event }
|
|
106
|
+
|
|
107
|
+
emits "WorkflowTriggerAdded"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
command "Secret" do
|
|
111
|
+
role "CI engineer"
|
|
112
|
+
goal "Name one repository secret this workflow passes in, so a caller must pass it too"
|
|
113
|
+
|
|
114
|
+
reference_to Workflow
|
|
115
|
+
attribute :secret, SecretName
|
|
116
|
+
|
|
117
|
+
sets :secrets, append: { value: :secret }
|
|
118
|
+
|
|
119
|
+
emits "WorkflowSecretAdded"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Writes the file from the rows, or with check only compares the committed file with the rows.
|
|
123
|
+
command "Project" do
|
|
124
|
+
role "CI engineer"
|
|
125
|
+
goal "Project the workflow's rows into its file, or with check only compare the committed file"
|
|
126
|
+
|
|
127
|
+
reference_to Workflow
|
|
128
|
+
attribute :check, Switch, optional: true
|
|
129
|
+
|
|
130
|
+
sets :check
|
|
131
|
+
|
|
132
|
+
emits "WorkflowProjectionRequested"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# A verdict is given only under check. The two verdicts are separate commands, because a policy
|
|
136
|
+
# can read only an event's name, so the verdict has to be carried by the event's name.
|
|
137
|
+
command "ReportCurrent" do
|
|
138
|
+
role "CI engineer"
|
|
139
|
+
goal "Say the committed file is the projection of its rows"
|
|
140
|
+
|
|
141
|
+
reference_to Workflow
|
|
142
|
+
attribute :projected, ProjectionDigest
|
|
143
|
+
attribute :on_disk, ProjectionDigest
|
|
144
|
+
|
|
145
|
+
given("a verdict is given under check") { check.value == true }
|
|
146
|
+
given("the committed file matches its projection") { projected.value == on_disk.value }
|
|
147
|
+
|
|
148
|
+
emits "WorkflowCurrent"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
command "ReportStale" do
|
|
152
|
+
role "CI engineer"
|
|
153
|
+
goal "Report that the committed file differs from its projection, under check"
|
|
154
|
+
|
|
155
|
+
reference_to Workflow
|
|
156
|
+
attribute :projected, ProjectionDigest
|
|
157
|
+
attribute :on_disk, ProjectionDigest
|
|
158
|
+
|
|
159
|
+
given("a stale projection is reported under check") { check.value == true }
|
|
160
|
+
given("the committed file differs from its projection") { projected.value != on_disk.value }
|
|
161
|
+
|
|
162
|
+
emits "WorkflowStale"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
query "All" do
|
|
166
|
+
description "Every workflow file, by name."
|
|
167
|
+
order_by :name
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# One job as the workflow file declares it: the YAML facts the projector writes, its gate, its
|
|
172
|
+
# steps, and its shard count. A job's run in one build is a Job below, which refers back here by
|
|
173
|
+
# name. Shards: `shard_total` is the one count; every shard leg checks its index against it. A
|
|
174
|
+
# job whose total is above one gets a matrix named `shard_axis` with a leg for each number from
|
|
175
|
+
# one to the total, and its legs never cancel one another, so every leg reports its timing. A
|
|
176
|
+
# step's command may write `%{shard_total}` where the total belongs, so the count is stated once.
|
|
177
|
+
# `needs` names the jobs of the same workflow this one waits for, and `outputs` the values its
|
|
178
|
+
# steps hand to the jobs that need it. `note` is the comment above the job.
|
|
179
|
+
aggregate "JobSpec" do
|
|
180
|
+
description "One job as its workflow file declares it: runner, time limit, permissions, gate, condition, steps, and shard total."
|
|
181
|
+
|
|
182
|
+
identified_by :name
|
|
183
|
+
|
|
184
|
+
attribute :name, JobName
|
|
185
|
+
reference_to Workflow
|
|
186
|
+
attribute :runner, RunnerLabel
|
|
187
|
+
attribute :timeout_minutes, TimeoutMinutes
|
|
188
|
+
# Empty when the job takes the workflow's default permissions.
|
|
189
|
+
attribute :permissions, Permissions, optional: true
|
|
190
|
+
attribute :required, Switch
|
|
191
|
+
attribute :gate, GateName
|
|
192
|
+
# The job's `if:` as the projector writes it. Empty when the job always runs.
|
|
193
|
+
attribute :condition, Condition
|
|
194
|
+
attribute :shard_total, ShardTotal
|
|
195
|
+
attribute :shard_axis, ShardAxis, optional: true
|
|
196
|
+
attribute :shards, list_of(ShardIndex)
|
|
197
|
+
attribute :note, JobNote, optional: true
|
|
198
|
+
attribute :needs, list_of(JobName)
|
|
199
|
+
attribute :outputs, list_of(JobOutput)
|
|
200
|
+
attribute :env, list_of(EnvVar)
|
|
201
|
+
attribute :steps, list_of(Step)
|
|
202
|
+
attribute :step_inputs, list_of(StepInput)
|
|
203
|
+
|
|
204
|
+
value_object "JobName" do
|
|
205
|
+
attribute :value, String, matches: :present
|
|
206
|
+
invariant("a job is named") { !value.to_s.empty? }
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
value_object "WorkflowName" do
|
|
210
|
+
attribute :value, String, pattern: '^[a-z][a-z0-9-]*[.]yml$'
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# A runner label such as `ubuntu-latest`.
|
|
214
|
+
value_object "RunnerLabel" do
|
|
215
|
+
attribute :value, String, matches: :present
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
value_object "TimeoutMinutes" do
|
|
219
|
+
attribute :value, Integer
|
|
220
|
+
invariant("a job has a positive time limit") { value.positive? }
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# The `permissions:` block as one line, such as `contents: read`; several scopes are separated
|
|
224
|
+
# by a comma and a space, as in `contents: read, checks: read`.
|
|
225
|
+
value_object "Permissions" do
|
|
226
|
+
attribute :value, String, matches: :present
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# A gate names a path or release-only check that skips work a change cannot affect. Empty means
|
|
230
|
+
# the job is not gated.
|
|
231
|
+
value_object "GateName" do
|
|
232
|
+
attribute :value, String, default: ""
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
value_object "Condition" do
|
|
236
|
+
attribute :value, String, default: ""
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
value_object "ShardTotal" do
|
|
240
|
+
attribute :value, Integer, default: 1
|
|
241
|
+
invariant("a sharded job has at least one shard") { value.positive? }
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
value_object "ShardIndex" do
|
|
245
|
+
attribute :value, Integer
|
|
246
|
+
invariant("a shard is numbered from one") { value.positive? }
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# The matrix's name, as a step reads it: `${{ matrix.group }}` for the axis `group`.
|
|
250
|
+
value_object "ShardAxis" do
|
|
251
|
+
attribute :value, String, pattern: '^[a-z][a-z0-9_]*$'
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# The comment written above a job, one line per line of text.
|
|
255
|
+
value_object "JobNote" do
|
|
256
|
+
attribute :value, String, default: ""
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# One entry of a job's `outputs:`: the value a step hands to the jobs that need this one.
|
|
260
|
+
value_object "JobOutput" do
|
|
261
|
+
attribute :key, OutputKey
|
|
262
|
+
attribute :value, OutputValue
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
value_object "OutputKey" do
|
|
266
|
+
attribute :value, String, pattern: '^[a-z][a-z0-9_]*$'
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
value_object "OutputValue" do
|
|
270
|
+
attribute :value, String, matches: :present
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# One step of a job, in order. `name` is the step's handle within its job, which a StepInput
|
|
274
|
+
# names; it is never written into the file. `title` is the `name:` the workflow shows, `id` the
|
|
275
|
+
# `id:` other steps read outputs by, and `note` the comment above the step. `uses` names a
|
|
276
|
+
# composite action in this repo or a pinned action from outside it; `run` is one shell command.
|
|
277
|
+
# Exactly one of the two is set.
|
|
278
|
+
value_object "Step" do
|
|
279
|
+
attribute :name, StepName
|
|
280
|
+
attribute :title, StepTitle, optional: true
|
|
281
|
+
attribute :id, StepId, optional: true
|
|
282
|
+
attribute :uses, ActionRef
|
|
283
|
+
attribute :run, StepRun
|
|
284
|
+
attribute :condition, Condition
|
|
285
|
+
attribute :note, JobNote, optional: true
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
value_object "StepName" do
|
|
289
|
+
attribute :value, String, matches: :present
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
value_object "StepTitle" do
|
|
293
|
+
attribute :value, String, default: ""
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
value_object "StepId" do
|
|
297
|
+
attribute :value, String, pattern: '^[a-z][a-z0-9_-]*$'
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# The composite actions under .github/actions, and the pinned actions the workflows use. A
|
|
301
|
+
# step that runs a command names none, which is the empty member. An action is added here when a
|
|
302
|
+
# workflow first uses it.
|
|
303
|
+
value_object "ActionRef" do
|
|
304
|
+
attribute :value, String, one_of: [
|
|
305
|
+
"",
|
|
306
|
+
"./.github/actions/cargo-cache", "./.github/actions/check-attestation",
|
|
307
|
+
"./.github/actions/generated-rust",
|
|
308
|
+
"./.github/actions/ghcr-binary-cache-restore", "./.github/actions/ghcr-binary-cache-save",
|
|
309
|
+
"./.github/actions/hecks-environment", "./.github/actions/postgres",
|
|
310
|
+
"./.github/actions/require-result", "./.github/actions/rust-toolchain",
|
|
311
|
+
"./.github/actions/setup-ruby", "./.github/actions/wasm-toolchain",
|
|
312
|
+
"./.github/actions/write-attestation",
|
|
313
|
+
"actions/cache@v4", "actions/cache/restore@v4", "actions/cache/save@v4",
|
|
314
|
+
"actions/checkout@v4", "actions/download-artifact@v4", "actions/setup-node@v4",
|
|
315
|
+
"actions/upload-artifact@v4"
|
|
316
|
+
]
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
value_object "StepRun" do
|
|
320
|
+
attribute :value, String, default: ""
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
# The `with:` input of a `uses` step, keyed by the step's name.
|
|
324
|
+
value_object "StepInput" do
|
|
325
|
+
attribute :step, StepName
|
|
326
|
+
attribute :key, InputKey
|
|
327
|
+
attribute :value, InputValue
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
value_object "InputKey" do
|
|
331
|
+
attribute :value, String, matches: :present
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
value_object "InputValue" do
|
|
335
|
+
attribute :value, String, default: ""
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
# One `env:` entry of a job, such as `BUNDLE_WITHOUT` set to `development`.
|
|
339
|
+
value_object "EnvVar" do
|
|
340
|
+
attribute :key, EnvName
|
|
341
|
+
attribute :value, EnvValue
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
value_object "EnvName" do
|
|
345
|
+
attribute :value, String, pattern: '^[A-Z][A-Z0-9_]*$'
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
value_object "EnvValue" do
|
|
349
|
+
attribute :value, String, default: ""
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
value_object "Switch" do
|
|
353
|
+
attribute :value, Boolean
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
command "Declare" do
|
|
357
|
+
role "CI engineer"
|
|
358
|
+
goal "Write down one job of a workflow: its runner, time limit, permissions, gate, and shard total"
|
|
359
|
+
|
|
360
|
+
attribute :name, JobName
|
|
361
|
+
reference_to Workflow
|
|
362
|
+
attribute :runner, RunnerLabel
|
|
363
|
+
attribute :timeout_minutes, TimeoutMinutes
|
|
364
|
+
attribute :permissions, Permissions
|
|
365
|
+
attribute :required, Switch
|
|
366
|
+
attribute :gate, GateName
|
|
367
|
+
attribute :condition, Condition
|
|
368
|
+
attribute :shard_total, ShardTotal
|
|
369
|
+
|
|
370
|
+
sets :name
|
|
371
|
+
sets :workflow
|
|
372
|
+
sets :runner
|
|
373
|
+
sets :timeout_minutes
|
|
374
|
+
sets :permissions
|
|
375
|
+
sets :required
|
|
376
|
+
sets :gate
|
|
377
|
+
sets :condition
|
|
378
|
+
sets :shard_total
|
|
379
|
+
|
|
380
|
+
emits "JobSpecDeclared"
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
command "AddStep" do
|
|
384
|
+
role "CI engineer"
|
|
385
|
+
goal "Add one step to the end of a job, as a composite action or a shell command"
|
|
386
|
+
|
|
387
|
+
reference_to JobSpec
|
|
388
|
+
attribute :step_name, StepName
|
|
389
|
+
attribute :uses, ActionRef
|
|
390
|
+
attribute :run, StepRun
|
|
391
|
+
attribute :condition, Condition
|
|
392
|
+
|
|
393
|
+
given("a step either uses an action or runs a command, not both") do
|
|
394
|
+
(uses.value != "" && run.value == "") || (uses.value == "" && run.value != "")
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
sets :steps, append: { name: :step_name, uses: :uses, run: :run, condition: :condition }
|
|
398
|
+
|
|
399
|
+
emits "StepAdded"
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
command "AddEnv" do
|
|
403
|
+
role "CI engineer"
|
|
404
|
+
goal "Set one environment variable for every step of a job"
|
|
405
|
+
|
|
406
|
+
reference_to JobSpec
|
|
407
|
+
attribute :key, EnvName
|
|
408
|
+
attribute :value, EnvValue
|
|
409
|
+
|
|
410
|
+
sets :env, append: { key: :key, value: :value }
|
|
411
|
+
|
|
412
|
+
emits "EnvAdded"
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
command "AddStepInput" do
|
|
416
|
+
role "CI engineer"
|
|
417
|
+
goal "Pass one `with:` input to a step of a job"
|
|
418
|
+
|
|
419
|
+
reference_to JobSpec
|
|
420
|
+
attribute :step, StepName
|
|
421
|
+
attribute :key, InputKey
|
|
422
|
+
attribute :value, InputValue
|
|
423
|
+
|
|
424
|
+
sets :step_inputs, append: { step: :step, key: :key, value: :value }
|
|
425
|
+
|
|
426
|
+
emits "StepInputAdded"
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
# One matrix leg. Its index must be within the shard total, which is the only count the job
|
|
430
|
+
# states; the matrix size the projector writes is that same total.
|
|
431
|
+
command "PlanShard" do
|
|
432
|
+
role "CI engineer"
|
|
433
|
+
goal "Plan one shard leg of a sharded job, numbered within the shard total"
|
|
434
|
+
|
|
435
|
+
reference_to JobSpec
|
|
436
|
+
attribute :index, ShardIndex
|
|
437
|
+
|
|
438
|
+
given("a shard index is within the shard total") do
|
|
439
|
+
index.value >= 1 && index.value <= shard_total.value
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
sets :shards, append: { value: :index }
|
|
443
|
+
|
|
444
|
+
emits "ShardPlanned"
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
query "All" do
|
|
448
|
+
description "Every declared job, by name."
|
|
449
|
+
order_by :name
|
|
450
|
+
end
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
# One job's run within one build. Its identity is the job's name, because a policy's `with:` can
|
|
454
|
+
# only copy an event field or write a literal, so an edge into a named job can address it only by
|
|
455
|
+
# name; the build it belongs to is a reference. The `needs`
|
|
456
|
+
# edges are policies below; `needs_total` is the number of edges into this job, so Queue can
|
|
457
|
+
# wait for all of them. A gated job queues only when its change touches the gate, else it is skipped.
|
|
458
|
+
aggregate "Job" do
|
|
459
|
+
description "One job of one build: what it waits for, and whether it was queued, started, passed, failed, or skipped by its gate."
|
|
460
|
+
|
|
461
|
+
identified_by :name
|
|
462
|
+
|
|
463
|
+
reference_to CiRun, as: :build
|
|
464
|
+
attribute :name, JobName
|
|
465
|
+
attribute :required, Switch
|
|
466
|
+
attribute :gate, GateName
|
|
467
|
+
attribute :needs_total, Count
|
|
468
|
+
attribute :needs_settled, Count
|
|
469
|
+
attribute :seconds, JobSeconds
|
|
470
|
+
|
|
471
|
+
lifecycle :status, default: "waiting" do
|
|
472
|
+
transition "Queue" => "queued", from: "waiting"
|
|
473
|
+
transition "Start" => "running", from: "queued"
|
|
474
|
+
transition "Pass" => "passed", from: "running"
|
|
475
|
+
transition "Fail" => "failed", from: "running"
|
|
476
|
+
transition "Skip" => "skipped", from: ["waiting", "queued"]
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
value_object "BuildId" do
|
|
480
|
+
attribute :value, String, matches: :present
|
|
481
|
+
invariant("a build is identified") { !value.to_s.empty? }
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
value_object "JobName" do
|
|
485
|
+
attribute :value, String, matches: :present
|
|
486
|
+
invariant("a job is named") { !value.to_s.empty? }
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
value_object "Switch" do
|
|
490
|
+
attribute :value, Boolean
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
value_object "GateName" do
|
|
494
|
+
attribute :value, String, default: ""
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
value_object "Count" do
|
|
498
|
+
attribute :value, Integer, default: 0
|
|
499
|
+
invariant("a count is not negative") { !value.negative? }
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
value_object "JobSeconds" do
|
|
503
|
+
attribute :value, Integer, default: 0
|
|
504
|
+
invariant("a job's wall time is not negative") { !value.negative? }
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
command "Declare" do
|
|
508
|
+
role "CI engineer"
|
|
509
|
+
goal "Write down one job of a build, the edges into it, and whether a gate can skip it"
|
|
510
|
+
|
|
511
|
+
reference_to CiRun, as: :build
|
|
512
|
+
attribute :name, JobName
|
|
513
|
+
attribute :required, Switch
|
|
514
|
+
attribute :gate, GateName
|
|
515
|
+
attribute :needs_total, Count
|
|
516
|
+
|
|
517
|
+
sets :build
|
|
518
|
+
sets :name
|
|
519
|
+
sets :required
|
|
520
|
+
sets :gate
|
|
521
|
+
sets :needs_total
|
|
522
|
+
|
|
523
|
+
emits "JobDeclared"
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
# One edge into this job is met: its upstream passed, was skipped by its gate, or its corpus is
|
|
527
|
+
# ready. Refused once every edge is met, so an extra edge cannot queue the job early.
|
|
528
|
+
command "Satisfy" do
|
|
529
|
+
role "CI engineer"
|
|
530
|
+
goal "Count one edge into a job as met"
|
|
531
|
+
|
|
532
|
+
reference_to Job
|
|
533
|
+
|
|
534
|
+
given("an edge is met once") { needs_settled.value < needs_total.value }
|
|
535
|
+
|
|
536
|
+
sets :needs_settled, increment: { value: 1 }
|
|
537
|
+
|
|
538
|
+
emits "Satisfied"
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
# A job queues only once every edge into it is met. A gated job queues only when its change
|
|
542
|
+
# touches the gate; otherwise Skip is the answer.
|
|
543
|
+
command "Queue" do
|
|
544
|
+
role "CI engineer"
|
|
545
|
+
goal "Queue a job once every job it needs has passed or been skipped"
|
|
546
|
+
|
|
547
|
+
reference_to Job
|
|
548
|
+
attribute :touched, Switch
|
|
549
|
+
|
|
550
|
+
given("every need is settled first") { needs_settled.value == needs_total.value }
|
|
551
|
+
given("a gated job queues only when its change touches the gate") do
|
|
552
|
+
gate.value.empty? || touched.value
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
emits "Queued"
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
command "Start" do
|
|
559
|
+
role "CI engineer"
|
|
560
|
+
goal "Start a queued job on its runner"
|
|
561
|
+
|
|
562
|
+
reference_to Job
|
|
563
|
+
|
|
564
|
+
emits "Started"
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
command "Pass" do
|
|
568
|
+
role "CI engineer"
|
|
569
|
+
goal "Record that a job passed, with its wall time and whether it was required"
|
|
570
|
+
|
|
571
|
+
reference_to Job
|
|
572
|
+
attribute :of_job, JobName
|
|
573
|
+
attribute :was_required, Switch
|
|
574
|
+
attribute :of_build, BuildId
|
|
575
|
+
attribute :seconds, JobSeconds
|
|
576
|
+
|
|
577
|
+
given("the restated name is the job's own") { of_job.value == name.value }
|
|
578
|
+
given("the restated flag is the job's own") { was_required.value == required.value }
|
|
579
|
+
given("the restated build is the job's own") { of_build.value == build }
|
|
580
|
+
|
|
581
|
+
sets :seconds
|
|
582
|
+
|
|
583
|
+
emits "Passed"
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
command "Fail" do
|
|
587
|
+
role "CI engineer"
|
|
588
|
+
goal "Record that a job failed, with its wall time and whether it was required"
|
|
589
|
+
|
|
590
|
+
reference_to Job
|
|
591
|
+
attribute :was_required, Switch
|
|
592
|
+
attribute :of_build, BuildId
|
|
593
|
+
attribute :seconds, JobSeconds
|
|
594
|
+
|
|
595
|
+
given("the restated flag is the job's own") { was_required.value == required.value }
|
|
596
|
+
given("the restated build is the job's own") { of_build.value == build }
|
|
597
|
+
|
|
598
|
+
sets :seconds
|
|
599
|
+
|
|
600
|
+
emits "Failed"
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
# A gate skips its job only when the change does not touch what the gate guards.
|
|
604
|
+
command "Skip" do
|
|
605
|
+
role "CI engineer"
|
|
606
|
+
goal "Skip a gated job, because the change does not touch what its gate guards"
|
|
607
|
+
|
|
608
|
+
reference_to Job
|
|
609
|
+
attribute :of_job, JobName
|
|
610
|
+
attribute :was_required, Switch
|
|
611
|
+
attribute :of_build, BuildId
|
|
612
|
+
attribute :touched, Switch
|
|
613
|
+
|
|
614
|
+
given("the restated name is the job's own") { of_job.value == name.value }
|
|
615
|
+
given("the restated flag is the job's own") { was_required.value == required.value }
|
|
616
|
+
given("the restated build is the job's own") { of_build.value == build }
|
|
617
|
+
given("a gate skips its job only when the change does not touch it") do
|
|
618
|
+
!gate.value.empty? && !touched.value
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
emits "Skipped"
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
query "Waiting" do
|
|
625
|
+
description "Jobs not yet queued, by build."
|
|
626
|
+
where(status: "waiting")
|
|
627
|
+
order_by :build
|
|
628
|
+
end
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
# One CI run of one commit. It passes only when every required job has passed or been skipped by
|
|
632
|
+
# its gate, and fails when one required job fails. Required jobs are counted as they land.
|
|
633
|
+
aggregate "CiRun" do
|
|
634
|
+
description "One CI run of one commit: how many of its required jobs passed, were skipped, or failed, and whether the run passed or failed."
|
|
635
|
+
|
|
636
|
+
identified_by :build
|
|
637
|
+
|
|
638
|
+
attribute :build, BuildId
|
|
639
|
+
attribute :commit, CommitSha
|
|
640
|
+
attribute :required_total, Count
|
|
641
|
+
attribute :passed, Count
|
|
642
|
+
attribute :skipped, Count
|
|
643
|
+
attribute :failed, Count
|
|
644
|
+
|
|
645
|
+
lifecycle :status, default: "pending" do
|
|
646
|
+
transition "Start" => "running", from: "pending"
|
|
647
|
+
transition "Pass" => "passed", from: "running"
|
|
648
|
+
transition "Fail" => "failed", from: ["pending", "running"]
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
value_object "BuildId" do
|
|
652
|
+
# A GitHub run id for a CI run on GitHub, or a local run's own id.
|
|
653
|
+
attribute :value, String, matches: :present
|
|
654
|
+
invariant("a build is identified") { !value.to_s.empty? }
|
|
655
|
+
end
|
|
656
|
+
|
|
657
|
+
value_object "CommitSha" do
|
|
658
|
+
# A full or abbreviated git commit hash, lowercase hex.
|
|
659
|
+
attribute :value, String, pattern: '^[0-9a-f]{7,40}$'
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
value_object "Count" do
|
|
663
|
+
attribute :value, Integer, default: 0
|
|
664
|
+
invariant("a count is not negative") { !value.negative? }
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
value_object "Document" do
|
|
668
|
+
attribute :text, String
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
command "Open" do
|
|
672
|
+
role "CI engineer"
|
|
673
|
+
goal "Open a build of one commit, with the number of required jobs it waits for"
|
|
674
|
+
|
|
675
|
+
attribute :build, BuildId
|
|
676
|
+
attribute :commit, CommitSha
|
|
677
|
+
attribute :required_total, Count
|
|
678
|
+
|
|
679
|
+
sets :build
|
|
680
|
+
sets :commit
|
|
681
|
+
sets :required_total
|
|
682
|
+
|
|
683
|
+
emits "BuildOpened"
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
command "Start" do
|
|
687
|
+
role "CI engineer"
|
|
688
|
+
goal "Start a build's jobs running"
|
|
689
|
+
|
|
690
|
+
reference_to CiRun
|
|
691
|
+
|
|
692
|
+
emits "BuildStarted"
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
command "CountPass" do
|
|
696
|
+
role "CI engineer"
|
|
697
|
+
goal "Count one required job as passed"
|
|
698
|
+
|
|
699
|
+
reference_to CiRun
|
|
700
|
+
|
|
701
|
+
given("a pass is counted while the build runs") { status == "running" }
|
|
702
|
+
|
|
703
|
+
sets :passed, increment: { value: 1 }
|
|
704
|
+
|
|
705
|
+
emits "PassCounted"
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
command "CountSkip" do
|
|
709
|
+
role "CI engineer"
|
|
710
|
+
goal "Count one required job as skipped by its gate, which settles it"
|
|
711
|
+
|
|
712
|
+
reference_to CiRun
|
|
713
|
+
|
|
714
|
+
given("a skip is counted while the build runs") { status == "running" }
|
|
715
|
+
|
|
716
|
+
sets :skipped, increment: { value: 1 }
|
|
717
|
+
|
|
718
|
+
emits "SkipCounted"
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
command "CountFailure" do
|
|
722
|
+
role "CI engineer"
|
|
723
|
+
goal "Count one required job as failed"
|
|
724
|
+
|
|
725
|
+
reference_to CiRun
|
|
726
|
+
|
|
727
|
+
given("a failure is counted while the build runs") { status == "running" }
|
|
728
|
+
|
|
729
|
+
sets :failed, increment: { value: 1 }
|
|
730
|
+
|
|
731
|
+
emits "FailureCounted"
|
|
732
|
+
end
|
|
733
|
+
|
|
734
|
+
# Refused until every required job is settled and none failed. That refusal is the answer
|
|
735
|
+
# "not yet", and the build keeps running.
|
|
736
|
+
command "Pass" do
|
|
737
|
+
role "CI engineer"
|
|
738
|
+
goal "Mark the build passed, once every required job passed or was skipped and none failed"
|
|
739
|
+
|
|
740
|
+
reference_to CiRun
|
|
741
|
+
|
|
742
|
+
given("every required job passed or was skipped by its gate") do
|
|
743
|
+
passed.value + skipped.value == required_total.value
|
|
744
|
+
end
|
|
745
|
+
given("no required job failed") { failed.value == 0 }
|
|
746
|
+
|
|
747
|
+
emits "BuildPassed"
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
command "Fail" do
|
|
751
|
+
role "CI engineer"
|
|
752
|
+
goal "Mark the build failed, because a required job failed"
|
|
753
|
+
|
|
754
|
+
reference_to CiRun
|
|
755
|
+
|
|
756
|
+
given("a required job failed") { failed.value > 0 }
|
|
757
|
+
|
|
758
|
+
emits "BuildFailed"
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
# The answer the runner gives for one build: its jobs' wall times and conclusion. An adapter
|
|
762
|
+
# answers it; this bluebook never fetches.
|
|
763
|
+
query "Reading" do
|
|
764
|
+
description "One build as the runner reports it: each job's wall time and the conclusion. An adapter answers it; this bluebook never fetches."
|
|
765
|
+
attribute :build, BuildId
|
|
766
|
+
returns Document
|
|
767
|
+
end
|
|
768
|
+
|
|
769
|
+
# The chain of jobs, each waiting on the one before, whose wall times add up to the build's.
|
|
770
|
+
# An adapter computes it from the Job seconds and the needs policies; this bluebook only asks.
|
|
771
|
+
query "CriticalPath" do
|
|
772
|
+
description "The chain of jobs that sets a build's wall time, from Job seconds and the needs edges. An adapter answers it."
|
|
773
|
+
attribute :build, BuildId
|
|
774
|
+
returns Document
|
|
775
|
+
end
|
|
776
|
+
|
|
777
|
+
query "All" do
|
|
778
|
+
description "Every build, by build id."
|
|
779
|
+
order_by :build
|
|
780
|
+
end
|
|
781
|
+
end
|
|
782
|
+
|
|
783
|
+
# The generated Rust a build's jobs share, addressed by a key derived from its named inputs. A
|
|
784
|
+
# miss regenerates it once, and every job that needs it waits for that one regeneration.
|
|
785
|
+
aggregate "Corpus" do
|
|
786
|
+
description "The generated Rust one build shares: its cache key, whether the cache held it, and whether it was regenerated and saved."
|
|
787
|
+
|
|
788
|
+
identified_by :build
|
|
789
|
+
|
|
790
|
+
attribute :build, BuildId
|
|
791
|
+
attribute :key, CacheKey
|
|
792
|
+
|
|
793
|
+
lifecycle :status, default: "unknown" do
|
|
794
|
+
transition "Hit" => "ready", from: "unknown"
|
|
795
|
+
transition "Miss" => "missing", from: "unknown"
|
|
796
|
+
transition "Materialize" => "ready", from: "missing"
|
|
797
|
+
end
|
|
798
|
+
|
|
799
|
+
value_object "BuildId" do
|
|
800
|
+
attribute :value, String, matches: :present
|
|
801
|
+
invariant("a build is identified") { !value.to_s.empty? }
|
|
802
|
+
end
|
|
803
|
+
|
|
804
|
+
# The cache address: a hex SHA-256 of the named inputs.
|
|
805
|
+
value_object "CacheKey" do
|
|
806
|
+
attribute :value, String, pattern: '^[0-9a-f]{64}$'
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
value_object "Document" do
|
|
810
|
+
attribute :text, String
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
command "Open" do
|
|
814
|
+
role "CI engineer"
|
|
815
|
+
goal "Open the corpus a build shares, under the cache key of its inputs"
|
|
816
|
+
|
|
817
|
+
attribute :build, BuildId
|
|
818
|
+
attribute :key, CacheKey
|
|
819
|
+
|
|
820
|
+
sets :build
|
|
821
|
+
sets :key
|
|
822
|
+
|
|
823
|
+
emits "CorpusOpened"
|
|
824
|
+
end
|
|
825
|
+
|
|
826
|
+
command "Hit" do
|
|
827
|
+
role "CI engineer"
|
|
828
|
+
goal "Record that the cache held the corpus, so no job regenerates it"
|
|
829
|
+
|
|
830
|
+
reference_to Corpus
|
|
831
|
+
|
|
832
|
+
emits "Hit"
|
|
833
|
+
end
|
|
834
|
+
|
|
835
|
+
command "Miss" do
|
|
836
|
+
role "CI engineer"
|
|
837
|
+
goal "Record that the cache did not hold the corpus, so it must be regenerated"
|
|
838
|
+
|
|
839
|
+
reference_to Corpus
|
|
840
|
+
|
|
841
|
+
emits "Miss"
|
|
842
|
+
end
|
|
843
|
+
|
|
844
|
+
# Once only: a second Materialize is refused, because the corpus is already ready.
|
|
845
|
+
command "Materialize" do
|
|
846
|
+
role "CI engineer"
|
|
847
|
+
goal "Record that the corpus was regenerated, once for every job that shares it"
|
|
848
|
+
|
|
849
|
+
reference_to Corpus
|
|
850
|
+
|
|
851
|
+
emits "Materialized"
|
|
852
|
+
end
|
|
853
|
+
|
|
854
|
+
command "Save" do
|
|
855
|
+
role "CI engineer"
|
|
856
|
+
goal "Save a regenerated corpus under its key, so the next build hits"
|
|
857
|
+
|
|
858
|
+
reference_to Corpus
|
|
859
|
+
|
|
860
|
+
given("only a ready corpus is saved") { status == "ready" }
|
|
861
|
+
|
|
862
|
+
emits "Saved"
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
# The answer the cache gives for one key. An adapter answers it.
|
|
866
|
+
query "Lookup" do
|
|
867
|
+
description "Whether the cache holds the corpus for a key. An adapter answers it."
|
|
868
|
+
attribute :key, CacheKey
|
|
869
|
+
returns Document
|
|
870
|
+
end
|
|
871
|
+
end
|
|
872
|
+
|
|
873
|
+
# Edges into ci-rspec.yml's rspec_shard job. Each edge is declared once, here, and is the only
|
|
874
|
+
# source of `needs:` for that job. The attestation edge is met by a pass or by a skip.
|
|
875
|
+
policy "SatisfyRspecShardOnAttestationPassed" do
|
|
876
|
+
on "Job.Passed"
|
|
877
|
+
where { of_job.value == "ci_attestation_rspec" }
|
|
878
|
+
trigger Job::Satisfy, with: { job: "rspec_shard" }
|
|
879
|
+
end
|
|
880
|
+
|
|
881
|
+
policy "SatisfyRspecShardOnAttestationSkipped" do
|
|
882
|
+
on "Job.Skipped"
|
|
883
|
+
where { of_job.value == "ci_attestation_rspec" }
|
|
884
|
+
trigger Job::Satisfy, with: { job: "rspec_shard" }
|
|
885
|
+
end
|
|
886
|
+
|
|
887
|
+
# The corpus edge is met by a hit, or by a regeneration after a miss.
|
|
888
|
+
policy "SatisfyRspecShardOnCorpusHit" do
|
|
889
|
+
on "Corpus.Hit"
|
|
890
|
+
trigger Job::Satisfy, with: { job: "rspec_shard" }
|
|
891
|
+
end
|
|
892
|
+
|
|
893
|
+
policy "SatisfyRspecShardOnCorpusMaterialized" do
|
|
894
|
+
on "Corpus.Materialized"
|
|
895
|
+
trigger Job::Satisfy, with: { job: "rspec_shard" }
|
|
896
|
+
end
|
|
897
|
+
|
|
898
|
+
# A miss regenerates the corpus once; the jobs that share it wait on that one regeneration.
|
|
899
|
+
policy "MaterializeOnCorpusMiss" do
|
|
900
|
+
on "Corpus.Miss"
|
|
901
|
+
trigger Corpus::Materialize, with: { corpus: :build }
|
|
902
|
+
end
|
|
903
|
+
|
|
904
|
+
# Only required jobs are counted toward their build.
|
|
905
|
+
policy "CountRequiredPass" do
|
|
906
|
+
on "Job.Passed"
|
|
907
|
+
where { was_required.value }
|
|
908
|
+
trigger CiRun::CountPass, with: { build: :of_build }
|
|
909
|
+
end
|
|
910
|
+
|
|
911
|
+
policy "CountRequiredSkip" do
|
|
912
|
+
on "Job.Skipped"
|
|
913
|
+
where { was_required.value }
|
|
914
|
+
trigger CiRun::CountSkip, with: { build: :of_build }
|
|
915
|
+
end
|
|
916
|
+
|
|
917
|
+
policy "CountRequiredFailure" do
|
|
918
|
+
on "Job.Failed"
|
|
919
|
+
where { was_required.value }
|
|
920
|
+
trigger CiRun::CountFailure, with: { build: :of_build }
|
|
921
|
+
end
|
|
922
|
+
|
|
923
|
+
# Refused until every required job is settled, which is the "not yet" answer.
|
|
924
|
+
policy "PassBuildOnPassCounted" do
|
|
925
|
+
on "CiRun.PassCounted"
|
|
926
|
+
trigger CiRun::Pass, with: { build: :build }
|
|
927
|
+
end
|
|
928
|
+
|
|
929
|
+
policy "PassBuildOnSkipCounted" do
|
|
930
|
+
on "CiRun.SkipCounted"
|
|
931
|
+
trigger CiRun::Pass, with: { build: :build }
|
|
932
|
+
end
|
|
933
|
+
|
|
934
|
+
policy "FailBuildOnFailureCounted" do
|
|
935
|
+
on "CiRun.FailureCounted"
|
|
936
|
+
trigger CiRun::Fail, with: { build: :build }
|
|
937
|
+
end
|
|
938
|
+
end
|