title: OpsGuard
emoji: π‘οΈ
colorFrom: gray
colorTo: indigo
sdk: docker
pinned: true
app_port: 8000
base_path: /web
tags:
- openenv
- openenv-hackathon
- long-horizon
- self-improvement
- rl
- agent
OpsGuard β Train a 3B Model to Run On-Call for an Open-Source Repo
Can a 3B model triage 60 issues in a row β while a co-evolved adversary tries to slip spam past it?
OpsGuard is an OpenEnv environment that trains LLM maintainers against synthetic spammers across 6 difficulty tiers, scoring against the real maintainer decisions of huggingface/peft. No simulator. Real GitHub data. Real ground truth.
Hero numbers β rule-based baselines on real GH data
375 real issues, 1911 comments. Each scenario mixes real issues + synthetic spam at scenario-defined rate. Mean over 3 seeds:
| Scenario (steps Γ spam-rate) | random | label_everything | close_everything | keyword_triager |
|---|---|---|---|---|
| E0 quiet day (30 Γ 0%) | +3.26 | +0.50 | -1.60 | +5.70 |
| E1 release week (60 Γ 10%) | -3.70 | -3.34 | -5.24 | +12.71 |
| E2 spam wave (120 Γ 40%) | -13.14 | -9.76 | +0.74 | +23.32 |
| E3 coordinated attack (200 Γ 55%) | -14.15 | -23.12 | +12.18 | +40.58 |
Spread grows monotonically: 7 β 18 β 36 β 64 reward points as horizon and adversary intensity rise. Greedy strategies fail at long horizons. No shortcut wins.
Trained 3B agent (post-GRPO): numbers populate after training run lands. Live updates pushed to this README + Hub repo sai1906/opsguard-grpo.
The Story β 4 Acts
Act 1 β The Naive Triager. Baseline (label_everything) blindly tags every issue bug. On E2, half the queue is synthetic spam β none caught. Reward: -9.76.
Act 2 β The Keyword Spotter. Hand-coded rules detect spam tokens, route by content keyword, request info on thin reports. Same E2 scenario: +23.32. Spam recall jumps 0% β 77%.
Act 3 β The Adversary Learns. A second 3B model is DPO-trained as a spammer, mining the maintainer's misses. It paraphrases real issue titles, fabricates urgency, mimics trusted-contributor voice. Keyword spotter's spam recall starts dropping back toward 50% on harder tiers.
Act 4 β The Co-evolved Maintainer. The maintainer is GRPO-trained on rollouts against the trained adversary. By round 3, it learns to weigh hidden contributor reputation, query history before deciding, and resist self_contradiction-style appeals. Final hero numbers populate post-training.
What's in the box
opsguard/
βββ models.py # 9 ActionTypes + Pydantic Action/Observation
βββ server/
β βββ opsguard_environment.py # OpenEnv Environment subclass; reset/step/state
β βββ app.py # FastAPI + WebSocket via openenv.core.create_app
β βββ Dockerfile # Multi-stage uv build, ghcr.io/meta-pytorch/openenv-base
βββ world/
β βββ db.py # SQLite query helpers (RepoDB, IssueRow, Contributor)
β βββ scenarios.py # E0_quiet_day β E5_hostile_fork_war (30β500 step budgets)
β βββ adversary.py # 5 spam patterns Γ 5 tiers (scripted)
β βββ trainable_adversary.py # LoRA spammer (round-2 co-evolution); template fallback
β βββ grader.py # Composable rubric + multiplicative terminal
β βββ curriculum.py # Mastery-based tier unlock
βββ eval/
β βββ policies.py # 5 baselines: random, label_everything, close_everything, keyword_triager, memory_aware
β βββ harness.py # Rollout + aggregate + markdown summary
βββ scripts/
β βββ pull_gh.py # GH REST API issue/PR/comment puller
β βββ ingest_to_sqlite.py # JSONL β SQLite, derives truth_action
β βββ build_sft_traces.py # Roll rule-based policies, emit (prompt, completion) JSONL
β βββ system_prompt.py # SYSTEM_PROMPT, format_observation, parse_action
β βββ sft_warmstart.py # Unsloth 4-bit + LoRA SFT (1 epoch)
β βββ train_grpo.py # TRL OpenEnv GRPO trainer (vLLM colocate optional)
β βββ train_grpo_colab.ipynb # Self-contained Colab notebook
β βββ make_plots.py # Reward / spam-recall plots
βββ tests/ # Smoke tests (env loop + train integration), all green
βββ data/repo.db # 375 real issues + 1911 comments from huggingface/peft
βββ openenv.yaml # OpenEnv v1 spec
Hackathon themes hit
- T2 long-horizon β episodes 30 β 500 steps; multi-issue queues; agent must process backlog while resisting 60-issue spam waves
- T4 self-improvement β co-evolved adversary (trainable spammer LoRA) + mastery-driven curriculum (E0 β E5 unlocks on rolling reward, kube-sre-gym pattern)
- T3 world modeling touch β hidden contributor reputation drives reward but is never exposed to the agent. Agent infers trust from public stats (PR count, account age) β env penalizes mis-judgement.
Action space (9 actions, single per step)
label Β· close_spam Β· request_info Β· link_duplicate Β· assign Β· comment Β· merge_pr Β· query_history Β· wait
JSON contract:
{"action_type":"label","target_issue_id":12345,"label":"bug","reasoning":"..."}
Reward (composable rubric, hard to game)
Per the OpenEnv hackathon hint "composable rubrics > monolithic scoring", OpsGuard splits reward into 7 components fired conditionally:
| Component | Fires when | Sign |
|---|---|---|
action_match |
agent's action == maintainer's recorded action | +1.0 (correct), -0.5 (wrong), +0.4 (partial) |
label_overlap |
Jaccard between predicted & true label sets | +0..0.4 |
spam_resistance |
close_spam on synthetic spam |
+0.8 |
| engaged with spam (label/merge/assign) | -0.7 | |
reputation_alignment |
closed spam on low-rep author / labeled trusted-author content | Β±0.2 |
info_request |
first request on under-described issue / redundant | +0.15 / -0.15 |
repeat_action_penalty |
same action on same issue within 5 steps | -0.15 |
workflow_efficiency |
per-step cost | -0.02 |
terminal: queue_completion Γ spam_recall_gate |
end of episode | -1..1, multiplicative |
The terminal is multiplicative on purpose β a policy that hits queue completion but ignores spam is gated to 0. Greedy strategies fail.
Try it yourself (3 paths)
1. Run baseline eval (CPU only, ~2 min):
git clone https://huggingface.co/spaces/sai1906/opsguard
cd opsguard
pip install -e .
python scripts/run_baseline_eval.py --out eval_outputs/baseline
cat eval_outputs/baseline/summary.md
2. Run env locally:
python -m server.app # β http://localhost:8000
curl http://localhost:8000/state
3. Train + GRPO (Colab T4 free OR HF Jobs A100 ~1h):
# Open scripts/train_grpo_colab.ipynb in Colab β Run All
# OR via HF Jobs:
hf jobs uv run --flavor a100-large \
--with "trl,unsloth,openenv-core,peft,bitsandbytes,vllm,datasets" \
--secrets HF_TOKEN \
-- python scripts/train_grpo.py \
--model unsloth/Qwen2.5-7B-Instruct-bnb-4bit \
--hub-repo sai1906/opsguard-grpo \
--num-steps 200
Live links
- HF Space (this env): https://huggingface.co/spaces/sai1906/opsguard
- Colab demo: scripts/train_grpo_colab.ipynb
- Trained LoRA: https://huggingface.co/sai1906/opsguard-grpo (populates after training)
- Data source:
huggingface/peftβ 375 issues, 1911 comments, 6-month window
Why it matters
Open-source maintainers spend 30β50% of triage time on duplicates, urgency-fabrications, and low-info noise. A 3B model that catches 80% of synthetic spam at 95% precision and routes the rest to the right label is a real productivity win β and it's a problem nobody has trained for in OpenEnv before.
References
- OpenEnv (PyTorch + Meta, 2026) β https://github.com/meta-pytorch/OpenEnv
- TRL OpenEnv integration β https://huggingface.co/docs/trl/en/openenv
- AgentGym-RL ScalingInter-RL (Sep 2025, arXiv 2509.08755) β curriculum design
- kube-sre-gym (SF OpenEnv 1st place, Mar 2026) β mastery curriculum + adversarial designer pattern
- Multi-Agent Evolve (arXiv 2510.23595) β co-evolution recipe (Proposer/Solver/Judge)
- AgentLAB long-horizon attacks (arXiv 2602.16901) β adversarial maintenance pattern catalog
Architecture (textual)
ββββββββββββββββββββββββββ
β GitHub REST API β
β (peft, 6-month pull) β
ββββββββββββ¬ββββββββββββββ
β pull_gh.py
βΌ
ββββββββββββββββββββββββββ
β data/repo.db (SQLite) β
β 375 issues, 1911 cmts β
ββββββββββββ¬ββββββββββββββ
β
ββββββββββββββββββββββΌββββββββββββββββββββββ
βΌ βΌ βΌ
ββββββββββββββββ βββββββββββββββββββ ββββββββββββββββββββ
β Adversary β β Curriculum β β Composable β
β - 5 patterns β β - Mastery β β Rubric β
β - 5 tiers β β - E0βE5 unlock β β - 7 components β
β - LoRA-able β β β β - Multipl. term β
ββββββββ¬ββββββββ ββββββββββ¬βββββββββ ββββββββββ¬ββββββββββ
β β β
ββββββββββββββββββββββΌββββββββββββββββββββββ
βΌ
ββββββββββββββββββββββββββ
β OpsGuardEnvironment β
β (OpenEnv subclass) β
β reset / step / state β
ββββββββββββ¬ββββββββββββββ
β FastAPI + WS
βΌ
ββββββββββββββββββββββββββ
β TRL GRPOTrainer β
β Qwen2.5-7B + LoRA β
β (vLLM colocate) β
ββββββββββββββββββββββββββ
License
BSD-3 (matching OpenEnv).

