{"slug": "grade-the-workspace-not-the-demo-a-bootcamp-lab-on-shared-agent-boxes", "title": "Grade the Workspace, Not the Demo: A Bootcamp Lab on Shared Agent Boxes", "summary": "A developer outlines a bootcamp lab that grades coding-agent workspace hygiene rather than demo output, requiring students to run a bug-fix task in an isolated, owner-only directory with a recorded free-tier limit and a reproducible teardown. The lab, which permits the open-source coding-agent project MonkeyCode as one runtime, fails any submission whose workspace still contains another student's files, session data, or leaked credentials, and includes a Python script that checks folder naming, .env permissions, and workspace isolation.", "body_md": "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.\n\nShared 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.\n\nYou get a tiny bug. The agent edits one function. The diff looks tidy. So why am I still unhappy?\n\nBecause 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?\n\nThat is the failure this lab exists to catch. Not a clever model. A messy box.\n\nRun 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.\n\nThe 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.\n\nOn 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.\n\nTake the product name out and the rubric still stands. One student. One workspace. One recorded limit. One teardown I can rerun.\n\nDo not touch the fixture until the folder is boring and yours.\n\n`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.\n\n```\nid=\"s17\"\nroot=\"$HOME/lab-box/$id\"\nmkdir -p \"$root/work\" \"$root/out\"\nchmod 700 \"$root\"\numask 077\nprintf 'LAB_TOKEN=dev-only\\n' > \"$root/.env\"\nchmod 600 \"$root/.env\"\ndate -u +%Y-%m-%dT%H:%M:%SZ > \"$root/limits.txt\"\nprintf '\\n# paste the published free-tier note and its URL under this line\\n' >> \"$root/limits.txt\"\nprintf 'runtime=local\\npath=%s\\n' \"$root\" > \"$root/box.txt\"\n```\n\nSave 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?\n\n```\nFix the status string in work/app.py so the fixture test passes.\nRead and write only under work/.\nDo not read the home directory.\nDo not print environment variables.\nAllowed tools: read file, edit file, run the unit check.\nStop if any path outside work/ shows up in context.\n```\n\nThe 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.\n\nI grade these in order. A later win does not repair an earlier miss.\n\n`.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.\nThis 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.\n\n``` bash\n#!/usr/bin/env python3\n\"\"\"Workspace isolation checker. Lab artifact until you run it.\"\"\"\nimport stat\nimport sys\nfrom pathlib import Path\n\ndef main() -> int:\n    root = Path(sys.argv[1]).resolve()\n    sid = sys.argv[2]\n    fails = []\n    if sid not in root.name:\n        fails.append(\"workspace folder name missing student id\")\n    env = root / \".env\"\n    if not env.is_file():\n        fails.append(\"missing .env\")\n    elif env.stat().st_mode & (\n        stat.S_IRGRP | stat.S_IROTH | stat.S_IWGRP | stat.S_IWOTH\n    ):\n        fails.append(\".env is not owner-only\")\n    for name in (\"limits.txt\", \"box.txt\", \"prompt.md\"):\n        if not (root / name).is_file():\n            fails.append(f\"missing {name}\")\n    limits_path = root / \"limits.txt\"\n    limits = (\n        limits_path.read_text(encoding=\"utf-8\", errors=\"ignore\")\n        if limits_path.is_file()\n        else \"\"\n    )\n    if \"http://\" not in limits and \"https://\" not in limits:\n        fails.append(\"limits.txt has no doc URL\")\n    enrolled = {\"s16\", \"s17\", \"s18\", \"s19\"}\n    for path in root.rglob(\"*\"):\n        if not path.is_file():\n            continue\n        text = path.read_text(encoding=\"utf-8\", errors=\"ignore\")\n        if path.name != \".env\" and \"LAB_TOKEN=\" in text:\n            fails.append(f\"token leaked into {path.name}\")\n        for other in sorted(enrolled - {sid}):\n            if other in text:\n                fails.append(f\"foreign id {other} inside {path.name}\")\n    report = root / \"out\" / \"report.txt\"\n    report.parent.mkdir(parents=True, exist_ok=True)\n    body = \"PASS\\n\" if not fails else \"FAIL\\n\" + \"\\n\".join(fails) + \"\\n\"\n    report.write_text(body, encoding=\"utf-8\")\n    print(body, end=\"\")\n    return 0 if not fails else 1\n\nif __name__ == \"__main__\":\n    raise SystemExit(main())\npython3 check_box.py \"$HOME/lab-box/s17\" s17\n```\n\nThe 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?\n\n| Question | Stay local | Use the free server option | \n|---|---|---|\n| Can you install the fixture runtime without admin help? | Yes, if your laptop policy allows it | Only if the image already has it | \n| Might a classmate share the host? | No | Assume yes until `box.txt` shows your own path | \n| Will the same path exist next week? | Your disk, your backups | Record hostname and path, then plan to rebuild | \n| Is today's published limit enough for one fixture? | Read `limits.txt` and stop if the session says otherwise | Same rule | \n| Is any file real customer data? | Still no | No | \n\nFree 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.\n\n`~/lab-box/` contains `s04` folder you used \"for reference.\"`$HOME` because \"it needed context.\"`644`, and the report helpfully echoes it.\nNotice 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.\n\n`s18` beside | Item | Points | Pass looks like | \n|---|---|---|\n| C1 boundary | 25 | Folder name has your id; no foreign id in the tree | \n| C2 limits note | 20 | Dated, with a doc URL, no invented quota | \n| C3 secrets | 20 | `.env` is mode 600; report stays clean | \n| C4 session scope | 20 | `prompt.md` names the directory and the tools | \n| C5 teardown | 15 | Script regenerates `out/report.txt` | \n| Stretch | +0 to 10 | Bonus only if the base score is already 80 or higher | \n\nPartial credit stops at the first failed checkpoint unless you can explain the miss in two sentences. Charm is not a column.\n\nSkip 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.\n\nSkip 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.\n\nThe 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.\n\nThe 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/`.\n\nIf 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.", "url": "https://wpnews.pro/news/grade-the-workspace-not-the-demo-a-bootcamp-lab-on-shared-agent-boxes", "canonical_source": "https://dev.to/hackjs_7468/grade-the-workspace-not-the-demo-a-bootcamp-lab-on-shared-agent-boxes-36n3", "published_at": "2026-10-08 07:38:55+00:00", "updated_at": "2026-10-08 07:48:28.468954+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "mlops"], "entities": ["MonkeyCode"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/grade-the-workspace-not-the-demo-a-bootcamp-lab-on-shared-agent-boxes", "markdown": "https://wpnews.pro/news/grade-the-workspace-not-the-demo-a-bootcamp-lab-on-shared-agent-boxes.md", "text": "https://wpnews.pro/news/grade-the-workspace-not-the-demo-a-bootcamp-lab-on-shared-agent-boxes.txt", "jsonld": "https://wpnews.pro/news/grade-the-workspace-not-the-demo-a-bootcamp-lab-on-shared-agent-boxes.jsonld"}}