domainforge 0.13.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.
- package/.cargo/config.toml +6 -0
- package/.claude/settings.local.json +18 -0
- package/.coderabbit.yml +43 -0
- package/.codex/skills/release-management/SKILL.md +151 -0
- package/.codex/skills/release-management/agents/openai.yaml +4 -0
- package/.github/actions/decrypt-secrets/action.yml +121 -0
- package/.github/agents/Coder.agent.md +97 -0
- package/.github/agents/DeepResearch.agent.md +61 -0
- package/.github/chatmodes/tdd.vibepro.chatmode.md +1183 -0
- package/.github/copilot-instructions.md +13 -0
- package/.github/dependabot.yml +68 -0
- package/.github/workflows/README.md +165 -0
- package/.github/workflows/ci.yml +335 -0
- package/.github/workflows/dependabot-automerge.yml +114 -0
- package/.github/workflows/dependency-review.yml +27 -0
- package/.github/workflows/deploy.yml +87 -0
- package/.github/workflows/prepare-release.yml +168 -0
- package/.github/workflows/release-crates.yml +42 -0
- package/.github/workflows/release-npm.yml +137 -0
- package/.github/workflows/release-please.yml +29 -0
- package/.github/workflows/release-pypi.yml +96 -0
- package/.gitkeep +1 -0
- package/.release-please-manifest.json +5 -0
- package/.sea-registry.toml +10 -0
- package/.serena/project.yml +133 -0
- package/.sops.yaml +10 -0
- package/AGENTS.md +216 -0
- package/CHANGELOG.md +400 -0
- package/CLAUDE.md +62 -0
- package/CONTRIBUTING.md +323 -0
- package/Cargo.lock +3612 -0
- package/Cargo.toml +12 -0
- package/LICENSE +201 -0
- package/README.md +660 -0
- package/README_PYTHON.md +256 -0
- package/README_TYPESCRIPT.md +305 -0
- package/README_WASM.md +329 -0
- package/RELEASE_NOTES.md +41 -0
- package/bun.lock +378 -0
- package/bunfig.toml +11 -0
- package/check_output.txt +83 -0
- package/clippy_output.txt +80 -0
- package/commitlint.config.cjs +8 -0
- package/deny.toml +42 -0
- package/devbox.json +14 -0
- package/devbox.lock +76 -0
- package/docs/RELEASE_PROCESS.md +360 -0
- package/docs/diagnostics.md +161 -0
- package/docs/doc_guidelines.md +53 -0
- package/docs/explanations/README.md +21 -0
- package/docs/explanations/architecture-overview.md +109 -0
- package/docs/explanations/cross-language-binding-strategy.md +68 -0
- package/docs/explanations/graph-store-design.md +47 -0
- package/docs/explanations/performance-benchmarks.md +63 -0
- package/docs/explanations/policy-evaluation-logic.md +106 -0
- package/docs/explanations/semantic-modeling-concepts.md +109 -0
- package/docs/explanations/three-valued-logic.md +66 -0
- package/docs/explanations/versioning-strategy.md +45 -0
- package/docs/governance.md +168 -0
- package/docs/how-tos/README.md +46 -0
- package/docs/how-tos/ci-cd-validation.md +93 -0
- package/docs/how-tos/create-custom-units.md +125 -0
- package/docs/how-tos/define-policies.md +119 -0
- package/docs/how-tos/export-to-calm.md +110 -0
- package/docs/how-tos/export-to-protobuf.md +312 -0
- package/docs/how-tos/extend-grammar.md +133 -0
- package/docs/how-tos/generate-rdf-turtle.md +106 -0
- package/docs/how-tos/import-from-calm.md +114 -0
- package/docs/how-tos/import-from-sbvr.md +249 -0
- package/docs/how-tos/install-cli.md +126 -0
- package/docs/how-tos/parse-sea-files.md +132 -0
- package/docs/how-tos/policy-evaluation-modes.md +30 -0
- package/docs/how-tos/run-cross-language-tests.md +115 -0
- package/docs/how-tos/troubleshoot-napi-builds.md +55 -0
- package/docs/how-tos/use-modules-imports.md +285 -0
- package/docs/index.md +13 -0
- package/docs/plans/canonical-normalizer.md +121 -0
- package/docs/plans/cd_improvement.md +112 -0
- package/docs/plans/cli-ast.md +29 -0
- package/docs/plans/expression-bindings-and-normalizer-integration.md +174 -0
- package/docs/plans/protobuf_advanced_features_plan.md +597 -0
- package/docs/plans/protobuf_plan.yml +525 -0
- package/docs/plans/refactor_dsl_architecture.md +131 -0
- package/docs/plans/release-plan.md +163 -0
- package/docs/plans/sea_fmt_implementation_plan.md +516 -0
- package/docs/playbooks/README.md +18 -0
- package/docs/playbooks/adding-new-primitive.md +68 -0
- package/docs/playbooks/debugging-parser-failures.md +42 -0
- package/docs/playbooks/local-release-preparation.md +139 -0
- package/docs/playbooks/migrating-schema-versions.md +43 -0
- package/docs/playbooks/onboarding-contributors.md +64 -0
- package/docs/playbooks/releasing-beta.md +86 -0
- package/docs/playbooks/secret-management.md +64 -0
- package/docs/reference/README.md +199 -0
- package/docs/reference/ast-json-api.md +427 -0
- package/docs/reference/calm-mapping.md +519 -0
- package/docs/reference/cli-commands.md +588 -0
- package/docs/reference/configuration.md +202 -0
- package/docs/reference/error-codes.md +664 -0
- package/docs/reference/generated-artifacts-policy.md +53 -0
- package/docs/reference/grammar-spec.md +255 -0
- package/docs/reference/primitives-api.md +317 -0
- package/docs/reference/protobuf-api.md +426 -0
- package/docs/reference/python-api.md +485 -0
- package/docs/reference/registry.md +50 -0
- package/docs/reference/sea-dsl-ai-cheatsheet.yaml +913 -0
- package/docs/reference/security-model.md +74 -0
- package/docs/reference/typescript-api.md +508 -0
- package/docs/reference/wasm-api.md +420 -0
- package/docs/semantic-pack-review.md +144 -0
- package/docs/semantic-pack-signing.md +234 -0
- package/docs/semantic-packs.md +284 -0
- package/docs/specs/ADR-001-sea-dsl-semantic-source-of-truth.md +33 -0
- package/docs/specs/ADR-002-projection-first-class-construct.md +50 -0
- package/docs/specs/ADR-003-protobuf-projection-target.md +51 -0
- package/docs/specs/ADR-004-projection-compatibility-semantics.md +57 -0
- package/docs/specs/ADR-005-multi-language-support-strategy.md +112 -0
- package/docs/specs/ADR-006-error-handling-strategy.md +115 -0
- package/docs/specs/ADR-007-policy-evaluation-engine.md +95 -0
- package/docs/specs/ADR-008-knowledge-graph-integration.md +90 -0
- package/docs/specs/ADR-009-module-resolution-strategy.md +115 -0
- package/docs/specs/ADR-010-unit-system.md +106 -0
- package/docs/specs/PRD-001-sea-projection-framework.md +155 -0
- package/docs/specs/PRD-002-sea-cli-tooling.md +169 -0
- package/docs/specs/PRD-003-dsl-core-capabilities.md +275 -0
- package/docs/specs/README.md +62 -0
- package/docs/specs/SDS-001-protobuf-projection-engine.md +451 -0
- package/docs/specs/SDS-002-sea-core-architecture.md +268 -0
- package/docs/specs/SDS-003-parser-semantic-graph.md +377 -0
- package/docs/specs/SDS-004-policy-engine-design.md +362 -0
- package/docs/specs/SDS-005-knowledge-graph-module.md +364 -0
- package/docs/specs/SDS-006-calm-integration.md +367 -0
- package/docs/specs/SDS-007-sbvr-import.md +347 -0
- package/docs/templates/template_explanation.md +14 -0
- package/docs/templates/template_howto.md +21 -0
- package/docs/templates/template_playbook.md +21 -0
- package/docs/templates/template_reference.md +17 -0
- package/docs/templates/template_tutorial.md +24 -0
- package/docs/tutorials/README.md +12 -0
- package/docs/tutorials/first-sea-model.md +85 -0
- package/docs/tutorials/getting-started.md +98 -0
- package/docs/tutorials/python-binding-quickstart.md +107 -0
- package/docs/tutorials/typescript-binding-quickstart.md +91 -0
- package/docs/tutorials/wasm-in-browser.md +75 -0
- package/domainforge-core/CHANGELOG.md +138 -0
- package/domainforge-core/Cargo.toml +101 -0
- package/domainforge-core/MIGRATING.md +32 -0
- package/domainforge-core/README.md +197 -0
- package/domainforge-core/benchmark_results.txt +51 -0
- package/domainforge-core/build.rs +6 -0
- package/domainforge-core/deny.toml +31 -0
- package/domainforge-core/docs/specs/projections/sbvr_kg_mapping.md +43 -0
- package/domainforge-core/examples/basic.sea +7 -0
- package/domainforge-core/examples/cli/import_export_workflow.sh +38 -0
- package/domainforge-core/examples/cli/validate_example.sh +30 -0
- package/domainforge-core/examples/evolution_semantics.sea +31 -0
- package/domainforge-core/examples/parser_demo.rs +203 -0
- package/domainforge-core/grammar/sea.pest +408 -0
- package/domainforge-core/schemas/calm-v1.schema.json +170 -0
- package/domainforge-core/schemas/shacl/sea_shapes.ttl +19 -0
- package/domainforge-core/src/authority/compiler.rs +309 -0
- package/domainforge-core/src/authority/environment.rs +203 -0
- package/domainforge-core/src/authority/error.rs +164 -0
- package/domainforge-core/src/authority/fact_resolver.rs +224 -0
- package/domainforge-core/src/authority/mod.rs +25 -0
- package/domainforge-core/src/authority/pack.rs +133 -0
- package/domainforge-core/src/authority/policy.rs +224 -0
- package/domainforge-core/src/authority/resolver.rs +446 -0
- package/domainforge-core/src/authority/trace.rs +217 -0
- package/domainforge-core/src/authority/transform.rs +168 -0
- package/domainforge-core/src/authority/types.rs +617 -0
- package/domainforge-core/src/bin/domainforge.rs +25 -0
- package/domainforge-core/src/calm/export.rs +538 -0
- package/domainforge-core/src/calm/import.rs +1220 -0
- package/domainforge-core/src/calm/mod.rs +9 -0
- package/domainforge-core/src/calm/models.rs +108 -0
- package/domainforge-core/src/calm/sbvr_import.rs +9 -0
- package/domainforge-core/src/cli/authority.rs +149 -0
- package/domainforge-core/src/cli/format.rs +85 -0
- package/domainforge-core/src/cli/import.rs +133 -0
- package/domainforge-core/src/cli/mod.rs +64 -0
- package/domainforge-core/src/cli/normalize.rs +180 -0
- package/domainforge-core/src/cli/pack.rs +904 -0
- package/domainforge-core/src/cli/parse.rs +112 -0
- package/domainforge-core/src/cli/project.rs +294 -0
- package/domainforge-core/src/cli/registry.rs +41 -0
- package/domainforge-core/src/cli/test.rs +12 -0
- package/domainforge-core/src/cli/validate.rs +195 -0
- package/domainforge-core/src/cli/validate_kg.rs +80 -0
- package/domainforge-core/src/concept_id.rs +89 -0
- package/domainforge-core/src/error/diagnostics.rs +426 -0
- package/domainforge-core/src/error/fuzzy.rs +253 -0
- package/domainforge-core/src/error/mod.rs +13 -0
- package/domainforge-core/src/formatter/comments.rs +223 -0
- package/domainforge-core/src/formatter/config.rs +114 -0
- package/domainforge-core/src/formatter/mod.rs +22 -0
- package/domainforge-core/src/formatter/printer.rs +906 -0
- package/domainforge-core/src/graph/mod.rs +858 -0
- package/domainforge-core/src/graph/to_ast.rs +66 -0
- package/domainforge-core/src/kg.rs +1476 -0
- package/domainforge-core/src/kg_import.rs +251 -0
- package/domainforge-core/src/lib.rs +203 -0
- package/domainforge-core/src/module/mod.rs +1 -0
- package/domainforge-core/src/module/resolver.rs +260 -0
- package/domainforge-core/src/parser/ast.rs +2919 -0
- package/domainforge-core/src/parser/ast_convert.rs +494 -0
- package/domainforge-core/src/parser/ast_schema.rs +491 -0
- package/domainforge-core/src/parser/error.rs +291 -0
- package/domainforge-core/src/parser/lint.rs +39 -0
- package/domainforge-core/src/parser/mod.rs +193 -0
- package/domainforge-core/src/parser/printer.rs +702 -0
- package/domainforge-core/src/parser/profiles.rs +71 -0
- package/domainforge-core/src/parser/string_utils.rs +138 -0
- package/domainforge-core/src/patterns.rs +68 -0
- package/domainforge-core/src/policy/core.rs +1148 -0
- package/domainforge-core/src/policy/expression.rs +399 -0
- package/domainforge-core/src/policy/mod.rs +18 -0
- package/domainforge-core/src/policy/normalize.rs +1028 -0
- package/domainforge-core/src/policy/quantifier.rs +940 -0
- package/domainforge-core/src/policy/three_valued.rs +140 -0
- package/domainforge-core/src/policy/three_valued_microbench.rs +104 -0
- package/domainforge-core/src/policy/type_inference.rs +67 -0
- package/domainforge-core/src/policy/violation.rs +36 -0
- package/domainforge-core/src/primitives/concept_change.rs +61 -0
- package/domainforge-core/src/primitives/entity.rs +224 -0
- package/domainforge-core/src/primitives/flow.rs +111 -0
- package/domainforge-core/src/primitives/instance.rs +93 -0
- package/domainforge-core/src/primitives/mapping_contract.rs +50 -0
- package/domainforge-core/src/primitives/metric.rs +79 -0
- package/domainforge-core/src/primitives/mod.rs +25 -0
- package/domainforge-core/src/primitives/projection_contract.rs +50 -0
- package/domainforge-core/src/primitives/quantity.rs +56 -0
- package/domainforge-core/src/primitives/relation.rs +68 -0
- package/domainforge-core/src/primitives/resource.rs +237 -0
- package/domainforge-core/src/primitives/resource_instance.rs +88 -0
- package/domainforge-core/src/primitives/role.rs +49 -0
- package/domainforge-core/src/projection/buf.rs +404 -0
- package/domainforge-core/src/projection/contracts.rs +22 -0
- package/domainforge-core/src/projection/engine.rs +19 -0
- package/domainforge-core/src/projection/mod.rs +16 -0
- package/domainforge-core/src/projection/protobuf.rs +3331 -0
- package/domainforge-core/src/projection/registry.rs +43 -0
- package/domainforge-core/src/python/authority.rs +253 -0
- package/domainforge-core/src/python/error.rs +227 -0
- package/domainforge-core/src/python/formatter.rs +86 -0
- package/domainforge-core/src/python/graph.rs +366 -0
- package/domainforge-core/src/python/mod.rs +9 -0
- package/domainforge-core/src/python/policy.rs +651 -0
- package/domainforge-core/src/python/primitives.rs +796 -0
- package/domainforge-core/src/python/registry.rs +98 -0
- package/domainforge-core/src/python/semantic_pack.rs +619 -0
- package/domainforge-core/src/python/units.rs +96 -0
- package/domainforge-core/src/registry/mod.rs +432 -0
- package/domainforge-core/src/registry/tests.rs +210 -0
- package/domainforge-core/src/sbvr.rs +744 -0
- package/domainforge-core/src/semantic_pack/builder.rs +470 -0
- package/domainforge-core/src/semantic_pack/canonical_json.rs +184 -0
- package/domainforge-core/src/semantic_pack/diagnostics.rs +214 -0
- package/domainforge-core/src/semantic_pack/diff.rs +216 -0
- package/domainforge-core/src/semantic_pack/mod.rs +31 -0
- package/domainforge-core/src/semantic_pack/pack_set.rs +240 -0
- package/domainforge-core/src/semantic_pack/resolver.rs +437 -0
- package/domainforge-core/src/semantic_pack/review.rs +125 -0
- package/domainforge-core/src/semantic_pack/schema.rs +342 -0
- package/domainforge-core/src/semantic_pack/signing.rs +105 -0
- package/domainforge-core/src/semantic_pack/validator.rs +368 -0
- package/domainforge-core/src/semantic_version.rs +140 -0
- package/domainforge-core/src/test_utils.rs +12 -0
- package/domainforge-core/src/typescript/authority.rs +184 -0
- package/domainforge-core/src/typescript/error.rs +146 -0
- package/domainforge-core/src/typescript/formatter.rs +76 -0
- package/domainforge-core/src/typescript/graph.rs +391 -0
- package/domainforge-core/src/typescript/mod.rs +9 -0
- package/domainforge-core/src/typescript/policy.rs +564 -0
- package/domainforge-core/src/typescript/primitives.rs +784 -0
- package/domainforge-core/src/typescript/registry.rs +88 -0
- package/domainforge-core/src/typescript/semantic_pack.rs +470 -0
- package/domainforge-core/src/typescript/units.rs +76 -0
- package/domainforge-core/src/units/mod.rs +462 -0
- package/domainforge-core/src/uuid_module.rs +42 -0
- package/domainforge-core/src/validation_error.rs +818 -0
- package/domainforge-core/src/validation_result.rs +30 -0
- package/domainforge-core/src/wasm/authority.rs +192 -0
- package/domainforge-core/src/wasm/error.rs +145 -0
- package/domainforge-core/src/wasm/formatter.rs +69 -0
- package/domainforge-core/src/wasm/graph.rs +471 -0
- package/domainforge-core/src/wasm/mod.rs +16 -0
- package/domainforge-core/src/wasm/policy.rs +607 -0
- package/domainforge-core/src/wasm/primitives.rs +295 -0
- package/domainforge-core/src/wasm/semantic_pack.rs +471 -0
- package/domainforge-core/src/wasm/units.rs +62 -0
- package/domainforge-core/std/aws.sea +6 -0
- package/domainforge-core/std/core.sea +6 -0
- package/domainforge-core/std/http.sea +27 -0
- package/domainforge-core/tests/aggregation_enhanced_tests.rs +162 -0
- package/domainforge-core/tests/aggregation_eval_tests.rs +248 -0
- package/domainforge-core/tests/aggregation_integration_tests.rs +379 -0
- package/domainforge-core/tests/aggregation_parser_tests.rs +92 -0
- package/domainforge-core/tests/aggregation_tests.rs +102 -0
- package/domainforge-core/tests/authority_conformance_tests.rs +1173 -0
- package/domainforge-core/tests/calm_round_trip_tests.rs +283 -0
- package/domainforge-core/tests/calm_schema_validation_tests.rs +137 -0
- package/domainforge-core/tests/cast_operator_tests.rs +85 -0
- package/domainforge-core/tests/cli_binary_check.rs +37 -0
- package/domainforge-core/tests/cli_import_tests.rs +291 -0
- package/domainforge-core/tests/cli_path_traversal_tests.rs +124 -0
- package/domainforge-core/tests/cli_tests.rs +63 -0
- package/domainforge-core/tests/diagnostics_tests.rs +203 -0
- package/domainforge-core/tests/dimension_unit_tests.rs +80 -0
- package/domainforge-core/tests/entity_tests.rs +69 -0
- package/domainforge-core/tests/evolution_semantics_tests.rs +157 -0
- package/domainforge-core/tests/flow_tests.rs +78 -0
- package/domainforge-core/tests/flow_unit_validation_tests.rs +31 -0
- package/domainforge-core/tests/graph_integration_tests.rs +218 -0
- package/domainforge-core/tests/graph_tests.rs +626 -0
- package/domainforge-core/tests/import_parsing_tests.rs +23 -0
- package/domainforge-core/tests/instance_integration_tests.rs +98 -0
- package/domainforge-core/tests/instance_parsing_tests.rs +58 -0
- package/domainforge-core/tests/instance_tests.rs +61 -0
- package/domainforge-core/tests/kg_uri_encoding_tests.rs +53 -0
- package/domainforge-core/tests/lint_tests.rs +19 -0
- package/domainforge-core/tests/metric_tests.rs +143 -0
- package/domainforge-core/tests/module_resolution_tests.rs +100 -0
- package/domainforge-core/tests/namespace_registry_tests.rs +247 -0
- package/domainforge-core/tests/null_handling_tests.rs +26 -0
- package/domainforge-core/tests/parser_ast_v3.rs +53 -0
- package/domainforge-core/tests/parser_dimension_registry_tests.rs +20 -0
- package/domainforge-core/tests/parser_integration_tests.rs +294 -0
- package/domainforge-core/tests/parser_metadata_tests.rs +97 -0
- package/domainforge-core/tests/parser_resource_domain_only_graph_test.rs +21 -0
- package/domainforge-core/tests/parser_resource_limits_tests.rs +122 -0
- package/domainforge-core/tests/parser_tests.rs +512 -0
- package/domainforge-core/tests/pattern_semantics_tests.rs +87 -0
- package/domainforge-core/tests/phase_14_determinism_tests.rs +166 -0
- package/domainforge-core/tests/phase_15_validation_error_tests.rs +136 -0
- package/domainforge-core/tests/phase_16_unicode_tests.rs +248 -0
- package/domainforge-core/tests/phase_17_export_tests.rs +285 -0
- package/domainforge-core/tests/phase_17_round_trip_tests.rs +264 -0
- package/domainforge-core/tests/policy_tests.rs +635 -0
- package/domainforge-core/tests/primitives_integration_tests.rs +151 -0
- package/domainforge-core/tests/print_rdf_xml.rs +14 -0
- package/domainforge-core/tests/printer_tests.rs +204 -0
- package/domainforge-core/tests/profile_tests.rs +35 -0
- package/domainforge-core/tests/projection_contracts_tests.rs +154 -0
- package/domainforge-core/tests/protobuf_projection_tests.rs +199 -0
- package/domainforge-core/tests/quantity_tests.rs +41 -0
- package/domainforge-core/tests/rdf_xml_typed_literal_tests.rs +105 -0
- package/domainforge-core/tests/registry_schema_tests.rs +33 -0
- package/domainforge-core/tests/resource_tests.rs +50 -0
- package/domainforge-core/tests/resource_unit_tests.rs +24 -0
- package/domainforge-core/tests/roles_relations_tests.rs +61 -0
- package/domainforge-core/tests/round_trip_tests.rs +34 -0
- package/domainforge-core/tests/runtime_toggle_tests.rs +70 -0
- package/domainforge-core/tests/sbvr_fact_schema_tests.rs +60 -0
- package/domainforge-core/tests/sbvr_flow_facts_tests.rs +55 -0
- package/domainforge-core/tests/sbvr_parsing_tests.rs +53 -0
- package/domainforge-core/tests/semantic_pack_alias_resolution.rs +197 -0
- package/domainforge-core/tests/semantic_pack_build.rs +302 -0
- package/domainforge-core/tests/semantic_pack_consumer_smoke.rs +150 -0
- package/domainforge-core/tests/semantic_pack_pack_set.rs +160 -0
- package/domainforge-core/tests/semantic_pack_signing.rs +157 -0
- package/domainforge-core/tests/semantic_pack_three_valued.rs +250 -0
- package/domainforge-core/tests/semantic_pack_validate.rs +196 -0
- package/domainforge-core/tests/std_lib_tests.rs +37 -0
- package/domainforge-core/tests/temporal_evaluation_tests.rs +159 -0
- package/domainforge-core/tests/temporal_semantics_tests.rs +214 -0
- package/domainforge-core/tests/three_valued_quantifiers_tests.rs +164 -0
- package/domainforge-core/tests/turtle_entity_export_tests.rs +38 -0
- package/domainforge-core/tests/turtle_escaping_tests.rs +53 -0
- package/domainforge-core/tests/turtle_resource_export_tests.rs +34 -0
- package/domainforge-core/tests/type_inference_tests.rs +40 -0
- package/domainforge-core/tests/unicode_validation_tests.rs +169 -0
- package/domainforge-core/tests/unit_tests.rs +81 -0
- package/domainforge-core/tests/validate_tests.rs +38 -0
- package/domainforge-core/tests/validation_unit_mismatch_tests.rs +83 -0
- package/domainforge-core/tests/wasm_tests.rs +229 -0
- package/domainforge-python/CHANGELOG-python.md +12 -0
- package/domainforge-python/MIGRATING.md +24 -0
- package/domainforge-python/README.md +256 -0
- package/domainforge-python/domainforge/__init__.py +95 -0
- package/domainforge-python/domainforge/domainforge.pyi +519 -0
- package/domainforge-python/pyproject.toml +36 -0
- package/domainforge-typescript/CHANGELOG-typescript.md +12 -0
- package/domainforge-typescript/LICENSE +201 -0
- package/domainforge-typescript/MIGRATING.md +24 -0
- package/domainforge-typescript/README.md +305 -0
- package/domainforge-typescript/index.d.ts +452 -0
- package/domainforge-typescript/index.js +361 -0
- package/domainforge-typescript/package.json +60 -0
- package/example.js +61 -0
- package/examples/browser.html +366 -0
- package/examples/namespaces/finance/cashflow.sea +5 -0
- package/examples/namespaces/logistics/core.sea +7 -0
- package/examples/observability_metrics.sea +38 -0
- package/fixtures/semantic_packs/acme_procurement/domain/entities.sea +39 -0
- package/fixtures/semantic_packs/acme_procurement/domain/metrics.sea +11 -0
- package/fixtures/semantic_packs/acme_procurement/domain/relations.sea +7 -0
- package/fixtures/semantic_packs/acme_procurement/domain/resources.sea +9 -0
- package/fixtures/semantic_packs/acme_procurement/review/acme.procurement.semantic-review.jsonl +7 -0
- package/fixtures/semantic_packs/acme_procurement/tests/ambiguous_vendor_alias.sea +8 -0
- package/fixtures/semantic_packs/acme_procurement/tests/deprecated_vendor_alias.sea +8 -0
- package/fixtures/semantic_packs/acme_procurement/tests/invalid_relation.sea +3 -0
- package/fixtures/semantic_packs/acme_procurement/tests/proposed_concept.sea +8 -0
- package/fixtures/semantic_packs/acme_procurement/tests/rejected_concept.sea +8 -0
- package/fixtures/semantic_packs/acme_procurement/tests/unit_mismatch.sea +7 -0
- package/fixtures/semantic_packs/acme_procurement/tests/unknown_vendor_policy.sea +8 -0
- package/fixtures/semantic_packs/acme_procurement/tests/valid_purchase_policy.sea +8 -0
- package/index.d.ts +2 -0
- package/index.js +8 -0
- package/justfile +200 -0
- package/lefthook.yml +13 -0
- package/lib/validate_native_exports.d.ts +4 -0
- package/lib/validate_native_exports.js +12 -0
- package/package.json +22 -0
- package/pytest.ini +5 -0
- package/python/tests/test_registry.py +75 -0
- package/python/tests/test_units.py +18 -0
- package/release-please-config.json +49 -0
- package/requirements-dev.txt +3 -0
- package/requirements.txt +3 -0
- package/rust-toolchain.toml +3 -0
- package/schemas/ast-v1.schema.json +72 -0
- package/schemas/ast-v2.schema.json +1200 -0
- package/schemas/ast-v3.schema.json +1200 -0
- package/schemas/sea-registry.schema.json +45 -0
- package/scripts/build-python.sh +37 -0
- package/scripts/build-release.sh +279 -0
- package/scripts/build-typescript.sh +13 -0
- package/scripts/build-wasm.sh +113 -0
- package/scripts/bump-version.sh +245 -0
- package/scripts/check_unused_test_imports.py +85 -0
- package/scripts/ci_tasks.py +379 -0
- package/scripts/clear_debug_test.sh +10 -0
- package/scripts/create-github-release.sh +262 -0
- package/scripts/create-tag.sh +203 -0
- package/scripts/find_and_link_test_binary.sh +70 -0
- package/scripts/generate-changelog.sh +271 -0
- package/scripts/generate-release-notes.sh +205 -0
- package/scripts/lint_release_security.py +96 -0
- package/scripts/lint_release_workflows.py +82 -0
- package/scripts/lint_workflow_gates.py +113 -0
- package/scripts/optimized-wasm-build.sh +61 -0
- package/scripts/patch_napi_types.py +62 -0
- package/scripts/pre-release-check.sh +289 -0
- package/scripts/prepare_rust_debug.sh +52 -0
- package/scripts/release.sh +373 -0
- package/scripts/resolve_rust_binary.py +230 -0
- package/scripts/run_commitlint.sh +29 -0
- package/scripts/test-all.sh +77 -0
- package/scripts/update_launch_program.py +93 -0
- package/secrets/README.md +27 -0
- package/secrets/secrets.yaml +21 -0
- package/test_integration.py +67 -0
- package/tests/test_authority.py +328 -0
- package/tests/test_ci_tasks.py +143 -0
- package/tests/test_expression.py +256 -0
- package/tests/test_golden_payment_flow.py +42 -0
- package/tests/test_graph.py +127 -0
- package/tests/test_instance.py +136 -0
- package/tests/test_parser.py +82 -0
- package/tests/test_primitives.py +68 -0
- package/tests/test_role_relation_parity.py +56 -0
- package/tests/test_runtime_toggle.py +156 -0
- package/tests/test_semantic_pack.py +639 -0
- package/tests/test_three_valued_eval.py +159 -0
- package/tsconfig.json +30 -0
- package/typescript-tests/advanced.test.ts +165 -0
- package/typescript-tests/authority.test.ts +216 -0
- package/typescript-tests/expression.test.ts +228 -0
- package/typescript-tests/golden-payment-flow.test.ts +51 -0
- package/typescript-tests/graph.test.ts +142 -0
- package/typescript-tests/native-binding.test.ts +20 -0
- package/typescript-tests/primitives.test.ts +88 -0
- package/typescript-tests/registry.test.ts +122 -0
- package/typescript-tests/role_relation.test.ts +63 -0
- package/typescript-tests/runtime_toggle.test.ts +141 -0
- package/typescript-tests/semantic-pack.test.ts +556 -0
- package/typescript-tests/three_valued_eval.test.ts +135 -0
- package/typescript-tests/units.test.ts +36 -0
- package/vitest.config.ts +13 -0
- package/wasm_demo.html +225 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Versioning Strategy
|
|
2
|
+
|
|
3
|
+
DomainForge follows [Semantic Versioning 2.0.0](https://semver.org/).
|
|
4
|
+
|
|
5
|
+
## Version Format: `MAJOR.MINOR.PATCH`
|
|
6
|
+
|
|
7
|
+
- **MAJOR**: Incompatible API changes or breaking grammar changes.
|
|
8
|
+
- **MINOR**: Functionality added in a backward-compatible manner.
|
|
9
|
+
- **PATCH**: Backward-compatible bug fixes.
|
|
10
|
+
|
|
11
|
+
## What Constitutes a Breaking Change?
|
|
12
|
+
|
|
13
|
+
### 1. Grammar Changes
|
|
14
|
+
|
|
15
|
+
- **Breaking**: Removing a keyword, changing the syntax of an existing primitive, making an optional field mandatory.
|
|
16
|
+
- **Non-Breaking**: Adding a new primitive, adding an optional field, relaxing a constraint.
|
|
17
|
+
|
|
18
|
+
### 2. Core API (Rust)
|
|
19
|
+
|
|
20
|
+
- **Breaking**: Changing public struct fields, altering function signatures in `domainforge-core`.
|
|
21
|
+
- **Non-Breaking**: Adding new methods, internal performance improvements.
|
|
22
|
+
|
|
23
|
+
### 3. Bindings (Python/TS)
|
|
24
|
+
|
|
25
|
+
- **Breaking**: Renaming a class or method exposed to the host language.
|
|
26
|
+
- **Non-Breaking**: Exposing previously internal methods.
|
|
27
|
+
|
|
28
|
+
## Release Coordination
|
|
29
|
+
|
|
30
|
+
Because `domainforge-core` and the bindings are in the same repository (monorepo style), they share a version number.
|
|
31
|
+
|
|
32
|
+
- When `domainforge-core` bumps to `0.5.0`, the Python package `domainforge` and NPM package `domainforge` also bump to `0.5.0`.
|
|
33
|
+
|
|
34
|
+
## Deprecation Policy
|
|
35
|
+
|
|
36
|
+
Before removing a feature:
|
|
37
|
+
|
|
38
|
+
1. Mark it as deprecated in the documentation.
|
|
39
|
+
2. Add a warning log in the CLI/Parser when the feature is used.
|
|
40
|
+
3. Maintain support for at least one MINOR release cycle.
|
|
41
|
+
|
|
42
|
+
## See Also
|
|
43
|
+
|
|
44
|
+
- [Releasing Beta](../playbooks/releasing-beta.md)
|
|
45
|
+
- [Migrating Schema Versions](../playbooks/migrating-schema-versions.md)
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Repository Governance
|
|
2
|
+
|
|
3
|
+
Branch protection, deployment environments, and release routing for DomainForge.
|
|
4
|
+
|
|
5
|
+
## Branch Protection: `main`
|
|
6
|
+
|
|
7
|
+
`main` is the only protected branch. All changes must arrive via pull request.
|
|
8
|
+
|
|
9
|
+
| Rule | Setting |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Pull request required | Yes |
|
|
12
|
+
| Required approvals | 0 |
|
|
13
|
+
| Dismiss stale reviews | Yes |
|
|
14
|
+
| Require code owner reviews | No |
|
|
15
|
+
| Enforce for admins | Yes |
|
|
16
|
+
| Linear history | Required (squash-merge or rebase-merge; no merge commits) |
|
|
17
|
+
| Force pushes | Blocked |
|
|
18
|
+
| Branch deletions | Blocked |
|
|
19
|
+
| Branch must be up to date | Yes (`strict: true`) |
|
|
20
|
+
|
|
21
|
+
### Required status checks
|
|
22
|
+
|
|
23
|
+
A PR cannot merge until all of these pass. Approvals are not required because
|
|
24
|
+
this is currently a solo-maintainer repository; CI remains the merge gate.
|
|
25
|
+
|
|
26
|
+
| Check | Source workflow | Job |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `Lint & Format` | `ci.yml` | `lint` |
|
|
29
|
+
| `Test Rust (ubuntu-latest)` | `ci.yml` | `test-rust` matrix leg |
|
|
30
|
+
| `Test Rust (macos-latest)` | `ci.yml` | `test-rust` matrix leg |
|
|
31
|
+
| `Test Rust (windows-2025-vs2026)` | `ci.yml` | `test-rust` matrix leg |
|
|
32
|
+
| `Test Python (3.11)` | `ci.yml` | `test-python` matrix leg |
|
|
33
|
+
| `Test Python (3.12)` | `ci.yml` | `test-python` matrix leg |
|
|
34
|
+
| `Test TypeScript` | `ci.yml` | `test-typescript` |
|
|
35
|
+
| `Minimal Integration Check` | `ci.yml` | `test-integration` |
|
|
36
|
+
| `Test WASM` | `ci.yml` | `test-wasm` |
|
|
37
|
+
| `Security Audit` | `ci.yml` | `security` (`cargo audit`, blocking) |
|
|
38
|
+
| `dependency-review` | `dependency-review.yml` | `dependency-review` |
|
|
39
|
+
|
|
40
|
+
### What this means for contributors
|
|
41
|
+
|
|
42
|
+
- **No direct pushes to `main`.** Push to a feature branch and open a PR.
|
|
43
|
+
- **PR must be up to date** with `main` before merging. Rebase or merge `main` into your branch if CI fails on staleness.
|
|
44
|
+
- **Linear history required.** Use squash-merge or rebase-merge when merging PRs. Do not use create-merge-commit.
|
|
45
|
+
- **Admins are not exempt.** The `enforce_admins` flag is on.
|
|
46
|
+
|
|
47
|
+
## Environments
|
|
48
|
+
|
|
49
|
+
This repository does not use GitHub deployment environments. There is no
|
|
50
|
+
`stage` or `prod` environment gate.
|
|
51
|
+
|
|
52
|
+
Publishing is triggered directly by component tag pushes. The publish
|
|
53
|
+
workflows (`release-crates.yml`, `release-pypi.yml`, `release-npm.yml`)
|
|
54
|
+
handle their own idempotency:
|
|
55
|
+
- crates.io: detects "already published" from cargo output
|
|
56
|
+
- PyPI: `--skip-existing` flag on maturin
|
|
57
|
+
- npm: `npm view <pkg>@<version>` pre-check
|
|
58
|
+
|
|
59
|
+
This matches the solo-maintainer model: CI on `main` is the merge gate, and
|
|
60
|
+
a component tag push is the publish signal.
|
|
61
|
+
|
|
62
|
+
## Deploy Pipeline
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
tag push (domainforge-core-v*, domainforge-v*, domainforge-typescript-v*)
|
|
66
|
+
│
|
|
67
|
+
▼
|
|
68
|
+
deploy.yml (router)
|
|
69
|
+
├── identify (parse tag → component + version)
|
|
70
|
+
└── dispatch to publish workflow based on component:
|
|
71
|
+
├── domainforge-core → release-crates.yml (crates.io)
|
|
72
|
+
├── domainforge → release-pypi.yml (PyPI, multi-platform matrix)
|
|
73
|
+
└── domainforge-typescript → release-npm.yml (npm + WASM)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Tag shape: `<component>-v<version>` where component is one of `domainforge-core`, `domainforge`, `domainforge-typescript`.
|
|
77
|
+
|
|
78
|
+
`deploy.yml` does NOT contain build or publish logic itself. It dispatches to
|
|
79
|
+
the same reusable publish workflows that the legacy `release.yml` uses. This
|
|
80
|
+
avoids duplication and keeps a single source of truth for each registry's
|
|
81
|
+
publish process.
|
|
82
|
+
|
|
83
|
+
## Release Routing (release-please)
|
|
84
|
+
|
|
85
|
+
`release-please-config.json` and `.release-please-manifest.json` configure independent per-package versioning. Each package gets its own release PR and component-prefixed tag.
|
|
86
|
+
|
|
87
|
+
| Package | Component | Release type | Tag form |
|
|
88
|
+
|---|---|---|---|
|
|
89
|
+
| `domainforge-core` (Rust) | `domainforge-core` | rust | `domainforge-core-vX.Y.Z` |
|
|
90
|
+
| `domainforge` (Python) | `domainforge` | python | `domainforge-vX.Y.Z` |
|
|
91
|
+
| `@godspeedai/domainforge` (TypeScript) | `domainforge-typescript` | node | `domainforge-typescript-vX.Y.Z` |
|
|
92
|
+
|
|
93
|
+
### Release-please trigger
|
|
94
|
+
|
|
95
|
+
`.github/workflows/release-please.yml` triggers on `push: branches: [main]` and opens/updates release PRs for each configured package.
|
|
96
|
+
|
|
97
|
+
## Conventional Commits Enforcement
|
|
98
|
+
|
|
99
|
+
`commitlint` + `lefthook` enforce conventional commit format on every commit via a `commit-msg` hook.
|
|
100
|
+
|
|
101
|
+
- Config: `commitlint.config.cjs`
|
|
102
|
+
- Hook: `lefthook.yml` → `commit-msg` → `npx commitlint --edit {1}`
|
|
103
|
+
|
|
104
|
+
### Required format
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
<type>(<scope>): <subject>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- `type` must be a conventional type (`feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `build`, `ci`, `perf`, `revert`, etc.)
|
|
111
|
+
- `scope` is **required** and must be one of 29 allowed values (see `commitlint.config.cjs` for the full list)
|
|
112
|
+
- `subject` must be non-empty
|
|
113
|
+
|
|
114
|
+
### Allowed scopes
|
|
115
|
+
|
|
116
|
+
**Release-please components:** `domainforge-core`, `domainforge`, `domainforge-typescript`
|
|
117
|
+
|
|
118
|
+
**Meta:** `ci`, `deps`, `repo`
|
|
119
|
+
|
|
120
|
+
**Historical (from commit history):** `bindings`, `calm`, `cli`, `code`, `core`, `docs`, `format`, `grammar`, `graph`, `new_docs`, `parser`, `pkg`, `pyo3`, `policy`, `python`, `registry`, `release`, `semantic-pack`, `authority`, `test`, `tests`, `units`, `wasm`
|
|
121
|
+
|
|
122
|
+
**Note:** commitlint uses `scope-case: kebab-case` enforcement only (no static allowlist). The components above reflect the release-please package keys and historical usage.
|
|
123
|
+
|
|
124
|
+
### Bypass
|
|
125
|
+
|
|
126
|
+
The hook is local-only (lefthook installs to `.git/hooks/`). CI does not run commitlint. To bypass locally, use `git commit --no-verify` (discouraged).
|
|
127
|
+
|
|
128
|
+
## Package Layout
|
|
129
|
+
|
|
130
|
+
release-please v4 manifest mode resolves file paths as `<package-key>/<file>`.
|
|
131
|
+
Each package's version file must live in a directory matching its key:
|
|
132
|
+
|
|
133
|
+
| Package | Directory | Version file |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| `domainforge-core` | `domainforge-core/` | `Cargo.toml` |
|
|
136
|
+
| `domainforge` | `domainforge-python/` | `pyproject.toml` |
|
|
137
|
+
| `domainforge-typescript` | `domainforge-typescript/` | `package.json` |
|
|
138
|
+
|
|
139
|
+
The root `package.json` is a private workspace root for dev dependencies
|
|
140
|
+
(commitlint, lefthook, vitest). It is NOT published. The root `Cargo.toml`
|
|
141
|
+
defines the Rust workspace; `domainforge-core/Cargo.toml` is the sole published crate.
|
|
142
|
+
|
|
143
|
+
## Secrets
|
|
144
|
+
|
|
145
|
+
| Secret | Used by | Purpose |
|
|
146
|
+
|---|---|---|
|
|
147
|
+
| `GITHUB_TOKEN` | All workflows | Automatic GitHub API token (cannot trigger downstream workflows) |
|
|
148
|
+
| `CREATE_PR_TOKEN` | `release-please.yml`, `prepare-release.yml` | PAT for creating PRs and tags that trigger downstream workflows |
|
|
149
|
+
| `SOPS_AGE_KEY` | `release-pypi.yml`, `release-npm.yml`, `release-crates.yml` | Decrypts `secrets/secrets.yaml` via sops |
|
|
150
|
+
| `PYPI_API_TOKEN` | `release-pypi.yml` | PyPI publishing fallback (primary token is sops-decrypted) |
|
|
151
|
+
|
|
152
|
+
## Tool Versions
|
|
153
|
+
|
|
154
|
+
| Tool | Required version | Verification |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| `release-please-action` | `v4.4.1`, pinned in `.github/workflows/release-please.yml` by commit SHA | Inspect the workflow `uses:` line |
|
|
157
|
+
| `@commitlint/cli` | `^21.0.2`, installed from `package.json` | `npx commitlint --version` |
|
|
158
|
+
| `@commitlint/config-conventional` | `^21.0.2`, installed from `package.json` | `npm ls @commitlint/config-conventional` |
|
|
159
|
+
| `lefthook` | `^2.1.9`, installed from `package.json` | `npx lefthook version` |
|
|
160
|
+
|
|
161
|
+
Keep commitlint packages on the same major version. Lefthook v2 syntax is used
|
|
162
|
+
in `lefthook.yml`; do not downgrade to v1 without testing hook compatibility.
|
|
163
|
+
|
|
164
|
+
## See Also
|
|
165
|
+
|
|
166
|
+
- [Release Process](./RELEASE_PROCESS.md) — How to cut a release
|
|
167
|
+
- [Workflows](../.github/workflows/README.md) — CI/CD workflow documentation
|
|
168
|
+
- [Contributing](../CONTRIBUTING.md) — Developer setup and PR process
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# How-Tos — DomainForge
|
|
2
|
+
|
|
3
|
+
Purpose: Solve a single task quickly and efficiently with concise, practical instructions.
|
|
4
|
+
|
|
5
|
+
## MECE checklist for a How-To page
|
|
6
|
+
|
|
7
|
+
- Short summary of the outcome
|
|
8
|
+
- Required prerequisites (tools, permissions, environment)
|
|
9
|
+
- Step-by-step instructions
|
|
10
|
+
- Common pitfalls and troubleshooting
|
|
11
|
+
- Links to related Tutorials, Reference, and Playbooks
|
|
12
|
+
|
|
13
|
+
## Current Guides
|
|
14
|
+
|
|
15
|
+
### Setup & Installation
|
|
16
|
+
|
|
17
|
+
- [Install CLI](install-cli.md)
|
|
18
|
+
|
|
19
|
+
### Parsing & Validation
|
|
20
|
+
|
|
21
|
+
- [Parse SEA Files](parse-sea-files.md)
|
|
22
|
+
|
|
23
|
+
### Domain Modeling
|
|
24
|
+
|
|
25
|
+
- [Define Policies](define-policies.md)
|
|
26
|
+
- [Create Custom Units](create-custom-units.md)
|
|
27
|
+
- [Policy Evaluation Modes](policy-evaluation-modes.md)
|
|
28
|
+
- [Use Modules and Imports](use-modules-imports.md) ⭐ NEW
|
|
29
|
+
|
|
30
|
+
### Export & Projection
|
|
31
|
+
|
|
32
|
+
- [Export to CALM](export-to-calm.md)
|
|
33
|
+
- [Export to Protobuf](export-to-protobuf.md) ⭐ NEW
|
|
34
|
+
- [Generate RDF/Turtle](generate-rdf-turtle.md)
|
|
35
|
+
|
|
36
|
+
### Import
|
|
37
|
+
|
|
38
|
+
- [Import from CALM](import-from-calm.md)
|
|
39
|
+
- [Import from SBVR](import-from-sbvr.md) ⭐ NEW
|
|
40
|
+
|
|
41
|
+
### Development & CI
|
|
42
|
+
|
|
43
|
+
- [Run Cross-Language Tests](run-cross-language-tests.md)
|
|
44
|
+
- [CI/CD Validation](ci-cd-validation.md)
|
|
45
|
+
- [Troubleshoot NAPI Builds](troubleshoot-napi-builds.md)
|
|
46
|
+
- [Extend Grammar](extend-grammar.md)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Validate SEA Models in CI/CD
|
|
2
|
+
|
|
3
|
+
Goal: run `sea` validation in CI pipelines with machine-readable output and PR feedback.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Rust toolchain installed in the CI runner.
|
|
8
|
+
- Access to the repository containing `.sea` models (checked out in the workflow).
|
|
9
|
+
- Optional: Python/Node for post-processing JSON results.
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
1. **Install and build the CLI**
|
|
14
|
+
|
|
15
|
+
```yaml
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
|
18
|
+
- name: Build SEA CLI
|
|
19
|
+
run: |
|
|
20
|
+
cd domainforge-core
|
|
21
|
+
cargo build --release --bin domainforge --features cli
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
2. **Validate models with JSON output**
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
- name: Validate models
|
|
28
|
+
run: |
|
|
29
|
+
./target/release/domainforge validate --format json models/ > validation-results.json
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- Exit code is non-zero on failure; wrap with `|| true` if you want to parse the report first.
|
|
33
|
+
|
|
34
|
+
3. **Parse and fail the job on violations**
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
- name: Parse validation results
|
|
38
|
+
if: always()
|
|
39
|
+
run: |
|
|
40
|
+
python3 <<'PY'
|
|
41
|
+
import json, sys
|
|
42
|
+
results = json.load(open("validation-results.json"))
|
|
43
|
+
errors = results.get("error_count", 0)
|
|
44
|
+
if errors:
|
|
45
|
+
print(f"❌ Validation failed with {errors} errors")
|
|
46
|
+
for v in results.get("violations", []):
|
|
47
|
+
print(f"- [{v.get('severity','').upper()}] {v.get('policy_name')}: {v.get('message')}")
|
|
48
|
+
sys.exit(1)
|
|
49
|
+
print(f"✅ Validation passed ({len(results.get('violations', []))} checks)")
|
|
50
|
+
PY
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
4. **Optional: Comment on pull requests**
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
- name: Comment on PR
|
|
57
|
+
if: github.event_name == 'pull_request' && always()
|
|
58
|
+
uses: actions/github-script@v7
|
|
59
|
+
with:
|
|
60
|
+
script: |
|
|
61
|
+
const fs = require('fs');
|
|
62
|
+
const results = JSON.parse(fs.readFileSync('validation-results.json', 'utf8'));
|
|
63
|
+
let body = '## SEA DSL Validation Results\n\n';
|
|
64
|
+
if (results.error_count > 0) {
|
|
65
|
+
body += `❌ **${results.error_count} errors found**\n\n`;
|
|
66
|
+
body += '### Violations:\n';
|
|
67
|
+
results.violations.forEach(v => { body += `- **[${v.severity.toUpperCase()}]** ${v.policy_name}: ${v.message}\n`; });
|
|
68
|
+
} else {
|
|
69
|
+
body += `✅ **All validations passed** (${results.violations.length} checks)\n`;
|
|
70
|
+
}
|
|
71
|
+
github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body });
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
5. **Publish artifacts for debugging (optional)**
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
- uses: actions/upload-artifact@v4
|
|
78
|
+
if: always()
|
|
79
|
+
with:
|
|
80
|
+
name: sea-validation
|
|
81
|
+
path: validation-results.json
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Verification
|
|
85
|
+
|
|
86
|
+
- Workflow fails when `error_count > 0`.
|
|
87
|
+
- `validation-results.json` contains error codes, locations, and suggestions for CI parsing.
|
|
88
|
+
|
|
89
|
+
## See also
|
|
90
|
+
|
|
91
|
+
- [CLI Commands](../reference/cli-commands.md) (`validate`, `explain` flags)
|
|
92
|
+
- [Error Codes](../reference/error-codes.md) for interpreting violations
|
|
93
|
+
- [Configuration](../reference/configuration.md) for registry and logging options
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Create Custom Units
|
|
2
|
+
|
|
3
|
+
Goal: Define custom dimensions/units and validate quantities using them in SEA models.
|
|
4
|
+
|
|
5
|
+
- ## Prerequisites
|
|
6
|
+
|
|
7
|
+
- SEA CLI installed.
|
|
8
|
+
|
|
9
|
+
- For developers building from source: `cargo install --path domainforge-core --features cli` (produces the `sea` binary).
|
|
10
|
+
- Recommended: install the official GitHub Releases binary for your platform.
|
|
11
|
+
- Alternates: `cargo install domainforge-core` from crates.io when published, or use the packaged release/installer provided for your OS.
|
|
12
|
+
- Familiarity with resources and flows in the SEA DSL.
|
|
13
|
+
- Optional: Python/TypeScript bindings if you want to assert units programmatically.
|
|
14
|
+
|
|
15
|
+
## Steps (be concise)
|
|
16
|
+
|
|
17
|
+
1. **Declare dimensions and units in DSL**
|
|
18
|
+
|
|
19
|
+
```sea
|
|
20
|
+
Dimension "Currency"
|
|
21
|
+
Unit "USD" of "Currency" factor 1 base "USD"
|
|
22
|
+
Unit "EUR" of "Currency" factor 1.07 base "USD"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- `factor` sets the multiplier relative to the base unit.
|
|
26
|
+
- Always include `base` to avoid ambiguous conversions.
|
|
27
|
+
|
|
28
|
+
2. **Attach units to resources and flows**
|
|
29
|
+
|
|
30
|
+
```sea
|
|
31
|
+
Resource "Money" USD
|
|
32
|
+
Entity "Alice"
|
|
33
|
+
Entity "Bob"
|
|
34
|
+
Flow "Money" from "Alice" to "Bob" quantity 100
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- Resources reference the canonical unit.
|
|
38
|
+
- Flows inherit the resource unit unless explicitly overridden.
|
|
39
|
+
|
|
40
|
+
3. **Convert units in policies or aggregations**
|
|
41
|
+
|
|
42
|
+
```sea
|
|
43
|
+
Policy euro_cap as:
|
|
44
|
+
forall f in flows: (f.resource = "Money" and f.quantity <= 10000)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- Keep comparisons in the resource's canonical unit to avoid ambiguous conversions.
|
|
48
|
+
|
|
49
|
+
4. **Create the example file and validate with the CLI**
|
|
50
|
+
|
|
51
|
+
Create `examples/custom_units.sea` (this file contains the model used by the following examples):
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
mkdir -p examples
|
|
55
|
+
cat > examples/custom_units.sea <<'SEA'
|
|
56
|
+
Dimension "Currency"
|
|
57
|
+
Unit "USD" of "Currency" factor 1 base "USD"
|
|
58
|
+
Unit "EUR" of "Currency" factor 1.07 base "USD"
|
|
59
|
+
|
|
60
|
+
Resource "Money" USD
|
|
61
|
+
Entity "Alice"
|
|
62
|
+
Entity "Bob"
|
|
63
|
+
Flow "Money" from "Alice" to "Bob" quantity 100
|
|
64
|
+
SEA
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Now validate the file with the CLI:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
domainforge validate --format human examples/custom_units.sea
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This validation will fail if a unit or dimension is missing, duplicated, or forms a circular base chain.
|
|
74
|
+
|
|
75
|
+
5. **Inspect units in Python (re-using examples/custom_units.sea)**
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from domainforge import Graph
|
|
79
|
+
|
|
80
|
+
with open("examples/custom_units.sea") as f:
|
|
81
|
+
graph = Graph.parse(f.read())
|
|
82
|
+
resource = graph.all_resources()[0]
|
|
83
|
+
assert resource.unit == "USD"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
6. **Inspect units in TypeScript (re-using examples/custom_units.sea)**
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { Graph } from "@godspeedai/domainforge";
|
|
90
|
+
import { readFileSync } from "fs";
|
|
91
|
+
|
|
92
|
+
const graph = Graph.parse(readFileSync("examples/custom_units.sea", "utf8"));
|
|
93
|
+
console.log(graph.allResources()[0].unit);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Edge Cases
|
|
97
|
+
|
|
98
|
+
- **Circular bases**: Avoid `USD` base `EUR` and `EUR` base `USD`; validation will fail with a descriptive error.
|
|
99
|
+
- **Precision**: Use decimal notation (`1.07`) to prevent rounding surprises; avoid locale-specific commas.
|
|
100
|
+
- **Namespace scoping**: Declare dimensions/units in the same namespace as consuming resources to prevent lookup failures.
|
|
101
|
+
- **Unit reuse**: Reusing unit names across dimensions is not allowed; pick unique names or namespace them explicitly.
|
|
102
|
+
|
|
103
|
+
## Testing and Validation Tips
|
|
104
|
+
|
|
105
|
+
- Add a small regression test under `tests/` that parses the DSL and asserts `graph.all_resources()[0].unit`.
|
|
106
|
+
- When exporting to CALM, confirm that quantities carry the correct `unit` field; run `jq '.models[0].flows[0].quantity' file.calm.json`.
|
|
107
|
+
- Use `domainforge project --format kg` and inspect the Turtle output to ensure unit annotations appear in the KG representation.
|
|
108
|
+
|
|
109
|
+
## Troubleshooting
|
|
110
|
+
|
|
111
|
+
- **Unknown unit error**: Define the unit before referencing it in resources/flows.
|
|
112
|
+
- **Factor mismatch**: Ensure factors are numeric; strings or missing values cause parse failures.
|
|
113
|
+
- **Conversion failures**: If policy evaluation fails due to missing conversion paths, verify the base chain is fully connected.
|
|
114
|
+
|
|
115
|
+
## Verification Checklist
|
|
116
|
+
|
|
117
|
+
- [ ] Dimension and unit declarations parse without errors.
|
|
118
|
+
- [ ] Resources reference valid units and flows inherit them correctly.
|
|
119
|
+
- [ ] Policy comparisons use consistent units (or canonical units) to avoid mismatches.
|
|
120
|
+
- [ ] CALM/KG exports include the units and survive round-trip import.
|
|
121
|
+
|
|
122
|
+
## Links
|
|
123
|
+
|
|
124
|
+
- Tutorials: [First SEA Model](../tutorials/first-sea-model.md)
|
|
125
|
+
- Reference: [Grammar Spec](../reference/grammar-spec.md), [Primitives API](../reference/primitives-api.md)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Define Policies
|
|
2
|
+
|
|
3
|
+
Goal: Author policies in SEA DSL and verify they evaluate correctly across CLI and bindings.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- SEA CLI installed with `cli` feature.
|
|
8
|
+
- A validated model that includes entities/resources/flows referenced by the policy.
|
|
9
|
+
- Optional bindings (Python/TypeScript) for programmatic evaluation.
|
|
10
|
+
|
|
11
|
+
## Steps (be concise)
|
|
12
|
+
|
|
13
|
+
1. **Write a policy in DSL**
|
|
14
|
+
|
|
15
|
+
```sea
|
|
16
|
+
Policy payment_threshold as:
|
|
17
|
+
forall f in flows: (f.resource = "Money" and f.quantity <= 10000 "USD")
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
- Use comprehensions (`forall`, `exists`) and comparisons (`=`, `<=`, `matches`).
|
|
21
|
+
- Qualify names with namespaces when needed (`finance/Money`).
|
|
22
|
+
|
|
23
|
+
2. **Attach predicates to roles or relations**
|
|
24
|
+
|
|
25
|
+
```sea
|
|
26
|
+
Role "Payer"
|
|
27
|
+
Role "Payee"
|
|
28
|
+
Relation "Payment"
|
|
29
|
+
subject: "Payer"
|
|
30
|
+
predicate: "pays"
|
|
31
|
+
object: "Payee"
|
|
32
|
+
via: flow "Money"
|
|
33
|
+
|
|
34
|
+
Policy payer_must_exist as:
|
|
35
|
+
forall r in relations: (r.name = "Payment" and r.subject = "Payer")
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
3. **Validate the policy with the CLI**
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
domainforge validate --format human examples/policies.sea
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
- Reports semantic errors (unknown identifiers, unit mismatches) with line/column.
|
|
45
|
+
- Use `--format json` for machine-readable diagnostics.
|
|
46
|
+
|
|
47
|
+
4. **Evaluate a policy in Python**
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from domainforge import Graph
|
|
51
|
+
from pathlib import Path
|
|
52
|
+
|
|
53
|
+
graph = Graph.parse(Path("examples/policies.sea").read_text())
|
|
54
|
+
# `policy.json` must be the JSON representation of the Policy object (crate::policy::Policy).
|
|
55
|
+
# You can create this file by authoring JSON manually or by exporting a policy from an authoring tool.
|
|
56
|
+
# Example quick generation:
|
|
57
|
+
# echo '{"id":"policy-uuid","name":"Limit","expression":"forall f in flows: f.quantity <= 1000"}' > policy.json
|
|
58
|
+
policy_json = Path("policy.json").read_text()
|
|
59
|
+
result = graph.evaluate_policy(policy_json)
|
|
60
|
+
print(result.violations)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- Enable three-valued logic for partial data: `graph.set_evaluation_mode(True)`.
|
|
64
|
+
|
|
65
|
+
5. **Evaluate a policy in TypeScript**
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { Graph } from "@godspeedai/domainforge";
|
|
69
|
+
import { readFileSync } from "fs";
|
|
70
|
+
|
|
71
|
+
const graph = Graph.parse(readFileSync("examples/policies.sea", "utf8"));
|
|
72
|
+
// `policy.json` is a JSON payload matching crate::policy::Policy (id, name, expression, modality)
|
|
73
|
+
// Create with an authoring tool or echo the JSON as a quick example
|
|
74
|
+
// echo '{"id":"policy-uuid","name":"Limit","expression":"forall f in flows: f.quantity <= 1000"}' > policy.json
|
|
75
|
+
const policyJson = readFileSync("policy.json", "utf8");
|
|
76
|
+
const outcome = graph.evaluatePolicy(policyJson);
|
|
77
|
+
console.log(outcome.violations);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
6. **Test policies as part of CI**
|
|
81
|
+
|
|
82
|
+
- Add a Rust test under `domainforge-core/tests/` that parses the DSL and calls `graph.evaluate_policy` on representative inputs.
|
|
83
|
+
- Mirror the test in Python/TypeScript to maintain parity. Use the same DSL snippet to avoid drift.
|
|
84
|
+
- Run `just all-tests` before merging changes.
|
|
85
|
+
|
|
86
|
+
## Expression Basics
|
|
87
|
+
|
|
88
|
+
- **Boolean logic**: `and`, `or`, `not` with standard precedence; wrap complex conditions in parentheses.
|
|
89
|
+
- **Comparisons**: `=`, `!=`, `<`, `<=`, `>`, `>=`, `matches` (regex-like), `contains`, `startswith`, `endswith`.
|
|
90
|
+
- **Quantifiers**: `forall <var> in <collection>: (<predicate>)` and `exists <var> in <collection>: (<predicate>)`.
|
|
91
|
+
- **Three-valued logic**: `Unknown` propagates when operands lack data; enable it when modeling incomplete datasets.
|
|
92
|
+
|
|
93
|
+
## Best Practices
|
|
94
|
+
|
|
95
|
+
- Keep policies near the DSL constructs they reference or register them via `.sea-registry.toml` so namespace resolution works.
|
|
96
|
+
- Normalize units before comparison. Prefer quantity literals (e.g., `100 "USD"`) and numeric + quoted unit for annotations (e.g., `@refresh_interval 60 "seconds"`).
|
|
97
|
+
- Use `as "<Unit>"` only where the grammar explicitly supports it — for example as a coercion suffix in an aggregation comprehension (`sum(f in flows: f.quantity as "USD")`).
|
|
98
|
+
- Note: Some examples use the `as "<Unit>"` form where the grammar allows it (e.g., aggregation coercion) to make conversions explicit. Annotation durations and quantity literals follow the canonical forms shown above.
|
|
99
|
+
- Avoid side effects; policies should be deterministic for reproducible validation.
|
|
100
|
+
- Document intent with comments; the parser ignores lines starting with `#`.
|
|
101
|
+
|
|
102
|
+
## Troubleshooting
|
|
103
|
+
|
|
104
|
+
- **Unknown identifier**: Ensure entities/resources/roles exist and are in scope; namespaces must match.
|
|
105
|
+
- **Unit mismatch**: Define units and dimensions before using them in policies.
|
|
106
|
+
- **Empty collections**: If `flows` or `relations` are empty, quantifiers may vacuously pass; add explicit existence checks when necessary.
|
|
107
|
+
- **Evaluation differences across bindings**: Rebuild bindings (`maturin develop`, `npm run build`) after changing policy evaluation logic in Rust.
|
|
108
|
+
|
|
109
|
+
## Verification Checklist
|
|
110
|
+
|
|
111
|
+
- [ ] `domainforge validate` passes for the policy file.
|
|
112
|
+
- [ ] Policy evaluates consistently in Rust, Python, and TypeScript for the same input.
|
|
113
|
+
- [ ] Unit conversions behave as expected where used.
|
|
114
|
+
- [ ] Documentation and examples updated when adding new operators or predicates.
|
|
115
|
+
|
|
116
|
+
## Links
|
|
117
|
+
|
|
118
|
+
- Tutorials: [Getting Started](../tutorials/getting-started.md)
|
|
119
|
+
- Reference: [Grammar Spec](../reference/grammar-spec.md), [Policy Evaluation Logic](../explanations/policy-evaluation-logic.md), [Three-Valued Logic](../explanations/three-valued-logic.md)
|