diff --git a/.github/workflows/skills-index-freshness.yml b/.github/workflows/skills-index-freshness.yml index 9e4b2767be..ff2bc393aa 100644 --- a/.github/workflows/skills-index-freshness.yml +++ b/.github/workflows/skills-index-freshness.yml @@ -23,6 +23,14 @@ jobs: timeout-minutes: 10 environment: trusted-automation steps: + # `Get GitHub App token` below is a LOCAL composite action + # (./.github/actions/get-app-token), so the repository must be on disk + # before it can be resolved. Without this checkout the job dies with + # "Can't find 'action.yml' ... under .github/actions/get-app-token" + # every time the probe is non-ok — i.e. exactly when the watchdog is + # supposed to file its issue. + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Probe live index id: probe run: | diff --git a/.github/workflows/skills-index.yml b/.github/workflows/skills-index.yml index 5415499e02..cf6812630e 100644 --- a/.github/workflows/skills-index.yml +++ b/.github/workflows/skills-index.yml @@ -63,12 +63,19 @@ jobs: timeout-minutes: 15 environment: trusted-automation steps: + # Required: `Get GitHub App token` is a LOCAL composite action + # (./.github/actions/get-app-token) and cannot resolve without the repo + # checked out. `build-index` above already does this; this job did not, + # so the scheduled deploy re-trigger never fired. + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Get GitHub App token id: app-token uses: ./.github/actions/get-app-token with: client-id: ${{ vars.APP_CLIENT_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Trigger Deploy Site workflow env: GH_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/tests/gateway/test_multiplex_busy_input_mode.py b/tests/gateway/test_multiplex_busy_input_mode.py index d23c3c062f..c7cfbfe1f7 100644 --- a/tests/gateway/test_multiplex_busy_input_mode.py +++ b/tests/gateway/test_multiplex_busy_input_mode.py @@ -1,7 +1,8 @@ """Profile-specific busy-input behavior for multiplexed gateways.""" import asyncio -from unittest.mock import AsyncMock, MagicMock +from pathlib import Path +from unittest.mock import AsyncMock, MagicMock, patch import pytest @@ -336,7 +337,20 @@ def test_profile_route_and_nonmultiplexed_resolution_preserve_boundaries(): ] source = _event(profile=None).source - assert runner._effective_busy_input_mode(source) == "steer" + # `_profile_name_for_source` rejects a route whose target profile is not in + # the served set (`profiles_to_serve`). Without this patch the test reads + # the runner's real on-disk profiles, so "research" is unserved on any + # machine that does not happen to have it — and the route is rejected + # before the busy-mode snapshot is consulted. Sibling coverage in + # tests/gateway/test_profile_resolution.py patches the same seam. + with patch( + "hermes_cli.profiles.profiles_to_serve", + return_value=[ + ("default", Path("/profiles/default")), + ("research", Path("/profiles/research")), + ], + ): + assert runner._effective_busy_input_mode(source) == "steer" runner.config.multiplex_profiles = False source.profile = "research"