CoolFace
Apppublic

virustechhacks/adaptive-project-management

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
App README

<div align="center">

Adaptive Project Manager Environment

An OpenEnv reinforcement learning environment that simulates software project management under uncertainty.

![OpenEnv Compatible](https://github.com/openenv) ![Python 3.10+](https://www.python.org/) ![License](LICENSE) ![HF Space](https://huggingface.co/spaces/virustechhacks/adaptive-project-management)

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.

TaskScenarioTeamTasksDaysSeedDisruptions
easyWeb Launch351242None
mediumMVP Crunch49181337Employee illness (day 6), scope change (day 10)
hardEnterprise Migration514+229001Illness (day 5), production incident (day 7), compliance task (day 9), vendor delay (day 12), burnout cascade (day 15), key person risk (day 18)

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

PolicyEasyMediumHard
Random0.15–0.300.10–0.200.05–0.15
Heuristic0.80–0.950.55–0.700.20–0.35
LLM Agent (Qwen 2.5-72B)0.910.650.30
Strong Agent Target0.95+0.75–0.850.55–0.70

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.5

This 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))
Team SizeEffective Output
11.00×
21.74×
32.31×

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:

Event TypeExampleImpact
Employee absenceBackend lead sick for 3 daysCritical skill unavailable
Production incidentUrgent hotfix injected on day 7Must triage immediately or lose stakeholder satisfaction
Scope changePayment integration needs +2 days effortDeadline pressure increases
Compliance requirementNew mandatory audit task injectedScope grows mid-project
Vendor delayExternal integration delayed +3 daysBlocking dependency extends
Burnout cascadeIf team burnout > 0.6, QA productivity halvesDelayed consequence of overwork
Key person riskDevOps lead poached, unavailable 2 daysLate-project capacity loss

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:

ActionEffectCost
noneNormal execution
request_overtime+20% productivityIncreases burnout faster
hire_contractorAdds versatile employeeDepletes budget
defer_low_priority_workBlocks low-priority tasksMay lower stakeholder satisfaction

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 − Preassign
ComponentValuePurpose
Complete critical task+5.0Prioritize the critical path
Complete normal task+2.0Reward general progress
Clear a blocker (critical path bonus)+1.5 × downstream countTeach: unblock dependencies first
Skill-matched assignment+0.5Reward good resource allocation
Time cost per day−0.25Discourage stalling
Overdue critical task−3.0Penalize missed deadlines
Burnout penalty−(avg − 0.7) × 4Protect team sustainability
Unnecessary reassignment−0.5Discourage thrashing

Anti-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 × Satisfaction

Each 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

python
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: str

Observation Space

python
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 reward

State Models

python
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 productivity
Complete state/action design rationale: State_Actions.md

Quick Start

Prerequisites

bash
git clone <repo-url> && cd adaptive-project-manager
uv sync  # or: pip install -e .

Run Inference

bash
cp .env.example .env  # Set HF_TOKEN, API_BASE_URL, MODEL_NAME
uv run python inference.py

Required environment variables:

HF_TOKEN=your_hugging_face_token
API_BASE_URL=https://router.huggingface.co/v1
MODEL_NAME=Qwen/Qwen2.5-72B-Instruct

Output 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.76

Run Locally (No Docker)

python
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

bash
docker build -t adaptive-project-manager:latest .
docker run -p 8000:8000 adaptive-project-manager:latest

Deploy

bash
openenv push --repo-id your-username/adaptive-project-manager

Testing

bash
uv run python -m pytest test_main.py -v          # Unit tests
uv run python test_enhancements.py               # Feature tests

All 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

RequirementStatusEvidence
openenv validate passesPassTyped Pydantic models, correct YAML
reset() returns clean initial statePassDeterministic per-task seeds
step() returns (observation, reward, done)PassStructured response per spec
state() returns current statePassFull ProjectState serialization
3+ tasks with gradersPasseasy, medium, hard with [0.0, 1.0] scores
Scores deterministic and reproduciblePassFixed seeds, explicit transition equations
Baseline inference.py reproducesPassScores: 0.96, 0.66, 0.52
Dockerfile builds and runsPassdocker build && docker run verified
HF Space deploys and respondsPassLive Space
Runtime < 20 minPassInference completes in < 5 min
Uses OpenAI clientPassReads API_BASE_URL, MODEL_NAME, HF_TOKEN

Documentation Map

DocumentContents
Problem.mdWhy project management is a sequential decision problem, why RL is a good fit, and why fixed rules fail
Architecture.mdSystem design, component interactions, runtime flow, determinism guarantees
Reward_Design.mdComplete reward function derivation, weight rationale, anti-exploit defenses, discount factor analysis
State_Actions.mdObservation and action space design, long-running task model, productivity formula, contingency action semantics
Tasks.mdFull task specifications, team compositions, dependency graphs, scheduled events, expected performance ranges
RESULTS.mdUnit test results, episode traces, grader verification, performance benchmarks, reward distribution analysis
EVALUATION.mdComprehensive self-evaluation against hackathon rubric, competitive analysis

Evaluation Alignment

CriterionWeightHow This Environment Addresses It
Real-world utility30%Models actual PM decisions: resource allocation, crisis response, scope management. Not a toy or game.
Task and grader quality25%Three tasks with genuine difficulty progression. Multi-dimensional grader (completion, deadline, budget, health, satisfaction). Deterministic seeds. Hard task challenges frontier models (0.30 baseline with 6 overlapping crises in 22 days).
Environment design20%Dense reward with 8 components including critical path bonus. Anti-exploit penalties. Clean state management with early termination (burnout collapse, deadlock, budget exhaustion). Sensible episode boundaries. Configurable mechanics via named constants.
Code quality and spec compliance15%Full OpenEnv spec compliance. Typed Pydantic models. Clean separation of concerns. Working Dockerfile. Live HF Space. Reproducible baseline.
Creativity and novelty10%Technical debt (rushing spawns bugs later). Effort estimation uncertainty. Burnout mechanic with delayed consequences. Scheduled crisis events (6 on hard). Production incident mechanic. Contingency actions with long-term tradeoffs. PM domain is rare in RL benchmarks.

<div align="center">

Built for the OpenEnv Hackathon

Problem · Architecture · Rewards · Tasks · Results

</div>