The "So, About This Codebase..." Problem
Here's a workflow I used to hate. You open a new terminal session, fire up some AI assistant, and the first five minutes are just you re-explaining the project. "This is a Django API. Auth lives in apps/auth. We use Postgres, not SQLite. The test runner is pytest with --reuse-db. Please don't touch legacy/."
Every. Single. Session.
Even if you're working on the same repo you've been in for three months. The context window is blank, and you're back to being a tour guide for your own codebase.
lac agent solves this with project memory — a file called .lac-memory.json that sits at the root of your project and loads automatically every time you start an agent session in that directory.
What .lac-memory.json Actually Is
It's a plain JSON file. No proprietary format, no binary blobs. You can read it, edit it by hand, and commit it to your repo if you want the whole team to share the same context. It stores structured information about your project that lac agent reads before it does anything else.
Think of it as the briefing doc the agent reads every morning before touching your code. Stack, conventions, off-limits directories, known quirks — all in one place.
When you run lac agent in a directory that has a .lac-memory.json, it loads that file into context automatically. You don't pass a flag. You don't remind it. It just knows.
How Memory Gets Built
The first time you run lac agent in a project, it doesn't have a memory file yet. But as you work through a session — asking it to read files, explaining architecture, telling it what's off limits — you can tell it to remember specific things.
Say something like:
Remember that auth logic lives in apps/auth and we never modify legacy/ directly.
The agent writes that to .lac-memory.json. Next session, it already knows. You can also just write the file by hand, which is honestly what I do for new projects. Takes two minutes and saves a lot of friction.
A minimal memory file might look like this:
{
"project": "billing-api",
"stack": "Django 4.2, PostgreSQL, Celery, Redis",
"test_command": "pytest --reuse-db -x",
"off_limits": ["legacy/", "migrations/"],
"conventions": [
"Use class-based views, not function-based",
"All API responses go through ResponseSerializer",
"Never hardcode environment variables"
],
"notes": "Stripe webhook handler is in payments/views.py line 88, it's fragile"
}
That last "notes" field is underrated. I use it to flag things that have bitten me before — files that look safe to edit but aren't, functions that have side effects, that one config setting that's weirdly load-bearing.
Why This Changes How You Actually Work
The shift isn't just about saving five minutes of setup. It changes the quality of what the agent does.
When lac agent knows your test command upfront, it runs your tests after edits without being asked. When it knows which directories are off limits, it won't touch them even when a refactor would logically lead it there. When it knows your conventions, the code it writes actually fits the rest of your codebase instead of introducing a random new pattern.
Without memory, the agent is doing its best with whatever it can infer from the files it's read in the current session. With memory, it has the same mental model you'd give a new engineer on day one — the stuff that isn't obvious from the code itself.
Sharing Memory Across a Team
This is where it gets genuinely useful for teams. Commit .lac-memory.json to your repo. Now every developer who uses lac agent on that codebase gets the same baseline context. No one has to discover the "don't touch legacy/" rule by accidentally breaking something. It's documented, version-controlled, and machine-readable.
You can update it the same way you'd update a README — open it in your editor, add a note, commit it. Or tell the agent during a session and let it update the file itself.
One thing worth knowing: if you don't want to commit it (maybe the notes contain internal context you'd rather not share), just add .lac-memory.json to your .gitignore. Local memory, still useful, just not shared.
Memory Works With the Rest of the Agent
Project memory isn't an isolated feature — it stacks with everything else lac agent does. When you use PlanMode, the plan it generates respects the conventions and off-limits paths from memory. When you run /multi to split a task across parallel agents, each agent gets the same memory context. Undo/redo still works the same way.
It's just context that's always there, the same way your editor's syntax highlighting is always there. You stop noticing it after a while because things just work the way you expect.
A Practical Starting Point
If you want to try this today, here's what I'd do. Go to a project you work in regularly. Create a .lac-memory.json at the root with at minimum: the stack, the test command, and any directories that should never be touched. Take five minutes on it. Then run lac agent and ask it to do something that would normally require you to explain the setup first.
The difference is immediate. Install lac-cli with:
pip install lac-cli
Or grab the install script from lacai.io/lac-cli. The memory file will be waiting for you after your first session in the project.
Once you've got it set up, the most useful thing you can add isn't the obvious stuff like stack and test commands — it's the weird institutional knowledge. The function that looks deletable but isn't. The environment variable that silently controls half the app's behavior. That stuff is worth writing down once, in a place that actually gets read.