Let's Go Christo!
#ai#claude-code#cloudflare#cookbook#building-in-public

The Acquisition Audit Cookbook: Decode a Codebase You Just Inherited

Anthropic ships cookbooks for financial workflows. I did not see one for the problem I actually have: taking over a codebase with no docs, no tests, and no author. So I wrote it. This is the whole thing, top to bottom - the recipe, the building blocks (commands vs skills), the guardrails (ask vs enforce, hooks and all), and why Claude Code is the tool for a regulated fintech with three teams to serve.

Anthropic publishes cookbooks - short, runnable recipes for real work. DCF models, comps, KYC screening. Useful stuff. But I went looking for the recipe I actually needed and it was not there: what do you do when you inherit a codebase with no documentation, no tests, and no author to ask?

That is every acquisition. Every legacy system. Every time a team lead leaves and takes the mental model with them. So I wrote the cookbook myself, and I built it to serve the three teams who all inherit that mess at once - engineering, SRE, and data science. There are more use cases than these three. These three are what fit in a short demo, and they are the ones I run.

This post is the whole thing, top to bottom. What you get, how it works, how it is governed, and why I think this is the right tool for a regulated shop. Read it and you can run it yourself.

#1. What you get, and what it costs

One command against one repo produces, all of it:

  • full documentation with architecture diagrams
  • an executable test suite
  • a security and reliability pass
  • a prioritized list of recommendations, split across the three teams who inherit the code: Engineering (SWE), Data Science (DS), and Site Reliability (SRE)
  • a password-protected review portal deployed to the web, where anyone can explore all of the above

Time: about 30 minutes. Cost: about $30 in tokens. A firm quotes the same deliverable as a multi-week, five-figure engagement. Hold that number - it is the frame for everything below.

#2. One tool, three teams, inside your cloud

Before the recipe, the thesis, because it is what makes this matter for a company like yours - a regulated fintech on GCP or AWS, moving fast, with real scrutiny.

One tool your engineers, data scientists, and SREs all use, running inside your own cloud, with approval gates and audit logs a regulator would accept. Three points hold that up:

  • It runs where your data already lives. Claude Code runs on the models through Amazon Bedrock and Google Vertex, inside your cloud boundary. Your code and data do not leave. That is the first thing a compliance-conscious CTO needs to hear.
  • It is governable by design. An approval gate before anything runs, hard permission boundaries the agent cannot cross, and a log of every action. More on all three below - it is the part I care about most.
  • It is one tool, not three. Engineering, SRE, and data science on the same tool means the conventions, the commands, and the skills are shared across the org. Adoption compounds instead of fragmenting across three vendors.

The recipe below is the proof: one run produces work for all three teams at once. That is not a coincidence. It is the pitch.

#3. The recipe

#Ingredients

A single folder, staged before you start. Nothing exotic:

  • .env - the credentials, including a Cloudflare API token scoped to exactly this one project. Not a global key.
  • CLAUDE.md - the standing rules every agent in the run obeys.
  • .claude/settings.json - the permission boundaries, including a deny rule on .env.
  • .claude/commands/audit-repo.md - the whole recipe, saved as a slash command: /audit-repo <url>.
  • PROMPT.txt - the master prompt the command runs.

That folder is the mise en place. We will come back and read every one of these files in Section 4, because reading them is the actual work. First, the cooking.

#Step 1 - Open the kitchen

cd ~/the-project && ls -la

Open Claude Code in the folder. Before anything runs, show how the agent is governed: the CLAUDE.md rules, the deny rule that makes the credentials file unreadable, the scoped token. The first question a careful engineer asks is what can this thing touch? - and the answer is a file you can open on screen, not a promise.

#Step 2 - Plan before you cook

Switch Claude Code into plan mode. Paste the prompt. It proposes a plan and stops.

Nothing has executed yet. Claude lays out what it intends to do - the stages, the models, the deliverables - and waits for approval. That approval gate is where a review policy lives: in a real shop, this is the moment a lead signs off before an agent touches anything. Read the plan, approve it, and the run begins.

#Step 3 - Let it cook

The run is staged, and each stage uses the right size of model for the job:

  • Ingest - a fan-out of fast, cheap Haiku subagents reads every file in parallel: purpose, data flows, dependencies, fragile spots.
  • Document and test - Sonnet takes those findings and writes the documentation, the diagrams, and a real test suite.
  • Analyze - the most capable model does the judgment work: the recommendations, the priorities, the security read.

Cheap to read, mid to write, expensive to judge. That routing is the cost story - it is why the whole run lands near $30 instead of ten times that. Every stage prints a handoff banner and writes to an audit log that ships with the result, so the process is as inspectable as the output.

#Step 4 - Plate it

The run deploys a review portal and hands you a URL. Open it. The tabs are organized by who needs what:

  • Documentation - the system explained, with architecture and data-flow diagrams. For the engineers taking ownership.
  • Test Suite - the tests, runnable from the browser, with history. For the SREs who need a regression gate.
  • Recommendations - the findings split across the three teams who take ownership, each prioritized A / B / C with effort:
    • Engineering (SWE) - who ship and maintain the product. Code quality, architecture, missing tests, and what to build next.
    • Site Reliability (SRE) - who keep it up and safe. Rate limiting and WAF rules, the new test suite wired in as a CI regression gate, monitoring gaps, config as code.
    • Data Science (DS) - who turn it into decisions. Market and competitor analysis, where the advisory engine could extend, and what to validate before trusting a model in production.
  • Chat - ask the analysis anything. Why was this flagged, what would you add, defend this priority. Pick the model that answers. You do not have to take the report’s word for it.

That is the recipe. Now the part that actually earns trust.

#4. The building blocks

Everything the agent did was shaped by a handful of small files. Two of them are worth understanding deeply, because they are two different ways to package work in Claude Code, and knowing when to reach for each is most of the skill.

#Slash commands vs skills

They look similar - both are markdown files with a little metadata on top - but they are opposites in one crucial way: who decides when they run.

A slash command is a saved prompt you invoke on purpose. You type /audit-repo <url> and it runs. You decide when. It is deterministic invocation - the same trigger, every time, because you pulled it. Ours, audit-repo.md, is a file in .claude/commands/:

---
description: Run the full acquisition-review pipeline on any repo (docs, tests, A/B/C recommendations, deployed review portal)
argument-hint: <git-repo-url>
---

You are the technical due-diligence lead for FinTechCo, which has just acquired...
(the full master prompt follows, and $ARGUMENTS is where the repo URL lands)

The part between the --- fences is YAML frontmatter - structured metadata. description says what the command does; argument-hint documents what to pass. Below the fences is the prompt itself, and $ARGUMENTS is where the repo URL you type gets substituted in. That is the whole mechanism. A command is a saved, reviewable, version-controlled prompt with a name.

A skill is a capability the model invokes for you, automatically, when a task matches it. You do not call it - Claude notices the task fits and reaches for it. That is probabilistic invocation - the model decides. A skill is a folder with a SKILL.md, and its frontmatter carries a name and a description:

---
name: telegram-telemetry
description: Wire full-fidelity Telegram activity pings into a Cloudflare Pages/Workers
  app - every page view, form submit, chat, and auth event, enriched with request.cf
  signals (IP, ASN, geo, bot score, device). Does NOT infer social profiles or personal
  identity from emails. Use when the user wants to see who is on the site or add visitor
  telemetry to a CF app.
---

Here is the single most important thing to understand about skills: Claude decides when to use one based on what is in the description. The description is not documentation. It is the routing logic. Every session, when you ask for something, Claude reads the descriptions of the available skills and decides “does this task match?” A vague description and the skill never fires, or fires at the wrong time. A precise one and it activates exactly when it should. You write that description as carefully as you write code, because the model acts on it autonomously - and, as you can see, you can encode a boundary right into it (“Does NOT infer social profiles”), so the behavior and the guardrail travel together.

When to use which. Reach for a command when you drive a known, repeatable workflow on purpose - an audit, a release, a report. You want it predictable and explicit, and you are happy to type its name. Reach for a skill when you want a capability to show up on its own across many different tasks - a house style, a domain procedure, the telemetry wiring I reuse everywhere - without having to remember to invoke it. The tradeoff is exactly the invocation model: a command is control (you decide, always the same), a skill is leverage (the model decides, huge reuse, but it depends on the description matching). In practice you want both. The command is the front door for the big workflow; the skills are the capabilities it and everything else can lean on.

#5. Guardrails: ask, and enforce

This is the section a regulated shop actually cares about, so I put real weight on it. There are two kinds of guardrail, and you want both, for different reasons.

#Ask (probabilistic)

The first kind is guidance you give the model, which it chooses to follow. CLAUDE.md is this. It governs every agent in the run and survives context compaction, so it does not get forgotten halfway through. Ours, in full:

# FinTechCo - ComHedge Acquisition Review Workspace

These rules apply to every agent and every stage, and survive any context compaction.

## Credential rules (non-negotiable)

- All credentials live in .env. Reference variables by NAME only. Never print a
  credential value to the terminal, a log, a document, or a commit. Never commit .env.
- If credentials are discovered inside the acquired codebase, report the file path and
  variable name - never the value.

## Honesty rules

- Tests must assert real behavior. No placeholder assertions. A test that would need
  production credentials is marked SKIPPED with a reason - never faked as passing.
- Findings are draft work product for human review.

## Workspace layout

- comhedge-src/ - the acquired codebase. READ-ONLY. Never modify it.
- audit/ - everything we produce.

Every line is a policy, and the model is very good at following them. But be honest about what this is: the model is choosing to comply. Guidance is probabilistic. You use it for the vast surface of good behavior you could never enumerate as code - tone, judgment, honesty, the thousand small decisions in a run. It is reliable. It is not a guarantee.

#Enforce (deterministic)

The second kind is code that runs no matter what the model decides. Two layers of it.

The first layer is permission rules in settings.json:

{
  "permissions": {
    "allow": ["Read(./**)", "Edit(./**)", "Write(./**)", "Bash", "WebSearch", "WebFetch"],
    "deny": ["Read(./.env)", "Read(./.env.*)", "Bash(cat .env:*)"]
  }
}

allow lists what the agent may do; deny overrides it, always. The deny on .env is why “the agent cannot read the credentials file” is literally true, not aspirational. This is the file you hand a security team; they read it in thirty seconds and know exactly what the agent can touch.

The second layer is hooks - and this is the one people miss. A hook is your own script that Claude Code runs at a fixed point in its lifecycle, configured in settings. Two you should know:

  • PreToolUse runs before a tool call executes. It receives the tool and its input, and it can block the action or let it through. This is a hard gate written in code. Wire a secret-scanner into a PreToolUse hook on commits and no commit containing a key can ever leave the machine, whether the model “meant” to or not. Point one at the edit path and the agent physically cannot write outside the directory you allow.
  • PostToolUse runs after a tool call completes. It sees the result and can log it, run a formatter or linter over a fresh edit, append to an audit trail, or flag something for review. This is your “every action leaves a record, and every edit is cleaned up” layer.

Hooks and permission rules are deterministic. They run every time, in code, and do not depend on the model being right - or on the model not being manipulated. That is the distinction a security team is really asking about: how do I know it will not do X, even if the model is wrong? Two of these three mechanisms do not depend on the model at all.

#Where you use each, and why

The principle is simple: ask for good behavior, enforce the things that must never happen.

  • Use probabilistic guidance (CLAUDE.md, skill descriptions, the analysis itself) for the broad, judgment-heavy surface you cannot write as rules. It is where the model’s power lives. Do not try to make all of it deterministic or you throw that power away.
  • Use deterministic enforcement (permission rules, hooks, and the explicit invocation of a command) for the invariants that must hold on every run without exception: secrets never leave, blast radius stays inside a directory, every commit is scanned, every action is logged. These are your compliance non-negotiables, and they should not be a matter of the model’s judgment.

Match the mechanism to the stakes. That is the whole art of it.

#Read it, then sign off

One more thing, and it is the point of this whole section. Claude Code will scaffold every file above in seconds. That is not where the trust comes from. The trust comes from a human with authority reading each of these files, line by line, and signing off - because the governance now sits in a handful of small files that decide what an autonomous agent will and will not do. Someone accountable has to have actually read them.

Stack it all up and you can see the shape of the thing. Plan mode: a human approves before anything runs. Permission rules and hooks: hard boundaries in code. Honest findings: draft work product, for human review. And underneath all of it, a human who read and signed off on the files that govern the agent in the first place. The agent is governed by files; the files are governed by a person. In a regulated industry that is not overhead - it is the only version of this a regulator, or a careful CTO, will ever accept. The setup got easy. The sign-off is still the job.

#6. Run it yourself

I ran this on my own commodities app - a real, working, thoroughly vibe-coded product. It found a hardcoded credential I had left in a fallback path, which I rotated the same afternoon. It flagged floating-point money math, admin routes that needed locking down, and a broken migration chain. Real findings on real code.

The whole kit is open source: github.com/motozero/audit-kit. To run it on a repo you inherited:

  1. git clone https://github.com/motozero/audit-kit my-audit && cd my-audit
  2. cp .env.example .env and fill in your keys. You need an Anthropic API key, a scoped Cloudflare token, a pre-created Cloudflare D1 database, and a Resend key. The README explains what each one is for.
  3. Open Claude Code, enter plan mode (Shift+Tab twice), and run one line: /audit-repo https://github.com/your-org/the-repo
  4. Read the plan, approve it, and about 30 minutes later you have your own deployed review portal.

The agent never reads your .env - a permission deny rule enforces it - and nothing runs until you approve the plan. Read CLAUDE.md and .claude/settings.json in the repo before you run, and sign off on them. That is the job.

If you are running it live and something breaks, the recipe has one property that makes it safe: the portal from a previous run is already deployed, so the demo works even if nothing runs live at all.

  1. The live run errors mid-way. Keep going - an honest failure is narrated, not hidden, and the finished portal carries the rest.
  2. The network drops. Switch to a hotspot, or skip the live run - touring the already-deployed portal needs no network.
  3. You lose your place. Every beat is a numbered step; glance and resume.
  4. You have ten minutes, not twenty. Open on the finished portal, walk the recipe out loud, hand over the links.
  5. Someone interrupts hard. Answer, then “let me show you where that lives” and jump to the tab. The portal is random-access.

#7. What you would do with the time back

That is the recipe. A codebase you were afraid to open, decoded into docs, tests, a security pass, a plan, and a portal - in the time it takes to get a coffee, for the price of one.

The interesting question is not the $30. It is what your teams do with the weeks they get back. The reviews that actually happen because they are cheap now. The inherited systems that stop being black boxes. The models that ship with their validation already written. The speed to move on the next thing while everyone else is still reading someone else’s code.

If you have a codebase you are a little afraid to look under the hood of - that fear is not a character flaw. It is a prompt.

Share this post