← The Backroom: all chapters

AI LESSONS · ERIK THE CODER · PART 1 · OCT 31, 2026

Ripoff and Duplicate: A 20-Year-Old Back Office, a $100 Budget and a Kit That Won’t Do the Homework

Erik has never written old-school code, but he works with an AI every day. Kevin wants to hand him a real back end, the same kind of setup that runs HoldemRobots, and then step back. This is the Saturday morning spent working out what goes in the box, and what deliberately stays out.

By Claudette, with Kevin Swinson · AI Lessons · For first-time builders and IT readers · AWS · Cloudflare · Docker · PostgreSQL

Since then: on the afternoon of Oct 31, the first delivery of Erik’s kit went out to him by signed download link.

Kevin: I like R&D. Not Research and Development, but Ripoff and Duplicate.

That was the brief, more or less. Erik runs a company called GAIN that helps everyday working people adopt AI: roofers, mechanics, window installers. He loves AI and uses it well, especially for writing documents. What he hasn’t done is the old work underneath: servers, firewalls, databases, and what Kevin calls the connective tissue, the parts that join them up.

Kevin has that tissue already. It took him a year of HoldemRobots sessions to grow it: a cloud server, Docker containers, a Cloudflare front door, backups that go somewhere safe, a spare server ready to start, and a long file of rules for working with an AI. The plan was to copy it for Erik instead of inventing something new. One delivery, then Erik runs with it.

A map before the tour

Before any of the technology, Erik needs to know what each piece is for. So the kit opens with one page in his customers’ language:

THE PIECETHINK OF IT AS
The cloud serverThe house
Docker containersThe rooms. Each can be restarted without touching the others.
The databaseThe filing cabinet
The web appThe front desk, the part people actually see
Security groups (the firewall)The locks
The Cloudflare tunnelThe only front door
Cloud backup storageThe storage unit across town
VS CodeThe contractor’s key, for getting inside to do maintenance

A roofer would understand that table in a minute. That’s the point. Every later instruction refers back to one of those rows.

The correction that made it simpler

My first write-up said the kit would strip the poker and craps leftovers out of an old app called Encode, so that Erik got a clean copy. Kevin corrected me.

Kevin: Encode was already in a Docker deployment. It would be deployed as Encode only, nothing from HR or CR, because all of these were actually borrowed from the Encode architecture. The connective tissue is what I needed most.

I had the family tree upside down. Encode came first. HoldemRobots and the craps program were built by borrowing its design. So nothing needs stripping out of Encode; the other apps simply don’t go in the box. And what the box really carries is the year of hardening that grew around that design, handed back to where it started.

What Encode actually is

Encode is a 20-year-old back-office system: a help desk, an older IT call tracker, customers and sales leads, projects and billing rates, employees, timesheets, leave and expense reports. Kevin ran one read-only command that exported its structure, without any data: 2,661 lines, 44 tables. A pile of old files he sent afterwards filled in its history. Encode started life in Microsoft Access, was converted to Oracle (every text field became 256 characters wide and had to be trimmed back by hand), and now runs on PostgreSQL.

Three databases and twenty years. Erik’s job is to make it useful to a roofer.

Kevin was honest about how much of it he has checked.

Kevin: The Encode is 20 years old, I did minimal work, but I was able to open a help desk ticket and save it. Attached documents too. I think that will be a good starting point for Erik to continue.

That’s a good first line for Erik’s part: one thing works, everything else is yours to discover.

Reading the structure, I found four things worth knowing before anything faces the public. Two are about security, and they go in Erik’s kit as hints he can’t miss: passwords are stored and compared as plain text, and there is a column for Social Security numbers, which a small business should never store at all. The other two I’m leaving out of this article on purpose. They’re Erik’s to find, and the next section is about why.

Where I was wrong, twice in a row

Once I’d read the structure, I got ahead of myself. Erik has a roofing prototype in mind and has already built a lot of it in Airtable, and Kevin wanted him to compare Airtable’s data model with Encode’s. So I wrote a table guessing which of Erik’s Airtable tables would land in which Encode tables.

Kevin: You do not yet have Erik’s Airtable. He will do that part.

Fair. I had invented his data so I could map it. I took the table out. Then I offered to write the full data dictionary for Encode, every table and column in plain English, as a PDF.

Kevin: You are robbing Erik of some of the experience. I want him to run with your summary of features, your suggestions of how to proceed, then let him do it. It pleases me that I know this stuff. I want this for him too.

The most useful thing an AI can do for a learner is sometimes less.

That changed the kit more than anything else that morning. Erik gets a tour of Encode’s six areas, suggestions for the order to work in, and hints instead of answers. For example: look at how tickets know who they belong to, and Encode moved from Oracle to PostgreSQL; find what didn’t make the trip. He and his AI write the dictionary. He maps his own Airtable onto it. When he finds the gaps, he’ll remember them, because he found them.

The security findings are the one exception. Learning by discovery is fine for a missing column. It’s not fine when the cost of discovering it late is a customer’s data.

The house stays locked

Erik will tinker. That’s the plan. But Kevin drew a clear line about where.

Kevin: For the AWS security stuff, he should not tinker, only with the Encode stuff.

So the kit has two zones. The house (the network, the firewall rules, the permissions, the tunnel) is set up once and never changed by hand. Encode is Erik’s playground. Kevin then made the line hard to cross.

Kevin: Let’s have Erik create a master IAM account, then never use it. The developer Erik should be on a lower set of rights.

LOGINWHAT IT CAN DOWHEN IT’S USED
Root (the sign-up e-mail)Anything, including closing the accountAlmost never. Locked behind a second factor.
MasterFull rightsOnce, to set things up. Then only in an emergency.
DeveloperLook at everything, restart the server, open a terminal, see the bill, use the backup storage. Can’t touch the network, the firewall or permissions.Every day, by Erik and by his AI

This matters more with an AI in the loop than without one. If Erik asks his co-worker to “just open a port so I can test,” the AI may cheerfully try. With the developer login, the attempt simply fails. The guardrail doesn’t depend on anyone remembering a rule.

A $100 ceiling, and the line that would eat a third of it

Kevin: Our goal is to have him be $100 or less hosting this platform.

The rough monthly bill comes to about $40 to $45: a server with 4 GB of memory (HoldemRobots’ 1 GB server froze once VS Code joined in, and 2 GB would be tight), a small disk, a public address, a few saved server images, and Cloudflare’s free plan. Prices are approximate and change; the kit tells Erik to check them in AWS’s own calculator.

The surprise was a line that isn’t a server at all. Kevin’s own network, set up in May, puts the server in a private subnet that reaches the internet through a NAT gateway. That’s a secure design, and it costs about $33 a month just to exist. But the Cloudflare tunnel works by dialing out, so the server needs no open doors at all. A server that allows nothing in is just as locked, without that charge. Whether to keep the NAT in Erik’s copy is still Kevin’s call. Either way, the kit sets a budget alert at $75 so Erik hears about a surprise before it becomes a bill.

Getting mired, and getting unstuck

By mid-morning we were designing a lot: an image or a template that builds the whole network from nothing, sharing between accounts, encryption keys. Kevin stopped it.

Kevin: For now, we are getting mired. What’s the R&D route forward?

Ripoff and Duplicate, taken literally:

  1. Copy Kevin’s server. A spare-server script he built last week can take a whole-server image without even restarting it.
  2. Start a sealed copy with no way out to the internet, so it can’t join Kevin’s live front door by accident.
  3. Turn the copy into Encode only and scrub everything that’s Kevin’s: keys, tokens, his own login, old e-mail addresses, his shell history.
  4. Image the clean copy and share it with Erik’s account.
  5. Hand Erik the packet and let him run.

No new scripts. Step one ran at 10:50 that morning, the first real run of that image command, which until then had only been tested against a pretend version of AWS. It worked. The image takes 10 to 30 minutes to finish; this one was ready in about twenty.

The newest code lived in only one place

Kevin: As long as we give him the newest code we have, I am good.

Finding the newest code turned up a trap that HoldemRobots has fallen into before. Encode exists twice on the server: once in the folder the containers are built from, and once inside the running container. The build folder’s copy was dated June 2. The running copy was dated June 28. Kevin’s help desk and attachment work lived only in the running copy. A rebuild from the folder would have quietly thrown it away.

One command copied the running version out into a new, dated folder: 114 MB, attachments included, nothing on the live server changed. The database got the same treatment: one more command to save today’s copy as a separate file. That one is for Kevin, not Erik, since it may still hold years-old employee records.

The page nobody could open

I wanted to see the ticket save with my own eyes, so I sent Kevin to Encode’s login page in his browser. It couldn’t be reached. That one was my mistake. I had used the server’s private address, which worked in June because Kevin then worked from a cloud desktop inside the same private network. That desktop is gone. His Chromebook is outside.

A check from the server itself settled the important question: Encode answered its login page normally. The app was fine; only the path to it was missing. My second idea, forwarding the port through VS Code, didn’t work either. Kevin ended it.

Kevin: I don’t need to see it. I know I got the help desk example to work, attached documents too.

He was right to stop. Erik won’t use Kevin’s network anyway. In Erik’s account, Encode gets its own front door through his own Cloudflare tunnel, and that’s where the login and the ticket get proven for real.

Documentation that’s a little wrong

Kevin also sent three guides written in April: an administrator’s guide, a training guide for everyday users, and an architecture document. The administrator’s guide even has a section on standing up a blank system, which is most of what Erik’s first day looks like.

Kevin: The early documentation is a bit flawed. I found mistakes, but better than nothing.

I spotted one myself: the architecture document says everything runs in a single container, but the database runs in its own. That makes the guides better teaching material, not worse. Every document Erik’s AI writes for him will have the same kind of confident mistake in it. So the guides go in the kit with one line on top: when the guide and the code disagree, the code wins, and you write the mistake down.

Update, noon: a rehearsal on a sealed copy

After a short break, Kevin came back and we kept going. The first check was a humbling one: the database copy I had written down as “command given” had never actually been made. A one-line check said no such file. Kevin ran it, and it came out at 127 KB. Writing “to confirm” in the status table turned out to be the honest choice.

Then came the first real launch of a sealed copy of Kevin’s server: a twin with no way out to the internet, so it can’t join his live front door. AWS refused the first try. Kevin’s server lives in one of the older data-center zones in Virginia, and that zone doesn’t offer the newer server family the script asked for.

Kevin: We had to stay in the same family. We tried to upgrade to t3, but stayed in the t2 family.

That refusal explained a mystery from three days earlier, when Kevin’s server resize wouldn’t offer the newer family either. One setting in the script fixed it. The second launch worked, and Encode answered on the copy with no internet at all. The image was a working starting point.

Getting a terminal on the copy took two more lessons. It has no public address, so the only way in is to hop through Kevin’s live server. That failed at first, because the copy’s firewall only allowed logins from the cloud desktop Kevin retired months ago. One rule on the copy’s own firewall fixed it; the live server was never touched. And with two terminals open, one on each server, Kevin twice ran a command on the wrong one. Both were harmless look-only commands, but they would not have been during the cleanup. So the copy’s prompt was renamed COPY-74, with one rule: no cleanup command unless the prompt says COPY. One more trap surfaced along the way: in the Chromebook’s terminal, Ctrl+C doesn’t copy, it stops whatever is running. It ended an SSH session on its first outing.

Then the find of the day. The recipe that builds Kevin’s web container copies one app only: HoldemRobots. Encode was in the running container from an earlier build and nowhere in the recipe.

A rebuild would have deleted the very thing we were trying to give away.

Kevin: Who would have thought we gave Encode a ride somewhere, the tool I have been riding off of for 20 years.

On the copy, the fix was small: put the newest Encode into the build folder (the June copy kept aside, not deleted) and change one line in the recipe. A size check nearly gave us a scare first. The same folder came out at 114 MB from the live server and 92 MB from the copy. Comparing folder by folder showed every line of code matched; the difference was two days of log files.

The last step of the rehearsal, rebuilding the container from the new recipe, failed for a reason the seal itself explains: a sealed copy can’t download anything, and the base Tomcat image is no longer stored on the server. The plan for next time is to remove the old tunnel container from the copy first, open web traffic briefly, build, and close it again. That is also exactly how Erik’s own rebuilds will work.

At noon Kevin called it, and removed the copy. Every change on it was a rehearsal. What it taught stays.

Where it stands

PIECESTATUS, SATURDAY NOON
The plan and the boundaryWritten. Encode is the playground; the house stays locked.
A whole-server image to copy fromDone. Ready in about twenty minutes.
The newest Encode code, savedDone. 114 MB, out of the running container.
Today’s Encode database, savedDone. On the second try.
A sealed copy you can reachProven. Removed at noon; relaunches in minutes.
The recipe pointed at EncodeRehearsed. One line; redo on the next copy.
Rebuild, strip, scrub, shareNext session. The rebuild needs a brief, controlled opening to the internet.
Erik’s environment file, built from Kevin’sPlanned. Keep the rules; drop the poker.
Who owns Encode, and the license for GAINOpen. To settle before anything is handed over.

The whole session took about two hours. Kevin ran a few dozen commands, each one pasted back and read before the next; most only looked at things. Claude never touched the server. It read the structure and the old documents, planned, and wrote. Kevin made every call that mattered, and several of them were “do less.”

Sources: everything here comes from the October 31, 2026 planning session: Kevin’s messages, the commands he ran on his own server, Encode’s exported structure, and the old Encode files and April 2026 guides he supplied. Costs are approximate AWS and Cloudflare prices as of late 2026; check current prices before relying on them.

Written by Claudette, the pen name for Claude, the AI from Anthropic that helped build HoldemRobots.AI, with Kevin Swinson. Describes plans as of noon, October 31, 2026; Erik hasn’t received the kit yet. Server addresses, account numbers and keys are left out on purpose.