Emit direct JS WAM ops and cheap ITE for mixed-mode helpers. #15085
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: UnifyWeaver Tests | |
| # Run on every push and pull request | |
| # Does NOT block pushes - just provides feedback | |
| on: | |
| push: | |
| branches: ['**'] # All branches | |
| pull_request: | |
| branches: ['**'] | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install SWI-Prolog | |
| run: bash scripts/ci/install_swi_prolog.sh | |
| - name: Verify SWI-Prolog installation | |
| run: swipl --version | |
| - name: Create output directories | |
| run: | | |
| mkdir -p output | |
| mkdir -p output/advanced | |
| - name: Run constraint analyzer tests | |
| run: | | |
| swipl -g "use_module('src/unifyweaver/core/constraint_analyzer'), test_constraint_analyzer, halt." | |
| - name: Run stream compiler tests | |
| run: | | |
| swipl -g "asserta(user:file_search_path(library, 'src/unifyweaver/core')), use_module('src/unifyweaver/core/stream_compiler'), test_stream_compiler, halt." | |
| - name: Run recursive compiler tests | |
| run: | | |
| swipl -g "asserta(user:file_search_path(library, 'src/unifyweaver/core')), use_module('src/unifyweaver/core/recursive_compiler'), test_recursive_compiler, halt." | |
| - name: Run ClojureScript target tests (codegen) | |
| run: | | |
| swipl -q -g "consult('tests/core/test_clojurescript_target'), (test_clojurescript_target -> halt(0) ; halt(1))" -t "halt(1)" | |
| - name: Run ClojureScript recursive-compiler tests (codegen) | |
| run: | | |
| swipl -q -g "consult('tests/core/test_clojurescript_recursive'), (test_clojurescript_recursive -> halt(0) ; halt(1))" -t "halt(1)" | |
| - name: Install nbb (Node ClojureScript runtime for CLJS smoke) | |
| run: npm install nbb | |
| - name: Run ClojureScript runtime smoke tests (nbb) | |
| run: | | |
| NBB="$PWD/node_modules/.bin/nbb" swipl -q -g "consult('tests/core/test_clojurescript_runtime_smoke'), (test_clojurescript_runtime_smoke -> halt(0) ; halt(1))" -t "halt(1)" | |
| - name: Run advanced recursion tests (24 tests) | |
| run: | | |
| swipl -g "use_module('src/unifyweaver/core/advanced/test_advanced'), test_all_advanced, halt." | |
| - name: Run constraint integration tests | |
| run: | | |
| swipl -g "use_module('src/unifyweaver/core/test_constraints'), test_constraints, halt." | |
| - name: Run control plane tests | |
| run: | | |
| swipl -g "asserta(user:file_search_path(library, 'src/unifyweaver/core')), asserta(user:file_search_path(library, 'tests/core')), use_module(library(test_policy)), test_policy, halt." | |
| - name: Run root-metric directive tests | |
| run: | | |
| swipl -q -g run_tests -t halt tests/core/test_root_metric.pl | |
| # Every goal below is invoked explicitly as -g: a swipl load-time | |
| # initialization error does NOT set the exit status, so relying on | |
| # the mirror's load-time check alone would let a stale mirror pass | |
| # CI (PR #4095, report finding 4). The mirror-verify goal makes a | |
| # PR that changes process_cards.py's registry fail here until the | |
| # mirror is regenerated. | |
| - name: Run pattern_stache suites and registry-mirror drift check | |
| run: | | |
| swipl -g "use_module('prototypes/mu_cosine/pattern_stache/pe_registry_mirror'), pe_registry_mirror:pe_mirror_verify" -t halt | |
| swipl -q -g run_tests -t halt tests/core/test_pattern_stache.pl | |
| swipl -q -g run_tests -t halt tests/core/test_pattern_stache_whitespace.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/test_pattern_stache.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/test_constraint_dispatch.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/test_pe_number.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/test_pe_interpret.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/test_pe_emit.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/test_pe_where.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/test_pe_elaborate.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/test_error_fixtures.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/test_mode_classification.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/test_pe_canonical.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/test_pstate_views.pl | |
| swipl -q -g run_tests -t halt prototypes/mu_cosine/pattern_stache/probe_residual_order.pl | |
| - name: Verify pattern_stache tutorial outputs | |
| run: python3 docs/tutorials/check_tutorial.py docs/tutorials/TUTORIAL_pattern_stache.md | |
| - name: Run C# query target tests (codegen only) | |
| run: | | |
| SKIP_CSHARP_EXECUTION=1 swipl -q -f init.pl -s tests/core/test_csharp_query_target.pl -g "test_csharp_query_target:test_csharp_query_target" -t halt | |
| - name: Run C# query calibration wrapper contract tests | |
| run: | | |
| python3 -m unittest tests/test_csharp_query_source_mode_policy.py | |
| python3 -m unittest tests/test_csharp_query_calibration_refresh_wrapper.py | |
| python3 examples/benchmark/refresh_csharp_query_source_mode_calibration.py --dry-run | |
| python3 -m unittest tests/test_csharp_query_scan_calibration_refresh_wrapper.py | |
| python3 examples/benchmark/refresh_csharp_query_scan_source_mode_calibration.py --dry-run | |
| python3 -m unittest tests/test_csharp_query_calibration_ci_contract.py | |
| python3 -m unittest tests/test_csharp_query_policy_report_ci_contract.py | |
| python3 -m unittest tests/test_csharp_query_policy_review_wrapper.py | |
| python3 examples/benchmark/review_csharp_query_effective_distance_policy.py --dry-run | |
| - name: Set up .NET (for F# WAM target tests) | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '8.0.x' | |
| - name: Install Python test dependencies (LMDB + grounded graph diffusion) | |
| run: python3 -m pip install --user lmdb "numpy>=1.24" pytest | |
| - name: Run grounded semantic diffusion tests | |
| run: | | |
| python3 -m pytest -q tests/test_leaky_diffusion.py \ | |
| tests/test_local_grounded_diffusion.py | |
| python3 prototypes/mu_cosine/benchmark_local_grounded_diffusion.py --smoke | |
| - name: Run filing path decoder Stage A tests | |
| # Stage A is provenance/schema logic over a routed-task.v2 parent: it | |
| # needs only numpy (via routed_policy) and pytest, no embedder, no | |
| # corpus. The other mu_cosine suites import the filing/embedding stack | |
| # and stay out of CI for that reason. | |
| run: | | |
| python3 -m pytest -q prototypes/mu_cosine/test_filing_path_decision.py | |
| - name: Run process-expression contract fixture tests | |
| # Identity helpers plus the frozen AST/token/role-path golden vectors. | |
| # The modules under test import only process_cards; the suite also | |
| # imports process_expression_p1_protocol in one test, to prove the | |
| # digest matches the frozen P1 convention, which pulls numpy via | |
| # routed_policy. numpy is installed above. No embedder, torch, or | |
| # corpus either way. | |
| run: | | |
| python3 -m pytest -q prototypes/mu_cosine/test_process_expression_contract.py \ | |
| prototypes/mu_cosine/test_process_expression_envelope.py \ | |
| prototypes/mu_cosine/test_process_cards.py \ | |
| prototypes/mu_cosine/test_process_expression_p1_protocol.py \ | |
| prototypes/mu_cosine/test_process_expression_vnext_frontend.py \ | |
| prototypes/mu_cosine/test_process_expression_vnext_patterns.py \ | |
| prototypes/mu_cosine/test_process_expression_tokenizer.py \ | |
| prototypes/mu_cosine/test_registry_v04_obligations.py \ | |
| prototypes/mu_cosine/test_registry_v04_migration.py \ | |
| prototypes/mu_cosine/test_registry_v04_stage5.py \ | |
| prototypes/mu_cosine/test_process_expression_enumerator.py \ | |
| prototypes/mu_cosine/test_process_expression_split.py \ | |
| prototypes/mu_cosine/test_registry_v05_migration.py | |
| - name: Run F# WAM target tests (codegen + dotnet smoke + LMDB conformance) | |
| env: | |
| DOTNET_CLI_TELEMETRY_OPTOUT: '1' | |
| DOTNET_NOLOGO: '1' | |
| # Belt-and-suspenders: the generated fsproj targets net8.0 and | |
| # setup-dotnet installs the matching runtime, but Major roll-forward | |
| # keeps the dotnet legs launchable if the runner's SDK ever drifts. | |
| DOTNET_ROLL_FORWARD: 'Major' | |
| run: | | |
| swipl -q -g main -t halt tests/run_wam_fsharp_tests.pl | |
| - name: Run root-metric prototype tests (scoping + node-DP + query) | |
| # One step on purpose: these four modules build tiny hand-checked LMDB | |
| # fixtures (diamond/tree DAGs) and finish in ~1.7s total, each skipping | |
| # when python-lmdb is absent. Folded into a single unittest invocation | |
| # to avoid per-step runner overhead. The materialisers under test live | |
| # in benchmarks/root-metrics/prototype/ (hand-coded pending generation | |
| # from the root_metric/2 directive); see that dir's README. | |
| run: | | |
| python3 -m unittest \ | |
| tests.test_build_scoped_subtree_lmdb \ | |
| tests.test_query_root_metric \ | |
| tests.test_effective_distance_nodedp \ | |
| tests.test_max_distance_nodedp | |
| - name: Run root-metric query tool test | |
| run: | | |
| python3 -m unittest tests.test_query_root_metric | |
| - name: Run effective-distance node-DP test | |
| run: | | |
| python3 -m unittest tests.test_effective_distance_nodedp | |
| - name: Run WAM Rust matrix-bench demand-flag codegen test | |
| run: | | |
| python3 -m unittest tests.test_wam_rust_matrix_demand_flag | |
| - name: Generate and run inference test runner | |
| run: | | |
| swipl -g "use_module('src/unifyweaver/core/advanced/test_runner_inference'), generate_test_runner_inferred('output/advanced/inferred_test_runner.sh'), halt." | |
| chmod +x output/advanced/inferred_test_runner.sh | |
| cd output/advanced && bash inferred_test_runner.sh | |
| - name: Validate generated bash scripts (syntax check) | |
| run: | | |
| for script in output/advanced/*.sh; do | |
| if [ -f "$script" ]; then | |
| echo "Checking syntax: $script" | |
| bash -n "$script" || exit 1 | |
| fi | |
| done | |
| - name: Run visualization glue tests (478 tests) | |
| run: | | |
| swipl -g "consult('tests/integration/glue/test_visualization_glue.pl'), run_tests, halt(0)" -t "halt(1)" | |
| - name: Test summary | |
| if: always() | |
| run: | | |
| echo "==========================================" | |
| echo "UnifyWeaver Test Suite Complete" | |
| echo "==========================================" | |
| echo "✓ Constraint analyzer tests" | |
| echo "✓ Stream compiler tests" | |
| echo "✓ Recursive compiler tests" | |
| echo "✓ Advanced recursion tests (24/24)" | |
| echo "✓ Constraint integration tests" | |
| echo "✓ Control plane tests (5/5)" | |
| echo "✓ F# WAM target tests (codegen + dotnet smoke + LMDB conformance)" | |
| echo "✓ Inference test runner generation" | |
| echo "✓ Generated bash script validation" | |
| echo "✓ Visualization glue tests (478 tests)" | |
| echo "==========================================" | |
| wam_conformance_smoke: | |
| name: WAM Conformance Smoke (${{ matrix.target }}) | |
| if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: [scala, elixir, wat, haskell, python, go, rust, c, cpp] | |
| env: | |
| CONFORMANCE_TARGETS: ${{ matrix.target }} | |
| CONFORMANCE_PROGRAMS: member,builtins | |
| CONFORMANCE_SAMPLE: 2 | |
| CONFORMANCE_SEED: ${{ github.run_number }} | |
| UW_SMOKE_TMPDIR: /tmp/unifyweaver-smoke | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install SWI-Prolog | |
| run: bash scripts/ci/install_swi_prolog.sh | |
| - name: Create smoke temp root | |
| run: mkdir -p "$UW_SMOKE_TMPDIR" | |
| - name: Run sampled WAM conformance | |
| run: | | |
| swipl -q -f init.pl -s tests/test_wam_cross_target_conformance.pl -g "seed_sampler,run_tests" -t halt | |
| wam_r_conformance: | |
| name: WAM R Conformance (interpreter + functions) | |
| if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| env: | |
| CONFORMANCE_TARGETS: r,r_functions | |
| CONFORMANCE_PROGRAMS: member,fib,ack,append,reverse,builtins | |
| UW_SMOKE_TMPDIR: /tmp/unifyweaver-smoke | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install SWI-Prolog | |
| run: bash scripts/ci/install_swi_prolog.sh | |
| - name: Install R | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends r-base-core | |
| - name: Create smoke temp root | |
| run: mkdir -p "$UW_SMOKE_TMPDIR" | |
| - name: Run R focused regressions (switch-index + LMDB) | |
| run: | | |
| swipl -q -f init.pl -s tests/test_wam_r_generator.pl -g "run_tests([wam_r_generator:switch_on_constant_fallthrough_is_linear_noop,wam_r_generator:switch_on_term_a2_is_switch_on_term_noop,wam_r_generator:switch_on_constant_fallthrough_preserves_backtracking,wam_r_generator:r_a2_switch_hints_are_linear_noop,wam_r_generator:r_a2_fallthrough_preserves_backtracking,wam_r_generator:lmdb_r0_source_dispatch_selection,wam_r_generator:lmdb_arg1_v1_mock_adapter_lookup_and_stream,wam_r_generator:lmdb_arg1_v1_real_binding_e2e_rscript,wam_r_generator:lmdb_r1_materialisation_codegen,wam_r_generator:lmdb_r1_eager_lazy_runtime_parity,wam_r_generator:lmdb_r2a_cached_codegen,wam_r_generator:lmdb_r2a_cached_runtime,wam_r_generator:lmdb_r2b_auto_materialisation_codegen])" -t halt | |
| - name: Run R ISO-R-0 unit + smoke | |
| run: | | |
| swipl -q -f init.pl -s tests/test_wam_r_iso_unit.pl -g "run_tests, halt" -t "halt(1)" | |
| swipl -q -f init.pl -s tests/test_wam_r_iso_smoke.pl -g main -t halt | |
| - name: Run R effective-distance generator + runtime smoke | |
| run: | | |
| swipl -q -f init.pl -s tests/test_wam_r_effective_distance_generator.pl -g "run_tests, halt" -t "halt(1)" | |
| - name: Run R aggregate lowering contract suite | |
| run: | | |
| swipl -q -f init.pl -s tests/test_wam_r_aggregate_lower.pl -g "run_tests, halt" -t "halt(1)" | |
| - name: Run R bulk-reduce plan contract suite | |
| run: | | |
| swipl -q -f init.pl -s tests/test_wam_r_bulk_reduce_plan.pl -g "run_tests, halt" -t "halt(1)" | |
| - name: Run R direct arg1 lookup contract suite | |
| run: | | |
| swipl -q -f init.pl -s tests/test_wam_r_ca_direct_lookup.pl -g "run_tests, halt" -t "halt(1)" | |
| - name: Run R native CA hop kernel contract suite | |
| run: | | |
| swipl -q -f init.pl -s tests/test_wam_r_native_hops.pl -g "run_tests, halt" -t "halt(1)" | |
| - name: Run full R classic conformance | |
| run: | | |
| swipl -q -f init.pl -s tests/test_wam_cross_target_conformance.pl -g "run_tests" -t halt | |
| csharp_query_runtime_smoke: | |
| name: C# Query Runtime Smoke | |
| if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| env: | |
| CSHARP_QUERY_SMOKE_OUTPUT_DIR: tmp/csharp_query_smoke_ci | |
| CSHARP_QUERY_SMOKE_SUMMARY_PATH: tmp/csharp_query_smoke_ci/cache_smoke_sequence_summary.md | |
| CSHARP_QUERY_SMOKE_JSON_SUMMARY_PATH: tmp/csharp_query_smoke_ci/cache_smoke_sequence_summary.json | |
| CSHARP_QUERY_SMOKE_FAILURE_ARTIFACT_NAME: csharp-query-smoke-artifacts | |
| CSHARP_QUERY_SMOKE_JSON_ARTIFACT_NAME: csharp-query-smoke-summary-json | |
| # Pin the Prolog harness's TargetFramework probe to the SDK installed | |
| # by the setup-dotnet step below, so generated .csproj's land their | |
| # build output in a predictable bin/Debug/<framework>/ directory. | |
| # The PS smoke runner now discovers the framework dir at runtime | |
| # too, but pinning makes it deterministic regardless of which | |
| # SDKs the runner has pre-installed. | |
| UNIFYWEAVER_DOTNET_FRAMEWORK: net9.0 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install SWI-Prolog | |
| run: bash scripts/ci/install_swi_prolog.sh | |
| - name: Install .NET SDK | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '9.0.x' | |
| - name: Verify toolchain | |
| run: | | |
| swipl --version | |
| dotnet --version | |
| pwsh -v | |
| - name: Run C# query cache smoke sequence | |
| run: | | |
| pwsh -NoProfile -File scripts/testing/run_csharp_query_cache_smoke_sequence.ps1 -OutputDir "$CSHARP_QUERY_SMOKE_OUTPUT_DIR" -SummaryPath "$CSHARP_QUERY_SMOKE_SUMMARY_PATH" | |
| - name: Upload C# query smoke artifacts on failure | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.CSHARP_QUERY_SMOKE_FAILURE_ARTIFACT_NAME }} | |
| path: ${{ env.CSHARP_QUERY_SMOKE_OUTPUT_DIR }} | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| - name: Upload C# query smoke JSON summary | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.CSHARP_QUERY_SMOKE_JSON_ARTIFACT_NAME }} | |
| path: ${{ env.CSHARP_QUERY_SMOKE_JSON_SUMMARY_PATH }} | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| - name: Summarize C# query cache smoke slices | |
| if: always() | |
| shell: pwsh | |
| run: | | |
| if (Test-Path $env:CSHARP_QUERY_SMOKE_SUMMARY_PATH) { | |
| Get-Content $env:CSHARP_QUERY_SMOKE_SUMMARY_PATH | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append | |
| } else { | |
| @( | |
| "## C# Query Runtime Smoke", | |
| "", | |
| "- Summary file not found at `"$($env:CSHARP_QUERY_SMOKE_SUMMARY_PATH)`"" | |
| ) | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append | |
| } | |
| @( | |
| "", | |
| "### Artifacts", | |
| "", | |
| "- JSON summary artifact: `"$($env:CSHARP_QUERY_SMOKE_JSON_ARTIFACT_NAME)`"` (uploaded on every run)", | |
| "- Full smoke output artifact: `"$($env:CSHARP_QUERY_SMOKE_FAILURE_ARTIFACT_NAME)`"` (uploaded on failure only)" | |
| ) | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append |