13 October, 2026
By S1 you already have:
By S2 you have:
Objective
Your repo currently works for you, on your machine, today. Make it work for an agent, a stranger, and future-you — on a different machine, next year.
We won’t re-teach git init / add / commit — you did that in S1. This session is about the parts of git and project structure that make a repo portable and legible to an agent, not just to you.
Want more git basics?
The old, longer walk-through — Git Version Control — is still in the repo as optional reference material if you want more drills on branches, merges, and conflict resolution.
This works exactly once: on your machine, in that exact location. It breaks the moment:
Why this matters more with agents
When you hand a repo to an agent and say “run the pipeline,” it infers structure from what it can see: file names, relative paths, a README. A hardcoded absolute path isn’t just non-portable — it’s context the agent cannot reconstruct from the repo alone. It has to fail, notice the failure, and ask where the data really is. That’s a wasted round trip you can eliminate for free.
Exercise 1
Ask your agent to grep your repo for absolute paths (/Users, /home, C:\) and fix every hit using one of the patterns above. Verify by running the scripts from a different working directory than usual.
your-project/
├── README.md # what this is, how to run it, what to expect
├── AGENTS.md # rules file for coding agents
├── .gitignore
├── data/ # raw + intermediate data
├── R/ or src/ # source code — functions, not just scripts
├── scripts/ # top-level "run this" entry points
├── tests/ # your S2 tests live here now
├── output/ # figures, tables — generated, not hand-edited
└── prompts/ # archived prompts/sessions
An agent that sees a tests/ folder looks there first, and is more likely to run the existing suite before declaring success. An agent that sees everything dumped flat in the repo root has no such signal — and will guess.
Exercise 2 — restructure your S2 repo
Move your S2 scripts and tests into this layout. Ask your agent to propose the move, then check its work: do scripts still run? Do tests still pass? Did any path silently break?
A README is the first (and sometimes only) context an agent — or a stranger, or you in eight months — gets before touching your code. A good README for this course answers, in order:
What a README is not: a changelog, a diary of what you tried, or a copy of your code comments. Keep it short enough that an agent’s context window doesn’t have to spend most of its budget reading prose to find the one command it needs.
Try it
Ask your agent — in a fresh session, with no prior context of this project — to read only your README and try to run your pipeline.
If it gets stuck, your README has a gap, not the agent. This is the only reliable way to check “could a stranger pick this up cold” — you already know how your own project works, so you can’t self-assess this one.
.gitignore disciplineNot everything belongs in version control. Three categories that must never be committed:
.DS_Store, .Rproj.user, __pycache__/.# secrets
.env
*.key
# data (if large / regenerable — document how to get it in README instead)
data/raw/
# machine/tooling junk
.DS_Store
.Rproj.user/
__pycache__/
*.pyc
Check now
Run git log --all --full-history -- "*.env" (or search for any key-shaped string) on your S2 repo. If anything comes back, treat that key as compromised — rotate it.
Copy the public key to GitHub → Settings → SSH keys:
Add the remote and push:
origin is just a name (convention); -u sets main as the tracked upstream so future git push needs no arguments.
Why bother for a solo course project? Because agent-assisted changes can be large and wrong in ways that are hard to spot mid-edit. A branch lets you review the whole diff before merging into main — the same discipline this course’s own repo uses (agentic-redesign → feature branches → review → merge).
OpenCode (and most harnesses) read a project-level instructions file at the repo root — conventionally AGENTS.md. Standing instructions go here instead of being re-typed into every prompt.
# Agent instructions for this repo
## Stack
- R (>= 4.3) and Python (>= 3.11), see README for exact deps.
## Conventions
- No hardcoded absolute paths. Use `here::here()` in R,
`Path(__file__)`-relative paths in Python.
- Every function in `R/` or `src/` should have a corresponding
test in `tests/`.
## Before declaring a task done
- Run the test suite (`Rscript tests/run_all.R` or `pytest`) and
confirm it passes. Do not just say tests would pass.
## Do not touch
- `data/raw/` is read-only — never overwrite raw source data.Exercise 3 — write your AGENTS.md
Write one for your S2 repo. Keep it short. Then start a fresh agent session and ask for a trivial change. Check whether it actually followed a rule you set (e.g. did it run the tests before saying it was done?).
“It worked when I tried it” is not reproducible if you don’t know which model you tried it with. Models get updated, deprecated, or silently change behavior server-side.
openrouter/deepseek-v3.2:free, checked 2026-09-20) in your README or AGENTS.md.git log records what your code looked like at each commit. It does not record what you asked the agent to get there.
prompts/
├── 2026-09-20-restructure-layout.md
└── 2026-09-20-add-agents-md.md
Each file: the prompt you gave, plus optionally a one-line note on what you had to correct afterward — material you’ll reuse for your S11 checklist.
Why bother
git log answers “what changed.” A prompt archive answers “why” — in an agent-assisted world, “why” often means “what did I ask for.”
(absorbs old Building R packages — not “how to publish to CRAN,” but “structure is what makes a project reproducible”)
A package (R) or installable module (Python) is the strict, tooling-enforced version of everything above: declared dependencies, fixed internal layout, a built-in place for tests.
R — minimal skeleton:
myproject/
├── pyproject.toml # declares deps + build system
├── src/myproject/
│ ├── __init__.py
│ └── clean_data.py
└── tests/
└── test_clean_data.py
Common thread: dependencies are declared, not just “whatever happened to be installed,” and tests live where a human and an agent will look for them by convention.
Exercise 4 (optional)
Turn one small function from your S2 scripts into a minimal package/module using the skeleton above, with one test. Full package-publishing depth (vignettes, pkgdown, GitHub Actions CI) is in the r-pkgs book if you want to go further.
By the end of this session your S2 repo should have:
README.md, AGENTS.md, data/, source folder, tests/).gitignore that keeps secrets and junk out of historyAGENTS.md with the conventions you actually want enforcedprompts/ folder with at least one archived prompt from this sessionKey points
.gitignore discipline keeps secrets and junk out of a history you can’t rewrite.AGENTS.md) is durable context: write conventions once, have every agent session read them automatically.