hecks 3.9.1 → 3.11.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/examples/pizzas/bluebook/pizzas.bluebook +29 -0
- data/examples/pizzas/bluebook/pizzas.hecksagon +7 -0
- data/exe/hecks +4 -4
- data/lib/hecks/adapters/driven/d1.rb +2 -10
- data/lib/hecks/adapters/driven/heki.adapter +1 -1
- data/lib/hecks/adapters/driven/heki.rb +2 -12
- data/lib/hecks/adapters/driven/lambda.adapter +1 -1
- data/lib/hecks/adapters/driven/lambda.rb +3 -18
- data/lib/hecks/adapters/driven/postgres.rb +4 -11
- data/lib/hecks/adapters/driven/sqlite.adapter +1 -1
- data/lib/hecks/adapters/driven/sqlite.rb +2 -10
- data/lib/hecks/adapters/driving/admission.rb +46 -0
- data/lib/hecks/adapters/driving/cli/nesting.rb +36 -0
- data/lib/hecks/adapters/driving/cli/shorthand.rb +88 -0
- data/lib/hecks/adapters/driving/cli.rb +127 -0
- data/lib/hecks/adapters/driving/cli_runner/answers.rb +160 -0
- data/lib/hecks/adapters/driving/cli_runner/resolution.rb +155 -0
- data/lib/hecks/adapters/driving/cli_runner/settling.rb +120 -0
- data/lib/hecks/adapters/driving/cli_runner/streaming.rb +93 -0
- data/lib/hecks/adapters/driving/cli_runner/suggestions.rb +47 -0
- data/lib/hecks/adapters/driving/cli_runner.rb +69 -0
- data/lib/hecks/adapters/driving/command_request.rb +121 -0
- data/lib/hecks/adapters/driving/handle.rb +214 -0
- data/lib/hecks/adapters/driving/json.rb +136 -0
- data/lib/hecks/adapters/driving/launcher_options.rb +267 -0
- data/lib/hecks/adapters/driving/mcp/properties.rb +49 -0
- data/lib/hecks/adapters/driving/mcp/tool_calls.rb +116 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions/auditing.rb +53 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions/calling.rb +71 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions/reading.rb +99 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions.rb +18 -0
- data/lib/hecks/adapters/driving/mcp.rb +159 -0
- data/lib/hecks/adapters/driving/mcp_guide_cache.rb +78 -0
- data/lib/hecks/adapters/driving/mcp_scope/argument_policy.rb +97 -0
- data/lib/hecks/adapters/driving/mcp_scope/env_problems.rb +69 -0
- data/lib/hecks/adapters/driving/mcp_scope/presenter.rb +83 -0
- data/lib/hecks/adapters/driving/mcp_scope.rb +213 -0
- data/lib/hecks/adapters/driving/ruby/aggregate_module.rb +171 -0
- data/lib/hecks/adapters/driving/ruby/chapter.rb +91 -0
- data/lib/hecks/adapters/driving/ruby.rb +83 -0
- data/lib/hecks/adapters/driving/usage_cache.rb +144 -0
- data/lib/hecks/{doors.rb → adapters/driving.rb} +10 -6
- data/lib/hecks/behaviors/expectations/boot.rb +1 -1
- data/lib/hecks/bench/ruby_runner.rb +1 -1
- data/lib/hecks/bluebook/ask_resolution.rb +130 -0
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +8 -2
- data/lib/hecks/bluebook/assembly/contracts/rules.rb +4 -2
- data/lib/hecks/bluebook/assembly/contracts/structure.rb +3 -1
- data/lib/hecks/bluebook/assembly/marks.rb +1 -0
- data/lib/hecks/bluebook/attribute.rb +1 -1
- data/lib/hecks/bluebook/behaviour/command.rb +13 -8
- data/lib/hecks/bluebook/behaviour/policy.rb +30 -0
- data/lib/hecks/bluebook/capabilities/attribute_values.rb +72 -0
- data/lib/hecks/bluebook/capabilities.rb +91 -9
- data/lib/hecks/bluebook/domain_port.rb +16 -4
- data/lib/hecks/bluebook/dsl/adapter_builder.rb +18 -6
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +13 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/computed_sources.rb +98 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/fan_out_rows.rb +42 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/projected_fields.rb +14 -2
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/provisions.rb +69 -3
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/with_projections.rb +17 -10
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +5 -0
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -0
- data/lib/hecks/bluebook/dsl/command_builder/mutations.rb +8 -1
- data/lib/hecks/bluebook/dsl/command_builder/operands.rb +121 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +2 -0
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +10 -1
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +45 -2
- data/lib/hecks/bluebook/dsl/policy_builder.rb +47 -10
- data/lib/hecks/bluebook/dsl/rule_reference.rb +7 -4
- data/lib/hecks/bluebook/dsl/world_builder.rb +1 -1
- data/lib/hecks/bluebook/expression/ast_json/emitters.rb +6 -0
- data/lib/hecks/bluebook/expression/ast_json.rb +9 -6
- data/lib/hecks/bluebook/expression/ast_reader.rb +14 -9
- data/lib/hecks/bluebook/expression/projection.json +36 -0
- data/lib/hecks/bluebook/expression/resolver/operations.rb +31 -0
- data/lib/hecks/bluebook/expression/resolver/parsing.rb +38 -5
- data/lib/hecks/bluebook/expression/resolver/scanning.rb +22 -5
- data/lib/hecks/bluebook/expression/resolver/values.rb +10 -0
- data/lib/hecks/bluebook/expression/resolver.rb +20 -1
- data/lib/hecks/bluebook/hecksagon.rb +23 -3
- data/lib/hecks/bluebook/lifecycle.rb +22 -3
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +13 -1
- data/lib/hecks/bluebook/meta_validator/modes.rb +4 -1
- data/lib/hecks/bluebook/meta_validator/readings.rb +18 -1
- data/lib/hecks/bluebook/meta_validator/reconstruction/heads.rb +2 -1
- data/lib/hecks/bluebook/meta_validator/shapes.rb +5 -0
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +1 -1
- data/lib/hecks/bluebook/meta_validator.rb +12 -12
- data/lib/hecks/bluebook/model_check/ask_checks.rb +71 -0
- data/lib/hecks/bluebook/model_check/policy_checks.rb +2 -1
- data/lib/hecks/bluebook/model_check/reference_checks.rb +70 -0
- data/lib/hecks/bluebook/model_check.rb +8 -2
- data/lib/hecks/bluebook/policy.rb +4 -2
- data/lib/hecks/bluebook/smoke_test.rb +1 -1
- data/lib/hecks/bluebook/synthesizer.rb +2 -0
- data/lib/hecks/bluebook.rb +1 -0
- data/lib/hecks/cli/command_table.rb +1 -1
- data/lib/hecks/cli/console.rb +2 -1
- data/lib/hecks/cli/document.rb +1 -1
- data/lib/hecks/cli/launcher_words.rb +4 -4
- data/lib/hecks/cli/mcp.rb +4 -4
- data/lib/hecks/cli/project_cli/launcher_source.rb +2 -2
- data/lib/hecks/cli/project_cli/templates.rb +5 -5
- data/lib/hecks/cli/project_cli.rb +9 -6
- data/lib/hecks/cli/run.rb +2 -2
- data/lib/hecks/cli/smoke_http/checks.rb +4 -1
- data/lib/hecks/cli/smoke_http/transport.rb +3 -3
- data/lib/hecks/cli/smoke_http.rb +3 -0
- data/lib/hecks/codemod.rb +5 -2
- data/lib/hecks/corpus/routes.rb +7 -0
- data/lib/hecks/corpus/rust.rb +3 -2
- data/lib/hecks/deploy/bluebook/deploy.bluebook +124 -2
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +8 -0
- data/lib/hecks/deploy/oidc.json +16 -3
- data/lib/hecks/doc/reference/rendering.rb +6 -3
- data/lib/hecks/forms/app/commands.rb +8 -7
- data/lib/hecks/forms/app/queries.rb +2 -1
- data/lib/hecks/forms/app.rb +1 -1
- data/lib/hecks/forms/record_renderer.rb +1 -1
- data/lib/hecks/framework/bluebook/privacy.bluebook +11 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +4 -1
- data/lib/hecks/fuzzing/failure_triage.rb +2 -1
- data/lib/hecks/fuzzing/mutation/run.rb +11 -4
- data/lib/hecks/fuzzing/properties/catalog.rb +6 -4
- data/lib/hecks/fuzzing/properties/guaranteed_by_construction.rb +18 -11
- data/lib/hecks/fuzzing/properties/guards.rb +1 -1
- data/lib/hecks/fuzzing/self_consistency/saga_redelivery.rb +1 -1
- data/lib/hecks/fuzzing/self_consistency.rb +6 -2
- data/lib/hecks/fuzzing/shrinker.rb +3 -1
- data/lib/hecks/fuzzing/value_generator.rb +19 -5
- data/lib/hecks/gate/stages.yml +4 -10
- data/lib/hecks/grammar/evolve.rb +1 -1
- data/lib/hecks/grammar/expression_operators.json +372 -0
- data/lib/hecks/grammar/operators.rb +3 -1
- data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +10 -10
- data/lib/hecks/hecks/adapters/codebase/inspection/rubycritic.rb +35 -0
- data/lib/hecks/hecks/adapters/codebase/inspection.rb +104 -0
- data/lib/hecks/hecks/adapters/codebase/publishing.rb +2 -1
- data/lib/hecks/hecks/adapters/codebase/release_facts.rb +12 -2
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +2 -1
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +1 -1
- data/lib/hecks/hecks/adapters/cost_explorer.rb +8 -5
- data/lib/hecks/hecks/adapters/deploy_toolchain/clearing.rb +51 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain/statuses.rb +2 -1
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +2 -0
- data/lib/hecks/hecks/adapters/finding_github.rb +13 -6
- data/lib/hecks/hecks/adapters/first_admin.rb +2 -2
- data/lib/hecks/hecks/adapters/github_rulesets.rb +6 -3
- data/lib/hecks/hecks/adapters/in_process_boot.rb +1 -1
- data/lib/hecks/hecks/adapters/journal_store/compaction.rb +1 -1
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +10 -20
- data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +28 -5
- data/lib/hecks/hecks/adapters/local_files.rb +2 -2
- data/lib/hecks/hecks/adapters/rehearsal/audit_report.rb +107 -0
- data/lib/hecks/hecks/adapters/rehearsal/census.rb +71 -0
- data/lib/hecks/hecks/adapters/rehearsal/declaration.rb +133 -0
- data/lib/hecks/hecks/adapters/rehearsal/environment.rb +83 -0
- data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +142 -0
- data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +96 -0
- data/lib/hecks/hecks/adapters/rehearsal/postgres_census.rb +100 -0
- data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +69 -0
- data/lib/hecks/hecks/adapters/rehearsal/postgres_store.rb +129 -0
- data/lib/hecks/hecks/adapters/rehearsal/rows.rb +41 -0
- data/lib/hecks/hecks/adapters/rehearsal/rust_audit.rb +83 -0
- data/lib/hecks/hecks/adapters/rehearsal/subject.rb +104 -0
- data/lib/hecks/hecks/adapters/rehearsal.rb +54 -0
- data/lib/hecks/hecks/adapters/rehearsal_store.adapter +7 -0
- data/lib/hecks/hecks/adapters/rehearsal_store.rb +81 -0
- data/lib/hecks/hecks/adapters/site_toolchain/role_prober.rb +78 -0
- data/lib/hecks/hecks/adapters/site_toolchain.rb +29 -4
- data/lib/hecks/hecks/adapters/terminal.rb +13 -11
- data/lib/hecks/hecks/adapters/world_clearing.rb +65 -0
- data/lib/hecks/hecks/codebase.behaviors +13 -1
- data/lib/hecks/hecks/codebase.bluebook +239 -5
- data/lib/hecks/hecks/custodian.behaviors +24 -6
- data/lib/hecks/hecks/custodian.bluebook +6 -1227
- data/lib/hecks/hecks/deploy.behaviors +1 -1
- data/lib/hecks/hecks/deploy.world +1 -3
- data/lib/hecks/hecks/hecks.behaviors +1 -1
- data/lib/hecks/hecks/hecks.hecksagon +61 -18
- data/lib/hecks/hecks/hecks.world +11 -10
- data/lib/hecks/hecks/rehearsal.bluebook +477 -0
- data/lib/hecks/hecks/site.behaviors +1 -1
- data/lib/hecks/hecks/site.world +0 -1
- data/lib/hecks/hecks/tooling.bluebook +1238 -0
- data/lib/hecks/indifferent_key.rb +20 -0
- data/lib/hecks/language/adapter.bluebook +13 -3
- data/lib/hecks/language/bluebook/aggregate.bluebook +23 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +15 -0
- data/lib/hecks/language/bluebook/entity.bluebook +18 -0
- data/lib/hecks/language/bluebook/policy.bluebook +9 -1
- data/lib/hecks/language/bluebook/query.bluebook +1 -1
- data/lib/hecks/language/bluebook/vocabulary.bluebook +11 -4
- data/lib/hecks/language/hecksagon/domain_port.bluebook +1 -1
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +22 -0
- data/lib/hecks/language/oidc.json +10 -0
- data/lib/hecks/language/port.bluebook +4 -4
- data/lib/hecks/literal.rb +12 -3
- data/lib/hecks/ports/key_vault.rb +7 -2
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +21 -10
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/boot.rb +4 -2
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +2 -1
- data/lib/hecks/ports/persistence/repository_factory.rb +6 -3
- data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +29 -0
- data/lib/hecks/projections/deploy/box/templates/deploy-service.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/fargate/settings/tuning.rb +15 -0
- data/lib/hecks/projections/deploy/fargate/settings.rb +3 -1
- data/lib/hecks/projections/deploy/fargate/stack/readers.rb +1 -0
- data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
- data/lib/hecks/projections/deploy/shared.rb +5 -2
- data/lib/hecks/projections/deploy/templates/fargate/Makefile.tmpl +7 -4
- data/lib/hecks/projections/model/deviations.rb +2 -2
- data/lib/hecks/projections/model.rb +2 -2
- data/lib/hecks/projections/oidc.rb +13 -1
- data/lib/hecks/projections/shape.rb +5 -2
- data/lib/hecks/projections/site/cms_editor/attributes.rb +95 -0
- data/lib/hecks/projections/site/cms_editor/blocks.rb +157 -0
- data/lib/hecks/projections/site/cms_editor/checks.rb +77 -0
- data/lib/hecks/projections/site/cms_editor/clearing.rb +70 -0
- data/lib/hecks/projections/site/cms_editor/color.rb +124 -0
- data/lib/hecks/projections/site/cms_editor/composition.rb +42 -0
- data/lib/hecks/projections/site/cms_editor/destructive.rb +61 -0
- data/lib/hecks/projections/site/cms_editor/drafts.rb +102 -0
- data/lib/hecks/projections/site/cms_editor/hints.rb +74 -0
- data/lib/hecks/projections/site/cms_editor/icons.rb +86 -0
- data/lib/hecks/projections/site/cms_editor/key_kinds.rb +31 -0
- data/lib/hecks/projections/site/cms_editor/limits.rb +72 -0
- data/lib/hecks/projections/site/cms_editor/media.rb +85 -0
- data/lib/hecks/projections/site/cms_editor/moment.rb +34 -0
- data/lib/hecks/projections/site/cms_editor/palette.rb +115 -0
- data/lib/hecks/projections/site/cms_editor/pickers.rb +85 -0
- data/lib/hecks/projections/site/cms_editor/pretty.rb +40 -0
- data/lib/hecks/projections/site/cms_editor/preview.rb +91 -0
- data/lib/hecks/projections/site/cms_editor/relations.rb +92 -0
- data/lib/hecks/projections/site/cms_editor/scale_checks.rb +66 -0
- data/lib/hecks/projections/site/cms_editor/scheduling.rb +150 -0
- data/lib/hecks/projections/site/cms_editor/schema.rb +161 -0
- data/lib/hecks/projections/site/cms_editor/setting.rb +130 -0
- data/lib/hecks/projections/site/cms_editor/targets.rb +86 -0
- data/lib/hecks/projections/site/cms_editor/templates/package.json.tmpl +36 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/app.ts.tmpl +370 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/assets.ts.tmpl +98 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/auth/membership.ts.tmpl +87 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/auth/session.ts.tmpl +36 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/auth/sso.ts.tmpl +20 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/app.css.tmpl +412 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/autosave.js.tmpl +144 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/blocks.js.tmpl +500 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/body_doc.js.tmpl +175 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/body_editor.js.tmpl +418 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/epoch.js.tmpl +61 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/forms.js.tmpl +210 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/lists.js.tmpl +40 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/main.js.tmpl +26 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/media_picker.js.tmpl +232 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/moments.js.tmpl +73 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/pickers.js.tmpl +152 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/preview.js.tmpl +98 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/shell.js.tmpl +140 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/toast.js.tmpl +66 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/choices.ts.tmpl +99 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/commands.ts.tmpl +133 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/config.ts.tmpl +29 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/flash.ts.tmpl +52 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/host.ts.tmpl +43 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/media/handler.ts.tmpl +177 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/media/multipart.ts.tmpl +53 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/media/sniff.ts.tmpl +94 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/media/storage.ts.tmpl +50 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/names.ts.tmpl +36 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/schema.ts.tmpl +214 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/server.ts.tmpl +65 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/availability.ts.tmpl +15 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/block_list.js.tmpl +213 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/blocks.ts.tmpl +275 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/body_model.js.tmpl +123 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/body_parse.js.tmpl +320 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/detail.ts.tmpl +88 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/dialogs.ts.tmpl +43 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/fields.ts.tmpl +275 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/html.ts.tmpl +61 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/icons.ts.tmpl +15 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/input.ts.tmpl +92 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/links.ts.tmpl +100 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/moments.ts.tmpl +44 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/outline.ts.tmpl +63 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/pages.ts.tmpl +213 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/paging.ts.tmpl +82 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/pickers.ts.tmpl +110 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/preview.ts.tmpl +87 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/related.ts.tmpl +97 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/schedule.ts.tmpl +160 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/shell.ts.tmpl +211 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/table.ts.tmpl +151 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/theme.js.tmpl +16 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/values.ts.tmpl +69 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/words.ts.tmpl +97 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/world.ts.tmpl +35 -0
- data/lib/hecks/projections/site/cms_editor/templates/tsconfig.json.tmpl +17 -0
- data/lib/hecks/projections/site/cms_editor/theme.rb +29 -0
- data/lib/hecks/projections/site/cms_editor/theme_checks.rb +57 -0
- data/lib/hecks/projections/site/cms_editor.rb +133 -0
- data/lib/hecks/projections/site/role_probe.rb +74 -0
- data/lib/hecks/projector/cli_audience.rb +2 -1
- data/lib/hecks/projector/cli_projector/listing.rb +1 -1
- data/lib/hecks/projector/cli_projector/option_specs.rb +1 -1
- data/lib/hecks/projector/docs_projector/closing.rb +1 -1
- data/lib/hecks/projector/docs_projector.rb +1 -1
- data/lib/hecks/projector/exporter/bindings.rb +40 -10
- data/lib/hecks/projector/exporter/capability_values.rb +55 -0
- data/lib/hecks/projector/narrate_projector/reactions.rb +1 -1
- data/lib/hecks/projector/target.rb +11 -0
- data/lib/hecks/projector.rb +32 -5
- data/lib/hecks/quality_control/adapters/github_checks.rb +12 -8
- data/lib/hecks/quality_control/adapters/github_issues.rb +8 -4
- data/lib/hecks/quality_control/cli/qa_open_pr.rb +2 -2
- data/lib/hecks/quality_control/cli/qa_sweep/checks/shrinking.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_sweep.rb +1 -1
- data/lib/hecks/quality_control/quality_control.bluebook +6 -2
- data/lib/hecks/release/approval.rb +64 -0
- data/lib/hecks/router/{door.rb → aggregate_reader.rb} +5 -4
- data/lib/hecks/router/namespace_installer.rb +16 -16
- data/lib/hecks/router.rb +1 -1
- data/lib/hecks/runtime/best_effort.rb +22 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +12 -2
- data/lib/hecks/runtime/command_interpreter.rb +3 -2
- data/lib/hecks/runtime/command_rules/emission.rb +1 -1
- data/lib/hecks/runtime/dispatcher.rb +4 -4
- data/lib/hecks/runtime/entity_element/location.rb +1 -1
- data/lib/hecks/runtime/event.rb +5 -0
- data/lib/hecks/runtime/identity.rb +7 -6
- data/lib/hecks/runtime/interpreting.rb +2 -1
- data/lib/hecks/runtime/invocation_builder.rb +1 -1
- data/lib/hecks/runtime/loader/boot_steps.rb +8 -5
- data/lib/hecks/runtime/loader.rb +10 -10
- data/lib/hecks/runtime/policy_interpreter/arguments.rb +7 -4
- data/lib/hecks/runtime/policy_interpreter/fan_out.rb +3 -3
- data/lib/hecks/runtime/policy_interpreter.rb +6 -6
- data/lib/hecks/runtime/port_operation_interpreter.rb +1 -1
- data/lib/hecks/runtime/reaction_invocation.rb +1 -1
- data/lib/hecks/runtime/rebuild_sweep.rb +11 -1
- data/lib/hecks/runtime/registry/ask_verification.rb +35 -0
- data/lib/hecks/runtime/registry/hecksagon_rules.rb +10 -0
- data/lib/hecks/runtime/registry/merging.rb +1 -1
- data/lib/hecks/runtime/registry/providers.rb +16 -0
- data/lib/hecks/runtime/registry/read_repository.rb +6 -4
- data/lib/hecks/runtime/registry/verification.rb +4 -1
- data/lib/hecks/runtime/registry/world_defaults.rb +29 -0
- data/lib/hecks/runtime/registry.rb +1 -1
- data/lib/hecks/runtime/saga_interpreter/compensation.rb +1 -1
- data/lib/hecks/runtime/saga_interpreter/delivery.rb +4 -4
- data/lib/hecks/runtime/saga_interpreter/transitions.rb +1 -1
- data/lib/hecks/runtime/saga_interpreter.rb +3 -3
- data/lib/hecks/runtime/tenant_check.rb +5 -4
- data/lib/hecks/runtime/value/coercion.rb +2 -2
- data/lib/hecks/runtime/value/validation.rb +16 -4
- data/lib/hecks/runtime.rb +9 -9
- data/lib/hecks/rust_build/project_rust/target_ir.rb +1 -1
- data/lib/hecks/rust_build/wasm.rb +1 -1
- data/lib/hecks/rust_build/wasm_browser.rb +1 -1
- data/lib/hecks/rust_build.rb +11 -0
- data/lib/hecks/served_options.rb +53 -0
- data/lib/hecks/site/bluebook/site.bluebook +29 -1
- data/lib/hecks/site/bluebook/site.ports.hecksagon +6 -0
- data/lib/hecks/storehouse/audit.rb +1 -1
- data/lib/hecks/storehouse/dispatching.rb +8 -6
- data/lib/hecks/storehouse/introspection.rb +2 -2
- data/lib/hecks/storehouse/querying.rb +6 -4
- data/lib/hecks/storehouse.rb +4 -4
- data/lib/hecks/tools/comment_style/source_file.rb +4 -1
- data/lib/hecks/tools/deploy_recipe_lint/fixtures.rb +4 -1
- data/lib/hecks/tools/lanes/rows.rb +6 -0
- data/lib/hecks/tools/oidc_manifests.rb +4 -5
- data/lib/hecks/tools/regeneration_run.rb +11 -4
- data/lib/hecks/tools/site_routes/cli.rb +1 -1
- data/lib/hecks/tools/site_routes/editor_files.rb +45 -0
- data/lib/hecks/tools/site_routes.rb +14 -7
- data/lib/hecks/tools/tenant_provisioning.rb +2 -2
- data/lib/hecks/tools/tools_doc.rb +4 -4
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks/vocabulary.rb +4 -4
- data/lib/hecks.rb +15 -15
- data/lib/rubocop/cop/hecks/env_dump.rb +69 -0
- data/lib/rubocop/cop/hecks/monotonic_duration.rb +53 -0
- data/lib/rubocop/cop/hecks/no_wall_clock_in_runtime.rb +34 -0
- data/lib/rubocop/cop/hecks/raw_shell_interpolation.rb +79 -0
- data/lib/rubocop/cop/hecks/sleep_in_spec.rb +34 -0
- data/lib/rubocop/cop/hecks/swallowed_rescue.rb +37 -0
- data/lib/rubocop/cop/hecks/symbol_string_key_mix.rb +50 -0
- data/lib/rubocop/cop/hecks/untyped_raise.rb +37 -0
- data/prebuilt/05c358d38d661a3774f813d49c66f5b68939af94432d66257a56f49ee2598994.marshal +0 -0
- data/prebuilt/26c40c61f09b09b11651c64668eda3ceb180f83cf2a3802d3033d2fd99ac841b.marshal +0 -0
- data/prebuilt/verdicts-230ac18c25abfd3d92ede032bee2661a4c2cd2773ab0cf0e2ae52546ba2f7af9.json +1 -0
- data/rust/.gitignore +6 -0
- data/rust/Cargo.toml +9 -1
- data/rust/build/src/binding_pass.rs +103 -0
- data/rust/build/src/cargo_sync.rs +6 -0
- data/rust/build/src/lineage_pass.rs +3 -3
- data/rust/build/src/main.rs +17 -5
- data/rust/build/src/pipeline.rs +48 -5
- data/rust/build/src/seams_pass.rs +123 -0
- data/rust/build/src/translation_pass.rs +167 -0
- data/rust/codegen/src/asks.rs +103 -0
- data/rust/codegen/src/bridging.rs +1 -1
- data/rust/codegen/src/commands.rs +13 -8
- data/rust/codegen/src/constraints.rs +25 -0
- data/rust/codegen/src/domain_generator.rs +11 -9
- data/rust/codegen/src/expr_emitter.rs +13 -0
- data/rust/codegen/src/json_codec.rs +54 -15
- data/rust/codegen/src/main.rs +2 -1
- data/rust/codegen/src/mutations.rs +174 -4
- data/rust/codegen/src/naming.rs +30 -0
- data/rust/codegen/src/queries.rs +11 -2
- data/rust/codegen/src/reactions.rs +1 -1
- data/rust/codegen/src/types.rs +166 -8
- data/rust/host/HECKS_RELEASE +1 -1
- data/rust/host/src/api.rs +4 -4
- data/rust/host/src/bin/validate_harness.rs +43 -0
- data/rust/host/src/boundary_fuzz/expr_json.rs +2 -2
- data/rust/host/src/boundary_fuzz/ir.rs +1 -0
- data/rust/host/src/boundary_fuzz/server.rs +1 -1
- data/rust/host/src/checkout.rs +35 -19
- data/rust/host/src/commerce_ir.rs +408 -2
- data/rust/host/src/expr_json.rs +118 -0
- data/rust/host/src/mint.rs +1 -1
- data/rust/host/src/payments/tests.rs +27 -1
- data/rust/host/src/payments.rs +12 -4
- data/rust/host/src/query_step.rs +22 -4
- data/rust/host/src/reference_validate.rs +653 -108
- data/rust/host/src/resend.rs +2 -0
- data/rust/host/src/server.rs +19 -6
- data/rust/host/src/ui_schema.rs +132 -5
- data/rust/host/src/web/newsletter.rs +7 -8
- data/rust/host/src/web/newsletter_send.rs +38 -13
- data/rust/host/src/web/registrations.rs +229 -26
- data/rust/host/src/web.rs +3 -3
- data/rust/parser/src/emit.rs +38 -6
- data/rust/parser/src/expr/ast_json.rs +7 -1
- data/rust/parser/src/expr/resolver.rs +171 -6
- data/rust/parser/src/ir.rs +7 -0
- data/rust/parser/src/keywords.rs +24 -0
- data/rust/parser/src/main.rs +3 -0
- data/rust/parser/src/parse/aggregate.rs +2 -1
- data/rust/parser/src/parse/chapter.rs +2 -2
- data/rust/parser/src/parse/command.rs +2 -0
- data/rust/parser/src/parse/hecksagon.rs +5 -2
- data/rust/parser/src/parse/lifecycle.rs +81 -0
- data/rust/parser/src/parse/mod.rs +15 -1
- data/rust/parser/src/parse/policy.rs +13 -2
- data/rust/parser/src/parse/value_object.rs +13 -8
- data/rust/parser/src/ruby_value.rs +1 -1
- data/rust/src/exemplar/commands.rs +4 -4
- data/rust/src/exemplar/constraints.rs +1 -1
- data/rust/src/exemplar/json.rs +43 -1
- data/rust/src/kernel/cli.rs +7 -5
- data/rust/src/kernel/dispatch.rs +2 -2
- data/rust/src/kernel/dispatch_guard_tests.rs +1 -1
- data/rust/src/kernel/expr.rs +73 -4
- data/rust/src/kernel/expression_operators/arithmetic.rs +130 -5
- data/rust/src/kernel/expression_operators/presence.rs +41 -3
- data/rust/src/kernel/expression_operators/text.rs +26 -2
- data/rust/src/kernel/json.rs +15 -0
- data/rust/src/kernel/mod.rs +1 -1
- data/rust/src/kernel/orchestrate.rs +54 -5
- data/rust/src/kernel/orchestrate_guard_tests.rs +67 -0
- data/rust/src/kernel/pattern.rs +60 -0
- data/rust/src/kernel/reference_lookup.rs +90 -7
- metadata +174 -36
- data/lib/hecks/doors/cli_door/nesting.rb +0 -34
- data/lib/hecks/doors/cli_door/shorthand.rb +0 -85
- data/lib/hecks/doors/cli_door.rb +0 -124
- data/lib/hecks/doors/cli_runner/answers.rb +0 -138
- data/lib/hecks/doors/cli_runner/resolution.rb +0 -146
- data/lib/hecks/doors/cli_runner/settling.rb +0 -115
- data/lib/hecks/doors/cli_runner/streaming.rb +0 -90
- data/lib/hecks/doors/cli_runner/suggestions.rb +0 -43
- data/lib/hecks/doors/cli_runner.rb +0 -66
- data/lib/hecks/doors/command_request.rb +0 -119
- data/lib/hecks/doors/handle.rb +0 -208
- data/lib/hecks/doors/json_door.rb +0 -132
- data/lib/hecks/doors/launcher_options.rb +0 -247
- data/lib/hecks/doors/mcp_door/properties.rb +0 -47
- data/lib/hecks/doors/mcp_door/tool_calls.rb +0 -113
- data/lib/hecks/doors/mcp_door/tool_definitions/auditing.rb +0 -51
- data/lib/hecks/doors/mcp_door/tool_definitions/calling.rb +0 -69
- data/lib/hecks/doors/mcp_door/tool_definitions/reading.rb +0 -97
- data/lib/hecks/doors/mcp_door/tool_definitions.rb +0 -15
- data/lib/hecks/doors/mcp_door.rb +0 -156
- data/lib/hecks/doors/mcp_door_scope/argument_policy.rb +0 -92
- data/lib/hecks/doors/mcp_door_scope/env_problems.rb +0 -55
- data/lib/hecks/doors/mcp_door_scope/presenter.rb +0 -78
- data/lib/hecks/doors/mcp_door_scope.rb +0 -201
- data/lib/hecks/doors/mcp_guide_cache.rb +0 -75
- data/lib/hecks/doors/ruby_door/aggregate_door.rb +0 -162
- data/lib/hecks/doors/ruby_door/chapter.rb +0 -89
- data/lib/hecks/doors/ruby_door.rb +0 -80
- data/lib/hecks/doors/usage_cache.rb +0 -139
- data/prebuilt/0ee7f83cba59ce7d1c45c65ba166b071779f70143449f584f33ff7989f64eccb.marshal +0 -0
- data/prebuilt/6e4a6bcf0aa880e2e6b056e1846b70e5a768090b9dc998bbadeaf5d6bcfd3db8.marshal +0 -0
- data/prebuilt/verdicts-91aaf93ce8981bd9a754948f075d95650dc2ec6435015376f5c60992b36a24b1.json +0 -1
|
@@ -0,0 +1,1238 @@
|
|
|
1
|
+
Hecks.bluebook "Hecks" do
|
|
2
|
+
# Tooling: developer tooling for working with a domain, in the Maintenance module (ADR 0096).
|
|
3
|
+
# A client runs these while building a domain, not while operating one; the operating half is
|
|
4
|
+
# in custodian.bluebook.
|
|
5
|
+
|
|
6
|
+
aggregate "Introspection" do
|
|
7
|
+
description "A look at a booted domain, answered by the runtime without changing anything."
|
|
8
|
+
|
|
9
|
+
attribute :domain, DomainPath
|
|
10
|
+
identified_by :domain
|
|
11
|
+
|
|
12
|
+
value_object "DomainPath" do
|
|
13
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
14
|
+
|
|
15
|
+
invariant("a domain is named by its path") { !value.to_s.empty? }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
value_object "ChapterName" do
|
|
19
|
+
attribute :value, String, pattern: '[^ \t\n\r]'
|
|
20
|
+
|
|
21
|
+
invariant("a chapter is named") { !value.to_s.empty? }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
value_object "AggregateName" do
|
|
25
|
+
attribute :value, String, pattern: '[^ \t\n\r]'
|
|
26
|
+
|
|
27
|
+
invariant("an aggregate is named") { !value.to_s.empty? }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Each query below is answered by the DomainRuntime port's adapter: the domain is booted
|
|
31
|
+
# in-process and the answer is the exact text the matching bin script printed.
|
|
32
|
+
|
|
33
|
+
# An answer that is one document of text, exactly as the tool that produced it wrote it.
|
|
34
|
+
value_object "Document" do
|
|
35
|
+
attribute :text, String
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
query "Ir" do
|
|
39
|
+
description "The IR a domain's boot produces, as JSON: what golden specs pin and an era hashes."
|
|
40
|
+
attribute :domain, DomainPath, optional: true
|
|
41
|
+
attribute :translations, Boolean, optional: true
|
|
42
|
+
attribute :meta, Boolean, optional: true
|
|
43
|
+
returns Document
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
query "Shape" do
|
|
47
|
+
description "The storage shape an era's label is minted from: a bluebook file or a directory of them."
|
|
48
|
+
attribute :domain, DomainPath
|
|
49
|
+
returns Document
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
query "Stores" do
|
|
53
|
+
description "Every aggregate's current records: the head, not the journal."
|
|
54
|
+
attribute :domain, DomainPath
|
|
55
|
+
returns Document
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
query "History" do
|
|
59
|
+
description "Every journal entry a domain's append-only adapters hold: the whole write history."
|
|
60
|
+
attribute :domain, DomainPath
|
|
61
|
+
returns Document
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
query "Statements" do
|
|
65
|
+
description "A chapter's declared facts, as plain English sentences."
|
|
66
|
+
attribute :domain, DomainPath
|
|
67
|
+
attribute :chapter, ChapterName
|
|
68
|
+
returns Document
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
query "Narrate" do
|
|
72
|
+
description "A domain read back in English, whole or for one aggregate."
|
|
73
|
+
attribute :domain, DomainPath, optional: true
|
|
74
|
+
attribute :aggregate, AggregateName, optional: true
|
|
75
|
+
returns Document
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
query "Docs" do
|
|
79
|
+
description "A domain's usage document, whole or for one aggregate."
|
|
80
|
+
attribute :domain, DomainPath, optional: true
|
|
81
|
+
attribute :aggregate, AggregateName, optional: true
|
|
82
|
+
returns Document
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# One file a projection would have written, held as its name and its text.
|
|
86
|
+
value_object "ProjectedFile" do
|
|
87
|
+
attribute :name, String
|
|
88
|
+
attribute :text, String
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
query "ProjectDiagrams" do
|
|
92
|
+
description "A chapter's Mermaid diagrams, as file names mapped to their text; nothing is written."
|
|
93
|
+
attribute :domain, DomainPath
|
|
94
|
+
attribute :chapter, ChapterName
|
|
95
|
+
returns list_of(ProjectedFile)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
query "Glossary" do
|
|
99
|
+
description "A chapter's Ubiquitous Language glossary, as file names mapped to their text; nothing is written."
|
|
100
|
+
attribute :domain, DomainPath
|
|
101
|
+
attribute :chapter, ChapterName
|
|
102
|
+
returns list_of(ProjectedFile)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# A journaled command whose work happens outside the runtime (ADR 0080, section 11). Every
|
|
107
|
+
# command below that runs something follows this one shape, so later aggregates copy it:
|
|
108
|
+
#
|
|
109
|
+
# 1. A creating command records the request as a record in state "requested" and emits.
|
|
110
|
+
# 2. A policy on that event asks for the work by name (`ask :check`); the hecksagon says which
|
|
111
|
+
# port answers. The runtime hands the port's adapter the whole record, so the adapter does
|
|
112
|
+
# all the IO, and only there.
|
|
113
|
+
# 3. The adapter answers (a hash named like a command's arguments) or raises (its message
|
|
114
|
+
# is the refusal). One policy per outcome re-enters the record with a command that stores it.
|
|
115
|
+
#
|
|
116
|
+
# The ports are declared in hecks.hecksagon; each adapter is in adapters/.
|
|
117
|
+
|
|
118
|
+
aggregate "ModelCheckRun" do
|
|
119
|
+
description "One static analysis over domains' models, and what it found: a check's history."
|
|
120
|
+
|
|
121
|
+
attribute :run, RunKey
|
|
122
|
+
attribute :domains, DomainList, optional: true
|
|
123
|
+
attribute :profile, ProfileName, optional: true
|
|
124
|
+
attribute :strict, Switch, optional: true
|
|
125
|
+
attribute :report, Report, optional: true
|
|
126
|
+
attribute :checked, Checked, optional: true
|
|
127
|
+
attribute :refusal, Report, optional: true
|
|
128
|
+
identified_by :run
|
|
129
|
+
|
|
130
|
+
value_object "RunKey" do
|
|
131
|
+
attribute :value, String, pattern: '[^ \t\n\r]'
|
|
132
|
+
|
|
133
|
+
invariant("a run is named") { !value.to_s.empty? }
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
value_object "DomainList" do
|
|
137
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
value_object "ProfileName" do
|
|
141
|
+
attribute :value, String, pattern: '^client$'
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
value_object "Switch" do
|
|
145
|
+
attribute :value, Boolean
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
value_object "Report" do
|
|
149
|
+
attribute :value, String
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# How many domains the report examined, counted from its headers so a reader need not.
|
|
153
|
+
value_object "Checked" do
|
|
154
|
+
attribute :value, Integer
|
|
155
|
+
|
|
156
|
+
invariant("a count is not negative") { value >= 0 }
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
lifecycle :status, default: "requested" do
|
|
160
|
+
mark :failure, "flagged"
|
|
161
|
+
transition "Pass" => "clean", from: "requested"
|
|
162
|
+
transition "Flag" => "flagged", from: "requested"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
command "ModelCheck" do
|
|
166
|
+
role "Operator"
|
|
167
|
+
goal "Check domains for dead states and unreachable steps, and keep the verdict"
|
|
168
|
+
|
|
169
|
+
attribute :run, RunKey
|
|
170
|
+
attribute :domains, DomainList, optional: true
|
|
171
|
+
attribute :profile, ProfileName, optional: true
|
|
172
|
+
attribute :strict, Switch, optional: true
|
|
173
|
+
|
|
174
|
+
sets :run
|
|
175
|
+
sets :domains
|
|
176
|
+
sets :profile
|
|
177
|
+
sets :strict
|
|
178
|
+
|
|
179
|
+
emits ModelCheckRequested
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
command "Pass" do
|
|
183
|
+
role "System"
|
|
184
|
+
goal "Record that the analysis left no error"
|
|
185
|
+
|
|
186
|
+
reference_to ModelCheckRun
|
|
187
|
+
attribute :report, Report
|
|
188
|
+
attribute :checked, Checked
|
|
189
|
+
|
|
190
|
+
sets :report
|
|
191
|
+
sets :checked
|
|
192
|
+
|
|
193
|
+
emits ModelCheckPassed
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
command "Flag" do
|
|
197
|
+
role "System"
|
|
198
|
+
goal "Record that the analysis found something, or could not run, and what it said"
|
|
199
|
+
|
|
200
|
+
reference_to ModelCheckRun
|
|
201
|
+
attribute :refusal, Report
|
|
202
|
+
|
|
203
|
+
sets :refusal
|
|
204
|
+
|
|
205
|
+
emits ModelCheckFlagged
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# `hecks model_check` answers once the request is recorded, so the verdict is read here.
|
|
209
|
+
query "Verdict" do
|
|
210
|
+
description "What one check found: its status, and the report or the reason it could not run."
|
|
211
|
+
attribute :run, RunKey
|
|
212
|
+
where(run: :run)
|
|
213
|
+
order_by :run
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
query "Flagged" do
|
|
217
|
+
description "Every check that left a finding or could not run."
|
|
218
|
+
where(status: "flagged")
|
|
219
|
+
order_by :run
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
policy "AnalyseWhenRequested" do
|
|
224
|
+
on "ModelCheckRun.ModelCheckRequested"
|
|
225
|
+
ask :check, with: { run: :run }
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
policy "RecordTheClean" do
|
|
229
|
+
on "ModelCheckRun.ModelCheckAnswered"
|
|
230
|
+
trigger ModelCheckRun::Pass, with: { report: :report, checked: :checked }
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
policy "RecordTheFlag" do
|
|
234
|
+
on "ModelCheckRun.ModelCheckRefused"
|
|
235
|
+
trigger ModelCheckRun::Flag, with: { refusal: :refusal }
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
aggregate "Package" do
|
|
239
|
+
description "One package of the bluebook registry, vendored into a project and pinned."
|
|
240
|
+
|
|
241
|
+
attribute :package, PackageRef
|
|
242
|
+
attribute :from, Location, optional: true
|
|
243
|
+
attribute :root, Location, optional: true
|
|
244
|
+
attribute :report, Report, optional: true
|
|
245
|
+
attribute :refusal, Report, optional: true
|
|
246
|
+
identified_by :package
|
|
247
|
+
|
|
248
|
+
# `name` for the newest release, `name@1.2.0` for one release, `name@9f2c1ab` for a commit.
|
|
249
|
+
value_object "PackageRef" do
|
|
250
|
+
attribute :value, String, pattern: '^[a-z][a-z0-9_]*(@[^ \t\n\r]+)?$'
|
|
251
|
+
|
|
252
|
+
invariant("a package is named") { !value.to_s.empty? }
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# A directory: the source repository (`from`), or the project the files land in (`root`).
|
|
256
|
+
value_object "Location" do
|
|
257
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
value_object "Report" do
|
|
261
|
+
attribute :value, String
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# An answer that is one document of text, exactly as the tool that produced it wrote it.
|
|
265
|
+
value_object "Document" do
|
|
266
|
+
attribute :text, String
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
lifecycle :status, default: "requested" do
|
|
270
|
+
mark :failure, "refused"
|
|
271
|
+
transition "Revendor" => "requested", from: %w[vendored refused]
|
|
272
|
+
transition "Complete" => "vendored", from: "requested"
|
|
273
|
+
transition "Abandon" => "refused", from: "requested"
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# `hecks vendor <package[@version]> [from=path] [root=path]`. The record is named by what was
|
|
277
|
+
# asked for, so a release is one record; vendoring the same spelling again is `hecks revendor`.
|
|
278
|
+
# `from` defaults to $EMBRYONAUT_BLUEBOOKS_SRC and `root` to the current directory, both read by
|
|
279
|
+
# the adapter.
|
|
280
|
+
command "Vendor" do
|
|
281
|
+
role "Operator"
|
|
282
|
+
goal "Pin a package of the bluebook registry into this project, at a release or a commit"
|
|
283
|
+
|
|
284
|
+
attribute :package, PackageRef
|
|
285
|
+
attribute :from, Location, optional: true
|
|
286
|
+
attribute :root, Location, optional: true
|
|
287
|
+
|
|
288
|
+
sets :package
|
|
289
|
+
sets :from
|
|
290
|
+
sets :root
|
|
291
|
+
|
|
292
|
+
emits VendorRequested
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
command "Revendor" do
|
|
296
|
+
role "Operator"
|
|
297
|
+
goal "Pin a package that was vendored before again, for the newest release or the same one"
|
|
298
|
+
|
|
299
|
+
reference_to Package
|
|
300
|
+
attribute :from, Location, optional: true
|
|
301
|
+
attribute :root, Location, optional: true
|
|
302
|
+
|
|
303
|
+
sets :from
|
|
304
|
+
sets :root
|
|
305
|
+
|
|
306
|
+
emits RevendorRequested
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
command "Complete" do
|
|
310
|
+
role "System"
|
|
311
|
+
goal "Record that the package was pinned, and what changed"
|
|
312
|
+
|
|
313
|
+
reference_to Package
|
|
314
|
+
attribute :report, Report
|
|
315
|
+
|
|
316
|
+
sets :report
|
|
317
|
+
|
|
318
|
+
emits PackageVendored
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
command "Abandon" do
|
|
322
|
+
role "System"
|
|
323
|
+
goal "Record that the package could not be pinned, and why"
|
|
324
|
+
|
|
325
|
+
reference_to Package
|
|
326
|
+
attribute :refusal, Report
|
|
327
|
+
|
|
328
|
+
sets :refusal
|
|
329
|
+
|
|
330
|
+
emits VendoringRefused
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
query "Pinning" do
|
|
334
|
+
description "What vendoring one package did: its status, and the report or the refusal."
|
|
335
|
+
attribute :package, PackageRef
|
|
336
|
+
where(package: :package)
|
|
337
|
+
order_by :package
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
query "Unpinned" do
|
|
341
|
+
description "Every package the last vendoring of which was refused."
|
|
342
|
+
where(status: "refused")
|
|
343
|
+
order_by :package
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
# `hecks package.verify [root=path]`: a read of the files, so it keeps no record. The manifest
|
|
347
|
+
# is the answer; a package that disagrees with its lock refuses it, naming each one.
|
|
348
|
+
query "Verify" do
|
|
349
|
+
description "Check every vendored package against its bluebook.lock, then describe them as the manifest a client image carries."
|
|
350
|
+
attribute :root, Location, optional: true
|
|
351
|
+
returns Document
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
policy "PinWhenVendored" do
|
|
356
|
+
on "Package.VendorRequested"
|
|
357
|
+
ask :pin, with: { package: :package }
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
policy "PinWhenRevendored" do
|
|
361
|
+
on "Package.RevendorRequested"
|
|
362
|
+
ask :pin, with: { package: :package }
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
policy "RecordThePinning" do
|
|
366
|
+
on "Package.PackagePinned"
|
|
367
|
+
trigger Package::Complete, with: { report: :report }
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
policy "RecordTheRefusedPin" do
|
|
371
|
+
on "Package.PinRefused"
|
|
372
|
+
trigger Package::Abandon, with: { refusal: :refusal }
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
aggregate "Registry" do
|
|
376
|
+
description "A bluebook registry repository: packages versioned in it and released as tags."
|
|
377
|
+
|
|
378
|
+
attribute :run, RegistryKey
|
|
379
|
+
attribute :package, PackageName, optional: true
|
|
380
|
+
attribute :root, Location, optional: true
|
|
381
|
+
attribute :report, Report, optional: true
|
|
382
|
+
attribute :refusal, Report, optional: true
|
|
383
|
+
identified_by :run
|
|
384
|
+
|
|
385
|
+
value_object "RegistryKey" do
|
|
386
|
+
attribute :value, String, pattern: '[^ \t\n\r]'
|
|
387
|
+
|
|
388
|
+
invariant("a release is named") { !value.to_s.empty? }
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
value_object "PackageName" do
|
|
392
|
+
attribute :value, String, pattern: '^[a-z][a-z0-9_]*$'
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
# The registry repository: the current directory when absent.
|
|
396
|
+
value_object "Location" do
|
|
397
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
value_object "Report" do
|
|
401
|
+
attribute :value, String
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
# An answer that is one document of text, exactly as the tool that produced it wrote it.
|
|
405
|
+
value_object "Document" do
|
|
406
|
+
attribute :text, String
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
lifecycle :status, default: "requested" do
|
|
410
|
+
mark :failure, "refused"
|
|
411
|
+
transition "Complete" => "tagged", from: "requested"
|
|
412
|
+
transition "Abandon" => "refused", from: "requested"
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
# `hecks package.release <package> [root=path]`. Tags the package's current version as
|
|
416
|
+
# `<package>-vX.Y.Z` in the local repository and never pushes; the report ends in the command
|
|
417
|
+
# that does. A refusal says which rule the package broke.
|
|
418
|
+
command "Release" do
|
|
419
|
+
role "Operator"
|
|
420
|
+
goal "Tag a package of this registry at the version its bluebook.yml carries"
|
|
421
|
+
|
|
422
|
+
attribute :run, RegistryKey
|
|
423
|
+
attribute :package, PackageName
|
|
424
|
+
attribute :root, Location, optional: true
|
|
425
|
+
|
|
426
|
+
sets :run
|
|
427
|
+
sets :package
|
|
428
|
+
sets :root
|
|
429
|
+
|
|
430
|
+
emits ReleaseRequested
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
command "Complete" do
|
|
434
|
+
role "System"
|
|
435
|
+
goal "Record that the release was tagged, and the command that publishes it"
|
|
436
|
+
|
|
437
|
+
reference_to Registry
|
|
438
|
+
attribute :report, Report
|
|
439
|
+
|
|
440
|
+
sets :report
|
|
441
|
+
|
|
442
|
+
emits ReleaseRecorded
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
command "Abandon" do
|
|
446
|
+
role "System"
|
|
447
|
+
goal "Record that the release was refused, and why"
|
|
448
|
+
|
|
449
|
+
reference_to Registry
|
|
450
|
+
attribute :refusal, Report
|
|
451
|
+
|
|
452
|
+
sets :refusal
|
|
453
|
+
|
|
454
|
+
emits ReleaseAbandoned
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
# `hecks package.check [root=path]`: a read of the repository's files and tags, so it keeps no
|
|
458
|
+
# record. A package that changed since its latest release without a version bump and a changelog
|
|
459
|
+
# entry refuses it, naming each one.
|
|
460
|
+
query "Check" do
|
|
461
|
+
description "Judge every package against its latest release: a changed package needs a newer version and a changelog entry."
|
|
462
|
+
attribute :root, Location, optional: true
|
|
463
|
+
returns Document
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
# `hecks package.digest <package> [root=path]`: a read of the package's files, so it keeps no
|
|
467
|
+
# record. The digest is `Lock.digest_of` over `<package>/bluebook/*.bluebook` only (the
|
|
468
|
+
# `bluebook.lock` digest line), then the package's shape labels; `root` is the registry, or a
|
|
469
|
+
# project that vendors the package.
|
|
470
|
+
query "Digest" do
|
|
471
|
+
description "Print a package's content digest and shape labels, as its bluebook.lock records them."
|
|
472
|
+
attribute :package, PackageName
|
|
473
|
+
attribute :root, Location, optional: true
|
|
474
|
+
returns Document
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
query "Releasing" do
|
|
478
|
+
description "What releasing one run did: its status, and the report or the refusal."
|
|
479
|
+
attribute :run, RegistryKey
|
|
480
|
+
where(run: :run)
|
|
481
|
+
order_by :run
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
query "Refused" do
|
|
485
|
+
description "Every release that was refused."
|
|
486
|
+
where(status: "refused")
|
|
487
|
+
order_by :run
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
policy "TagWhenReleased" do
|
|
492
|
+
on "Registry.ReleaseRequested"
|
|
493
|
+
ask :tag, with: { run: :run }
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
policy "RecordTheTag" do
|
|
497
|
+
on "Registry.ReleaseTagged"
|
|
498
|
+
trigger Registry::Complete, with: { report: :report }
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
policy "RecordTheRefusedTag" do
|
|
502
|
+
on "Registry.ReleaseRefused"
|
|
503
|
+
trigger Registry::Abandon, with: { refusal: :refusal }
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
# A run record for one launch onto the framework, not an adapter: the driving adapters live in `Hecks::Adapters::Driving`.
|
|
507
|
+
aggregate "Launch" do
|
|
508
|
+
description "A way into the framework opened for a project: its launchers, or an MCP server."
|
|
509
|
+
|
|
510
|
+
attribute :run, LaunchKey
|
|
511
|
+
attribute :domains, DomainList, optional: true
|
|
512
|
+
attribute :stdio, Switch, optional: true
|
|
513
|
+
attribute :name, DomainName, optional: true
|
|
514
|
+
attribute :adapter, AdapterName, optional: true
|
|
515
|
+
attribute :dir, TargetDir, optional: true
|
|
516
|
+
attribute :expert, ExpertName, optional: true
|
|
517
|
+
attribute :no_ai, Switch, optional: true
|
|
518
|
+
attribute :output, Note, optional: true
|
|
519
|
+
attribute :refusal, Note, optional: true
|
|
520
|
+
identified_by :run
|
|
521
|
+
|
|
522
|
+
value_object "LaunchKey" do
|
|
523
|
+
attribute :value, String, pattern: '[^ \t\n\r]'
|
|
524
|
+
|
|
525
|
+
invariant("a launch is named") { !value.to_s.empty? }
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
# Domain directories under the project, comma separated.
|
|
529
|
+
value_object "DomainList" do
|
|
530
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
value_object "Switch" do
|
|
534
|
+
attribute :value, Boolean
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
# What a new domain is called, as its bluebook spells it: a capital and then letters and digits.
|
|
538
|
+
value_object "DomainName" do
|
|
539
|
+
attribute :value, String, pattern: '[A-Z][A-Za-z0-9]*'
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
# A persistence adapter a stub can be bound to; `Hecks::CLI::DomainStub` names the ones it knows.
|
|
543
|
+
value_object "AdapterName" do
|
|
544
|
+
attribute :value, String, pattern: '[A-Za-z]+'
|
|
545
|
+
end
|
|
546
|
+
|
|
547
|
+
# Where the new domain goes; the domain's snake-cased name under the current directory when absent.
|
|
548
|
+
value_object "TargetDir" do
|
|
549
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
# Who is interviewed; asked for at the terminal when absent.
|
|
553
|
+
value_object "ExpertName" do
|
|
554
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
value_object "Note" do
|
|
558
|
+
attribute :value, String
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
lifecycle :status, default: "requested" do
|
|
562
|
+
mark :failure, "stopped"
|
|
563
|
+
transition "Finish" => "finished", from: "requested"
|
|
564
|
+
transition "Stop" => "stopped", from: "requested"
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
# Writes a launcher beside each domain. It replaces the generated launcher already there and
|
|
568
|
+
# deletes nothing, so it runs without `confirm` (`hecks project_cli` never asked for one).
|
|
569
|
+
command "ProjectCli" do
|
|
570
|
+
role "Operator"
|
|
571
|
+
goal "Write a command-line launcher beside each domain of this project"
|
|
572
|
+
|
|
573
|
+
attribute :run, LaunchKey
|
|
574
|
+
attribute :domains, DomainList, optional: true
|
|
575
|
+
|
|
576
|
+
sets :run
|
|
577
|
+
sets :domains
|
|
578
|
+
|
|
579
|
+
emits LaunchersRequested
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
# Writes the stub files of a new domain (ADR 0087). It asks nothing and replaces nothing: a
|
|
583
|
+
# directory that already holds any file it would write is refused, with that file named.
|
|
584
|
+
command "Init" do
|
|
585
|
+
role "Operator"
|
|
586
|
+
goal "Write the stub files of a new domain"
|
|
587
|
+
|
|
588
|
+
attribute :run, LaunchKey
|
|
589
|
+
attribute :name, DomainName
|
|
590
|
+
attribute :adapter, AdapterName, optional: true
|
|
591
|
+
attribute :dir, TargetDir, optional: true
|
|
592
|
+
|
|
593
|
+
sets :run
|
|
594
|
+
sets :name
|
|
595
|
+
sets :adapter
|
|
596
|
+
sets :dir
|
|
597
|
+
|
|
598
|
+
emits StubRequested
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
# Holds an interview with a subject matter expert and drafts a first domain from it (ADR 0088).
|
|
602
|
+
# The Terminal adapter runs the conversation, as it runs a console; the journal records that one
|
|
603
|
+
# was held and how it ended, not what was said. `--no-ai` leaves the model out.
|
|
604
|
+
command "Interview" do
|
|
605
|
+
role "Operator"
|
|
606
|
+
goal "Hold an interview with a subject matter expert and draft a first domain from it"
|
|
607
|
+
|
|
608
|
+
attribute :run, LaunchKey
|
|
609
|
+
attribute :name, DomainName
|
|
610
|
+
attribute :adapter, AdapterName, optional: true
|
|
611
|
+
attribute :dir, TargetDir, optional: true
|
|
612
|
+
attribute :expert, ExpertName, optional: true
|
|
613
|
+
attribute :no_ai, Switch, optional: true
|
|
614
|
+
|
|
615
|
+
sets :run
|
|
616
|
+
sets :name
|
|
617
|
+
sets :adapter
|
|
618
|
+
sets :dir
|
|
619
|
+
sets :expert
|
|
620
|
+
sets :no_ai
|
|
621
|
+
|
|
622
|
+
emits InterviewRequested
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
# A stdio server runs until its client closes stdin, so it cannot be asked and answered
|
|
626
|
+
# quickly like the others. The command records that the launch was started; the Terminal
|
|
627
|
+
# adapter hands the process over to the launch and answers when it closes, as OpenConsole
|
|
628
|
+
# does for a console. The launcher spells it `serve_mcp`; the `mcp` spelling exe/hecks ships
|
|
629
|
+
# today stays with its router until the launcher is generated.
|
|
630
|
+
command "ServeMcp" do
|
|
631
|
+
role "Operator"
|
|
632
|
+
goal "Serve the storehouse bus to an MCP client over stdio until it closes"
|
|
633
|
+
|
|
634
|
+
attribute :run, LaunchKey
|
|
635
|
+
attribute :stdio, Switch, optional: true
|
|
636
|
+
|
|
637
|
+
sets :run
|
|
638
|
+
sets :stdio
|
|
639
|
+
|
|
640
|
+
emits McpRequested
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
command "Finish" do
|
|
644
|
+
role "System"
|
|
645
|
+
goal "Record that the launch did its work, or was closed, and what it said"
|
|
646
|
+
|
|
647
|
+
reference_to Launch
|
|
648
|
+
attribute :output, Note
|
|
649
|
+
|
|
650
|
+
sets :output
|
|
651
|
+
|
|
652
|
+
emits LaunchFinished
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
command "Stop" do
|
|
656
|
+
role "System"
|
|
657
|
+
goal "Record that the launch could not be opened, and why"
|
|
658
|
+
|
|
659
|
+
reference_to Launch
|
|
660
|
+
attribute :refusal, Note
|
|
661
|
+
|
|
662
|
+
sets :refusal
|
|
663
|
+
|
|
664
|
+
emits LaunchStopped
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
query "Ended" do
|
|
668
|
+
description "How one launch ended: its status, and what it said or why it stopped."
|
|
669
|
+
attribute :run, LaunchKey
|
|
670
|
+
where(run: :run)
|
|
671
|
+
order_by :run
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
query "Stopped" do
|
|
675
|
+
description "Every launch that could not be opened."
|
|
676
|
+
where(status: "stopped")
|
|
677
|
+
order_by :run
|
|
678
|
+
end
|
|
679
|
+
end
|
|
680
|
+
|
|
681
|
+
policy "WriteWhenRequested" do
|
|
682
|
+
on "Launch.LaunchersRequested"
|
|
683
|
+
ask :write, with: { run: :run }
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
policy "ScaffoldWhenRequested" do
|
|
687
|
+
on "Launch.StubRequested"
|
|
688
|
+
ask :scaffold, with: { run: :run }
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
policy "ConverseWhenRequested" do
|
|
692
|
+
on "Launch.InterviewRequested"
|
|
693
|
+
ask :converse, with: { run: :run }
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
policy "ServeWhenRequested" do
|
|
697
|
+
on "Launch.McpRequested"
|
|
698
|
+
ask :serve, with: { run: :run }
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
policy "RecordTheLaunch" do
|
|
702
|
+
on "Launch.LaunchAnswered"
|
|
703
|
+
trigger Launch::Finish, with: { output: :output }
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
policy "RecordTheStoppedLaunch" do
|
|
707
|
+
on "Launch.LaunchRefused"
|
|
708
|
+
trigger Launch::Stop, with: { refusal: :refusal }
|
|
709
|
+
end
|
|
710
|
+
|
|
711
|
+
aggregate "Build" do
|
|
712
|
+
description "One build of a domain for the Rust host, or a check of that build against Ruby."
|
|
713
|
+
|
|
714
|
+
attribute :run, BuildKey
|
|
715
|
+
attribute :domain, DomainPath, optional: true
|
|
716
|
+
attribute :script, ScriptPath, optional: true
|
|
717
|
+
attribute :artifact, Artifact, optional: true
|
|
718
|
+
attribute :target, TargetTriple, optional: true
|
|
719
|
+
attribute :stage_dir, StagePath, optional: true
|
|
720
|
+
attribute :seeds, Count, optional: true
|
|
721
|
+
attribute :steps, Count, optional: true
|
|
722
|
+
attribute :output, Report, optional: true
|
|
723
|
+
attribute :refusal, Report, optional: true
|
|
724
|
+
identified_by :run
|
|
725
|
+
|
|
726
|
+
value_object "BuildKey" do
|
|
727
|
+
attribute :value, String, pattern: '[^ \t\n\r]'
|
|
728
|
+
|
|
729
|
+
invariant("a build is named") { !value.to_s.empty? }
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
# A domain directory. Its last part is also a Rust module and a Cargo feature, so it is a
|
|
733
|
+
# lowercase identifier; the toolchain refuses the reserved words the pattern cannot.
|
|
734
|
+
value_object "DomainPath" do
|
|
735
|
+
attribute :value, String, pattern: '(^|/)[a-z][a-z0-9_]*/?$'
|
|
736
|
+
end
|
|
737
|
+
|
|
738
|
+
# A generated module: the directory name a domain was built as.
|
|
739
|
+
value_object "ModuleName" do
|
|
740
|
+
attribute :value, String, pattern: '^[a-z][a-z0-9_]*$'
|
|
741
|
+
end
|
|
742
|
+
|
|
743
|
+
# A JSON file of steps for a domain to replay.
|
|
744
|
+
value_object "ScriptPath" do
|
|
745
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
746
|
+
end
|
|
747
|
+
|
|
748
|
+
# What a build is replayed through: `native`, `build` (the domain's own feature), a `.wasm`
|
|
749
|
+
# module, or a binary.
|
|
750
|
+
value_object "Artifact" do
|
|
751
|
+
attribute :value, String, pattern: '[^ \t\n\r]'
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
# A Rust target triple: `<arch>-<vendor>-<os>` with an optional `-<env>`. The toolchain
|
|
755
|
+
# refuses the triples a host cannot be built for (a wasm target) and the ones not installed.
|
|
756
|
+
value_object "TargetTriple" do
|
|
757
|
+
attribute :value, String, pattern: '^[a-z0-9_]+(-[a-z0-9_.]+){2,3}$'
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
# The directory a host build stages its files in.
|
|
761
|
+
value_object "StagePath" do
|
|
762
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
value_object "Count" do
|
|
766
|
+
attribute :value, Integer
|
|
767
|
+
|
|
768
|
+
invariant("a count is positive") { value > 0 }
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
value_object "CodegenName" do
|
|
772
|
+
attribute :value, String, pattern: '^(ruby|rust)$'
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
value_object "Report" do
|
|
776
|
+
attribute :value, String
|
|
777
|
+
end
|
|
778
|
+
|
|
779
|
+
lifecycle :status, default: "requested" do
|
|
780
|
+
mark :failure, "faulted"
|
|
781
|
+
transition "Complete" => "completed", from: "requested"
|
|
782
|
+
transition "Fault" => "faulted", from: "requested"
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
# Writes the domain's Rust source and a Cargo feature for it into the build workspace: the
|
|
786
|
+
# checkout's own `rust/`, or a copy of the packaged workspace under `.hecks/rust/<version>/`.
|
|
787
|
+
# Nothing is ever written into the installed gem.
|
|
788
|
+
command "ProjectRust" do
|
|
789
|
+
role "Operator"
|
|
790
|
+
goal "Generate a domain's Rust source for the Rust host"
|
|
791
|
+
|
|
792
|
+
attribute :domain, DomainPath
|
|
793
|
+
attribute :run, BuildKey
|
|
794
|
+
|
|
795
|
+
sets :domain
|
|
796
|
+
sets :run
|
|
797
|
+
|
|
798
|
+
emits RustProjectionRequested
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
command "BuildWasm" do
|
|
802
|
+
role "Operator"
|
|
803
|
+
goal "Compile a domain to a WASI module a runtime such as wasmtime can run"
|
|
804
|
+
|
|
805
|
+
attribute :domain, DomainPath
|
|
806
|
+
attribute :run, BuildKey
|
|
807
|
+
|
|
808
|
+
sets :domain
|
|
809
|
+
sets :run
|
|
810
|
+
|
|
811
|
+
emits WasmBuildRequested
|
|
812
|
+
end
|
|
813
|
+
|
|
814
|
+
# Compiles the host binary from the installed gem's workspace for the target and stages it with
|
|
815
|
+
# the domain's `.wasm` and `.ir.json` (in `.hecks/host/<target>/` unless `stage_dir` names a
|
|
816
|
+
# directory), the files a container image copies in.
|
|
817
|
+
command "BuildHost" do
|
|
818
|
+
role "Operator"
|
|
819
|
+
goal "Build the Rust host for a domain, with its wasm and IR, ready to copy into an image"
|
|
820
|
+
|
|
821
|
+
attribute :domain, DomainPath
|
|
822
|
+
attribute :run, BuildKey
|
|
823
|
+
attribute :target, TargetTriple, optional: true
|
|
824
|
+
attribute :stage_dir, StagePath, optional: true
|
|
825
|
+
|
|
826
|
+
sets :domain
|
|
827
|
+
sets :run
|
|
828
|
+
sets :target
|
|
829
|
+
sets :stage_dir
|
|
830
|
+
|
|
831
|
+
emits HostBuildRequested
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
command "BuildBrowserWasm" do
|
|
835
|
+
role "Operator"
|
|
836
|
+
goal "Compile a domain to an ES module a browser can import"
|
|
837
|
+
|
|
838
|
+
attribute :domain, DomainPath
|
|
839
|
+
attribute :run, BuildKey
|
|
840
|
+
|
|
841
|
+
sets :domain
|
|
842
|
+
sets :run
|
|
843
|
+
|
|
844
|
+
emits BrowserWasmBuildRequested
|
|
845
|
+
end
|
|
846
|
+
|
|
847
|
+
# Without an artifact it answers Ruby's own result, which saved to a file becomes a pinned
|
|
848
|
+
# expectation; with one it compares Ruby's result with that artifact's.
|
|
849
|
+
command "CheckConformance" do
|
|
850
|
+
role "Operator"
|
|
851
|
+
goal "Replay a script through Ruby and a Rust build of the domain and compare what each did"
|
|
852
|
+
|
|
853
|
+
attribute :domain, DomainPath
|
|
854
|
+
attribute :script, ScriptPath
|
|
855
|
+
attribute :run, BuildKey
|
|
856
|
+
attribute :artifact, Artifact, optional: true
|
|
857
|
+
|
|
858
|
+
sets :domain
|
|
859
|
+
sets :script
|
|
860
|
+
sets :run
|
|
861
|
+
sets :artifact
|
|
862
|
+
|
|
863
|
+
emits ConformanceRequested
|
|
864
|
+
end
|
|
865
|
+
|
|
866
|
+
command "FuzzConformance" do
|
|
867
|
+
role "Operator"
|
|
868
|
+
goal "Replay generated sequences through Ruby and a Rust build of the domain and compare them"
|
|
869
|
+
|
|
870
|
+
attribute :domain, DomainPath
|
|
871
|
+
attribute :artifact, Artifact
|
|
872
|
+
attribute :run, BuildKey
|
|
873
|
+
attribute :seeds, Count, optional: true
|
|
874
|
+
attribute :steps, Count, optional: true
|
|
875
|
+
|
|
876
|
+
sets :domain
|
|
877
|
+
sets :artifact
|
|
878
|
+
sets :run
|
|
879
|
+
sets :seeds
|
|
880
|
+
sets :steps
|
|
881
|
+
|
|
882
|
+
emits ConformanceFuzzRequested
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
command "CheckCoverageAllowlist" do
|
|
886
|
+
role "Operator"
|
|
887
|
+
goal "Check that every rule excusing a Rust coverage gap still excuses a real one"
|
|
888
|
+
|
|
889
|
+
attribute :run, BuildKey
|
|
890
|
+
|
|
891
|
+
sets :run
|
|
892
|
+
|
|
893
|
+
emits CoverageAllowlistRequested
|
|
894
|
+
end
|
|
895
|
+
|
|
896
|
+
command "Complete" do
|
|
897
|
+
role "System"
|
|
898
|
+
goal "Record that the build or check ended well, and what it reported"
|
|
899
|
+
|
|
900
|
+
reference_to Build
|
|
901
|
+
attribute :output, Report
|
|
902
|
+
|
|
903
|
+
sets :output
|
|
904
|
+
|
|
905
|
+
emits BuildCompleted
|
|
906
|
+
end
|
|
907
|
+
|
|
908
|
+
command "Fault" do
|
|
909
|
+
role "System"
|
|
910
|
+
goal "Record that the build or check was refused or found a difference, and what it said"
|
|
911
|
+
|
|
912
|
+
reference_to Build
|
|
913
|
+
attribute :refusal, Report
|
|
914
|
+
|
|
915
|
+
sets :refusal
|
|
916
|
+
|
|
917
|
+
emits BuildFaulted
|
|
918
|
+
end
|
|
919
|
+
|
|
920
|
+
query "Result" do
|
|
921
|
+
description "How one build or check ended: its status, and what it reported or why it failed."
|
|
922
|
+
attribute :run, BuildKey
|
|
923
|
+
where(run: :run)
|
|
924
|
+
order_by :run
|
|
925
|
+
end
|
|
926
|
+
|
|
927
|
+
query "Faulted" do
|
|
928
|
+
description "Every build or check that was refused or found a difference."
|
|
929
|
+
where(status: "faulted")
|
|
930
|
+
order_by :run
|
|
931
|
+
end
|
|
932
|
+
|
|
933
|
+
# An answer that is one document of text, exactly as the tool that produced it wrote it.
|
|
934
|
+
value_object "Document" do
|
|
935
|
+
attribute :text, String
|
|
936
|
+
end
|
|
937
|
+
|
|
938
|
+
query "RustCoverage" do
|
|
939
|
+
description "Whether each construct of a generated module has a routed Rust implementation."
|
|
940
|
+
attribute :module_name, ModuleName
|
|
941
|
+
attribute :codegen, CodegenName, optional: true
|
|
942
|
+
returns Document
|
|
943
|
+
end
|
|
944
|
+
end
|
|
945
|
+
|
|
946
|
+
policy "GenerateWhenRequested" do
|
|
947
|
+
on "Build.RustProjectionRequested"
|
|
948
|
+
ask :generate, with: { run: :run }
|
|
949
|
+
end
|
|
950
|
+
|
|
951
|
+
policy "CompileWasmWhenRequested" do
|
|
952
|
+
on "Build.WasmBuildRequested"
|
|
953
|
+
ask :wasm, with: { run: :run }
|
|
954
|
+
end
|
|
955
|
+
|
|
956
|
+
policy "BuildHostWhenRequested" do
|
|
957
|
+
on "Build.HostBuildRequested"
|
|
958
|
+
ask :host, with: { run: :run }
|
|
959
|
+
end
|
|
960
|
+
|
|
961
|
+
policy "CompileBrowserWasmWhenRequested" do
|
|
962
|
+
on "Build.BrowserWasmBuildRequested"
|
|
963
|
+
ask :browser_wasm, with: { run: :run }
|
|
964
|
+
end
|
|
965
|
+
|
|
966
|
+
policy "ConformWhenRequested" do
|
|
967
|
+
on "Build.ConformanceRequested"
|
|
968
|
+
ask :conform, with: { run: :run }
|
|
969
|
+
end
|
|
970
|
+
|
|
971
|
+
policy "ReplayWhenRequested" do
|
|
972
|
+
on "Build.ConformanceFuzzRequested"
|
|
973
|
+
ask :replay, with: { run: :run }
|
|
974
|
+
end
|
|
975
|
+
|
|
976
|
+
policy "AuditWhenRequested" do
|
|
977
|
+
on "Build.CoverageAllowlistRequested"
|
|
978
|
+
ask :audit, with: { run: :run }
|
|
979
|
+
end
|
|
980
|
+
|
|
981
|
+
policy "RecordTheBuild" do
|
|
982
|
+
on "Build.BuildAnswered"
|
|
983
|
+
trigger Build::Complete, with: { output: :output }
|
|
984
|
+
end
|
|
985
|
+
|
|
986
|
+
policy "RecordTheFault" do
|
|
987
|
+
on "Build.BuildRefused"
|
|
988
|
+
trigger Build::Fault, with: { refusal: :refusal }
|
|
989
|
+
end
|
|
990
|
+
|
|
991
|
+
# Named for the run, as ModelCheckRun is: `Hecks::Fuzzing` is the fuzzing toolkit's own module,
|
|
992
|
+
# so a hecksagon could not spell an aggregate of that name.
|
|
993
|
+
aggregate "FuzzRun" do
|
|
994
|
+
description "One fuzz sweep or benchmark, and how it ended; and the generated sequences it replays."
|
|
995
|
+
|
|
996
|
+
attribute :domain, DomainPath, optional: true
|
|
997
|
+
attribute :run, FuzzKey
|
|
998
|
+
attribute :seeds, Count, optional: true
|
|
999
|
+
attribute :steps, Count, optional: true
|
|
1000
|
+
attribute :workers, Count, optional: true
|
|
1001
|
+
attribute :budget, Count, optional: true
|
|
1002
|
+
attribute :adapter, Persistence, optional: true
|
|
1003
|
+
attribute :persist_regressions, RegressionSwitch, optional: true
|
|
1004
|
+
attribute :domains, NameList, optional: true
|
|
1005
|
+
attribute :targets, NameList, optional: true
|
|
1006
|
+
attribute :iterations, Count, optional: true
|
|
1007
|
+
attribute :warmup, Warmup, optional: true
|
|
1008
|
+
attribute :runs, Count, optional: true
|
|
1009
|
+
attribute :rust_binary, BinaryPath, optional: true
|
|
1010
|
+
attribute :format, Format, optional: true
|
|
1011
|
+
attribute :output, OutputPath, optional: true
|
|
1012
|
+
attribute :report, Report, optional: true
|
|
1013
|
+
attribute :refusal, Report, optional: true
|
|
1014
|
+
identified_by :run
|
|
1015
|
+
|
|
1016
|
+
value_object "FuzzKey" do
|
|
1017
|
+
attribute :value, String, pattern: '[^ \t\n\r]'
|
|
1018
|
+
|
|
1019
|
+
invariant("a sweep is named") { !value.to_s.empty? }
|
|
1020
|
+
end
|
|
1021
|
+
|
|
1022
|
+
# A domain directory; a sweep with none covers every domain of a hecks checkout.
|
|
1023
|
+
value_object "DomainPath" do
|
|
1024
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
1025
|
+
|
|
1026
|
+
invariant("a domain is named by its path") { !value.to_s.empty? }
|
|
1027
|
+
end
|
|
1028
|
+
|
|
1029
|
+
value_object "Count" do
|
|
1030
|
+
attribute :value, Integer
|
|
1031
|
+
|
|
1032
|
+
invariant("a count is positive") { value > 0 }
|
|
1033
|
+
end
|
|
1034
|
+
|
|
1035
|
+
value_object "Warmup" do
|
|
1036
|
+
attribute :value, Integer
|
|
1037
|
+
|
|
1038
|
+
invariant("a warmup is not negative") { value >= 0 }
|
|
1039
|
+
end
|
|
1040
|
+
|
|
1041
|
+
# Which persistence every ephemeral boot of a sweep uses.
|
|
1042
|
+
value_object "Persistence" do
|
|
1043
|
+
attribute :value, String, pattern: '^(memory|sqlite|postgres)$'
|
|
1044
|
+
end
|
|
1045
|
+
|
|
1046
|
+
# Whether each distinct finding's minimized repro is also kept under `spec/corpus/regressions/`.
|
|
1047
|
+
value_object "RegressionSwitch" do
|
|
1048
|
+
attribute :value, Boolean
|
|
1049
|
+
end
|
|
1050
|
+
|
|
1051
|
+
# Names, comma separated: benchmark domains, or the targets to measure.
|
|
1052
|
+
value_object "NameList" do
|
|
1053
|
+
attribute :value, String, pattern: '^[^ \t\n\r,]+(,[^ \t\n\r,]+)*$'
|
|
1054
|
+
end
|
|
1055
|
+
|
|
1056
|
+
value_object "BinaryPath" do
|
|
1057
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
1058
|
+
end
|
|
1059
|
+
|
|
1060
|
+
value_object "Format" do
|
|
1061
|
+
attribute :value, String, pattern: '^(markdown|json)$'
|
|
1062
|
+
end
|
|
1063
|
+
|
|
1064
|
+
value_object "OutputPath" do
|
|
1065
|
+
attribute :value, String, pattern: '[^\t\n\r]'
|
|
1066
|
+
end
|
|
1067
|
+
|
|
1068
|
+
value_object "Report" do
|
|
1069
|
+
attribute :value, String
|
|
1070
|
+
end
|
|
1071
|
+
|
|
1072
|
+
lifecycle :status, default: "requested" do
|
|
1073
|
+
mark :failure, "halted"
|
|
1074
|
+
transition "Conclude" => "concluded", from: "requested"
|
|
1075
|
+
transition "Halt" => "halted", from: "requested"
|
|
1076
|
+
end
|
|
1077
|
+
|
|
1078
|
+
# A sweep replays generated command and query sequences and checks properties over each.
|
|
1079
|
+
# A finding is shrunk and saved under `tmp/fuzz-failures/`, and ends the run as halted, with
|
|
1080
|
+
# what was found. Sweeping every domain of a checkout needs a hecks checkout; a client names
|
|
1081
|
+
# the domain. The sweep runs in child processes started through the ProcessPool adapter, so an
|
|
1082
|
+
# interrupt reaches the workers.
|
|
1083
|
+
command "Fuzz" do
|
|
1084
|
+
role "Operator"
|
|
1085
|
+
goal "Fuzz a domain with generated sequences and keep whether anything broke a property"
|
|
1086
|
+
|
|
1087
|
+
attribute :domain, DomainPath, optional: true
|
|
1088
|
+
attribute :run, FuzzKey
|
|
1089
|
+
attribute :seeds, Count, optional: true
|
|
1090
|
+
attribute :steps, Count, optional: true
|
|
1091
|
+
attribute :workers, Count, optional: true
|
|
1092
|
+
attribute :adapter, Persistence, optional: true
|
|
1093
|
+
attribute :persist_regressions, RegressionSwitch, optional: true
|
|
1094
|
+
|
|
1095
|
+
sets :domain
|
|
1096
|
+
sets :run
|
|
1097
|
+
sets :seeds
|
|
1098
|
+
sets :steps
|
|
1099
|
+
sets :workers
|
|
1100
|
+
sets :adapter
|
|
1101
|
+
sets :persist_regressions
|
|
1102
|
+
|
|
1103
|
+
emits FuzzRequested
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1106
|
+
# Mutation-tests a domain's own checks: changes its bluebooks in small ways and keeps which
|
|
1107
|
+
# changes the fuzz properties, the corpus script and the domain's behaviors tests let through.
|
|
1108
|
+
# A survivor is a hole in those checks. `budget` caps how many mutants are tried. The run is a
|
|
1109
|
+
# child process started through the ProcessPool adapter, as a sweep is.
|
|
1110
|
+
command "Mutate" do
|
|
1111
|
+
role "Operator"
|
|
1112
|
+
goal "Mutate a domain's rules and keep whether its checks noticed each change"
|
|
1113
|
+
|
|
1114
|
+
attribute :domain, DomainPath
|
|
1115
|
+
attribute :run, FuzzKey
|
|
1116
|
+
attribute :seeds, Count, optional: true
|
|
1117
|
+
attribute :steps, Count, optional: true
|
|
1118
|
+
attribute :budget, Count, optional: true
|
|
1119
|
+
|
|
1120
|
+
sets :domain
|
|
1121
|
+
sets :run
|
|
1122
|
+
sets :seeds
|
|
1123
|
+
sets :steps
|
|
1124
|
+
sets :budget
|
|
1125
|
+
|
|
1126
|
+
emits MutateRequested
|
|
1127
|
+
end
|
|
1128
|
+
|
|
1129
|
+
# Measures each persistence adapter, and the Rust binary when there is one to build or use.
|
|
1130
|
+
# The report is kept in this record, which the Hecks domain binds to Memory: keeping a
|
|
1131
|
+
# domain's benchmark history beside it, in Sqlite under the project's `.hecks/`, is decided
|
|
1132
|
+
# with the persistence binding for Custodian, not here. `output` also writes the full JSON.
|
|
1133
|
+
command "Bench" do
|
|
1134
|
+
role "Operator"
|
|
1135
|
+
goal "Measure command throughput and latency for each target, and keep the report"
|
|
1136
|
+
|
|
1137
|
+
attribute :run, FuzzKey
|
|
1138
|
+
attribute :domains, NameList, optional: true
|
|
1139
|
+
attribute :targets, NameList, optional: true
|
|
1140
|
+
attribute :iterations, Count, optional: true
|
|
1141
|
+
attribute :warmup, Warmup, optional: true
|
|
1142
|
+
attribute :runs, Count, optional: true
|
|
1143
|
+
attribute :rust_binary, BinaryPath, optional: true
|
|
1144
|
+
attribute :format, Format, optional: true
|
|
1145
|
+
attribute :output, OutputPath, optional: true
|
|
1146
|
+
|
|
1147
|
+
sets :run
|
|
1148
|
+
sets :domains
|
|
1149
|
+
sets :targets
|
|
1150
|
+
sets :iterations
|
|
1151
|
+
sets :warmup
|
|
1152
|
+
sets :runs
|
|
1153
|
+
sets :rust_binary
|
|
1154
|
+
sets :format
|
|
1155
|
+
sets :output
|
|
1156
|
+
|
|
1157
|
+
emits BenchRequested
|
|
1158
|
+
end
|
|
1159
|
+
|
|
1160
|
+
command "Conclude" do
|
|
1161
|
+
role "System"
|
|
1162
|
+
goal "Record that the sweep or benchmark ended well, and what it reported"
|
|
1163
|
+
|
|
1164
|
+
reference_to FuzzRun
|
|
1165
|
+
attribute :report, Report
|
|
1166
|
+
|
|
1167
|
+
sets :report
|
|
1168
|
+
|
|
1169
|
+
emits FuzzConcluded
|
|
1170
|
+
end
|
|
1171
|
+
|
|
1172
|
+
command "Halt" do
|
|
1173
|
+
role "System"
|
|
1174
|
+
goal "Record that the sweep found something or the benchmark could not run, and what it said"
|
|
1175
|
+
|
|
1176
|
+
reference_to FuzzRun
|
|
1177
|
+
attribute :refusal, Report
|
|
1178
|
+
|
|
1179
|
+
sets :refusal
|
|
1180
|
+
|
|
1181
|
+
emits FuzzHalted
|
|
1182
|
+
end
|
|
1183
|
+
|
|
1184
|
+
query "Conclusion" do
|
|
1185
|
+
description "How one sweep or benchmark ended: its status, and what it reported or found."
|
|
1186
|
+
attribute :run, FuzzKey
|
|
1187
|
+
where(run: :run)
|
|
1188
|
+
order_by :run
|
|
1189
|
+
end
|
|
1190
|
+
|
|
1191
|
+
query "Halted" do
|
|
1192
|
+
description "Every sweep that found something and every benchmark that could not run."
|
|
1193
|
+
where(status: "halted")
|
|
1194
|
+
order_by :run
|
|
1195
|
+
end
|
|
1196
|
+
|
|
1197
|
+
# An answer that is one document of text, exactly as the tool that produced it wrote it.
|
|
1198
|
+
value_object "Document" do
|
|
1199
|
+
attribute :text, String
|
|
1200
|
+
end
|
|
1201
|
+
|
|
1202
|
+
# The generator `hecks fuzz` draws from, on its own: one valid dispatch sequence as a
|
|
1203
|
+
# replayable script. `adversarial` is the fraction of steps mutated to be refused; 0 is off.
|
|
1204
|
+
query "GenerateSequence" do
|
|
1205
|
+
description "One generated, valid dispatch sequence for a domain, as a script `hecks run` replays."
|
|
1206
|
+
attribute :domain, DomainPath
|
|
1207
|
+
attribute :seed, Integer, optional: true
|
|
1208
|
+
attribute :steps, Integer, optional: true
|
|
1209
|
+
attribute :adversarial, Float, optional: true
|
|
1210
|
+
returns Document
|
|
1211
|
+
end
|
|
1212
|
+
end
|
|
1213
|
+
|
|
1214
|
+
policy "SweepWhenRequested" do
|
|
1215
|
+
on "FuzzRun.FuzzRequested"
|
|
1216
|
+
ask :sweep, with: { run: :run }
|
|
1217
|
+
end
|
|
1218
|
+
|
|
1219
|
+
policy "MutateWhenRequested" do
|
|
1220
|
+
on "FuzzRun.MutateRequested"
|
|
1221
|
+
ask :probe, with: { run: :run }
|
|
1222
|
+
end
|
|
1223
|
+
|
|
1224
|
+
policy "MeasureWhenRequested" do
|
|
1225
|
+
on "FuzzRun.BenchRequested"
|
|
1226
|
+
ask :measure, with: { run: :run }
|
|
1227
|
+
end
|
|
1228
|
+
|
|
1229
|
+
policy "RecordTheSweep" do
|
|
1230
|
+
on "FuzzRun.FuzzAnswered"
|
|
1231
|
+
trigger FuzzRun::Conclude, with: { report: :report }
|
|
1232
|
+
end
|
|
1233
|
+
|
|
1234
|
+
policy "RecordTheFinding" do
|
|
1235
|
+
on "FuzzRun.FuzzRefused"
|
|
1236
|
+
trigger FuzzRun::Halt, with: { refusal: :refusal }
|
|
1237
|
+
end
|
|
1238
|
+
end
|