virustechhacks/adaptive-project-management
<div align="center">
Adaptive Project Manager Environment
An OpenEnv reinforcement learning environment that simulates software project management under uncertainty.
   
Quick Start · How It Works · Tasks · Reward System · API Reference · Documentation
</div>
Why This Environment Exists
Software projects fail for predictable, repeatable reasons: critical work discovered late, overloaded teams, shifting priorities, cascading delays. Existing tools track status. They do not decide what to do next.
This environment frames project management as a sequential decision problem and asks:
Given the current project state, what should the manager do today?
The agent must balance five competing objectives every step: delivery speed, budget, team health, scope, and stakeholder satisfaction. No single heuristic solves all states. The best action depends on what has already happened, what is likely to happen next, and how today's choice changes tomorrow's options.
This makes it a natural fit for reinforcement learning: repeated decisions, delayed consequences, multiple conflicting goals, and changing conditions.
Full problem analysis: Problem.md
How It Works
One environment step simulates one project day. The orchestrator executes in deterministic order:
Scheduled Events → Task Assignments → Work Execution → Burnout Update → Budget Deduction → Reward Calculation → Termination Check┌──────────────────┐ ┌──────────────────┐ ┌──────────────────────┐
│ Agent / Policy │ ──► │ OpenEnv API │ ──► │ Env Orchestrator │
│ chooses action │ │ reset / step │ │ deterministic order │
└────────┬─────────┘ └────────┬─────────┘ └──────────┬───────────┘
│ │ │
│ ▼ ▼
│ ┌─────────────────┐ ┌───────────────┐
│ │ ProjectState │ ◄─────► │ Task Engine │
│ │ (truth source) │ │ dependencies │
│ │ │ │ effort calc │
│ │ • day, budget │ └───────────────┘
│ │ • tasks [ ] │ ┌───────────────┐
│ │ • employees [ ]│ ◄─────► │ Employee Eng │
│ │ • risks [ ] │ │ burnout/skills│
│ └────────┬────────┘ └───────────────┘
│ │ ┌───────────────┐
│ └────────────────► │ Reward Engine │
│ │ + Grader │
▼ └───────────────┘
┌──────────────────┐
│ Observation Out │ ◄── (obs, reward, done)
└──────────────────┘Key properties:
- Fixed scenario seeds ensure deterministic, reproducible evaluation
- All state transitions follow explicit equations (no hidden randomness)
- Same action sequence always produces the same outcome
Full system design: Architecture.md
Tasks
Three difficulty levels, each modeling a real software delivery scenario. Difficulty scales through longer horizons, more dependencies, and overlapping disruptions — not just more tasks.
What Each Level Tests
- Easy: Can the agent handle basic dependency-aware scheduling? Start T1 and T2 in parallel to unblock T3. A strong heuristic solves this.
- Medium: Can the agent reason about tradeoffs? Long-running tasks (6-day payment integration) must start early. A key employee goes unavailable mid-project. Greedy shortest-task-first policies miss the deadline.
- Hard: Can the agent plan across overlapping crises? Six disruptions interact across 22 days: early overtime helps short-term throughput but triggers the day-15 burnout check, which halves QA productivity and threatens the release. A production incident on day 7 demands immediate attention while the key backend developer is already unavailable. On day 18, the DevOps lead gets poached. Local heuristics fail.
Baseline Scores
The hard task baseline of 0.30 demonstrates the massive complexity of overlapping crises, technical debt, and delayed consequences. The gap between current frontier models (~0.30) and the theoretical ceiling provides a huge optimization curve for RL and Agentic solvers.
Full task specifications: Tasks.md
Core Mechanics
Team Burnout
Every employee tracks a burnout value in [0, 1]. Each day of work increases burnout. Rest decreases it.
burnout += 0.15 × workload − 0.05 × rest
if overtime: burnout += 0.10
if burnout > 0.8: productivity × 0.5This creates a fundamental tradeoff: pushing the team harder today risks lower output tomorrow. Overtime on day 3 can cause a productivity collapse on day 10. The agent must learn to manage team health across the full episode, not just maximize immediate throughput.
Skill Matching and Coordination
Each task requires a specific skill. Assigning an exact-match employee yields 1.0 productivity. Partial match yields 0.5. No match yields 0.0.
Multiple employees can work on the same task, but coordination overhead applies:
productivity = Σ(skill_scores) × 1 / (1 + 0.15 × (n_assigned − 1))This forces a planning decision: concentrate people on one blocker, or distribute them across multiple tasks?
Scheduled Events
Medium and hard tasks include deterministic disruptions at specific days:
Events are seeded, so they occur on the same day every run. The agent must learn to anticipate and mitigate them.
Contingency Actions
Beyond task assignments, the agent can take strategic actions with long-term consequences:
These are high-impact choices. Using overtime early may prevent a delay, but the accumulated burnout can trigger cascade failures later. Hiring a contractor saves time but consumes budget that affects the final score.
Reward System
The reward has two components: dense step rewards that shape daily behavior, and a terminal score that evaluates the overall project outcome. This prevents both sparse-reward failure (agent cannot learn) and reward hacking (agent games local signals while ignoring final outcome).
Step Reward
R = 5·Ccrit + 2·Cnorm + 1.5·Dblocked + 0.5·Umatch − 0.25 − 3·Overdue − Pburnout − PreassignAnti-exploit measures: The reward explicitly penalizes task-switching loops (+0.5 assignment reward is small enough that the −0.5 reassignment penalty makes farming impossible), idle employees when work exists (−2.0), and repeated useless assignments (−2.0).
Terminal Score (Grader)
At episode end, the grader computes a normalized score in [0.0, 1.0]:
Score = 0.35 × Completion + 0.25 × Deadline + 0.15 × Budget + 0.15 × TeamHealth + 0.10 × SatisfactionEach component is normalized to [0, 1]. The weights reflect real PM priorities: delivery matters most, but burning the team or blowing the budget produces a lower score even with 100% task completion.
The step reward and terminal grader are intentionally aligned: optimizing step rewards should also optimize the final score. This prevents the common failure where an agent learns to maximize intermediate rewards while producing poor final outcomes.
Full reward rationale, edge cases, and anti-hacking analysis: Reward_Design.md
API Reference
Action Space
class ProjectAction(BaseModel):
assignments: List[Assignment] # Employee-to-task assignments
reprioritized_tasks: List[str] # Tasks to escalate to critical
contingency_action: Literal[
"none",
"request_overtime",
"hire_contractor",
"defer_low_priority_work"
]
class Assignment(BaseModel):
employee_id: str
task_id: strObservation Space
class ProjectObservation(BaseModel):
day: int # Current project day
days_remaining: int # Days until deadline
budget_remaining: float # Remaining budget
project_completion: float # Overall completion (0.0–1.0)
blocked_tasks: int # Tasks that cannot proceed
overdue_tasks: int # Tasks past internal deadline
average_burnout: float # Team health (0.0–1.0)
tasks: List[TaskState] # Full task details
employees: List[EmployeeState] # Full employee details
risks: List[RiskState] # Active risks
message: str # Recent events
done: bool # Episode complete
reward: float # Step rewardState Models
class TaskState(BaseModel):
id: str
priority: Literal["low", "medium", "high", "critical"]
status: Literal["todo", "in_progress", "blocked", "done"]
required_skill: str
remaining_effort: float # Continuous: tracks long-running work
dependencies: List[str]
is_critical_path: bool
class EmployeeState(BaseModel):
id: str
skills: List[str]
available: bool
assigned_task_id: Optional[str]
workload: float # 0.0–1.0
burnout: float # 0.0–1.0, >0.8 halves productivityComplete state/action design rationale: State_Actions.md
Quick Start
Prerequisites
git clone <repo-url> && cd adaptive-project-manager
uv sync # or: pip install -e .Run Inference
cp .env.example .env # Set HF_TOKEN, API_BASE_URL, MODEL_NAME
uv run python inference.pyRequired environment variables:
HF_TOKEN=your_hugging_face_token
API_BASE_URL=https://router.huggingface.co/v1
MODEL_NAME=Qwen/Qwen2.5-72B-InstructOutput format:
[START] task=easy
[STEP] day=2 action={"assignments":[{"e":"emp_1","t":"task_1"}],"contingency":"none"} reward=0.50
[END] task=easy score=0.96
[START] task=medium
...
[END] task=hard score=0.66
[SUMMARY] average_score=0.76Run Locally (No Docker)
from server.hustlers_env_environment import AdaptiveProjectManagerEnv
from models import ProjectAction, Assignment
env = AdaptiveProjectManagerEnv()
obs = env.reset(task_id="easy")
while not obs.done:
action = ProjectAction(
assignments=[Assignment(employee_id="emp_1", task_id="task_1")],
contingency_action="none"
)
obs = env.step(action)
print(f"Day {obs.day}: {obs.project_completion:.0%} complete, burnout={obs.average_burnout:.2f}")Docker
docker build -t adaptive-project-manager:latest .
docker run -p 8000:8000 adaptive-project-manager:latestDeploy
openenv push --repo-id your-username/adaptive-project-managerTesting
uv run python -m pytest test_main.py -v # Unit tests
uv run python test_enhancements.py # Feature testsAll graders verified for bound compliance: scores always in [0.0, 1.0]. Deterministic seeds ensure reproducible results across runs.
Full test results and performance data: RESULTS.md
Project Structure
├── models.py # Pydantic models (Action, Observation, State)
├── client.py # Docker-based environment client
├── inference.py # LLM baseline inference script
├── openenv.yaml # OpenEnv spec configuration
├── pyproject.toml # Dependencies (uv-managed)
├── Dockerfile # Container definition
├── server/
│ ├── app.py # FastAPI application
│ ├── hustlers_env_environment.py # Core environment logic (27KB)
│ └── custom_gradio_ui.py # Interactive dashboard
├── tasks/
│ ├── easy.py # Web Launch scenario (seed 42)
│ ├── medium.py # MVP Crunch scenario (seed 1337)
│ └── hard.py # Enterprise Migration scenario (seed 9001)
└── graders/
├── base_grader.py # Shared multi-dimensional scoring
├── easy_grader.py # Easy task grader
├── medium_grader.py # Medium task grader (event-aware)
└── hard_grader.py # Hard task grader (crisis-aware)OpenEnv Spec Compliance
Documentation Map
Evaluation Alignment
<div align="center">
Built for the OpenEnv Hackathon
Problem · Architecture · Rewards · Tasks · Results
</div>
