Shared Project Memory for AI Coding Assistants: Keep Context When You Switch Tools

    Running two or more AI coding assistants at the same time is now routine, yet every switch forces you to re-explain the same architecture decisions, rejected options, and domain knowledge, because that context lives in one tool's chat history. This article explains the structural reasons context is lost, then describes how to treat project context as a versioned code asset stored as Markdown in the repository: a four-layer memory model (long-term constraints, decision records, knowledge base, in-progress task state), a directory layout and entry template, the triggers that decide when memory is written, layered injection so each assistant picks it up automatically, concurrency control through single-writer discipline, optimistic locking, and atomic writes, privacy boundaries for what must never be stored, four metrics for judging whether the approach works, and a phased rollout plan.

    1. Where the Problem Starts: The Tooling Is Fine, the Memory Is Locked In

    Using two or more AI coding assistants in parallel is already common. People keep a primary tool and a backup for practical reasons: account availability, quota allocation, differences in model capability, or compliance requirements. What actually drains energy is not maintaining two toolchains, it is re-entering context.

    The architecture choice you settled on in your primary tool yesterday, the option you rejected, the production incident you already debugged, the code style you agreed on — all of it has to be explained from scratch when you move to the backup tool today. Worse, those conclusions usually exist only inside the history of a single conversation. They belong to the tool, not to the project.

    Step back one level and the conclusion is obvious: context is a project asset and should not be parked in the session state of any single tool. Tools get swapped, accounts get throttled, sessions expire — but the technical decisions and domain knowledge of a project should persist.

    2. Why Context Gets Lost: Four Structural Reasons

    1. State lives inside the process. In most conversational tools, context has the lifetime of a session. Once the session ends or its history is cleared, it is unreachable.
    2. There is no standard export/import contract. Session formats are mutually incompatible, so migration cannot be automated; it is copy-paste by hand.
    3. Context is narrative, not structured. A block of free text mixes background, conclusions, to-dos, and speculation. Reusing it is hard: it resists retrieval, resists verification, and grows without bound.
    4. There are no freshness or confidence markers. A conclusion from three months ago looks exactly like one from last week, so whoever reuses it cannot tell what has already gone stale.

    The fix is therefore not “find a tool that remembers everything,” but decouple memory from the tool and put it in the project’s own repository.

    3. Design Principles: Treat Context as a Code Asset

    • Files are the contract. All memory is stored as plain text (Markdown) inside the project repository. Any tool that can read files gets the context, which makes the setup tool-agnostic by construction.
    • Put it under version control. Every change to memory has an author, a timestamp, a reason, and a rollback path, which prevents memory from being quietly corrupted.
    • Structure beats narrative. A shared template, explicit fields, and an explicit state machine make memory parseable, verifiable, and searchable.
    • Inject on demand rather than dumping everything. The context window is a limited budget. Long-term memory should stay out of the prompt by default and be retrieved only when relevant.
    • Sensitive data never enters the repository. Keys, tokens, and real user data do not belong in the memory layer. This is a hard boundary, not a preference.

    4. A Four-Layer Memory Model

    Splitting “memory” into four layers with different lifecycles and different uses is the core of this design:

    Layer Contents Change frequency Injection mode
    L1 Long-term constraints Tech stack, coding conventions, prohibitions, environment agreements Very low Loaded by default in every session
    L2 Decision records Architecture choices, trade-offs, reasons for rejection Low, append-only Retrieved by tag or task
    L3 Knowledge base Domain terms, interface contracts, pitfalls already hit Medium Semantic or keyword retrieval
    L4 Session state Current task progress, next steps, blockers Very high Load the “current task” at startup

    L4 is the only layer most people actually use — and it is precisely the layer most likely to be lost. Modeling it explicitly as an in-progress task file gives cross-tool handoff a deterministic landing point.

    5. Directory Layout and Format Conventions

    1. docs/agent-memory/
    2. ├── README.md # read/write rules, index, owner
    3. ├── constitution.md # L1: long-term constraints
    4. ├── decisions/ # L2: decision records (incrementing IDs)
    5. │ ├── DEC-0003-cache-layer-choice.md
    6. │ └── DEC-0007-rate-limit-placement.md
    7. ├── knowledge/ # L3: glossary, interface contracts, incident lessons
    8. │ ├── domain-glossary.md
    9. │ └── pitfalls.md
    10. ├── tasks/ # L4: in-progress tasks
    11. │ └── 2026-08-20-login-refactor.md
    12. └── .meta/
    13. └── manifest.json # revision, entry list, checksums

    Each memory entry uses one shared template so that scripts can validate it field by field:

    1. ---
    2. id: DEC-0007
    3. title: Rate limiting belongs in the gateway, not in business services
    4. status: accepted # proposed | accepted | superseded
    5. updated: 2026-08-27
    6. confidence: high # high | medium | low (whether re-validation is needed)
    7. supersedes: DEC-0003
    8. tags: [gateway, rate-limiting, observability]
    9. ---
    10. ## Background
    11. When traffic spikes, business-service thread pools saturate; there is no single
    12. place that enforces a global limit.
    13. ## Decision
    14. Enforce centralized rate limiting at the gateway layer, and keep a degradation
    15. switch in the business services.
    16. ## Alternatives and why they were rejected
    17. - Rate limiting inside each service: rules are scattered, no global quota is possible.
    18. - A dedicated rate-limiting service: one extra network hop, higher operating cost.
    19. ## Impact and rollback
    20. Affects all inbound requests; rollback means disabling the gateway limiter and
    21. restoring service-level quotas.
    22. ## Open questions
    23. - [ ] Whether peak quotas cover large promotional events

    The point is status and supersedes. When new knowledge arrives, mark the old entry as superseded and point it at the new entry instead of deleting it. Deletion destroys traceability, and traceability is the memory store’s biggest advantage over a chat history.

    6. The Write Path: When Memory Actually Gets Persisted

    Writes must be driven by explicit triggers, otherwise the memory store degrades into an unmaintained pile of drafts. Usable triggers include:

    • End of session: once a task reaches a natural stopping point, write conclusions into L2/L3 and progress into L4.
    • Pre-commit hook: before code is committed, check whether the memory store has unsynchronized changes, so you avoid “the code merged but the reasoning was never recorded.”
    • External events: incident retrospectives, review outcomes, requirement changes.

    Wrapping the persistence step in a command reduces format drift from manual editing:

    1. # End of session: freeze this round's conclusions and write progress back to the task file
    2. memory wrap-up --task current --extract-decisions
    3. # Before starting a new tool: load long-term constraints and the current task brief
    4. memory load --scope project --task current > /tmp/brief.md

    7. The Injection Path: Making Every Assistant Read the Memory Automatically

    Mainstream AI coding tools generally support an instruction file at the repository root, a global preference file at the user level, and supplementary instruction files placed per directory. Using that shared convention is enough to implement layered injection:

    1. # Project instructions (auto-loaded)
    2. @docs/agent-memory/constitution.md
    3. @docs/agent-memory/knowledge/domain-glossary.md
    • Default layer: L1 constraints are always loaded. They are small and change slowly, so the cost is controllable.
    • Retrieval layer: L2/L3 are not injected by default; the tool looks up relevant entries by tags or keywords before starting a task.
    • Task layer: only the single file under tasks/ marked as in progress is loaded. Read it at handoff, archive it on completion.

    For a knowledge base with many entries, keep an index file alongside it (entry ID, title, tags, summary). Read the index first and fetch the body only when needed; this significantly reduces context overhead.

    8. Consistency, Conflicts, and Versioning

    Running several tools in parallel introduces concurrent-write problems. Three strategies are recommended:

    1. Single-writer principle: only one session may hold the write lock at a time (implemented with a lock file or an exclusive branch); all other sessions are read-only.
    2. Optimistic locking check: compare the revision in manifest.json before writing; if it does not match, reject the write and ask the caller to sync first.
    3. Atomic write: write to a temporary file, then rename, so an interrupted process cannot leave a half-written file.
    1. def append_memory(entry: str, expected_revision: int) -> None:
    2. m = load_manifest()
    3. if m.revision != expected_revision:
    4. raise ConflictError("The memory store was updated by another session; sync before retrying")
    5. write_entry(entry)
    6. m.revision += 1
    7. save_manifest_atomic(m) # temp file + rename
    8. git_commit(f"memory: append {entry.id}")

    Add a validation script that runs on a schedule and checks format completeness, duplicate entries, and accepted entries that have not been updated for a long time. That turns “memory rot” into a detectable engineering signal.

    9. Privacy and Security Boundaries

    • Treat the memory store as a sensitive asset by default: host it in a private repository with explicit read/write permissions and access auditing.
    • Define redaction rules: host names, internal addresses, accounts, tokens, and customer identifiers are replaced with placeholders. Intercept them at write time rather than cleaning up afterwards.
    • When off-site backup is required, use a private storage bucket from a general-purpose cloud provider with server-side encryption and access logging enabled; object storage offerings such as Baidu AI Cloud’s satisfy persistence and access-control needs. Versioning on top of that also keeps historical snapshots of the memory.
    • Keep an explicit “never store” list: credentials, keys, unredacted data, and personal reasoning unrelated to the project.

    10. Measuring Whether It Works

    Without measurement, you cannot tell whether the approach actually solved the problem. Four metrics are worth tracking:

    • Context rebuild time: how long it takes to reach a workable state after switching tools.
    • Repeated explanation rounds: how many times you had to restate the same background before the tool understood it.
    • Memory hit rate: the share of injected entries that the tool actually referenced, used to judge retrieval precision.
    • Stale entry ratio: the share of accepted entries not updated within the agreed period, used to judge maintenance health.

    11. Phased Rollout

    1. Phase 1 (immediate payoff): create the instruction file at the project root and write down the tech stack, directory conventions, coding standards, and prohibitions as L1 constraints.
    2. Phase 2: introduce decision-record and task-file templates, standardize the handoff process, and make “every tool reads the brief first” the norm.
    3. Phase 3: add the missing write triggers (pre-commit hook, end-of-session command) and the validation script so the memory store maintains itself.
    4. Phase 4: add the retrieval index and cloud backup, and handle concurrent writes and permission governance for multi-person collaboration.

    12. Common Pitfalls

    • Using the memory store as a log: piling up a timeline without structure. Retrieval noise quickly exceeds the benefit.
    • Chasing full injection: long-term memory eats the context budget and degrades output quality instead of improving it.
    • Overwriting instead of marking as superseded: rewriting an old conclusion directly loses the information about why it changed.
    • Ignoring concurrency: two tools writing at the same time with no revision check is the most common and hardest-to-debug failure source.

    Ultimately, sharing context across tools is a transfer of context ownership: take memory out of the tool’s conversation history and give it back to the project repository and version control. Once that is done, the tool becomes a replaceable execution layer, and the project’s knowledge assets stay in your hands.