Working with Claude
A working method for shipping production software with AI — the loop, six pieces of real work, and the limitations nobody advertises.
Scott Allen Willis · Enterprise Distribution Software Specialist
What We'll Cover
1
The method — and the one step most people skip
2
Six pieces of shipped work, and what each one cost to get wrong
3
Choosing a model tier, because the largest is rarely the right one
4
What I got wrong, and the limitations nobody advertises
Ten minutes · the detail is in the long-form version, and the rest is a conversation
How I Actually Work with Claude
These aren't tips from a blog post. They're patterns I learned by shipping real things and failing first.
1Know what "done" looks like before you start — I decide the exact output format before writing a single prompt. Vague asks get vague results.
2Give it real data, not descriptions of data — I paste actual queries, actual error messages, actual court documents. Summaries lose the details that matter.
3Be surgically specific when something's wrong — "Row 47 returns NULL on the join" gets fixed in one round. "It's broken" gets five rounds of guessing.
4Re-establish context every session anyway — Correction, August 2026: Claude does remember now. On paid plans it searches past chats and generates a memory summary automatically, scoped separately per Project. I still paste the context file, because curated memory beats extracted memory for hard constraints — I choose what survives instead of finding out afterwards what it kept.
5Nothing ships until it's copy-paste ready — No placeholder text, no "insert X here." If I can't deploy it or file it immediately, it's not done.
The Loop
Define done → draft → test against reality → precise feedback → ship or repeat. Most people stop after the draft, which is why most people conclude the tool does not work.
1 · Define done
Before a word is typed. "Copy-pastes into the live environment with zero errors" is a target. "Good" is not. A fuzzy definition produces a fuzzy output and there is no prompt that recovers it.
2 · Draft on real artifacts
Actual code, actual logs, actual data — never a summary of them. State the hard constraints up front, then leave the first pass alone.
3 · Test against reality
This is the step that gets skipped, and it is the whole value. Run it in dev. Deploy it and send traffic at it. The model lives in word-space; production does not.
4 · Feedback precise enough to converge
"Make it better" wanders. "Line 47 throws on the temp buffer because the alias only exists in the older code path" converges. Reproducible beats vague.
5 · Ship or repeat
Two outcomes, no third. Ship means it passed production with no caveats. Repeat means back to step 3 with new failure data. Never "one more prompt".
Keep it tight
A context file carried into every session, a library of what shipped and the feedback that got it there, and a hard 15–20 minute cap per loop. If it is not converging, step 1 was wrong — go back, do not prompt harder.
The loop is model-agnostic. The leverage is in the discipline, not the vendor — and the human stays the domain expert throughout.
Auditing 300+ Database Views
The Process, Not the Tech
I fed Claude real production queries one at a time — not theoretical examples. It identified performance patterns I'd been living with for years. Things that looked correct but were silently slow.
We worked in batches: 7 scripts first, then 62 more. The second batch revealed a critical lesson — Claude generated placeholder syntax in several scripts. My "nothing ships until it's ready" rule caught every one before production.
The AI accelerated the work. My standards were the quality gate.
~27%
performance improvement
measured after deployment
Replacing What Nobody Understood
9 Macros → 1 Automation
The warehouse ran on 9 fragile Excel macros that nobody fully understood. Instead of documenting them, I described the end-to-end workflow to Claude — scan, look up, validate, ship — and we rebuilt it from the intent, not the legacy code.
Tested against legacy output until we hit 99%+ match. The team validated daily before we cut over.
Migration: Conversation as Strategy
Multiple locations needed to move between enterprise distribution platforms. Instead of hiring a consultant, I walked Claude through the data domains one by one and we built a phased migration plan together.
The mapping strategy came out of conversation. The domain knowledge came from me. The structure came from the collaboration.
Closing a Data Exposure
The Hole
A members table held real personal data — names, emails, phone numbers, cities. The page read and wrote it directly from the browser using a key printed in the page source, scoped by an email address the database had no way to verify.
From an unauthenticated browser, that table returned 200 and every row. It now returns 401.
The Fix
All four operations moved server-side behind a function that takes the caller's identity from a verified ID token — signature checked against the provider's public keys — and ignores whatever the request body claims. The browser key and client-side database SDK are gone from the page. Row-level security enabled and forced, public grants revoked, and 36 assertions covering forged, expired, unsigned and tampered tokens.
Two traps worth carrying to any project. The table already had four dormant access policies, inert only because row-level security was switched off — enabling it would have activated them. Revoking the grants is what saved it, because privilege denial is evaluated before policies are. And do not write a policy matching a token claim when your identity provider is not the database's own: the claim is null, the policy matches nothing, and it looks exactly like working access control.
The Bugs Nothing Reports
Three production faults that returned no error, logged nothing, and read correctly in every file involved.
Six months of 404
Two redirect config files, one silently outranking the other. A rule in the losing file never runs and nothing says so. One endpoint 404'd for six months; another for two days. Both files were individually correct.
Two hyphens
A -- inside an XML comment is illegal and makes the entire sitemap not well-formed. Search Console reported "couldn't fetch", zero pages indexed — while the URL returned 200, the right content type, the right length, and fetched fine as the crawler. Nothing in the response reveals it. Only parsing does.
A year-old stylesheet
Assets served immutable for a year with no fingerprinting. Ship markup that needs a new class without bumping the version token and returning visitors get unstyled pages for up to a year — and it looks perfect to you, because your first visit fetched both fresh.
The common thread: every one of these passes review, passes config validation, and produces no error anywhere. The only thing that finds them is probing the live URL and parsing what actually comes back. Config that reads correctly is not evidence.
Never Put a Credential on the Critical Path
What Happened
Two public forms sent an email and returned success only if the send worked. When the mail credential died, every submission returned an error and was destroyed — the handler logged only the domain of the address, never the address itself, so there was nothing to recover from. Two real people who wrote in over two days were lost that way.
The forms now record the submission first and notify second. Read it, write it down, then try to send it.
The Part That Only Failed in Production
The mail handshake was measured at 28.7s, 2.3s, 21.5s, 22.4s and 1.5s. The timeout was 7 seconds, so roughly half of all sends aborted — in production only, while identical code worked locally every time.
I initially wrote the slow handshakes off as an artifact of my home connection. That assumption cost more time than the bug.
Generalise it: anything that can fail independently of the user's intent belongs after the durable write, not before it. A form whose success depends on a third-party credential is a form that quietly deletes messages the day that credential expires.
Proving a Refactor Changed Nothing
Don't Reason About It. Measure It.
For a mechanical change across many files, "I read the diff and it looks equivalent" is not a claim you can support. So: check out the pre-change tree, serve both versions on two local ports, and for every rendered element read about twenty computed properties, concatenate and hash them. Compare the hashes. Compare the geometry too.
Then investigate every mismatch before shipping.
What It Caught
Two real bugs that produced no console error and looked fine in the diff.
Three pages had a style block inside an inline SVG. Swapping it for a stylesheet link in place does nothing — SVG has no such mechanism — and the diagrams would have shipped unstyled.
Converting 1,316 inline styles to classes silently lost six declarations to higher-specificity rules.
Instrument the instrument. Always measure one file the change never touched. If the control reports differences too, your checker is broken, not the site — that is exactly how a run of false positives got caught before it buried the one real error.
Route Across Tiers, Not Just Vendors
The previous slide routes work across four companies. The cheaper, higher-leverage version of the same idea routes it across tiers inside one of them — and for two years I did not do it. Every task got the biggest model, which is the same mistake as running every report on the production server.
| Model | What Anthropic says it is for | What I actually send it |
| Haiku 4.5 | The fastest model with near-frontier intelligence | The 62-script batch. Mechanical, high-volume, verifiable by diff |
| Sonnet 5 | The best combination of speed and intelligence | Most of the loop. Drafting, refactors, dashboard work |
| Opus 5 | Complex agentic coding and enterprise work | The immunity briefing. The migration plan. Anything I would regret getting subtly wrong |
| Fable 5 | Next-generation intelligence for long-running agents | Long autonomous runs I check on rather than watch |
The routing rule is the delegation rule. Give the expensive model the ambiguous, high-consequence work and the cheap model the well-specified, easily-checked work — which is exactly how you would staff it if the models were people. Switch with /model in Claude Code or the model picker in the app. Prices, context windows and tier descriptions are on the models page in the sources at the end.
What I Got Wrong (Honest Version)
Over-Engineering
Not every problem needs a pipeline or a multi-step workflow. Sometimes a clean prompt in a fresh session is faster and better than an elaborate system. I built complexity that didn't earn its keep.
Trusting Without Checking
Claude's Batch 2 placeholder bug taught me this permanently. The output looked right. It was structured correctly. But several scripts had syntax that would have broken in production. You lose nuance and edge-case details if you don't verify.
Forgetting the Tradeoffs
AI gives you speed, but speed costs something. You lose experiential texture. You lose the thinking-through-it process that sometimes is the point. I had to learn when to use Claude and when to just sit with the problem myself.
Building More Than Was Asked
I added impersonator-blocking to a firewall that only needed to let verified crawlers through. The pattern it matched also appears in a real consumer browser's user agent, so every reader using that browser got a 403 on every page.
An outside tool then reported the site as hostile to crawlers. It was not a policy. It was my unrequested feature. Verification now grants passage only — it never denies.
The rule I follow now: If the problem is well-defined and the output format is clear — delegate to AI. If the problem is ambiguous and I need to think — I do that myself first, then bring Claude the result.
The Honest Limitations
Everything in this deck is real. So is everything below. Anyone selling you Claude as a magic co-founder is lying.
Compaction loses thingsSharpened, August 2026: "the context window fills up and Claude summarizes" is real but it is not one uniform behaviour. In Claude Code it is auto-compaction, plus /compact on demand. On the API it is an opt-in beta you switch on, with a trigger threshold you set. On claude.ai it happens automatically only when code execution is enabled. Whichever surface you are on, the summary drops nuance and edge cases — it is not lossless. Know which one you are relying on before you rely on it.
Confidently wrongClaude produces answers that sound right and aren't — often enough that verification has to be a step, not a habit. I am not going to give you a percentage, because I have not measured one and neither has anyone quoting you a figure. Citations get fabricated. Working code gets rewritten unnecessarily.
Plausibility is not a signalFour substantive errors sat live on a reference site for months. One was repeated across four pages, and the worst of them was inside the structured data — the exact text search engines and assistants quote back. None were caught by re-reading or by asking whether the draft was right. All four came from opening the primary source and comparing.
Instructions get ignoredEspecially in long sessions. "Don't change X" gets violated. Re-state critical constraints in every meaningful turn.
Memory is real — and it is still not your system of recordCorrected, August 2026. The old version of this row said "default chat has no memory between sessions," and that is now wrong. On paid plans Claude searches past chats and generates a memory summary automatically, per Project, with citations back to the chats it drew from. What is still true is the part the old wording was actually about: memory you did not curate is a summary of what you happened to say, not a specification of what must hold. Incognito chats write nothing. Free accounts have no memory at all. Design for what you control.
The honest framing: Claude is a smart but unreliable junior — not a co-founder. The leverage comes from how you wrap it, not from the model alone. And tell it, explicitly, that saying "I don't know" is an acceptable answer. Models default to producing something; a model that has been given permission to return a gap will return a gap instead of inventing a bridge, and a gap is a thing you can go and fill.
How to Use Claude AI Effectively
Most people are using Claude wrong. They treat it like a chatbot. The most effective way to use Claude AI is as a production system — wrapped in a structured workflow with real artifacts, real tests, and tight feedback loops. This 14-slide presentation walks through that workflow with real case studies.
What Claude AI Actually Is
Claude is a large language model built by Anthropic for reasoning, coding, long-form writing, and tool use. The most effective way to use Claude is not "better prompting" — it is wrapping the model in a structured workflow. Prompting is Stage 1 thinking. System design is Stage 2 thinking. This presentation is about Stage 2.
What Most People Get Wrong About Claude
Three failure modes account for almost every "Claude isn't that useful" complaint: one-shotting it (no iteration, no verification), feeding it summaries instead of real artifacts, and treating the chat itself as the system instead of building a workflow around it.
My Actual Claude Workflow (Step by Step)
Step 1: Define the Output
Before you type a single word, know exactly what "done" looks like in production reality. Not "a good query" — copy-paste into the live environment with zero errors. Not "a legal-looking brief" — filed with zero procedural defects. If the target pattern is fuzzy, the output is fuzzy.
Step 2: Provide Real Context
Feed Claude the actual code, the actual error message, the actual log lines, the actual document. Never summaries. Summaries leak the exact signal Claude needs. Include hard constraints up front so the first draft doesn't violate them.
Step 3: Iterate and Debug
Test every draft against reality immediately. Document failures with surgical precision: "Line 47 throws an invalid handle on the temp buffer because the alias only exists in the older code path" beats "it's wrong" by an order of magnitude. Specific feedback is the convergence engine.
Step 4: Ship Only Production-Ready Work
Two choices: ship if it passes your production test with zero caveats, or repeat from step 3 with the new failure data. No "maybe one more prompt." The loop is sacred.
Hardening What You Shipped
Content Security Policy without unsafe-inline
A content security policy containing unsafe-inline is not a policy. Removing it means removing what made it necessary: inline event handlers, executable inline script blocks, style blocks, and inline style attributes. Across one site that meant 258 event handlers, 118 executable script blocks, 49 style blocks and 1,316 inline style attributes going to zero, taking the observatory grade from B to A+. Structured-data blocks are the exception — browsers do not execute them and the script directive does not govern them, so they correctly stay inline.
Auditing who can actually read your data
A browser-side database key plus row-level security that was never switched on meant a table of personal data returned every row to anyone who read the page source. Closing it required moving every operation server-side behind a verified identity token rather than trusting an email address supplied by the caller. Two traps generalise: dormant access policies already on the table would have activated the moment row-level security was enabled, so revoking public grants is what actually closed it; and a policy matching a token claim does nothing when your identity provider is not the database's own — the claim is null and the policy silently matches nothing.
Production bugs that report nothing
Three faults that produce no error and read correctly in every file involved: one redirect configuration silently taking precedence over another so a rule never runs (a six-month 404), two consecutive hyphens inside an XML comment making an entire sitemap not well-formed while the URL returns 200 with correct headers, and assets served immutable for a year with no fingerprinting so a stylesheet change without a version bump breaks returning visitors invisibly. Passing configuration is not evidence. Probe the live URL and parse what comes back.
Never put a credential on the critical path of a public form
A form that sends an email and reports success only if the send worked will destroy submissions the day the mail credential expires. Record the submission durably first, notify second. Related: transactional mail handshakes vary enormously — measured between 1.5 and 28.7 seconds against a 7-second timeout, aborting roughly half of all sends, in production only.
Proving a mechanical refactor changed nothing
Do not reason about equivalence, measure it. Serve the pre-change tree and the working tree on two ports, read roughly twenty computed properties for every rendered element, hash and compare, and compare geometry as well. This caught a style block inside an inline SVG that would have shipped diagrams unstyled, and six declarations lost to specificity when inline styles became classes. Always include a control file the change never touched, so a broken checker is distinguishable from a broken site.
Claude vs ChatGPT: When to Use Each
Neither Claude nor ChatGPT is universally better. Use Claude for long-context work, careful editing, conservative tone, and tool-use / agent workflows. Use ChatGPT for fast breadth-first ideation, the broader plugin ecosystem, and native image generation. An earlier version of this page said to use ChatGPT for "multi-modal work (images, voice)" generally, which is too broad and is corrected here: every current Claude model accepts image input and has vision, Claude reads PDFs, and voice mode runs in the Claude mobile, desktop and web apps. The defensible difference is image generation, which Claude does not do natively — it produces SVG, charts and code-built artifacts instead, or calls an image model through MCP. Most serious users keep both open and route work to whichever fits the task. Anyone telling you "X is always better than Y" is selling you something.
Common Mistakes That Break Claude
- Prompting in summary form instead of pasting real artifacts.
- Defining "done" in the middle of a session instead of before it starts.
- Letting context-window compaction happen silently and lose your earlier constraints — and not knowing which compaction your surface actually does.
- Trusting fabricated citations, library names, function signatures, or config flags without verifying — verify by making the model fetch and quote the source, not by asking it whether it was right.
- Skipping the test-against-reality step because the output "looked right."
- Re-prompting "try again" instead of giving a precise correction.
- Treating automatically generated memory as a specification. Claude does have cross-session memory on paid plans now, scoped per Project, but it is an extracted summary of past conversations — put constraints you cannot afford to lose somewhere you control.
- Never telling the model that admitting uncertainty is acceptable, and then being surprised when it invents rather than reports a gap.
- Sending every task to the largest model instead of routing by difficulty across Haiku, Sonnet and Opus.
Reusable Claude Workflow Template
Paste this at the top of any new serious Claude session. If you can't fill all six sections in before you start prompting, you're not ready to prompt — go figure out the missing piece first.
- Outcome (definition of done): What artifact will exist when this session is over? What test will it pass? Where will it be deployed or filed?
- Constraints (hard rules): Language, framework, version. Things you must NOT change. Style and format requirements.
- Context (real artifacts only): Paste the actual code, log, document, or data. Never summaries.
- One example of output that would count as done: A single worked instance of the thing you want. This section was added in August 2026 and it was the largest omission in the original template — a concrete example pins format, length, tone and level of detail in a way that no amount of describing them does. If you don't have a real one, write a fake one.
- Prior failures: What did the last attempt get wrong? What was the precise reason?
- Verification plan: How will you test the output before shipping? What command or step proves it works? Where a claim depends on an external source, require the model to fetch and quote that source rather than answer from memory — and state that returning "I could not verify this" is an acceptable, expected answer.
Frequently Asked Questions
What is Claude AI used for?
Claude is used for long-form writing, code generation and refactoring, structured reasoning over long documents, legal and technical drafting, data analysis, and as the LLM behind agent and tool-use workflows. Its strength is holding coherent context over many thousands of tokens.
Is Claude better than ChatGPT?
Neither is universally better. Claude tends to win on long-context work, careful editing, and conservative tone. ChatGPT tends to win on fast breadth-first ideation, the plugin ecosystem, and native image generation. Note that "ChatGPT for multi-modal" is out of date as a general claim: every current Claude model takes image input and has vision, Claude reads PDFs, and voice mode is available in the Claude apps.
How do you write good prompts for Claude?
The best Claude prompts are specific, not clever. State the outcome, paste real artifacts, list hard constraints, and include any prior failures so the model doesn't repeat them.
Can Claude replace developers?
No. Claude amplifies developers — it doesn't replace them. Without domain expertise to verify output and define what "done" actually means, you get confident-sounding garbage.
What is the biggest mistake people make with Claude?
Treating it like a search engine instead of a junior collaborator. The leverage is in the iteration loop, not in any single prompt.
Does Claude have memory between sessions?
Yes, on paid plans. Claude can search and reference your past chats and can generate a memory summary from your chat history automatically, capturing things like your role, preferences and ongoing project context. Memory is scoped separately for each Project, references are cited back to the original chats so you can see and delete what it drew from, and incognito chats are excluded entirely. Free accounts do not have it. Earlier versions of this page said default chat had no cross-session memory; that was true when it was written and is no longer true, and the correction is noted here rather than made silently. The workflow advice survives the correction: for constraints you cannot afford to lose, an externalized context file or Project instructions you wrote deliberately beats an automatically extracted summary, because you choose what persists rather than discovering afterwards what was kept.
Should I use Claude Code or the chat app?
Use the chat app when you are thinking, drafting or reasoning over documents. Use Claude Code when the work involves reading and writing files, running commands, and verifying its own output — audits, refactors, migrations, anything where the test-against-reality step can be automated. Cowork is for handing off a multi-step task and reviewing the finished result, and Claude for Microsoft 365 puts the same capability inside Excel, PowerPoint and Word. The iteration loop is identical on all of them; the surface only changes who executes the verification step.
Which Claude model should I use?
Route by difficulty rather than defaulting to the largest. Haiku is the fastest and cheapest and suits high-volume mechanical work that is easy to verify. Sonnet is the best balance of speed and intelligence and handles most day-to-day work. Opus is for complex agentic coding and enterprise work where a subtle error is expensive. Fable is the top tier, aimed at long-running autonomous agents. Consult the official models page for current context windows and pricing before committing to a tier.
Read the long-form blog version · Anthropic · Claude platform documentation · Claude Code documentation · SiegeStack home · ETL showcase · Case studies · Operations modernization