Skip to content

ci(cmux-next): the macOS cascade and the other pickers skip a Blacksmith label that started nothing - #28515

Merged
teamleaderleo merged 2 commits into
feat-cmux-nextfrom
dep-fleet/cascade-dead-label
Oct 30, 2026
Merged

teamleaderleo merged 2 commits into
feat-cmux-nextfrom
dep-fleet/cascade-dead-label

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

What was wrong

#28480 (main) and #28484 (feat-cmux-next) added the dead-label rule (simple_pool_picker.blacksmith_dead(): nothing running on a label and no job started on it in the hour before the snapshot; a truncated snapshot proves nothing) to the DEV daily picker and nightly_sign_runner.py. The cmux-next macOS cascade (next_macos_cascade.py) still judged Blacksmith labels by the oldest-wait stall rule alone. So once blacksmith-12vcpu-macos-26's queue was cleared, its five slots read as free, and the cascade sent jobs, overflow and the bot's retry_runner to a label that had started nothing for about a day (2026-10-30).

What changed

One wrapper, simple_pool_picker.dead_macos_26(), built on #28484's blacksmith_dead(), is now read by every picker on this branch. When every label shows dead it returns nothing, because with no label showing life the snapshot gives nothing to choose between. Pickers changed:

  • next_macos_cascade.py: Seen.dead carries the dead labels from the fresh snapshot, from a stale reservation reading, or from a snapshot only old enough to show dead labels (stale_seen(), up to the six-hour evidence window). A dead label:

    • is stalled whatever its queue says, so it gets no slot and is not the retry_runner;
    • counts as full for a feed's compile (fresh_stalled);
    • is a dead 6 vCPU, which takes no overflow even when the owned route is a dead end, since dead_end() no longer waives it.

    With no fresh counts, a feed's compile no longer takes a 6 vCPU label that the older snapshot shows dead.

  • nightly_sign_runner.pick(): with no fresh snapshot it skipped nothing. It now skips a dead variable label. dev_landing_place.py's overflow (OVERFLOW_LABEL, 12 vCPU) and nightly_build_runner.py use this pick. dead() now delegates to the cascade instead of keeping its own copy.

  • nightly_build_runner.blacksmith_route(): a label a stale snapshot shows dead is no alternative to the excluded one.

  • simple_pool_picker.state_from() (ci.yml's picker on this branch): a dead macOS 26 label has no free slot.

Nothing changes when there is no start evidence: no label_started map (an older janitor), a truncated listing, a snapshot older than six hours, or every label dead.

The main side (ci.yml's simple_pool_picker.state_from() there) is #28516.

Tests

New regression tests, each run against the old scripts first. All 12 fail there (6 failures and 6 errors) and pass here:

  • tests/test_ci_next_macos_cascade.py DeadLabel (5)
  • tests/test_nightly_sign_runner.py test_an_unverified_pick_skips_a_dead_variable_label
  • tests/test_nightly_build_runner.py DeadLabel
  • tests/test_dev_landing_place.py test_the_overflow_skips_a_dead_label_a_stale_snapshot_shows
  • tests/test_ci_simple_pool_picker.py test_a_dead_macos_26_label_with_its_queue_cleared_has_no_free_slot

Every suite that imports these pickers passes locally (19 files, including test_cmux_next_checks_workflow.py, test_ci_side_lane_placement.py, test_ci_pr_runner_pool.py and test_ci_runs_on_fallback.py).

Risk: placement only. It acts only on positive start evidence from a complete, recent snapshot, and the worst wrong call keeps a job on the label that last showed life.

Overlap: #28249 and #28391 (open, same owner lane family) add a separate label_full_or_dead adapter fed by bs_health and gates. This PR does not touch that adapter. The two compose: each only adds labels to stall.

🤖 Generated with Claude Code
Agent session: agent session

teamleaderleo and others added 2 commits October 30, 2026 20:11
…ith label that started nothing

The cascade read only the oldest-wait stall rule, so a dead label whose queue was cleared counted its slots
free and took jobs, overflow and the retry runner (2026-10-30: blacksmith-12vcpu-macos-26 started nothing for
about a day). It now reads simple_pool_picker.blacksmith_dead() (cmux#28484) through one wrapper,
simple_pool_picker.dead_macos_26(), which nightly_sign_runner.dead() and the ci.yml picker share:

- next_macos_cascade: a dead label is stalled (no slot, no retry_runner), a feed's compile counts it full
  (fresh_stalled), a dead 6 vCPU takes no overflow even beside a dead-end owned route, and a snapshot too old
  for counts still keeps a feed's compile off a dead 6 vCPU.
- nightly_sign_runner.pick(): an unverified pick skips a dead variable label. dev_landing_place.py's
  overflow (OVERFLOW_LABEL, 12 vCPU) and nightly_build_runner.py read this pick.
- nightly_build_runner.blacksmith_route(): a stale snapshot's dead label is no alternative to the excluded one.
- simple_pool_picker.state_from(): a dead macOS 26 label has no free slot.

With every label dead, a truncated listing, an older janitor or a snapshot past six hours, nothing changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-0b4091cd6a9b72e19edf
…dule copy

nightly_build_runner's tests patch sys.modules' nightly_sign_runner; a fresh load() there broke them when
the suites ran in one process.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-0b4091cd6a9b72e19edf
@github-actions

Copy link
Copy Markdown
Contributor

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

Review 03c8b08: 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=pr28515 -f ref=dep-fleet/cascade-dead-label -f platform=macos -f backend_mode=local

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

@github-actions github-actions Bot added the risk:high Risk tier (docs/ci/risk-tiers.md) label Oct 30, 2026
@teamleaderleo
teamleaderleo merged commit 638ca7c into feat-cmux-next Oct 30, 2026
163 of 175 checks passed
@teamleaderleo
teamleaderleo deleted the dep-fleet/cascade-dead-label branch October 30, 2026 20:36
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 03c8b08b Deployed Oct 30, 2026 by teamleaderleo via cmux-tui tree preflight #84919
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