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,80 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Bluebook
|
|
3
|
+
module DSL
|
|
4
|
+
class BluebookBuilder
|
|
5
|
+
# Groups a bluebook's aggregates in the modules it declares (ADR 0163). `domain_module
|
|
6
|
+
# "Deliver" do … end` opens a block whose `aggregate` words are recorded under the module;
|
|
7
|
+
# the module changes no aggregate, it names the task each one belongs to. Policies, read
|
|
8
|
+
# models and process managers inside the block are the bluebook's own, as they are outside it.
|
|
9
|
+
module Modules
|
|
10
|
+
# Opens the module `name` and evaluates its body; a module of that name that an earlier
|
|
11
|
+
# file opened gains the aggregates this body declares.
|
|
12
|
+
#
|
|
13
|
+
# @param name [String] the module's own name, such as `"Deliver"`
|
|
14
|
+
# @yield the module body: its vision, aggregates, policies, read models and process managers
|
|
15
|
+
# @return [Array<Bluebook::Declaration::ModuleRow>] every membership declared so far
|
|
16
|
+
# @raise [Bluebook::DSL::Malformed] if a module opens inside another, or holds no aggregate
|
|
17
|
+
def domain_module(name, &)
|
|
18
|
+
refuse_nested_module!(name)
|
|
19
|
+
@open_module = name.to_s
|
|
20
|
+
instance_eval(&) if block_given?
|
|
21
|
+
refuse_empty_module!(@open_module)
|
|
22
|
+
module_rows
|
|
23
|
+
ensure
|
|
24
|
+
@open_module = nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
# One row per aggregate a module groups, in declaration order, each carrying its module's
|
|
30
|
+
# vision (empty when the module names none).
|
|
31
|
+
def module_rows
|
|
32
|
+
module_members.map do |name, aggregate|
|
|
33
|
+
Declaration::ModuleRow.new(name: name, vision: module_visions[name].to_s, aggregate: aggregate)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Each `[module, aggregate]` pair declared so far, in declaration order.
|
|
38
|
+
def module_members = @module_members ||= []
|
|
39
|
+
|
|
40
|
+
# Each module's vision by its name, for the modules that declared one.
|
|
41
|
+
def module_visions = @module_visions ||= {}
|
|
42
|
+
|
|
43
|
+
# Records an aggregate under the open module, if one is open.
|
|
44
|
+
def note_in_open_module(name)
|
|
45
|
+
module_members << [@open_module, name.to_s] if @open_module
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Records the open module's vision.
|
|
49
|
+
def module_vision(value)
|
|
50
|
+
held = module_visions[@open_module]
|
|
51
|
+
raise Malformed, "domain_module #{@open_module.inspect} declares two visions" if held && held != value
|
|
52
|
+
|
|
53
|
+
module_visions[@open_module] = value
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Refuses a bluebook-wide word written inside a module block.
|
|
57
|
+
def bluebook_wide!(word)
|
|
58
|
+
return unless @open_module
|
|
59
|
+
|
|
60
|
+
raise Malformed, "#{word} describes the whole bluebook, so it cannot sit inside " \
|
|
61
|
+
"domain_module #{@open_module.inspect}"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def refuse_nested_module!(name)
|
|
65
|
+
return unless @open_module
|
|
66
|
+
|
|
67
|
+
raise Malformed, "domain_module #{name.inspect} sits inside domain_module " \
|
|
68
|
+
"#{@open_module.inspect}; modules do not nest"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def refuse_empty_module!(name)
|
|
72
|
+
return if module_members.any? { |held, _| held == name }
|
|
73
|
+
|
|
74
|
+
raise Malformed, "domain_module #{name.inspect} holds no aggregate"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -8,6 +8,57 @@ module Hecks
|
|
|
8
8
|
module CorrelationKeys
|
|
9
9
|
private
|
|
10
10
|
|
|
11
|
+
# A bare name (`correlates_by Message`) naming an aggregate of this bluebook means
|
|
12
|
+
# that aggregate's identity, `"Message.id"`. Any other bare name is refused here,
|
|
13
|
+
# with the message the builder used to give. Runs before the other correlation
|
|
14
|
+
# checks, so they only ever see the dotted form.
|
|
15
|
+
def resolve_bare_correlation_keys!(bluebook)
|
|
16
|
+
bluebook.process_managers.each do |process_manager|
|
|
17
|
+
key = process_manager.correlates_by.to_s
|
|
18
|
+
next if bare_correlation_key?(key)
|
|
19
|
+
|
|
20
|
+
resolve_bare_correlation_key!(bluebook, process_manager, key)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def bare_correlation_key?(key)
|
|
25
|
+
key.empty? || key.include?(".")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def resolve_bare_correlation_key!(bluebook, process_manager, key)
|
|
29
|
+
aggregate = find_correlated_aggregate(bluebook, key)
|
|
30
|
+
unless aggregate
|
|
31
|
+
raise ProcessManagerBuilder::InvalidProcessManager,
|
|
32
|
+
bare_correlation_message(process_manager.name, key)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
path = identity_path(process_manager, aggregate)
|
|
36
|
+
process_manager.correlate_by!("#{aggregate.name}.#{path}")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# The refusal for a bare name that does not name an aggregate of the bluebook.
|
|
40
|
+
def bare_correlation_message(name, key)
|
|
41
|
+
"#{name} correlates_by #{key}, which names a whole field rather than one of its scalars " \
|
|
42
|
+
"— say which one, e.g. #{key}.value (or name an aggregate of this bluebook, " \
|
|
43
|
+
"which correlates by its identity)"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def find_correlated_aggregate(bluebook, key)
|
|
47
|
+
bluebook.aggregates.find { |candidate| candidate.name.to_s == Naming.demodulise(key) }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# The one field an aggregate is correlated by: its identity, or `id` when it declares none.
|
|
51
|
+
# A value-object identity drops its trailing `.value`, so `Thing` reads as `Thing.id`.
|
|
52
|
+
def identity_path(process_manager, aggregate)
|
|
53
|
+
paths = aggregate.identity_paths.map(&:to_s)
|
|
54
|
+
return "id" if paths.empty?
|
|
55
|
+
return paths.first.delete_suffix(".value") if paths.one?
|
|
56
|
+
|
|
57
|
+
raise ProcessManagerBuilder::InvalidProcessManager,
|
|
58
|
+
"#{process_manager.name} correlates_by #{aggregate.name}, but #{aggregate.name} has a " \
|
|
59
|
+
"composite identity — name the one field, e.g. #{aggregate.name}.#{paths.first}"
|
|
60
|
+
end
|
|
61
|
+
|
|
11
62
|
# `correlates_by` must land on a scalar: the dotted path is walked against each
|
|
12
63
|
# command that emits an event the process manager reacts to. A command lacking the
|
|
13
64
|
# first segment is skipped, since correlation has fallback tiers
|
|
@@ -35,6 +35,7 @@ module Hecks
|
|
|
35
35
|
# @raise [Bluebook::DSL::ProcessManagerBuilder::InvalidProcessManager] if a
|
|
36
36
|
# `correlates_by` resolves to something other than a scalar field
|
|
37
37
|
def validate_assembled!(bluebook)
|
|
38
|
+
resolve_bare_correlation_keys!(bluebook)
|
|
38
39
|
validate_not_the_gem_module!(bluebook)
|
|
39
40
|
validate_declarations!(bluebook)
|
|
40
41
|
validate_owner_stamped!(bluebook)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
require_relative "word_gate"
|
|
2
2
|
require_relative "bluebook_builder/validation"
|
|
3
3
|
require_relative "bluebook_builder/pending_givens"
|
|
4
|
+
require_relative "bluebook_builder/modules"
|
|
5
|
+
require_relative "bluebook_builder/metadata"
|
|
4
6
|
module Hecks
|
|
5
7
|
module Bluebook
|
|
6
8
|
module DSL
|
|
@@ -10,6 +12,8 @@ module Hecks
|
|
|
10
12
|
GRAMMAR_CONTEXT = "Bluebook".freeze
|
|
11
13
|
|
|
12
14
|
include WordGate
|
|
15
|
+
include Modules
|
|
16
|
+
include Metadata
|
|
13
17
|
extend Validation
|
|
14
18
|
|
|
15
19
|
attr_reader :classification
|
|
@@ -56,23 +60,11 @@ module Hecks
|
|
|
56
60
|
# @param value [String] the vision text, as given to `vision "..."`
|
|
57
61
|
# @return [void]
|
|
58
62
|
def vision(value)
|
|
63
|
+
return module_vision(value) if @open_module
|
|
64
|
+
|
|
59
65
|
@vision = value
|
|
60
66
|
end
|
|
61
67
|
|
|
62
|
-
# Records the bluebook's earlier name, so the storage layer recognizes its history
|
|
63
|
-
# under it instead of minting a new lineage — a bluebook's identity can change.
|
|
64
|
-
#
|
|
65
|
-
# @param value [String, Symbol] the bluebook's earlier name
|
|
66
|
-
# @return [String] `value`, stringified, as stored
|
|
67
|
-
def formerly_known_as(value) = @formerly_known_as = value.to_s
|
|
68
|
-
|
|
69
|
-
# Names the Ruby module the bluebook's constants install under instead of its own name,
|
|
70
|
-
# such as `namespace "Hecks::Domain"` for a bluebook that would otherwise collide.
|
|
71
|
-
#
|
|
72
|
-
# @param value [String] a constant path, such as `"Hecks::Domain"`
|
|
73
|
-
# @return [String] `value`, stringified, as stored
|
|
74
|
-
def namespace(value) = @namespace = value.to_s
|
|
75
|
-
|
|
76
68
|
# Names a core grammar context this bluebook's sub-language extends (ADR 0026).
|
|
77
69
|
# Variadic and accumulates across calls, like `identified_by`/`group_by`.
|
|
78
70
|
#
|
|
@@ -82,7 +74,10 @@ module Hecks
|
|
|
82
74
|
# @param contexts [Array<String>] one or more core grammar context names, such as
|
|
83
75
|
# `"Query"`/`"ReadModel"`
|
|
84
76
|
# @return [Array<String>] every context named so far, this call's included
|
|
85
|
-
def attaches_to_impl(*contexts)
|
|
77
|
+
def attaches_to_impl(*contexts)
|
|
78
|
+
bluebook_wide!(:attaches_to)
|
|
79
|
+
(@attaches_to ||= []).concat(contexts.map(&:to_s))
|
|
80
|
+
end
|
|
86
81
|
|
|
87
82
|
# Records a capability this bluebook answers for other domains, one row per key —
|
|
88
83
|
# checked once the bluebook is whole, since verbs may be declared later in the file.
|
|
@@ -94,6 +89,7 @@ module Hecks
|
|
|
94
89
|
# this capability's included
|
|
95
90
|
# @raise [Bluebook::DSL::Malformed] if `verbs` is empty
|
|
96
91
|
def provides_impl(capability, **verbs)
|
|
92
|
+
bluebook_wide!(:provides)
|
|
97
93
|
if verbs.empty?
|
|
98
94
|
raise Malformed, "#{@name}'s provides #{capability.inspect} names no verb — say which of this " \
|
|
99
95
|
"bluebook's commands and queries answer it"
|
|
@@ -103,22 +99,6 @@ module Hecks
|
|
|
103
99
|
(@provides ||= []).concat(rows)
|
|
104
100
|
end
|
|
105
101
|
|
|
106
|
-
# Classifies this bluebook as core to the framework, rather than a domain built on it.
|
|
107
|
-
#
|
|
108
|
-
# @return [Symbol] `:core`
|
|
109
|
-
def core = @classification = :core
|
|
110
|
-
|
|
111
|
-
# Classifies this bluebook as a supporting piece of the framework, rather than a domain
|
|
112
|
-
# built on it.
|
|
113
|
-
#
|
|
114
|
-
# @return [Symbol] `:supporting`
|
|
115
|
-
def supporting = @classification = :supporting
|
|
116
|
-
|
|
117
|
-
# Classifies this bluebook as generic infrastructure, rather than a domain built on it.
|
|
118
|
-
#
|
|
119
|
-
# @return [Symbol] `:generic`
|
|
120
|
-
def generic = @classification = :generic
|
|
121
|
-
|
|
122
102
|
# Declares an aggregate belonging to this bluebook. `@bluebook_named_givens` is
|
|
123
103
|
# threaded into it — see `AggregateBuilder#given` for the sharing this enables.
|
|
124
104
|
#
|
|
@@ -126,15 +106,18 @@ module Hecks
|
|
|
126
106
|
# named in `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`.
|
|
127
107
|
#
|
|
128
108
|
# @param name [String] the aggregate's own name
|
|
109
|
+
# @param kind [String, nil] the kind whose text the aggregate's body is evaluated within
|
|
129
110
|
# @yield the aggregate body, evaluated against a new `AggregateBuilder`; may be omitted
|
|
130
111
|
# @return [Array<Bluebook::Aggregate>] every aggregate declared so far, this one last
|
|
131
112
|
# @raise [Bluebook::DSL::Malformed] if the aggregate's own body fails any check
|
|
132
113
|
# `AggregateBuilder#build` raises
|
|
133
|
-
def aggregate_impl(name, &)
|
|
114
|
+
def aggregate_impl(name, kind: nil, &body)
|
|
115
|
+
note_in_open_module(name)
|
|
134
116
|
@aggregates << AggregateBuilder.build(name, bluebook_named_givens: @bluebook_named_givens,
|
|
135
117
|
bluebook_pending_givens: @bluebook_pending_givens,
|
|
136
118
|
bluebook_entity_named_givens: @bluebook_entity_named_givens,
|
|
137
|
-
bluebook_entity_pending_givens: @bluebook_entity_pending_givens,
|
|
119
|
+
bluebook_entity_pending_givens: @bluebook_entity_pending_givens,
|
|
120
|
+
&Kinds.wrap(name, kind, &body))
|
|
138
121
|
end
|
|
139
122
|
|
|
140
123
|
# Declares a read model belonging to this bluebook.
|
|
@@ -257,7 +240,7 @@ module Hecks
|
|
|
257
240
|
{ aggregates: @aggregates, read_models: @read_models,
|
|
258
241
|
policies: @aggregates.flat_map(&:policies) + @policies,
|
|
259
242
|
process_managers: @process_managers,
|
|
260
|
-
attaches_to: @attaches_to || [], provides: @provides || [] }
|
|
243
|
+
attaches_to: @attaches_to || [], provides: @provides || [], modules: module_rows }
|
|
261
244
|
end
|
|
262
245
|
end
|
|
263
246
|
end
|
|
@@ -15,6 +15,8 @@ module Hecks
|
|
|
15
15
|
# [context, word] => the method a word's whole call forwards to.
|
|
16
16
|
CALLS = {
|
|
17
17
|
["Aggregate", "provenance"] => :provenance_impl,
|
|
18
|
+
["Aggregate", "formerly_known_as"] => :formerly_known_as_impl,
|
|
19
|
+
["Aggregate", "created_by"] => :created_by_impl,
|
|
18
20
|
["Aggregate", "identified_by"] => :identified_by_impl,
|
|
19
21
|
["Aggregate", "reference_to"] => :reference_to_impl,
|
|
20
22
|
["Aggregate", "has_many"] => :has_many_impl,
|
|
@@ -36,8 +38,10 @@ module Hecks
|
|
|
36
38
|
["Bluebook", "provides"] => :provides_impl,
|
|
37
39
|
["Bluebook", "aggregate"] => :aggregate_impl,
|
|
38
40
|
["Command", "role"] => :role_impl,
|
|
41
|
+
["Command", "audience"] => :audience_impl,
|
|
39
42
|
["Command", "provenance"] => :provenance_impl,
|
|
40
43
|
["Command", "idempotent"] => :idempotent_impl,
|
|
44
|
+
["Command", "mints_era"] => :mints_era_impl,
|
|
41
45
|
["Command", "reference_to"] => :reference_to_impl,
|
|
42
46
|
["Command", "given"] => :given_impl,
|
|
43
47
|
["Command", "sets"] => :sets_impl,
|
|
@@ -62,8 +66,10 @@ module Hecks
|
|
|
62
66
|
["Policy", "trigger"] => :trigger_impl,
|
|
63
67
|
["Policy", "ask"] => :ask_impl,
|
|
64
68
|
["Policy", "across"] => :across_impl,
|
|
69
|
+
["ProcessManager", "correlates_by"] => :correlates_by_impl,
|
|
65
70
|
["ProcessManager", "starts_on"] => :starts_on_impl,
|
|
66
71
|
["ProcessManager", "ends_on"] => :ends_on_impl,
|
|
72
|
+
["ProcessManager", "resumes"] => :resumes_impl,
|
|
67
73
|
["ProcessManager", "transition"] => :transition_impl,
|
|
68
74
|
["Handler", "dispatch"] => :dispatch_impl,
|
|
69
75
|
["Dispatch", "compensates"] => :compensates_impl,
|
|
@@ -98,8 +104,10 @@ module Hecks
|
|
|
98
104
|
["Hecksagon", "port"] => :port_impl,
|
|
99
105
|
["PortOperation", "reference_to"] => :reference_to_impl,
|
|
100
106
|
["PortOperation", "attribute"] => :attribute_impl,
|
|
107
|
+
["PortOperation", "handles"] => :handles_impl,
|
|
101
108
|
["Translation", "aggregate"] => :aggregate_impl,
|
|
102
109
|
["TranslationAggregate", "rename"] => :rename_impl,
|
|
110
|
+
["TranslationAggregate", "split"] => :split_impl,
|
|
103
111
|
["TranslationAggregate", "move"] => :move_impl,
|
|
104
112
|
["TranslationAggregate", "convert"] => :convert_impl,
|
|
105
113
|
["TranslationAggregate", "retype"] => :retype_impl,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative "word_gate"
|
|
2
2
|
require_relative "need_word"
|
|
3
|
+
require_relative "audience_word"
|
|
3
4
|
require_relative "command_builder/owner"
|
|
4
5
|
require_relative "command_builder/rules"
|
|
5
6
|
require_relative "command_builder/mutations"
|
|
@@ -22,6 +23,7 @@ module Hecks
|
|
|
22
23
|
include RuleReference
|
|
23
24
|
include WordGate
|
|
24
25
|
include NeedWord
|
|
26
|
+
include AudienceWord
|
|
25
27
|
include ImplicitAttributes
|
|
26
28
|
include Operands
|
|
27
29
|
include FoldedSets
|
|
@@ -82,6 +84,14 @@ module Hecks
|
|
|
82
84
|
# @return [true]
|
|
83
85
|
def idempotent_impl = @idempotent = true
|
|
84
86
|
|
|
87
|
+
# Declares that this command's own record may be written through a boot whose shape no era
|
|
88
|
+
# holds yet, so the command that mints the held era can persist its request. Every other
|
|
89
|
+
# write from such a boot stays refused.
|
|
90
|
+
#
|
|
91
|
+
# @param value [Boolean] `true` to allow the write; any other value declares nothing
|
|
92
|
+
# @return [Boolean] the flag as stored
|
|
93
|
+
def mints_era_impl(value) = @mints_era = value == true
|
|
94
|
+
|
|
85
95
|
# Declares the aggregate this command acts on (with no `as:`), or a cross-reference to
|
|
86
96
|
# another aggregate (with `as:`).
|
|
87
97
|
#
|
|
@@ -203,13 +213,13 @@ module Hecks
|
|
|
203
213
|
end
|
|
204
214
|
|
|
205
215
|
def declared_rules
|
|
206
|
-
{ name: @name, role: @role, roles: @roles || [],
|
|
207
|
-
ensures: @ensures, needs: @needs }
|
|
216
|
+
{ name: @name, role: @role, roles: @roles || [], audience: @audience || [], goal: @goal,
|
|
217
|
+
attributes: attributes, givens: @givens, ensures: @ensures, needs: @needs }
|
|
208
218
|
end
|
|
209
219
|
|
|
210
220
|
def declared_effects
|
|
211
221
|
{ mutations: @mutations, emits: @emits, references: @references, from: @from,
|
|
212
|
-
provenance: @provenance, idempotent: @idempotent || false }
|
|
222
|
+
provenance: @provenance, idempotent: @idempotent || false, mints_era: @mints_era || false }
|
|
213
223
|
end
|
|
214
224
|
end
|
|
215
225
|
end
|
|
@@ -51,7 +51,6 @@ module Hecks
|
|
|
51
51
|
|
|
52
52
|
# `has_many_impl`/`has_one_impl` are DSL keywords (`has_many`/`has_one` in a bluebook),
|
|
53
53
|
# not real predicates, so Naming/PredicatePrefix does not apply here.
|
|
54
|
-
# rubocop:disable Naming/PredicatePrefix
|
|
55
54
|
# Declares a list-typed relationship to another entity, referenced by its plural name.
|
|
56
55
|
def has_many_impl(type, as: nil, **options)
|
|
57
56
|
unless options.empty?
|
|
@@ -69,7 +68,6 @@ module Hecks
|
|
|
69
68
|
target = Naming.demodulise(type)
|
|
70
69
|
relationship_attribute(target, :has_one, as || Naming.snake(target).to_sym, optional: optional)
|
|
71
70
|
end
|
|
72
|
-
# rubocop:enable Naming/PredicatePrefix
|
|
73
71
|
|
|
74
72
|
# Declares a single-valued relationship to the entity that owns this one.
|
|
75
73
|
def belongs_to_impl(type, as: nil, optional: false)
|
|
@@ -10,6 +10,9 @@ module Hecks
|
|
|
10
10
|
|
|
11
11
|
COERCE_BY_KIND = { "text" => :to_s, "symbol" => :to_sym }.freeze
|
|
12
12
|
|
|
13
|
+
# The arguments of one word call: its positional arguments, its keyword arguments, and its block.
|
|
14
|
+
Invocation = Struct.new(:args, :kwargs, :block)
|
|
15
|
+
|
|
13
16
|
# Not derivable from `fills:` (these rows all carry `fills: ""`) — the append target
|
|
14
17
|
# for each opens-block word must be named here explicitly.
|
|
15
18
|
SAFE_OPENS_BLOCK = {
|
|
@@ -31,13 +34,12 @@ module Hecks
|
|
|
31
34
|
|
|
32
35
|
# Executes a table-admitted word via the shape `shape_for` found for it, or returns
|
|
33
36
|
# NOT_HANDLED so the caller can fall back to its own "not yet implemented" refusal.
|
|
34
|
-
# The
|
|
35
|
-
|
|
36
|
-
def try(builder, context, word, args, kwargs, block, rows)
|
|
37
|
+
# The call's arguments travel together as an `Invocation`, which keeps the signature short.
|
|
38
|
+
def try(builder, context, word, invocation, rows)
|
|
37
39
|
shape = shape_for(context, word, rows)
|
|
38
40
|
return NOT_HANDLED unless shape
|
|
39
41
|
|
|
40
|
-
run_shape(shape, builder, args, kwargs, block)
|
|
42
|
+
run_shape(shape, builder, invocation.args, invocation.kwargs, invocation.block)
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
# Runs the dispatcher the shape's kind names.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Bluebook
|
|
3
|
+
module DSL
|
|
4
|
+
# The aggregate kinds: `aggregate "GateRun", kind: "Run"` evaluates the kind's own text,
|
|
5
|
+
# written in the bluebook's words, around the aggregate's body. A kind is data, the file
|
|
6
|
+
# `lib/hecks/language/kinds/<kind>.kind`, not code: `{Name}` in it stands for the aggregate's
|
|
7
|
+
# name and `{Stem}` for that name without the kind, and a `# body` line marks where the
|
|
8
|
+
# aggregate's own body is evaluated.
|
|
9
|
+
module Kinds
|
|
10
|
+
DIRECTORY = File.expand_path("../../language/kinds", __dir__).freeze
|
|
11
|
+
BODY_MARK = /^# body\n/
|
|
12
|
+
|
|
13
|
+
module_function
|
|
14
|
+
|
|
15
|
+
# The block an aggregate is built from: its own body, or, for a kind, that body inside the
|
|
16
|
+
# kind's text.
|
|
17
|
+
#
|
|
18
|
+
# @param name [String] the aggregate's name
|
|
19
|
+
# @param kind [String, nil] the kind written after `kind:`, if any
|
|
20
|
+
# @yield the aggregate's own body; may be omitted
|
|
21
|
+
# @return [Proc, nil] the block to evaluate on the aggregate's builder
|
|
22
|
+
# @raise [Malformed] if the kind has no file
|
|
23
|
+
def wrap(name, kind, &body)
|
|
24
|
+
return body unless kind
|
|
25
|
+
|
|
26
|
+
before, after = halves(kind, name)
|
|
27
|
+
file = path(kind)
|
|
28
|
+
proc do
|
|
29
|
+
instance_eval(before, file, 1)
|
|
30
|
+
instance_eval(&body) if body
|
|
31
|
+
instance_eval(after, file, before.lines.size + 2)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @return [Array(String, String)] the kind's text, names filled in, split at the body
|
|
36
|
+
def halves(kind, name)
|
|
37
|
+
before, after = File.read(path(kind)).split(BODY_MARK, 2)
|
|
38
|
+
[before, after].map { |text| fill(text, name, kind) }
|
|
39
|
+
rescue Errno::ENOENT
|
|
40
|
+
raise Malformed, "#{name} declares kind #{kind.inspect}, which has no file at #{path(kind)}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @return [String] the kind's text with `{Name}` and `{Stem}` replaced
|
|
44
|
+
def fill(text, name, kind)
|
|
45
|
+
text.gsub("{Name}", name.to_s).gsub("{Stem}", name.to_s.delete_suffix(kind.to_s))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @return [String] the file that holds a kind
|
|
49
|
+
def path(kind) = File.join(DIRECTORY, "#{kind.to_s.downcase}.kind")
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -25,6 +25,7 @@ module Hecks
|
|
|
25
25
|
@owner = owner
|
|
26
26
|
@direction = direction
|
|
27
27
|
@emits = []
|
|
28
|
+
@handles = []
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
# Refuses `reference_to` inside an operation body; a port operation has no self-reference
|
|
@@ -47,6 +48,12 @@ module Hecks
|
|
|
47
48
|
# Names one event an inbound operation records once the external fact has arrived.
|
|
48
49
|
def emits(event_name) = @emits << event_name.to_s
|
|
49
50
|
|
|
51
|
+
# Names one value of a command this operation handles, e.g. `handles "Build.build!",
|
|
52
|
+
# value: "wasm"`. Recorded in the IR only; nothing routes on it yet.
|
|
53
|
+
def handles_impl(command, value:)
|
|
54
|
+
@handles << { command: command.to_s, value: value.to_s }
|
|
55
|
+
end
|
|
56
|
+
|
|
50
57
|
# `answers`/`refuses`, the two halves of an `asks` — separate words rather than two
|
|
51
58
|
# `emits` so a reader can tell what came back from what the outside refused, without
|
|
52
59
|
# reading the adapter.
|
|
@@ -64,7 +71,8 @@ module Hecks
|
|
|
64
71
|
|
|
65
72
|
PortOperation.new(
|
|
66
73
|
name: @name, attributes: attributes, emits: @emits,
|
|
67
|
-
direction: @direction, answers: @answers, refuses: @refuses, to: @to
|
|
74
|
+
direction: @direction, answers: @answers, refuses: @refuses, to: @to,
|
|
75
|
+
handles: @handles
|
|
68
76
|
)
|
|
69
77
|
end
|
|
70
78
|
|
|
@@ -116,7 +124,6 @@ module Hecks
|
|
|
116
124
|
|
|
117
125
|
# Evaluates one operation block against a fresh builder and returns what it built;
|
|
118
126
|
# `private` above doesn't reach this singleton method, since `.build` is the real entry.
|
|
119
|
-
# rubocop:disable-next Lint/IneffectiveAccessModifier
|
|
120
127
|
def self.build(name, to: nil, owner: nil, direction: :inbound, &block)
|
|
121
128
|
builder = new(name, to: to, owner: owner, direction: direction)
|
|
122
129
|
builder.instance_eval(&block) if block
|
|
@@ -17,6 +17,15 @@ module Hecks
|
|
|
17
17
|
@handlers = []
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# Records the key that ties one instance's events together. A dotted path or symbol is
|
|
21
|
+
# kept as written; a bare aggregate name (`correlates_by Message`) is kept as its bare
|
|
22
|
+
# name, which `BluebookBuilder` resolves to `"Message.<identity>"` once every aggregate
|
|
23
|
+
# is known.
|
|
24
|
+
#
|
|
25
|
+
# @param key [Symbol, String, Module] the dotted path, or a bare aggregate name
|
|
26
|
+
# @return [void]
|
|
27
|
+
def correlates_by_impl(key) = @correlates_by = key
|
|
28
|
+
|
|
20
29
|
# Records the event that begins a fresh instance of this process manager.
|
|
21
30
|
#
|
|
22
31
|
# `starts_on Transfer::TransferRequested`: a bare constant, stored as the bare event
|
|
@@ -35,9 +44,14 @@ module Hecks
|
|
|
35
44
|
# @param event_ref [Symbol, String, Module] the event, as a bare constant (a
|
|
36
45
|
# `ScopedConstant` module `ConstShim` resolves) or quoted text
|
|
37
46
|
# @return [void]
|
|
38
|
-
def ends_on_impl(event_ref)
|
|
39
|
-
|
|
40
|
-
|
|
47
|
+
def ends_on_impl(event_ref) = (@endings ||= []) << Naming.event_name_ref(event_ref)
|
|
48
|
+
|
|
49
|
+
# Records the command that resumes one stage, written `stage=command`, as the stage
|
|
50
|
+
# map a resume reads. The runtime does not read it yet.
|
|
51
|
+
#
|
|
52
|
+
# @param entry [String] one `stage=command` pair, for example `"gated=GateRun.Gate"`
|
|
53
|
+
# @return [void]
|
|
54
|
+
def resumes_impl(entry) = (@resumes ||= []) << entry.to_s
|
|
41
55
|
|
|
42
56
|
# Records one leg of the state machine: the event that takes it, the state(s) it
|
|
43
57
|
# applies from, and the dispatches (with optional compensations) it fires.
|
|
@@ -81,7 +95,8 @@ module Hecks
|
|
|
81
95
|
name: @name,
|
|
82
96
|
correlates_by: @correlates_by,
|
|
83
97
|
starts_on: @starts_on,
|
|
84
|
-
ends_on: @
|
|
98
|
+
ends_on: @endings&.first,
|
|
99
|
+
endings: @endings || [], resumes: @resumes || [],
|
|
85
100
|
states: derived_states,
|
|
86
101
|
handlers: @handlers
|
|
87
102
|
)
|
|
@@ -148,19 +163,14 @@ module Hecks
|
|
|
148
163
|
refuse_ambiguous_legs!
|
|
149
164
|
end
|
|
150
165
|
|
|
166
|
+
# A bare name is not checked here: it may name an aggregate, which only the bluebook
|
|
167
|
+
# can see. `BluebookBuilder` resolves it to `"<Aggregate>.<identity>"`, or refuses it
|
|
168
|
+
# with `bare_correlation_message`. A dotted path is a scalar by its spelling.
|
|
151
169
|
def refuse_bad_correlation!
|
|
152
|
-
|
|
153
|
-
raise InvalidProcessManager, "#{@name} declares no correlates_by — " \
|
|
154
|
-
"nothing would tie its events to one instance"
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
# Names a scalar (`:"end_to_end.value"`), never a whole field or value object.
|
|
158
|
-
# A syntactic check: the dotted spelling leaves no question about the key's type.
|
|
159
|
-
return if @correlates_by.to_s.include?(".")
|
|
170
|
+
return if @correlates_by
|
|
160
171
|
|
|
161
|
-
raise InvalidProcessManager, "#{@name}
|
|
162
|
-
"
|
|
163
|
-
"#{@correlates_by}.value"
|
|
172
|
+
raise InvalidProcessManager, "#{@name} declares no correlates_by — " \
|
|
173
|
+
"nothing would tie its events to one instance"
|
|
164
174
|
end
|
|
165
175
|
|
|
166
176
|
# A leg is selected by (event, current state), so two legs on the same pair would
|
|
@@ -121,6 +121,20 @@ module Hecks
|
|
|
121
121
|
# `method_missing`/`respond_to_missing?` (via the included `WordGate`) give a
|
|
122
122
|
# table-driven refusal naming the legal words, rather than a hand-typed list.
|
|
123
123
|
|
|
124
|
+
# ADR 0166: writes rows into `into` from this aggregate's rows, keyed by `keyed_by`.
|
|
125
|
+
#
|
|
126
|
+
# @param into [String, Symbol] the aggregate that receives the rows
|
|
127
|
+
# @param keyed_by [Symbol] the field both aggregates carry, which the target identifies by
|
|
128
|
+
# @param fields [Array<Symbol>] the fields copied into the target
|
|
129
|
+
# @raise [Bluebook::DSL::Malformed] if any of the three is missing or empty
|
|
130
|
+
def split_impl(into: nil, keyed_by: nil, fields: nil)
|
|
131
|
+
raise Malformed, "a split needs a target aggregate (into:)" if into.to_s.empty?
|
|
132
|
+
raise Malformed, "a split needs a key field (keyed_by:)" if keyed_by.to_s.empty?
|
|
133
|
+
raise Malformed, "a split needs at least one field (fields:)" if Array(fields).empty?
|
|
134
|
+
|
|
135
|
+
@splits << TranslationSplit.new(into.to_s, keyed_by.to_sym, Array(fields).map(&:to_sym))
|
|
136
|
+
end
|
|
137
|
+
|
|
124
138
|
# Assembles the declared rules into a `TranslationAggregate`.
|
|
125
139
|
#
|
|
126
140
|
# @return [Bluebook::TranslationAggregate] the built per-aggregate translation
|
|
@@ -128,7 +142,7 @@ module Hecks
|
|
|
128
142
|
TranslationAggregate.new(
|
|
129
143
|
name: @name, was: @was, renames: @renames, moves: @moves, converts: @converts,
|
|
130
144
|
drops: @drops, retypes: @retypes, derives: @derives, rekeys: @rekeys,
|
|
131
|
-
backfills: @backfills
|
|
145
|
+
backfills: @backfills, splits: @splits
|
|
132
146
|
)
|
|
133
147
|
end
|
|
134
148
|
|
|
@@ -142,6 +156,7 @@ module Hecks
|
|
|
142
156
|
@retypes = []
|
|
143
157
|
@derives = []
|
|
144
158
|
@rekeys = []
|
|
159
|
+
@splits = []
|
|
145
160
|
@backfills = []
|
|
146
161
|
end
|
|
147
162
|
|
|
@@ -72,7 +72,7 @@ module Hecks
|
|
|
72
72
|
|
|
73
73
|
refuse_unadmitted_word!(keywords, context, word) if admitted.empty?
|
|
74
74
|
|
|
75
|
-
dispatched = GenericDispatch.try(self, context, word.to_s, args, kwargs, block, rows)
|
|
75
|
+
dispatched = GenericDispatch.try(self, context, word.to_s, GenericDispatch::Invocation.new(args, kwargs, block), rows)
|
|
76
76
|
return dispatched unless dispatched.equal?(GenericDispatch::NOT_HANDLED)
|
|
77
77
|
|
|
78
78
|
raise Malformed,
|
data/lib/hecks/bluebook/dsl.rb
CHANGED
|
@@ -25,6 +25,7 @@ require_relative "dsl/attribute_collector"
|
|
|
25
25
|
require_relative "dsl/identity_declaration"
|
|
26
26
|
require_relative "dsl/rule_reference"
|
|
27
27
|
require_relative "dsl/word_gate"
|
|
28
|
+
require_relative "dsl/kinds"
|
|
28
29
|
require_relative "dsl/value_object_builder"
|
|
29
30
|
require_relative "dsl/command_builder"
|
|
30
31
|
require_relative "dsl/lifecycle_builder"
|
|
@@ -17,14 +17,19 @@ module Hecks
|
|
|
17
17
|
{ value: text.to_s }
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
# A reference argument is passed as the bare id it names;
|
|
21
|
-
# other field is wrapped as a one-field value object
|
|
20
|
+
# A reference argument is passed as the bare id it names; a list argument is passed
|
|
21
|
+
# as one value per item; every other field is wrapped as a one-field value object.
|
|
22
22
|
def carried(plan, verb, argument, value)
|
|
23
|
-
return
|
|
23
|
+
return value if reference?(plan, verb, argument)
|
|
24
|
+
return value.map { |item| v(item) } if list?(plan, verb, argument, value)
|
|
24
25
|
|
|
25
|
-
value
|
|
26
|
+
v(value)
|
|
26
27
|
end
|
|
27
28
|
|
|
29
|
+
def reference?(plan, verb, argument) = !!(plan && verb && plan.references?(verb, argument))
|
|
30
|
+
|
|
31
|
+
def list?(plan, verb, argument, value) = value.is_a?(Array) && !!(plan && verb && plan.list?(verb, argument))
|
|
32
|
+
|
|
28
33
|
# A record's id is its declared identity, joined the same way the
|
|
29
34
|
# runtime joins it, so there is exactly one way to name a thing.
|
|
30
35
|
# Each part comes from the parent link, the walk index
|