Context Mastery: GEMINI.md & .aiexclude
G02's key insight was "your file is the prompt." This module scales that up: your project is the prompt — and you get to decide exactly what's in it, what rules govern it, and what must never leave your machine.
The Context Layers
A new contractor walks onto your job site. What they know arrives in layers: what they can see standing there (the room they're in), the blueprints for the whole building, the site rulebook taped to the wall ("hard hats always, no welding after 6pm"), and a locked office they're explicitly not allowed to enter. Remove any layer and you get predictable failures — no rulebook means every contractor improvises their own standards; no locked office means your payroll files end up in a stranger's truck. Gemini Code Assist has exactly these four layers, and by the end of this module you'll control all of them.
Local Codebase Awareness
Local codebase awareness means Gemini Code Assist doesn't limit itself to open files: when you ask a question or request a change, it retrieves the relevant files from your whole workspace and includes them in the prompt, leaning on Gemini's 1M-token context window. It's how "where do we validate recipe input?" gets answered with the actual three locations across app.py and storage.py rather than a guess.
Awareness of your full local workspace is a Standard/Enterprise capability; the free tier works from a narrower window (open files + selections). Enterprise's code customization (G11) goes one step further — awareness of your organization's remote private repos, not just the project on disk.
A million tokens is huge but not infinite, and relevant retrieval beats raw size. Two practical habits: keep your repo tidy (a workspace full of node_modules, build artifacts, and data dumps dilutes retrieval — .gitignored paths are generally skipped), and for surgical questions still select code or attach the file explicitly — explicit beats inferred every time.
GEMINI.md: Standing Rules For Your Project
Every team has a senior engineer who repeats the same review comments forever: "we use type hints here," "wrap storage errors," "don't return raw dicts from routes." Repeating them is the pain — the knowledge exists, but it lives in one person's head and gets re-taught one pull request at a time. GEMINI.md is those review comments written down once and injected into every AI request automatically. The model stops being a talented stranger and starts being a teammate who's read your team's handbook — because now there is one, and it's three paragraphs of Markdown.
GEMINI.md is a free-form Markdown file of project facts and rules that Gemini Code Assist automatically loads as system-level context. Placement:
- Project:
GEMINI.mdat the project root (VS Code also honors them in subdirectories — deeper files refine broader ones for code in that subtree) - Global:
~/.gemini/GEMINI.md— your personal rules across all projects (VS Code) - IntelliJ:
GEMINI.mdat the project root
It is shared by chat, agent mode (G06–G07), and Gemini CLI (G08) — one rulebook, three surfaces. There's no fixed schema: write what a new senior hire would need on day one, in the order they'd need it.
Without rules, you correct the same AI mistake daily — suppose a correction costs 90 seconds and you make 10 AI requests a day where conventions matter: that's 15 minutes/day of re-explaining, ~60 hours/year, per developer. A GEMINI.md takes 20 minutes to write once and applies to every request from every teammate who clones the repo (commit it!). It's the single highest-leverage file in this course.
.aiexclude: Keeping Secrets Out of Prompts
.aiexclude is a file (project root, or deeper directories for scoped rules) using .gitignore syntaxOne pattern per line: exact names (secrets.json), wildcards (*.pem), directory paths (config/keys/). A pattern matches files relative to the .aiexclude file's location. that blocks matching files from all Gemini Code Assist context: completions, chat, codebase awareness, and agent mode. An empty .aiexclude blocks everything in its directory and below.
Difference from .gitignore: gitignore controls what enters version control; aiexclude controls what enters AI prompts. You usually want both — but they are not interchangeable. A checked-in customer_data/ folder belongs in version control AND out of prompts.
# Credentials and keys — never in any prompt
.env
.env.*
*.pem
*.key
service-account*.json
# Real data — privacy, not secrecy
customer_exports/
*.sqlite
recipes.db
# Vendored code — noise that dilutes retrieval
vendor/
Without exclusions, a completion triggered inside config.py can legitimately include your .env contents in the prompt context — that's the tool working as designed, reading "related files." Your API keys then transit to the model along with everything else. Standard/Enterprise contractually exclude your prompts from training, so this isn't "Google learns your keys" — but your security team is still right to demand that credentials never leave the machine at all. .aiexclude is how you honor that, mechanically, for every current and future teammate.
Lab: Prove That Rules Change Output
This lab is an experiment with a control group: same prompt, before and after GEMINI.md. You'll see the difference with your own eyes — the most convincing demo in this course.
Baseline: ask without rules
In chat (no selection), run this exact prompt and save the answer (paste it into a scratch file):
Add a DELETE /recipes/<id> endpoint to app.py
Typical baseline output: a working route, but with choices the model had to invent — maybe raw dict returns, maybe no 404 handling, maybe inline SQL instead of a storage function. Note its choices; they're about to change.
Write Recipe Box's GEMINI.md
Create GEMINI.md at the project root:
# Recipe Box — Project Context
## What this is
A Flask + SQLite recipe API. Entry point: app.py (port 5001).
Storage layer: storage.py — ALL database access goes through it.
Search: search.py. Tests: tests/ (pytest, temp-DB fixture in conftest.py).
## Architecture rules
- Routes never touch sqlite3 directly. Add storage functions instead.
- Every route validates input and returns JSON errors:
{"error": "..."} with a correct status (400 bad input, 404 missing).
- Successful creation returns 201; successful deletion returns 204.
- All storage functions wrap sqlite3.Error in StorageError.
- Type hints on every function. Google-style docstrings on public ones.
## Testing rules
- Every new storage function and route gets pytest tests.
- Tests use the temp-DB fixture — never the real recipes.db.
## Never do
- Never use f-strings to build SQL (parameterized queries only).
- Never return hashed/internal fields to clients.
- Never add a dependency without flagging it explicitly.
Re-run the experiment
Start a new chat (fresh context — this matters: old chats may not reload rules) and run the identical prompt:
Add a DELETE /recipes/<id> endpoint to app.py
storage.delete_recipe(recipe_id) function (not inline SQL), return 404 with a JSON error for missing ids and 204 on success, carry type hints and a docstring — and likely offer pytest tests because the rules demand them. Count the differences; each one is a correction you'll never have to make by hand again.Add the safety layer
Create .aiexclude at the project root, then verify it took effect:
.env
*.pem
recipes.db
Create a decoy .env file containing FAKE_API_KEY=test-12345-not-real. In a new chat, ask: "What environment variables does this project use?"
.env contents — the file is invisible to it. If it names your fake key, check the .aiexclude location (project root) and spelling, reload the window, and retry in a fresh chat.Commit the contract
git init
git add GEMINI.md .aiexclude app.py storage.py search.py tests/
git commit -m "Recipe Box with AI context rules and exclusions"
Committing GEMINI.md and .aiexclude makes them team infrastructure: every teammate (and every agent run in G06) inherits the same rules and the same safety rails. You'll also need this git repo for G07 and G09.
You ran a controlled experiment: identical prompt, observably different output, with GEMINI.md as the only variable — proof that rules are real, not placebo. Then you mechanically excluded secrets and committed both files as team infrastructure. Layers 1–4 are now all under your control, which is the prerequisite for what comes next: handing the keys to an agent.
Knowledge Check
1. What does local codebase awareness add over G02's cursor context?
2. Where does a personal, applies-to-all-projects rule file live for VS Code?
3. .gitignore vs .aiexclude — which statement is correct?
4. Why did the lab insist on a NEW chat after creating GEMINI.md?
5. Which content belongs in GEMINI.md rather than in each prompt?
Quiz Complete!
Ready for G06: Agent Mode I — Delegating Multi-File Work →