How Software Development ChangedLesson 34 of 87

Contents

How Software Development Changed

Lesson 34 of 87. Sign in to keep your place.

Module 4 · Saying what you want

What the tool can actually know about your codebase

9 min read

It invents your helper because it cannot see your helper

The most common frustration (it rewrote a function we already have, in a style we do not use, using a library we removed last year) has one explanation, and understanding it changes how you work.

A model reasons over the text it is given. That text is a window: the files you attached, the ones the tool retrieved, the recent conversation, and any standing instructions. Your repository is not in the window. Neither is your team’s history, your incident from March, or the convention that everyone follows and nobody wrote down.

So when it needs a date formatter and cannot see yours, it writes one. Not because it ignored yours. Because from where it stands, yours does not exist.

This reframes the whole activity. You are not instructing a colleague who knows the codebase. You are briefing a capable contractor on their first morning, who will not ask, and who will make something up rather than stop.

Retrieval helps and does not solve it

Modern coding tools search the repository and pull in what looks relevant: by keyword, by embedding similarity, by following imports. This works well and it fails in a specific, predictable way: it finds files that resemble the request.

What it misses is the thing that does not resemble the request but governs it. The middleware that already handles authentication for every route. The config value that means this environment behaves differently. The comment in an unrelated module explaining why the obvious approach breaks. Retrieval is similarity search, and the constraint you most need is often the one phrased in different words.

The practical consequence: name the files. Three specific paths beat any amount of asking it to look around, and it is faster.

The conventions file

Every major coding tool now reads a plain-text instructions file from the repository root. The filenames differ by vendor and will keep changing; the idea does not. Write one, keep it short, and keep it true.

What belongs in it: things that are true across the whole repository and cannot be inferred from a single file:

Markdown
# Working in this repository

## Commands
- Test: `make test` (not pytest directly — it sets the test DB URL)
- Type check: `make types` — must pass before any commit
- Never run `alembic upgrade` against a real database

## Conventions
- Money is always an integer of minor units, never a float. See `lib/money.py`.
- All datetimes are timezone-aware UTC at the boundary. `naive_now()` does not exist here.
- HTTP calls go through `lib/http.py`, which sets timeouts and retries.
  Do not import `requests` directly.
- Database access lives in `repo/`. Handlers never write SQL.

## Things that look wrong and are not
- `billing/fx.py` fails open on a rate-service outage. See docs/adr/0009.
- The duplicate `format_date` in `reports/` is deliberate; the report format
  is frozen by contract and must not follow app-wide changes.

What does not belong: anything a reader can see from the code, restatements of general good practice, aspirations nobody follows, and anything long. A file that has grown to 400 lines is competing with the actual code for the window, and the parts nobody maintains are actively misleading.

Keep it honest, or delete it. A conventions file that describes a policy the team abandoned is worse than none, because it will be followed.

Attention decays across a long window

One practical property worth knowing: material in the middle of a very long context is used less reliably than material at the beginning or the end. This has been measured repeatedly across models and is often called the lost-in-the-middle effect. It is a tendency, not a rule, and it varies by model and by version.

The working implications are simple:

  • Put constraints at the end of the message, closest to the request, not buried at the top.
  • Prefer three relevant files over thirty. Filling the window is not the same as informing it.
  • On a long session, restate the important constraint rather than trusting that it is still in view from an hour ago.

The test that tells you whether it understands

Before letting anything write code against an unfamiliar part of your system, ask it to describe that part and check the description against reality.

Describe how authentication works for the /api/v2 routes in this repository, and list the files involved.

Thirty seconds to verify. If it names a middleware that does not exist, you have found out before it built a change on that assumption, and you know exactly which file to attach next.

This is the same discipline as the whole course, in miniature: the cheap check that precedes the expensive commitment.

Every lesson here is open. Your progress is recorded once you pass the AI at Work exam.

Check your understanding

A team adds a 600-line conventions file describing every rule, style preference and past decision. Generated code still ignores the rule about not importing requests directly. What is the most likely mechanism?

Pick the one you would defend. Your answer stays private.

Next lesson · 9 minDesign the seam, generate the filling

Stuck on something?Ask Larissa, your AI tutor

How to cite: Addaly (2026) ‘What the tool can actually know about your codebase’, in How Software Development Changed. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/how-software-changed/what-the-tool-can-know (Accessed: 13 October 2026).