refactor(substrate): split host mechanics into @agent-device/host-kit capability ports #871
Workflow file for this run
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: Mutation Affected | |
| # PR-side half of the decision-kernel mutation lane (issue #1415). | |
| # | |
| # Advisory only — the lane reports and never gates (#1457). `scripts/mutation/run.ts` | |
| # exits non-zero on a harness failure, never on a score. | |
| # | |
| # Cost control: the kernel report that pays is the weekly sweep, so this lane | |
| # spends mutants on one thing only — proving the harness still runs end to end | |
| # when the harness itself changes. `select` therefore returns an empty matrix | |
| # unless the diff touches the lane's own sources. Selecting on derived kernel | |
| # ownership instead would run the full ten-shard sweep on 24 of the last 40 | |
| # merged PRs. | |
| # | |
| # On a harness diff the matrix is the canary (`LANE_CANARY`, the registry's | |
| # cheapest real sweep — lane sources own no kernel, so derivation alone would | |
| # select nothing) plus any kernel that same diff reaches through the import | |
| # graph (scripts/mutation/ownership.ts): a kernel source, or a test that reaches | |
| # one. Selected modules are sharded like the weekly sweep, so the PR's wall | |
| # clock is one module rather than their sum. | |
| on: | |
| pull_request: | |
| paths: | |
| # Exactly `LANE_TOOLING` in scripts/mutation/run.ts plus this file — the | |
| # only diffs that can produce a non-empty matrix, asserted both ways by | |
| # scripts/mutation/workflow.test.ts. A kernel or test path here would only | |
| # start a job that selects nothing. | |
| - 'scripts/mutation/**' | |
| - 'scripts/lib/**' | |
| - 'stryker.config.json' | |
| - '.github/workflows/mutation-affected.yml' | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| select: | |
| name: Select affected kernels | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| outputs: | |
| modules: ${{ steps.select.outputs.result }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup toolchain | |
| uses: ./.github/actions/setup-node-pnpm | |
| - name: Harness self-test | |
| uses: ./.github/actions/run-gate | |
| with: { gate: mutation-model } | |
| - id: select | |
| name: Derive the affected shard matrix | |
| uses: ./.github/actions/run-gate | |
| with: | |
| gate: mutation-affected | |
| args: | | |
| --list-affected | |
| --base | |
| origin/${{ github.event.pull_request.base.ref }} | |
| # The self-test and the derivation run before any mutant, so a failure here | |
| # would leave the lane with no envelope at all (#1430). | |
| - name: Record a failed lane envelope | |
| if: failure() | |
| run: | | |
| pnpm gate mutation --affected --fail-envelope \ | |
| "affected selection failed before any mutant ran (run ${{ github.run_id }})" || true | |
| - name: Upload selection envelope | |
| if: failure() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: mutation-affected-select | |
| include-hidden-files: true | |
| path: .tmp/mutation/lane-envelope.json | |
| if-no-files-found: warn | |
| mutants: | |
| name: Mutants (${{ matrix.name }}) | |
| needs: select | |
| if: needs.select.outputs.modules != '[]' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: ${{ fromJSON(needs.select.outputs.modules) }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Setup toolchain | |
| uses: ./.github/actions/setup-node-pnpm | |
| - name: Run mutants for ${{ matrix.name }} | |
| uses: ./.github/actions/run-gate | |
| with: | |
| gate: mutation | |
| args: | | |
| --modules | |
| ${{ matrix.module }} | |
| ${{ matrix.shard && '--shard' || '' }} | |
| ${{ matrix.shard || '' }} | |
| - name: Record a failed shard envelope | |
| if: failure() | |
| run: | | |
| pnpm gate mutation --affected --modules ${{ matrix.module }} --fail-envelope \ | |
| "shard ${{ matrix.name }} failed before producing a report (run ${{ github.run_id }})" || true | |
| - name: Upload shard report | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: mutation-affected-shard-${{ matrix.name }} | |
| include-hidden-files: true | |
| path: | | |
| .tmp/mutation/mutation.json | |
| .tmp/mutation/mutation.html | |
| .tmp/mutation/lane-envelope.json | |
| if-no-files-found: warn | |
| report: | |
| name: Affected decision-kernel mutants | |
| needs: [select, mutants] | |
| if: always() && needs.select.result == 'success' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup toolchain | |
| uses: ./.github/actions/setup-node-pnpm | |
| - name: Download shard reports | |
| if: needs.select.outputs.modules != '[]' | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| with: | |
| pattern: mutation-affected-shard-* | |
| path: .tmp/mutation/shards | |
| # No shards means no affected kernel: run.ts reports "nothing to mutate" | |
| # and still writes the envelope, so the lane is never silently absent. | |
| # Either invocation writes the score table to $GITHUB_STEP_SUMMARY. | |
| - name: Score the affected modules | |
| run: | | |
| if [ -d .tmp/mutation/shards ]; then | |
| expected=$(echo '${{ needs.select.outputs.modules }}' | jq length) | |
| pnpm gate mutation-check --report-dir .tmp/mutation/shards --affected \ | |
| --expect-shards "$expected" \ | |
| --base "origin/${{ github.event.pull_request.base.ref }}" | |
| else | |
| pnpm gate mutation-affected --base "origin/${{ github.event.pull_request.base.ref }}" | |
| fi | |
| - name: Record a failed lane envelope | |
| if: failure() | |
| run: | | |
| pnpm gate mutation --affected --fail-envelope \ | |
| "affected report failed before producing a score table (run ${{ github.run_id }})" || true | |
| - name: Upload mutation report | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: mutation-affected | |
| include-hidden-files: true | |
| path: | | |
| .tmp/mutation/shards | |
| .tmp/mutation/lane-envelope.json | |
| if-no-files-found: ignore |