Lab 1
Read-only Lab specification
Lab specification
Lab 1 — Terminal, Git, and CI Bootstrap
Assigned: Tuesday, August 25 · Due: before Thursday, September 3
Prerequisites: None (this is the setup lab).
Prepares for: All subsequent labs and projects. The Claude Code configuration, Spacebar installation, and CI pipeline you create here are the foundation everything else builds on.
Estimated time: 105–150 minutes with agentic tools (setup: ~30 min; exploration: ~30 min; CI: ~30 min; client connect: ~20–30 min; reflection: ~15 min).
Grading: Pass/fail.
Overview
You will set up your development environment from scratch, get Spacebar running locally, configure Claude Code pointed at the course LiteLLM proxy, bootstrap a CI pipeline that runs on every push, and connect a real chat client to prove the server does what it claims. The goal is not just to check boxes — it is to have a working baseline that you fully understand and can explain.
By the end you will have: a running Spacebar server, a working Claude Code installation routed through the course proxy, an auto-generated CLAUDE.md, a CI workflow that lights up green on every push, and a channel with real messages posted through a connected client.
Repository platform
Staff provisions a private, per-group repository containing the pinned Spacebar checkout, hosted on Gitea and managed through Agent P, the course portal. Gitea is a Git host with a GitHub-like workflow: you will use branches, issues, Pull Requests, and repository checks in much the same way, but your course repository and links are on Gitea, reached through Agent P. Use the repository URL and pinned commit or tag Agent P gives you; do not clone an unpinned public upstream copy. If the staff instance exposes CI through a separate provider, use the checks page linked from the Gitea repository.
Before you can clone anything, you need an SSH key registered with Agent P — see "SSH Key Setup and Repository Access" below.
Lab System Prompt
Before starting, save [AGENTS.md](AGENTS.md) as your CLAUDE.md (or paste it as a system prompt). It configures the agent to produce structured, verifiable artifacts for every lab this semester, not just this one — you only need to set it up once.
Platform Setup: Get to an Ubuntu 22.04 Terminal
Everything in this course — every lab, every project, every command anyone will ever debug with you — assumes an Ubuntu 22.04 terminal. Neither macOS Terminal nor Windows PowerShell is that, directly, so step zero is getting a real Ubuntu 22.04 environment running and learning to open a terminal into it. Do the section for your host OS; skip the other one.
Once you're in — for the rest of this lab, and every lab this semester — run every command in your Ubuntu terminal, not in a native macOS or Windows shell.
macOS — OrbStack
- Install OrbStack:
brew install --cask orbstack(No Homebrew? Download the installer directly from [orbstack.dev](https://orbstack.dev) instead.) Launch OrbStack once from your Applications folder — first launch asks for a couple of macOS permissions (networking, in particular); allow them.
- Create an Ubuntu 22.04 machine from your Mac's Terminal app (this one command, only, runs outside Ubuntu — everything after it runs inside):
orb create ubuntu:jammy spacebar-dev (jammy is Ubuntu 22.04's release codename.)
- Open a shell inside it:
orb -m spacebar-dev You should see your prompt change to something like you@spacebar-dev. That's Ubuntu 22.04, not macOS — confirm with cat /etc/os-release.
OrbStack machines run systemd by default — no extra configuration needed for the systemctl commands used later in this lab (PostgreSQL, in Part A step 3).
- Install VS Code on macOS if you don't already have it — [code.visualstudio.com](https://code.visualstudio.com), or
brew install --cask visual-studio-code.
- Install the Remote - SSH extension: click the Extensions icon in the left sidebar (four squares), search "Remote - SSH", click Install on the one published by Microsoft.
- Open the Command Palette (
Cmd+Shift+P), type "Remote-SSH: Connect to Host", and select or typespacebar-dev@orb— OrbStack registers this hostname for you automatically once the machine exists. A new window opens; the first connection takes a minute while VS Code installs a small server component inside Ubuntu.
- Confirm you're actually editing files inside Ubuntu, not on macOS: the bottom-left corner of the window should show a green
><SSH: spacebar-devindicator. Editing files from the macOS side and expecting Ubuntu-side tools (git, npm, Claude Code) to see the changes is a common source of confusion — this indicator is how you check you're not doing that.
- Once connected,
File → Open Folderand point it at your home directory (~) — you'll clonespacebarinto it in Part A, and can reopen the folder afterward to see it appear.
- Open a terminal for Claude Code: with this Remote-SSH window open, use
Terminal → New Terminal(or `Ctrl+`). Because the window itself is the Remote-SSH session, this terminal opens inside Ubuntu automatically — it is not macOS Terminal in disguise. If you want to double check, runcat /etc/os-releasein it; you should see the same Ubuntu 22.04 output as step 3. Use this integrated terminal for every command for the rest of this lab, includingnpm install,git, and — once you install it in Part B —claude` itself. You do not need a separate Terminal.app window at any point.
Windows 11 — WSL2
- Open PowerShell as Administrator (right-click the Start menu → "Terminal (Admin)" or search for PowerShell, right-click, "Run as administrator").
- Install WSL2 with Ubuntu 22.04 specifically.
wsl --install -d Ubuntu-22.04This enables the Windows features WSL2 needs and installs Ubuntu 22.04 in one step. Restart Windows if prompted.
- After restarting, launch "Ubuntu 22.04 LTS" from the Start menu. The first launch takes a minute to finish setting up and will ask you to create a Linux username and password — these are separate from your Windows login and only exist inside this Ubuntu environment.
- Enable systemd — required later in this lab for the
systemctlcommands that manage PostgreSQL, and generally expected by tooling that assumes a normal Linux init system. It is not on by default for a distro installed this way:
sudo nano /etc/wsl.confAdd these two lines to the file:
[boot]
systemd=true Save and exit (Ctrl+O, Enter, then Ctrl+X in nano). Back in PowerShell (not inside Ubuntu), restart WSL for the change to take effect:
wsl --shutdownReopen "Ubuntu 22.04 LTS" from the Start menu. Confirm systemd is actually running as PID 1:
ps -p 1 -o comm= This should print systemd. If it prints init instead, the wsl.conf change didn't take — double check the file contents and that you ran wsl --shutdown from PowerShell, not from inside Ubuntu.
- Install VS Code on Windows if you don't already have it — [code.visualstudio.com](https://code.visualstudio.com).
- Install the WSL extension: click the Extensions icon in the left sidebar (four squares), search "WSL", click Install on the one published by Microsoft.
- From inside your Ubuntu terminal, launch VS Code connected to this machine:
cd ~
code .The first time, this installs a small VS Code server component inside Ubuntu and opens a new window — expected, and only happens once. (VS Code's Command Palette also has a "WSL: Connect to WSL" command if you'd rather start from the Windows side instead.)
- Confirm you're actually editing files inside the Linux filesystem, not on Windows: the bottom-left corner of the window should show a green
><WSL: Ubuntu-22.04indicator.
- Open a terminal for Claude Code: with this WSL window open, use
Terminal → New Terminal(or `Ctrl+`). Because the window itself is the WSL session, this terminal opens inside Ubuntu automatically — it is not PowerShell in disguise. If you want to double check, runps -p 1 -o comm=in it; you should still seesystemd, same as step 4. Use this integrated terminal for every command for the rest of this lab, includingnpm install,git, and — once you install it in Part B —claude` itself. You do not need to switch back to a separate PowerShell or Ubuntu console window.
SSH Key Setup and Repository Access
Everything below happens inside your Ubuntu terminal (from Platform Setup, above) and on Agent P, the course portal (URL posted on the course website). Do this once — the same key and repository access carry through the rest of the semester.
<div class="callout warn">
Agent P's Git host is only reachable from Penn's network. If you're off campus, connect to the Penn VPN (vpn.upenn.edu) before running any `git clone`, `git push`, or `git pull` — for this lab and every lab and project afterward. A clone or push that hangs or times out is usually this, not a broken key.
</div>Before anything else, tell git who you are. A fresh Ubuntu install has no identity configured, and your very first git commit (Part C) will fail with Please tell me who you are without this — do it once, now, and it's set for every lab this semester:
git config --global user.name "Your Name"
git config --global user.email "you@seas.upenn.edu"Use the same email Agent P has on file for you if you know it — it's how your commits get attributed to you for grading.
- Check whether you already have an SSH key:
ls ~/.ssh/id_ed25519.pubIf that file exists, you can reuse it — skip to step 2. If you see "No such file or directory," generate one:
ssh-keygen -t ed25519 Press Enter at every prompt to accept the defaults — this saves the key to ~/.ssh/id_ed25519 and ~/.ssh/id_ed25519.pub with no passphrase. Using the default filename is fine; a fresh Ubuntu 22.04 environment won't already have a conflicting key.
- Print your public key so you can copy it:
cat ~/.ssh/id_ed25519.pub Select and copy the entire line — it starts with ssh-ed25519 and ends with a comment.
If you already use SSH for something else (a personal GitHub account, another server) and have more than one key under ~/.ssh/, add this to ~/.ssh/config (create the file if it doesn't exist):
Host ssh.git.agent-p.org
User git
Port 2224
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yesWithout this, SSH may offer your other keys first, and Agent P's Git host will reject the connection with "Too many authentication failures" before it ever tries the right one. If you only have the one key this lab just created, you can skip this.
- Log into Agent P and go to Profile / Git access. Paste your public key into the field there and save it.
- Go to My Courses and scroll to the bottom of the page. You'll see a "Your Git repositories are ready" panel with a card for each provisioned repository, including one for Lab 1. Click Copy on the
git clonecommand shown on that card — it will look like:
git clone ssh://git@ssh.git.agent-p.org:2224/<your-course-and-section>/<your-repo-slug>.gitYou'll come back to this same panel for every subsequent lab and project to find that assignment's clone command.
- Add
spacebarto the end of the copied command so the checkout lands in a directory with that name — this is the destination directory Part A and the rest of this lab assume:
git clone ssh://git@ssh.git.agent-p.org:2224/<your-course-and-section>/<your-repo-slug>.git spacebarYou'll run this for real in Part A, step 2.
Git, Just Enough for Today
You'll use six git ideas in this lab. If you already know git, skip this — Week 9 covers it in real depth. If this is new to you:
- Repository (repo) — the project folder, plus its entire tracked history.
spacebar/becomes your repo the moment you clone it in Part A. - Commit — a saved snapshot of a set of changes, with a message describing what and why.
git add <file>stages which changes go into the next commit;git commit -m "..."actually saves it. - Branch — a named line of development. You start on
main;git checkout -b <name>creates a new branch and switches to it, so you can make changes without touchingmainuntil you're ready to. - Remote — a copy of the repo hosted somewhere else — for this course, on Agent P's Gitea instance.
originis the name git gives by default to the remote you cloned from. - Push —
git push origin <branch>sends your local commits to the remote. (You won't needgit pullin this lab — nobody else is committing to your repo yet.) - Tag — a fixed pointer to one specific commit. This course uses tags to mark exactly which commit counts as "the submission" for a given lab — see "Submitting Your Lab" below.
Two habits worth starting now, both free: run git status before you commit, so nothing unexpected gets swept in, and git log --oneline afterward, so you can see what you actually recorded.
Taking and Saving Screenshots
Several deliverables in this lab ask for a screenshot. Screenshots are captured by your host OS (macOS or Windows), not from inside the Ubuntu terminal — then moved into your repo, which lives inside the Ubuntu filesystem. Save every screenshot into the lab1/ folder in your repo, alongside lab1/submission.md, using the exact filename given at each step.
macOS:
- Capture the active window: press
Cmd+Shift+4, then pressSpace, then click the window you want to capture — this grabs the whole window without you having to drag a selection box. (To capture a region instead, pressCmd+Shift+4and drag.) Either way, the screenshot saves as a.pngto your Desktop by default. - Get the file into your repo. Easiest: open your project in VS Code (already connected to your Ubuntu machine via Remote-SSH, per Platform Setup above), then drag the
.pngstraight from Finder into thelab1/folder in the VS Code Explorer sidebar.
- Command-line alternative: OrbStack shares your Mac's files into Ubuntu automatically under
/mnt/mac. From your Ubuntu terminal:
mv /mnt/mac/Users/<your-mac-username>/Desktop/Screenshot*.png ~/spacebar/lab1/<name>.pngWindows:
- Capture a region: press
Win+Shift+S, drag to select the terminal window, then release — this copies the screenshot to your clipboard. Open Paint (search "Paint" in the Start menu), pressCtrl+Vto paste, then save as a.png. - Get the file into your repo. Easiest: open your project in VS Code (already connected to your Ubuntu machine via the WSL extension, per Platform Setup above), then drag the
.pngstraight from File Explorer into thelab1/folder in the VS Code Explorer sidebar.
- Command-line alternative: WSL2 shares your Windows drives into Ubuntu automatically under
/mnt/c. From your Ubuntu terminal:
mv "/mnt/c/Users/<your-windows-username>/Pictures/<file>.png" ~/spacebar/lab1/<name>.pngConfirm each screenshot actually landed in the right place before committing: ls lab1/.
Part A — Terminal and Project Setup
Goal: Confirm you can navigate the command line and get Spacebar running locally.
- Open a terminal (Ubuntu via Orb on Mac, or WSL2 on Windows).
- Clone your repository using the command you copied from Agent P above (see "SSH Key Setup and Repository Access"), with
spacebaradded as the destination directory:
git clone ssh://git@ssh.git.agent-p.org:2224/<your-course-and-section>/<your-repo-slug>.git spacebar
cd spacebar
npm installVerify the checkout before making changes. The commit or tag should match the staff-pinned value announced for your group:
git rev-parse HEAD
git status Do not run npm audit fix in the pinned baseline. It can rewrite the lockfile and change the experiment everyone is meant to share; dependency auditing and remediation belong to the later supply-chain work.
- Install and start PostgreSQL — Spacebar will not boot without it.
sudo apt update
sudo apt install -y postgresql
sudo systemctl start postgresql
sudo systemctl enable postgresql # optional: start automatically on every VM bootOn Windows WSL2, you can install it but you may need to start it each time you restart WSL:
Ubuntu's default PostgreSQL install creates a postgres role with no password and only local "peer" authentication — that won't work with the postgres://user:password@host:port/db connection string Spacebar expects. Give it a password and create the database:
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
sudo -u postgres createdb spacebar (A password of postgres is fine for a local throwaway dev database. Don't reuse it anywhere that matters!!!)
npm startruns in the foreground and doesn't return your prompt — and you'll want the server running again later in this lab (Part F) and for most labs afterward. Rather than backgrounding it with&(which interleaves its log output with whatever else you're doing in the same terminal — workable, but annoying), open a second terminal tab or pane into the same Ubuntu environment and dedicate it to the running server. Call it your server tab — the instructions below refer back to it.
In your server tab:
export DATABASE=postgres://postgres:postgres@localhost:5432/spacebar
export CONFIG_PATH=./config.json
npm run build
npm run sync:db
npm startLeave this tab open and running. Do the rest of Part A in your original tab.
- Back in your original tab, confirm the server is live:
curl http://localhost:3001/healthz You should see a response like: OK. Screenshot this and save it as lab1/healthz.png — this is your evidence that the server runs.
npm teststarts its own server instance on port 3001 (hardcoded — seescripts/test.js) to run its smoke test. That collides with the one already running in your server tab, so stop it first: switch to your server tab and pressCtrl+C. Then, back in your original tab:
npm test npm test is a smoke test: it starts the server, waits for the word "listening" in stdout, and exits. A passing result confirms the server boots without crashing — not that the code is correct. You will add real tests later in the semester. Screenshot the passing output and save it as lab1/npm-test.png.
Once it passes, go back to your server tab and run npm start again (same command as step 4) — you'll want it running for the rest of this lab and most labs afterward. If you skip stopping it, you'll see EADDRINUSE: address already in use :::3001 here, and the smoke test fails.
Part B — Claude Code Installation and LiteLLM Configuration
Goal: Get Claude Code working through the course proxy.
- Install Claude Code globally:
npm install -g @anthropic-ai/claude-code- Configure Claude Code to use the course LiteLLM proxy. Edit (or create)
~/.claude/settings.json:
{
"model": "parcc/GLM-5.2",
"env": {
"ANTHROPIC_BASE_URL": "https://litellm.parcc.upenn.edu",
"ANTHROPIC_API_KEY": "<your-course-api-key>",
"MAX_THINKING_TOKENS": "0"
}
} Replace <your-course-api-key> with the value posted on the course portal. The proxy routes your requests to the nvidia/GLM-5.2-NVFP4 model while enforcing per-student rate limits.
- Verify the installation:
claude --version
claude "What is 2 + 2?" You should get a response routed through the proxy. Screenshot this output and save it as lab1/litellm-check.png — it is a required deliverable confirming your LiteLLM routing works.
Part C — Project Initialization with Claude Code
Goal: Use Claude Code to generate an initial CLAUDE.md and understand the project structure.
- In the VS Code integrated terminal (Platform Setup, step 9),
cdinto the root of your cloned Spacebar repository and start Claude Code:
claude- Inside the Claude Code session, run:
/init This scans the repository and generates a CLAUDE.md with a summary of the project structure, key files, and conventions. Review the generated file critically — it will be imperfect. Do not edit it yet: Lab 3 will have you verify and rewrite it properly.
Commit the auto-generated file to a branch called lab1/claude-init — your first real commit of the semester, so worth a git status glance first to confirm you're only about to commit CLAUDE.md:
git checkout -b lab1/claude-init
git status
git add CLAUDE.md
git commit -m "chore: auto-generated CLAUDE.md from /init"- Ask Claude Code to produce a Mermaid diagram of the main modules:
"Generate a Mermaid diagram showing the top-level modules of this codebase, their responsibilities, and how they communicate with each other."
Copy (or use Claude code to write) the Mermaid source into docs/module-diagram.mmd in your repo. Render it using the Marp/Mermaid VS Code extension, screenshot the rendered diagram, and save the screenshot as lab1/module-diagram.png.
Part D — Understanding Discord Servers via the Agent
Goal: Use Claude Code to learn the domain model, and practice critical evaluation of what it tells you.
- Use Claude Code to get a thorough explanation of the Discord/guild domain model:
"Using this codebase as a reference, explain in detail how a Discord server (called a 'guild' in the API) works: the data model, the hierarchy of guilds → channels → messages → roles → permissions, how real-time events are dispatched to clients, and how the permission system determines what each user can see and do. Cite specific files and functions from this codebase where relevant."
- Read the response critically. Identify:
- Two claims you can verify by looking directly at the source files. Verify them. Quote the relevant file path and line number.
- Two claims you cannot easily verify (or that seem uncertain). Note why they are uncertain — for example: "The agent says X, but I couldn't find the relevant code in the file it cited."
Write this up as a short annotation — a few sentences per claim is enough.
Why this matters: This is the core skill of the course. An LLM produces confident, plausible output. Plausible ≠ correct. The discipline of checking specific claims against the actual source — rather than accepting the summary — is what separates an engineer from someone who delegates without understanding.
Part E — CI Bootstrap
Goal: Put a CI workflow in place on day one. This workflow will grow with the course — right now it just proves the code compiles and boots.
- Create
.github/workflows/ci.ymlwith the following content:
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
env:
DATABASE: postgres://postgres:postgres@postgres:5432/spacebar
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: spacebar
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm install
- run: npm run build
- run: npm test- Commit this file on your lab branch and push it to the course Gitea repository. Confirm the green check in the repository's CI/checks view (or the linked staff-configured CI provider). If the repository protects
main, do not bypass the protection; use the normal Pull Request workflow.
- Break one existing test intentionally (e.g., add
throw new Error("intentional break")at the top of any test file). Push; screenshot the red X and save it aslab1/ci-fail.png. Then restore the file, push again, confirm the green check returns, and screenshot that aslab1/ci-pass.png.
The point: CI failing loudly on a broken push is the whole value. The pipeline exists to catch mistakes before they get to main.
<div class="callout">
This workflow only proves the server starts. That is intentional — the posture of <em>running something on every push</em> matters more than what it runs today. The pipeline grows with the course: conformance tests in P1, integration tests in Labs 8–10, and additional quality gates in later projects.
</div>Part F — Connect a Client and Post Messages
Goal: A success message from /healthz proves the process is alive. It doesn't prove the thing you built is actually a chat server. This part closes that gap — install a Discord-compatible client, connect it to your local instance, and use it the way an actual user would.
Check your server tab from Part A before continuing — if you closed it, restarted your Ubuntu environment, or it's otherwise not running, restart it now (same commands as Part A step 4) and reconfirm with curl http://localhost:3001/healthz. Fermi needs a live server to connect to.
- In a separate directory outside your `spacebar/` repo, install [Fermi](https://github.com/MathMan05/Fermi), a lightweight Spacebar-compatible web client:
cd ~
git clone https://github.com/MathMan05/Fermi.git
cd Fermi
npm install
npm run build
npm start Fermi serves on http://localhost:8080 by default. Open that address in a browser.
<div class="callout warn">
Do not try to point the real Discord desktop or web app at Spacebar. Patching Discord's official client to talk to a third-party server is a violation of Discord's Terms of Service. Spacebar-compatible clients like Fermi are built for exactly this use case — use one of them.
</div>- On Fermi's login page, change the Instance from "Harmony" to "Other Instance" and enter your local server's address (
http://localhost:3001).
Client/server compatibility across independent Spacebar-client projects shifts over time, so this step may not work on the first try — treat that as expected, not a sign you did something wrong earlier. If the client can't connect, ask Claude Code: "Fermi at localhost:8080 can't connect to my local Spacebar instance at http://localhost:3001. What request is it making, and what does the server's response look like? Check `src/api/middlewares/CORS.ts` and my `config.json` — is there a configuration mismatch?" Verify whatever the agent tells you against the actual request (the browser's dev-tools Network tab) and the actual source file, and write down what you changed, if anything, to get it working.
(spacebarchat/client, the official React client, is a heavier alternative if you want to try it instead — but it is a React Native / webpack project with a more involved build, and is not required.)
- Once connected: create a Guild ("server") from scratch, create a text channel inside it, and post at least three messages through the client's UI.

- Screenshot the channel with your messages visible and save it as
lab1/client-channel.png.
Deliverables
Start from the [Lab 1 submission template](lab-01-submission.md) and copy it to lab1/submission.md in your repo — the same template can also be downloaded from the bottom of the Lab 1 assignment page on Agent P, if that's more convenient than pulling it from this repo. Save every screenshot into lab1/ alongside it, using the exact filenames below, and embed each one in submission.md with Markdown image syntax () — see "Taking and Saving Screenshots" above for how to capture and move them. It should include:
- LiteLLM verification:
lab1/litellm-check.png— output ofclaude "What is 2 + 2?"confirming the proxy routing works. - Running server:
lab1/healthz.png(curl http://localhost:3001/healthzreturningOK) andlab1/npm-test.png(npm testpassing). - Module diagram:
docs/module-diagram.mmdcommitted to your repo with the Mermaid source, pluslab1/module-diagram.png— a screenshot of the rendered diagram. - Auto-generated CLAUDE.md: Committed to the
lab1/claude-initbranch (leave it there; Lab 3 writes its own reference version atlab3/CLAUDE.mdrather than overwriting this one). Link to the branch. - Guild explanation annotation: Two verified claims (file:line for each), two uncertain claims (explanation of why).
- CI evidence: Link to a repository with the CI workflow committed;
lab1/ci-fail.png(red X on a broken push) andlab1/ci-pass.png(green after restore). - One sentence: What does it mean that the CI check runs on every push, not just on
main? - Connected client:
lab1/client-channel.png— a channel you created in Fermi (or another Spacebar-compatible client) with at least three posted messages visible. If you had to troubleshoot the connection, a short note on what was wrong and how you diagnosed it (agent-assisted or not).
Submitting Your Lab
A tag, not the current state of main, is what actually gets graded — see "Repository and artifact conventions" in [homeworks.md](../homeworks.md) for the full policy.
- Confirm
lab1/submission.mdis complete and every screenshot it links to actually exists inlab1/.
- Push your
lab1/claude-initbranch (from Part C) so the branch link in your submission resolves for grading:
git push origin lab1/claude-init- Commit and push your submission to
main, then tag it:
git add lab1/
git commit -m "Submit Lab 1"
git push origin main
git tag lab1-submission
git push origin lab1-submissionA lab with no tag by the deadline is treated as late or incomplete, even if the files exist somewhere in the repo's history.
- If you need to fix something before the deadline, commit the fix, push
main, then move the tag rather than leaving two conflicting states:
git tag -d lab1-submission && git push origin :refs/tags/lab1-submission
git tag lab1-submission && git push origin lab1-submissionRemember the VPN requirement from "SSH Key Setup and Repository Access" above — every git push here needs the Penn VPN if you're off campus.
Grading
Pass/fail. Required to pass:
- Claude Code routes through LiteLLM (screenshot required).
- Module diagram is plausible Mermaid (renders without errors; nodes correspond to real
src/directories). /initoutput is committed to a branch.- Guild explanation annotation is substantive — generic observations ("I couldn't verify everything") receive zero credit. Name specific files and lines.
- CI/checks view shows both a red failure (on a broken push) and a green check (after restore).
- A connected client shows a real channel with at least three messages (screenshot required). If the connection needed troubleshooting, the write-up names the specific fix, not just "eventually got it working."
Agent P