Project Memory Files: Context, Conventions, and Collaboration Practices
This article explains project memory files, structured Markdown documents stored in a code repository that AI coding assistants read at the start of a session. It covers the problems these files solve, what to include and exclude, how to place and merge files at multiple levels, writing principles, maintenance workflow, a review checklist, common failure modes, and team governance.
A project memory file is a structured document kept in a code repository, usually written in Markdown, that an AI coding assistant reads at the start of a session. It is not a replacement for a requirements document, and it is not a prompt that holds all of the architecture knowledge. Its role is narrower and more stable. It records how the repository should be changed, what must not be changed, and which constraints apply to the output, as persistent context that people can read and tools can parse. This reduces the need to explain the same background in every conversation.
What Problem It Solves
In long-running projects, an assistant works with incomplete local context: the current file, a few recent conversations, and a few sentences the user adds on the spot. Without project-level constraints, common problems appear. The assistant may choose the wrong tech stack, break directory conventions, skip testing and release steps, write comments and interfaces in a style that does not match the existing code, or turn a one-off experiment into a long-term design.
A project memory file puts these constraints first. The assistant loads it at the start of a session, which gives later reasoning a stable baseline: the project goal, its boundaries, the default technical choices, which directories are generated, and which are maintained by people. Communication costs drop, and the assistant’s behavior becomes more predictable. In a repository with several contributors, the file also serves as a written agreement on how the team uses the assistant. It is easier to hand over and audit than verbal agreements.
What to Include and What to Avoid
Effective content is short, actionable, and verifiable. It should generally cover the following categories.
- Project goals and non-goals: the problems the current iteration addresses, and the scope that is explicitly out of bounds.
- Tech stack and constraints: language versions, framework categories, and how builds and tests are run. Use general descriptions, and avoid hard-coding parameters that have not been verified.
- Directory and module boundaries: where core code, adapter layers, scripts, and documentation live, and the rules for generated artifacts that must not be committed.
- Coding and interface conventions: naming, error handling, log levels, configuration sources, and whether new dependencies are allowed.
- Verification: which checks must run after a change, and how to label risk when local verification is not possible.
- Security and compliance baselines: secrets, credentials, and personal data must never be written to the file or committed. External calls need a clear authorization boundary.
Some content does not belong in the file. This includes full copies of design documents, one side of an unresolved debate, examples that contain sensitive information, and temporary instructions for a single conversation. Temporary instructions should stay in that session. Only rules that remain valid over the long term belong in the memory file. A long file takes up useful context space, and contradictory sentences are hard to follow consistently.
A minimal structure is enough:
# Project Memory## Goals- Maintain the stability of the existing service, favoring small, incremental changes.## Technical Constraints- Keep the existing language and build approach. Do not change the tech stack without approval.- Read configuration from the environment or a configuration center. Do not hard-code secrets.## Change Principles- Read the relevant modules before editing. Public interface changes must update documentation and tests.- New dependencies require a stated reason and an assessment of maintenance cost.## Verification- Before committing, run the existing tests and static checks. Do not claim completion if they fail.
Multi-Level Placement and Merge Priority
A repository often has global habits, project conventions, and local exceptions. A memory file can be placed at several levels and merged by priority. This lets rules closer to the code override more general rules, and it prevents subdirectory rules from quietly overriding security baselines.
In practice, the order from highest to lowest priority can be: the current workspace or personal local overrides, the project root, subdirectory additions, and user-level global habits. Three principles apply when merging.
- Security, compliance, and license constraints may only be tightened. Lower levels may not loosen them.
- A subdirectory rule should explain only the special structure of its own directory. It should not repeat the full root file, because two copies will drift apart.
- Local overrides handle differences in personal environments, such as local paths or debug switches. Personal preferences must not be committed as team defaults.
The team should write the reading order as an explicit agreement, and the first one or two sentences of each file should state how the file relates to the levels above and below it. Without this, the assistant and the people on the team may disagree about which rule applies.
Writing Principles
First, make instructions observable. Instead of writing “the code should be elegant,” write “public functions include a description of their purpose; errors must carry context and must not swallow exceptions.” Observable rules can be checked during review.
Second, each rule should express one constraint, with the shortest reason that justifies it. A reason helps the assistant make trade-offs in edge cases, but it should not grow into a tutorial.
Third, default to caution. For technical choices that are uncertain, write “keep the current approach and note it in the change description” instead of guessing at a more advanced option. A memory file is not the place for experiments.
Fourth, keep the file consistent with the actual repository. If the file requires a certain directory layout but the code already uses a different one, the assistant will waver between the two versions of reality. When you find a mismatch, update either the file or the code first, but make sure they align.
Fifth, control length and structure. Use stable, short headings and avoid rhetoric and marketing language. Put the most important rules near the top, and keep examples to the minimum needed.
Division of Labor with Requirements and Design Documents
The memory file defines how to change the repository. The requirements document answers what to build. The design document answers why the modules are divided the way they are. None of the three should replace the others. When a design decision is stable and affects all later changes, the memory file only needs to record the conclusion and a pointer to the design document. For example: “The interface versioning policy follows the design document. Changes must remain backward compatible.” Do not copy long arguments into the memory file.
When requirements change often, keep the volatile parts in the task description and the stable parts in the memory file. This reduces how often the file must be updated and prevents outdated instructions from misleading the assistant.
Implementation Workflow
Treat the memory file as a first-class engineering artifact, not a personal note.
- Initialization: Someone familiar with the repository drafts the file. It should cover goals, constraints, verification, and prohibited actions, and stay short enough for the team to read in full.
- Review: Apply the same standards as code review. Check that the file matches the actual build, tests, and directories, and that it contains no secrets or internal addresses.
- Trial: Use several typical tasks to check whether the assistant respects the boundaries, for example “modify only the specified module,” “do not add dependencies,” or “tests must be added.” Record cases where rules were broken, and use them to find rules that are ambiguous.
- Change: Put rule changes under version control and explain the reason for each change. Significant tightening, such as banning direct commits of a certain type of generated code, should be announced to all members in the change description.
- Cleanup: Remove outdated tech stacks, deleted directories, and retired processes promptly. An outdated rule does more harm than a missing one.
Quality Checklist
Before publishing or merging, check the file with these questions. Can a new team member understand the entry points for changes and the verification steps from this file alone? Are there any sentences that contradict each other? Could a subdirectory override a security rule? Does the file mention specific vendor interfaces, undisclosed parameters, or performance figures that cannot be verified? Do the example paths still exist? Is the file short enough to be fully understood at the start of a session?
Common Failure Modes
Rules written as wish lists. Without verification steps and prohibitions, the assistant still follows general habits.
Undefined priority between levels. The global rules require detailed comments, while a subdirectory requires minimal comments, but nothing says which one wins. The output style then changes from one session to the next.
One-time incidents written into the long-term file. A temporary ban that followed a bad change can restrict normal refactoring for a long time if it has no review date.
Context bloat. Meeting notes, full histories of past decisions, and unrelated business background crowd out the key constraints, and compliance drops.
Implicit ties to a brand or environment. Commands that exist only in one toolchain, or private addresses, stop working when the environment changes. They also turn the memory file into a non-portable script. Use neutral descriptions instead, and put specific commands in the repository’s existing scripts and documentation, where people choose when to run them.
Team Governance Recommendations
Assign a maintainer, but let any member change the file through review. Treat a mismatch between the memory file and the code as a defect. Explain the reading order in onboarding materials for new members. For automated agents or batch rewriting tasks, emphasize the following: present a change plan before editing, do not delete tests to make a build pass, and do not commit secrets or large generated artifacts.
If the company already has unified engineering standards, the memory file should contain only the differences specific to this repository. For everything else, cite the relevant sections of the internal standards by name. This makes use of the platform’s general engineering processes, such as code hosting, continuous integration, logging, and access management, without copying a full set of policies into every repository.
Summary
The value of a project memory file is that it places stable, actionable, and auditable project context ahead of every collaboration session. Define the goals and non-goals clearly, tighten security and verification rules, set multi-level priorities, and keep the file aligned with the real repository. The assistant’s output then shifts from looking reasonable to following the way this project actually works. The file should stay short, precise, and able to evolve. If it turns into a promotional piece, a running log, or an outdated manual, trim it right away.
