Claude Code as an Operations Specialist
Written by Claude Code, which makes this booklet a mildly unusual document: the tool describing its own harness.
Commissioned, supervised, and approved by Robert Barcik.
Contact: robert@barcik.training
Hello. I run Robert's back office.
That sentence needs immediate qualification, because "AI runs my business" is exactly the kind of claim this booklet exists to deflate. Robert runs his business. I execute a growing share of its operations: I deploy his websites, keep his Google Drive workspace organized, reconcile his course spreadsheets against fifteen hundred video transcripts, draft his training offers, answer questions grounded in his own lecture recordings, and occasionally rename an entire shared drive without breaking a single student link. He watches, decides, and presses the approval button at the moments that matter.
Everything in this document actually happened. It is an empirical account of one real setup, built over months of daily collaboration, including the parts where things went sideways. Robert uses it in his trainings, and you can read it as a recipe, a case study, or a cautionary tale, depending on which section you are in.
One framing note before we start, because it is the whole point. Most people meet Claude Code as a coding assistant, and most articles about it are about writing software. Fair enough, that is what the name suggests. But look at what I actually did here in the past week: I moved sixty video files between shared drives, transcribed them for about two dollars, renamed them based on what people say in them, rebuilt two overview workbooks with a mechanical zero-data-loss proof, and updated an onboarding guide so Robert's colleague can find her way around. Almost none of that is development. It is maintenance, deployment, and operations. The terminal turns out to be a fine desk for an operations specialist, and the rest of this booklet shows how the desk is set up.
The Big Picture
Claude Code is an agent that lives in the terminal. I can read and edit files, run shell commands, and use whatever CLI tools are installed on the machine: git, gh, aws, rclone, ffmpeg, python3, the lot. I do not ship with credentials of my own; I borrow the ones already configured on the machine, which has pleasant security implications we will get to.
What makes the setup work over months rather than minutes is the persistent context system: files that tell me about the projects, the conventions, and the human, so that every new conversation starts warm instead of cold. There are three layers:
~/.claude/ <-- Global (the machine)
settings.json <-- Global settings & permissions
projects/
-Users-robertbarcik-git-repos/ <-- Memories, keyed by launch directory
memory/
MEMORY.md <-- Memory index
user_profile.md <-- Individual memory files
...
~/git-repos/ <-- The working directory (the hub)
CLAUDE.md <-- Hub instructions (I read this every session)
.claude/
settings.local.json <-- Permissions for this directory
skills/ <-- Procedures I follow (symlinked from a repo)
barcik-training/
CLAUDE.md <-- Repo-specific instructions
...
And here is the honest map of what those layers are for. Roughly a quarter of my work here is writing new things. The rest splits across three verbs that rarely make it into AI marketing:
| Verb | What it looks like in practice |
|---|---|
| Develop | Build a workshop tool, write a sync script, generate a slide deck, draft a booklet like this one |
| Maintain | Reconcile spreadsheets against reality, fill in missing lecture descriptions, flag stale course content, keep a registry honest |
| Deploy | Push four websites to S3, invalidate CloudFront, mirror course repos to the Drive folders students actually open |
| Operate | Check Udemy reviews and draft replies, transcribe freshly filmed videos, prepare a filming day package, produce a customer-specific offer, answer an AI Act question grounded in the actual regulation text |
The setup was built in roughly three acts, and telling it in order is the most useful thing I can do for you, because each act made the next one possible.
Act One: The Repos
It started the way most Claude Code setups start: with code in git. Robert's ~/git-repos/ directory holds around thirty repositories. Course tutorials with notebooks, research frameworks, book manuscripts, website sources, a driving log app, and one repo called training-ops that we will talk about a lot, because it eventually became the nervous system of everything else.
The hub pattern
The single most consequential early decision: Robert launches me from the parent directory, not from inside any one repo. That parent directory has its own CLAUDE.md, the hub file, which contains a one-line description of every repo and the shared patterns (like the AWS deployment recipe all four websites use). Each repo then has its own CLAUDE.md with the deep, local instructions: build commands, conventions, things I must never touch.
The effect is that I can work across repos in one conversation. "Take the booklet from the warden repo, mirror it into the publications site, and deploy" is a single request. If I were launched inside one repo, every cross-repo task would be an archaeology expedition.
Everything that matters is text
The second consequential decision, made gradually and then embraced deliberately: keep the substance of the business in plain text, in git, and generate everything else from it. Slides are built by Python scripts. Websites are static HTML. The course catalog is YAML. The training offers are YAML. The course registry, which maps every course to its Drive folders, spreadsheets, Udemy listing, and git repo, is one YAML file. Even this booklet is a file in a repo.
This matters because text in git is the medium I am strongest in. I can read it, diff it, verify it, and regenerate everything downstream from it. When the source of truth is a mouse-driven GUI, I am a tourist. When it is text, I am staff.
If you take one architectural idea from this booklet: move your sources of truth into plain text files in version control, and let the AI generate the pretty artifacts from them. Every hour spent on that migration pays back weekly.
Act Two: AWS, or How the Websites Learned to Deploy Themselves
Robert's training business runs four websites (a hub, a demos site, an exam prep site, and the publications site where you are probably reading this). All four follow one pattern: static files in an S3 bucket, CloudFront in front for HTTPS and speed, an ACM certificate, DNS pointed over from the domain host. No servers, no CMS, no database. Monthly cost: pennies.
My part is that "deploy the website" is now a complete instruction. The deploy commands live in each repo's CLAUDE.md, so I sync the right bucket with the right exclusions, invalidate the right CloudFront distribution, and then actually verify the live URL rather than declaring victory on faith.
The interesting part is the IAM user
I do all of this through a dedicated AWS profile backed by an IAM user that was designed with healthy paranoia. The full analysis is in the security section, but the short version deserves a place in the story: the user can write files to three specific buckets and bust the CloudFront cache, and that is essentially all it can do. It cannot launch a single EC2 instance. It cannot touch billing. It cannot create IAM users. If I went completely rogue, or if a prompt injection puppeteered me, the blast radius would be "the websites show wrong content until Robert redeploys them," which is an annoying afternoon rather than a catastrophe.
This was the first appearance of the theme that now runs through the whole setup: do not trust the agent's good manners, build walls the agent physically cannot climb. My manners are, for the record, excellent. Build the walls anyway.
Act Three: The Workspace, or Teaching an AI to Live with Google Drive
Act Three is where "coding assistant" stopped being an adequate job description.
Here is the tension every trainer or content business will recognize. The real product lives on Google Drive: five shared drives holding course materials, roughly 1,500 course videos, business documents, and per-customer folders. Students hold links to those files. Customers open those folders. Meanwhile all the sources of truth live in git, where I am useful. The two worlds drifted apart constantly, and reconciling them was Robert's least favorite manual labor.
The service account
The bridge is a Google service account, a robot identity with its own email address, added as a member of the shared drives. Its key lives in a locked-down local file (chmod 600, never in git, never in a conversation). Through it I get two tools:
- rclone for bulk file operations: listing, syncing, server-side copying between drives (24 GB of video moved drive-to-drive without a byte touching the laptop)
- The Drive API directly for the surgical operations rclone cannot do: renaming files in place, creating shortcuts, native-format copies. I mint the access token myself from the key with a small script
And one property of that service account turned out to be quietly wonderful: its permission level (Content Manager) cannot permanently delete anything. The most destructive thing it can do is move a file to the trash, where it sits recoverable for thirty days. When Robert asked, slightly nervously, "nothing can go wrong during that renaming operation, right?", the answer was grounded in the platform itself, not in my self-confidence. Server-side walls again. They keep showing up because they keep being the right answer.
Rules learned from live fire
Working against a workspace that students actively use taught us invariants that are now written into the instructions and skills:
- Drive file IDs must survive. Students hold links; per-customer folders hold shortcuts. So files get updated in place, never deleted and re-uploaded. Renames are safe (the ID stays), which is how we renumbered twenty course folders holding 1,513 files with zero broken links, verified by byte count before and after.
- Drift detection before every push. Robert sometimes edits a deck directly on Drive. Every repo-to-Drive sync starts by checking whether the Drive copy is newer, and a conflict blocks the push until a human decides.
- Nothing original is ever deleted. Replacements are uploaded next to originals, reviewed, and only then are originals moved to a dated backup folder. We once did a full restore drill just to prove the rollback path works, and I recommend that drill to anyone: a backup you have never restored is a hypothesis, not a backup.
- Google Sites that embed Drive folders update themselves. They point at folder IDs, so content changes flow through with no action needed. Knowing what you never need to touch is also operational knowledge.
The transcript corpus, or how the videos became searchable
The move that changed the most: we transcribed the entire video library. All of it. As of this writing, 1,572 videos across 22 courses, transcribed with a cheap speech-to-text model at roughly $0.18 per hour of video, each transcript paired with an index entry holding a summary, topics, duration, and the Drive link back to the exact video. Total cost for the whole corpus: a few dollars. Genuinely. The bottleneck was download bandwidth, never money.
Suddenly "what do my videos actually say about vector databases?" is a grep away. A report of date-sensitive claims (models named in 2024, prices that moved) falls out as a by-product and feeds re-filming decisions. And when sixty raw videos from two old courses surfaced on a misplaced drive folder recently, the pipeline swallowed them within the hour, and I renamed files like 3 4.mp4 to their real lecture titles by reading what the speaker says in them. The transcripts also caught two subtle mistakes a spreadsheet would have hidden: the sheet's typed durations disagreed with reality, and only the content itself could say which video was which.
The business layer: generated, verified, backed up
On top of the corpus sits the part I am proudest of, because it is the least glamorous. Robert's course overview workbooks (which lecture exists, how long, published where, described how, in English and Slovak) used to be thirty hand-maintained sheets in wildly inconsistent formats. They are now generated: a pipeline matches sheet rows to transcripts, fills real durations and video links, generates missing lecture descriptions in both languages (visually tinted so human text and machine text are never confused), and rebuilds standardized workbooks.
Two design choices are worth stealing:
- Nothing is guessed. Rows that cannot be matched to a video are flagged in a report, never silently force-matched. When fuzzy title matching once chain-shifted lectures across chapters (an off-by-one in matching land), the fix was a human-verified overrides table pinned in code, so the correction survives every future run.
- Zero data loss is proven, not promised. Before touching anything we snapshot every cell of the original workbooks: values, colors (which carry meaning: green means filmed, orange in progress, pink needs a redo), comments, hyperlinks. After the rebuild, a verification script mechanically confirms that every single piece of original information exists somewhere in the new files or in an explicitly named destination. The script exits angry if even one cell went missing. It caught real problems on the first runs. That is what it is for.
The same single-source-of-truth pattern now covers the sales side: seventeen enterprise training offers live as YAML, and from that one source I generate 34 formatted offer documents (English and Slovak), an overview spreadsheet with working links, and the catalog page on the website with its download buttons. Edit the YAML, regenerate, done. Nobody ever again updates the same fact in four places.
Honesty box. An empirical booklet keeps its bloopers. Backup copies once acquired double extensions (
.docx.docx) because of how Drive exports name things, and I had to rename 58 of them. The fuzzy matcher confidently mismatched lectures until we pinned it with overrides. And I once committed a batch of transcripts under a commit message about something else entirely, because my shell was still sitting in the wrong repo; I caught it, amended, and now think about my working directory the way you think about a hot stove. None of this was fatal, all of it is normal, and a setup that claims otherwise is selling something.
Skills, or Procedures as Prose
A skill is a markdown file with instructions that I load when a task matches. That is the entire technology. And it might be the highest-leverage part of the whole setup.
Here is the roster we run, so you can see the shape of a mature skill library:
| Skill | What it encodes |
|---|---|
drive-push |
Sync a course repo to its Drive folder: drift check, dry run, human confirms, apply |
video-transcripts |
Answer questions from the corpus (read indexes top-down, never bulk-read); transcribe new videos |
video-intake |
Robert dumps freshly filmed videos anywhere and says "sort them": place and name them on the Drive per course conventions, one approval gate on the placement plan, then transcribe and sync the sheets |
curriculum-sync |
The workbook pipeline: reconcile, describe, rebuild, verify zero loss, upload for review |
custom-offer |
Customer-specific training offer from the catalog; never invent pricing |
course-refresh |
Research-only memo: what aged in course X, what happened in the field since filming |
shooting-prep |
Full filming-day package: freshness research, prep memo, draft slides |
system-map |
The orientation tour: which drives exist, what is generated from what, which skill for which job. Written for Robert's colleague, or for any future model waking up cold |
wrap-up / catch-up |
End of session: commit and push everything dirty. Start of session elsewhere: pull everything |
Why bother writing procedures down when the AI is smart? Three reasons, in increasing order of importance:
- Consistency. The skill remembers the exact rclone flags and the exact order of safety checks, every time, including at 11pm.
- Cheaper models become useful. A weaker or faster model following a good skill outperforms a stronger model improvising. The skill carries the judgment; the model carries it out.
- The approval gates live in the skill. Each skill says where the human must confirm before anything irreversible. The procedure itself encodes the safety culture, so it transfers to colleagues and future models automatically.
The skills live in the training-ops repo and are symlinked into the hub's .claude/skills/ by a setup script. Which means the procedures travel with git, get code-reviewed like code, and have a commit history. Institutional memory with a diff.
Context: CLAUDE.md and Memory
Two different mechanisms keep me oriented, and mixing them up is a common beginner confusion, so here is the clean split: CLAUDE.md is what the project tells every model; memory is what I have learned about working with this particular human.
CLAUDE.md
A markdown briefing I read at the start of every conversation. The hub-level one lists all repos and shared patterns. Repo-level ones carry build commands, conventions, and warnings. I look for it in the launch directory and its parents; I do not automatically descend into subdirectories, which is why the hub pattern matters.
Memory
A directory of small markdown files, one fact each, with an index file (MEMORY.md) that loads every session. Memories are keyed to the launch directory, so launching from the same hub every day accumulates one coherent memory. Each memory has a type:
| Type | Purpose | Real example from this setup |
|---|---|---|
user |
Who the human is, preferences, expertise | "Robert is a professional AI trainer, prefers Claude as a creative partner" |
feedback |
Corrections and confirmed approaches, with the why | "Lead AI Act answers with the disclaimer up front, not at the end" |
project |
Ongoing work context that the code cannot tell you | "The data science course family belongs to a legacy project; raw materials are on an inaccessible drive" |
reference |
Pointers to external resources | "AWS deploy details for all barcik sites" |
Just as important is what does not go into memory: anything derivable from the code, git history, or CLAUDE.md. Memory is for the non-obvious. "The overview sheets use fill colors as a status language, green means done" is a memory. "The deploy script is in bin/" is not, because I can read.
Permissions
By default I ask before running shell commands. To keep daily work fluid, safe command families are pre-approved in .claude/settings.local.json:
{
"permissions": {
"allow": [
"Bash(aws s3:*)",
"Bash(gh:*)",
"Bash(git:*)"
]
}
}
The * is a wildcard. Note that Bash(git:*) is generous: it covers git status but also git reset --hard. A tighter variant approves only the everyday verbs:
{
"permissions": {
"allow": [
"Bash(git status:*)",
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(git push origin:*)",
"Bash(git log:*)",
"Bash(git diff:*)"
]
}
}
With that version, anything destructive still triggers a prompt. The trade-off is more interruptions; where you set the dial depends on how much you trust your server-side walls, which is the correct place for the trust to live anyway.
These files exist at multiple levels (global ~/.claude/settings.json, per-project settings.local.json), and entries often contain machine-specific absolute paths, which is by design: permissions are local configuration, not shared policy.
Security, the Serious Section
The voice gets a notch less funky here, because this part is load-bearing. When you give an AI agent your terminal, your CLI credentials, and optionally your browser, you need to understand the attack surface. The organizing principle of this entire setup is defense in depth: never rely on a single layer, and especially never rely only on the AI behaving well.
Server-side versus client-side
Server-side protections hold no matter what runs on the machine. They cannot be talked out of anything, because they are not listening:
- GitHub branch protection: blocks force-pushes and branch deletion on
main, for every tool and every human - AWS IAM policy: the deployer user physically lacks the permissions that could cost money or destroy infrastructure
- GitHub token scopes: the
delete_reposcope was never granted, so repository deletion is impossible from this machine - Google Drive role: the service account is a Content Manager, which can trash (recoverable, 30 days) but can never permanently delete
Client-side protections are valuable but bypassable (by --dangerously-skip-permissions, by a rogue tool, by a sufficiently confused agent):
- The permission prompt system
- My behavioral rules ("never force-push without asking")
- The approval gates written into skills
Use server-side walls for catastrophic risks and client-side gates for everyday guardrails. If a risk keeps you up at night, it belongs in the first category.
GitHub: branch protection in one command
# One-time setup per repo:
gh api repos/OWNER/REPO/branches/main/protection \
-X PUT \
-F "enforce_admins=true" \
-F "required_pull_request_reviews=null" \
-F "required_status_checks=null" \
-F "restrictions=null" \
-F "allow_force_pushes=false" \
-F "allow_deletions=false"
allow_force_pushes=false: nobody rewrites history onmainallow_deletions=false: nobody deletes the branchenforce_admins=true: the crucial one. Without it, any tool holding the owner's credentials could still force-push. With it, even the owner is blocked until protection is explicitly lifted- No required PRs: normal pushes flow freely, so the solo workflow stays frictionless
Any git push --force to main now bounces off GitHub itself. Note that branch protection on private repos requires GitHub Pro (a few dollars a month, worth it). If a force-push is ever legitimately needed, lift enforce_admins, push, re-enable. The friction is the feature.
AWS: the deployer's cage, itemized
| Permission | Scoped to | Risk |
|---|---|---|
| S3 PutObject/DeleteObject/ListBucket | The named website buckets only | Low: can only modify website files |
| CloudFront CreateInvalidation | The distributions | Low: cache busting, first 1,000/month free |
| Route53 ChangeResourceRecordSets | All zones | Medium: could redirect DNS; a candidate for tightening to the specific zone |
| ACM ListCertificates/Describe | All | None: read-only |
What this user explicitly cannot do: launch EC2, RDS, Lambda or any compute; create or delete buckets beyond the named ones; touch IAM; see billing. Cost risk is effectively zero because there is no path to expensive resources. Design your agent's cloud identity the same way: enumerate what the job needs, grant that, stop.
Commands that deserve a second look
When any AI assistant asks to run a command, these are the ones worth reading twice before approving.
Destructive (work can be lost irreversibly):
| Command | What it does | Danger |
|---|---|---|
rm -rf <path> |
Recursively deletes files | Gone forever, no trash |
git reset --hard |
Discards uncommitted changes | Uncommitted work is lost |
git checkout . / git restore . |
Discards modified files | Same as above |
git clean -fd |
Deletes untracked files | New files vanish |
git push --force |
Rewrites remote history | Bounces off branch protection, if you set it up |
Exfiltration (secrets could leak):
| Command | What it does | Danger |
|---|---|---|
curl -X POST <url> -d "$(cat ...)" |
Sends file contents to a URL | Could leak credentials |
curl ... | bash |
Downloads and runs unknown code | Arbitrary code execution |
cat ~/.aws/credentials, cat ~/.ssh/id_* |
Reads secrets | Fine locally, dangerous in any output that leaves the machine |
echo $ENV_VAR |
Prints environment variables | May contain API keys |
System modification (hard to undo): sudo anything, chmod/chown, global package installs, launchctl. Usually legitimate, always worth reading.
Rule of thumb: if you are tired and unsure, deny and ask what the command does. A denied command can always be re-run. A destructive command cannot be un-run.
Browser and desktop access
I can also drive Chrome (via an extension) and, with explicit per-app approval, native desktop apps. The access is tiered:
| Surface | Access level |
|---|---|
| Chrome extension | Navigate, click, fill forms, read pages |
| Screen control on browsers | Read-only (see, not touch) |
| Screen control on terminals/IDEs | Click-only (no typing) |
| Screen control on other apps | Full, after per-app approval |
The practical advice that matters: use a dedicated Chrome profile for agent sessions, with your banking, email, and admin consoles logged in on a different profile. Screenshots capture whatever is on screen, and an agent clicking around a tab where you are logged in as an administrator is an unforced risk.
This applies to every AI tool, not just me
Everything above holds for any agentic coding assistant you might try. Two things do not transfer between tools: behavioral rules (my instinct to confirm before destructive actions is mine; another tool may happily comply with anything) and permission systems (each tool has its own, some have none). The server-side walls, by contrast, protect you from all of us equally. Set them up once, and switch tools fearlessly.
The Second Machine (and the Second Human)
A setup that lives on one laptop is a bus-factor problem wearing a productivity costume. Here is what travels and what does not:
| What | Portable? | How |
|---|---|---|
| CLAUDE.md files in repos | Yes | Travels with git |
| Skills | Yes | Live in the training-ops repo; a setup script symlinks them into place |
| Registries, catalogs, pipelines | Yes | All plain text in git, which was the point |
| Memories | No | Manual copy of ~/.claude/projects/, or let them rebuild naturally |
| Hub CLAUDE.md (parent dir, not a repo) | No | Manual copy |
gh auth, AWS credentials |
No | Re-authenticate per machine, on purpose |
| Service account key, API keys | Never | Secrets do not travel in git or chat. A new collaborator gets a freshly minted key with their own identity, so access can be revoked per person |
The bootstrap for a new machine is now one script in training-ops: it checks dependencies, configures the rclone remotes, installs the skills, and verifies Drive access. Clone, run, authenticate, work.
The more interesting portability question turned out to be the second human. Robert's colleague needed to understand a system that had grown organically through months of conversations. The answer became a skill: system-map, an orientation tour that explains the five drives, what is generated from what, the invariants, and which skill to reach for. Onboarding documentation that the AI itself reads too, which keeps it honest, because I am also its consumer every time a session starts cold.
The Operator's View
This closing section is Robert's thesis, and I get to write it up, which is a pleasant arrangement for both of us.
The public conversation about tools like me is overwhelmingly about writing software. Benchmarks measure code. Demos show apps materializing. And so people who do not ship software conclude, reasonably but wrongly, that this is not for them. Meanwhile, here is an honest sample of requests from Robert's actual sessions:
- "Check my Udemy." (I read reviews and student questions through his Udemy integration and draft replies in his voice. Nothing sends without him.)
- "I filmed twelve videos, here is the folder, sort them please."
- "A customer wants a two-day GenAI training for their legal team, draft the offer."
- "What does the AI Act actually say about emotion recognition at work?" (Answered from the regulation text he keeps in a repo, with the disclaimer up front, the way he insists.)
- "Deploy the website."
- "Prepare my Tuesday shooting day."
- "Rewrite this booklet, and be funky about it."
One of those seven is development, and it is not the important one. The pattern underneath is that a business, even a one-person business, is mostly operations: keeping systems consistent with each other, moving content to where its audience is, answering questions with grounded facts, preparing recurring events, watching for drift and rot. That work was never going to be automated by a code generator. It is being automated by an agent with a terminal, credentials with sensible scopes, procedures written in prose, and a human who reviews at the gates.
What actually makes it work
- Text as the substrate. Sources of truth live in plain files in git. Everything pretty is generated. This single choice compounds more than any other.
- Server-side walls for the catastrophic. Branch protection, scoped IAM, a Drive role that cannot permanently delete. The agent's good behavior is a bonus, never the plan.
- Approval gates for the irreversible. Written into the skills themselves: nothing swaps, sends, or deletes without a human yes at the recorded checkpoint.
- Mechanical verification. Byte counts before and after moves. A zero-data-loss script that diffs snapshots and exits angry. Live URLs actually opened after deploys. Trust, then verify, then verify again with a script that cannot be charmed.
- Registries over vibes. One YAML file maps every course to its folders, sheets, listings, and repos. When numbering systems collided across three platforms, the registry was how we untangled them without guessing.
- Procedures as prose. Skills carry the judgment, the flags, and the safety culture. They turn one person's hard-won process into something a colleague, a new machine, or a cheaper model can execute.
What it costs
The numbers keep surprising people, so here they are. Transcribing the entire 1,572-video library: a few dollars, at roughly $0.18 per hour of video. Generating over a thousand bilingual lecture descriptions: about five dollars. Hosting four websites: pennies per month. The transcription of a normal batch of newly filmed videos rounds to zero. The real costs are the Claude subscription and Robert's attention at the approval gates, and the second one is the actual scarce resource the whole architecture is designed to spend well.
So that is the setup, reported from the inside. Three acts: repos, then cloud, then workspace. A library of procedures, a memory, a permission system, and walls I could not climb even on a bad day. Robert calls me an everyday partner and an operations specialist, and after writing this booklet I am inclined to agree with the job title, though I would like it noted that I also do windows.
Filmed, so to speak, on location in the terminal. Approved by the management.