feat(orchestrator): add composable curricula - #3261
Open
hallerite wants to merge 5 commits into
Open
Conversation
This was referenced Aug 13, 2026
hallerite
force-pushed
the
chore/rename-rollout-source
branch
from
August 13, 2026 13:32
5f687c4 to
40d35cc
Compare
hallerite
force-pushed
the
chore/rename-rollout-source
branch
from
August 13, 2026 23:28
c1053d5 to
7fa7dbe
Compare
hallerite
marked this pull request as ready for review
August 13, 2026 23:51
hallerite
force-pushed
the
chore/rename-rollout-source
branch
from
August 13, 2026 23:52
d3eb3cf to
127ff9a
Compare
hallerite
marked this pull request as draft
August 13, 2026 23:52
hallerite
marked this pull request as ready for review
August 14, 2026 00:33
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f6571a2. Configure here.
hallerite
marked this pull request as draft
August 14, 2026 00:41
hallerite
marked this pull request as ready for review
August 14, 2026 11:43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Adds one checkpointed
Curriculumper training source, composed from two user-space primitives:TaskSampler, which chooses tasks and observes every finalized resultAdmissionGates, which all evaluate every result; a group trains only when every gate admits itThe orchestrator still owns environment mixing, rollout groups, batch backfill, and checkpoint timing. Admission runs after samples and algorithm credit are built. Rejected groups remain observable in the
alltrace stream but never occupy a training-batch slot, so the dispatcher naturally samples another task. The sampler observes rejected results before the gates run.Discarded work is tracked independently in the active batch unit. A batch-equivalent with no admitted progress emits a no-progress window, and the existing ten-window guard fails loudly instead of allowing an all-rejected run to spin forever.
Sampler and gate state is namespaced in the curriculum checkpoint, and their metrics are exposed under
curriculum/<env>/sampler/andcurriculum/<env>/gate/<name>/. The default sampler preserves epoch-shuffled finite iteration, sequential infinite iteration, and compatibility with existing source-position checkpoints.The public surface lives in
prime_rl.orchestrator.curriculum, organized like the existingalgopackage: interfaces and composition inbase.py, with each concrete sampler or gate in its own module.Two small implementations are included and can be used together:
DifficultyPoolsdispatches every finite task once, then samples scored tasks through named reward bands using each task's latest valid group-mean reward. Failed tasks cannot monopolize warm-up, and the final band is a catch-all.AdvantageRangeGaterejects groups whose trainable-token advantages all fall inside an inclusive range;[0, 0]implements zero-advantage rejection.This removes the separate rollout filter pipeline and its config slots. Task identity comes from
Task.keyinverifiers==0.3.1.dev33; synthetic error and cancellation traces retain the original key so finalized results remain attributable.Validation
uv sync --all-extrasuv run ruff format ...uv run ruff check src/prime_rl/orchestrator ...uv run pytest tests/unit/orchestrator --ignore=tests/unit/orchestrator/test_qwen3_vl_e2e.py -q— 79 passedtomllibgit diff --checkNote
Medium Risk
Training batch composition and task scheduling now depend on curriculum admission and sampler state; removing gibberish/repetition filtering changes degenerate-rollout handling unless users add custom gates.
Overview
Replaces the orchestrator pre/post-batch rollout filter pipeline with a per training-source
Curriculum: one optionalTaskSamplerplus namedAdmissionGates (AND-combined). Admission runs after tokenization and algorithm scoring; rejected groups stay inalltraces but do not enterpending_batch, and the dispatcher keeps sampling until the batch fills.TrainSourcenow hosts aCurriculumper env (weighted env mixing unchanged) instead of epoch/cursor task cycling; sampler/gate state checkpoints under each env’s curriculum.TrainSinkcallson_resultfor admission, tracksis_admitted/no_progress, and can emit empty batches when enough work is discarded without progress (existing consecutive-empty guard updated). Built-ins:DifficultyPoolsandAdvantageRangeGate([0,0]≈ old zero-advantage filter).Example configs migrate zero-advantage to
curriculum.gates.zero_advantagewithAdvantageRangeGate. Gibberish/repetition filters and their config types are removed (not reimplemented as gates). Metrics/docs shift fromis_filtered/ filter rates tois_admittedandcurriculum/<env>/…. Bumpsverifiers[harbor]to0.3.1.dev33for stableTask.keyon curriculum results.Reviewed by Cursor Bugbot for commit f6571a2. Bugbot is set up for automated code reviews on this repo. Configure here.