hecks 0.2.0 → 0.3.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 +5 -5
- data/lib/hecks/adapters/driven/claude_code.adapter +3 -0
- data/lib/hecks/adapters/driven/claude_code.rb +127 -0
- data/lib/hecks/adapters/driven/d1.adapter +12 -0
- data/lib/hecks/adapters/driven/d1.rb +403 -0
- data/lib/hecks/adapters/driven/folder.adapter +3 -0
- data/lib/hecks/adapters/driven/folder.rb +199 -0
- data/lib/hecks/adapters/driven/google_authentication.adapter +3 -0
- data/lib/hecks/adapters/driven/google_authentication.rb +100 -0
- data/lib/hecks/adapters/driven/governance_authorization.adapter +3 -0
- data/lib/hecks/adapters/driven/governance_authorization.rb +62 -0
- data/lib/hecks/adapters/driven/heki/journal.rb +51 -0
- data/lib/hecks/adapters/driven/heki/saga_store.rb +0 -0
- data/lib/hecks/adapters/driven/heki/snapshot.rb +38 -0
- data/lib/hecks/adapters/driven/heki.adapter +4 -0
- data/lib/hecks/adapters/driven/heki.rb +148 -0
- data/lib/hecks/adapters/driven/identity_registry.adapter +3 -0
- data/lib/hecks/adapters/driven/identity_registry.rb +26 -0
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +51 -0
- data/lib/hecks/adapters/driven/lambda/client.rb +63 -0
- data/lib/hecks/adapters/driven/lambda.adapter +4 -0
- data/lib/hecks/adapters/driven/lambda.rb +131 -0
- data/lib/hecks/adapters/driven/memory.adapter +3 -0
- data/lib/hecks/adapters/driven/memory.rb +103 -0
- data/lib/hecks/adapters/driven/mock_stripe_adapter.adapter +3 -0
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +28 -0
- data/lib/hecks/adapters/driven/postgres/codec.rb +80 -0
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +168 -0
- data/lib/hecks/adapters/driven/postgres.adapter +5 -0
- data/lib/hecks/adapters/driven/postgres.rb +391 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/era_store.rb +171 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/field_cache.rb +190 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/head_compiler.rb +429 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/mint_transaction.rb +166 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/provisioning.rb +286 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/resumable_backfill.rb +168 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/tail_merge.rb +163 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/transform_installer.rb +114 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage.rb +137 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb +89 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolver.rb +82 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/merge_coordinator.rb +43 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/minter.rb +132 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager.rb +74 -0
- data/lib/hecks/adapters/driven/postgres_era.adapter +6 -0
- data/lib/hecks/adapters/driven/postgres_era.rb +671 -0
- data/lib/hecks/adapters/driven/prism.adapter +3 -0
- data/lib/hecks/adapters/driven/prism.rb +80 -0
- data/lib/hecks/adapters/driven/secure_random_identity.adapter +3 -0
- data/lib/hecks/adapters/driven/secure_random_identity.rb +14 -0
- data/lib/hecks/adapters/driven/sql_query_builder.rb +221 -0
- data/lib/hecks/adapters/driven/sqlite/codec.rb +63 -0
- data/lib/hecks/adapters/driven/sqlite/projection.rb +105 -0
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +180 -0
- data/lib/hecks/adapters/driven/sqlite.adapter +9 -0
- data/lib/hecks/adapters/driven/sqlite.rb +285 -0
- data/lib/hecks/adapters/driven/system_clock.adapter +3 -0
- data/lib/hecks/adapters/driven/system_clock.rb +14 -0
- data/lib/hecks/adapters/driven.rb +36 -0
- data/lib/hecks/adapters.rb +6 -0
- data/lib/hecks/behaviors/dsl.rb +96 -0
- data/lib/hecks/behaviors/expectations.rb +280 -0
- data/lib/hecks/behaviors/ir.rb +31 -0
- data/lib/hecks/behaviors/rspec.rb +42 -0
- data/lib/hecks/behaviors/runner.rb +96 -0
- data/lib/hecks/behaviors.rb +25 -0
- data/lib/hecks/bluebook/aggregate.rb +108 -0
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +134 -0
- data/lib/hecks/bluebook/assembly/build.rb +48 -0
- data/lib/hecks/bluebook/assembly/contract.rb +112 -0
- data/lib/hecks/bluebook/assembly/contracts.rb +409 -0
- data/lib/hecks/bluebook/assembly/marks.rb +227 -0
- data/lib/hecks/bluebook/assembly/specializer.rb +70 -0
- data/lib/hecks/bluebook/assembly.rb +78 -0
- data/lib/hecks/bluebook/attribute.rb +96 -0
- data/lib/hecks/bluebook/behaviour/aggregate.rb +83 -0
- data/lib/hecks/bluebook/behaviour/attribute.rb +27 -0
- data/lib/hecks/bluebook/behaviour/chapter.rb +72 -0
- data/lib/hecks/bluebook/behaviour/command.rb +116 -0
- data/lib/hecks/bluebook/behaviour/domain_port.rb +25 -0
- data/lib/hecks/bluebook/behaviour/entity.rb +59 -0
- data/lib/hecks/bluebook/behaviour/hexagon.rb +50 -0
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +51 -0
- data/lib/hecks/bluebook/behaviour/policy.rb +52 -0
- data/lib/hecks/bluebook/behaviour/process_manager.rb +38 -0
- data/lib/hecks/bluebook/behaviour/query.rb +10 -0
- data/lib/hecks/bluebook/behaviour/read_model.rb +29 -0
- data/lib/hecks/bluebook/behaviour/traits.rb +81 -0
- data/lib/hecks/bluebook/behaviour/value_object.rb +33 -0
- data/lib/hecks/bluebook/chapter.rb +68 -0
- data/lib/hecks/bluebook/command.rb +124 -0
- data/lib/hecks/bluebook/domain_port.rb +102 -0
- data/lib/hecks/bluebook/dsl/adapter_builder.rb +34 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +906 -0
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +327 -0
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +71 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +1018 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +626 -0
- data/lib/hecks/bluebook/dsl/const_shim.rb +81 -0
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +79 -0
- data/lib/hecks/bluebook/dsl/entity_builder.rb +305 -0
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +366 -0
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +163 -0
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +191 -0
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +44 -0
- data/lib/hecks/bluebook/dsl/malformed.rb +7 -0
- data/lib/hecks/bluebook/dsl/policy_builder.rb +120 -0
- data/lib/hecks/bluebook/dsl/port_builder.rb +30 -0
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +142 -0
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +207 -0
- data/lib/hecks/bluebook/dsl/query_builder.rb +113 -0
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +233 -0
- data/lib/hecks/bluebook/dsl/rule_reference.rb +172 -0
- data/lib/hecks/bluebook/dsl/translation_builder.rb +243 -0
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +178 -0
- data/lib/hecks/bluebook/dsl/word_gate.rb +221 -0
- data/lib/hecks/bluebook/dsl/world_builder.rb +77 -0
- data/lib/hecks/bluebook/dsl.rb +45 -0
- data/lib/hecks/bluebook/entity.rb +103 -0
- data/lib/hecks/bluebook/expression/canonical_form.rb +55 -0
- data/lib/hecks/bluebook/expression/evaluator.rb +261 -0
- data/lib/hecks/bluebook/expression/projection.json +170 -0
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +233 -0
- data/lib/hecks/bluebook/expression/resolver.rb +630 -0
- data/lib/hecks/bluebook/expression.rb +13 -0
- data/lib/hecks/bluebook/hexagon.rb +60 -0
- data/lib/hecks/bluebook/lifecycle.rb +42 -0
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +54 -0
- data/lib/hecks/bluebook/meta_validator/judge.rb +559 -0
- data/lib/hecks/bluebook/meta_validator/plan.rb +332 -0
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +47 -0
- data/lib/hecks/bluebook/meta_validator/readings.rb +350 -0
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +312 -0
- data/lib/hecks/bluebook/meta_validator/shapes.rb +246 -0
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +255 -0
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +138 -0
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +78 -0
- data/lib/hecks/bluebook/meta_validator.rb +452 -0
- data/lib/hecks/bluebook/model_check.rb +318 -0
- data/lib/hecks/bluebook/pattern_subset.rb +120 -0
- data/lib/hecks/bluebook/policy.rb +41 -0
- data/lib/hecks/bluebook/process_manager.rb +86 -0
- data/lib/hecks/bluebook/project_discovery.rb +30 -0
- data/lib/hecks/bluebook/project_loader.rb +40 -0
- data/lib/hecks/bluebook/project_register.rb +82 -0
- data/lib/hecks/bluebook/query.rb +61 -0
- data/lib/hecks/bluebook/read_model.rb +109 -0
- data/lib/hecks/bluebook/reference.rb +74 -0
- data/lib/hecks/bluebook/smoke_test.rb +166 -0
- data/lib/hecks/bluebook/synthesizer.rb +95 -0
- data/lib/hecks/bluebook/translation.rb +92 -0
- data/lib/hecks/bluebook/value_object.rb +58 -0
- data/lib/hecks/bluebook.rb +74 -0
- data/lib/hecks/codemod.rb +342 -0
- data/lib/hecks/construct.rb +71 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +219 -0
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +4 -0
- data/lib/hecks/deploy/oidc.json +18 -0
- data/lib/hecks/doc/reference.rb +389 -0
- data/lib/hecks/embryonaut_bluebook.rb +75 -0
- data/lib/hecks/facade/cli_door.rb +116 -0
- data/lib/hecks/facade/cli_runner.rb +190 -0
- data/lib/hecks/facade/command_request.rb +105 -0
- data/lib/hecks/facade/handle.rb +173 -0
- data/lib/hecks/facade/json_door.rb +154 -0
- data/lib/hecks/facade/surface/aggregate_door.rb +185 -0
- data/lib/hecks/facade/surface/chapter.rb +107 -0
- data/lib/hecks/facade/surface.rb +48 -0
- data/lib/hecks/facade.rb +44 -0
- data/lib/hecks/forms/app.rb +300 -0
- data/lib/hecks/forms/command_form_renderer.rb +113 -0
- data/lib/hecks/forms/examples/banking_console.bluebook +3 -0
- data/lib/hecks/forms/field_renderer.rb +170 -0
- data/lib/hecks/forms/field_shape.rb +232 -0
- data/lib/hecks/forms/html.rb +53 -0
- data/lib/hecks/forms/index_renderer.rb +35 -0
- data/lib/hecks/forms/page.rb +157 -0
- data/lib/hecks/forms/params.rb +132 -0
- data/lib/hecks/forms/query_form_renderer.rb +114 -0
- data/lib/hecks/forms/record_renderer.rb +115 -0
- data/lib/hecks/forms/record_table.rb +63 -0
- data/lib/hecks/forms/reference_options.rb +30 -0
- data/lib/hecks/forms/value_object_shape.rb +46 -0
- data/lib/hecks/forms.rb +54 -0
- data/lib/hecks/fqn.rb +94 -0
- data/lib/hecks/framework/bluebook/compliance.bluebook +1 -0
- data/lib/hecks/framework/bluebook/console_settings.bluebook +489 -0
- data/lib/hecks/framework/bluebook/framework.hecksagon +32 -0
- data/lib/hecks/framework/bluebook/governance.bluebook +130 -0
- data/lib/hecks/framework/bluebook/identity.bluebook +90 -0
- data/lib/hecks/framework/oidc.json +39 -0
- data/lib/hecks/framework.rb +90 -0
- data/lib/hecks/freezer.rb +67 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +86 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +92 -0
- data/lib/hecks/fuzzing/properties.rb +1146 -0
- data/lib/hecks/fuzzing/replay.rb +635 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +93 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +54 -0
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +96 -0
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +185 -0
- data/lib/hecks/fuzzing/sequence_generator.rb +130 -0
- data/lib/hecks/fuzzing/value_generator.rb +177 -0
- data/lib/hecks/fuzzing.rb +12 -0
- data/lib/hecks/grammar/evolve.rb +291 -0
- data/lib/hecks/grammar/expression.bluebook +417 -0
- data/lib/hecks/grammar/expression_operators.json +1152 -0
- data/lib/hecks/grammar/grammar.hecksagon +20 -0
- data/lib/hecks/grammar/oidc.json +69 -0
- data/lib/hecks/grammar/translation.bluebook +203 -0
- data/lib/hecks/grammar.rb +178 -0
- data/lib/hecks/ir.rb +126 -0
- data/lib/hecks/language/adapter.bluebook +116 -0
- data/lib/hecks/language/bluebook/aggregate.bluebook +581 -0
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +76 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +256 -0
- data/lib/hecks/language/bluebook/bluebook.hecksagon +24 -0
- data/lib/hecks/language/bluebook/command.bluebook +437 -0
- data/lib/hecks/language/bluebook/entity.bluebook +316 -0
- data/lib/hecks/language/bluebook/policy.bluebook +172 -0
- data/lib/hecks/language/bluebook/process_manager.bluebook +264 -0
- data/lib/hecks/language/bluebook/projection.bluebook +267 -0
- data/lib/hecks/language/bluebook/query.bluebook +245 -0
- data/lib/hecks/language/bluebook/shape.bluebook +292 -0
- data/lib/hecks/language/bluebook/syntax.bluebook +447 -0
- data/lib/hecks/language/bluebook/vocabulary.bluebook +364 -0
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +51 -0
- data/lib/hecks/language/hecksagon/domain_port.bluebook +76 -0
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +131 -0
- data/lib/hecks/language/hecksagon/port_operation.bluebook +102 -0
- data/lib/hecks/language/oidc.json +313 -0
- data/lib/hecks/language/port.bluebook +92 -0
- data/lib/hecks/language/translation/translation.bluebook +110 -0
- data/lib/hecks/language/translation/translation_aggregate.bluebook +267 -0
- data/lib/hecks/language/world/wiring.bluebook +62 -0
- data/lib/hecks/language/world/world.bluebook +84 -0
- data/lib/hecks/literal.rb +125 -0
- data/lib/hecks/naming.rb +121 -0
- data/lib/hecks/ports/access_control.port +4 -0
- data/lib/hecks/ports/access_control.rb +62 -0
- data/lib/hecks/ports/agent/answers.rb +104 -0
- data/lib/hecks/ports/agent.port +4 -0
- data/lib/hecks/ports/agent.rb +167 -0
- data/lib/hecks/ports/authentication.port +4 -0
- data/lib/hecks/ports/authentication.rb +50 -0
- data/lib/hecks/ports/authorization.port +4 -0
- data/lib/hecks/ports/authorization.rb +59 -0
- data/lib/hecks/ports/clock.port +4 -0
- data/lib/hecks/ports/clock.rb +62 -0
- data/lib/hecks/ports/extraction.port +4 -0
- data/lib/hecks/ports/extraction.rb +37 -0
- data/lib/hecks/ports/identity_assignment.port +4 -0
- data/lib/hecks/ports/identity_assignment.rb +45 -0
- data/lib/hecks/ports/identity_generation.port +4 -0
- data/lib/hecks/ports/identity_generation.rb +49 -0
- data/lib/hecks/ports/identity_resolution.port +4 -0
- data/lib/hecks/ports/identity_resolution.rb +40 -0
- data/lib/hecks/ports/loading.port +4 -0
- data/lib/hecks/ports/loading.rb +13 -0
- data/lib/hecks/ports/persistence/append_only.rb +102 -0
- data/lib/hecks/ports/persistence/binding_policy.rb +56 -0
- data/lib/hecks/ports/persistence/execution.rb +18 -0
- data/lib/hecks/ports/persistence/lineage.rb +277 -0
- data/lib/hecks/ports/persistence/null_saga_store.rb +25 -0
- data/lib/hecks/ports/persistence/remote_runtime.rb +42 -0
- data/lib/hecks/ports/persistence/repository_factory.rb +30 -0
- data/lib/hecks/ports/persistence.port +4 -0
- data/lib/hecks/ports/persistence.rb +39 -0
- data/lib/hecks/ports/projection.port +4 -0
- data/lib/hecks/ports/projection.rb +76 -0
- data/lib/hecks/ports/query/in_memory.rb +60 -0
- data/lib/hecks/ports/query/ordering.rb +41 -0
- data/lib/hecks/ports/query.rb +36 -0
- data/lib/hecks/ports.rb +27 -0
- data/lib/hecks/projections/diagrams.rb +413 -0
- data/lib/hecks/projections/ir.rb +18 -0
- data/lib/hecks/projections/model/deviations.rb +98 -0
- data/lib/hecks/projections/model.rb +145 -0
- data/lib/hecks/projections/oidc.rb +110 -0
- data/lib/hecks/projections/parser_table.rb +159 -0
- data/lib/hecks/projections/reference.rb +38 -0
- data/lib/hecks/projections/shape.rb +31 -0
- data/lib/hecks/projections/statements.rb +110 -0
- data/lib/hecks/projections/vocabulary.rb +100 -0
- data/lib/hecks/projections.rb +32 -0
- data/lib/hecks/projector/cli_projector.rb +437 -0
- data/lib/hecks/projector/docs_projector.rb +321 -0
- data/lib/hecks/projector/exporter.rb +141 -0
- data/lib/hecks/projector/ir_projector.rb +18 -0
- data/lib/hecks/projector/narrate_projector.rb +243 -0
- data/lib/hecks/projector/target.rb +97 -0
- data/lib/hecks/projector.rb +186 -0
- data/lib/hecks/query_ir.rb +392 -0
- data/lib/hecks/query_specification/common/authorization_spec.rb +9 -0
- data/lib/hecks/query_specification/common/comparators.rb +25 -0
- data/lib/hecks/query_specification/common/comparison.rb +174 -0
- data/lib/hecks/query_specification/common/cursor_spec.rb +9 -0
- data/lib/hecks/query_specification/common/dsl.rb +58 -0
- data/lib/hecks/query_specification/common/inspection_spec.rb +9 -0
- data/lib/hecks/query_specification/common/limit_spec.rb +9 -0
- data/lib/hecks/query_specification/common/null_policy.rb +80 -0
- data/lib/hecks/query_specification/common/null_semantics.rb +11 -0
- data/lib/hecks/query_specification/common/offset_spec.rb +9 -0
- data/lib/hecks/query_specification/common/options.rb +32 -0
- data/lib/hecks/query_specification/common/order_by.rb +9 -0
- data/lib/hecks/query_specification/common/specification.rb +10 -0
- data/lib/hecks/query_specification/common/where_clause.rb +9 -0
- data/lib/hecks/query_specification/field_path.rb +89 -0
- data/lib/hecks/query_specification/hop_path.rb +130 -0
- data/lib/hecks/query_specification/read_model/specification.rb +18 -0
- data/lib/hecks/query_specification.rb +14 -0
- data/lib/hecks/rendering.rb +48 -0
- data/lib/hecks/router/namespace_installer.rb +157 -0
- data/lib/hecks/router.rb +70 -0
- data/lib/hecks/runtime/caller.rb +50 -0
- data/lib/hecks/runtime/capability_graph.rb +44 -0
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +124 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +248 -0
- data/lib/hecks/runtime/command_interpreter.rb +413 -0
- data/lib/hecks/runtime/command_rules/admissibility.rb +307 -0
- data/lib/hecks/runtime/command_rules/arithmetic.rb +254 -0
- data/lib/hecks/runtime/command_rules/authorization.rb +64 -0
- data/lib/hecks/runtime/command_rules/emission.rb +34 -0
- data/lib/hecks/runtime/command_rules/references.rb +181 -0
- data/lib/hecks/runtime/command_rules.rb +28 -0
- data/lib/hecks/runtime/dependency_planning.rb +231 -0
- data/lib/hecks/runtime/dispatcher.rb +286 -0
- data/lib/hecks/runtime/entity_element.rb +253 -0
- data/lib/hecks/runtime/entity_interpreter.rb +228 -0
- data/lib/hecks/runtime/era_check.rb +136 -0
- data/lib/hecks/runtime/era_guard/shape_diff.rb +128 -0
- data/lib/hecks/runtime/era_guard.rb +193 -0
- data/lib/hecks/runtime/era_tamper.rb +61 -0
- data/lib/hecks/runtime/errors.rb +100 -0
- data/lib/hecks/runtime/event.rb +51 -0
- data/lib/hecks/runtime/identity.rb +128 -0
- data/lib/hecks/runtime/instance.rb +120 -0
- data/lib/hecks/runtime/interpreting.rb +69 -0
- data/lib/hecks/runtime/loader.rb +143 -0
- data/lib/hecks/runtime/policy_interpreter.rb +366 -0
- data/lib/hecks/runtime/port_operation_interpreter.rb +210 -0
- data/lib/hecks/runtime/query_interpreter.rb +254 -0
- data/lib/hecks/runtime/reaction_invocation.rb +245 -0
- data/lib/hecks/runtime/read_model_interpreter.rb +266 -0
- data/lib/hecks/runtime/rebuild_sweep.rb +74 -0
- data/lib/hecks/runtime/reference_hop.rb +99 -0
- data/lib/hecks/runtime/refusal_wording.rb +124 -0
- data/lib/hecks/runtime/registry/saga_persistence.rb +70 -0
- data/lib/hecks/runtime/registry/verification.rb +158 -0
- data/lib/hecks/runtime/registry.rb +218 -0
- data/lib/hecks/runtime/remote_dispatcher.rb +143 -0
- data/lib/hecks/runtime/routing.rb +96 -0
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +97 -0
- data/lib/hecks/runtime/saga_interpreter.rb +301 -0
- data/lib/hecks/runtime/storage_shape.rb +120 -0
- data/lib/hecks/runtime/tenant_check.rb +84 -0
- data/lib/hecks/runtime/tenant_scope.rb +55 -0
- data/lib/hecks/runtime/value/admission.rb +112 -0
- data/lib/hecks/runtime/value/coercion.rb +500 -0
- data/lib/hecks/runtime/value/invariant_violation.rb +5 -0
- data/lib/hecks/runtime/value.rb +125 -0
- data/lib/hecks/runtime.rb +95 -0
- data/lib/hecks/translation/audit/approval_digest.rb +31 -0
- data/lib/hecks/translation/audit/layer_one.rb +37 -0
- data/lib/hecks/translation/audit/layer_two.rb +77 -0
- data/lib/hecks/translation/audit/unfed_report.rb +42 -0
- data/lib/hecks/translation/audit.rb +70 -0
- data/lib/hecks/translation/reattest.rb +72 -0
- data/lib/hecks/translation/rule_compiler.rb +120 -0
- data/lib/hecks/translation/scaffold/differ.rb +183 -0
- data/lib/hecks/translation/scaffold/renderer.rb +41 -0
- data/lib/hecks/translation/scaffold/writer.rb +28 -0
- data/lib/hecks/translation/scaffold.rb +30 -0
- data/lib/hecks/translation.rb +11 -0
- data/lib/hecks/version.rb +16 -0
- data/lib/hecks/vocabulary.rb +213 -0
- data/lib/hecks.rb +118 -6
- metadata +401 -222
- data/bin/hecks +0 -7
- data/bin/hecks-package +0 -65
- data/bin/hecks_console +0 -12
- data/bin/hecks_serverless +0 -6
- data/lib/cli/build.rb +0 -14
- data/lib/cli/command_runner.rb +0 -28
- data/lib/cli/console.rb +0 -10
- data/lib/cli/generate.rb +0 -37
- data/lib/cli/hecks-cli.rb +0 -27
- data/lib/cli/test.rb +0 -57
- data/lib/console/commands.rb +0 -8
- data/lib/console/hecks-console.rb +0 -1
- data/lib/packager/README.md +0 -0
- data/lib/packager/app_runner.rb +0 -21
- data/lib/packager/args.rb +0 -26
- data/lib/packager/compatibility/fixnum.rb +0 -6
- data/lib/packager/hecks.rb +0 -39
- data/lib/packager/query_runner.rb +0 -21
- data/lib/packager/resources/Dockerfile +0 -11
- data/lib/packager/resources/app_binary +0 -7
- data/lib/packager/resources/bundle_config +0 -3
- data/lib/packager/resources/traveling-ruby-20150715-2.2.2-linux-x86_64.tar.gz +0 -0
- data/lib/packager/resources/traveling-ruby-20150715-2.2.2-osx.tar.gz +0 -0
- data/lib/serverless/Domain +0 -32
- data/lib/serverless/cli.rb +0 -75
- data/lib/serverless/resources/command_name.js +0 -5
- data/lib/serverless/resources/environment.js +0 -7
- data/lib/serverless/resources/handler.js.tt +0 -28
- data/lib/serverless/resources/run_binary.js +0 -22
- data/lib/serverless/resources/serverless.yml +0 -20
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
Hecks.bluebook "ConsoleSettings" do
|
|
2
|
+
vision "A generic admin console's own curated UI facts — nav, columns, state tones, which rows a detail panel shows — as real dispatched data instead of a hand-rewritten YAML file. A UI opinion the DOMAIN it's pointed at has no way to answer, never a business record; see embryonaut_console's own presentation_config.rb for the fuller story."
|
|
3
|
+
supporting
|
|
4
|
+
|
|
5
|
+
# A FRAMEWORK MEMBER LIKE IDENTITY/GOVERNANCE — attach with
|
|
6
|
+
# `uses_framework "ConsoleSettings"` in the consuming app's own
|
|
7
|
+
# `.hecksagon`, plus a `Hecks.hecksagon "ConsoleSettings" do ... end`
|
|
8
|
+
# persistence binding (Heki is the common case — a small, local,
|
|
9
|
+
# per-app settings store, no shared database needed). This used to
|
|
10
|
+
# boot in a SECOND, independent registry (embryonaut_console's own
|
|
11
|
+
# console_settings_domain.rb) specifically so no consuming app needed
|
|
12
|
+
# any change at all — that property is real and now given up on
|
|
13
|
+
# purpose, in favor of the one binding mechanism every other
|
|
14
|
+
# framework member already uses, rather than this being the one
|
|
15
|
+
# exception with its own private boot path.
|
|
16
|
+
#
|
|
17
|
+
# NOT named "Forms" — Hecks::Forms (lib/hecks/forms/) already
|
|
18
|
+
# names a different, real thing: a dormant prototype (the working half
|
|
19
|
+
# of command_form.bluebook/query_form.bluebook, see docs/command-form-
|
|
20
|
+
# and-query-form-bluebook.md) that renders raw forms/query views
|
|
21
|
+
# straight off any IR, zero config. This chapter is the opposite kind
|
|
22
|
+
# of surface — a CURATED, hand-authored dashboard's own settings — and
|
|
23
|
+
# picks a name that doesn't read as the same one.
|
|
24
|
+
#
|
|
25
|
+
# SCOPE: everything presentation.yml carries EXCEPT a collection's own
|
|
26
|
+
# `after_create` (a dispatch chain with a literal-or-$field-or-
|
|
27
|
+
# count_query arg shape — a harder design problem that shouldn't gate
|
|
28
|
+
# everything else; Ruby-side PresentationConfig keeps validating it,
|
|
29
|
+
# same as always, with nowhere yet to persist it). `overview.stats`
|
|
30
|
+
# (Overview, below) and every `extra_json`/`identity_extra_json`
|
|
31
|
+
# field throughout this chapter were BOTH originally scoped out on an
|
|
32
|
+
# "confirmed unused in any real presentation.yml" basis that turned
|
|
33
|
+
# out to be checked against the wrong file — embryonaut_console's own
|
|
34
|
+
# fixture, never this app's actual, live one. Migrating the real file
|
|
35
|
+
# found both very much in use.
|
|
36
|
+
|
|
37
|
+
aggregate "StateStyle" do
|
|
38
|
+
description "One aggregate's one lifecycle state, styled — a tone and whether it needs attention. Every real state gets a row, even a bare one (PresentationConfig's own missing_state_entries! check), so Declare and the two Set commands are separate: a bare row is a real, valid thing to have."
|
|
39
|
+
|
|
40
|
+
# `agg`, not `aggregate` — the bluebook DSL's own word for what's being
|
|
41
|
+
# declared right now; naming an attribute that would shadow it invites
|
|
42
|
+
# exactly the confusion ui_schema.rb's own identity-collision fix
|
|
43
|
+
# (see [[project_generic_founder_app]]) already had to work around
|
|
44
|
+
# once for `id`.
|
|
45
|
+
attribute :agg, StateStyleText
|
|
46
|
+
attribute :state, StateStyleText
|
|
47
|
+
attribute :tone, one_of("good", "warn", "danger", "muted", "accent"), optional: true
|
|
48
|
+
|
|
49
|
+
identified_by :agg, :state
|
|
50
|
+
# `Flag`, wrapping "true"/"false" — not a bare `String` and not
|
|
51
|
+
# `TrueClass`. Two confirmed-by-trying reasons neither works directly
|
|
52
|
+
# on an aggregate/command attribute:
|
|
53
|
+
# - `TrueClass`/`FalseClass` are real, pre-existing Ruby constants,
|
|
54
|
+
# so writing them here resolves through NORMAL Ruby constant
|
|
55
|
+
# lookup rather than ever reaching the DSL's own ConstShim (unlike
|
|
56
|
+
# a bareword like `Flag`, which has no such constant and so DOES
|
|
57
|
+
# reach it) — the meta-validator has no separate case for the
|
|
58
|
+
# literal class objects, so it goes looking for a declared value
|
|
59
|
+
# object named "TrueClass" and fails. `Attribute::PRIMITIVES`
|
|
60
|
+
# lists them, but no real bluebook in this codebase spells one.
|
|
61
|
+
# - A bare primitive (`String`, `Integer`) directly on an
|
|
62
|
+
# AGGREGATE or COMMAND attribute fails the identical way — every
|
|
63
|
+
# real example in this codebase only ever uses `String`/`Integer`
|
|
64
|
+
# INSIDE a `value_object do...end` block, never as a top-level
|
|
65
|
+
# attribute's own type; reproduced with a 4-line isolated bluebook
|
|
66
|
+
# before trusting it as a real rule, not a guess.
|
|
67
|
+
# PresentationConfig's own Ruby glue converts "true"/"false" at the
|
|
68
|
+
# boundary.
|
|
69
|
+
attribute :attention, Flag, optional: true
|
|
70
|
+
|
|
71
|
+
# WHATEVER A STATE ENTRY CARRIES THAT ISN'T tone/attention — a
|
|
72
|
+
# display `label` (e.g. Client's own "active" reading "Active
|
|
73
|
+
# client", not the raw state name) or a `note`, confirmed live as
|
|
74
|
+
# real, in-use fields this schema didn't model. Serialized, not
|
|
75
|
+
# decomposed — the same verified-then-opaque reasoning Overview's
|
|
76
|
+
# own `where_json` already documents: PresentationConfig's own
|
|
77
|
+
# reshape/write is where the real key set is enumerated and
|
|
78
|
+
# subtracted from, in Ruby, not here.
|
|
79
|
+
attribute :extra_json, StateStyleExtra, optional: true
|
|
80
|
+
|
|
81
|
+
value_object "StateStyleText" do
|
|
82
|
+
attribute :value, String
|
|
83
|
+
invariant("names something") { !value.to_s.empty? }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
value_object "Flag" do
|
|
87
|
+
attribute :value, String
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# A bare `String` fails directly on an aggregate/command attribute
|
|
91
|
+
# (StateStyleText's own comment gives the confirmed-by-trying
|
|
92
|
+
# reason) — this wraps extra_json's own opaque JSON text the same
|
|
93
|
+
# way every other scalar field in this chapter already wraps one.
|
|
94
|
+
value_object "StateStyleExtra" do
|
|
95
|
+
attribute :value, String
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
command "Declare" do
|
|
99
|
+
role "Console"
|
|
100
|
+
goal "Give one aggregate's one state a presentation row, styled or bare"
|
|
101
|
+
|
|
102
|
+
attribute :agg, StateStyleText
|
|
103
|
+
attribute :state, StateStyleText
|
|
104
|
+
|
|
105
|
+
given("a style names its own aggregate") { !agg.value.to_s.empty? }
|
|
106
|
+
given("a style names its own state") { !state.value.to_s.empty? }
|
|
107
|
+
|
|
108
|
+
emits "StateStyleDeclared"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
command "SetTone" do
|
|
112
|
+
role "Console"
|
|
113
|
+
goal "Color one state"
|
|
114
|
+
|
|
115
|
+
reference_to StateStyle
|
|
116
|
+
attribute :tone, one_of("good", "warn", "danger", "muted", "accent")
|
|
117
|
+
|
|
118
|
+
sets :tone
|
|
119
|
+
emits "ToneSet"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
command "SetAttention" do
|
|
123
|
+
role "Console"
|
|
124
|
+
goal "Mark whether one state needs a person's attention"
|
|
125
|
+
|
|
126
|
+
reference_to StateStyle
|
|
127
|
+
attribute :attention, Flag
|
|
128
|
+
|
|
129
|
+
sets :attention
|
|
130
|
+
emits "AttentionSet"
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
command "SetExtra" do
|
|
134
|
+
role "Console"
|
|
135
|
+
goal "Carry whatever per-state fields aren't individually modeled yet (label, note, ...)"
|
|
136
|
+
|
|
137
|
+
reference_to StateStyle
|
|
138
|
+
attribute :extra_json, StateStyleExtra
|
|
139
|
+
|
|
140
|
+
sets :extra_json
|
|
141
|
+
emits "StateStyleExtraSet"
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
aggregate "Collection" do
|
|
146
|
+
description "One app aggregate's own console presentation — nav label, curated columns, detail-panel fields (with an optional entity state_filter and a row_columns subset), identity-assignment strategy, field formats, preconditions, and which query lists it. Every list-shaped piece is rows on this root, never a nested list inside a value object — the same 'an open map is rows on a head' shape Wiring::Setting and Query::AskOption already use, and the same reason: no value object here can hold a map, and this sidesteps ever needing to find out whether one can hold a plain list either."
|
|
147
|
+
|
|
148
|
+
attribute :agg, SettingsText
|
|
149
|
+
|
|
150
|
+
identified_by :agg
|
|
151
|
+
|
|
152
|
+
attribute :label, SettingsText, optional: true
|
|
153
|
+
attribute :key, SettingsText, optional: true
|
|
154
|
+
attribute :nav_order, SettingsNumber, optional: true
|
|
155
|
+
attribute :primary_field, SettingsText, optional: true
|
|
156
|
+
attribute :list_query, SettingsText, optional: true
|
|
157
|
+
attribute :identity_field, SettingsText, optional: true
|
|
158
|
+
attribute :identity_strategy, one_of("slug", "sequence", "port"), optional: true
|
|
159
|
+
attribute :identity_source, SettingsText, optional: true
|
|
160
|
+
attribute :identity_prefix, SettingsText, optional: true
|
|
161
|
+
# `pad` (a sequence strategy's own zero-padding width, e.g. "C-004"
|
|
162
|
+
# vs "C-4") confirmed live as real, in-use — not modeled as its own
|
|
163
|
+
# attribute for the same reason `identity_source`/`identity_prefix`
|
|
164
|
+
# aren't a closed set either: whatever a real identity rule carries
|
|
165
|
+
# beyond field/strategy/source/prefix, opaque, same as extra_json
|
|
166
|
+
# below.
|
|
167
|
+
attribute :identity_extra_json, CollectionExtra, optional: true
|
|
168
|
+
attribute :columns, list_of(Column)
|
|
169
|
+
attribute :detail_fields, list_of(DetailField)
|
|
170
|
+
attribute :detail_field_columns, list_of(DetailFieldColumn)
|
|
171
|
+
attribute :preconditions, list_of(Precondition)
|
|
172
|
+
attribute :field_formats, list_of(FieldFormat)
|
|
173
|
+
# WHATEVER A COLLECTION ENTRY CARRIES beyond the fields above —
|
|
174
|
+
# `noun_sing`, `create_label`, `nav_group` confirmed live as real,
|
|
175
|
+
# in-use fields this schema didn't model (10/8/2 real occurrences
|
|
176
|
+
# respectively). Same verified-then-opaque reasoning as StateStyle's
|
|
177
|
+
# own extra_json.
|
|
178
|
+
attribute :extra_json, CollectionExtra, optional: true
|
|
179
|
+
|
|
180
|
+
value_object "SettingsText" do
|
|
181
|
+
attribute :value, String
|
|
182
|
+
invariant("names something") { !value.to_s.empty? }
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
value_object "SettingsNumber" do
|
|
186
|
+
attribute :value, Integer
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# A bare `String` fails directly on an aggregate/command attribute —
|
|
190
|
+
# see StateStyleExtra's own comment. Shared by both extra_json and
|
|
191
|
+
# identity_extra_json; both are opaque JSON text, no reason for two
|
|
192
|
+
# separate wrapper types.
|
|
193
|
+
value_object "CollectionExtra" do
|
|
194
|
+
attribute :value, String
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# A list/table column. `sortable`/`sort_default` are optional — most
|
|
198
|
+
# columns take the frontend's own default (sortable, no forced order).
|
|
199
|
+
# `sort_default` stays a plain String, not a closed set — narrow
|
|
200
|
+
# enough (and PresentationConfig.validate! already checks it in
|
|
201
|
+
# Ruby) that a dedicated `one_of: [...]` (S3, ADR 0025 — the field's
|
|
202
|
+
# own keyword now, no sibling value object or `admits:` indirection
|
|
203
|
+
# needed) still isn't worth it for this one field.
|
|
204
|
+
value_object "Column" do
|
|
205
|
+
attribute :field, String
|
|
206
|
+
attribute :sortable, String, optional: true # "true"/"false" — see StateStyle.attention's own comment
|
|
207
|
+
attribute :sort_default, String, optional: true
|
|
208
|
+
# `head`/`as`/`hop` confirmed live as real, in-use column-level
|
|
209
|
+
# overrides this schema didn't model — verified-then-opaque, same
|
|
210
|
+
# reasoning as StateStyle's own extra_json.
|
|
211
|
+
attribute :extra_json, String, optional: true
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# One field the detail panel shows. `state_filter` only means anything
|
|
215
|
+
# on an entity-backed rows field (ui_schema.rb's own apply_row_state_
|
|
216
|
+
# filter checks this at read time, same as it does today) — nothing
|
|
217
|
+
# here refuses a state_filter on the wrong shape of field, since that
|
|
218
|
+
# check needs the APP's own live IR, which this domain can't see; it
|
|
219
|
+
# stays a Ruby-side PresentationConfig.validate! check, same as always.
|
|
220
|
+
# `display` is a plain String for the same nested-`one_of` collision
|
|
221
|
+
# reason `sort_default` is, above.
|
|
222
|
+
value_object "DetailField" do
|
|
223
|
+
attribute :field, String
|
|
224
|
+
attribute :display, String, optional: true
|
|
225
|
+
attribute :state_filter, String, optional: true
|
|
226
|
+
# `head`/`as`/`hop` confirmed live as real, in-use detail-field
|
|
227
|
+
# overrides this schema didn't model — verified-then-opaque, same
|
|
228
|
+
# reasoning as StateStyle's own extra_json.
|
|
229
|
+
attribute :extra_json, String, optional: true
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# A rows-shaped detail field's own sub-column filter, FLATTENED to one
|
|
233
|
+
# row per (field, column) pair rather than nested inside DetailField —
|
|
234
|
+
# grouped back by `field` on the way out. The same flattening
|
|
235
|
+
# Query::AskOption already uses for a compound option's own parts.
|
|
236
|
+
value_object "DetailFieldColumn" do
|
|
237
|
+
attribute :field, String
|
|
238
|
+
attribute :column, String
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
value_object "Precondition" do
|
|
242
|
+
attribute :field, String
|
|
243
|
+
attribute :state, String
|
|
244
|
+
# `message` (a custom refusal message override) confirmed live as
|
|
245
|
+
# real, in-use — verified-then-opaque, same reasoning as
|
|
246
|
+
# StateStyle's own extra_json.
|
|
247
|
+
attribute :extra_json, String, optional: true
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# `format` stays a plain String too — same nested-`one_of` collision.
|
|
251
|
+
value_object "FieldFormat" do
|
|
252
|
+
attribute :field, String
|
|
253
|
+
attribute :format, String
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
command "Declare" do
|
|
257
|
+
role "Console"
|
|
258
|
+
goal "Give one app aggregate a presentation row, before anything is curated on it yet"
|
|
259
|
+
|
|
260
|
+
attribute :agg, SettingsText
|
|
261
|
+
|
|
262
|
+
given("a collection names its own aggregate") { !agg.value.to_s.empty? }
|
|
263
|
+
|
|
264
|
+
emits "CollectionDeclared"
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
command "SetLabel" do
|
|
268
|
+
role "Console"
|
|
269
|
+
goal "Name a collection's own nav label"
|
|
270
|
+
|
|
271
|
+
reference_to Collection
|
|
272
|
+
attribute :label, SettingsText
|
|
273
|
+
|
|
274
|
+
sets :label
|
|
275
|
+
emits "LabelSet"
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
command "SetKey" do
|
|
279
|
+
role "Console"
|
|
280
|
+
goal "Override a collection's own nav/route key"
|
|
281
|
+
|
|
282
|
+
reference_to Collection
|
|
283
|
+
attribute :key, SettingsText
|
|
284
|
+
|
|
285
|
+
sets :key
|
|
286
|
+
emits "KeySet"
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
command "SetNavOrder" do
|
|
290
|
+
role "Console"
|
|
291
|
+
goal "Place a collection in the nav"
|
|
292
|
+
|
|
293
|
+
reference_to Collection
|
|
294
|
+
attribute :nav_order, SettingsNumber
|
|
295
|
+
|
|
296
|
+
sets :nav_order
|
|
297
|
+
emits "NavOrderSet"
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
command "SetPrimaryField" do
|
|
301
|
+
role "Console"
|
|
302
|
+
goal "Name which field stands in for a whole record"
|
|
303
|
+
|
|
304
|
+
reference_to Collection
|
|
305
|
+
attribute :primary_field, SettingsText
|
|
306
|
+
|
|
307
|
+
sets :primary_field
|
|
308
|
+
emits "PrimaryFieldSet"
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
command "SetListQuery" do
|
|
312
|
+
role "Console"
|
|
313
|
+
goal "Name which of an aggregate's own queries lists its records"
|
|
314
|
+
|
|
315
|
+
reference_to Collection
|
|
316
|
+
attribute :list_query, SettingsText
|
|
317
|
+
|
|
318
|
+
sets :list_query
|
|
319
|
+
emits "ListQuerySet"
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
command "SetIdentity" do
|
|
323
|
+
role "Console"
|
|
324
|
+
goal "Name how a collection assigns its own new records' identity"
|
|
325
|
+
|
|
326
|
+
reference_to Collection
|
|
327
|
+
attribute :identity_field, SettingsText
|
|
328
|
+
attribute :identity_strategy, one_of("slug", "sequence", "port")
|
|
329
|
+
|
|
330
|
+
sets :identity_field
|
|
331
|
+
sets :identity_strategy
|
|
332
|
+
sets :identity_source
|
|
333
|
+
sets :identity_prefix
|
|
334
|
+
sets :identity_extra_json
|
|
335
|
+
emits "IdentitySet"
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
command "SetExtra" do
|
|
339
|
+
role "Console"
|
|
340
|
+
goal "Carry whatever per-collection fields aren't individually modeled yet (noun_sing, create_label, nav_group, ...)"
|
|
341
|
+
|
|
342
|
+
reference_to Collection
|
|
343
|
+
attribute :extra_json, CollectionExtra
|
|
344
|
+
|
|
345
|
+
sets :extra_json
|
|
346
|
+
emits "CollectionExtraSet"
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
command "ReplaceColumns" do
|
|
350
|
+
role "Console"
|
|
351
|
+
goal "Replace a collection's own whole list of table columns"
|
|
352
|
+
|
|
353
|
+
reference_to Collection
|
|
354
|
+
|
|
355
|
+
sets :columns
|
|
356
|
+
emits "ColumnsReplaced"
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
command "ReplaceDetailFields" do
|
|
360
|
+
role "Console"
|
|
361
|
+
goal "Replace a collection's own whole list of detail-panel fields"
|
|
362
|
+
|
|
363
|
+
reference_to Collection
|
|
364
|
+
|
|
365
|
+
sets :detail_fields
|
|
366
|
+
emits "DetailFieldsReplaced"
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
command "ReplaceDetailFieldColumns" do
|
|
370
|
+
role "Console"
|
|
371
|
+
goal "Replace every rows-field's own sub-column filter, whole"
|
|
372
|
+
|
|
373
|
+
reference_to Collection
|
|
374
|
+
|
|
375
|
+
sets :detail_field_columns
|
|
376
|
+
emits "DetailFieldColumnsReplaced"
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
command "ReplacePreconditions" do
|
|
380
|
+
role "Console"
|
|
381
|
+
goal "Replace a collection's own whole list of dispatch preconditions"
|
|
382
|
+
|
|
383
|
+
reference_to Collection
|
|
384
|
+
|
|
385
|
+
sets :preconditions
|
|
386
|
+
emits "PreconditionsReplaced"
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
command "ReplaceFieldFormats" do
|
|
390
|
+
role "Console"
|
|
391
|
+
goal "Replace a collection's own whole list of field display formats"
|
|
392
|
+
|
|
393
|
+
reference_to Collection
|
|
394
|
+
|
|
395
|
+
sets :field_formats
|
|
396
|
+
emits "FieldFormatsReplaced"
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
# THE DASHBOARD'S OWN STAT CARDS — domain-WIDE, not per-aggregate the
|
|
401
|
+
# way Collection is (a stat can name any collection, or none in
|
|
402
|
+
# particular), so this is a SINGLETON: exactly one row, ever, for the
|
|
403
|
+
# whole console. `attribute :key, OverviewKey` holds a literal constant
|
|
404
|
+
# ("overview") rather than anything a person chooses — the same reason
|
|
405
|
+
# a creating command needs SOME identity to hydrate against (hydrate's
|
|
406
|
+
# own "an identity that is invented is neither derived from the record
|
|
407
|
+
# nor permanently associated with it" comment), just with the value
|
|
408
|
+
# fixed instead of derived from what's being declared.
|
|
409
|
+
aggregate "Overview" do
|
|
410
|
+
description "The console's own dashboard stat cards, whole. One row, ever — `key` is always the literal 'overview', never chosen. Every stat gets replaced as a whole list on save, the same 'replace whole, never patch one' convention Collection's own columns/detail_fields/preconditions/field_formats already use."
|
|
411
|
+
|
|
412
|
+
attribute :key, OverviewKey
|
|
413
|
+
|
|
414
|
+
identified_by :key
|
|
415
|
+
|
|
416
|
+
attribute :stats, list_of(Stat)
|
|
417
|
+
|
|
418
|
+
value_object "OverviewKey" do
|
|
419
|
+
attribute :value, String
|
|
420
|
+
invariant("is the one true singleton key") { value == "overview" }
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
# `where_json` carries the stat's own recursive filter expression
|
|
424
|
+
# (`not:` wrapping another whole where clause, `state:`/
|
|
425
|
+
# `has_related:`/`not_has_related:` combined by implicit AND) —
|
|
426
|
+
# serialized, not decomposed into the bluebook's own closed
|
|
427
|
+
# attribute grammar. That tree is genuinely open-ended (arbitrary
|
|
428
|
+
# nesting depth via `not:`, an arbitrary literal attribute name as
|
|
429
|
+
# a where key for anything that isn't `state`), and hecks's
|
|
430
|
+
# attribute types have no way to express "arbitrary nested map" at
|
|
431
|
+
# all — the same reason `sort_default`/`display`/`format` above stay
|
|
432
|
+
# plain Strings rather than a nested `one_of`. PresentationConfig's
|
|
433
|
+
# own `validate_where!`/`validate_has_related!` still walk and check
|
|
434
|
+
# the REAL structure, in Ruby, against the app's own live IR, before
|
|
435
|
+
# this is ever serialized and dispatched — this field is the
|
|
436
|
+
# verified-then-opaque storage, not an unchecked one.
|
|
437
|
+
value_object "Stat" do
|
|
438
|
+
attribute :label, String
|
|
439
|
+
attribute :collection, String
|
|
440
|
+
attribute :as, String, optional: true
|
|
441
|
+
attribute :field, String, optional: true
|
|
442
|
+
attribute :where_json, String, optional: true
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
command "Declare" do
|
|
446
|
+
role "Console"
|
|
447
|
+
goal "Create the one console-wide overview row, before any stat is curated"
|
|
448
|
+
|
|
449
|
+
attribute :key, OverviewKey
|
|
450
|
+
|
|
451
|
+
given("only the one true singleton key is ever declared") { key.value == "overview" }
|
|
452
|
+
|
|
453
|
+
emits "OverviewDeclared"
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
command "ReplaceStats" do
|
|
457
|
+
role "Console"
|
|
458
|
+
goal "Replace the dashboard's whole list of stat cards"
|
|
459
|
+
|
|
460
|
+
reference_to Overview
|
|
461
|
+
|
|
462
|
+
sets :stats
|
|
463
|
+
emits "StatsReplaced"
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
# BOTH ROOTLESS — bulk, no root record, no id argument at dispatch —
|
|
468
|
+
# and grouped by an aggregate's own full identity, which is what makes
|
|
469
|
+
# each leaf exactly one row rather than an arbitrary collision (see
|
|
470
|
+
# `group_by`'s own reference doc). PresentationConfig.rb's own read
|
|
471
|
+
# side (`reshape_states`/`reshape_collections`) dispatches these
|
|
472
|
+
# instead of hand-rolling the unwrap/grouping in Ruby — see its own
|
|
473
|
+
# header for what's still Ruby (the detail_field_columns/detail_fields
|
|
474
|
+
# join, which isn't a report concern at all — two list attributes on
|
|
475
|
+
# the SAME record, not two aggregates — and Overview's own stat cards,
|
|
476
|
+
# which are read straight off Overview.find, a singleton needing
|
|
477
|
+
# neither grouping nor unwrapping either).
|
|
478
|
+
read_model "Styles" do
|
|
479
|
+
description "Every StateStyle row, nested by the aggregate and state it styles."
|
|
480
|
+
include StateStyle
|
|
481
|
+
group_by :agg, :state
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
read_model "Curated" do
|
|
485
|
+
description "Every Collection row, nested by the app aggregate it curates."
|
|
486
|
+
include Collection
|
|
487
|
+
group_by :agg
|
|
488
|
+
end
|
|
489
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# The framework members, bound so they can boot standing alone —
|
|
2
|
+
# `Hecks.boot("lib/hecks/framework")` rather than only as something
|
|
3
|
+
# another domain attached with `uses_framework`.
|
|
4
|
+
#
|
|
5
|
+
# `uses_framework` does NOT read this file (Framework.load! loads a
|
|
6
|
+
# member's bluebook and nothing else, deliberately — see framework.rb),
|
|
7
|
+
# so an attaching domain still declares its own binding for these
|
|
8
|
+
# aggregates, exactly as before. This only answers the case where the
|
|
9
|
+
# framework is the domain being booted.
|
|
10
|
+
Hecks.hecksagon "Compliance" do
|
|
11
|
+
# Every command here declares `role "Compliance officer"` — only real
|
|
12
|
+
# access control once Governance can check it against something (S8).
|
|
13
|
+
uses_framework "Governance"
|
|
14
|
+
persisted_by "Memory"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
Hecks.hecksagon "ConsoleSettings" do
|
|
18
|
+
# Same reason as Compliance, above — S8.
|
|
19
|
+
uses_framework "Governance"
|
|
20
|
+
persisted_by "Memory"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
Hecks.hecksagon "Governance" do
|
|
24
|
+
persisted_by "Memory"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Hecks.hecksagon "Identity" do
|
|
28
|
+
# `Identity::Identity.Register` declares `role "Identity registrar"` —
|
|
29
|
+
# same reason as Compliance/ConsoleSettings, above — S8.
|
|
30
|
+
uses_framework "Governance"
|
|
31
|
+
persisted_by "Memory"
|
|
32
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
Hecks.bluebook "Governance" do
|
|
2
|
+
vision "Organizational authority is explicit, reviewable, and historically explainable."
|
|
3
|
+
supporting
|
|
4
|
+
|
|
5
|
+
aggregate "RoleAssignment" do
|
|
6
|
+
description "One actor holding one role, over one scope, from one point in time — revoked by setting when it ended, never deleted."
|
|
7
|
+
|
|
8
|
+
# THE IDENTITY IS THE EVENT, not the (actor, role) pair — an actor can
|
|
9
|
+
# hold the same role again later, after a prior assignment ended, and
|
|
10
|
+
# that is a SECOND real assignment, not a state to overwrite. No UUID
|
|
11
|
+
# adapter exists yet in this codebase to mint a synthetic id, and none
|
|
12
|
+
# is needed: `starts_at` already makes "this actor started holding this
|
|
13
|
+
# role at this time" unique on its own.
|
|
14
|
+
attribute :actor_id, IdentityId
|
|
15
|
+
attribute :role_name, RoleName
|
|
16
|
+
attribute :scope, Scope
|
|
17
|
+
attribute :starts_at, Timestamp
|
|
18
|
+
attribute :ends_at, Timestamp, optional: true
|
|
19
|
+
|
|
20
|
+
identified_by :actor_id, :role_name, :starts_at
|
|
21
|
+
|
|
22
|
+
value_object "IdentityId" do
|
|
23
|
+
attribute :value, String
|
|
24
|
+
invariant("an identity id is present") { !value.to_s.empty? }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
value_object "RoleName" do
|
|
28
|
+
attribute :value, String
|
|
29
|
+
invariant("a role is named") { !value.to_s.empty? }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
value_object "Scope" do
|
|
33
|
+
attribute :value, String
|
|
34
|
+
invariant("a scope is named") { !value.to_s.empty? }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
value_object "Timestamp" do
|
|
38
|
+
attribute :value, String
|
|
39
|
+
invariant("a timestamp is present") { !value.to_s.empty? }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
command "Assign" do
|
|
43
|
+
role "Governance administrator"
|
|
44
|
+
goal "Authorize an actor to perform a responsibility"
|
|
45
|
+
|
|
46
|
+
attribute :actor_id, IdentityId
|
|
47
|
+
attribute :role_name, RoleName
|
|
48
|
+
attribute :scope, Scope
|
|
49
|
+
attribute :starts_at, Timestamp
|
|
50
|
+
|
|
51
|
+
emits "RoleAssigned"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
command "Revoke" do
|
|
55
|
+
role "Governance administrator"
|
|
56
|
+
goal "Remove organizational authority"
|
|
57
|
+
|
|
58
|
+
reference_to RoleAssignment
|
|
59
|
+
attribute :ends_at, Timestamp
|
|
60
|
+
|
|
61
|
+
sets :ends_at
|
|
62
|
+
emits "RoleRevoked"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
query "AssignmentsForActor" do
|
|
66
|
+
description "Every role an actor currently or historically holds."
|
|
67
|
+
attribute :actor_id, IdentityId
|
|
68
|
+
where(actor_id: :actor_id)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# WHO HOLDS A ROLE is `RoleAssignment`'s question. This is a different one:
|
|
73
|
+
# may role X ACT AS role Y — the fact `act_as` (the plan's §2) needs before
|
|
74
|
+
# a caller is allowed to dispatch under a role it does not itself hold.
|
|
75
|
+
# Same event-log shape as RoleAssignment : a natural key, `ends_at` for
|
|
76
|
+
# revocation, no delete.
|
|
77
|
+
aggregate "RoleTransition" do
|
|
78
|
+
description "Role X is authorized to act as role Y — until revoked."
|
|
79
|
+
|
|
80
|
+
attribute :from_role, RoleName
|
|
81
|
+
attribute :to_role, RoleName
|
|
82
|
+
attribute :ends_at, Timestamp, optional: true
|
|
83
|
+
|
|
84
|
+
identified_by :from_role, :to_role
|
|
85
|
+
|
|
86
|
+
value_object "RoleName" do
|
|
87
|
+
attribute :value, String
|
|
88
|
+
invariant("a role is named") { !value.to_s.empty? }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
value_object "Timestamp" do
|
|
92
|
+
attribute :value, String
|
|
93
|
+
invariant("a timestamp is present") { !value.to_s.empty? }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
command "Grant" do
|
|
97
|
+
role "Governance administrator"
|
|
98
|
+
goal "Authorize one role to act as another"
|
|
99
|
+
|
|
100
|
+
attribute :from_role, RoleName
|
|
101
|
+
attribute :to_role, RoleName
|
|
102
|
+
|
|
103
|
+
emits "RoleTransitionGranted"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
command "Revoke" do
|
|
107
|
+
role "Governance administrator"
|
|
108
|
+
goal "Remove an authorized role transition"
|
|
109
|
+
|
|
110
|
+
reference_to RoleTransition
|
|
111
|
+
attribute :ends_at, Timestamp
|
|
112
|
+
|
|
113
|
+
sets :ends_at
|
|
114
|
+
emits "RoleTransitionRevoked"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# THE RECORD FOR THIS PAIR, granted or revoked — same deferral
|
|
118
|
+
# `AssignmentsForActor` already makes for RoleAssignment: the where
|
|
119
|
+
# clause has no way to ask "and ends_at is absent", so the query
|
|
120
|
+
# answers with the row and the CALLER reads `ends_at` to tell a
|
|
121
|
+
# live grant from a revoked one, exactly as it already must for
|
|
122
|
+
# every assignment.
|
|
123
|
+
query "Allowed" do
|
|
124
|
+
description "The role transition granted for this exact pair, if any — revoked or not."
|
|
125
|
+
attribute :from_role, RoleName
|
|
126
|
+
attribute :to_role, RoleName
|
|
127
|
+
where(from_role: :from_role, to_role: :to_role)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|