Repository navigation
ci(nightly): prefer proven dedicated publication mini - #30278
Conversation
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
There was a problem hiding this comment.
2 issues found across 2 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/workflows/nightly.yml">
<violation number="1" location=".github/workflows/nightly.yml:6228">
P3: This adds a fixed Glaeda label to nightly publication jobs, contradicting the repository's stated rule that publication uses Linux and nightly jobs cannot name runner-specific labels. Document this exception and update the runner-policy checks, or keep the route on an approved pooled selector.</violation>
</file>
<file name="tests/test_nightly_trusted_routing.py">
<violation number="1" location="tests/test_nightly_trusted_routing.py:363">
P2: This negative case changes the owner along with the repository, so the earlier fork branch makes it pass without testing the `manaflow-ai/cmux` restriction; it also leaves the branch restriction untested. Keep the owner as `manaflow-ai` when testing a different repository, and add a separate wrong-ref case so the dedicated runner cannot be enabled outside `nightly-next`.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
| self.assertEqual(evaluate(expr, {**dedicated, "github.repository": "someone/cmux", | ||
| "github.repository_owner": "someone"}), | ||
| "ubuntu-24.04") |
There was a problem hiding this comment.
P2: This negative case changes the owner along with the repository, so the earlier fork branch makes it pass without testing the manaflow-ai/cmux restriction; it also leaves the branch restriction untested. Keep the owner as manaflow-ai when testing a different repository, and add a separate wrong-ref case so the dedicated runner cannot be enabled outside nightly-next.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At tests/test_nightly_trusted_routing.py, line 363:
<comment>This negative case changes the owner along with the repository, so the earlier fork branch makes it pass without testing the `manaflow-ai/cmux` restriction; it also leaves the branch restriction untested. Keep the owner as `manaflow-ai` when testing a different repository, and add a separate wrong-ref case so the dedicated runner cannot be enabled outside `nightly-next`.</comment>
<file context>
@@ -336,6 +336,34 @@ def test_credentialed_publish_controls_use_owned_claim_then_linux_overflow(self)
+ "blacksmith-16vcpu-ubuntu-2404")
+ self.assertEqual(evaluate(expr, {**dedicated, "vars.CI_NIGHTLY_ONLY_RUNNER": ""}),
+ "blacksmith-16vcpu-ubuntu-2404")
+ self.assertEqual(evaluate(expr, {**dedicated, "github.repository": "someone/cmux",
+ "github.repository_owner": "someone"}),
+ "ubuntu-24.04")
</file context>
| self.assertEqual(evaluate(expr, {**dedicated, "github.repository": "someone/cmux", | |
| "github.repository_owner": "someone"}), | |
| "ubuntu-24.04") | |
| self.assertEqual(evaluate(expr, {**dedicated, "github.repository": "someone/cmux"}), | |
| "blacksmith-16vcpu-ubuntu-2404") | |
| self.assertEqual(evaluate(expr, {**dedicated, "github.ref": "refs/heads/main"}), | |
| "blacksmith-16vcpu-ubuntu-2404") |
| runs-on: ${{ needs.pick-nightly-sign-runner.outputs.attempt == github.run_attempt && needs.pick-nightly-sign-runner.outputs.sign_owned_pool || vars.LINUX_RUNNER == 'blacksmith-16vcpu-ubuntu-2404' && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-32vcpu-ubuntu-2404' }} | ||
| # CI_NIGHTLY_ONLY_RUNNER stays off until every eligible m4pro slot is registered with the exclusive claim hook. | ||
| # The first claim step below proves that capability before any release token is read. | ||
| runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'ubuntu-24.04' || github.repository == 'manaflow-ai/cmux' && github.ref == 'refs/heads/nightly-next' && github.event_name == 'push' && github.run_attempt == 1 && vars.CI_NIGHTLY_ONLY_RUNNER == 'glaeda-nightly-only-m4pro' && vars.CI_NIGHTLY_ONLY_RUNNER || needs.pick-nightly-sign-runner.outputs.attempt == github.run_attempt && needs.pick-nightly-sign-runner.outputs.sign_owned_pool || vars.LINUX_RUNNER == 'blacksmith-16vcpu-ubuntu-2404' && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-32vcpu-ubuntu-2404' }} |
There was a problem hiding this comment.
P3: This adds a fixed Glaeda label to nightly publication jobs, contradicting the repository's stated rule that publication uses Linux and nightly jobs cannot name runner-specific labels. Document this exception and update the runner-policy checks, or keep the route on an approved pooled selector.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At .github/workflows/nightly.yml, line 6228:
<comment>This adds a fixed Glaeda label to nightly publication jobs, contradicting the repository's stated rule that publication uses Linux and nightly jobs cannot name runner-specific labels. Document this exception and update the runner-policy checks, or keep the route on an approved pooled selector.</comment>
<file context>
@@ -6223,7 +6223,9 @@ jobs:
- runs-on: ${{ needs.pick-nightly-sign-runner.outputs.attempt == github.run_attempt && needs.pick-nightly-sign-runner.outputs.sign_owned_pool || vars.LINUX_RUNNER == 'blacksmith-16vcpu-ubuntu-2404' && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-32vcpu-ubuntu-2404' }}
+ # CI_NIGHTLY_ONLY_RUNNER stays off until every eligible m4pro slot is registered with the exclusive claim hook.
+ # The first claim step below proves that capability before any release token is read.
+ runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'ubuntu-24.04' || github.repository == 'manaflow-ai/cmux' && github.ref == 'refs/heads/nightly-next' && github.event_name == 'push' && github.run_attempt == 1 && vars.CI_NIGHTLY_ONLY_RUNNER == 'glaeda-nightly-only-m4pro' && vars.CI_NIGHTLY_ONLY_RUNNER || needs.pick-nightly-sign-runner.outputs.attempt == github.run_attempt && needs.pick-nightly-sign-runner.outputs.sign_owned_pool || vars.LINUX_RUNNER == 'blacksmith-16vcpu-ubuntu-2404' && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-32vcpu-ubuntu-2404' }}
timeout-minutes: 120
env:
</file context>
|
Review (subagent gpt-6.1-sol): SHIP at 1d53d8f. Follow-ups: add independent wrong-repository and wrong-ref assertions; document the approved dedicated-label exception in the runner policy guard if required. |
1d53d8f to
dc9d906
Compare
|
Review (subagent): SHIP at 67abe05 |
There was a problem hiding this comment.
1 existing issue remains and 4 new issues found across 8 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/ci/signing_runner.py">
<violation number="1" location="scripts/ci/signing_runner.py:346">
P3: `owned_pool_label` is unreachable because `main` hardcodes `owned_pool = ""` on every path, leaving an unused helper and documentation that promises a label the command never emits. Remove the helper until the controller evidence exists, or wire it in when the pooled route is enabled and document the currently empty output.</violation>
</file>
<file name="tests/test_nightly_trusted_routing.py">
<violation number="1" location="tests/test_nightly_trusted_routing.py:357">
P2: This test never exercises the owned-pool route despite its name and comment. Add a non-empty `sign_owned_pool` fixture and assert that each publication control selects that pool label.</violation>
<violation number="2" location="tests/test_nightly_trusted_routing.py:395">
P2: The test does not reject another non-empty value for `CI_NIGHTLY_ONLY_RUNNER`, so it can miss removal of the exact `glaeda-nightly-only-m4pro` allowlist check. Add a wrong non-empty value expecting the Linux fallback.</violation>
</file>
<file name="tests/test_ci_signing_owned_mac.py">
<violation number="1" location="tests/test_ci_signing_owned_mac.py:398">
P1: The publication guard does not actually require the claim gate to precede release credentials; it only requires the gate to follow checkout. A secret-bearing step inserted between `Claim the whole Mac for signing` and `claim-gate` would pass because the existing ordering check compares secrets only with the claim script, allowing credentials onto an unclaimed shared Mac. Reject any secret-bearing step between checkout and `claim-gate` (or require `gate_index` to precede the first secret).</violation>
</file>
Requires human review: Auto-approval blocked because this review re-detected 1 unresolved issue already reported by Cubic.
View guided diff | Turn on auto-fix | Re-trigger cubic
| elif publication: | ||
| checkout_index = next((index for index, step in enumerate(steps) | ||
| if "actions/checkout@" in str(step.get("uses", ""))), None) | ||
| if checkout_index is None or gate_index <= checkout_index: |
There was a problem hiding this comment.
P1: The publication guard does not actually require the claim gate to precede release credentials; it only requires the gate to follow checkout. A secret-bearing step inserted between Claim the whole Mac for signing and claim-gate would pass because the existing ordering check compares secrets only with the claim script, allowing credentials onto an unclaimed shared Mac. Reject any secret-bearing step between checkout and claim-gate (or require gate_index to precede the first secret).
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At tests/test_ci_signing_owned_mac.py, line 398:
<comment>The publication guard does not actually require the claim gate to precede release credentials; it only requires the gate to follow checkout. A secret-bearing step inserted between `Claim the whole Mac for signing` and `claim-gate` would pass because the existing ordering check compares secrets only with the claim script, allowing credentials onto an unclaimed shared Mac. Reject any secret-bearing step between checkout and `claim-gate` (or require `gate_index` to precede the first secret).</comment>
<file context>
@@ -358,19 +360,43 @@ def check(documents: dict[str, dict]) -> tuple[list[str], int]:
+ elif publication:
+ checkout_index = next((index for index, step in enumerate(steps)
+ if "actions/checkout@" in str(step.get("uses", ""))), None)
+ if checkout_index is None or gate_index <= checkout_index:
+ failures.append(f"{label}: publication claim gate must run after checkout and before release credentials")
failures.extend(f"{label}: {why}" for why in twin_failures(jobs, name, owned_reads, workflow))
</file context>
| if checkout_index is None or gate_index <= checkout_index: | |
| if (checkout_index is None or gate_index <= checkout_index | |
| or any("secrets." in json.dumps(step) for step in steps[checkout_index + 1:gate_index])): |
| "needs.pick-nightly-sign-runner.outputs.sign_owned_pool": "", | ||
| "vars.LINUX_RUNNER": "blacksmith-16vcpu-ubuntu-2404", | ||
| } | ||
| self.assertEqual(evaluate(parse_expression(source), fallback), "blacksmith-16vcpu-ubuntu-2404") |
There was a problem hiding this comment.
P2: This test never exercises the owned-pool route despite its name and comment. Add a non-empty sign_owned_pool fixture and assert that each publication control selects that pool label.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At tests/test_nightly_trusted_routing.py, line 357:
<comment>This test never exercises the owned-pool route despite its name and comment. Add a non-empty `sign_owned_pool` fixture and assert that each publication control selects that pool label.</comment>
<file context>
@@ -327,6 +327,77 @@ def test_signer_jobs_use_the_dedicated_blacksmith_linux_picker(self):
+ "needs.pick-nightly-sign-runner.outputs.sign_owned_pool": "",
+ "vars.LINUX_RUNNER": "blacksmith-16vcpu-ubuntu-2404",
+ }
+ self.assertEqual(evaluate(parse_expression(source), fallback), "blacksmith-16vcpu-ubuntu-2404")
+ self.assertEqual(evaluate(parse_expression(source), {**fallback, "github.repository_owner": "someone"}),
+ "ubuntu-24.04")
</file context>
| self.assertEqual(evaluate(parse_expression(source), fallback), "blacksmith-16vcpu-ubuntu-2404") | |
| self.assertEqual(evaluate(parse_expression(source), fallback), "blacksmith-16vcpu-ubuntu-2404") | |
| self.assertEqual( | |
| evaluate(parse_expression(source), { | |
| **fallback, | |
| "needs.pick-nightly-sign-runner.outputs.sign_owned_pool": "glaeda-signing-std", | |
| }), | |
| "glaeda-signing-std", | |
| ) |
| self.assertEqual(evaluate(expr, {**dedicated, "vars.CI_NIGHTLY_ONLY_RUNNER": ""}), | ||
| "blacksmith-16vcpu-ubuntu-2404") |
There was a problem hiding this comment.
P2: The test does not reject another non-empty value for CI_NIGHTLY_ONLY_RUNNER, so it can miss removal of the exact glaeda-nightly-only-m4pro allowlist check. Add a wrong non-empty value expecting the Linux fallback.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At tests/test_nightly_trusted_routing.py, line 395:
<comment>The test does not reject another non-empty value for `CI_NIGHTLY_ONLY_RUNNER`, so it can miss removal of the exact `glaeda-nightly-only-m4pro` allowlist check. Add a wrong non-empty value expecting the Linux fallback.</comment>
<file context>
@@ -327,6 +327,77 @@ def test_signer_jobs_use_the_dedicated_blacksmith_linux_picker(self):
+ "blacksmith-16vcpu-ubuntu-2404")
+ self.assertEqual(evaluate(expr, {**dedicated, "github.event_name": "schedule"}),
+ "blacksmith-16vcpu-ubuntu-2404")
+ self.assertEqual(evaluate(expr, {**dedicated, "vars.CI_NIGHTLY_ONLY_RUNNER": ""}),
+ "blacksmith-16vcpu-ubuntu-2404")
+ self.assertEqual(evaluate(expr, {**dedicated, "github.repository": "someone/cmux",
</file context>
| self.assertEqual(evaluate(expr, {**dedicated, "vars.CI_NIGHTLY_ONLY_RUNNER": ""}), | |
| "blacksmith-16vcpu-ubuntu-2404") | |
| self.assertEqual(evaluate(expr, {**dedicated, "vars.CI_NIGHTLY_ONLY_RUNNER": ""}), | |
| "blacksmith-16vcpu-ubuntu-2404") | |
| self.assertEqual(evaluate(expr, {**dedicated, "vars.CI_NIGHTLY_ONLY_RUNNER": "glaeda-other-m4pro"}), | |
| "blacksmith-16vcpu-ubuntu-2404") |
| drain_anyway=(env.get("DRAIN_ANYWAY") or "").strip() == DRAIN_ANYWAY_VALUE) | ||
|
|
||
|
|
||
| def owned_pool_label(owned: str) -> str: |
There was a problem hiding this comment.
P3: owned_pool_label is unreachable because main hardcodes owned_pool = "" on every path, leaving an unused helper and documentation that promises a label the command never emits. Remove the helper until the controller evidence exists, or wire it in when the pooled route is enabled and document the currently empty output.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At scripts/ci/signing_runner.py, line 346:
<comment>`owned_pool_label` is unreachable because `main` hardcodes `owned_pool = ""` on every path, leaving an unused helper and documentation that promises a label the command never emits. Remove the helper until the controller evidence exists, or wire it in when the pooled route is enabled and document the currently empty output.</comment>
<file context>
@@ -341,6 +343,17 @@ def owned_pick(env: Mapping[str, str],
drain_anyway=(env.get("DRAIN_ANYWAY") or "").strip() == DRAIN_ANYWAY_VALUE)
+def owned_pool_label(owned: str) -> str:
+ """Return the shared pool label from an owned pick, never its per-runner label."""
+ if not owned:
</file context>
67abe05 to
66167e2
Compare
|
Review (subagent): SHIP at 66167e2 |
|
Review (claude opus-5.5 medium): BLOCK at 66167e2 Read the full diff against feat-cmux-next: Findings:
Checked and fine: with the var unset, the non-fork routes resolve as before. The YAML anchors ( Follow-ups:
|
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 4e81bfe; does not block Shipped in:
|
|
Review (codex, router-review): SHIP at d317a18 Reviewer: codex gpt-6-astra high, fast tier. Follow-ups: 1. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward. SHIP at d317a18 Visual verdict: no images; Leo tries the build
No blocking regression found. Parsed workflow comparison confirms only the three runner expressions change; the environment anchors preserve values. Routing, fork, and size suites pass (64 tests). Signing checks pass 21/23; two fail because this box lacks network access and omitted certificate files. Follow-ups:
|
… job env as its value #30278 (fe4577e) turned the publish jobs' NIGHTLY_FEEDS into a YAML anchor (`&pub-feeds ${{ needs.decide.outputs.feeds }}`) and aliases (`*pub-feeds`). tests/test_nightly_next_identity.py reads job env as raw text, so test_each_app_reads_the_feed_its_publisher_writes failed on the anchor prefix. job_env now resolves an alias to its one anchor and drops an anchor name, as YAML does; the asserted values are the same. Red at 03423de: python3 tests/test_nightly_next_identity.py 7/8 passed Green here: same command, 8/8 passed.
… (highlights, capabilities, step coverage, arm64 recorder) (#30624) * base red: tooling-tests, register test_ci_blacksmith_linux_sizes.py as manual and the unregistered tests tooling-tests failed on every feat-cmux-next pull request at "validate_test_execution_registry.py --pr-lanes feat-cmux-next": tests/test_ci_blacksmith_linux_sizes.py: linux-guard lane is not run by any workflow #30360 (d57f2fc) registered the test as linux-guard but added no ci-guards.yml step that runs it. CLAUDE.md forbids new CI tests (Lawrence 2026-10-23), so it becomes a manual entry with how to run it. The registry also warned about six tests with no entry. test_nightly_dedicated_mini.py is already run by ci-guards.yml, so it takes linux-guard; the other five are run by no workflow and enter as manual, each with its own run command. Red at 03423de: python3 scripts/ci/validate_test_execution_registry.py --pr-lanes feat-cmux-next --base-sha HEAD^1 exit 1 Green here: same command, exit 0 (594 tests, manual=31). * base red: Checks job structure, the preflight tests read the preflight step by id tests/test_cmux_next_checks_workflow.py read the preflight script as the last step of cmux-tui-artifacts.yml's tree-preflight job. #30221 (5bdd4c9) added "Record tree owner observation" and an upload step after it, so 14 tests failed with KeyError: 'run' on every pull request. They now take the step by its id (push-head-preflight's `head`, tree-preflight's `inspect`); the assertions do not change. Red at 03423de: python3 tests/test_cmux_next_checks_workflow.py FAILED (errors=14) Green here: same command, 165 tests OK. * base red: Tier routing, an agent pane on a dev server URL loads its own document test_no_suite_runs_page_javascript_on_a_built_bundle flagged AgentPageHibernationTests.swift after #30312 (b16b20c) made it call waitUntilLoaded. That suite's agent pane loads AgentPaneSource.devURLVariable, a loopback port nobody serves (Debug test builds honor it), not the built bundle, so it reads no bundle content. The check now counts AgentPaneSource.devURLVariable as a suite's own document, beside loadHTMLString and the fixture roots. Red at 03423de: python3 tests/test_cmux_next_route.py FAILED (failures=1) Green here: same command, 112 tests OK. * base red: daemon capabilities export lists agent-session-start-no-cwd-v1 #30363 (efd30f5) added the optional capability agent-session-start-no-cwd-v1 to DaemonEndpoint.swift without the export, which reddened "Daemon capabilities export is fresh" and the daemon-capabilities-fresh.test.sh script test. Regenerated with the check's own renderer (--write), as base-autofix does. Red at 03423de: python3 scripts/cmux-next/check-daemon-capabilities-fresh.py exit 1 Green here: same command, exit 0; bash scripts/cmux-next/tests/daemon-capabilities-fresh.test.sh ok. * base red: String tables, store.updates.available has English's plural forms in every language #30288 (e6bfd26) made store.updates.available a plural with `one` and `other`, but ja, km, ko, th, vi, zh-Hans and zh-Hant got only `other`, and check-l10n.sh requires English's forms in every language. Their `one` form is their `other` text, as home.stopAll.couldNotStop does. Also adds the 12 languages #27883 (16b7cc2) left out of action.sidebar.compactList.toggle (style debt CI only warns about), marked needs_review. Red at 03423de: scripts/cmux-next/check-l10n.sh . 7 errors (19 without L10N_STYLE_WARN_MAX) Green here: same command, 0 errors. * base red: release-notary, three highlights link their pull requests scripts/whats-new/test_digest.py needs a try-it action, docs or a pr link on every highlight. chat-title-plain (#29920), cloud-live-previews (#30334) and working-harness-tab-icons (#27905) had none; each now links its pull request, as #29939 did for priority-view-drag. Red at 03423de: python3 scripts/whats-new/test_digest.py FAILED (failures=1) Green here: same command, OK. * base red: release-notary, the static capability check skips agent-session-start-no-cwd-v1 #30363 (efd30f5) added agent-session-start-no-cwd-v1, which cmux-tui's identify_capabilities pushes at runtime (capabilities.rs), so the bundled static manifest never lists it. tests/test_cmux_next_static_capability_runtime_only.py (release-notary, "Validate nightly push throttle") failed, and every nightly's check-daemon-capabilities.sh --static-only would refuse the build. It joins runtime_only, as #30447 did for agent-session-settings-v1. Red at 03423de: python3 tests/test_cmux_next_static_capability_runtime_only.py FAILED (failures=1) Green here: same command, OK. * l10n: compact workspace list uses this table's word for workspace (it, pl, pt-BR, uk, th) * base red: release-notary, nightly step coverage follows #30200's visual verdict steps #30200 (86fd376) removed find-nightly-next-recovery's "Read the visual gate's verdicts" and renamed visual-gate-nightly-verdict's "Fail with the gate when it holds the build" to "Record failed advisory verdict" (same script, visual-gate-fail-when-held.sh). .github/nightly-step-coverage.json kept the old names, so tests/test_nightly_step_coverage.py failed. The stale entry goes and the renamed step keeps its plumbing entry. Red at 03423de: python3 tests/test_nightly_step_coverage.py FAILED (failures=1) Green here: same command, OK. * base red: release-notary, the nightly arm64-only recorder has the cache classifier the Release step sources #30107 (2379dd9) made nightly.yml's "Build nightly app (Release)" source scripts/cmux-next/lib/compilation-cache.sh. tests/test_nightly_next_arm64_only.py runs that step in a scratch tree with recorder executables, and the tree had no such file, so the step exited 1 before xcodebuild's recorder and the test failed with CalledProcessError. The scratch tree now gets the real file, as it does scripts/lib/rust-targets.sh. Every assertion is the same. Red at 03423de: GITHUB_STEP_SUMMARY=/tmp/s python3 tests/test_nightly_next_arm64_only.py CalledProcessError Green here: same command, PASS: nightly-next arm64 only. * base red: release-notary, nightly-next identity reads a YAML-anchored job env as its value #30278 (fe4577e) turned the publish jobs' NIGHTLY_FEEDS into a YAML anchor (`&pub-feeds ${{ needs.decide.outputs.feeds }}`) and aliases (`*pub-feeds`). tests/test_nightly_next_identity.py reads job env as raw text, so test_each_app_reads_the_feed_its_publisher_writes failed on the anchor prefix. job_env now resolves an alias to its one anchor and drops an anchor name, as YAML does; the asserted values are the same. Red at 03423de: python3 tests/test_nightly_next_identity.py 7/8 passed Green here: same command, 8/8 passed.
Leo asked: “FOR OUR NIGHTLIES ARE THEY END TO END ON OUR FLEET? WE CAN'T BE RELYING ON BLACKSMITH THAT CUTS OUT.”
This stacked follow-up to #30098 gives the three credentialed NEXT publication controls a dedicated-m4pro preference when all activation conditions hold: the same
manaflow-ai/cmuxrepository,nightly-next, a push, attempt 1, andCI_NIGHTLY_ONLY_RUNNER=glaeda-nightly-only-m4pro. Existing fork, owned-pool, and measured Linux overflow routes remain in place.The existing claim gate and post-checkout helper stay ahead of release credentials. The dedicated variable must remain unset until every eligible slot is registered with the exclusive claim-capable Glaeda hook; a runner without the exclusive claim or a hook absent from the pinned allowlist fails before any release token. This PR does not change signing trust, hook pins, or host enrollment.
Validation: local
tests/test_nightly_trusted_routing.py(39),tests/test_ci_signing_owned_mac.py(23),tests/test_ci_fork_runner_routing.py(23), andtests/test_nightly_workflow_size.py(2) pass; the 490k legacy margin check remains the same named base red.Review (subagent): SHIP at 66167e2
Uses #30098 claim controls; this PR adds only the dedicated publication preference and equivalent YAML anchors that preserve parsed workflow values while keeping the file below the 508k nightly guard.
Agent session: agent session
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.Summary by cubic
Routes the three credentialed NEXT publication jobs to the dedicated
glaeda-nightly-only-m4prorunner when all activation conditions hold, so nightlies run end to end on our fleet rather than relying on Blacksmith.The dedicated path activates only on
manaflow-ai/cmux, thenightly-nextref, a push, run attempt 1, andvars.CI_NIGHTLY_ONLY_RUNNER=glaeda-nightly-only-m4pro. Forks route to GitHub-hostedubuntu-24.04instead of Blacksmith overflow. The three jobs also hold the whole Mac: the exclusive-claim gate and claim helper run after checkout, before any release credential, and the pooledowned_poolroute stays empty until hook coverage is provable.Migration
CI_NIGHTLY_ONLY_RUNNERunset until every eligible slot is registered with the exclusive claim-capable Glaeda hook; a runner or hook missing the claim fails before release credentials are read.Written for commit 66167e2. Summary will update on new commits.