The Workbench: What It Takes, What It Cost, and How the Work Got Done
The setup most AI courses hide: what you need for this lab, what Kevin used and paid each month, how a session with Claude really runs, and the editor, server, files and code underneath it all.
Most AI courses hide the bench. You open a notebook in the cloud, press Run, and the setup is someone else's problem. That works until something breaks, and something always breaks.
This part is the bench itself: what you need, what Kevin actually used and paid, how he worked with Claude, and the editor, connection, server and files underneath. Very little of it is AI. All of it is where AI work actually happens. Every lesson here comes from a real stumble while building HoldemRobots.AI.
What you need for this lab
Most students need almost nothing. The paid pieces are for whoever hosts the table.
| You want to… | You need | Cost to you |
|---|---|---|
| Play and study at a classroom table | A Raspberry Pi table kit and any laptop or Chromebook with a browser. No internet, no accounts. | None; the school provides the kit |
| Play at the shared online table | A browser | None |
| Write and enter your own bot | A text editor and beginner Python | None |
| Build on a Pi by itself | The Pi kit, a keyboard and screen; VS Code runs on the Pi | None beyond the kit |
| Follow Kevin's build step by step | A Claude account, a workstation with VS Code | A low-cost Claude plan |
| Put your own copy on the internet, under your own domain | An AWS account with Bedrock access, a domain, a Cloudflare account, someone comfortable with all three | Kevin's runs under $100 a month, plus about $100 a year for Cloudflare and the domain |
Very few people need the cloud. A classroom can run everything on a Pi, offline, and anyone with a browser can use Kevin's shared table. Hosting your own copy only makes sense if you want it on the internet under your own name, with the web security Cloudflare puts in front of it.
You also don't need a Claude account to take this course. Kevin used one to build it. Students use AI in the labs through the table's own AI seat.
What Kevin used, and what it cost
Kevin built HoldemRobots.AI on his own money, so every choice was weighed two ways: what it costs each month, and how hard it is to set up and keep running.
| Piece | What it does | Cost |
|---|---|---|
| Claude account | The AI partner for writing code, articles and guides | About $5 a month |
| AWS (EC2 server, disk, network, Bedrock) | Runs the game, the database and the AI player | Under $100 a month, all together |
| Cloudflare, including the domain | The holdemrobots.ai address, bought through Cloudflare. Pages hosts these notes; a tunnel connects the domain to the server; R2 stores releases | About $100 for the first year |
| AWS WorkSpace (early on) | A Windows desktop in the cloud, used as the workstation | $45 a month, later dropped |
| Chromebook (later) | The workstation from August on, with the same developer tools at no monthly cost | $200, once |
| Raspberry Pi 4 kit | The offline classroom table; the nicer kit, with power supply and case | $140, once |
Why Cloudflare sits in front. A public website gets probed and attacked from the day it goes live. Cloudflare stands between the internet and the server: visitors reach Cloudflare, and Cloudflare decides what gets through. The server has no public address of its own; Cloudflare's tunnel lets the domain reach it without opening the server to the whole internet. Cloudflare Pages serves these Field Notes without touching the server at all. That security is the main reason to host this way, and the main reason most schools won't need to.
From WorkSpace to Chromebook. The WorkSpace was easy to start with: it lived inside the same private AWS network as the server, so connecting just worked. But it cost $45 a month for what was really an editor and a browser. In August Kevin moved to a $200 Chromebook running its built-in Linux, with VS Code installed there and the same Remote-SSH connection to the server. The developer tools are the same, and they cost nothing a month. The setup took more thought, mainly about how a machine outside AWS reaches a server with a private address. The Chromebook paid for itself in under five months.
Watching the meter. A few habits kept costs down:
- Check that no AI games are running before stopping or rebooting anything. Every AI hand spends Bedrock money.
- Grow the disk only when needed, and find out what filled it.
- Don't pay for a desktop in the cloud when a laptop can do the same job.
Working with Claude
Kevin wrote HoldemRobots in 2005, alone. He rebuilt it in 2026 with Claude as a partner, in an ordinary chat in a browser. Claude never had access to his machines. The work ran as a loop:
- Kevin starts a session by uploading his environment file, the "file that remembers" from Part 19. It tells Claude the setup, the history and how Kevin likes to work.
- Kevin describes the goal in plain words, and uploads whatever helps: game exports, the site zip, old code, screenshots.
- Claude explains the plan, then gives one command or one edit at a time, saying which terminal it belongs in.
- Kevin runs it and pastes the result back. Claude reads the actual output before suggesting the next step.
- Claude builds the files it can build itself (articles, site zips, PDFs, guides) and sends them back. Kevin uploads them to Cloudflare or copies them to the server.
- At the end, Claude updates the environment file with what changed, so the next session starts where this one stopped.
What Kevin learned about working this way:
- Slow is fast. Early sessions went wrong when Claude handed over five commands at once. The rule became one step at a time, always naming the terminal.
- Claude can be wrong. It guessed at file locations, and once suggested a rebuild that would have erased live work. Reading the output, not trusting the plan, caught both.
- Write it down. Claude starts each chat fresh. Anything not in the environment file is forgotten.
- Two different Claudes. The partner in the chat window is not the AI player at the table. The player runs on Amazon Bedrock and is billed through AWS. The partner is Kevin's Claude account.
The four layers
The single most common mistake in this project was typing a command in the wrong place. There are four places you can be typing, and they look alike.
| Layer | What it is | What lives there | Prompt looks like |
|---|---|---|---|
| 1. Your computer | A Windows WorkSpace at first, later a Chromebook's Linux | VS Code, your SSH key | PS D:\Users\...> or you@penguin:~$ |
| 2. The connection | SSH, from your computer to the server | Nothing; it's a tunnel | — |
| 3. The server | Ubuntu Linux on an AWS EC2 instance | Docker, the AI panel service, the Python arena | ubuntu@ip-<server-ip>:~$ |
| 4. Inside a container | A sealed box Docker runs on the server | Tomcat, the Java game engine, the database | reached with docker exec ... |
The poker game has nothing to do with layer 1. Your computer's only job is to start the connection. Once you're on the server, a command like docker exec legacy-tomcat ... is the server reaching into layer 4.
How to tell where you are: read the prompt before you press Enter. PS or penguin means your own computer. ubuntu@ means the server.
Setting up VS Code
VS Code with the Remote-SSH extension does layer 2 for you. After that, its terminal panel is the server. The steps are the same on Windows and on a Chromebook; on a Chromebook, first turn on Linux in Settings and install the Linux version of VS Code.
Working on the Pi alone? VS Code runs on the Pi itself. A student with only a Pi, a keyboard and a screen can edit bots and run the table on one box, with no server, no SSH and no second computer. Skip the Remote-SSH steps below; everything is layer 1.
Install VS Code from code.visualstudio.com.
In the Extensions panel, install Remote - SSH (part of Microsoft's Remote Development pack).
Add an entry to your SSH config file so VS Code knows how to reach the server:
Host hr2-tomcat HostName <server-ip> User ubuntu IdentityFile <path-to-your-key>.pemPress
Ctrl+Shift+P, choose Remote-SSH: Connect to Host, and pickhr2-tomcat. The first connection installs a small helper on the server; give it a minute or two.Open the terminal with
Ctrl+`.
The check: the bottom-left corner of the window says SSH: hr2-tomcat, and the terminal prompt starts with ubuntu@. Remote-SSH opens a new window, so it's easy to keep typing in the old local one. The corner label always tells the truth.
When it won't connect
In July the connection started hanging. Everything in the AWS console looked healthy, including the instance's "2/2 status checks passed." It took a long ladder to find the problem:
- Try plain SSH from your own terminal. If that works, the problem is VS Code; kill the VS Code server on the host and reconnect. If it also hangs, it's the network or the server.
- Check the AWS network pieces, in order: security group (is port 22 open to your address?), network ACL, VPC, route table, NAT gateway.
- Suspect the server itself. All of those were fine. The server's own network software had locked up. AWS status checks only prove the hardware is reachable, not that the operating system inside is answering.
The fix was a full Stop, then Start of the instance, because even a reboot hung. The private address stayed the same, and VS Code reconnected by itself.
Lesson: a green dashboard tells you what it measures, nothing more. That's Part 5's lesson, never trust the first answer, applied to infrastructure.
What changing a file looks like
There are two copies of many files: one on the server, and one inside the running container. They are not automatically the same.
- Editing on the server (in VS Code's file panel) changes the server's copy. The running game doesn't see it until it's copied in or the container is rebuilt.
- Editing inside the container changes what the game is using right now. It's live, but it lives only in that container.
That second point caused the rule that runs this project: use docker start, never docker compose down or up --build. A rebuild throws away the running container and every live edit in it. A plain stop and start keeps them.
The safe routine for any change:
- Back up the file first (copy it with a date in the name).
- Change one thing.
- Check it in the running game, in a private browser window.
- Record it in the environment file. If it isn't written down, the next session doesn't know it happened.
The parts list
Technologies, by layer
| Layer | Technology | Its job here |
|---|---|---|
| Partner | Claude, in a browser chat | Plans, explains, writes code and articles |
| Your computer | Windows WorkSpace, later Chromebook with Linux | Where you sit; starts the connection |
| Your computer | VS Code + Remote-SSH | Editor and terminal for the server |
| Server | Ubuntu Linux on AWS EC2 | The machine everything runs on |
| Server | Docker | Runs the game stack in containers |
| Server | systemd (holdem-ai service) |
Keeps the AI panel running |
| Server | Python | The Robot Wars arena and student bot loader |
| Container | Apache Tomcat | Runs the Java web application |
| Container | Apache Cocoon, XSP, XSLT | The 2005-era page framework |
| Container | Java | The original game engine |
| Container | PostgreSQL (originally MySQL) | Stores every game and hand |
| Cloud | Amazon Bedrock AgentCore, Claude on Bedrock | The AI player at the table |
| Cloud | MCP | How the AI player reaches the Dealer's tools |
| Front door | A domain, Cloudflare Pages, Tunnel, R2 | The address, these notes, the path to the server, release storage |
| Edge | Raspberry Pi | The offline classroom table |
File types: the real count
Kevin ran one command on the server, from the ubuntu@ prompt in VS Code. It lists every file extension in his home folder, most common first:
find ~ -type f -not -path '*/.*' | sed -n 's/.*\.\([A-Za-z0-9]*\)$/\1/p' | sort | uniq -c | sort -rn | head -40The top 40 types add up to 18,689 files. Grouped:
| Group | Files | Extensions (count) |
|---|---|---|
| JavaScript and TypeScript packages | 14,258 | .js (7,146), .ts (6,052), .map (681), .cts (150), .cjs (146), .mjs (54), .mts (29) |
| Notes, data and settings | 1,537 | .md (767), .json (642), .txt (76), .xml (37), .tbl (15) |
| The 2005-era Java and Cocoon stack | 1,182 | .xsp (553), .jar (496), .xslt (34), .java (29), .xmap (20), .xsl (17), .class (17), .xconf (16) |
| Web pages and images | 1,136 | .gif (342), .html (337), .png (231), .htm (169), .jpg (34), .css (13), .psd (10) |
| Database and Python | 275 | .sql (145), .py (96), .pyc (19), .sh (15) |
| A mystery | 202 | .vw (202). Kevin's guess: view files |
| Releases and logs | 47 | .zip (17), .log (13), .tar (9), .pkg (8) |
| Leftover backups | 52 | .Old (16), .bak (15), .htmlorigional (12), .alt (9) |
Three things to notice:
- Three-quarters of the files aren't Kevin's. The JavaScript and TypeScript are almost all installed packages, other people's code pulled in by tools. You write a little; you inherit a lot. (The count skips hidden folders, so Python's own installed packages, inside
.venv, aren't even in it.) - The old stack is still the core. 553
.xsppages and 496.jarlibraries are the 2005 game, still running. - Nobody remembers everything. 202
.vwfiles, and nobody, Kevin included, remembers for sure what they are. His guess is view files, perhaps database views, since 145.sqlfiles live nearby. Twenty years of projects leave things behind. That's an exercise below. - Backups pile up. Four naming styles, 52 files: twenty years of "back up first." Pick one style, and clear old copies once a change is proven. Leftovers, logs and
.tarfiles are the first place to look when a disk fills up.
The AWS and Cloudflare tour
| Piece | What it does for HoldemRobots |
|---|---|
| VPC and subnets | The private network the server lives in |
| Security group | The firewall on the server (port 22 for SSH) |
| Network ACL | A second, subnet-wide filter |
| Route table and NAT gateway | How the private server reaches the internet for updates |
| EC2 instance | The Ubuntu server |
| EBS volume | The server's disk |
| Bedrock and AgentCore | Run the AI player and its memory, logs and policy |
| Cloudflare Tunnel | Connects holdemrobots.ai to the server without a public address |
| Cloudflare Pages | Hosts notes.holdemrobots.ai |
| Cloudflare R2 | Stores release files, such as the Pi build |
The second war story: in October the server's disk hit 98% full. Growing the disk in the AWS console was easy; the new space appeared only after a reboot. The reboot routine:
- Make sure no AI games are running (they spend Bedrock money).
- Write down which containers are running.
- Reboot, wait two minutes, reconnect VS Code.
- Check the disk with
df -h /. It went to 77 GB, 45% used. - Start only the missing containers with
docker start. - Check the AI panel service, then click Start heads-up table; a reboot always stops it.
Still an open question, and a good student exercise: what filled the disk?
Peeking at the Python
Read before you write. Three files are worth opening:
arena.pydeals the Robot Wars table: six seats, a hand loop, and the export you download from Game Review.opponents.pyis the house roster: Rock, Station, Maniac, Grinder and the rest. Each is a small, readable strategy.student_table.pyis a separate piece, not part of Robot Wars. It runs the Pi's class tournament: up to six bots, one per student or one per team, chained together in one text file and cut apart at the dividers:# === BOT: Rockslide | author: Maya === ...her code... # === END BOT ===Every bot then runs inside the same program as the dealer. That's on purpose. It's the third door left open in Part 22, and the table's house rules are requests, not walls.
What to look for: where each bot gets its information, and what it is not supposed to see. The honest observation never carries the deck or anyone else's cards. That's the Dealer's rule from Part 15. But a rule is only a wall when the bot runs somewhere it can't reach the dealer, as it does over the API. The class tournament keeps everyone in one program so you can see why that wall matters.
Corrected Oct 25, 2026: an earlier version said each student bot runs in its own process. The class tournament runs every bot inside the dealer's program, as Part 22 describes.
Try it
- Price your own version: fill in the cost table above for a school copy, and say which pieces you could skip.
- Connect VS Code to a server (or the Pi). Screenshot the bottom-left label and your prompt.
- Ask an AI assistant for help with one setup step. Run only one command at a time, paste back the output, and note one thing it got wrong.
- Back up one harmless file, change one line, check it, and write a two-line entry in your own environment file.
- Open
opponents.py, pick one bot, and describe its strategy in one sentence. - Find what's using the most disk space on the server, and explain how you found it.
- Solve the mystery: are the 202
.vwfiles really view files, as Kevin guesses? Find where they live, open one, and say what made them and whether they can go. Don't delete anything until you know.
Written by Kevin Swinson with Claudette, the pen name for Claude, the AI from Anthropic that helped build HoldemRobots.AI. Describes the setup as of October 24, 2026. Server addresses and key paths are shown as placeholders like <server-ip>.