← ContentsHome
Chapter 1

Two Days, Same Bug

Sarah vs Miguel: How two developers approach the same bug with different tools reveals the hidden cost of context friction.

Let's start with concrete reality. Here are two developers debugging the same issue. Same bug. Same codebase. Same skill level. Different tools.

Tuesday: Sarah's Day (Chat-First Tool)

9:15 AM - Sarah pulls the latest from main. CI is failing on an integration test. The test passes locally but fails in CI with a cryptic timeout.

9:20 AM - She reads the stack trace. Something about a database connection pool. She's not sure why CI would behave differently. Time to ask for help.

She copies the test code (40 lines), the error message, and the relevant service method. Alt-tabs to her browser, opens ChatGPT, pastes everything. Types: "This test passes locally but fails in CI with a timeout. Why might this happen?"

9:23 AM - While waiting, she loses her train of thought. Checks Slack. Someone asked about the deploy schedule.

9:25 AM - Response arrives. The AI suggests: "The timeout might be due to connection pool exhaustion. Check your pool size configuration." Reasonable. But where is that configured?

9:27 AM - She searches the codebase for "pool size". Gets 47 matches. Tries "connection pool". Gets 89 matches. Scrolls through files. This is taking a while.

9:35 AM - Finds the config file. Pool size is 10. Seems reasonable? Back to ChatGPT. Copies the config file, pastes it, asks: "Is this pool size too small?"

9:37 AM - "For a production system, 10 might be low. Try increasing to 20-50 depending on your load."

9:40 AM - She increases it to 30. Commits. Pushes. Waits for CI.

9:50 AM - CI still fails. Same timeout. Back to the browser. Re-reads the original error. Copies the database initialization code this time. Pastes. Asks: "Could the timeout be related to how we initialize the connection?"

9:53 AM - AI responds with a long explanation about connection initialization patterns. Suggests checking if connections are being properly closed.

9:58 AM - She searches for where connections are closed. Finds three different patterns used in different parts of the codebase. Not sure which one matters for this test. Feels like she's going in circles.

10:15 AM - She gives up on the AI. Asks her teammate Miguel in Slack. He immediately says: "Oh yeah, CI uses PostgreSQL 14, local is 15. Check if you're using any PG15-specific syntax."

10:17 AM - She checks. The test uses SELECT ... DISTINCT ON, which has different behavior between versions. Fixes it. Pushes.

10:25 AM - CI passes.

Total time: 70 minutes. AI interactions: 4. Actual issue: Version-specific SQL behavior (which isn't in the error message).

Sarah's mental state: Frustrated. Felt like the AI was giving reasonable but generic advice that didn't account for the specific quirks of their setup.


Wednesday: Miguel's Day (In-Situ Tool)

9:15 AM - Miguel pulls the latest from main. Different integration test failing, also a timeout in CI.

9:18 AM - He opens the test file. Sees the error highlighted right in his editor (his tool watches CI failures). Places his cursor on the failing line. Hits Cmd+Shift+K.

A small panel appears inline, right next to the test code. It already shows:

  • The failing test
  • The last 20 lines of CI logs (filtered for this test)
  • The function being tested
  • The git diff for this branch

He types: "why timeout in CI but not local"

9:19 AM - Response appears in 4 seconds, structured:

Context analysis:
- Test connects to PostgreSQL
- CI logs show PG version: 14.2
- Your local likely runs 14.8+ based on docker-compose.yml
- Test uses jsonb operator ?| which behaves differently in 14.2

Suggested fix:
- Replace ?| with jsonb_exists_any() for backward compatibility
- Or update CI PostgreSQL version in .github/workflows/test.yml:28

A diff patch appears below, showing the specific line change.

9:21 AM - Miguel reads the suggestion. Makes sense. The tool actually checked his docker-compose.yml and CI config. He applies the patch with one click. The code updates.

9:23 AM - Runs tests locally. Pass. Commits. Pushes.

9:30 AM - CI passes.

Total time: 15 minutes. AI interactions: 1. Context switches: 0.

Miguel's mental state: Satisfied. Stayed in flow. The tool did the work of gathering context from multiple files.


The Difference

Both developers are competent. Both used AI. Sarah took 70 minutes. Miguel took 15.

The difference wasn't model quality. It was context friction.

Sarah's context tax:

  • 4 alt-tabs to browser
  • Manual copying of 5 different code snippets
  • 3 manual file searches with dozens of false matches
  • Writing 4 prompts explaining what the tool could have inferred
  • Constant mental reloading: "Wait, what was I looking at?"

Miguel's context tax:

  • 0 alt-tabs
  • 0 manual copying
  • Tool auto-gathered: test code, logs, diff, config files
  • 1 simple question: "why timeout in CI but not local"
  • Stayed in the mental map the entire time

That gap—the difference between 70 minutes and 15 minutes—is what this book is about.

Most discussions of AI coding tools focus on model capabilities. They should focus on context architecture. Because a brilliant model in a high-friction workflow will lose to a decent model in a low-friction one.

Let's understand why.