863435915c
Co-authored-by: claude <claude@jpaul.io> Co-committed-by: claude <claude@jpaul.io>
98 lines
10 KiB
Markdown
98 lines
10 KiB
Markdown
<!--
|
|
Suggested title: Commit the AI's Config, Not Just the Code
|
|
Alt title: Stop Re-Explaining Your Project to the AI Every Morning
|
|
Slug: commit-the-ai-config
|
|
Meta description: The instructions you give an AI (your conventions, test commands,
|
|
don't-touch list) are as worth versioning as the code. Commit them,
|
|
and every teammate and every agent inherits the same setup.
|
|
Tags: AI, developer workflow, version control, configuration, AGENTS.md, conventions
|
|
-->
|
|
|
|
# Commit the AI's Config, Not Just the Code
|
|
|
|
I used to start every AI coding session the same way: by giving the same little speech. "We use four-space indent. Run the tests with `python -m unittest` before you tell me it works. The logic goes in `tasks.py`, not crammed into the CLI file. And whatever you do, don't hand-edit `tasks.json`; it's generated."
|
|
|
|
The AI would nod (figuratively), do exactly that, and we'd have a great session. Then I'd close the tab. The next morning I'd open a fresh one, and the AI had forgotten every word of it. So I'd give the speech again. And again. I was a broken record reading my own project back to a goldfish.
|
|
|
|
This is the fix, and it's almost embarrassingly simple: write the speech down once, put it in a file, and **commit it**. That's the whole module. But the *why* underneath it is bigger than "save yourself some typing," and that's the part I want to talk about.
|
|
|
|
(New here? This is the next stop in [The Workflow](https://git.jpaul.io/justin/ai-workflow-course), my free course on the engineering scaffolding around AI coding. Earlier posts installed version control as a safety net; this one builds on it. You can follow along without having read them.)
|
|
|
|
## The file your tool is already looking for
|
|
|
|
Here's something most people don't realize: open almost any agentic coding tool (the kind that lives in your editor or terminal and reads your files directly), and *before it does anything*, it scans the repo for a committed, repo-level instructions file. A plain markdown file at the project root that tells the AI how *this* project works.
|
|
|
|
Different vendors look for different filenames, and honestly, the names keep changing; that's noise, and I'm not going to anchor you to one. (This very course commits one called `AGENTS.md`; yours might be named something else. Check your tool's docs for "project instructions," "rules," or "context.") The durable fact is the *pattern*: your tool reads a committed instructions file from the repo, and you decide what's in it. That pattern is going to outlive whatever the vendors call it this year.
|
|
|
|
So what goes in it? Not a prompt, and not your README. This is a briefing for an agent that's about to edit your code. Keep it to things that actually change the AI's behavior:
|
|
|
|
- **Project conventions**: the layout and patterns this codebase actually uses. *"Core logic lives in `tasks.py`; the CLI front end is `cli.py`; state persists to `tasks.json`."*
|
|
- **Build and test commands**: the exact, copy-pasteable commands. *"Run tests with `python -m unittest`. Don't claim a change works until they pass."* That one line stops the AI from inventing a test runner you don't use.
|
|
- **Coding standards**: *"Standard library only, no third-party packages. Type-hint public functions."*
|
|
- **The don't-touch list**: generated files, vendored code, secrets. *"Never edit `tasks.json` by hand; it's generated."*
|
|
- **House style**: the taste calls that otherwise come back wrong every time. *"Keep functions small. Don't reformat files you aren't changing."*
|
|
|
|
My test for whether a line belongs: would I otherwise have to say it again next session? If yes, it goes in the file. If the AI already gets it right without being told, leave it out; every junk line dilutes the signal.
|
|
|
|
[insert a screenshot referencing an open instructions file (e.g. AGENTS.md) at the repo root, alongside the tasks-app file tree here]
|
|
|
|
## Why *commit* it, instead of keeping it in your head
|
|
|
|
Most tools also let you set instructions *globally*, on your machine, for every project. That's fine for personal preferences. But it's the wrong home for *project* knowledge, and the reason is simple: it lives on your laptop, invisible to everyone else.
|
|
|
|
Picture a two-person project with no committed instructions file. You've trained your local setup to run the right test command and leave the generated JSON alone. Your teammate's setup hasn't, so their agent happily reformats whole files and hand-edits `tasks.json`. You're both "using AI on the same repo," getting different behavior, and neither of you can see the other's configuration. That's **drift**: one codebase, slowly diverging, because the rules live in two heads instead of one file.
|
|
|
|
Commit the file and that whole problem collapses. The configuration is now part of the repo. Clone the repo, get the rules. A new teammate (or a brand-new agent that has never seen the project) is configured correctly on its very first run, because the setup travels *with the code* instead of with whoever happened to set it up.
|
|
|
|
## The real payoff: AI behavior becomes reviewable
|
|
|
|
Here's the part that elevates this from "handy" to "actually important." Once the instructions live in the repo, **a change to how the AI works is a change to a tracked file.** Which means it shows up exactly like a code change does:
|
|
|
|
```bash
|
|
git diff
|
|
```
|
|
|
|
When someone tightens *"keep functions small"* into *"no function over 30 lines,"* or adds `infra/` to the don't-touch list, that decision arrives as a **diff** you can read, question, and accept or reject. It's no longer an invisible tweak buried in one person's local settings, silently changing what the AI does for everyone. The way your team works with AI becomes a reviewable artifact with a history; you can `git log` it and see *why* a rule exists and when it showed up.
|
|
|
|
That, to me, is the quiet brilliance of the whole idea. We already trust version control to make code changes visible and attributable. This just points the same machinery at the *instructions*, and suddenly "how we use AI here" is as auditable as the code itself.
|
|
|
|
## This course eats its own dog food
|
|
|
|
You don't have to take my word for it, because the course repo does precisely what this module teaches. At its root is an `AGENTS.md`, the committed instructions for the agents that help me author the course. It spells out what the repo is, the core promises (model-agnostic, no hard tool requirements), the voice, the lab conventions, and a flat "Don't" list. Take a look at it and its history:
|
|
|
|
```bash
|
|
git show HEAD:AGENTS.md # or just open AGENTS.md in your editor
|
|
git log --oneline AGENTS.md # every change to how agents work on this repo
|
|
```
|
|
|
|
That single file is the reason all twenty-seven modules sound like one course instead of twenty-seven unrelated tutorials. It's the worked example for everything I'm describing.
|
|
|
|
## Try it on the lab app
|
|
|
|
If you've got the `tasks-app` from the earlier modules, this is a ten-minute exercise. Copy a starter instructions file to whatever filename your tool reads, edit it to match your project, and commit it:
|
|
|
|
```bash
|
|
git add <your-tool-file>
|
|
git commit -m "Add committed AI instructions for tasks-app"
|
|
```
|
|
|
|
Now the good part. Start a **fresh** AI session and hand it a real task: *"Add a `search <term>` command that lists tasks whose title contains `term`, then confirm it works."* Watch what happens without you saying a single rule this time: it should put the logic where your conventions said, leave `tasks.json` alone, skip the surprise `pip install`, and run your stated test command before declaring victory. That delta (behavior you'd normally have to dictate, now happening by default) *is the file working*.
|
|
|
|
Then change a rule (add `Keep functions under 20 lines; split anything longer.`), run `git diff` to read it like a reviewer would, and commit it. You just made a change to your AI workflow that's readable, attributable, and revertable.
|
|
|
|
## Where it breaks (because I always tell you)
|
|
|
|
- **It's guidance, not a guarantee.** The file biases the model hard; it doesn't bind it. An AI can still blow past a vague line deep in a long session. The enforcement that *can't* be ignored (tests that fail the build, scans that block a merge) comes later in the course. The instructions file reduces how often things go wrong; it doesn't replace the gates that catch it when they do.
|
|
- **Bloat kills it.** A 300-line instructions file gets read the way *you* read a 300-line terms-of-service: not really. Prune anything the model already honors.
|
|
- **Stale is worse than empty.** A file that names the wrong test command will *actively* misdirect the AI. This thing is code-adjacent; maintain it like code, review it like code.
|
|
- **It is not a security control.** "Don't touch `secrets.env`" is a convention, not a permission boundary. A confused or adversarial agent can still read it. Real isolation comes much later; the file expresses intent, it doesn't enforce it.
|
|
- **The team payoff isn't fully here yet.** On a solo local repo, "no more drift between teammates" is theoretical; there's only you. What you get *today* is the habit and the local history. The full value lands once the file reaches a shared remote and a review process, which is exactly where the next couple of posts go.
|
|
|
|
## Where this is heading
|
|
|
|
A committed instructions file is the lightweight foundation: always-on context, read every session, saying *how this project works* in general. The moment you find yourself wanting to capture a *specific repeatable procedure* (say, "here's exactly how we cut a release" or "here's our playbook for adding a CLI command"), that's the structured big sibling: **Skills**, which show up in Unit 4 of the course. Same instinct (write the knowledge down, commit it, let the AI run it your way), but packaged as reusable playbooks instead of one always-on briefing. Start with the instructions file; graduate to skills when a procedure earns its own page.
|
|
|
|
For now, the goal is smaller and very satisfying: open your project, watch the AI behave like it already knows the place, without saying a word this session. That's the file doing its job.
|
|
|
|
If you've got an instructions file that's saved your bacon, or a rule you wish you'd written down three sessions ago, drop it in the comments. I read them, and the good ones make the course better. Next up: branches, so the AI can go try something wild in a sandbox you can throw away if it makes a mess.
|