Skip to content

feat(run): record the resolved scheduler in run receipts - #543

Merged
solomonneas merged 1 commit into
mainfrom
t3code/review-brigade-dag-router
Jul 26, 2026
Merged

feat(run): record the resolved scheduler in run receipts#543
solomonneas merged 1 commit into
mainfrom
t3code/review-brigade-dag-router

Conversation

@solomonneas

Copy link
Copy Markdown
Collaborator

Summary

The DAG ready-queue scheduler (#447) became the roster default via limits.scheduler (#472), but run.json never recorded which scheduler actually ran. The DAG-to-waves fallback printed only to stderr, so a receipt could not tell a real DAG dispatch from a silent degrade to waves.

run.json now carries:

"scheduler": {"requested": "dag", "used": "dag", "fallback_reason": null}
  • requested is written at record_run_start, so a run that dies before dispatch says what it was asked to do rather than claiming a mode it never reached. record_run_termination merges into the existing payload, so the field survives startup failures.
  • used / fallback_reason are filled by a new on_scheduler_resolved callback out of run_transport.dispatch, following the existing on_stage_start / on_interrupt callback pattern. used stays null until dispatch resolves it.
  • Scheduler precedence (--scheduler, then roster limits.scheduler, then waves) now lives in one helper, cli/run.py::_resolved_scheduler.

Why this was blocking

An audit of the 25 most recent runs in the maintainer's checkout found that of the 20 with a parsed plan, only 2 were DAG-eligible, and only 1 of those ran after the roster flip. The other 18 were single-worker (--worker) runs whose assignments carry no covers, so _dag_placement_error returns "plan not fully covered" and they degrade to waves every time.

That degrade is correct behavior, but it means any DAG-vs-waves comparison must use multi-seat runs only. Counting all runs understates DAG engagement to near zero. Without the scheduler field there was no way to establish that from receipts, which left the route-recomposition decision (docs/proposals/route-recomposition.md) undecidable.

Blast radius

Established with GraphTrail before the first edit:

  • _dag_placement_error <- run_transport.dispatch:625 <- aboyeur.dispatch:1196. Two hops, contained.
  • _run_payload <- record_run_start:2128 and the aboyeur.run._payload closure:2315, which aboyeur.run calls at 11 sites. Injecting the field in the closure covers all 11 at once rather than editing each.
  • Downstream run.json consumers (release_cmd/candidate.py, release_cmd/commands.py) read existing keys only; the new key is additive.

Tests

Four new tests, written red-first (failing receipt 20260726-065836-work-verify-e65eb5, exit 1, before implementation):

  • test_scheduler_resolution_reported_when_dag_engages
  • test_scheduler_resolution_reports_wave_fallback
  • test_scheduler_resolution_reports_missing_route_dependencies
  • test_run_cli_records_requested_scheduler_before_dispatch

Verification

brigade work verify run --target . --command "./scripts/verify" --capture brigade-work

Receipt 20260726-070342-work-verify-edd4dd: completed, exit 0, 505.3s, 4218 passed / 3 skipped, coverage 82.67% (floor 78%). Tree fingerprint 54dc40a635bcac6411bca7b88fa1f54a078c79c97cfa8de4bbf995860c5f8fd5.

Smoke against the branch source wrote "scheduler": {"requested": "dag", "used": null, "fallback_reason": null} to a dry-run run.json (used null is correct: a dry run never dispatches).

Caveat: that green predates #542. ./scripts/verify currently fails on this machine with 6 failures in tests/test_repos_sweep_health_cmd.py, which reproduce on a clean checkout of main and are unrelated to this diff. The gate should be re-run once #542 is resolved.

Follow-ups

The DAG ready-queue scheduler became the roster default via limits.scheduler,
but run.json never recorded which scheduler actually ran. The DAG-to-waves
fallback printed only to stderr, so a receipt could not distinguish a real DAG
dispatch from a silent degrade to waves, and no DAG-vs-waves comparison was
possible from run history.

run.json now carries a scheduler block:

    "scheduler": {"requested": "dag", "used": "dag", "fallback_reason": null}

- requested is written at record_run_start, so a run that dies before dispatch
  reports what it was asked to do instead of claiming a mode it never reached.
- used and fallback_reason are filled by a new on_scheduler_resolved callback
  out of run_transport.dispatch, following the existing on_stage_start and
  on_interrupt callback pattern. used stays null until dispatch resolves it.
- record_run_termination merges into the existing payload rather than
  overwriting, so the field survives startup failures.
- Scheduler precedence (--scheduler, then roster limits.scheduler, then waves)
  now lives in one helper, cli/run.py::_resolved_scheduler, instead of being
  spelled out separately at each call site.

Co-authored-by: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • coderabbit-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: escoffier-labs/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5b637a6e-e555-4096-93ae-c14a5e08e827

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch t3code/review-brigade-dag-router

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@solomonneas solomonneas self-assigned this Jul 26, 2026
@solomonneas
solomonneas merged commit 37feb6a into main Jul 26, 2026
28 checks passed
@solomonneas
solomonneas deleted the t3code/review-brigade-dag-router branch July 26, 2026 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant