Make AI Coding Tools Follow Your Project Conventions

    A project guide file in the repo root gives AI coding tools the architecture, module boundaries, naming rules, and verification steps they cannot infer from local code alone. This article explains what to put in that file, how to write executable rules, and how to keep it in sync with the codebase.

    As AI coding tools enter everyday development, a common problem appears: they can generate code without really understanding the current project.

    They know language syntax and can complete a function from nearby context. When a task involves architecture, module boundaries, naming conventions, testing, or deployment, the result often drifts from real requirements. The code may run, yet it can violate existing rules, break directory layout, reimplement existing capabilities, or add dependencies the team has banned.

    The gap is not only the model. It is whether project context is provided accurately and continuously.

    In practice, a dedicated project guide file can act as a map for the tool. Place it at the repository root. Name it by team convention, for example PROJECT.md, AI_GUIDE.md, or another clear name. Its value is not a pile of prose. It makes explicit what developers already know and the tool cannot infer.

    Why a project guide file matters

    Ordinary completion relies on the current file, nearby code, and limited context. A real software project has many layers:

    • Dependencies between business modules
    • Directories that may hold interfaces only, not business logic
    • Features that must reuse existing services
    • Fixed test, build, and release flows
    • Different formatting, naming, and error-handling rules per file type
    • Config, secrets, or generated files that must not be edited directly

    These facts rarely live in a single source file, yet they decide whether code is acceptable.

    The guide consolidates rules from team experience, historical docs, review comments, and deploy scripts into something the tool can use. It is a navigation map and a set of behavior boundaries. It should help answer:

    1. What problem does this project solve?
    2. What is each major directory for?
    3. Where should you start reading the code?
    4. Which files does a typical feature change touch?
    5. Which technical choices are already in use?
    6. Which practices are forbidden?
    7. How do you run tests, lint, and verify results?
    8. What should you ask first when requirements are unclear?

    Without that background, the tool guesses from local snippets. With a structured guide, it behaves more like an engineer who has already read the project handbook.

    What the guide should contain

    A good file is dense and actionable, not long. Cover at least the following.

    1. Project purpose and technical boundaries

    State purpose, users, and core capabilities. For example:

    1. Project purpose:
    2. This project collects, cleans, and queries internal business data.
    3. Technical boundaries:
    4. - The server handles data processing and permission checks.
    5. - The frontend handles display and interaction only; it must not access underlying data sources directly.
    6. - All writes must go through a unified service layer.
    7. - Do not introduce a new persistence approach in this project unless it has passed a technical review.

    This keeps the tool from expanding a local request into an unsupported area.

    For a multi-module repo, describe module relationships:

    1. Module relationships:
    2. - api: external interface layer; parameter intake and response assembly only.
    3. - service: business rules and flow orchestration.
    4. - repository: data access; no business decisions.
    5. - shared: reusable foundations across modules.

    Clear module notes reduce logic in controllers and duplicated helpers.

    2. Directory layout and key entry points

    A tree is useful only if each directory’s role is explained.

    1. Directory notes:
    2. src/
    3. api/ Interface definitions and request handling
    4. service/ Core business logic
    5. repository/ Data access
    6. domain/ Domain objects and business rules
    7. config/ Config loading and environment adaptation
    8. tests/ Automated tests
    9. scripts/ Local development and check scripts
    10. docs/ Design and API documentation

    Add reading guidance for important paths:

    1. Reading order:
    2. 1. Start with src/api/ to see how the system is called.
    3. 2. Then read src/service/ for business flow.
    4. 3. Database logic lives in src/repository/.
    5. 4. For new features, find a similar existing implementation first; do not invent a parallel structure from scratch.

    Directory names alone do not tell a tool whether a folder is a stable API, temporary code, generated output, or a test-only experiment.

    3. Coding standards and design constraints

    Write rules that can be followed, not vague values.

    Avoid:

    1. Keep the code simple and maintainable.

    Prefer:

    1. Coding requirements:
    2. - Each function has one clear responsibility.
    3. - New public functions must have unit tests.
    4. - Do not access the database from the controller layer.
    5. - Errors must use the project’s unified error types.
    6. - Do not store request-scoped state in globals.
    7. - Reuse existing helpers; do not reimplement the same logic.
    8. - Use full, meaningful names; avoid opaque abbreviations.

    Add language- or framework-specific rules as needed: async I/O, whether generated files may be edited, explicit null and exception handling, debug prints in business code, docs for public APIs, and backward compatibility.

    Rules should match real workflow. Do not dump every personal preference. Over-fine constraints hurt readability and make the tool confirm irrelevant details on simple tasks.

    How to write rules the tool can actually use

    1. Use clear, verifiable language

    This is not marketing copy. Each rule should be checkable by tests, lint, or review.

    Example:

    1. Before submitting a change, you must:
    2. - Run unit tests
    3. - Run static checks
    4. - Check for unused dependencies
    5. - Confirm generated directories were not modified
    6. - Add related docs for API changes

    That is easier to execute than “review carefully before submit.”

    2. State priority and exceptions

    Rules conflict. Global reuse may clash with a performance-sensitive module that allows a specialized implementation. Rank them:

    1. Rule priority:
    2. 1. Safety and data integrity come first.
    3. 2. Module-level constraints override global ones.
    4. 3. Existing public interfaces must not change casually.
    5. 4. Performance work must not skip required checks.

    If a directory has special rules, put a more specific file there so local rules override global ones. That keeps the root file smaller and rules closer to the code.

    3. Show good and bad examples

    Examples beat abstract wording:

    1. Preferred:
    2. - Validate business rules in the service layer.
    3. - Limit the repository layer to reads and writes.
    4. - Return failures through a unified error object.
    5. Not preferred:
    6. - Put complex business flow in interface handlers.
    7. - Copy the same data-transform logic across modules.
    8. - Catch exceptions and ignore them silently.

    You do not need every case—focus on the mistakes that happen most.

    Document run and verification flows

    Tools can help run checks as well as generate code. Describe how to start, test, and verify:

    1. Local verification:
    2. 1. Install project dependencies.
    3. 2. Run format checks.
    4. 3. Run static analysis.
    5. 4. Run unit tests.
    6. 5. If APIs changed, run API tests.
    7. 6. Inspect the build result and changed files.
    8. Test requirements:
    9. - Bug fixes must add a test that reproduces the issue.
    10. - New business branches must cover success and failure paths.
    11. - Permission, money, and state-transition changes need boundary tests.

    If there are test subsets, say when to use them: fast tests for local iteration, full tests before submit. Then the tool will not run a slow suite on a tiny change or skip checks on an important one.

    Do not invent commands, scripts, or flags that do not exist. Document only real flows. If a step depends on the local environment, state the prerequisites instead of letting the tool guess.

    Common failures and how to fix them

    Failure 1: Project intro only, no operating rules

    Long background with no “how to change code” helps humans more than generation.

    Fix: less slogan, more directory duties, change boundaries, verification, and bans.

    Failure 2: Too long; the important rules drown

    History, meeting notes, and repetition hide constraints.

    Fix:

    • Keep stable rules in the main file
    • Put detailed design in separate docs
    • Use headings and lists
    • Delete stale history
    • Group high-priority rules

    Failure 3: Contradictory rules

    One place requires API compatibility; another says change the response shape. One bans new dependencies; another requires an unintroduced component.

    Fix: review consistency regularly. State priority, scope, and exceptions.

    Failure 4: Docs drift from the code

    If structure changes and the guide still describes old directories and flows, the tool is misled.

    Keep the file in version control and update it when you:

    • Add or remove core modules
    • Change build or test flow
    • Change APIs or data models
    • Add security requirements
    • Align team coding standards
    • See the tool repeat the same mistake

    Small projects can use one root file. Large repos can layer:

    1. project root/
    2. PROJECT.md Global rules and project map
    3. src/
    4. api/
    5. PROJECT.md API-layer-specific rules
    6. data/
    7. PROJECT.md Data-access-layer-specific rules
    8. tests/
    9. PROJECT.md Test writing and verification

    The root file covers purpose, overall architecture, shared rules, and basic verification. Subdirectory files add local differences only.

    Benefits:

    1. Rules sit next to code and cost less to update
    2. Modules can have independent constraints
    3. Local tasks get more focused context

    Keep improving the guide

    The file is accumulated team knowledge, not a one-time config.

    Record typical tool mistakes

    If it keeps putting data access in the API layer, spell out module duties and add correct examples. If it edits generated files, mark those directories and the right change entry points.

    Turn review comments into rules

    Repeated review issues—inconsistent errors, weak tests, duplicated helpers—become short constraints.

    Prune stale content

    Periodically check directories, scripts, dependencies, and flows. Drop expired rules and merge duplicates so the doc matches the current engineering state.

    Separate facts from suggestions

    “This directory is produced by the build” is a fact. “Prefer this style” is a suggestion. Label them so the tool does not treat advice as hard limits or ignore real facts.

    Conclusion

    How well an AI coding tool works depends on the model and on whether the project supplies clear, accurate, executable context. The project guide is the bridge between general intelligence and this codebase’s practice.

    Treat it as part of how the team collaborates: describe structure, define code boundaries, explain tests, record pitfalls, and update it as the system evolves.

    When the tool knows where code belongs, why the layout exists, what is unacceptable, and how to verify a change, it is no longer completing from local text alone. It is working inside the project’s existing rules. Individuals spend less time repeating instructions and reworking output. Teams get more consistent standards, faster onboarding, and more controllable AI-assisted development.