May 2026 · Series "Trace Lock — Governance Notes from AI Pair-Programming" · Post 8 of 9
This is the engineering version of C1 Combined Offense + Defense, and also the convergence point of A2 Defense Engineering Edition and B2 Offense Engineering Edition.
A2 explains how to lock a single known trace using 5 artifacts. B2 explains how to fix N gaps surfaced by an audit using a 6-piece fix pattern. Each of those posts came with its own "cross-project reuse" table, but only covered its own side. This post merges the two tables into an 11-piece matrix, then adds cross-stack mapping, objective-vs-subjective project differences, AI pair-programming vs traditional development differences, plus an expanded "when not to use" list.
Written for engineers who already know A2's 5 artifacts and B2's 6-piece pattern. If you are a non-technical reader, C1 Combined Offense + Defense (plain version) is the post you want.
My environment: Vue 3 + Vite + Vitest + Supabase (PostgreSQL) + Node.js scripts. The "framework layer / content layer" split and porting cost estimates below are based on this stack. Moving to a different stack (Next.js + Prisma + Jest + tRPC, or Django + pytest + Celery) keeps the skeleton applicable, but code skeletons need to be replaced.
The 11-Piece Matrix
Merge A2's 5 artifacts with B2's 6-piece pattern. Deduplicate the overlap (Registry / Trace test / Governance rule are shared). Add each side's unique pieces. The result is an 11-piece total list:
| # | Piece | A2 uses? | B2 uses? | Main location | Reusability | Framework dependency |
|---|---|---|---|---|---|---|
| 1 | Registry markdown entry | ✅ | ✅ |
文檔/data-source-registry.md Critical Traces section |
★★★★★ | Pure markdown |
| 2 | Trace test 5-section structure | ✅ | ✅ | frontend-app/src/__tests__/traces/T{NN}-*.trace.test.js |
★★★★☆ | Any unit test runner |
| 3 | Governance rule A (trace-registry-test-coverage) | ✅ | ✅ | scripts/governance-guard.mjs |
★★★★☆ | Node.js script |
| 4 | Governance rule B (trace-test-must-import-anchor) | ✅ | ✅ | scripts/governance-guard.mjs |
★★★★☆ | Node.js script |
| 5 | AI reminder skill | ✅ | ⚠️ partial |
.claude/skills/trace-lock-modify/SKILL.md + .claude/skills/business-flow-audit-fix/SKILL.md
|
★★★☆☆ | Claude Code / Cursor / other skill-enabled AI tools |
| 6 | Pure-function helper convention | ❌ | ✅ | frontend-app/src/lib/business-rules/<feature>Logic.js |
★★★★★ | Pure JS module convention, framework-agnostic |
| 7 | Caller exemption comment convention | ⚠️ occasional | ✅ | source code inline @xxx-ok: <reason>
|
★★★★★ | Pure text regex convention |
| 8 | Iteration log 5-section structure | ❌ | ✅ | 文檔/iteration-logs/<sprint>/NN_Gap-N_<topic>.md |
★★★★★ | Pure markdown record |
| 9 | Reverse verification anchor-break flow | ⚠️ occasional | ✅ | 5-step flow (write test → green → break anchor → confirm red → revert) | ★★★★☆ | Pure procedure, needs team / AI cooperation |
| 10 | sql-only-trace variant | ⚠️ occasional | ✅ |
scripts/integration-test/T{NN}-*.sql + DO block |
★★★☆☆ | PostgreSQL-specific |
| 11 | Decision Pinning (business contract freezing) | ❌ | ✅ | trace test's pin current behavior section + registry's backlog finding |
★★★★★ | Pure discipline, tool-agnostic |
A few observations.
Framework layer vs content layer split
Pull out pieces rated ≥ ★★★★☆:
Framework layer (high reusability):
1 Registry markdown entry ★★★★★
2 Trace test 5-section structure ★★★★☆
3 Governance rule A ★★★★☆
4 Governance rule B ★★★★☆
6 Pure-function helper convention ★★★★★
7 Caller exemption comment ★★★★★
8 Iteration log 5-section ★★★★★
9 Reverse verification anchor-break ★★★★☆
11 Decision Pinning discipline ★★★★★
Medium reusability (★★★☆☆):
5 AI reminder skill (tool-specific)
10 sql-only-trace variant (DB-specific)
Content layer (not reusable ★☆☆☆☆, reinvent per project):
- Specific traces (business chain shape)
- Specific helpers (business algorithm)
- Specific business contracts (pinning content)
- Specific incident pinning cases
A2 line 321 and B2 line 644 each observed "framework layer 80-90% reusable, business contract 0% reusable". The 11-piece matrix matches: 9 framework-layer pieces, 2 medium-tier pieces, business contract 0% reusable.
Why piece 5 (AI reminder skill) and piece 10 (sql-only-trace) drop to ★★★☆☆
Both have strong framework dependencies.
Piece 5 AI reminder skill depends on Claude Code's skill auto-trigger mechanism (description-based fuzzy matching + frontmatter). Cursor has .cursorrules with similar intent but different syntax. Other AI tools (GitHub Copilot / Continue.dev / Cody) currently lack this mechanism. Reusability depends on whether the target environment has the "skill auto-trigger" primitive:
- Claude Code / Cursor: portable, syntax conversion needed
- VSCode + GitHub Copilot: not portable (no description-based trigger)
- Others: requires evaluation
Without this primitive, fall back to "PR template + checklist". But losing the "auto-trigger" property means relying on humans to remember the checklist, which becomes another rot source.
Piece 10 sql-only-trace variant depends on PostgreSQL's DO $$ ... $$ LANGUAGE plpgsql block + JWT config + SET LOCAL. MySQL / SQLite / MongoDB each have their own stored-procedure / migration-test concepts, but with different syntax and portability (see cross-database mapping below).
Applicability Dimensions
"My environment hits all the conditions" decomposes into 5 dimensions. Each dimension has its own marginal-value curve for the combined offense + defense pattern.
Dimension 1 (team size)
| Size | Offense applicable? | Defense applicable? | Why |
|---|---|---|---|
| Solo developer | ✅ Strongly recommended | ✅ Strongly recommended | Zero external correction force; engineering means is the only remedy |
| 2-3 small team | ✅ Recommended | ✅ Recommended | Before code review culture forms, similar to solo |
| 4-10 team | ⚠️ Evaluate | ✅ Recommended | Code review partly plays the attack role, but reviews do not actively audit |
| 10+ organization | ⚠️ Evaluate | ⚠️ Evaluate | Multi-tier review + QA + senior dev pings, governance rule marginal returns diminish |
10+ organizations are not "cannot use", but "ROI becomes hard to calculate". Yet piece 1 (Registry markdown) and piece 8 (Iteration log) remain applicable. These two are for "organizational memory", independent of team size.
Dimension 2 (project maintenance horizon)
| Horizon | Offense applicable? | Defense applicable? | Why |
|---|---|---|---|
| < 1 month (hackathon / spike) | ❌ | ❌ | Forgetting "3 months later" does not exist; pinning via commit message is sufficient |
| 1-3 months (early MVP) | ❌ | ⚠️ Evaluate | Business contract not stable; frequent trace breaks drag iteration |
| 3-12 months (growth phase) | ⚠️ Evaluate | ✅ Recommended | Cross-layer bug experience accumulating; pick 2-3 painful traces to lock first |
| 12+ months (long-term maintenance) | ✅ Strongly recommended | ✅ Strongly recommended | "Forgetting 3 months later" cost fully visible |
My environment (24+ months maintenance) hits the strongly recommended region.
Dimension 3 (cross-layer complexity)
"Cross-layer dependency" definition: a piece of data flowing from DB to UI through N transformation points (trigger / RPC / store / composable / component / helper).
| Depth | Offense applicable? | Defense applicable? |
|---|---|---|
| ≤ 2 layers (DB → UI direct) | ❌ | ❌ |
| 3-5 layers (with store + composable) | ⚠️ Evaluate | ✅ Recommended |
| 6+ layers (with trigger + RPC + helper + ACL + multiple components) | ✅ Strongly recommended | ✅ Strongly recommended |
My environment (e-commerce + inventory + roasting + POS + multiple RLS policies) sits at roughly 6-9 layers per business chain.
Dimension 4 (business contract stability)
| Change frequency | Offense applicable? | Defense applicable? |
|---|---|---|
| Weekly algorithm change | ❌ | ❌ |
| Monthly 1-2 changes | ⚠️ Evaluate | ⚠️ Evaluate |
| Quarterly 0-1 change | ✅ | ✅ |
| Yearly stable | ✅ Strongly recommended | ✅ Strongly recommended |
When business contracts churn often, pinning becomes a burden (every change requires updating trace test + registry + iteration log).
Dimension 5 (AI pair-programming intensity)
| Intensity | Offense applicable? | Defense applicable? |
|---|---|---|
| Never use AI | ✅ but piece 5 unused | ✅ but piece 5 unused |
| Occasional (few times a week) | ✅ Recommended | ✅ Strongly recommended |
| Heavy (daily main driver) | ✅ Strongly recommended | ✅ Strongly recommended |
When AI pair-programming is heavy, piece 5 (AI reminder skill) provides the highest value because AI lacks the "I edited X last week" muscle memory; every new conversation starts from zero.
Objective vs Subjective Project Differences
"Objective" vs "subjective" is my own coarse project classification (working name, my own placeholder term).
- Objective: Has clear "right / wrong" business logic. E-commerce (inventory / pricing / checkout), accounting, finance, ERP, CRM derived fields, ticketing, check-in
- Subjective: Output is "taste / style / subjective experience". Design mockups, copywriting, video editing, UX A/B test outcomes, recommendation systems
The two project classes have very different applicability profiles.
Objective projects
| Piece | Applicability for objective projects | Why |
|---|---|---|
| 1 Registry / 2 Trace test / 3-4 Governance rule | ✅ High | "Right / wrong" has explicit oracle (queryable from DB, expressible as spec) |
| 6 Pure-function helper | ✅ High | Business logic expressible as pure function (e.g. "annual threshold → tier") |
| 7 Caller exemption | ✅ High | Thin wrapper scenarios common |
| 8 Iteration log | ✅ High | Decisions like "why cash-first not bonus-first" need recording |
| 9 Reverse verification | ✅ High | Breaking the anchor produces a clear expected red |
| 10 sql-only-trace | ✅ High | Useful when DB logic is dense |
| 11 Business contract freezing | ✅ High | "Current behavior" is definable |
The combined pattern fits as a whole set. My environment is objective.
Subjective projects
| Piece | Applicability for subjective projects | Why |
|---|---|---|
| 1 Registry / 2 Trace test | ⚠️ Partial | No clear "right / wrong" oracle; pinning does not land |
| 3-4 Governance rule | ⚠️ Partial | Can pin "structure" (helper must exist) but not "content" |
| 6 Pure-function helper | ✅ | But helper itself is a suggested value, not a SSOT |
| 7 Caller exemption | ✅ | Same applicability as objective |
| 8 Iteration log | ✅ | "Why this copy revision" decisions still valuable |
| 9 Reverse verification | ❌ | Breaking the anchor does not necessarily produce red (no clear oracle) |
| 10 sql-only-trace | ❌ | Subjective projects usually do not use DB logic |
| 11 Business contract freezing | ⚠️ Partial | "Contract" concept on subjective side is closer to "style guide" |
Subjective projects typically use 5-6 of the 11 pieces. A rubric-driven workflow + iteration log fits better than pinning test + governance rule.
Hybrid projects
Many projects are hybrid. Examples:
- My CS-SAAS: objective business logic (inventory / pricing / orders) + subjective blog copy
- Design tool: objective UI behavior + subjective aesthetics / typography
- Recommendation system: objective infra (instrumentation / statistics) + subjective recommendation result
Hybrid projects use "zoned governance": objective zones get the full combined set, subjective zones get rubric + iteration log.
AI Pair-Programming vs Traditional Development Differences
Why does AI pair-programming need trace lock more? Four structural differences.
Difference 1 (no muscle memory)
A traditional developer who has spent 6 months in a codebase has "if I change X, also touch Y" baked into muscle memory. Grep is no longer needed every time; past pitfalls are avoided instinctively.
An AI agent enters every new conversation with empty context. A bug fixed last week is rediscovered from symptom-grep this week. Institutional memory does not exist at all.
Trace lock externalizes muscle memory into AI-readable artifacts (registry markdown + skill auto-trigger), so each new conversation inherits the previous one's "muscle memory" directly.
Difference 2 (no colleague pings)
Traditional teams have Slack threads, code review comments, standups. A senior dev seeing a PR will proactively ping "remember to also update Y after editing X".
AI has no senior dev on Slack. Governance rule + skill auto-trigger is the engineering means of supplying the "senior dev on Slack" role.
Difference 3 (context window has a ceiling)
A traditional developer does not "forget" after reading the codebase. An AI agent's context window has a hard cap (~200k tokens); long conversations drop early decisions.
Iteration log + registry externalize decisions into markdown, so the next conversation reloads from markdown.
Difference 4 (AI is more prone to "change without understanding why")
When AI sees a red test, the instinct is to edit the test (turn it green) rather than ask "why was this test written this way".
Business contract freezing (piece 11) + a // Why: contract pinned after last week's bug; read incident pinning case before editing comment inside the trace test is what blocks the instinct. Without that comment, AI two turns later will flip expect(x).toBe(true) to expect(x).toBe(false) because "the test was red".
Concrete value-add to AI pair-programming
AI pair-programming pain → Combined-pattern piece
Unaware of N cross-layer rels → Offensive audit + piece 1 Registry
Unaware editing X breaks Y → Piece 2 Trace test + piece 5 skill auto-trigger
Internal helper edit unblocked → Piece 3-4 Governance rule
Unsure why this was written → Piece 8 Iteration log + piece 11 Decision Pinning
Red test → edit the test → Piece 11 + trace test's incident pinning comment
Every pain point has a corresponding piece.
Cross-Stack Mapping
When porting pieces to a different stack, the skeleton stays but the implementation gets swapped.
Trace test framework mapping (piece 2)
| Source (Vitest) | Target framework | Main replacement |
|---|---|---|
describe / it / expect |
Jest | Same, near-zero edits |
describe / it / expect |
Mocha + Chai |
expect(x).toBe(y) → expect(x).to.equal(y)
|
describe / it / expect |
Pytest |
def test_xxx(): + assert x == y
|
describe / it / expect |
RSpec | describe "x" do; it "..." do; expect(x).to eq(y); end; end |
describe / it / expect |
Go testing |
func TestXxx(t *testing.T) + if x != y { t.Errorf(...) }
|
The 5-section structure (imports anchor / setup current state / assert behavior / future regression catch / why-comment) is framework-independent.
Governance rule script mapping (pieces 3-4)
| Source (Node.js) | Target | Main replacement |
|---|---|---|
fs.readFileSync + /regex/
|
Python |
open().read() + re.compile(...)
|
| Node script | Ruby rake task |
Rake::Task + File.read + Regexp
|
| Node script | bash + grep / awk | Feasible but regex syntax inconsistent; recommend ripgrep + logic layer in bash |
| Node script | Go binary |
os.ReadFile + regexp.MustCompile
|
CI integration: every stack supports pre-push hook (Husky / pre-commit / lefthook) + GitHub Actions / GitLab CI.
Caller exemption comment convention (piece 7)
| Source | Target | Replacement |
|---|---|---|
JS // @xxx-ok: reason
|
Python |
# noqa: xxx-ok reason (or custom) |
| JS | Go |
//go:build xxx-ok or custom build tag |
| JS | Ruby |
# rubocop:disable Style/Xxx style |
The key: the rule is "a comment containing the xxx-ok token is recognized by the governance rule as a valid bypass", language-independent.
Cross-database mapping (piece 10 sql-only-trace)
This is the most stack-specific piece.
| Database | Corresponding mechanism | Main difference |
|---|---|---|
| PostgreSQL |
DO $$ ... $$ LANGUAGE plpgsql block |
My environment, full support |
| MySQL |
DELIMITER // PROCEDURE ... // + manual CALL |
No DO block; needs CREATE PROCEDURE + CALL two-step |
| SQLite | No stored procedure; use BEGIN TRANSACTION + application-layer driver | Most restricted |
| MongoDB | No SQL; use aggregation pipeline or mongosh script | Different paradigm entirely |
| Snowflake / BigQuery | Stored procedures exist, syntax differs | Cloud DW; CI integration harder |
The SET LOCAL mechanism (RLS JWT simulation) is PostgreSQL-specific. MySQL / SQLite have no equivalent; you must test through the application layer or bypass RLS.
If your stack is not PostgreSQL, downgrade piece 10 to "application-layer integration test" (run tests via Node / Python / Ruby code connecting to the DB). The skeleton stays "SEED / RUN / ASSERTIONS / CLEANUP" but sits in the application layer instead of SQL.
When Not to Use (A2 + B2 + new additions = 8 cases)
A2 line 327-337 lists 5 cases (against pieces 1-5); B2 line 650-660 lists 5 cases (against pieces 6-11). Merging, deduplicating, and adding fresh cases gives 8.
1. Hackathon / spike / project less than 1 month old
Forgetting "3 months later" does not exist; pinning via commit message + PR description is sufficient. The setup cost of the combined pattern (A2 takes about 3-4h, B2's first gap takes 6-9h) exceeds the entire short-project development time.
2. Only 1-2 cross-layer relationships
Writing to commit message or PR description is enough; building a registry is over-engineering. The offensive audit also will not reach N BLOCKER (no N traces to find), so ROI does not justify the work.
3. No markdown-friendly editing pipeline
If the team lives in Notion / Confluence, syncing git and wiki in parallel becomes a drag. Piece 1 (Registry) and piece 8 (Iteration log) both assume markdown is first-class; moving them to Notion / Confluence is infeasible (no git diff, no CI integration).
4. CI pipeline cannot accept custom scripts
Pieces 3-4 (Governance rule) depend on pre-push hook or CI enforcement. If the CI pipeline cannot accept custom Node / Python scripts, governance rules have nowhere to attach and slowly drift to "ignored".
5. No AI pair-programming
Piece 5 (AI reminder skill) targets the integration points of Claude Code / Cursor and similar tools. Without such a tool the skill has nowhere to attach. The pattern drops to "9 applicable pieces" and still works, but loses the "auto-trigger" key property.
6. Business contract churns extremely fast
In scenarios where helper algorithms change weekly, trace test pinning becomes a drag. Stabilize business first, then lock. This is dimension 4's "weekly change" case.
7. Multi-person maintenance with strong code review culture
Traditional code review already plays part of the governance role. The combined pattern still works but with diminishing marginal returns, so ROI needs evaluation. This is dimension 1's 10+ organization case.
That said, piece 1 Registry + piece 8 Iteration log remain applicable (for organizational memory), and can be adopted standalone.
8. Pure read-only reporting systems / pure ML data pipelines
Two C1 cases:
- Pure read-only reporting systems have no write path, so there is no "data flow" and no trace to build
- Pure ML / data pipelines benefit more from data-contract tests (Great Expectations / Pandera). The "business contract" concept of the combined pattern does not fit ML pipelines well
Real Porting Cost Estimate (from my environment to a new project)
Suppose I take on a contract and want to apply the combined pattern to a new Vue + Supabase project (same stack).
| Phase | Estimated time | Content |
|---|---|---|
| 1. Copy 9 framework-layer pieces | 1h | Copy governance-guard.mjs / .claude/skills/ / registry markdown template / iteration log template |
| 2. Update paths and env vars | 0.5h | repoRoot logic / registry path / trace test directory |
| 3. Write first trace (client-specific) | 1-1.5h | Run 5-step audit + write registry block + trace test |
| 4. Write first helper (business-specific) | 1-2h | Extract pure-function logic from scattered callers |
| 5. CI / pre-push hook integration | 0.5h | Add governance-guard.mjs to hook |
| 6. Write the matching CLAUDE.md rule | 0.5h | Document "this project's trace nodes are X; AI must run 5-step audit before editing" |
| Total | 4.5-6h | Includes first trace + first helper |
Each subsequent trace is roughly 30-45 min (A2 estimate); each gap fix using the 6-piece pattern is roughly 1-1.5h (B2 estimate).
Switching to a different stack (e.g. Next.js + Prisma + Jest) adds 2-3h of replacement work (trace test syntax / governance rule regex / sql-only-trace variant).
ROI break-even: in my environment it is 2-3 months (past 6 months: 5 cross-layer bugs × 3-5h = 15-25h of fixing). The break-even on a new project depends on cross-layer bug frequency: six months without a cross-layer bug is unprofitable; six months with 3+ such bugs is clearly profitable.
If You Want to Try This
The order I would suggest (extending C1's suggestion with engineering details):
Phase 1 (Defense, 3-4 hours)
- Copy the 9 framework-layer templates (about 1h)
- Write the first trace (about 1.5h), choosing the one closest to "the bug I hit in the past 6 months"
- Integrate pre-push hook + CI (about 0.5h)
- Validate: intentionally break the trace test's expected value → governance should turn red → revert → should turn green
Phase 2 (Offense, 5-10 hours)
- Wait until business produces 2-3 cross-layer bugs, then run the first offensive audit
- Use the
business-flow-audit-fixskill to run 11 chain-nodes × 3 questions audit - Fix each BLOCKER using the 6-piece pattern
- Write sprint summary
Phase 3 (Steady state, one offensive sprint per quarter)
- Run one offensive audit per quarter to keep system entropy from rising
- Routine code change is auto-protected by the defensive side
Not sure whether it is worth doing?
C1's heuristic: did the past 6 months produce ≥ 3 "cross-layer contract drift" bugs? Yes → worth it. No → maybe not yet.
The engineering version adds a quantified indicator: the cumulative hours spent fixing cross-layer bugs in the past 6 months.
- Cumulative < 5h: skip this pattern
- Cumulative 5-15h: consider Phase 1 (defense only)
- Cumulative 15-30h: consider Phase 1 + Phase 2
- Cumulative 30h+: strongly recommend the full set
My own past 6 months totals about 25-30h.
I am also unsure whether this threshold transfers to your situation. But "cumulative bug-fix hours" is a more honest signal than "count" (5 small bugs differ from 1 big bug).
Related posts
- C1 · Combined Offense + Defense (plain version) (series same-topic plain version)
- A2 · Defense Engineering Edition: 5 artifacts implementation details (series same-branch, two posts earlier)
- B2 · Offense Engineering Edition: 6-piece fix pattern (series same-branch, previous post)
- D · sql-only-trace Engineering Edition: testing DB-side pure logic (series same-branch, next post)
- Chinese version
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 (11-piece matrix / framework layer vs content layer / objective vs subjective projects / combined pattern / Trace Lock / business contract freezing / Decision Pinning / 6-piece fix pattern / 5 artifacts / sql-only-trace / AI reminder skill / reverse verification anchor break) 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.
本文原載於我的部落格:Combined Offense + Defense (Engineering Edition) — Cross-Project Reuse Matrix and When Not to Use
Top comments (0)