All posts
|7 min read

The Six Things Your AI Coding Agent Doesn't Know About Your Codebase

Your agent reads files. A senior developer knows architecture, history, decisions, patterns, and context. Here's the gap — and why it makes AI agents unreliable for real work.

Your AI coding agent can read every file in your repository. It can grep, it can follow imports, it can parse ASTs. And it still doesn't understand your codebase the way a developer who's been on the project for six months does.

The gap isn't intelligence. The gap is knowledge — specifically, six layers of knowledge that exist in a codebase but don't live in the source code.

Layer 1: Structure (what exists)

This is the only layer most AI tools provide. It's the inventory:

  • What functions, classes, and types exist
  • Where they're defined (file and line number)
  • What imports what
  • What calls what

An agent that reads your source files gets this layer for free, at the cost of reading many files and burning through tokens. A tool like tree-sitter can extract it more efficiently into a symbol index and dependency graph.

Structure answers "what's here?" It doesn't answer "what does it do?" or "why is it this way?"

What it looks like for an agent: `` computeScore | function | src/scoring/compute.ts:42 signature: (wallet: string, txns: Transaction[]) => Promise<Score> callers: worker.ts:89, routes.ts:112, mcp/server.ts:67 imports: db/client, config/constants

Useful. But the agent still doesn't know what "computing a score" means in the context of this application.

Layer 2: Semantics (what it means)

This is the understanding layer. It's what a developer explains to a new teammate:

  • "The scoring module takes blockchain transactions and produces a trust score between 0 and 100"
  • "Data flows from indexers → worker → scoring engine → database"
  • "The MCP server is the external interface — it's how AI agents query our data"

Semantic knowledge requires reading the code and reasoning about it. You can't extract it with a parser. You need an LLM or a human to generate it. But once generated, it rarely changes — a module's purpose stays stable across dozens of commits.

What it looks like for an agent: `` Module: scoring Purpose: Trust score computation for AI agent wallets Data flow: indexer transactions → computeScore() → weighted signal aggregation → Postgres Public API: computeScore(), computeTier(), validateAddress() Gotchas: batch inserts required (1/row is too slow), computeTier() is duplicated in worker.ts

Now the agent knows what the module does, how data flows, and what pitfalls to watch for. This is ~700 tokens versus ~4,000 tokens of reading the raw source to derive the same understanding.

Layer 3: History (what changes and what's coupled)

This is the layer that surprised us most when we built it. Source code shows you the present. Git history shows you the behavior:

  • Which files change most frequently (hotspots, volatility)
  • Which files always change together (behavioral coupling)
  • Which bug patterns have already been fixed (and might be reintroduced)

The killer insight: some files are deeply coupled through shared assumptions with zero imports between them. Git history reveals these hidden dependencies. Static analysis cannot.

What it looks like for an agent: ``` Hotspots: worker.ts 12 changes VOLATILE routes.ts 10 changes VOLATILE constants.ts 3 changes STABLE

Hidden coupling: routes.ts ↔ worker.ts 75% co-change rate, no import ⚠️ routes.ts ↔ migrate.ts 58% co-change rate, no import

Bug lessons: worker.ts: "NULL-coalescing SQL fails on neon() — use explicit branching" compute.ts: "batch inserts required — 1/row is 500x too slow" ```

An agent without this layer will confidently edit routes.ts without checking worker.ts. The historical coupling data says that's a mistake 75% of the time.

Layer 4: Decisions (why it was built this way)

Every codebase carries invisible decisions:

  • Why Hono instead of Express? (Performance on Cloudflare Workers — Express doesn't support edge runtimes)
  • Why Neon Postgres instead of SQLite? (Need serverless-compatible database for Cloudflare Workers)
  • Why dual entry points? (worker.ts for production CF Workers, routes.ts for local dev with standard HTTP server)

Without decision records, an AI agent might suggest "let's migrate to Express for better middleware support." That's a reasonable suggestion in isolation — and completely wrong given the architectural constraint that the app runs on Cloudflare Workers where Express doesn't work.

What it looks like for an agent: `` Decision: Use Hono as web framework Context: App deploys to Cloudflare Workers. Express requires Node.js APIs. Alternatives: Express (rejected — no CF Workers support), itty-router (too minimal) Consequence: All route handlers use Hono API. Middleware follows Hono patterns.

Decisions prevent the agent from suggesting changes that violate design intent. They're the difference between "technically correct" and "actually appropriate."

Layer 5: Patterns (how code is written here)

Every team has conventions. They're enforced through code review, not through linters:

  • Error handling: we use Zod for validation, return typed error responses (never throw)
  • Testing: vitest, fixtures in `__tests__/` directories, describe/it blocks
  • Naming: kebab-case files, camelCase functions, PascalCase types
  • Database: all queries go through the connection pool in `db/client.ts`, never raw SQL strings

An AI agent that doesn't know these patterns will generate syntactically valid code that doesn't match the codebase's style. The code works but the PR gets rejected because it throws errors instead of returning them, or puts tests in the wrong directory, or uses a raw SQL string instead of the pool.

What it looks like for an agent: `` Pattern: Error Handling Approach: Never throw from API handlers. Use Zod .safeParse(), return typed error response. Example: { success: false, error: { code: "INVALID_ADDRESS", message: "..." } } Files: routes.ts, worker.ts, mcp/server.ts

Layer 6: Sessions (what happened recently)

The most overlooked layer. What was discussed yesterday? What's in progress? What was tried and didn't work?

Without session context, every AI interaction starts from scratch. The agent doesn't know that yesterday you refactored the scoring module, that there's a half-finished migration in progress, or that you tried a different approach and reverted it.

What it looks like for an agent: `` Last session (2026-03-02): Modified: scoring/compute.ts, worker.ts, routes.ts Decision: switched from per-row to batch inserts (500/batch) In progress: adding percentile rank to score response Open question: should percentile be computed on read or cached?

Session context turns "start from zero" into "pick up where we left off."

The compound effect

Each layer is useful independently. Together, they create understanding that matches what an experienced developer carries:

An agent with all six layers:
  "You want to modify computeScore(). It's in src/scoring/compute.ts:42,
   takes wallet+transactions, returns a Score. It's called from 3 places.
   This file changes frequently (8 commits) and is coupled to worker.ts
   and routes.ts (both need matching changes). Last bug here was batch
   insert performance — make sure new code uses batch writes. The team
   uses Zod for validation and returns typed errors, never throws.

An agent with only source code: "I'll read compute.ts... it's a scoring function. Let me also check what imports it... [reads 5 more files] ...okay I think I understand. What was the question again?" ```

The six-layer agent uses ~5,000 tokens and starts immediately. The source-only agent uses ~37,000 tokens, takes 5 minutes, and still misses the hidden coupling, the bug history, the team patterns, and the session context.

Building your knowledge stack

You can build this incrementally. Start with structure (tree-sitter parsing) and temporal analysis (git history). Those two layers alone catch hidden dependencies and surface risk. Add semantic summaries per module next. Decisions and patterns come naturally as the team records them.

CodeCortex generates all six layers with codecortex init and serves them to AI agents via MCP. But the principle is universal: AI agents work better with structured knowledge than with raw files.

The question isn't whether your agent is smart enough. It's whether you're giving it the right information.