YAXH64 commited on
Commit
8def8a8
·
1 Parent(s): 7bc4ef6

final README

Browse files
Files changed (1) hide show
  1. README.md +140 -269
README.md CHANGED
@@ -1,4 +1,5 @@
1
  ---
 
2
  title: AI Code Review OpenEnv
3
  emoji: 🤖
4
  colorFrom: blue
@@ -6,359 +7,221 @@ colorTo: purple
6
  sdk: docker
7
  app_file: inference.py
8
  pinned: false
9
- ---
10
- # 🔍 AI Code Review — OpenEnv Environment
11
-
12
- An RL environment where an AI agent performs structured code review tasks —
13
- identifying bugs and proposing fixes across progressively harder JavaScript challenges.
14
 
15
- Built for the **Meta × Hugging Face × OpenEnv × Scaler** hackathon.
16
-
17
- ---
18
 
19
- ## 📌 Project Overview
20
 
21
- Most code review tools either flag syntax errors with a linter or generate
22
- free-form suggestions with an LLM. Neither approach is structured for
23
- reinforcement learning — there is no clear action space, no reward signal,
24
- and no way to train an agent to improve over time.
25
 
26
- **AI Code Review** frames code review as an RL problem:
27
-
28
- - The **agent** reads buggy code and must first *identify* the bug, then *fix* it
29
- - The **environment** grades both steps deterministically and returns a shaped reward
30
- - The **episode** runs three tasks of increasing difficulty, giving the agent a
31
- continuous learning signal across syntax, logic, and performance bug categories
32
-
33
- This makes it possible to train or evaluate LLM agents on code review skills in
34
- a reproducible, measurable way — without relying on human judges or expensive
35
- model-based graders.
36
 
37
  ---
38
 
39
- ## 💡 Motivation
40
 
41
- Code review is one of the highest-leverage activities in a software team.
42
- Developers spend an estimated **10–15% of their time** reviewing others' code,
43
- and studies show that poor reviews are a leading source of production bugs.
44
 
45
- Despite this, most AI coding tools are optimised for *generation*, not *review*.
46
- There are no widely-adopted RL benchmarks for teaching agents to:
 
47
 
48
- - Classify the type of bug they are looking at
49
- - Explain why the code is wrong
50
- - Produce a minimal, correct fix
51
 
52
- This environment fills that gap. It models the two-step workflow a human
53
- reviewer follows — *"what is wrong?"* then *"here is the fix"* — and rewards
54
- the agent at each step. The result is a training signal that encourages
55
- coherent reasoning, not just lucky guesses.
56
 
57
- **Real-world applications of agents trained in this environment:**
58
 
59
- - Automated PR review bots that flag and fix common bug patterns
60
- - CI/CD pipeline integration to catch issues before human review
61
- - Developer tooling that explains *why* code is wrong, not just that it is
62
- - Fine-tuning data generation for code-focused LLMs
 
 
 
 
63
 
64
  ---
65
 
66
  ## 🏗️ Environment Design
67
 
68
- The environment follows the [OpenEnv](https://github.com/meta-pytorch/OpenEnv)
69
- specification, implementing three required interfaces: `reset()`, `step()`, and
70
- the `state` property.
71
 
72
- ### Observation Space
 
 
 
 
73
 
74
- Each observation exposes the following fields:
 
 
75
 
76
- | Field | Type | Description |
77
- |--------------|-----------------|--------------------------------------------------------------|
78
- | `code` | `str` | The buggy JavaScript code to review |
79
- | `task` | `str` | Full task prompt: difficulty, category, description, phase |
80
- | `history` | `List[str]` | Log of all prior steps taken in this episode |
81
- | `task_id` | `int` | Current task index (1, 2, or 3) |
82
- | `language` | `str` | Always `"javascript"` in this environment |
83
- | `difficulty` | `str` | One of `easy`, `medium`, `hard` |
84
- | `category` | `str` | One of `syntax`, `logic`, `performance` |
85
 
86
- The `task` field changes with phase — in the `IDENTIFY` phase it instructs the
87
- agent to explain the bug; in the `FIX` phase it instructs the agent to correct it.
88
 
89
- ### Action Space
90
 
91
- Each step the agent submits one action:
 
 
 
92
 
93
- | Field | Type | Values | Description |
94
- |---------------|-------|---------------------|------------------------------------------------|
95
- | `action_type` | `str` | `identify` / `fix` | Which phase this action addresses |
96
- | `content` | `str` | Free text or code | Bug explanation (identify) or corrected code (fix) |
97
 
98
- The expected episode flow per task is:
99
 
100
  ```
101
- identify → fix → [next task] → identify → fix → ...
 
102
  ```
103
 
104
- Deviating from this order is allowed but penalised (see Reward section).
105
-
106
- ### State
107
-
108
- The `state` property returns an `EpisodeState` dataclass with episode metadata:
109
-
110
- | Field | Type | Description |
111
- |----------------------------|-------------|--------------------------------------|
112
- | `current_task_id` | `int` | ID of the task currently active |
113
- | `current_task_difficulty` | `str` | Difficulty of the current task |
114
- | `current_task_category` | `str` | Bug category of the current task |
115
- | `phase` | `str` | Current phase: `identify` or `fix` |
116
- | `step` | `int` | Total steps taken so far |
117
- | `total_reward` | `float` | Cumulative reward across the episode |
118
- | `done` | `bool` | Whether the episode has ended |
119
- | `history` | `List[str]` | Step-by-step reward log |
120
 
121
  ---
122
 
123
  ## 🧪 Tasks
124
 
125
- The environment defines three tasks covering distinct bug categories. Each task
126
- requires exactly two steps: one `identify` and one `fix`.
127
-
128
- ### Task 1 — Easy: Missing Closing Parenthesis
129
-
130
- **Category:** Syntax
131
- **Language:** JavaScript
132
 
133
  ```javascript
134
- // Buggy code
135
  function add(a, b {
136
  return a + b;
137
  }
138
 
139
- // Expected fix
140
  function add(a, b) {
141
  return a + b;
142
  }
143
  ```
144
 
145
- The function parameter list is missing a closing parenthesis `)`. This is a
146
- parse-time `SyntaxError` — no JavaScript engine will execute this code. The
147
- agent must identify that the issue is a missing parenthesis and restore it.
148
-
149
  ---
150
 
151
- ### Task 2 — Medium: Wrong Even/Odd Condition
152
-
153
- **Category:** Logic
154
- **Language:** JavaScript
155
 
156
  ```javascript
157
- // Buggy code
158
  function isEven(n) {
159
  return n % 2 === 1;
160
  }
161
 
162
- // Expected fix
163
  function isEven(n) {
164
  return n % 2 === 0;
165
  }
166
  ```
167
 
168
- The function uses `=== 1` instead of `=== 0` in the remainder check, inverting
169
- the result. It silently returns `true` for odd numbers and `false` for even ones —
170
- no crash, just wrong output. The agent must recognise this as a logic error
171
- and correct the condition.
172
-
173
  ---
174
 
175
- ### Task 3 — Hard: Inefficient Array Iteration
176
-
177
- **Category:** Performance
178
- **Language:** JavaScript
179
 
180
  ```javascript
181
- // Buggy code
182
  for (let i = 0; i < arr.length; i++) {
183
  console.log(arr[i]);
184
  }
185
 
186
- // Expected fix
187
  arr.forEach(item => {
188
  console.log(item);
189
  });
190
  ```
191
 
192
- The loop re-evaluates `arr.length` on every iteration and uses verbose
193
- index-based element access. A `forEach` approach is cleaner, avoids repeated
194
- property lookups, and is idiomatic in modern JavaScript. The agent must
195
- recognise this as a performance and style issue and propose the functional
196
- alternative.
197
-
198
  ---
199
 
200
- ## 🎯 Reward Function
201
-
202
- Rewards are **fully deterministic** — no LLM judges, no randomness. The grader
203
- uses keyword matching for identify and code comparison for fix.
204
 
205
- > **Deterministic grading ensures reproducibility across runs, which is critical
206
- > for fair agent evaluation and leaderboard consistency.**
207
 
208
- All rewards are strictly clamped to **[0.0, 1.0]** before being returned from
209
- `step()`, ensuring full compliance with the OpenEnv specification.
210
 
211
- ### Identify Phase
212
 
213
- Smooth partial scoring — every matched keyword contributes proportionally
214
- with no hard threshold. A single correct keyword earns partial credit.
215
 
216
  ```
217
- score = matched_keywords / total_keywords (capped at 1.0)
218
  ```
219
 
220
- Keywords use **whole-word boundary matching** — `"paren"` does not match inside
221
- `"parenthesis"`, preventing accidental substring hits. This is fully deterministic
222
- with no randomness involved.
223
-
224
- ### Fix Phase
225
-
226
- Fix scoring runs four tiers in order:
227
-
228
- | Tier | Condition | Score |
229
- |------|----------------------------------|-------|
230
- | 1 | Exact match (after stripping) | 1.0 |
231
- | 2 | Whitespace-normalised match | 0.9 |
232
- | 3 | ≥ 80% token overlap | 0.6 |
233
- | 4 | ≥ 50% token overlap | 0.3 |
234
- | — | Below 50% overlap | 0.0 |
235
-
236
- The grader automatically extracts code from fenced ` ``` ` blocks if present,
237
- so agents that wrap their fix in a code block are handled correctly.
238
-
239
- ### Identify Bonus
240
-
241
- When an agent scores `≥ 0.4` on the identify step, a **+0.1 bonus** is applied
242
- to the fix reward before clamping. This incentivises the agent to reason through
243
- the bug before jumping to a fix — coherent two-step reasoning earns more than
244
- lucky fixes.
245
-
246
- > **The two-phase (identify → fix) structure mirrors real developer workflows
247
- > and encourages reasoning before action, reducing reward hacking.**
248
-
249
- The identify bonus is always applied before the final clamp, so the maximum
250
- fix reward remains **1.0** (not 1.1). No reward ever exceeds 1.0.
251
-
252
- ### Behaviour for Edge Cases
253
-
254
- | Situation | Reward |
255
- |------------------------------------------|---------------------|
256
- | Skipped identify, fix submitted directly | fix score × 0.5 |
257
- | Repeated `identify` in fix phase | 0.0 |
258
- | Unknown `action_type` | 0.0 |
259
 
260
- ### Reward Summary
261
 
262
- | Step | Max Reward |
263
- |--------------------|------------|
264
- | Identify (perfect) | 1.0 |
265
- | Fix (exact + bonus)| 1.0 (clamped from 1.1) |
266
- | Full episode | ~6.0 (3 tasks × identify + fix) |
 
 
267
 
268
  ---
269
 
270
- ## ⚙️ Setup Instructions
271
-
272
- ### Prerequisites
273
 
274
- - [Docker](https://docs.docker.com/get-docker/) installed and running
275
- - A Hugging Face token (`HF_TOKEN`) with inference access
276
 
277
- ### Environment Variables
278
 
279
- | Variable | Required | Default | Description |
280
- |---------------|----------|--------------------------------|--------------------------------------|
281
- | `HF_TOKEN` | ✅ Yes | — | HF token used as the API key |
282
- | `API_BASE_URL`| ❌ No | `https://api.openai.com/v1` | OpenAI-compatible inference endpoint |
283
- | `MODEL_NAME` | ❌ No | `gpt-4.1-mini` | Model name for the LLM client |
284
 
285
- ### Build the Docker Image
 
 
 
 
286
 
287
- ```bash
288
- docker build -t ai-code-review-env:latest .
289
- ```
290
 
291
- ### Run the Environment
292
 
293
- ```bash
294
- docker run --rm \
295
- -e HF_TOKEN=your_hf_token_here \
296
- ai-code-review-env:latest
297
- ```
298
 
299
- ### Run with a Custom Endpoint
300
 
301
- To point at a Hugging Face Inference Endpoint or any OpenAI-compatible API:
302
 
303
- ```bash
304
- docker run --rm \
305
- -e HF_TOKEN=your_hf_token_here \
306
- -e API_BASE_URL=https://api-inference.huggingface.co/v1 \
307
- -e MODEL_NAME=meta-llama/Llama-3.1-8B-Instruct \
308
- ai-code-review-env:latest
309
  ```
310
-
311
- ### Run Locally (without Docker)
312
-
313
- ```bash
314
- pip install -r requirements.txt
315
-
316
- export HF_TOKEN=your_hf_token_here
317
- export API_BASE_URL=https://api.openai.com/v1
318
- export MODEL_NAME=gpt-4.1-mini
319
-
320
- python inference.py
321
  ```
322
 
323
  ---
324
 
325
- ## 🤖 How `inference.py` Works
326
-
327
- `inference.py` is the hackathon-required entry point. It wires the LLM agent
328
- to the environment and runs a full episode.
329
-
330
- **Flow:**
331
 
332
  ```
333
- 1. Read env vars (HF_TOKEN, API_BASE_URL, MODEL_NAME)
334
- 2. Initialise OpenAI client + CodeReviewEnvironment
335
- 3. Print [START] log line
336
- 4. env.reset() → get first observation
337
- 5. Loop:
338
- a. Build identify prompt from observation
339
- b. Call LLM → get explanation
340
- c. env.step(Action("identify", explanation)) → log [STEP]
341
- d. Build fix prompt (includes prior identify response for context)
342
- e. Call LLM → get corrected code
343
- f. env.step(Action("fix", corrected_code)) → log [STEP]
344
- g. If done → break
345
- 6. Print [END] log line
346
  ```
347
 
348
- **Design choices:**
349
-
350
- - `temperature=0.0` for deterministic LLM output
351
- - The fix prompt includes the agent's own identify response as context,
352
- encouraging coherent two-step reasoning
353
- - All LLM call failures are caught per-step — the episode continues and
354
- the error is recorded in the `[STEP]` log without crashing
355
- - `[END]` is always printed, even if an unrecoverable error occurs
356
-
357
  ---
358
 
359
- ## 📊 Baseline Results
360
-
361
- Below is example output from a full episode using `gpt-4.1-mini`:
362
 
363
  ```
364
  [START] task=code-review env=ai-code-review-env model=gpt-4.1-mini
@@ -371,23 +234,24 @@ Below is example output from a full episode using `gpt-4.1-mini`:
371
  [END] success=true steps=6 rewards=0.71,1.00,0.60,1.00,0.45,1.00
372
  ```
373
 
374
- ### Score Breakdown
375
 
376
- | Task | Difficulty | Identify | Fix | Notes |
377
- |------|-------------|----------|------|----------------------------------------------|
378
- | 1 | Easy | 0.71 | 1.00 | Correct fix + identify bonus (clamped to 1.0)|
379
- | 2 | Medium | 0.60 | 1.00 | Correct fix + identify bonus (clamped to 1.0)|
380
- | 3 | Hard | 0.45 | 1.00 | Correct fix + identify bonus (clamped to 1.0)|
381
 
382
- **Total reward: 4.76 / ~6.0 max**
 
 
 
383
 
384
- The model consistently identifies the correct fix across all three tasks.
385
- Identify scores decrease with difficulty — the performance task has the most
386
- keywords to cover (`performance`, `optimize`, `forEach`, `iteration`, etc.),
387
- so partial credit is lower even when the agent's explanation is qualitatively correct.
388
 
389
- > **The environment is designed to run within strict resource constraints (2 vCPU,
390
- > 8GB RAM), ensuring fast evaluation cycles and scalability across many agent runs.**
 
 
 
 
 
391
 
392
  ---
393
 
@@ -395,21 +259,28 @@ so partial credit is lower even when the agent's explanation is qualitatively co
395
 
396
  ```
397
  code-review-env/
398
- ├── inference.py # Entry point (hackathon required, at root)
399
- ├── openenv.yaml # Environment manifest
400
- ├── Dockerfile # Container definition
401
- ├── requirements.txt # Minimal dependencies
402
- ├── README.md # This file
403
  └── env/
404
- ├── __init__.py
405
- ├── models.py # Observation, Action, EpisodeState dataclasses
406
- ├── tasks.py # 3 task definitions (easy → medium → hard)
407
- ├── grader.py # Deterministic identify + fix graders
408
- └── environment.py # Core environment: reset(), step(), state
409
  ```
410
 
411
  ---
412
 
 
 
 
 
 
 
 
 
 
 
 
 
413
  ## 📄 License
414
 
415
- MIT License. Built for the Meta × Hugging Face × OpenEnv × Scaler hackathon.
 
 
1
  ---
2
+
3
  title: AI Code Review OpenEnv
4
  emoji: 🤖
5
  colorFrom: blue
 
7
  sdk: docker
8
  app_file: inference.py
9
  pinned: false
10
+ -------------
 
 
 
 
11
 
12
+ # 🔍 AI Code Review — OpenEnv RL Environment
 
 
13
 
14
+ > Train and evaluate AI agents on real-world code review using structured RL environments.
15
 
16
+ A **real-world reinforcement learning environment** where AI agents learn structured code review:
17
+ **identify bugs → reason about them → fix them correctly**.
 
 
18
 
19
+ Built for the **Meta × Hugging Face × OpenEnv × Scaler Hackathon 2026 (Round 1 Submission)**.
 
 
 
 
 
 
 
 
 
20
 
21
  ---
22
 
23
+ ## 🚀 Why This Matters
24
 
25
+ Most AI coding tools are built for *generation*, not *review*.
26
+ But in real-world software engineering, that's the wrong priority:
 
27
 
28
+ * Code review is the last line of defence against production bugs
29
+ * Bugs often slip through because reviewers miss the *why*, not the *what*
30
+ * Understanding why code is wrong matters more than just patching it
31
 
32
+ 👉 This environment turns **code review into a measurable, learnable RL problem** — with structure, reward signal, and reproducibility built in from the ground up.
 
 
33
 
34
+ ---
 
 
 
35
 
36
+ ## 🧠 What Makes This Environment Strong
37
 
38
+ | Property | Detail |
39
+ | ------------------------- | ------------------------------------------------------ |
40
+ | ✅ Real-world task | Code review, not a toy problem |
41
+ | ✅ Two-phase reasoning | Agent must identify before it can fix |
42
+ | ✅ Deterministic grading | No LLM judge, no randomness |
43
+ | ✅ Reward shaping | Partial progress is rewarded at every step |
44
+ | ✅ Reproducible evaluation | Same input always produces same score |
45
+ | ✅ Spec compliant | Fully compatible with OpenEnv + hackathon requirements |
46
 
47
  ---
48
 
49
  ## 🏗️ Environment Design
50
 
51
+ Implements the full OpenEnv interface — three methods, no more:
 
 
52
 
53
+ ```python
54
+ obs = env.reset() # Start a new episode
55
+ result = env.step(action) # Execute one action → {observation, reward, done, info}
56
+ metadata = env.state # Inspect episode state
57
+ ```
58
 
59
+ ---
60
+
61
+ ## 📥 Observation Space
62
 
63
+ | Field | Description |
64
+ | ------------ | ----------------------------------- |
65
+ | `code` | Buggy JavaScript code to review |
66
+ | `task` | Task description + current phase |
67
+ | `history` | Log of all prior steps this episode |
68
+ | `task_id` | Task number (1, 2, or 3) |
69
+ | `language` | `javascript` |
70
+ | `difficulty` | `easy` / `medium` / `hard` |
71
+ | `category` | `syntax` / `logic` / `performance` |
72
 
73
+ ---
 
74
 
75
+ ## 🎮 Action Space
76
 
77
+ | Field | Values |
78
+ | ------------- | ----------------------------- |
79
+ | `action_type` | `"identify"` or `"fix"` |
80
+ | `content` | Free-text explanation or code |
81
 
82
+ ---
 
 
 
83
 
84
+ ## 🔁 Episode Flow
85
 
86
  ```
87
+ identify → fix → identify → fix → identify → fix
88
+ task 1 task 2 task 3
89
  ```
90
 
91
+ One episode covers all 3 tasks in order.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  ---
94
 
95
  ## 🧪 Tasks
96
 
97
+ ### 🟢 Task 1 — Syntax Error (Easy)
 
 
 
 
 
 
98
 
99
  ```javascript
100
+ // buggy
101
  function add(a, b {
102
  return a + b;
103
  }
104
 
105
+ // fixed
106
  function add(a, b) {
107
  return a + b;
108
  }
109
  ```
110
 
 
 
 
 
111
  ---
112
 
113
+ ### 🟡 Task 2 — Logic Bug (Medium)
 
 
 
114
 
115
  ```javascript
116
+ // buggy
117
  function isEven(n) {
118
  return n % 2 === 1;
119
  }
120
 
121
+ // fixed
122
  function isEven(n) {
123
  return n % 2 === 0;
124
  }
125
  ```
126
 
 
 
 
 
 
127
  ---
128
 
129
+ ### 🔴 Task 3 — Performance Issue (Hard)
 
 
 
130
 
131
  ```javascript
132
+ // buggy
133
  for (let i = 0; i < arr.length; i++) {
134
  console.log(arr[i]);
135
  }
136
 
137
+ // fixed
138
  arr.forEach(item => {
139
  console.log(item);
140
  });
141
  ```
142
 
 
 
 
 
 
 
143
  ---
144
 
145
+ ## 🎯 Reward System
 
 
 
146
 
147
+ ### ✔ Deterministic & Reproducible
 
148
 
149
+ No randomness. Same input → same score.
 
150
 
151
+ ---
152
 
153
+ ### 🧩 Identify Reward
 
154
 
155
  ```
156
+ score = matched_keywords / total_keywords
157
  ```
158
 
159
+ ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
 
161
+ ### 🛠️ Fix Reward
162
 
163
+ | Condition | Score |
164
+ | --------------------- | ----- |
165
+ | Exact match | 1.0 |
166
+ | Whitespace-normalised | 0.9 |
167
+ | ≥ 80% token overlap | 0.6 |
168
+ | ≥ 50% token overlap | 0.3 |
169
+ | Below 50% | 0.0 |
170
 
171
  ---
172
 
173
+ ### 🎁 Identify Bonus
 
 
174
 
175
+ +0.1 bonus if identify ≥ 0.4
176
+ (final reward clamped to 1.0)
177
 
178
+ ---
179
 
180
+ ### ⚠️ Edge Case Handling
 
 
 
 
181
 
182
+ | Situation | Effect |
183
+ | ---------------------- | --------------- |
184
+ | Skipped identify phase | fix score × 0.5 |
185
+ | Unknown `action_type` | 0.0 |
186
+ | Repeated identify | 0.0 |
187
 
188
+ ---
 
 
189
 
190
+ ### 📊 Max Reward Per Episode
191
 
192
+ | Scope | Max Reward |
193
+ | ------------ | ---------- |
194
+ | Per step | 1.0 |
195
+ | Per task | ~2.0 |
196
+ | Full episode | ~6.0 |
197
 
198
+ ---
199
 
200
+ ## 🤖 Inference Pipeline
201
 
 
 
 
 
 
 
202
  ```
203
+ 1. Read HF_TOKEN, API_BASE_URL, MODEL_NAME
204
+ 2. Initialise OpenAI client + environment
205
+ 3. Reset environment
206
+ 4. Identify → Fix for each task
207
+ 5. Log results in required format
 
 
 
 
 
 
208
  ```
209
 
210
  ---
211
 
212
+ ## 🧾 Log Format (Strict)
 
 
 
 
 
213
 
214
  ```
215
+ [START]
216
+ [STEP]
217
+ [STEP]
218
+ ...
219
+ [END]
 
 
 
 
 
 
 
 
220
  ```
221
 
 
 
 
 
 
 
 
 
 
222
  ---
223
 
224
+ ## 📊 Example Output
 
 
225
 
226
  ```
227
  [START] task=code-review env=ai-code-review-env model=gpt-4.1-mini
 
234
  [END] success=true steps=6 rewards=0.71,1.00,0.60,1.00,0.45,1.00
235
  ```
236
 
237
+ ---
238
 
239
+ ## 📌 Why This Stands Out
 
 
 
 
240
 
241
+ * Real-world problem (not synthetic)
242
+ * Deterministic evaluation (fair + reproducible)
243
+ * Reward shaping (better learning signal)
244
+ * Two-phase reasoning (prevents shortcutting)
245
 
246
+ ---
 
 
 
247
 
248
+ ## ⚙️ Setup
249
+
250
+ ```bash
251
+ pip install -r requirements.txt
252
+ export HF_TOKEN=your_token
253
+ python inference.py
254
+ ```
255
 
256
  ---
257
 
 
259
 
260
  ```
261
  code-review-env/
262
+ ├── inference.py
263
+ ├── openenv.yaml
264
+ ├── Dockerfile
265
+ ├── README.md
 
266
  └── env/
 
 
 
 
 
267
  ```
268
 
269
  ---
270
 
271
+ ## 🏆 Evaluation Alignment
272
+
273
+ | Criteria | Covered |
274
+ | ------------------ | ------- |
275
+ | Real-world utility | ✅ |
276
+ | Task design | ✅ |
277
+ | Grader quality | ✅ |
278
+ | Environment design | ✅ |
279
+ | Spec compliance | ✅ |
280
+
281
+ ---
282
+
283
  ## 📄 License
284
 
285
+ MIT License
286
+ Built for Meta × Hugging Face × OpenEnv × Scaler Hackathon 2026