feat(campaign): experiment-campaign loop — controller skill, worker agents, kill-rule core#18
Open
sumtopmus wants to merge 17 commits into
Open
feat(campaign): experiment-campaign loop — controller skill, worker agents, kill-rule core#18sumtopmus wants to merge 17 commits into
sumtopmus wants to merge 17 commits into
Conversation
Controller skill + worker subagents that run RL experiments, monitor W&B telemetry, early-stop bad runs (hard rules + model judgment), analyze results, design the next experiment, and continue. Interactive and autonomous modes; ledger + brain rollup; config + guarded code. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
11 tasks: kill-rule evaluator + telemetry reader + dsim campaign-status (TDD), campaign templates, controller skill + three worker agents, asset-validation test, docs, and verification. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The repo sets package=false, so there is no bare dsim console script; the campaign-status monitor tick and obs-preflight must run via python -m dsim (matching the Makefile). Also clarify obs-preflight is skipped for scratch inits. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Scaffold docs/campaigns/smoke/ (goal/ledger/frontier), a tiny real single-agent experiment (conf/experiment/smoke_canary.yaml, 200k steps, video off), realistic + force-kill rules files, and a step-by-step runbook for manual end-to-end validation of the run-campaign loop on a W&B-authed machine. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two defects surfaced by the smoke validation campaign that together made the run-campaign kill-rule loop silently inoperative on single-agent runs: 1. envs/quidditch/simple_env.py emitted info['scored'] but not info['is_success']. SB3's EvalCallback only records eval/success_rate when episode info carries 'is_success', so the campaign's objective metric was never logged. Mirror scored -> is_success. 2. core/campaign/telemetry.py fetched all keys in one run.history(keys=...) call. wandb returns ZERO rows if ANY requested key was never logged (e.g. rollout/ep_rew_mean, which these runs don't emit) or if requested metrics never co-occur at a step. That blinded every kill-rule -> vacuous kill:false. Fetch each metric key independently and merge by _step. Validated live: healthy kill:false pre-150k -> kill:true (floor_at_step + budget) once eval/success_rate data crosses the gate. Regression tests added for both; scripts/callbacks.py docstring updated (single-agent env now logs honest success rates). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Record the first (and only) smoke iteration: single-agent smoke_canary ran to 200k with eval/success_rate identically 0.0 (verdict null; n_eval_episodes=20 is noise, not a real judgement). The campaign's real value was validating the run-campaign loop end-to-end and surfacing the two monitor-path defects fixed in the preceding commit. Frontier records loop-validation status and queues the lr-bump follow-up; no iteration 2 run (smoke purpose met). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
What this adds
A Claude Code experiment-campaign loop for RL runs: a durable controller skill plus worker subagents that launch training, monitor W&B telemetry, early-stop bad runs, analyze results, design the next experiment, and continue — backed by one deterministic, unit-tested telemetry/kill-rule helper exposed as a read-only CLI command.
Implements
docs/superpowers/plans/2026-06-08-experiment-campaign.md.Components
Deterministic core (pure, unit-tested):
core/campaign/killrules.py—evaluate(rows, rules, baselines) → KillVerdict; rule typesnan/floor_at_step/collapse_vs_baseline/budget.core/campaign/telemetry.py— W&B history reader via an injectableapi_factory(tests never touch the network). Fetches each metric key independently and merges by_stepso an absent or step-disjoint metric can't zero out the fetch.CLI:
dsim campaign-status <run> [--rules f.json]— read-only telemetry + kill-rule verdict as JSON; the deterministic monitor tick. Invoked aspython -m dsim …(repo setspackage = false).Agent layer (
.claude/):run-campaigncontroller skill +experiment-analyst,experiment-monitor,experiment-coderworker agents.Scaffolding & docs:
docs/campaigns/TEMPLATE/{goal,ledger,frontier}.md, thesmokevalidation campaign (+ runbook),conf/experiment/smoke_canary.yaml, and acampaign-statusentry in the README CLI surface.Validation
Driven end-to-end on real W&B telemetry as the
smokecampaign (interactive gate → launch → healthy monitor tickkill:false→ forced abortkill:true/floor_at_step→ analyst report card → ledger/frontier written). The smoke surfaced and fixed two real monitor-path defects, each with a regression test:info['scored']but SB3'sEvalCallbackkeys oninfo['is_success'], soeval/success_rate(the campaign objective) was absent. Mirroredscored → is_successinenvs/quidditch/simple_env.py.telemetry.pyrequested a never-logged key in a singlehistory(keys=…)call; wandb returns zero rows if any requested key is absent, silently neutering every kill-rule (kill:false). Fixed with the per-key fetch + merge described above.Tests
tests/core/campaign/*,tests/dsim/test_campaign_status_cli.py,tests/test_agent_assets.py, plus regression tests for both defects (test_simple_env_is_success.py, the absent-key telemetry test).test_render_smoke.py/test_video_callback_team.pyabort on GL context creation — environmental, unrelated to this change.Notes for reviewers
success_rate ≡ 0.0at lr 5e-5 / 200k steps) — expected; the smoke validated loop mechanics, not training quality. An lr-bump follow-up is queued indocs/campaigns/smoke/frontier.md.feature/experiment-campaign; the merge intodevelopwas verified conflict-free via an in-memory trial merge.https://claude.ai/code/session_018gE4JxQZ9dQSjuZJQGcm7R
Generated by Claude Code