hecks 2.7.0 → 2.9.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 +11 -0
- data/lib/hecks/adapters/driven/claude_code.rb +4 -104
- data/lib/hecks/adapters/driven/d1.rb +44 -237
- data/lib/hecks/adapters/driven/folder.rb +17 -76
- data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
- data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
- data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
- data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
- data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
- data/lib/hecks/adapters/driven/heki.rb +13 -42
- data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
- data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
- data/lib/hecks/adapters/driven/lambda.rb +10 -84
- data/lib/hecks/adapters/driven/local_storage.rb +5 -40
- data/lib/hecks/adapters/driven/memory.rb +18 -99
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
- data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
- data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +4 -30
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
- data/lib/hecks/adapters/driven/postgres.rb +145 -134
- data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
- data/lib/hecks/adapters/driven/prism.rb +7 -30
- data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
- data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
- data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
- data/lib/hecks/adapters/driven/sqlite.rb +128 -65
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +15 -37
- data/lib/hecks/adapters/driven.rb +5 -36
- data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
- data/lib/hecks/behaviors/dsl.rb +7 -25
- data/lib/hecks/behaviors/expectations.rb +32 -142
- data/lib/hecks/behaviors/ir.rb +7 -20
- data/lib/hecks/behaviors/rspec.rb +6 -17
- data/lib/hecks/behaviors/runner.rb +10 -34
- data/lib/hecks/behaviors.rb +4 -8
- data/lib/hecks/bluebook/aggregate.rb +9 -75
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
- data/lib/hecks/bluebook/assembly/build.rb +4 -15
- data/lib/hecks/bluebook/assembly/contract.rb +15 -136
- data/lib/hecks/bluebook/assembly/contracts.rb +54 -174
- data/lib/hecks/bluebook/assembly/marks.rb +31 -223
- data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
- data/lib/hecks/bluebook/assembly.rb +6 -45
- data/lib/hecks/bluebook/attribute.rb +12 -61
- data/lib/hecks/bluebook/behaviour/aggregate.rb +10 -39
- data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
- data/lib/hecks/bluebook/behaviour/chapter.rb +17 -42
- data/lib/hecks/bluebook/behaviour/command.rb +14 -66
- data/lib/hecks/bluebook/behaviour/domain_port.rb +4 -20
- data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
- data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
- data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
- data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
- data/lib/hecks/bluebook/behaviour/read_model.rb +38 -26
- data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
- data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
- data/lib/hecks/bluebook/capabilities.rb +17 -49
- data/lib/hecks/bluebook/chapter.rb +10 -48
- data/lib/hecks/bluebook/command.rb +23 -81
- data/lib/hecks/bluebook/domain_port.rb +14 -63
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +17 -65
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +86 -708
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +56 -170
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +1 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
- data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +12 -87
- data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +26 -189
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
- data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
- data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
- data/lib/hecks/bluebook/dsl/query_builder.rb +11 -42
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
- data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
- data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
- data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
- data/lib/hecks/bluebook/dsl/world_builder.rb +19 -106
- data/lib/hecks/bluebook/entity.rb +13 -71
- data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
- data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
- data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
- data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
- data/lib/hecks/bluebook/expression/resolver.rb +37 -660
- data/lib/hecks/bluebook/hexagon.rb +5 -28
- data/lib/hecks/bluebook/lifecycle.rb +5 -16
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
- data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
- data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
- data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +24 -176
- data/lib/hecks/bluebook/meta_validator/shapes.rb +54 -268
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -308
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
- data/lib/hecks/bluebook/meta_validator.rb +79 -349
- data/lib/hecks/bluebook/model_check/client_profile.rb +10 -91
- data/lib/hecks/bluebook/model_check.rb +102 -600
- data/lib/hecks/bluebook/pattern_subset.rb +11 -69
- data/lib/hecks/bluebook/process_manager.rb +13 -83
- data/lib/hecks/bluebook/project_loader.rb +3 -39
- data/lib/hecks/bluebook/project_register.rb +12 -60
- data/lib/hecks/bluebook/query.rb +9 -48
- data/lib/hecks/bluebook/read_model.rb +57 -81
- data/lib/hecks/bluebook/reference.rb +7 -41
- data/lib/hecks/bluebook/smoke_test.rb +8 -98
- data/lib/hecks/bluebook/synthesizer.rb +13 -62
- data/lib/hecks/bluebook/translation.rb +26 -62
- data/lib/hecks/bluebook/value_object.rb +11 -36
- data/lib/hecks/bluebook.rb +5 -22
- data/lib/hecks/cache_dir.rb +84 -0
- data/lib/hecks/cli/document.rb +86 -0
- data/lib/hecks/cli/ir.rb +45 -0
- data/lib/hecks/cli/mcp.rb +31 -0
- data/lib/hecks/cli/mcp_door.rb +366 -0
- data/lib/hecks/cli/model_check.rb +203 -0
- data/lib/hecks/cli/project_cli.rb +90 -0
- data/lib/hecks/cli/project_diagrams.rb +36 -0
- data/lib/hecks/cli/run.rb +173 -0
- data/lib/hecks/cli/smoke_test.rb +45 -0
- data/lib/hecks/cli/stores.rb +53 -0
- data/lib/hecks/cli.rb +160 -0
- data/lib/hecks/construct.rb +8 -34
- data/lib/hecks/deploy/bluebook/deploy.bluebook +33 -142
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +2 -9
- data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
- data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
- data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
- data/lib/hecks/embryonaut_bluebook.rb +4 -71
- data/lib/hecks/facade/cli_door.rb +24 -106
- data/lib/hecks/facade/cli_runner.rb +28 -172
- data/lib/hecks/facade/command_request.rb +13 -33
- data/lib/hecks/facade/handle.rb +34 -121
- data/lib/hecks/facade/json_door.rb +31 -146
- data/lib/hecks/facade/surface/aggregate_door.rb +39 -104
- data/lib/hecks/facade/surface/chapter.rb +10 -54
- data/lib/hecks/facade/surface.rb +8 -23
- data/lib/hecks/facade.rb +10 -25
- data/lib/hecks/forms/app.rb +15 -70
- data/lib/hecks/forms/command_form_renderer.rb +10 -29
- data/lib/hecks/forms/field_renderer.rb +17 -156
- data/lib/hecks/forms/field_shape.rb +30 -222
- data/lib/hecks/forms/html.rb +12 -47
- data/lib/hecks/forms/index_renderer.rb +1 -4
- data/lib/hecks/forms/page.rb +3 -9
- data/lib/hecks/forms/params.rb +14 -60
- data/lib/hecks/forms/port_argument.rb +2 -19
- data/lib/hecks/forms/query_form_renderer.rb +4 -79
- data/lib/hecks/forms/record_renderer.rb +8 -75
- data/lib/hecks/forms/record_table.rb +7 -50
- data/lib/hecks/forms/reference_options.rb +3 -30
- data/lib/hecks/forms/value_object_shape.rb +8 -35
- data/lib/hecks/forms.rb +5 -33
- data/lib/hecks/fqn.rb +5 -12
- data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
- data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
- data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
- data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
- data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
- data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
- data/lib/hecks/framework.rb +11 -80
- data/lib/hecks/freezer.rb +5 -39
- data/lib/hecks/grammar/expression.bluebook +15 -40
- data/lib/hecks/grammar/translation.bluebook +3 -6
- data/lib/hecks/grammar.rb +16 -41
- data/lib/hecks/ir.rb +14 -83
- data/lib/hecks/language/adapter.bluebook +2 -7
- data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
- data/lib/hecks/language/bluebook/bluebook.bluebook +15 -83
- data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
- data/lib/hecks/language/bluebook/command.bluebook +27 -144
- data/lib/hecks/language/bluebook/entity.bluebook +24 -97
- data/lib/hecks/language/bluebook/policy.bluebook +16 -67
- data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
- data/lib/hecks/language/bluebook/projection.bluebook +126 -60
- data/lib/hecks/language/bluebook/query.bluebook +12 -43
- data/lib/hecks/language/bluebook/shape.bluebook +23 -73
- data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
- data/lib/hecks/language/bluebook/vocabulary.bluebook +98 -197
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
- data/lib/hecks/language/hecksagon/domain_port.bluebook +4 -19
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +6 -25
- data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
- data/lib/hecks/language/oidc.json +35 -0
- data/lib/hecks/language/port.bluebook +4 -17
- data/lib/hecks/language/translation/translation.bluebook +3 -9
- data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
- data/lib/hecks/language/world/wiring.bluebook +1 -3
- data/lib/hecks/language/world/world.bluebook +5 -7
- data/lib/hecks/literal.rb +8 -50
- data/lib/hecks/mcp_door_scope.rb +95 -0
- data/lib/hecks/mcp_stdio_guard.rb +4 -41
- data/lib/hecks/naming.rb +29 -137
- data/lib/hecks/ports/access_control.rb +7 -23
- data/lib/hecks/ports/agent/answers.rb +5 -23
- data/lib/hecks/ports/agent.rb +47 -172
- data/lib/hecks/ports/authentication.rb +12 -39
- data/lib/hecks/ports/authorization.rb +16 -43
- data/lib/hecks/ports/clock.rb +5 -45
- data/lib/hecks/ports/extraction.rb +7 -12
- data/lib/hecks/ports/identity_assignment.rb +8 -29
- data/lib/hecks/ports/identity_generation.rb +6 -29
- data/lib/hecks/ports/identity_resolution.rb +2 -10
- data/lib/hecks/ports/key_vault.rb +9 -45
- data/lib/hecks/ports/persistence/append_only.rb +62 -65
- data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
- data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
- data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
- data/lib/hecks/ports/persistence/plugin.rb +13 -42
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +38 -141
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +16 -84
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +7 -26
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +3 -22
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +18 -75
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +14 -115
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +127 -554
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +9 -25
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +22 -122
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
- data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
- data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
- data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
- data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
- data/lib/hecks/ports/persistence/state_codec.rb +23 -103
- data/lib/hecks/ports/persistence.rb +7 -14
- data/lib/hecks/ports/projection.rb +42 -84
- data/lib/hecks/ports/query/in_memory.rb +10 -58
- data/lib/hecks/ports/query/ordering.rb +11 -32
- data/lib/hecks/ports/query.rb +14 -37
- data/lib/hecks/ports.rb +2 -8
- data/lib/hecks/projections/bootstrap_table.rb +11 -43
- data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
- data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
- data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
- data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
- data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
- data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
- data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
- data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
- data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
- data/lib/hecks/projections/deploy/fargate.rb +35 -202
- data/lib/hecks/projections/deploy/lambda.rb +151 -679
- data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
- data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
- data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
- data/lib/hecks/projections/deploy/preview/script.rb +2 -14
- data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
- data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
- data/lib/hecks/projections/deploy/preview/template.rb +2 -58
- data/lib/hecks/projections/deploy/preview.rb +2 -67
- data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
- data/lib/hecks/projections/deploy/scripts.rb +4 -57
- data/lib/hecks/projections/deploy/shared.rb +47 -146
- data/lib/hecks/projections/deploy/smoke.rb +4 -61
- data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
- data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
- data/lib/hecks/projections/deploy/template_diff.rb +5 -57
- data/lib/hecks/projections/diagrams.rb +20 -582
- data/lib/hecks/projections/glossary/html.rb +14 -130
- data/lib/hecks/projections/glossary/markdown.rb +8 -69
- data/lib/hecks/projections/glossary/mermaid.rb +9 -66
- data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
- data/lib/hecks/projections/glossary/sentences.rb +14 -159
- data/lib/hecks/projections/glossary.rb +30 -222
- data/lib/hecks/projections/ir.rb +3 -10
- data/lib/hecks/projections/model/deviations.rb +15 -42
- data/lib/hecks/projections/model.rb +12 -51
- data/lib/hecks/projections/oidc.rb +12 -56
- data/lib/hecks/projections/parser_table.rb +9 -28
- data/lib/hecks/projections/reference.rb +9 -16
- data/lib/hecks/projections/rust_vocabulary.rb +12 -250
- data/lib/hecks/projections/shape.rb +3 -29
- data/lib/hecks/projections/statements.rb +7 -86
- data/lib/hecks/projections/vocabulary.rb +6 -22
- data/lib/hecks/projections.rb +2 -16
- data/lib/hecks/projector/cli_projector.rb +60 -375
- data/lib/hecks/projector/docs_projector.rb +10 -201
- data/lib/hecks/projector/exporter.rb +46 -138
- data/lib/hecks/projector/ir_projector.rb +2 -9
- data/lib/hecks/projector/narrate_projector.rb +15 -189
- data/lib/hecks/projector/target.rb +13 -76
- data/lib/hecks/projector.rb +30 -121
- data/lib/hecks/query_specification/common/comparators.rb +5 -26
- data/lib/hecks/query_specification/common/comparison.rb +35 -143
- data/lib/hecks/query_specification/common/dsl.rb +8 -24
- data/lib/hecks/query_specification/common/null_policy.rb +20 -70
- data/lib/hecks/query_specification/common/options.rb +2 -6
- data/lib/hecks/query_specification/common/where_clause.rb +2 -10
- data/lib/hecks/query_specification/field_path.rb +37 -77
- data/lib/hecks/query_specification/hop_path.rb +12 -76
- data/lib/hecks/release/gem_pin.rb +2 -26
- data/lib/hecks/release/runner/ci_publisher.rb +93 -0
- data/lib/hecks/release/runner/commands.rb +66 -0
- data/lib/hecks/release/runner/console.rb +52 -0
- data/lib/hecks/release/runner/gem_publisher.rb +43 -0
- data/lib/hecks/release/runner/git.rb +48 -0
- data/lib/hecks/release/runner/npm_publisher.rb +75 -0
- data/lib/hecks/release/runner/preflight.rb +104 -0
- data/lib/hecks/release/runner/published.rb +55 -0
- data/lib/hecks/release/runner/tagger.rb +80 -0
- data/lib/hecks/release/runner.rb +215 -0
- data/lib/hecks/rendering.rb +4 -26
- data/lib/hecks/router/namespace_installer.rb +12 -36
- data/lib/hecks/router.rb +4 -8
- data/lib/hecks/runtime/aggregate_lock.rb +8 -33
- data/lib/hecks/runtime/boot_gates.rb +3 -18
- data/lib/hecks/runtime/caller.rb +19 -59
- data/lib/hecks/runtime/capability_graph.rb +5 -21
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +23 -160
- data/lib/hecks/runtime/command_interpreter.rb +125 -307
- data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
- data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
- data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
- data/lib/hecks/runtime/command_rules/emission.rb +8 -21
- data/lib/hecks/runtime/command_rules/references.rb +23 -202
- data/lib/hecks/runtime/dependency_planning.rb +30 -102
- data/lib/hecks/runtime/dispatcher.rb +82 -241
- data/lib/hecks/runtime/entity_element.rb +40 -462
- data/lib/hecks/runtime/entity_interpreter.rb +65 -220
- data/lib/hecks/runtime/errors.rb +32 -115
- data/lib/hecks/runtime/event.rb +3 -25
- data/lib/hecks/runtime/identity.rb +18 -154
- data/lib/hecks/runtime/instance.rb +18 -150
- data/lib/hecks/runtime/interpreting.rb +11 -70
- data/lib/hecks/runtime/invocation.rb +28 -164
- data/lib/hecks/runtime/loader.rb +48 -186
- data/lib/hecks/runtime/outbox.rb +38 -261
- data/lib/hecks/runtime/policy_interpreter.rb +38 -200
- data/lib/hecks/runtime/port_operation_interpreter.rb +26 -87
- data/lib/hecks/runtime/query_interpreter.rb +45 -187
- data/lib/hecks/runtime/reaction_invocation.rb +36 -138
- data/lib/hecks/runtime/read_model_interpreter.rb +139 -208
- data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
- data/lib/hecks/runtime/reference_hop.rb +8 -81
- data/lib/hecks/runtime/refusal_wording.rb +8 -89
- data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
- data/lib/hecks/runtime/registry/verification.rb +52 -225
- data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
- data/lib/hecks/runtime/registry.rb +103 -244
- data/lib/hecks/runtime/remote_dispatcher.rb +37 -152
- data/lib/hecks/runtime/routing.rb +4 -15
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
- data/lib/hecks/runtime/saga_interpreter.rb +79 -263
- data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
- data/lib/hecks/runtime/tenant_check.rb +6 -68
- data/lib/hecks/runtime/tenant_scope.rb +3 -28
- data/lib/hecks/runtime/value/admission.rb +16 -67
- data/lib/hecks/runtime/value/coercion.rb +155 -641
- data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
- data/lib/hecks/runtime/value.rb +12 -84
- data/lib/hecks/runtime.rb +17 -65
- data/lib/hecks/storehouse.rb +146 -567
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +8 -32
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
- data/lib/hecks/vendoring/git_environment.rb +2 -8
- data/lib/hecks/vendoring/git_source.rb +4 -10
- data/lib/hecks/vendoring.rb +7 -46
- data/lib/hecks/version.rb +3 -14
- data/lib/hecks/vocabulary.rb +5 -0
- data/lib/hecks.rb +32 -82
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
- metadata +30 -59
- data/lib/hecks/bench/cli.rb +0 -74
- data/lib/hecks/bench/environment.rb +0 -100
- data/lib/hecks/bench/postgres_probe.rb +0 -41
- data/lib/hecks/bench/report.rb +0 -116
- data/lib/hecks/bench/ruby_runner.rb +0 -151
- data/lib/hecks/bench/run.rb +0 -55
- data/lib/hecks/bench/rust_runner.rb +0 -165
- data/lib/hecks/bench/stats.rb +0 -75
- data/lib/hecks/bench/suite.rb +0 -172
- data/lib/hecks/bench/workload.rb +0 -137
- data/lib/hecks/bench.rb +0 -28
- data/lib/hecks/codemod.rb +0 -443
- data/lib/hecks/corpus.rb +0 -479
- data/lib/hecks/doc/reference.rb +0 -585
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +0 -684
- data/lib/hecks/fuzzing/combination_miner.rb +0 -178
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +0 -469
- data/lib/hecks/fuzzing/coverage_campaign.rb +0 -161
- data/lib/hecks/fuzzing/differential.rb +0 -192
- data/lib/hecks/fuzzing/domain_generator.rb +0 -871
- data/lib/hecks/fuzzing/era_boundary.rb +0 -154
- data/lib/hecks/fuzzing/form_census.rb +0 -285
- data/lib/hecks/fuzzing/generated_domain_check.rb +0 -171
- data/lib/hecks/fuzzing/invalid_value_generator.rb +0 -125
- data/lib/hecks/fuzzing/isolated_boot.rb +0 -658
- data/lib/hecks/fuzzing/nondeterministic.rb +0 -79
- data/lib/hecks/fuzzing/persistence_parity.rb +0 -253
- data/lib/hecks/fuzzing/properties/corrections.rb +0 -125
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +0 -688
- data/lib/hecks/fuzzing/properties/guards.rb +0 -398
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +0 -399
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +0 -137
- data/lib/hecks/fuzzing/properties/outbox.rb +0 -180
- data/lib/hecks/fuzzing/properties/querying.rb +0 -260
- data/lib/hecks/fuzzing/properties.rb +0 -267
- data/lib/hecks/fuzzing/qa_settings.rb +0 -164
- data/lib/hecks/fuzzing/replay.rb +0 -930
- data/lib/hecks/fuzzing/rotation_priority.rb +0 -114
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +0 -139
- data/lib/hecks/fuzzing/self_consistency.rb +0 -825
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +0 -532
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +0 -171
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +0 -127
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +0 -116
- data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +0 -138
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +0 -344
- data/lib/hecks/fuzzing/sequence_generator.rb +0 -311
- data/lib/hecks/fuzzing/shrinker.rb +0 -309
- data/lib/hecks/fuzzing/structural_skips.rb +0 -53
- data/lib/hecks/fuzzing/sweep_depth.rb +0 -61
- data/lib/hecks/fuzzing/target_capabilities.rb +0 -255
- data/lib/hecks/fuzzing/value_generator.rb +0 -340
- data/lib/hecks/fuzzing.rb +0 -23
- data/lib/hecks/grammar/evolve.rb +0 -524
- data/lib/hecks/query_ir.rb +0 -482
|
@@ -3,24 +3,8 @@ require_relative "../../forms/html"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Projections
|
|
5
5
|
module Glossary
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# its `##` headings, each `###` a term entry, every ```mermaid fence
|
|
9
|
-
# a diagram, every `[x](#y)` an in-page link. Nothing here reads
|
|
10
|
-
# the bluebook; if the page shows it, the Markdown says it, so the
|
|
11
|
-
# two cannot drift.
|
|
12
|
-
#
|
|
13
|
-
# A subset renderer, not a markdown library — the projector emits
|
|
14
|
-
# a fixed handful of constructs (`Markdown`'s own header lists
|
|
15
|
-
# them), and this reads exactly those. The Gemfile keeps every
|
|
16
|
-
# dependency justified in its own comment; a full Markdown engine
|
|
17
|
-
# for six constructs would not earn one.
|
|
18
|
-
#
|
|
19
|
-
# The look lives in page.css / page.js beside this file — read at
|
|
20
|
-
# render time and inlined, so the page is one self-contained file.
|
|
21
|
-
# The only things it fetches are the two typefaces (Google Fonts)
|
|
22
|
-
# and Mermaid itself (cdnjs), which draws the diagrams in the
|
|
23
|
-
# browser; without a network the diagrams show as their source.
|
|
6
|
+
# Renders `glossary.md` into a self-contained HTML page with a navigation rail.
|
|
7
|
+
# A subset renderer for the constructs the projector emits, not a Markdown library.
|
|
24
8
|
module Html
|
|
25
9
|
Block = Struct.new(:type, :text, :items, :level, keyword_init: true)
|
|
26
10
|
|
|
@@ -31,9 +15,7 @@ module Hecks
|
|
|
31
15
|
module_function
|
|
32
16
|
|
|
33
17
|
# Renders `glossary.md`'s Markdown source as a self-contained HTML page.
|
|
34
|
-
#
|
|
35
|
-
# @param markdown [String] `glossary.md`'s own rendered Markdown source
|
|
36
|
-
# @return [String] the complete `html/index.html` source
|
|
18
|
+
# Reads only the Markdown, never the bluebook, so the two cannot drift.
|
|
37
19
|
def render(markdown)
|
|
38
20
|
blocks = parse(markdown)
|
|
39
21
|
slugs = heading_slugs(blocks)
|
|
@@ -42,14 +24,7 @@ module Hecks
|
|
|
42
24
|
page(title, sections, slugs)
|
|
43
25
|
end
|
|
44
26
|
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
# Parses the subset of Markdown the glossary projector emits into
|
|
48
|
-
# structured blocks.
|
|
49
|
-
#
|
|
50
|
-
# @param markdown [String] the Markdown source to parse
|
|
51
|
-
# @return [Array<Block>] one block per heading, quote, list, mermaid
|
|
52
|
-
# fence, or paragraph, in document order
|
|
27
|
+
# Parses the Markdown subset the glossary projector emits into blocks.
|
|
53
28
|
def parse(markdown)
|
|
54
29
|
lines = markdown.lines.map(&:chomp)
|
|
55
30
|
blocks = []
|
|
@@ -78,27 +53,13 @@ module Hecks
|
|
|
78
53
|
blocks
|
|
79
54
|
end
|
|
80
55
|
|
|
81
|
-
# The mermaid
|
|
82
|
-
# closing one, and the index just past that.
|
|
83
|
-
#
|
|
84
|
-
# @param lines [Array<String>] the document's lines
|
|
85
|
-
# @param index [Integer] the opening ` ```mermaid ` fence's line index
|
|
86
|
-
# @return [Array(Block, Integer)] the parsed `:mermaid` block, and the line
|
|
87
|
-
# index just past its closing fence
|
|
56
|
+
# The mermaid block opened at `index`, and the line index just past its closing fence.
|
|
88
57
|
def fence(lines, index)
|
|
89
58
|
close = ((index + 1)...lines.size).find { |at| lines[at] == "```" } || lines.size
|
|
90
59
|
[Block.new(type: :mermaid, text: lines[(index + 1)...close].join("\n")), close + 1]
|
|
91
60
|
end
|
|
92
61
|
|
|
93
|
-
# The consecutive lines from `index` that satisfy the block, and
|
|
94
|
-
# the index just past them.
|
|
95
|
-
#
|
|
96
|
-
# @param lines [Array<String>] the document's lines
|
|
97
|
-
# @param index [Integer] the line index to start scanning from
|
|
98
|
-
# @yieldparam text [String] one candidate line
|
|
99
|
-
# @yieldreturn [Boolean] whether that line belongs to the run
|
|
100
|
-
# @return [Array(Array<String>, Integer)] the consecutive matching lines, and
|
|
101
|
-
# the line index just past them
|
|
62
|
+
# The consecutive lines from `index` that satisfy the block, and the index past them.
|
|
102
63
|
def run(lines, index)
|
|
103
64
|
taken = []
|
|
104
65
|
while index < lines.size && yield(lines[index])
|
|
@@ -108,17 +69,9 @@ module Hecks
|
|
|
108
69
|
[taken, index]
|
|
109
70
|
end
|
|
110
71
|
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
# Keyed by the block itself, not its value — a Struct compares by
|
|
115
|
-
# members, so two "### Open" headings in different sections would
|
|
116
|
-
# otherwise be one key, and the first would answer with the
|
|
117
|
-
# second's "-1" slug, leaving `#open` with nothing to land on.
|
|
118
|
-
#
|
|
119
|
-
# @param blocks [Array<Block>] every parsed block, in document order
|
|
120
|
-
# @return [Hash{Block => String}] each heading block, mapped to its GitHub-style
|
|
121
|
-
# slug, keyed by object identity
|
|
72
|
+
# GitHub's slugs for these headings, so links the Markdown carries land here too.
|
|
73
|
+
# Keyed by identity: a Struct compares by members, so two "### Open" headings in
|
|
74
|
+
# different sections would collide and `#open` would have nothing to land on.
|
|
122
75
|
def heading_slugs(blocks)
|
|
123
76
|
seen = Hash.new(0)
|
|
124
77
|
slugs = {}.compare_by_identity
|
|
@@ -130,13 +83,7 @@ module Hecks
|
|
|
130
83
|
slugs
|
|
131
84
|
end
|
|
132
85
|
|
|
133
|
-
#
|
|
134
|
-
# opens a section that runs to the next.
|
|
135
|
-
#
|
|
136
|
-
# @param blocks [Array<Block>] every parsed block, in document order
|
|
137
|
-
# @return [Array<Hash{Symbol => Object}>] one Hash per section: `:heading`
|
|
138
|
-
# (the `Block`, or nil for the leading front matter) and `:blocks` (its
|
|
139
|
-
# own `Array<Block>`)
|
|
86
|
+
# Blocks before the first `##` are front matter (heading nil); each `##` opens a section.
|
|
140
87
|
def split_sections(blocks)
|
|
141
88
|
sections = [{ heading: nil, blocks: [] }]
|
|
142
89
|
blocks.each do |block|
|
|
@@ -146,15 +93,6 @@ module Hecks
|
|
|
146
93
|
sections
|
|
147
94
|
end
|
|
148
95
|
|
|
149
|
-
# ── writing the page ─────────────────────────────────────────────
|
|
150
|
-
|
|
151
|
-
# Renders the full HTML page shell around the navigation rail and content.
|
|
152
|
-
#
|
|
153
|
-
# @param title [String] the document's `#` heading text
|
|
154
|
-
# @param sections [Array<Hash{Symbol => Object}>] every `##` section, as
|
|
155
|
-
# `split_sections` builds (the front matter excluded by the caller)
|
|
156
|
-
# @param slugs [Hash{Block => String}] every heading block's own slug
|
|
157
|
-
# @return [String] the complete HTML page source
|
|
158
96
|
def page(title, sections, slugs)
|
|
159
97
|
front, *rest = sections
|
|
160
98
|
<<~HTML
|
|
@@ -186,14 +124,6 @@ module Hecks
|
|
|
186
124
|
HTML
|
|
187
125
|
end
|
|
188
126
|
|
|
189
|
-
# Renders the navigation rail: the domain name, a search box, and one
|
|
190
|
-
# link per section.
|
|
191
|
-
#
|
|
192
|
-
# @param title [String] the document's `#` heading text, `"Domain — Glossary"`
|
|
193
|
-
# @param sections [Array<Hash{Symbol => Object}>] every `##` section (the
|
|
194
|
-
# front matter excluded)
|
|
195
|
-
# @param slugs [Hash{Block => String}] every heading block's own slug
|
|
196
|
-
# @return [String] the rail's HTML source
|
|
197
127
|
def rail(title, sections, slugs)
|
|
198
128
|
domain = title.split(" — ").first
|
|
199
129
|
items = sections.map do |section|
|
|
@@ -213,10 +143,6 @@ module Hecks
|
|
|
213
143
|
HTML
|
|
214
144
|
end
|
|
215
145
|
|
|
216
|
-
# Renders the page's `<header>`: the title, vision, lede, and overview diagram.
|
|
217
|
-
#
|
|
218
|
-
# @param blocks [Array<Block>] the front matter's own blocks
|
|
219
|
-
# @return [String] the header's HTML source
|
|
220
146
|
def front_matter(blocks)
|
|
221
147
|
parts = ["<header>"]
|
|
222
148
|
blocks.each do |block|
|
|
@@ -231,15 +157,8 @@ module Hecks
|
|
|
231
157
|
parts.join("\n")
|
|
232
158
|
end
|
|
233
159
|
|
|
234
|
-
#
|
|
235
|
-
#
|
|
236
|
-
# runs to the next. A bold-only paragraph is the caption of
|
|
237
|
-
# whatever figure or list follows it.
|
|
238
|
-
#
|
|
239
|
-
# @param section [Hash{Symbol => Object}] one `##` section, as `split_sections`
|
|
240
|
-
# builds
|
|
241
|
-
# @param slugs [Hash{Block => String}] every heading block's own slug
|
|
242
|
-
# @return [String] the section's `<section>` HTML source
|
|
160
|
+
# Each `###` opens an article running to the next. A bold-only paragraph
|
|
161
|
+
# captions whatever figure or list follows it.
|
|
243
162
|
def section_html(section, slugs)
|
|
244
163
|
heading = section[:heading]
|
|
245
164
|
state = { parts: [%(<section id="#{slugs[heading]}">), "<h2>#{inline(heading.text)}</h2>"],
|
|
@@ -250,15 +169,7 @@ module Hecks
|
|
|
250
169
|
state[:parts].join("\n")
|
|
251
170
|
end
|
|
252
171
|
|
|
253
|
-
# Renders one block into `state[:parts]`, mutating `state
|
|
254
|
-
#
|
|
255
|
-
# @param block [Block] the block to render
|
|
256
|
-
# @param state [Hash{Symbol => Object}] the section's own render state:
|
|
257
|
-
# `:parts` (the growing `Array<String>` of HTML), `:caption` (a pending
|
|
258
|
-
# bold-only paragraph's text, or nil), `:in_terms` (whether a `###` term
|
|
259
|
-
# article is currently open)
|
|
260
|
-
# @param slugs [Hash{Block => String}] every heading block's own slug
|
|
261
|
-
# @return [void]
|
|
172
|
+
# Renders one block into `state[:parts]`, mutating `state`.
|
|
262
173
|
def section_block(block, state, slugs)
|
|
263
174
|
parts = state[:parts]
|
|
264
175
|
case block.type
|
|
@@ -279,13 +190,6 @@ module Hecks
|
|
|
279
190
|
end
|
|
280
191
|
end
|
|
281
192
|
|
|
282
|
-
# Renders one paragraph, either capturing it as a pending caption (a
|
|
283
|
-
# bold-only line) or appending it to `state[:parts]`.
|
|
284
|
-
#
|
|
285
|
-
# @param text [String] the paragraph's own text
|
|
286
|
-
# @param state [Hash{Symbol => Object}] the section's own render state (see
|
|
287
|
-
# `section_block`); `:caption` and `:parts` may be mutated
|
|
288
|
-
# @return [void]
|
|
289
193
|
def paragraph(text, state)
|
|
290
194
|
if text.match?(/\A\*\*[^*]+\*\*\z/)
|
|
291
195
|
state[:caption] = text.delete("*")
|
|
@@ -295,11 +199,6 @@ module Hecks
|
|
|
295
199
|
end
|
|
296
200
|
end
|
|
297
201
|
|
|
298
|
-
# Renders a mermaid block as a `<figure>`, with an optional caption.
|
|
299
|
-
#
|
|
300
|
-
# @param block [Block] the `:mermaid` block to render
|
|
301
|
-
# @param caption [String, nil] the figure's caption text, or nil for none
|
|
302
|
-
# @return [String] the `<figure>`'s HTML source
|
|
303
202
|
def figure(block, caption)
|
|
304
203
|
parts = ["<figure>"]
|
|
305
204
|
parts << "<figcaption>#{escape(caption)}</figcaption>" if caption
|
|
@@ -307,20 +206,9 @@ module Hecks
|
|
|
307
206
|
parts.join("\n")
|
|
308
207
|
end
|
|
309
208
|
|
|
310
|
-
# ── inline text ──────────────────────────────────────────────────
|
|
311
|
-
|
|
312
|
-
# Escapes text for HTML.
|
|
313
|
-
#
|
|
314
|
-
# @param text [Object, nil] the value to escape, rendered with `to_s`
|
|
315
|
-
# @return [String] `text`, HTML-escaped
|
|
316
209
|
def escape(text) = Forms::Escape.html(text)
|
|
317
210
|
|
|
318
|
-
#
|
|
319
|
-
# the three inline forms the Markdown uses, on the escaped text.
|
|
320
|
-
#
|
|
321
|
-
# @param text [String] the inline text to render
|
|
322
|
-
# @return [String] `text`, HTML-escaped, with `[x](#y)` links, `**bold**` and
|
|
323
|
-
# `*italic*` spans converted to their HTML equivalents
|
|
211
|
+
# Escapes first so prose never becomes a tag, then converts links, bold and italic.
|
|
324
212
|
def inline(text)
|
|
325
213
|
escape(text)
|
|
326
214
|
.gsub(/\[([^\]]+)\]\(#([^)]+)\)/) { %(<a href="##{Regexp.last_match(2)}">#{Regexp.last_match(1)}</a>) }
|
|
@@ -328,10 +216,6 @@ module Hecks
|
|
|
328
216
|
.gsub(/\*(.+?)\*/) { "<em>#{Regexp.last_match(1)}</em>" }
|
|
329
217
|
end
|
|
330
218
|
|
|
331
|
-
# Reads one static asset file from beside this file.
|
|
332
|
-
#
|
|
333
|
-
# @param name [String] the asset's filename, such as `"page.css"`
|
|
334
|
-
# @return [String] the asset file's contents, read from beside this file
|
|
335
219
|
def asset(name) = File.read(File.join(__dir__, name))
|
|
336
220
|
end
|
|
337
221
|
end
|
|
@@ -7,25 +7,8 @@ require_relative "../statements"
|
|
|
7
7
|
module Hecks
|
|
8
8
|
module Projections
|
|
9
9
|
module Glossary
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# GitHub renders as-is (headings, blockquotes, ```mermaid fences,
|
|
13
|
-
# lists, in-page links), so the file is a complete, readable
|
|
14
|
-
# glossary on its own before any page is built from it:
|
|
15
|
-
#
|
|
16
|
-
# # Banking — Glossary
|
|
17
|
-
# > vision
|
|
18
|
-
# lede
|
|
19
|
-
# ```mermaid the map
|
|
20
|
-
# ## Account
|
|
21
|
-
# > description
|
|
22
|
-
# Starts out open. Can be open, frozen, or closed.
|
|
23
|
-
# **How it fits** ```mermaid
|
|
24
|
-
# **How it moves** ```mermaid
|
|
25
|
-
# **Always true** - one sentence per declared fact
|
|
26
|
-
# ### Account number one ### per term, A to Z
|
|
27
|
-
# Made up of a value (text).
|
|
28
|
-
# Always true: an account number is present.
|
|
10
|
+
# Renders `glossary.md`, the source the glossary page is built from.
|
|
11
|
+
# Uses only Markdown that GitHub renders as-is, so the file reads on its own.
|
|
29
12
|
module Markdown
|
|
30
13
|
LEDE = "Every term %<name>s uses, in the words of the people who work in it — grouped under the thing " \
|
|
31
14
|
"each belongs to, and listed A to Z within it. This page is generated from the working " \
|
|
@@ -41,9 +24,6 @@ module Hecks
|
|
|
41
24
|
module_function
|
|
42
25
|
|
|
43
26
|
# Titles the document after its chapter.
|
|
44
|
-
#
|
|
45
|
-
# @param bluebook [Bluebook::Behaviour::Chapter] the chapter to title after
|
|
46
|
-
# @return [String] the document's `#` heading text
|
|
47
27
|
def title(bluebook) = "#{bluebook.name} — Glossary"
|
|
48
28
|
|
|
49
29
|
# Renders the full `glossary.md` document.
|
|
@@ -56,11 +36,7 @@ module Hecks
|
|
|
56
36
|
"#{parts.join("\n\n")}\n"
|
|
57
37
|
end
|
|
58
38
|
|
|
59
|
-
# Renders the
|
|
60
|
-
#
|
|
61
|
-
# @param bluebook [Bluebook::Behaviour::Chapter] the chapter to render a
|
|
62
|
-
# header for
|
|
63
|
-
# @return [String] the header's Markdown source
|
|
39
|
+
# Renders the title, vision blockquote, lede, and overview map.
|
|
64
40
|
def header(bluebook)
|
|
65
41
|
parts = ["# #{title(bluebook)}"]
|
|
66
42
|
parts << "> #{bluebook.vision}" if bluebook.vision
|
|
@@ -69,13 +45,7 @@ module Hecks
|
|
|
69
45
|
parts.join("\n\n")
|
|
70
46
|
end
|
|
71
47
|
|
|
72
|
-
# Renders one `##` section: its opening
|
|
73
|
-
# group's blurb), followed by every term inside it.
|
|
74
|
-
#
|
|
75
|
-
# @param section [Glossary::Section] the section to render
|
|
76
|
-
# @param document [Glossary::Document] the document `section` belongs to,
|
|
77
|
-
# for its bluebook and link index
|
|
78
|
-
# @return [String] the section's Markdown source
|
|
48
|
+
# Renders one `##` section: its opening, then every term inside it.
|
|
79
49
|
def section_text(section, document)
|
|
80
50
|
parts = ["## #{section.title}"]
|
|
81
51
|
parts += if section.aggregate
|
|
@@ -88,16 +58,7 @@ module Hecks
|
|
|
88
58
|
parts.join("\n\n")
|
|
89
59
|
end
|
|
90
60
|
|
|
91
|
-
#
|
|
92
|
-
# and what is always true of it — before a single term.
|
|
93
|
-
#
|
|
94
|
-
# @param aggregate [Bluebook::Aggregate] the aggregate to render an opening for
|
|
95
|
-
# @param bluebook [Bluebook::Behaviour::Chapter] the chapter `aggregate` belongs
|
|
96
|
-
# to, for drawing its context diagram
|
|
97
|
-
# @param marked [Array<Hash{Symbol => String}>] the markings that flag
|
|
98
|
-
# `aggregate`'s own fields sensitive, listed after its rules
|
|
99
|
-
# @return [Array<String>] the opening's Markdown blocks, one per paragraph or
|
|
100
|
-
# diagram, not yet joined
|
|
61
|
+
# An aggregate's opening: what it is, how it fits and moves, what is always true.
|
|
101
62
|
def opening(aggregate, bluebook, marked = [])
|
|
102
63
|
parts = []
|
|
103
64
|
parts << "> #{aggregate.description}" if aggregate.description
|
|
@@ -113,19 +74,9 @@ module Hecks
|
|
|
113
74
|
parts
|
|
114
75
|
end
|
|
115
76
|
|
|
116
|
-
# The statements projection's
|
|
117
|
-
#
|
|
118
|
-
#
|
|
119
|
-
# ATMCard references an Account."), and a construct name is the
|
|
120
|
-
# one thing this page never shows as an identifier — so each is
|
|
121
|
-
# replaced with how it is said, whole-word, and nothing else in
|
|
122
|
-
# the sentence is touched.
|
|
123
|
-
#
|
|
124
|
-
# @param aggregate [Bluebook::Aggregate] the aggregate to gather rules for
|
|
125
|
-
# @param bluebook [Bluebook::Behaviour::Chapter] the chapter to read every
|
|
126
|
-
# construct name from, for de-identifying relationship sentences
|
|
127
|
-
# @return [Array<String>] `aggregate`'s (and its entities') attribute and
|
|
128
|
-
# invariant statements, spoken and deduplicated
|
|
77
|
+
# The statements projection's sentences for `aggregate` and its entities, spoken.
|
|
78
|
+
# Invariants stay verbatim; construct names in other sentences are replaced with
|
|
79
|
+
# how they are said, because this page never shows an identifier.
|
|
129
80
|
def always_true(aggregate, bluebook)
|
|
130
81
|
names = bluebook.aggregates.flat_map { |other| [other.hecks_name, *other.entities.map(&:hecks_name)] }
|
|
131
82
|
[aggregate, *aggregate.entities].flat_map do |holder|
|
|
@@ -135,28 +86,16 @@ module Hecks
|
|
|
135
86
|
end
|
|
136
87
|
|
|
137
88
|
# Replaces every whole-word construct name in `sentence` with how it is said.
|
|
138
|
-
#
|
|
139
|
-
# @param sentence [String] the sentence to de-identify
|
|
140
|
-
# @param names [Array<String>] every construct name to replace, whole-word
|
|
141
|
-
# @return [String] `sentence` with each name in `names` replaced by
|
|
142
|
-
# `Naming.words(name)`
|
|
143
89
|
def spoken(sentence, names)
|
|
144
90
|
names.reduce(sentence) { |text, name| text.gsub(/\b#{Regexp.escape(name)}\b/, Naming.words(name)) }
|
|
145
91
|
end
|
|
146
92
|
|
|
147
93
|
# Renders one term's `###` heading and its paragraphs.
|
|
148
|
-
#
|
|
149
|
-
# @param entry [Glossary::Entry] the term to render
|
|
150
|
-
# @param index [Glossary::Index] the document's link index
|
|
151
|
-
# @return [String] the term's Markdown source
|
|
152
94
|
def term_text(entry, index)
|
|
153
95
|
["### #{entry.headword}", *Sentences.paragraphs(entry, index)].join("\n\n")
|
|
154
96
|
end
|
|
155
97
|
|
|
156
98
|
# Wraps a Mermaid diagram's source in a fenced code block.
|
|
157
|
-
#
|
|
158
|
-
# @param source [String] a Mermaid diagram's own source
|
|
159
|
-
# @return [String] `source` wrapped in a ` ```mermaid ` fence
|
|
160
99
|
def fence(source) = "```mermaid\n#{source}\n```"
|
|
161
100
|
end
|
|
162
101
|
end
|
|
@@ -3,31 +3,13 @@ require_relative "../../naming"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Projections
|
|
5
5
|
module Glossary
|
|
6
|
-
# The three
|
|
7
|
-
#
|
|
8
|
-
# issue at hand", never the whole model at once.
|
|
9
|
-
#
|
|
10
|
-
# map the aggregates and which points at which — one small
|
|
11
|
-
# graph at the top, for the reader who wants the shape
|
|
12
|
-
# of the domain before its words.
|
|
13
|
-
# context one aggregate, its entities, and the neighbours it
|
|
14
|
-
# points at or is pointed at by. Value objects are
|
|
15
|
-
# words in the text ("Made up of …"), not boxes here —
|
|
16
|
-
# Account alone has eight, and eight boxes say less
|
|
17
|
-
# than one sentence.
|
|
18
|
-
# lifecycle the states a thing can be in and what moves it.
|
|
19
|
-
#
|
|
20
|
-
# Every label is a person's spelling (`Naming.words`), and the
|
|
21
|
-
# edges read from the same declared facts `Projections::Diagrams`
|
|
22
|
-
# draws its own from (`reference?`, `type.target_name`, `name`,
|
|
23
|
-
# `lifecycle.transitions`) — a different picture of the same
|
|
24
|
-
# declaration, not a second declaration.
|
|
6
|
+
# The glossary's three diagrams: the map, one aggregate's context, and a lifecycle.
|
|
7
|
+
# Value objects appear as words in the text, not as boxes, to keep diagrams small.
|
|
25
8
|
module Mermaid
|
|
26
9
|
module_function
|
|
27
10
|
|
|
28
11
|
# Draws the whole chapter's aggregates and which points at which.
|
|
29
12
|
#
|
|
30
|
-
# @param bluebook [Bluebook::Behaviour::Chapter] the chapter to draw
|
|
31
13
|
# @return [String] a Mermaid `flowchart LR` source
|
|
32
14
|
def map(bluebook)
|
|
33
15
|
names = bluebook.aggregates.map(&:hecks_name)
|
|
@@ -45,9 +27,6 @@ module Hecks
|
|
|
45
27
|
|
|
46
28
|
# Draws one aggregate, its entities, and its neighbours.
|
|
47
29
|
#
|
|
48
|
-
# @param aggregate [Bluebook::Aggregate] the aggregate to focus on
|
|
49
|
-
# @param bluebook [Bluebook::Behaviour::Chapter] the chapter to find
|
|
50
|
-
# neighbouring aggregates in
|
|
51
30
|
# @return [String] a Mermaid `flowchart LR` source
|
|
52
31
|
def context(aggregate, bluebook)
|
|
53
32
|
focus = aggregate.hecks_name
|
|
@@ -70,8 +49,6 @@ module Hecks
|
|
|
70
49
|
|
|
71
50
|
# Draws the states a holder can be in and what moves it between them.
|
|
72
51
|
#
|
|
73
|
-
# @param holder [Bluebook::Aggregate, Bluebook::Entity] the holder whose
|
|
74
|
-
# lifecycle to draw
|
|
75
52
|
# @return [String] a Mermaid `stateDiagram-v2` source
|
|
76
53
|
def lifecycle(holder)
|
|
77
54
|
lifecycle = holder.lifecycle
|
|
@@ -87,35 +64,17 @@ module Hecks
|
|
|
87
64
|
lines.join("\n")
|
|
88
65
|
end
|
|
89
66
|
|
|
90
|
-
# ── the facts drawn ──────────────────────────────────────────────
|
|
91
|
-
|
|
92
|
-
# Names a holder's own reference attributes.
|
|
93
|
-
#
|
|
94
|
-
# @param holder [Bluebook::Aggregate, Bluebook::Entity] the holder to
|
|
95
|
-
# read reference attributes from
|
|
96
|
-
# @return [Array<Bluebook::Attribute>] `holder`'s own reference attributes
|
|
97
67
|
def references(holder) = holder.attributes.select(&:reference?)
|
|
98
68
|
|
|
99
|
-
# An entity is held as `list_of(LedgerEntry)
|
|
100
|
-
#
|
|
101
|
-
#
|
|
102
|
-
# @param aggregate [Bluebook::Aggregate] the aggregate to read entity
|
|
103
|
-
# attributes from
|
|
104
|
-
# @return [Array<Bluebook::Attribute>] attributes whose element type is one
|
|
105
|
-
# of `aggregate`'s own entities
|
|
69
|
+
# An entity is held as `list_of(LedgerEntry)`: an attribute whose element type
|
|
70
|
+
# names one of the aggregate's own entities.
|
|
106
71
|
def entities(aggregate)
|
|
107
72
|
names = aggregate.entities.map(&:hecks_name)
|
|
108
73
|
aggregate.attributes.select { |attribute| !attribute.reference? && names.include?(attribute.type.to_s) }
|
|
109
74
|
end
|
|
110
75
|
|
|
111
|
-
# Finds every other aggregate that
|
|
112
|
-
#
|
|
113
|
-
# @param aggregate [Bluebook::Aggregate] the aggregate to find pointers to
|
|
114
|
-
# @param bluebook [Bluebook::Behaviour::Chapter] the chapter to search other
|
|
115
|
-
# aggregates in
|
|
116
|
-
# @return [Array<Array(Bluebook::Aggregate, Bluebook::Attribute)>] every other
|
|
117
|
-
# aggregate's own reference attribute that targets `aggregate`, paired
|
|
118
|
-
# with its holder
|
|
76
|
+
# Finds every other aggregate's reference attribute that targets `aggregate`,
|
|
77
|
+
# as `[holder, attribute]` pairs.
|
|
119
78
|
def pointing_at(aggregate, bluebook)
|
|
120
79
|
bluebook.aggregates.reject { |other| other.equal?(aggregate) }.flat_map do |other|
|
|
121
80
|
references(other).select { |attribute| attribute.type.target_name == aggregate.hecks_name }
|
|
@@ -123,32 +82,16 @@ module Hecks
|
|
|
123
82
|
end
|
|
124
83
|
end
|
|
125
84
|
|
|
126
|
-
#
|
|
127
|
-
|
|
128
|
-
# A node id the page source can carry without an identifier in
|
|
129
|
-
# it — `n_atm_card`, never `n_ATMCard`.
|
|
130
|
-
#
|
|
131
|
-
# @param name [String, Symbol] the construct name to derive an id from
|
|
132
|
-
# @return [String] a Mermaid-safe node id, such as `"n_atm_card"`
|
|
85
|
+
# A node id that carries no identifier: `n_atm_card`, never `n_ATMCard`.
|
|
133
86
|
def id(name) = "n_#{Naming.snake(name).gsub(/[^a-z0-9_]/, '_')}"
|
|
134
87
|
|
|
135
|
-
# Renders one Mermaid node declaration.
|
|
136
|
-
#
|
|
137
|
-
# @param name [String, Symbol] the node's construct name
|
|
138
|
-
# @param focus [Boolean] whether to mark this node with the `focus` CSS class
|
|
139
|
-
# @return [String] a Mermaid node declaration line
|
|
88
|
+
# Renders one Mermaid node declaration, marked `focus` when asked.
|
|
140
89
|
def node(name, focus: false)
|
|
141
90
|
line = " #{id(name)}[\"#{Naming.words(name)}\"]"
|
|
142
91
|
focus ? "#{line}:::focus" : line
|
|
143
92
|
end
|
|
144
93
|
|
|
145
|
-
# Renders one Mermaid edge
|
|
146
|
-
#
|
|
147
|
-
# @param from [String, Symbol] the source node's construct name
|
|
148
|
-
# @param attribute [Bluebook::Attribute] the attribute the edge is labelled after
|
|
149
|
-
# @param to [String, Symbol] the target node's construct name
|
|
150
|
-
# @return [String] a Mermaid edge declaration line, labelled with the
|
|
151
|
-
# attribute's spoken name
|
|
94
|
+
# Renders one Mermaid edge, labelled with the attribute's spoken name.
|
|
152
95
|
def edge(from, attribute, to)
|
|
153
96
|
" #{id(from)} -->|\"#{Naming.words(attribute.name).downcase}\"| #{id(to)}"
|
|
154
97
|
end
|
|
@@ -3,38 +3,17 @@ require_relative "../../naming"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Projections
|
|
5
5
|
module Glossary
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# `has_phi(readable_by:)` chain in a `.hecksagon`) and handed in as
|
|
9
|
-
# `options[:markings]`. A marking names an aggregate by its qualified
|
|
10
|
-
# name (`"Site::Registration"`) and a field by its dotted path
|
|
11
|
-
# (`"attendee.medications"`). Its category is spoken as the acronym it
|
|
12
|
-
# is, uppercased and never reworded, because the category vocabulary is
|
|
13
|
-
# the deployment's own and open-ended.
|
|
6
|
+
# The sensitive fields a glossary flags, read from markings handed in as
|
|
7
|
+
# `options[:markings]` and keyed by aggregate name and dotted field path.
|
|
14
8
|
module Sensitivity
|
|
15
9
|
module_function
|
|
16
10
|
|
|
17
|
-
# The markings that name one aggregate of the chapter.
|
|
18
|
-
#
|
|
19
|
-
# @param markings [Array<Hash{Symbol => String}>] every marking handed in, each
|
|
20
|
-
# with `:domain`, `:attribute_path`, `:category` and `:readable_by`
|
|
21
|
-
# @param chapter_name [String] the chapter's declared name
|
|
22
|
-
# @param aggregate [Bluebook::Aggregate] the aggregate to find markings for
|
|
23
|
-
# @return [Array<Hash{Symbol => String}>] the markings whose `:domain` is
|
|
24
|
-
# `aggregate`'s qualified name, in the order they were declared
|
|
25
11
|
def for_aggregate(markings, chapter_name, aggregate)
|
|
26
12
|
qualified = "#{chapter_name}::#{aggregate.hecks_name}"
|
|
27
13
|
markings.select { |marking| marking[:domain].to_s == qualified }
|
|
28
14
|
end
|
|
29
15
|
|
|
30
|
-
#
|
|
31
|
-
# the aggregate's attributes holds that value object.
|
|
32
|
-
#
|
|
33
|
-
# @param marked [Array<Hash{Symbol => String}>] the aggregate's own markings
|
|
34
|
-
# @param aggregate [Bluebook::Aggregate] the aggregate holding the value object
|
|
35
|
-
# @param value_object [Bluebook::ValueObject] the value object to look inside
|
|
36
|
-
# @return [Hash{String => Hash{Symbol => String}}] each marked field's name,
|
|
37
|
-
# mapped to its marking; empty when no marking reaches one of its fields
|
|
16
|
+
# Marked fields inside a value object, matched by attribute name then field.
|
|
38
17
|
def for_value_object(marked, aggregate, value_object)
|
|
39
18
|
holders = aggregate.attributes.select { |attribute| attribute.type.to_s == value_object.hecks_name }
|
|
40
19
|
holder_names = holders.map { |attribute| attribute.name.to_s }
|
|
@@ -44,18 +23,10 @@ module Hecks
|
|
|
44
23
|
end
|
|
45
24
|
end
|
|
46
25
|
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# @param marking [Hash{Symbol => String}] one marking
|
|
50
|
-
# @return [String] the marking's category, uppercased
|
|
26
|
+
# Uppercased, never otherwise reworded — the category vocabulary is the deployment's own.
|
|
51
27
|
def tag(marking) = marking[:category].to_s.upcase
|
|
52
28
|
|
|
53
|
-
#
|
|
54
|
-
# kind of sensitive, and who may read it unredacted.
|
|
55
|
-
#
|
|
56
|
-
# @param marking [Hash{Symbol => String}] one marking
|
|
57
|
-
# @return [String] the field's spoken path, its uppercased category, and the
|
|
58
|
-
# role that reads it unredacted, as one sentence
|
|
29
|
+
# Renders one "Handled as sensitive" line: field, category, and who may read it unredacted.
|
|
59
30
|
def sentence(marking)
|
|
60
31
|
path = marking[:attribute_path].to_s.split(".").map { |part| Naming.words(part).downcase }.join(" ")
|
|
61
32
|
reader = Naming.words(marking[:readable_by]).downcase
|