May 2026 · Series “Trace Lock — Governance notes from pairing with AI to write code” · Post 4 of 9
The previous two posts covered the two trace-lock modes separately:
- A1 Defensive: after tripping on a cross-layer bug once, lock that relationship down so it doesn’t rot
- B1 Offensive: proactively audit a business flow, find unprotected chain nodes, fix them all at once
This post covers “how the two pair up.” It’s also what I saw when I looked back after the offensive sprint Claude and I finished over the past 2 weeks.
This is still the plain-language version for self-taught developers. Engineering details (cross-project reuse matrix, what counts as transferable helper patterns, governance rule templates) go into C2 (engineer-facing).
Why covering them separately isn’t enough
After writing the A1 post and re-reading it, I noticed a gap:
The defensive mode sounds complete on its own. Five artifacts, registry, fuse test, two governance rules, AI reminder skill. Locking one cross-layer relationship takes 30-45 minutes. By the 7th lock, the total time invested breaks even.
But there’s an unanswered question: How do I know which relationships still need locking but haven’t been locked yet?
The defensive mode answers “how to lock a known relationship.” It assumes you already know which one will break. But most of the time I have no idea how many cross-layer relationships my codebase actually contains, let alone which ones are most dangerous.
It took the 5th cross-layer bug on May 25th for me to stop and ask Claude “should I go looking for other leaks of the same shape.” That question opened the offensive sprint, expanding from 13 known traces to 17 plus fixing 4 BLOCKERs.
In other words: without offensive, defensive only reacts to bugs already hit. Without defensive, the BLOCKERs offensive finds get re-fixed next month. The two are one set; neither is complete alone.
Division of labor between the two modes
Claude and I summarized the two roles in this table:
Dimension Offensive (B1) Defensive (A1) Trigger I say “audit the whole X chain” I (or AI) touch any node listed in trace nodes Frequency Once a month or quarter (planned, low frequency) Every code change auto-triggers (high frequency) Output N new traces locked (range expansion) Existing traces don’t rot (range maintenance) Target A whole business flow (containing N chain nodes) A single trace (one node in one chain) Cost per use 7-15 hours (audit + fix + summary) 30-45 minutes (5-step checklist) Cost of not having it Trace count stays flat, always chasing known bugs Existing traces rot, fixing one breaks anotherThe division is clean. Offensive handles “advancing into new territory.” Defensive handles “holding territory already taken.”
Four states of system entropy
When Claude and I discussed ROI, I sketched another mental model. System entropy (total bugs + hidden debt) over time:
- No offense, no defense: entropy increases monotonically. Bugs accumulate faster than I fix them
- Offense only: entropy oscillates. Each sprint reduces it temporarily, climbs back up months later
- Defense only: entropy stays flat at current level. Existing traces held, but no expansion
- Offense + defense: entropy decreases monotonically. Quarterly offensive expands lock coverage, daily defensive maintains, overall trend down
I only saw this picture after the sprint was done. While writing the code I was just thinking “fix these 4 BLOCKERs,” not realizing system entropy had actually started trending down for the first time.
The real sprint’s numbers
Pulling the past 2 weeks onto a timeline:
Day 1 (defensive emerges):
- Customer screenshot: “half-pound drip bag only orderable as 1 pack”
- 30-minute fix
- But realized this was the 6th similar bug in 6 months
- Discussed with Claude “why does this keep happening” → arrived at the 5-artifact Trace Lock pattern
- 4 hours to build registry + first trace (T-018) + two governance checkers + skill
Day 2-3 (defensive expands to 13 traces):
- Backfilled past cross-layer bugs into traces one by one (T-001 to T-017, partially historical events)
- 30-45 minutes each
- 13 locked. Self-estimated chain protection: 30% → 45%
Day 4 (offensive emerges):
- 5th cross-layer contract bug hit (roasting station “complete” button frozen)
- Asked Claude “can we find all same-shape leaks at once”
- 1-hour audit → 11 chain nodes → 4 BLOCKERs
Day 4-5 (offensive sprint):
- 7 hours to fix all 4 BLOCKERs + write sprint summary
- Each BLOCKER did Decision Pinning + 6-piece fix
- Also added these 4 to the defensive registry (T-019/020/021/022) → 13 expanded to 17
- Self-estimated chain protection: 45% → 81%
Day 6 (the dual-blade insight):
- While writing the E meta post, looking back I saw “offensive finds + defensive locks” as a closed loop
- Offensive finds N at a time, defensive maintains daily, next offensive round finds new candidates
- That’s when I started writing this post
Total 17 days, including 4 blog posts of writing, around 50-60 hours of pure governance investment.
Why neither alone works (two counter-examples)
Counter-example 1: the defense-only developer
After locking my first 13 traces, I had a brief “OK that’s probably enough” illusion.
The reality: those 13 were all “known bugs hit in the past 6 months.” A bug I lock is one a customer already tripped on. Bugs not yet hit are completely outside the defensive perimeter.
Stopping there, 6 months later I’d hit bug #14, #15, each taking 3-5 hours to fix, then backfilled into the registry. Defense scope always trails the bugs. At best, you break even.
Counter-example 2: the offense-only developer
Suppose I run an offensive audit every quarter, find 5 BLOCKERs, fix them all. But I have no defensive registry, no tests, no governance rules.
3 months later, I (or an AI) change some internal logic of a helper. No fuse test fails. No governance rule warns. The change ships to prod, no one notices. The next audit re-discovers this as a new BLOCKER.
The offensive sprint becomes “perpetually re-fixing the same set of bugs.” Marginal cost never goes down.
The closed loop when used together
Offensive audit
↓
Find N BLOCKERs
↓
Decision Pinning
↓
6-piece fix + add to defensive registry
↓
Defensive maintains daily (fuse test + governance + skill)
↓
Next quarter's offensive doesn't re-find these N, only finds new candidates
↓
Coverage expands continuously, marginal cost drops
Enter fullscreen mode Exit fullscreen mode
Run this loop for 6-12 months, codebase shifts from “decays as I change it” to “stabilizes as I change it.”
Cross-project application: what transfers, what doesn’t
The next context I’d try this in is a different project (if I take on consulting work). Predicting in advance:
Directly copyable (framework layer):
- Registry markdown format
- The two governance checker script skeletons
- AI reminder skill’s frontmatter structure
- 6-piece fix pattern step order
- Iteration log’s 5-section structure
Not copyable (content layer):
- Specific traces (every project’s business flows differ)
- Specific helpers (depends on domain logic)
- Specific business contracts (every company / product makes different decisions)
- Migrations / RPC details
In short: 80% framework transfers, 20% content must be re-invented.
Time estimate for moving to a new project: ~4-6 hours to set up framework + first trace. Each subsequent trace takes about the same as in the original project (30-45 minutes).
Where this doesn’t apply (don’t take the wrong lesson)
There’s a risk in writing this far. Readers might think “every project should use trace lock.” That’s not what I’m claiming.
Scenarios I can think of where it doesn’t fit:
- Pure read-only reporting systems: no write path means no “data flow,” nothing to trace
- Early-stage MVP under 2 months old: business contracts aren’t stable yet, traces break frequently and slow iteration
- 5+ person team with strong code review culture: governance overlaps with human review, value drops (unless you use governance as a “save reviewer attention” tool)
- Pure frontend SaaS with no DB: few cross-layer dependencies, trace nodes mostly in frontend, regular hooks/composables extracted as helpers is enough
- Pure ML / data pipeline: the “business contract” concept doesn’t quite apply, data contract tests (Great Expectations / Pandera) fit better
If your project matches any of those, you don’t need this. Trace lock works best for “many cross-layer dependencies + ambiguous business contracts + AI pair programming.” It’s not a universal solution.
A transferable suggestion
If you decide to try the dual-blade approach, the order I’d recommend:
- Defensive first (3-4 hours to build framework + first trace). Simpler, immediate protection.
- Lock 1-2 traces to learn the pattern, don’t start with 10
- After your business surfaces 2-3 cross-layer bugs, run the first offensive audit (5-10 hours)
- Quarterly offensive to keep system entropy from rising
Not sure if it’s worth the investment? My own heuristic: have you had ≥ 3 “cross-layer contract drift” bugs in the past 6 months? Yes → worth it. No → maybe not yet.
I’m not sure if this threshold generalizes. But under 3, fixing one at a time might be cheaper than building governance.
Why this works well for AI pair programming
Both ends of the dual-blade are AI-friendly:
-
Offensive: I ask Claude “audit the whole X chain,” it has the
business-flow-audit-fixskill that auto-runs the 11-node × 3-question audit + 6-piece fix -
Defensive: AI touches any node in trace nodes,
trace-lock-modifyskill auto-triggers, reminds it to run the fuse test first
I don’t have to re-explain governance rules each time. Skill written once, AI inherits it next session.
Compared to “please AI be more careful” (which is not executable), “write the audit flow into a skill so AI auto-runs it” is an executable engineering intervention.
What this series will expand on next
The next few posts rewrite the plain-language content from an engineering angle (for engineers who’ve written governance rules / pinning tests):
- A2 Defensive engineering version: 5-artifact implementation details (how the registry parser script is written, fuse test’s 5-section structure, the two governance rules’ code)
- B2 Offensive engineering version: 6-piece fix pattern templates (pure-function helper / trace test / governance rule / caller exemption list / iteration log)
- C2 Cross-project reuse matrix (each artifact’s transferability rated 0-5 stars)
- D sql-only-trace: how to test pure-DB logic (why unit test frameworks aren’t enough, gotchas of running SQL tests via Supabase CLI)
If you’re an engineer who wants implementation details after reading this, those 4 posts are for you.
Related posts
- A1 · Defensive Trace Lock — How to lock down a cross-layer relationship (one of the previous two in series)
- B1 · Offensive audit — How to periodically audit a whole business flow (previous in series)
- 中文版
About this post
This post is an organized record of conversations I had with Claude (an AI pair-programming tool)
during May 2026. I noticed some patterns worth keeping for my own future reference,
so I asked Claude to help structure them into writing.
A few things I’m not claiming:
- Terms used in this post (dual-blade / offensive / defensive / Trace Lock / Decision Pinning / 6-piece fix pattern / sql-only-trace) are working names I gave them myself, not industry-standard terminology
- My system has a specific shape (solo-maintained, many cross-layer dependencies, ambiguous business contracts). These patterns may not apply to your context
- I’m not a software engineer, just a barista who pairs with AI to write code
If a professional engineer spots misuse, or there’s already a more standard name for any of these concepts, I genuinely welcome corrections.
本文原載於我的部落格:Offense + Defense combined — How the two pair up (for self-taught developers)
답글 남기기