Last week I gave three directives on GitFlow Analytics—a project I’ve been building for several months to analyze git commit history and surface developer productivity patterns. Took me maybe three minutes total. Here’s the exact text:
Batch the classification requests to the LLM. Don’t call once per commit—accumulate, call once per batch.
Use a cheap model for commit classification. Haiku or Nova Lite. This is semantic triage, not reasoning.
Use Bedrock as the LLM provider, not the OpenRouter API.
Three sentences. Three decisions. And here’s what struck me when I looked back at them: each one lives in a completely different category of concern. The first is about performance shape. The second is about economics. The third is about infrastructure.
The AI didn’t suggest any of them. The AI implemented all of them.
That’s the pattern master dynamic in its cleanest form. Not a collaboration on what to build but a division of labor between someone who knows what constraints apply and something that knows how to implement against constraints. But naming the dynamic doesn’t tell you what it looks like from the inside. What are the actual moves? What’s the vocabulary?
TL;DR
Pattern mastery means issuing decisions the AI cannot generate from code context alone
These decisions cluster into six recognizable types: infrastructure, economic, performance, data integrity, architecture, and API hygiene
The GitFlow Analytics examples are real—batching LLM calls, cheap model for classification, Bedrock over direct APIs
Bug fixes reveal patterns too: ORM session discipline and immediate persistence both emerged from broken code
A pattern catalog—CLAUDE.md files, system prompts, project memory, reusable skills, commit standards, coding docs—is the actual artifact of this work
When you write the pattern down, you’ve written the spec
What’s Different About These Three
The “Irreducibles” piece from January explored what remains when AI handles implementation—judgment, context, accountability. This is the operational companion to that argument. Not what remains in the abstract, but what it looks like moment-to-moment when you’re actually doing it.
Those three sentences from GitFlow aren’t code review. They’re not debugging. They’re not feature requests. They’re architectural constraints applied before implementation, drawn from a vocabulary of patterns the AI has no access to.
Take the Bedrock decision. AWS Bedrock instead of direct OpenRouter API—why? Enterprise compliance considerations. Cost structure under AWS committed spend. An existing organizational relationship with AWS that makes the integration path smoother and the billing cleaner. None of that lives in the codebase. None of it is inferable from the commit history. The AI would happily call the OpenRouter directly, because that’s the path of least resistance and it works fine. The Bedrock decision requires knowing things about the operating context that only I know.
Model selection works the same way. The AI will use whatever model I give it. It has no opinion about whether commit classification warrants a $15-per-million-token model or a $0.25-per-million-token model—because it doesn’t have visibility into my cost structure, my volume projections, or my accuracy requirements. That’s an economic decision, and economics don’t live in code.
Batching is perhaps the clearest example. The AI will write a loop that calls the API once per item unless I tell it otherwise. Not because it’s careless. Because single-item calls work. They’re not wrong. They’re just expensive and slow at scale, and “scale” is context the AI doesn’t have unless I supply it.
So what’s actually happening in those three sentences? I want to be specific about this, because the abstract answer (”context” and “judgment”) is true but not actionable.
Six Types of Decisions
Working through the full GitFlow Analytics commit history—the decisions I made, the bugs that exposed missing decisions, the refactors that enforced constraints—the pattern master moves cluster into six categories. These aren’t theoretical. They reflect six different kinds of context that live outside the codebase, which is why the AI can’t generate them unprompted.
Infrastructure patterns. Where does this run? Who provides the compute, the APIs, the managed services?
The Bedrock decision lives here. Vendor agreements, compliance posture, cost structures under enterprise procurement, existing security reviews—none of this is in the code, and none of it should be. The AI implements against whatever infrastructure decisions you’ve made. Your job is to make them and say them explicitly.
This category is easy to overlook because it often feels like obvious overhead. Of course you pick your cloud provider before you write code. But with agentic coding tools, the AI starts writing before you’ve said anything, and it will happily accumulate implementation decisions that lock you into infrastructure choices you never consciously made.
Economic patterns. Which capability at what cost?
The commit classification decision lives here. Semantic triage—deciding whether a commit is a feat, a fix, a refactor, or a chore—is pattern matching against short text. It doesn’t require abstract reasoning. It doesn’t benefit from a frontier model’s broad knowledge base. Haiku gets it right at a fraction of the cost of Opus. The AI is agnostic about this distinction. You’re not.
This is what I built in GitFlow as tiered intelligence: spaCy-based processing for 85-90% of commits, LLM classification only for cases that stump the rule-based approach. The AI implements whatever tier structure you define. It won’t design the structure unprompted, because designing it requires knowing your cost tolerance, your accuracy threshold, and your volume projections—three things that only exist outside the codebase.
Economic decisions also include things like: when to cache aggressively, how much to pay for higher-quality embeddings, whether to process synchronously or batch asynchronously. These are all model-selection-style decisions applied to different dimensions. The principle is consistent: the AI will use the most convenient approach unless you specify the cost-appropriate one.
Performance patterns. How should the work be shaped?
Batching lives here. And the batching decision isn’t just “accumulate before calling”—it’s understanding the specific shape that LLM API consumption should take for a classification workload. Call overhead dominates cost at low item counts. Throughput constraints kick in at high item counts. The optimal batch size is a function of your specific model, your rate limits, and your latency tolerance. I know the rough shape of this tradeoff from experience. The AI doesn’t.
This category also includes: when to use async, when to parallelize, where to put caches, how to structure database queries for a read-heavy versus write-heavy workload. Performance decisions require knowing your actual performance requirements, which are rarely in the code. They’re in conversations with stakeholders, in capacity planning spreadsheets, in the incident retrospectives from the last time something got slow in production.
Data integrity patterns. What guarantees does the system make?
This one showed up twice in GitFlow bugs, and both times the pattern was identical: I had to specify what guarantee I wanted before the AI could implement it correctly. The code was running fine in tests. The guarantee was missing.
First bug: _store_commit_classification() was a no-op. It built a dict, then didn’t persist it. The function completed without error and did nothing useful. Fix: look up the CachedCommit row by hash, upsert a QualitativeCommitData row. Make re-classification idempotent. The actual guarantee I needed to specify was immediate persistence plus idempotency—write on completion, not on flush; upsert not insert, so re-runs don’t corrupt existing data.
Second bug: _classify_weekly_batches() loaded ORM objects in one session, closed the session, then tried to write to the detached objects. SQLAlchemy silently discarded the writes. No error. No traceback. Just missing data. Fix: collect IDs from the detached objects, re-query in the new session. The guarantee I should have specified earlier: objects are only writable inside their creating session. When you cross a session boundary, re-query by ID.
Both fixes look like debugging. They are. But debugging is often the moment when you discover a pattern was never specified. You thought you implied it. You didn’t. The pattern master’s job is to specify guarantees before the code demonstrates their absence.
Architecture patterns. What shape should the code take?
Two examples from GitFlow. First, the analyze() function. It had grown to approximately 3,700 lines in cli.py. One function. I extracted it into analyze_pipeline.py and analyze_pipeline_helpers.py. The analyze() body dropped from ~3,700 to ~1,255 lines. cli.py went from 5,621 to 3,446 lines—a reduction of 2,175 lines from a single extraction.
The AI is perfectly willing to write a 3,700-line function if you let it. It’ll maintain it, extend it, add features to it. Function length doesn’t register as a problem unless you’ve told the AI it’s a problem. Named pipeline stages—where the function body becomes a sequence of named sub-function calls, each of which is a meaningful concept—require you to specify that extraction is mandatory.
Second: the 800-line rule. json_exporter.py at 2,977 lines, extracted into six focused modules. narrative_writer.py at 2,912 lines, same. models/database.py at 1,632 lines, split into four files. The rule is simple: files over 800 lines have too many responsibilities. Split is mandatory, not optional. The AI doesn’t have this constraint unless you give it one. It’ll happily maintain a 3,000-line file because 3,000-line files work fine. They just don’t scale to teams or to the next developer who has to understand them.
API hygiene patterns. What standards does the codebase maintain?
GitFlow had datetime.utcnow() calls throughout—deprecated as of Python 3.12, with behavior changes in 3.13. Replace with datetime.now(timezone.utc). The specific fix is straightforward. The pattern is the interesting part: when you spot a deprecated API anywhere, fix it everywhere in that pass. Don’t let deprecated patterns accumulate across the codebase. Fix it all now, not later.
The AI writes code that works. You specify the standards it works to. “Works” and “meets our standards” are different bars, and the AI will consistently hit the lower one unless you’ve explicitly set the higher one.
Why the AI Can’t Generate These
The common thread across all six categories: the AI has no access to the context these decisions require.
It doesn’t know your vendor agreements. It doesn’t know your cost structure or your performance requirements or your data integrity guarantees. It doesn’t know your code quality standards or your organizational constraints. These things live in your head, in institutional memory, in agreements that predate the codebase by years.
There’s a version of this explanation that blames AI limitations—the model isn’t smart enough, the context window isn’t big enough, the training data doesn’t include your private Slack history. Some of that is true. But the deeper issue is structural. Even a perfect AI model couldn’t make the Bedrock decision correctly, because the right answer depends on your specific AWS relationship. There’s no amount of additional capability that would let the AI know your negotiated pricing tier or your compliance officer’s requirements. That information is local to you. It doesn’t exist in any dataset.
And the information exists in your experience. I know to batch LLM calls partly because I’ve seen the cost and latency impact of not batching on a project where we called once per row of a 50,000-row table. I know ORM session boundaries matter partly because I’ve lost writes to detached objects before, in a system where the silence made the data loss hard to find. I know 800 lines is too long partly because I’ve spent real time not understanding files that were longer—and spent even more time watching someone else not understand them.
The pattern catalog is built from things that went wrong. That’s probably why it doesn’t show up cleanly in training data—training data shows correct solutions. The scar tissue is in the incident reports, the postmortems, the Slack threads where someone figures out why the data is missing. The pattern master’s advantage isn’t superior knowledge of what’s right. It’s accumulated memory of what fails.
The Catalog Problem
Here’s what took me a while to see clearly: the actual deliverable of pattern mastery isn’t individual decisions. It’s the catalog.
Each time I issue one of those directives, I’m drawing from a mental library of patterns. “Don’t accumulate in memory and hope to flush later” is a pattern. “Upsert not insert for idempotency” is a pattern. “Route by complexity: cheap for bulk, expensive for edge cases” is a pattern. “Re-query by ID when you cross a session boundary” is a pattern.
Patterns that exist only in my head are fragile. I apply them inconsistently. I forget them between projects. I can’t hand them off. And with agentic coding—where the AI is running fast and making implementation decisions continuously—an inconsistently applied pattern is almost the same as no pattern at all.
So the work of pattern mastery is partly to externalize the catalog. This shows up in six specific forms:
CLAUDE.md files. Project-level instructions that tell the AI what the patterns are for this codebase. File size limits. Session discipline rules. API hygiene standards. Model routing decisions. These are patterns written down. Once written, the AI applies them consistently, every session, without re-prompting. The pattern becomes the specification.
System prompts for agent frameworks. If you’re running an orchestration layer—claude-mpm or similar—the system prompt is where you encode the patterns that apply to all agents in a session. Economic routing decisions. Infrastructure preferences. Performance shape requirements. The agents reference these constraints; you don’t have to re-issue them every time.
Project memory. Unlike a CLAUDE.md file, which you write consciously, memory accumulates from work. Tools like Kuzu Memory maintain a living record across sessions—bug patterns, architectural decisions, things that failed and why. The _store_commit_classification() no-op goes in memory. The detached-session data loss goes in memory. Next time a similar situation comes up, that context loads automatically. This matters because most patterns don’t get written down when they’re learned. They get written down when something breaks. Memory captures them at the moment of failure, not the moment of reflection.
Skills. Where CLAUDE.md files encode what’s true for this project, skills encode what’s true for this technology. A spaCy skill. An ORM session skill. An LLM cost-routing skill. Not project-specific—portable across codebases. You write the pattern once; every project that uses that stack gets it.
Commit message standards. The Conventional Commits format (feat:, fix:, refactor:, chore:) is itself a pattern—one that makes the fix:feat ratio calculable, which makes quality measurable. The pattern enables the metric. Without the commit message standard, you can’t see the ratio. Without the ratio, you can’t measure first-attempt success. The documentation convention is load-bearing infrastructure.
Coding standards documents. The 800-line rule. The session discipline rule. The immediate persistence rule. Written down once, applied by reference. The AI can cite them. New contributors can read them. You don’t have to re-derive them from first principles on every project.
When you look at it this way, a lot of what pattern masters do is write documentation. Not code documentation—pattern documentation. Code documentation describes what’s there. Pattern documentation specifies what must be true. The distinction matters because “must be true” is a constraint on all future implementation, including the implementation the AI will do tomorrow.
The Pattern is the Spec
There’s a version of the “what does a pattern master do” answer that sounds very abstract. Context management. Judgment. Domain expertise. True, but not particularly useful.
The concrete version: a pattern master issues directives the AI cannot generate, drawn from a catalog of patterns that encode context the AI cannot access. The work is fast when it’s going well—not because it’s easy, but because the catalog is deep and the pattern matching is fast. You recognize the situation, retrieve the pattern, issue the directive. Three seconds. Move on.
The batching directive—don’t call once per item—is three words with real economic and performance consequences. Three seconds to type. Years of seeing what happens when you don’t batch to know to say it.
The Bedrock directive is one word—a vendor name—that encodes an entire infrastructure decision tree. Three seconds to type. Years of working within enterprise compliance requirements to know why it matters.
The idempotency directive—upsert, not insert—is three words that specify a data integrity guarantee. Three seconds to type. One incident of watching corrupted data to know that guarantee was necessary.
The fast part is the delivery. The slow part is building the vocabulary to draw from.
One thing worth naming: the catalog is not static. When the _store_commit_classification() bug showed up—the no-op that silently failed—that was a pattern gap. I didn’t have “immediate persistence” explicitly in my data integrity vocabulary for this project. I thought I’d implied it. I hadn’t. The bug added the pattern. Now it’s written down. Now the AI knows.
That’s the feedback loop. Bugs reveal missing patterns. Missing patterns get documented. Documentation becomes the spec for future implementation. The catalog learns from its own gaps, but only if the human is paying attention to what each failure means.
That’s the actual job. The catalog comes from the career.
Bob Matsuoka is CTO of Duetto and writes about AI-powered engineering at HyperDev.
Related reading:
Don’t Be a Canut — Be a Pattern Master — Why pattern mastery matters: the Jacquard loom analogy and what it means for developers today
The Irreducibles: What a Pattern Master Does — What remains when AI handles implementation: judgment, context, accountability
AI Power Ranking — Tool comparisons and benchmarks for AI practitioners
LinkedIn Newsletter — Strategic AI insights for CTOs and engineering leaders





