Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/strix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ jobs:
# docs/doctoring/required-workflow-path-filter-boundary.md.
# Fails OPEN: an unreadable, empty, or truncated file list scans everything.
if: github.event_name != 'pull_request_target' || (github.event.action != 'closed' && github.event.action != 'converted_to_draft')
runs-on: ubuntu-24.04
runs-on: ${{ (github.repository == 'ContextualWisdomLab/.github' || github.repository == 'ContextualWisdomLab/fast-mlsirm') && github.workflow_ref == 'ContextualWisdomLab/.github/.github/workflows/strix.yml@refs/heads/main' && fromJSON('{"group":"CWL central control","labels":["self-hosted","linux","x64","cwlab-control"]}') || fromJSON('["ubuntu-24.04"]') }}
timeout-minutes: 5
permissions:
contents: read
Expand Down Expand Up @@ -187,7 +187,7 @@ jobs:
if: >-
github.event_name != 'pull_request_target' ||
(github.event.action != 'closed' && github.event.action != 'converted_to_draft')
runs-on: ubuntu-24.04
runs-on: ${{ (github.repository == 'ContextualWisdomLab/.github' || github.repository == 'ContextualWisdomLab/fast-mlsirm') && github.workflow_ref == 'ContextualWisdomLab/.github/.github/workflows/strix.yml@refs/heads/main' && fromJSON('{"group":"CWL central control","labels":["self-hosted","linux","x64","cwlab-control"]}') || fromJSON('["ubuntu-24.04"]') }}
timeout-minutes: 5
permissions:
contents: read
Expand Down Expand Up @@ -260,7 +260,7 @@ jobs:
github.event.pull_request.base.repo.full_name || github.repository }}-${{
github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
runs-on: ubuntu-24.04
runs-on: ${{ (github.repository == 'ContextualWisdomLab/.github' || github.repository == 'ContextualWisdomLab/fast-mlsirm') && github.workflow_ref == 'ContextualWisdomLab/.github/.github/workflows/strix.yml@refs/heads/main' && fromJSON('{"group":"CWL central control","labels":["self-hosted","linux","x64","cwlab-control"]}') || fromJSON('["ubuntu-24.04"]') }}
# Bound this gh-api-only cleanup job so a stuck call (rate limit, hung
# `gh api --paginate`) cannot silently occupy a runner for GitHub's
# 360-minute platform default -- exactly the window when a busy PR is
Expand Down Expand Up @@ -1172,7 +1172,7 @@ jobs:
name: publish-manual-pr-evidence-status
needs: strix
if: ${{ always() && !cancelled() && github.event_name == 'repository_dispatch' && github.event.client_payload.pr_head_sha != '' }}
runs-on: ubuntu-24.04
runs-on: ${{ (github.repository == 'ContextualWisdomLab/.github' || github.repository == 'ContextualWisdomLab/fast-mlsirm') && github.workflow_ref == 'ContextualWisdomLab/.github/.github/workflows/strix.yml@refs/heads/main' && fromJSON('{"group":"CWL central control","labels":["self-hosted","linux","x64","cwlab-control"]}') || fromJSON('["ubuntu-24.04"]') }}
# Single-shot OIDC exchange plus a handful of curl/gh api calls, no loop
# or pagination -- same shape as the agent-mention-*-dispatch.yml
# validate-and-forward jobs, which bound at timeout-minutes: 5. Without
Expand Down
22 changes: 22 additions & 0 deletions docs/doctoring/central-dedicated-runner-routing-20260927.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,25 @@ capacity or independent service-time measurement justifies another solver.
The routing regression fails against the unchanged baseline. Workflow syntax
and affected contracts passed: 238 passed, 2 skipped with `GITHUB_ACTIONS=true`;
`actionlint` and `git diff --check` passed.


## fast-mlsirm Strix control admission

Current fast-mlsirm PR #2220 head `4eaeb799a6647ea29f3f4902d9ca79a1377e795c`
queued Strix admission job `108617323217` with `ubuntu-24.04`, despite the
self-hosted rollout. Route only changed-scope, current-head admission,
superseded-run cleanup and manual status publication through group 6 when
the source is exactly central `strix.yml@refs/heads/main` and the caller is
the central repository or fast-mlsirm. These jobs do not check out PR code.
The model scan keeps its existing hosted image and all evidence, credentials,
fork handling and live-head validation remain intact.

Reuse the deployed allocation; no new service-time or capacity measurement
justifies a different solver result. Deployment requires adding only central
`strix.yml@refs/heads/main` to group 6's selected workflows, preserving all
existing restrictions and grants. Old queued jobs keep their original source.

The routing test failed on the unmodified workflow. The affected runner,
changed-scope and dependency-hash tests passed (21 tests); actionlint and
diff whitespace checks passed. This is local source proof, not completed
consumer gate evidence.
8 changes: 4 additions & 4 deletions tests/test_docs_only_pr_runner_admission.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ def test_gate_job_is_byte_identical_across_the_five_workflows_apart_from_if():
workflow = _read(filename)
block = _top_level_job_block(workflow, "changed-scope")
normalized = "\n".join(
line for line in block.splitlines() if not line.strip().startswith("if:")
line for line in block.splitlines() if not line.strip().startswith(("if:", "runs-on:"))
)
normalized_blocks.add(normalized)
assert len(normalized_blocks) == 1, (
"changed-scope gate copies drifted; keep them byte-identical apart "
"from the single 'if:' line"
"from the event guard and separately tested runner allocation"
)


Expand Down Expand Up @@ -132,9 +132,9 @@ def test_gate_jobs_use_supported_runner_allocation():
"""Scope jobs preserve trusted-main routing and a supported hosted fallback."""
for filename in GATE_WORKFLOWS:
block = _top_level_job_block(_read(filename), "changed-scope")
if filename == "opencode-review.yml":
if filename in ("opencode-review.yml", "strix.yml"):
assert '"group":"CWL central control"' in block, filename
assert "github.workflow_ref == 'ContextualWisdomLab/.github/.github/workflows/opencode-review.yml@refs/heads/main'" in block, filename
assert f"github.workflow_ref == 'ContextualWisdomLab/.github/.github/workflows/{filename}@refs/heads/main'" in block, filename
assert "fromJSON('[\"ubuntu-24.04\"]')" in block, filename
elif filename == "noema-review.yml":
assert "endsWith(github.workflow_ref, '@refs/heads/main')" in block, filename
Expand Down
16 changes: 14 additions & 2 deletions tests/test_required_review_runner_image_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,20 @@ def assert_explicit_supported_image(self, path: Path) -> None:
self.assertEqual(runs_on, {"runs-on: ubuntu-24.04"})

def test_strix_uses_explicit_supported_image(self) -> None:
"""Require every Strix job to use explicit Ubuntu 24.04."""
self.assert_explicit_supported_image(STRIX)
"""Route trusted metadata to control while preserving the scan image."""
workflow = STRIX.read_text(encoding="utf-8")
for name in ("changed-scope", "admit-current-head", "cancel-superseded-pr-runs", "publish-manual-pr-evidence-status"):
block = re.split(r"\n [a-z][a-z-]*:\n", workflow.split(f"\n {name}:\n", 1)[1], maxsplit=1)[0]
self.assertIn('"group":"CWL central control"', block)
self.assertIn('"labels":["self-hosted","linux","x64","cwlab-control"]', block)
self.assertIn("github.workflow_ref == 'ContextualWisdomLab/.github/.github/workflows/strix.yml@refs/heads/main'", block)
self.assertIn("github.repository == 'ContextualWisdomLab/.github'", block)
self.assertIn("github.repository == 'ContextualWisdomLab/fast-mlsirm'", block)
self.assertIn("fromJSON('[\"ubuntu-24.04\"]')", block)
self.assertNotIn("actions/checkout", block)
scan = workflow.split("\n strix:\n", 1)[1].split("\n publish-manual-pr-evidence-status:\n", 1)[0]
self.assertIn("runs-on: ubuntu-24.04", scan)
self.assertNotIn("cwlab-control", scan)

def test_opencode_review_uses_explicit_supported_image(self) -> None:
"""Keep metadata-only OpenCode admission on the trusted control pool."""
Expand Down
Loading