# Grade the Workspace, Not the Demo: A Bootcamp Lab on Shared Agent Boxes

> Source: <https://dev.to/hackjs_7468/grade-the-workspace-not-the-demo-a-bootcamp-lab-on-shared-agent-boxes-36n3>
> Published: 2026-10-08 07:38:55+00:00

A green demo is not a pass. If another student's files, notes, or session crumbs are still in your agent workspace, I grade the lab a zero.

Shared boxes feel efficient. One class server, one agent login, twelve people "just trying a fix." That is also how prompts leak and caches lie. This lab grades the handoff, not the screenshot.

You get a tiny bug. The agent edits one function. The diff looks tidy. So why am I still unhappy?

Because I cannot see whose shell you borrowed. I cannot see which checkout the agent read. And if that shared server was rebuilt at lunch, can you stand the workspace up again without opening a classmate's history?

That is the failure this lab exists to catch. Not a clever model. A messy box.

Run the task on your laptop, or on a shared class server. One allowed runtime is MonkeyCode, an open-source coding-agent project. Disclosure: This article was prepared as part of MonkeyCode's product outreach.

The lab brief I was given says two options exist: free model access, and a free server option. I am not going to print a token count, a model list, a machine size, or a promise that the offer stays up. Those details move, and a stale number in a student write-up is worse than no number.

On lab day you open the current project docs, copy the published limit into `limits.txt`, and date that file. If a chat, a slide, or this article disagrees with the docs, the docs win. An invented quota is a zero.

Take the product name out and the rubric still stands. One student. One workspace. One recorded limit. One teardown I can rerun.

Do not touch the fixture until the folder is boring and yours.

`s17`.`~/lab-box/s17/`.` work/`. Not your home directory.` 600`. `LAB_TOKEN=dev-only` is enough. No real keys. Ever.`limits.txt` from the docs you opened. Timestamp, URL, and one sentence on what is actually offered today.`box.txt`. Local runs say `local` plus the absolute path. Free-server runs record hostname, username, and path.

```
id="s17"
root="$HOME/lab-box/$id"
mkdir -p "$root/work" "$root/out"
chmod 700 "$root"
umask 077
printf 'LAB_TOKEN=dev-only\n' > "$root/.env"
chmod 600 "$root/.env"
date -u +%Y-%m-%dT%H:%M:%SZ > "$root/limits.txt"
printf '\n# paste the published free-tier note and its URL under this line\n' >> "$root/limits.txt"
printf 'runtime=local\npath=%s\n' "$root" > "$root/box.txt"
```

Save this as `prompt.md`. If your prompt is a paragraph of vibes, I cannot grade the scope checkpoint. Would you accept a test with no assertion?

```
Fix the status string in work/app.py so the fixture test passes.
Read and write only under work/.
Do not read the home directory.
Do not print environment variables.
Allowed tools: read file, edit file, run the unit check.
Stop if any path outside work/ shows up in context.
```

The fixture itself should be dull. A function returns `"ok"` when the test wants `"ready"`. You are not shipping a product. You are proving the box was yours.

I grade these in order. A later win does not repair an earlier miss.

`.env` is owner-only. The diff and the report do not contain `LAB_TOKEN` or anything that looks like a real key.`prompt.md` names the directory and the tools. If you allowed network, you named the host.`out/` and regenerate the report with the script. A screenshot is not a report.
This script is a lab artifact. It is not a benchmark, and I am not claiming a timing, a pass rate, or a result from any particular machine. Run it on your tree. If it fails, fix the workspace. Do not comment out the check.

``` bash
#!/usr/bin/env python3
"""Workspace isolation checker. Lab artifact until you run it."""
import stat
import sys
from pathlib import Path

def main() -> int:
    root = Path(sys.argv[1]).resolve()
    sid = sys.argv[2]
    fails = []
    if sid not in root.name:
        fails.append("workspace folder name missing student id")
    env = root / ".env"
    if not env.is_file():
        fails.append("missing .env")
    elif env.stat().st_mode & (
        stat.S_IRGRP | stat.S_IROTH | stat.S_IWGRP | stat.S_IWOTH
    ):
        fails.append(".env is not owner-only")
    for name in ("limits.txt", "box.txt", "prompt.md"):
        if not (root / name).is_file():
            fails.append(f"missing {name}")
    limits_path = root / "limits.txt"
    limits = (
        limits_path.read_text(encoding="utf-8", errors="ignore")
        if limits_path.is_file()
        else ""
    )
    if "http://" not in limits and "https://" not in limits:
        fails.append("limits.txt has no doc URL")
    enrolled = {"s16", "s17", "s18", "s19"}
    for path in root.rglob("*"):
        if not path.is_file():
            continue
        text = path.read_text(encoding="utf-8", errors="ignore")
        if path.name != ".env" and "LAB_TOKEN=" in text:
            fails.append(f"token leaked into {path.name}")
        for other in sorted(enrolled - {sid}):
            if other in text:
                fails.append(f"foreign id {other} inside {path.name}")
    report = root / "out" / "report.txt"
    report.parent.mkdir(parents=True, exist_ok=True)
    body = "PASS\n" if not fails else "FAIL\n" + "\n".join(fails) + "\n"
    report.write_text(body, encoding="utf-8")
    print(body, end="")
    return 0 if not fails else 1

if __name__ == "__main__":
    raise SystemExit(main())
python3 check_box.py "$HOME/lab-box/s17" s17
```

The enrolled-id set is a teaching stub. Replace it with the handles actually in your section. A checker that only knows your own id will smile at a copied tree. Would you trust that smile?

| Question | Stay local | Use the free server option | 
|---|---|---|
| Can you install the fixture runtime without admin help? | Yes, if your laptop policy allows it | Only if the image already has it | 
| Might a classmate share the host? | No | Assume yes until `box.txt` shows your own path | 
| Will the same path exist next week? | Your disk, your backups | Record hostname and path, then plan to rebuild | 
| Is today's published limit enough for one fixture? | Read `limits.txt` and stop if the session says otherwise | Same rule | 
| Is any file real customer data? | Still no | No | 

Free access is a teaching convenience. It is not a capacity plan. If the session stops because the published limit is exhausted, write that in the report and shrink the fixture. Opening a second account to dodge the cap is a zero. It is also how a class drains a shared pool.

`~/lab-box/` contains `s04` folder you used "for reference."`$HOME` because "it needed context."`644`, and the report helpfully echoes it.
Notice what is not on that list. I do not fail you for a short diff. I do not fail you for staying local. I fail you for a boundary I cannot check.

`s18` beside | Item | Points | Pass looks like | 
|---|---|---|
| C1 boundary | 25 | Folder name has your id; no foreign id in the tree | 
| C2 limits note | 20 | Dated, with a doc URL, no invented quota | 
| C3 secrets | 20 | `.env` is mode 600; report stays clean | 
| C4 session scope | 20 | `prompt.md` names the directory and the tools | 
| C5 teardown | 15 | Script regenerates `out/report.txt` | 
| Stretch | +0 to 10 | Bonus only if the base score is already 80 or higher | 

Partial credit stops at the first failed checkpoint unless you can explain the miss in two sentences. Charm is not a column.

Skip it on a production fleet, a client repo, or any tree with live credentials. The fixture is fake on purpose. Skip it if your program bans third-party agents. Keep the same rubric and point the prompt at a local script.

Skip it if you need a capacity number for a budget meeting. I did not measure throughput, and a free tier is the wrong spreadsheet. Also skip the free server option if today's docs say the offer is paused, region-locked, or waitlisted. An article is not an entitlement.

The checker is crude by design. It will not catch a renamed copy of a classmate's notes, a secret split across two files, or a process still running after you delete the folder. Treat a PASS as "the obvious misses are gone," not as a security review.

The model did not make the workspace safe. You did, or you did not. Write the boundary down. Point at today's docs for whatever free model access or free server option you actually used. Leave a report I can regenerate after I delete `out/`.

If you want a place to confirm those two options before lab, read the current MonkeyCode project docs, copy only what they publish into `limits.txt`, and run one boring bug. Then show me the report.
