Repository navigation
feat(runtime): add decision policy governance types #2202
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: Main | |
| on: | |
| push: | |
| branches: | |
| - master | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: master-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| quality: | |
| timeout-minutes: 20 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.cache/prek | |
| key: prek-${{ hashFiles('.pre-commit-config.yaml') }} | |
| - name: Set up the environment | |
| uses: ./.github/actions/setup-python-env | |
| - name: Run checks | |
| run: make check | |
| - name: Check OpenAPI contract | |
| run: make contract-test | |
| tests: | |
| timeout-minutes: 40 | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ["3.11", "3.12", "3.13", "3.14"] | |
| fail-fast: false | |
| defaults: | |
| run: | |
| shell: bash | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the environment | |
| uses: ./.github/actions/setup-python-env | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Set up project tools | |
| uses: jdx/mise-action@c37c93293d6b742fc901e1406b8f764f6fb19dac # v2 | |
| - name: Install and resolve native DSH configuration test APIs | |
| run: | | |
| pnpm --dir integrations/dsh/plugins/powercontext/tests/config-runtime install --frozen-lockfile | |
| boot="$(node --input-type=module -e "import { createRequire } from 'node:module'; import { resolve } from 'node:path'; const require = createRequire(resolve('integrations/dsh/plugins/powercontext/tests/config-runtime/package.json')); process.stdout.write(require.resolve('@deepseek-ai/dsh-app-boot'))")" | |
| test -n "$boot" && test -f "$boot" || { echo "DSH configuration runtime unresolved"; exit 1; } | |
| echo "DSH_TEST_CONFIG_BOOT=$boot" >> "$GITHUB_ENV" | |
| - name: Run unit tests | |
| env: | |
| PYTEST_ADDOPTS: --require-dsh-config-runtime | |
| run: make unit-test | |
| - name: Run end-to-end tests | |
| run: make e2e-test | |
| evaluation-tests: | |
| timeout-minutes: 20 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the environment | |
| uses: ./.github/actions/setup-python-env | |
| # Evaluation has its own uv project. Collect each suite's unit tests through | |
| # its dedicated path; the root project's testpaths do not include them. | |
| - name: Run the evaluation project unit tests | |
| run: | | |
| set -o pipefail | |
| make evaluation-unit-test 2>&1 | tee evaluation/pytest.log | |
| # A pull request from a fork cannot read this run's raw job log — the log | |
| # endpoint answers `Must have admin rights to Repository` — so a red check | |
| # is otherwise an exit code and nothing else. Both the step summary and an | |
| # annotation are readable by the contributor, and the annotation is the one | |
| # that still says something when the failure happened before the tests ran. | |
| - name: Report the failing cases | |
| if: failure() | |
| run: | | |
| { | |
| echo "### evaluation unit tests" | |
| echo | |
| echo '```' | |
| uv --version || true | |
| python3 -V || true | |
| echo '```' | |
| echo | |
| if grep -qE '^(FAILED|ERROR) ' evaluation/pytest.log; then | |
| echo '```' | |
| grep -E '^(FAILED|ERROR) ' evaluation/pytest.log | |
| echo '```' | |
| else | |
| echo "No failing case was reported, so the run failed before the tests ran:" | |
| echo | |
| echo '```' | |
| tail -n 40 evaluation/pytest.log | |
| echo '```' | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| detail=$(tail -n 25 evaluation/pytest.log | awk '{gsub(/%/, "%25"); gsub(/\r/, "%0D"); printf "%s%%0A", $0}') | |
| echo "::error title=evaluation unit tests failed::${detail}" | |
| code-seekdb: | |
| timeout-minutes: 20 | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.11", "3.14"] | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the environment | |
| uses: ./.github/actions/setup-python-env | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Test code indexing with embedded seekdb | |
| run: make code-seekdb-test | |
| - name: Test unified migrations with embedded seekdb | |
| timeout-minutes: 10 | |
| env: | |
| POWERCONTEXT_TEST_MIGRATION_SEEKDB: "1" | |
| POWERCONTEXT_TEST_MIGRATION_SQL_LOG: "1" | |
| PYTHONUNBUFFERED: "1" | |
| TMPDIR: ${{ runner.temp }}/seekdb-migration | |
| run: | | |
| set -o pipefail | |
| mkdir -p "$TMPDIR" | |
| collect_diagnostics() { | |
| df -h . /tmp | |
| # A timed-out pytest process cannot run fixture cleanup. Retain | |
| # bounded native logs from its isolated data directories as well | |
| # as the Python stack and SQL trace. | |
| find "$TMPDIR" -type f \( -name '*.log' -o -name '*.log.wf' \) \ | |
| -print -exec tail -c 8388608 {} \; > seekdb-native.log | |
| } | |
| trap collect_diagnostics EXIT | |
| df -h . /tmp | |
| uv run --locked --extra seekdb pytest -vv \ | |
| -o faulthandler_timeout=120 --durations=20 \ | |
| tests/builtin/persistence/test_database_migration_backends.py \ | |
| tests/builtin/persistence/test_database_backup_providers.py \ | |
| tests/builtin/persistence/test_database_migration_connections.py \ | |
| tests/builtin/persistence/test_mysql_migration_schema.py -k seekdb \ | |
| 2>&1 | tee seekdb-migrations.log | |
| uv run --locked --extra seekdb pytest --collect-only -q --color=no \ | |
| tests/builtin/persistence/test_mysql_migration_runner.py -k seekdb \ | |
| 2>&1 | tee seekdb-runner-collection.log | tee -a seekdb-migrations.log | |
| mapfile -t seekdb_runner_nodes < <( | |
| sed -n '/^tests\/builtin\/persistence\/test_mysql_migration_runner\.py::/p' \ | |
| seekdb-runner-collection.log | |
| ) | |
| if [ "${#seekdb_runner_nodes[@]}" -eq 0 ]; then | |
| echo "No seekdb migration runner tests were collected" >&2 | |
| exit 1 | |
| fi | |
| for seekdb_runner_node in "${seekdb_runner_nodes[@]}"; do | |
| timeout --signal=TERM --kill-after=10s 180s \ | |
| uv run --locked --extra seekdb pytest -vv \ | |
| -o faulthandler_timeout=120 --durations=20 --log-cli-level=INFO \ | |
| "$seekdb_runner_node" -k seekdb \ | |
| 2>&1 | tee -a seekdb-migrations.log | |
| done | |
| - name: Upload seekdb migration diagnostics | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: seekdb-migrations-${{ matrix.python-version }} | |
| path: | | |
| seekdb-migrations.log | |
| seekdb-native.log | |
| if-no-files-found: ignore | |
| atomic-memory-clean-seekdb: | |
| name: Atomic Memory clean migration (SeekDB) | |
| timeout-minutes: 40 | |
| runs-on: ubuntu-latest | |
| env: | |
| POWERCONTEXT_TEST_MIGRATION_SEEKDB: "1" | |
| PYTHONUNBUFFERED: "1" | |
| MIGRATION_REPORTS: ${{ github.workspace }}/.powercontext/atomic-memory-clean-seekdb | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the environment | |
| uses: ./.github/actions/setup-python-env | |
| with: | |
| python-version: "3.12" | |
| - name: Run clean migration evidence, grants and vectors without skips | |
| timeout-minutes: 35 | |
| env: | |
| TMPDIR: ${{ runner.temp }}/am-seekdb | |
| run: | | |
| mkdir -p "$TMPDIR" | |
| uv run --locked --extra seekdb python scripts/run_atomic_memory_clean_migration.py \ | |
| seekdb --output "$MIGRATION_REPORTS" | |
| - name: Collect native diagnostics | |
| if: always() | |
| env: | |
| TMPDIR: ${{ runner.temp }}/am-seekdb | |
| run: | | |
| mkdir -p "$MIGRATION_REPORTS" | |
| df -h . /tmp > "$MIGRATION_REPORTS/disk.txt" | |
| if [ -d "$TMPDIR" ]; then | |
| find "$TMPDIR" -type f \( -name '*.log' -o -name '*.log.wf' \) \ | |
| -print -exec tail -c 8388608 {} \; > "$MIGRATION_REPORTS/seekdb-native.log" | |
| fi | |
| - name: Save clean migration reports | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: atomic-memory-clean-seekdb-${{ github.sha }} | |
| path: ${{ env.MIGRATION_REPORTS }}/ | |
| include-hidden-files: true | |
| if-no-files-found: error | |
| retention-days: 7 | |
| windows-unit-portability: | |
| timeout-minutes: 20 | |
| runs-on: windows-latest | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the environment | |
| uses: ./.github/actions/setup-python-env | |
| - name: Check Windows worker types | |
| run: >- | |
| uv run --locked --no-sync ty check --python-platform win32 | |
| src/powercontext/builtin/runtime/artifact_processing.py | |
| tests/builtin/runtime/test_artifact_processing.py | |
| - name: Verify spawned worker lifecycle on Windows | |
| run: uv run --locked --no-sync pytest -q tests/builtin/runtime/test_artifact_processing.py | |
| - name: Verify unsupported native indexing is skipped on Windows | |
| run: >- | |
| uv run --locked --no-sync pytest -q | |
| tests/builtin/test_native_code.py | |
| tests/builtin/test_native_code_multilanguage.py | |
| tests/e2e/test_native_code_multilanguage.py | |
| - name: Exercise fixtures without Windows long-path support | |
| shell: pwsh | |
| run: | | |
| Set-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name LongPathsEnabled -Value 0 | |
| # Keep pytest's default temporary root: a short --basetemp would hide | |
| # regressions in the nested checkout fixtures covered by issue #1501. | |
| - name: Run Windows portability regressions | |
| shell: pwsh | |
| run: >- | |
| uv run pytest -q | |
| tests/builtin/artifacts/skill/test_package.py | |
| tests/builtin/runtime/test_external_skills.py | |
| tests/test_cli.py::test_remote_enroll_can_install_automatic_service_in_one_command | |
| tests/test_openclaw_cli.py::test_build_openclaw_plugin_runs_pnpm_install_non_interactively | |
| tests/test_opencode_cli.py | |
| tests/test_service.py | |
| tests/test_service_bootstrap.py | |
| tests/test_service_environment.py | |
| tests/test_cli_workbuddy.py::test_setup_workbuddy_remote_checkout_refreshes_the_requested_ref | |
| dify-tools: | |
| timeout-minutes: 15 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the environment | |
| uses: ./.github/actions/setup-python-env | |
| with: | |
| python-version: "3.12" | |
| - name: Check out the supported Dify host helpers | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| repository: langgenius/dify | |
| ref: 8387590ace4a094de812b7847fc6a4c3a27cd52b # 1.17.1 | |
| path: .artifacts/dify-host | |
| persist-credentials: false | |
| sparse-checkout-cone-mode: false | |
| sparse-checkout: | | |
| api/core/entities/parameter_entities.py | |
| api/core/plugin/entities/parameters.py | |
| api/core/tools/__base/tool.py | |
| api/core/tools/entities/common_entities.py | |
| api/core/tools/entities/tool_entities.py | |
| docker/docker-compose.yaml | |
| web/app/components/workflow/nodes/tool/default.ts | |
| web/app/components/workflow/nodes/tool/output-schema-utils.ts | |
| web/app/components/workflow/nodes/_base/components/variable/utils.ts | |
| - name: Check out the default Dify plugin daemon entities | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| repository: langgenius/dify-plugin-daemon | |
| ref: 1310a18b2f6bc6f18768a0a6265484830891433c # 0.6.10 (Dify 1.17.1 compose default) | |
| path: .artifacts/dify-daemon | |
| persist-credentials: false | |
| - name: Set up Go for daemon entity serialization | |
| uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 | |
| with: | |
| go-version-file: .artifacts/dify-daemon/go.mod | |
| cache-dependency-path: .artifacts/dify-daemon/go.sum | |
| - name: Set up project tools | |
| uses: jdx/mise-action@7a4e45a543138629540c9a1616d08632b893e492 # v5.0.1 | |
| - name: Check daemon serialization, host casting, Workflow selectors and SDK HTTP readback | |
| env: | |
| POWERCONTEXT_DIFY_SOURCE: ${{ github.workspace }}/.artifacts/dify-host | |
| POWERCONTEXT_DIFY_DAEMON_SOURCE: ${{ github.workspace }}/.artifacts/dify-daemon | |
| run: make dify-test | |
| hermes-skills: | |
| timeout-minutes: 15 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the environment | |
| uses: ./.github/actions/setup-python-env | |
| - name: Check out the supported Hermes host | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| repository: NousResearch/hermes-agent | |
| ref: e624e9fde561e1add9388384012b295fde669ade # v2026.8.18 / CLI 0.20.4 | |
| path: .hermes-native | |
| persist-credentials: false | |
| - name: Verify native Skill discovery and metadata | |
| env: | |
| POWERCONTEXT_HERMES_SOURCE: ${{ github.workspace }}/.hermes-native | |
| run: uv run pytest tests/e2e/test_hermes_skills.py | |
| dsh-package: | |
| timeout-minutes: 30 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the Python environment | |
| uses: ./.github/actions/setup-python-env | |
| - name: Set up project tools | |
| uses: jdx/mise-action@7a4e45a543138629540c9a1616d08632b893e492 # v5.0.1 | |
| - name: Test DSH package | |
| run: make js-test | |
| - name: Test built plugin in the real DSH runtime | |
| run: make dsh-runtime-test | |
| - name: Install native DSH configuration test APIs | |
| run: pnpm --dir integrations/dsh/plugins/powercontext/tests/config-runtime install --frozen-lockfile | |
| - name: Resolve required DSH test runtimes | |
| run: | | |
| bin="$(node --input-type=module -e "import { dshBin } from './integrations/dsh/plugins/powercontext/tests/runtime/fixture.mjs'; process.stdout.write(dshBin)")" | |
| test -n "$bin" && test -f "$bin" || { echo "DSH test executable unresolved"; exit 1; } | |
| boot="$(node --input-type=module -e "import { createRequire } from 'node:module'; import { resolve } from 'node:path'; const require = createRequire(resolve('integrations/dsh/plugins/powercontext/tests/config-runtime/package.json')); process.stdout.write(require.resolve('@deepseek-ai/dsh-app-boot'))")" | |
| test -n "$boot" && test -f "$boot" || { echo "DSH configuration runtime unresolved"; exit 1; } | |
| echo "DSH_TEST_EXECUTABLE=$bin" >> "$GITHUB_ENV" | |
| echo "DSH_TEST_CONFIG_BOOT=$boot" >> "$GITHUB_ENV" | |
| - name: Verify DSH setup with customized profiles | |
| run: uv run pytest tests/test_dsh_transport.py --require-dsh-runtime | |
| - name: Verify DSH guidance adapter requests and results | |
| run: uv run pytest "tests/test_integration_guidance_evaluation.py::test_native_adapter_handoff_uses_real_request_mapping_and_response_envelopes[dsh]" | |
| pi-package: | |
| timeout-minutes: 20 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the Python environment | |
| uses: ./.github/actions/setup-python-env | |
| - name: Set up project tools | |
| uses: jdx/mise-action@7a4e45a543138629540c9a1616d08632b893e492 # v5.0.1 | |
| - name: Test Pi package | |
| run: make pi-test | |
| - name: Verify Pi guidance adapter requests and results | |
| run: uv run pytest "tests/test_integration_guidance_evaluation.py::test_native_adapter_handoff_uses_real_request_mapping_and_response_envelopes[pi]" | |
| opencode-package: | |
| timeout-minutes: 20 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the Python environment | |
| uses: ./.github/actions/setup-python-env | |
| - uses: jdx/mise-action@7a4e45a543138629540c9a1616d08632b893e492 # v5.0.1 | |
| - name: Test OpenCode package | |
| run: make opencode-test | |
| - name: Verify OpenCode guidance adapter requests and results | |
| run: uv run pytest "tests/test_integration_guidance_evaluation.py::test_native_adapter_handoff_uses_real_request_mapping_and_response_envelopes[opencode]" | |
| openclaw-package: | |
| timeout-minutes: 20 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the Python environment | |
| uses: ./.github/actions/setup-python-env | |
| - uses: jdx/mise-action@7a4e45a543138629540c9a1616d08632b893e492 # v5.0.1 | |
| # The pinned OpenClaw SDK requires the SQLite runtime shipped with Node 24.15+. | |
| - run: mise install node@24.15.0 | |
| - name: Test OpenClaw package | |
| run: mise exec node@24.15.0 -- make openclaw-plugin-test | |
| - name: Verify OpenClaw guidance adapter requests and results | |
| run: mise exec node@24.15.0 -- uv run pytest tests/test_integration_guidance_evaluation.py::test_openclaw_handoff_adapter_preserves_generated_source_identity | |
| opendal-package: | |
| timeout-minutes: 20 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the Python environment | |
| uses: ./.github/actions/setup-python-env | |
| with: | |
| python-version: "3.12" | |
| - name: Test OpenDAL package | |
| run: make opendal-test | |
| website-link-validation-windows: | |
| timeout-minutes: 20 | |
| runs-on: windows-latest | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up website tools | |
| uses: jdx/mise-action@7a4e45a543138629540c9a1616d08632b893e492 # v5.0.1 | |
| - name: Install website dependencies | |
| run: pnpm --dir website install --frozen-lockfile | |
| - name: Test route scanning and link validation | |
| run: pnpm --dir website test:links | |
| check-website: | |
| timeout-minutes: 20 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up the environment | |
| uses: ./.github/actions/setup-python-env | |
| - name: Set up website tools | |
| uses: jdx/mise-action@7a4e45a543138629540c9a1616d08632b893e492 # v5.0.1 | |
| - name: Check website | |
| run: make docs-test |