Skip to content

ci(nightly): prefer proven dedicated publication mini - #30278

Merged
teamleaderleo merged 4 commits into
feat-cmux-nextfrom
lane/nightly-publication-dedicated-mini
Nov 1, 2026
Merged

teamleaderleo merged 4 commits into
feat-cmux-nextfrom
lane/nightly-publication-dedicated-mini

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

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/cmux repository, nightly-next, a push, attempt 1, and CI_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), and tests/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


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Routes the three credentialed NEXT publication jobs to the dedicated glaeda-nightly-only-m4pro runner 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, the nightly-next ref, a push, run attempt 1, and vars.CI_NIGHTLY_ONLY_RUNNER=glaeda-nightly-only-m4pro. Forks route to GitHub-hosted ubuntu-24.04 instead 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 pooled owned_pool route stays empty until hook coverage is provable.

Migration

Written for commit 66167e2. Summary will update on new commits.

View guided diff Turn on auto-fix

@cursor

cursor Bot commented Nov 1, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot 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.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread tests/test_nightly_trusted_routing.py Outdated
Comment on lines +363 to +365
self.assertEqual(evaluate(expr, {**dedicated, "github.repository": "someone/cmux",
"github.repository_owner": "someone"}),
"ubuntu-24.04")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
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")

Comment thread .github/workflows/nightly.yml Outdated
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' }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

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.

@teamleaderleo
teamleaderleo force-pushed the lane/nightly-publication-dedicated-mini branch from 1d53d8f to dc9d906 Compare November 1, 2026 06:27
Base automatically changed from lane/nightly-publish-controls to feat-cmux-next November 1, 2026 06:30
@github-actions github-actions Bot added the risk:high Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent): SHIP at 67abe05

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
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")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
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",
)

Comment thread tests/test_nightly_trusted_routing.py Outdated
Comment on lines +395 to +396
self.assertEqual(evaluate(expr, {**dedicated, "vars.CI_NIGHTLY_ONLY_RUNNER": ""}),
"blacksmith-16vcpu-ubuntu-2404")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
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:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

@teamleaderleo
teamleaderleo force-pushed the lane/nightly-publication-dedicated-mini branch from 67abe05 to 66167e2 Compare November 1, 2026 06:39
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent): SHIP at 66167e2

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (claude opus-5.5 medium): BLOCK at 66167e2

Read the full diff against feat-cmux-next: .github/workflows/nightly.yml and tests/test_nightly_trusted_routing.py.

Findings:

  • [blocking] The PR sends the three credentialed publication jobs (publish-nightly, publish-nightly-next-github, publish-nightly-next-github-names) to glaeda-nightly-only-m4pro on attempt 1 once CI_NIGHTLY_ONLY_RUNNER is set. These jobs hold the release environment and the release App key, and they gate on GLAEDA_JOB_CLAIM=exclusive (the claim-gate step and signing-runner-claim.sh). The dedicated nightly-only runners take no capacity units, so they can't give a real exclusive claim. That leaves two outcomes. If the hook doesn't grant the claim, every first-attempt publish fails at the claim gate. The error says "this run's Blacksmith job signs instead", but these jobs have no Blacksmith twin; only a manual re-run (attempt 2) reaches the pool or Blacksmith route. So the nightly stops publishing as soon as the var goes live. If the hook does grant it, the claim is false. The var is the same switch that turns on the rest of ci(nightly): route credentialed publication controls through owned Macs #30098's dedicated routing, so it can't be turned on without also triggering this. Signing and publication jobs must stay off the nightly-only label. Fix: drop the dedicated branch from &pub-runner, keep the fork/owned-pool/Linux-overflow expression, and change the new test to assert these three jobs never resolve to glaeda-nightly-only-m4pro.
  • [follow-up] Forks now get ubuntu-24.04 for these jobs instead of blacksmith-16vcpu-ubuntu-2404. This changes behavior with the var unset, but only on forks, which have no release secrets anyway. It matches the fork prefix ci(nightly): route credentialed publication controls through owned Macs #30098 uses elsewhere. Say it in the PR body, or drop it along with the fix above.
  • [follow-up] The new test has no wrong-repository case (same owner, other repo) and no wrong-ref case (for example refs/heads/main on a push). Both were carried over from the earlier receipt.
  • [follow-up] Document the dedicated-label exception (nightly-only, no capacity units, never for credentialed jobs) beside the routing, so the next change doesn't route signing there again.

Checked and fine: with the var unset, the non-fork routes resolve as before. The YAML anchors (&pub-runner, &pub-feeds, and the others) parse to the same values; the file already uses anchors. No cancel-in-progress was added (the publish job keeps cancel-in-progress: false). The file is 507571 bytes, under the 508000 guard. Each route keeps its fallback.

Follow-ups:

  • Fork route change: say it in the PR body, or revert it
  • Wrong-repository and wrong-ref test cases
  • Document the dedicated-label exclusion for credentialed jobs

@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review d317a18: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr30278 -f ref=lane/nightly-publication-dedicated-mini -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 4e81bfe; does not block

Shipped in:

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

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

  1. [P2] [follow-up] .github/workflows/nightly.yml:6247 — The advertised dedicated publication route is absent. Even with all five activation conditions satisfied, these three jobs still select Blacksmith because the expression ignores CI_NIGHTLY_ONLY_RUNNER and the picker currently emits an empty owned_pool. The new test explicitly requires this behavior. Update the PR title, description, and migration guidance to reflect the final scope; landing this head does not enable publication end to end on the fleet.

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:

  • Correct the dedicated-publication claims to match the final routing behavior.

@teamleaderleo teamleaderleo removed the risk:high Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmux-bot approves d317a18: an independent review passed this exact head (router-review receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

@github-actions github-actions Bot added the risk:high Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
lawrencecchen added a commit that referenced this pull request Nov 1, 2026
… 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.
@teamleaderleo
teamleaderleo merged commit fe4577e into feat-cmux-next Nov 1, 2026
168 of 171 checks passed
@teamleaderleo
teamleaderleo deleted the lane/nightly-publication-dedicated-mini branch November 1, 2026 09:41
lawrencecchen added a commit that referenced this pull request Nov 1, 2026
… (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.

This branch was previously deployed

1 inactive deployment
ci-routing-agent — d317a18e Deployed Nov 1, 2026 by teamleaderleo via wait for same-key tree publisher #94464
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:high Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant