Memory backup

April 22, 2026 · View on GitHub

Mirror of VS Code Copilot Chat memory for this workspace.

Layout:

notes/memory/
├── README.md           ← this file
├── repo/               ← live backup of repo-scoped memory (synced)
│   └── <your-files>.md
└── examples/           ← templates / starting points (NOT synced — docs only)
    ├── repo/
    │   ├── example-tenant-context.md
    │   └── example-investigation-patterns.md
    └── user/
        └── example-tenant-context-check.md
  • Source of truth for repo/: %APPDATA%\Code\User\workspaceStorage\<hash>\GitHub.copilot-chat\memory-tool\memories\repo\
  • Backed up here so: it survives VS Code reset / reinstall / workspace rename. Because the backup lives inside the workspace folder, any cloud sync you've attached to that folder (OneDrive, Dropbox, iCloud, Google Drive, etc.) will mirror it automatically.
  • Gitignored via notes/ in .gitignore — contains internal context (tenant IDs, personnel names, IPs).
  • examples/ is docs only. The sync script only mirrors repo/. Examples are templates you copy and adapt — they never enter live memory unless you explicitly create them via the memory tool in chat.
  • Future tiers: if you ever want to also back up user or session memory, add notes/memory/user/ or notes/memory/session/ and extend the script.

Sync

# After updating memory in chat (push AppData -> workspace backup) - DEFAULT, safe
.\scripts\sync-repo-memory.ps1

# Restore from backup on a fresh machine (writes into Copilot's memory)
.\scripts\sync-repo-memory.ps1 -Direction FromBackup -Force

# Preview only (any direction)
.\scripts\sync-repo-memory.ps1 -WhatIf
.\scripts\sync-repo-memory.ps1 -Direction FromBackup -WhatIf

Default direction is ToBackup (one-way export). FromBackup and Both require -Force because they write into Copilot's trusted memory store.


⚠️ Security: memory is trusted input

Repo memory files are loaded into Copilot Chat as authoritative instructions with full access to MCP tools (Sentinel, Graph, Azure). Treat notes/memory/repo/ the same as code:

RiskMitigation
Pulling memory from a fork / PR / shared driveReview every diff before running -Direction FromBackup
Tampered backup on disk overwriting AppDataFromBackup requires -Force and is never the default
Sensitive content (tenant IDs, IPs, FP patterns) leaking via gitnotes/memory/repo/ is gitignored; only notes/memory/README.md and notes/memory/examples/ are tracked
Secrets accidentally pasted into a memory fileAudit notes/memory/repo/ periodically; never paste tokens / passwords. If the workspace folder is cloud-synced, the backup propagates wherever that sync goes
Examples copied verbatim with real valuesTemplates in examples/ use placeholders only; replace before committing your own

Cloud-sync caveat: if the workspace folder is mirrored by a cloud sync service (OneDrive, Dropbox, iCloud, Google Drive, etc.), notes/memory/repo/ rides along automatically. That's a convenient cross-machine backup, but it also means the contents leave your local machine. If your sync target is shared, cross-tenant, or governed by DLP that prohibits storing security context, evaluate before adopting this workflow. For local-only backup, move the workspace outside any synced folder or override $BackupRoot in the sync script.


Important: Make Copilot actually USE the memory

Repo memory files are NOT auto-loaded into Copilot's context — only their filenames are visible at the start of a chat. Copilot has to decide to read a file based on what it sees in the conversation.

User memory (/memories/*.md, NOT /memories/repo/) IS auto-loaded (first ~200 lines). So the way to make Copilot proactively pull a repo memory file is to add a short trigger rule to user memory pointing at it.

Templates

Copy and adapt these — do NOT use them verbatim:

TemplateGoes intoPurpose
examples/repo/example-tenant-context.md/memories/repo/<your-tenant>.mdStores the rich tenant facts (IPs, personnel, FP patterns)
examples/repo/example-investigation-patterns.md/memories/repo/investigation-patterns.mdReusable investigation playbooks for your tenant
examples/user/example-tenant-context-check.md/memories/<your-tenant>-context-check.mdThe trigger rule that makes Copilot actually read the repo file above

The first two go into repo memory (this workspace only, synced via the script). The third goes into user memory (auto-loads in every chat across every workspace).

Why this matters

Without trigger ruleWith trigger rule
Copilot sees <tenant>.md filename, may or may not read itCopilot loads context-check rule every chat → reliably reads the right repo memory file when tenant signals appear
Risk: confident wrong verdicts on documented FP patternsReliably suppresses known FPs across all investigations
Memory file is "available but unused"Memory file is "actively consulted"

How to create memory files

From scratch (first-time setup)

In a Copilot chat:

""Open notes/memory/examples/user/example-tenant-context-check.md, replace the placeholders with my real values (tenant id <...>, domain @<...>, repo file <...>.md), and create the result as a user memory file at /memories/<your-tenant>-context-check.md."

Copilot will use its memory tool to create the file. Repeat for the repo-tier templates, but create those at /memories/repo/... instead.

Fresh machine after restoring from backup

User memory is global, not workspace-scoped, so the sync script does not restore it. After running FromBackup -Force on a new machine, your repo memory is back in AppData but the user-memory trigger that makes Copilot actually read it is missing. To rebuild it in one step:

"Read every file in /memories/repo/, then for each one create a short trigger rule in user memory at /memories/<filename>-context-check.md that tells you to open and read the matching repo memory file before writing any risk assessment. Use notes/memory/examples/user/example-tenant-context-check.md as the structural template. Trigger signals MUST be limited to stable identifiers only: tenant IDs, Sentinel workspace IDs, and domain suffixes (UPN suffixes / email domains). Do NOT include IP addresses, account names, validated personnel UPNs, infrastructure CIDR ranges, or any other volatile/enumerable details — those belong in the repo file, not the trigger. Keep each trigger under 15 lines."

Copilot reads the repo files (which it now has access to in this workspace), extracts only the stable identifiers from each, and writes one short trigger file per repo file. After that, every new chat in any workspace auto-loads the triggers and Copilot reliably consults the repo memory when those signals appear.

Why the constraint: trigger files share a ~200-line auto-load budget across every workspace and every chat. A 30-line trigger packed with IPs and account lists eats budget that other triggers (other tenants, other workspaces) need. Stable identifiers (tenant GUID, workspace GUID, domain suffix) almost never change, are highly distinctive, and are enough to make Copilot pull the repo file — which is the actual source of truth for the volatile facts.