Repository navigation
mem workspace
mem-workspace lets you keep your MEM knowledge base in a private repository that sits beside your public one, instead of inside it, and teaches the agent to work correctly across the two. It adds a status command that covers every repository at once, a check that nothing private has reached a public repository, and an init command that records which folder is which. It runs only read-only, local git commands and never touches the network.
| Version | 1.0.0 |
| Commands |
MEM WORKSPACE, MEM WORKSPACE CHECK, MEM WORKSPACE INIT
|
| Executable content | No |
| External actions | No. It runs a closed list of read-only local git commands, nothing else |
| Requirements |
git, and a project with public content plus private development material. You create the repositories yourself |
A knowledge base is working memory: decisions, daily logs, half-finished plans, review notes. In a public repository you usually do not want any of that published. The obvious fix, a .gitignore line, is a poor one: the knowledge base then lives in no repository at all, with no history and no backup, and it is one git add -f away from a public push.
mem-workspace describes the alternative. The knowledge base lives in a private repository, next to the public one, both inside a plain workspace folder that is not itself a repository. An optional wiki repository can sit beside them. Privacy then comes from the remote, not from an ignore rule, and the knowledge base gets history and backup like any other repository.
Splitting one project across several repositories introduces its own mistakes: writing a file into the wrong repository, linking from public documentation into the private one, forgetting to commit half of a change. The extension exists to make the agent aware of those, and to check for them.
If your whole project is private, you do not need it: keep the knowledge base inside the repository and do not install this extension.
<workspace root>/ a plain folder, NOT a repository
public/ <owner>/<project> public the product
private/ <owner>/<project>.Dev private contains the knowledge base
wiki/ <owner>/<project>.wiki public optional
These folder names are defaults and may differ; the workspace file records the real ones. Names that state the visibility are preferred, because visibility is where the one irreversible mistake lives. "Workspace" here means a folder holding several repositories side by side, not an npm, pnpm or Cargo workspace.
- One repository, one top-level folder. None is nested inside another, and the workspace root is not a repository.
- Dependency runs one way. The private repository may reference the public ones. A public repository must never reference the private one: no path, no link, no project or build reference, no CI step, and no mention in a commit message.
- Each public repository is usable alone. A clone of it is complete.
-
Privacy comes from the remote. The knowledge base is tracked in the private repository. A
.gitignoreentry in a public repository is at most a second layer. - Commits are not atomic across repositories. One piece of work may land as several commits on several remotes, and nothing forces all of them to be made.
These behaviours apply without any command.
It knows where each file goes. Before writing a file, the agent must know which repository it is writing into; "the repository root" is ambiguous in a workspace, so it names the folder.
| Material | Repository |
|---|---|
| The product, its README, changelog, licence, upgrade notes | public |
| Contributor- and operator-facing documentation | wiki, or public when there is no wiki |
| The knowledge base, dev notes, draft plans, review notes, scratch planning | private |
| The all-inclusive dev solution or editor workspace | private |
| Secrets | none of them |
Material written to help you or the agent work goes to the private repository, and when in doubt the answer is private, since two of the three repositories are public by default. When a public document needs some information from the private side, the agent restates it there rather than linking to it. Agent temporary files go at the workspace root.
It moves files so history follows. Git records no moves; it reconstructs a rename from content similarity. Inside one repository the agent moves tracked files with git mv and commits the move on its own, before editing the moved content, so the file does not read as deleted and re-created. Across repositories git mv cannot work; when history matters, the setup guide explains how to carry it over. A move also changes every inbound link, so the agent searches for the old path in every repository of the workspace.
It tells you what is left before calling a change done. It lists, per repository and in push order, what remains to commit or push. The half most often forgotten is the daily log in the private repository, because it is written last.
It commits and pushes only when asked. When you ask, it proposes one commit per repository and pushes in the recorded order, by default public, then wiki, then private: the knowledge base describes the product, so publishing it first would reference commits that do not exist yet. Every commit is made as you, with your configured identity, in every repository.
Where to start it. Start the agent from the workspace root or from the private repository. An agent started inside a public repository alone cannot see the knowledge base, and the public repository must not tell it where to look.
mem-workspace is listed in the MEM extension manifest. Like any extension, it installs only after you confirm a request naming the files and the source URL, and it is loaded only once registered as active in your project's extensions/EXT.md. Its bootstrap entry is the workspace file, custom/workspace.md, written at installation by the same procedure as MEM WORKSPACE INIT, because every rule above needs to know which folder is which before the first file is written.
Setting up the repositories themselves is your job. In every scenario below the agent proposes each step and performs none that creates a repository, changes a remote, or reaches the network. Finish every scenario with MEM WORKSPACE INIT, then MEM WORKSPACE CHECK.
A. A new project. Create the workspace folder (without git init), create the public and private repositories on your hosting service, and clone each into its own folder by name (git clone <url> public, and so on). For a GitHub wiki, create its first page in the web UI once: an uninitialised wiki has no repository to clone. Add a .gitignore to the private repository before its first commit, install MEM there, and add the private folder name and the dev solution or workspace file name to each public .gitignore as a safety net. Do not ignore the wiki folder.
B. A knowledge base already committed to a public repository. The common case. Stop publishing it first: until its removal is pushed, every push publishes the latest knowledge base. Move the existing clone into <root>/public/, clone the private repository beside it, and bring the knowledge base across, with its history when that matters. Verify the private copy is complete and committed, then git rm -r the folder in the public repository, add the safety-net ignore entries, and commit that removal on its own with a message that does not name the private repository. Finally update every pointer to the old path.
This does not erase the past. The knowledge base is still in the public repository's history and in every clone and fork made before the removal; CHECK reports it. Rewriting public history is destructive, breaks existing clones, and removes nothing from copies already taken, so that decision is yours alone. If the knowledge base ever held a secret, treat the secret as disclosed and rotate it.
C. A knowledge base ignored inside a public repository. Follow B, with a plain copy, since there is no history to carry. Before removing anything, confirm with git log --all -- <kb-folder> in the public repository that it was never committed; if it was, B's warning applies.
History cannot be moved, but it can be rewritten into new commits and merged into the receiving repository. The preferred tool is git filter-repo (maintained outside git), run on a fresh scratch clone, never the working one: it rewrites the paths, so git log --follow on the new location reaches back before the move. The fallback is git subtree, which needs git alone but keeps commits under their old paths behind a merge commit, so a path-based log stops at that merge. Neither changes the public repository's history. The spec's setup guide has the exact command sequences.
If you start the agent somewhere it cannot see the knowledge base, give it a one-paragraph pointer (where MEM.md is, and that mem-workspace is active) in one of two places: a file at the workspace root that your assistant reads (AGENTS.md, CLAUDE.md...), which is never published because the root is in no repository, but also not versioned, so you recreate it per machine; or your own assistant instructions. Starting the agent from the workspace root or the private repository makes the pointer unnecessary.
Two optional recipes let you see and commit every repository from one window. Both files live in the private repository, because they name the private folder.
| Adapter | How |
|---|---|
| Visual Studio | Two solutions: a public one with the product only (what CI builds and contributors open), and a private dev solution that includes everything by relative path. Visual Studio only lets you commit a repository when the open solution contains a project inside it, so repositories with nothing to compile, such as the knowledge base or a wiki, get a small "container" project that holds Markdown files and compiles nothing |
| VS Code | A multi-root .code-workspace file in the private repository listing the private, public and wiki folders. Each folder shows up separately in Source Control. List the private folder first, so an agent rooted at the first folder keeps the knowledge base in view |
When the workspace file names an adapter, CHECK adds its checks: for example, that every path in the dev solution or workspace file still resolves, and that no public build file reaches into the private folder.
| Command | What it does |
|---|---|
MEM WORKSPACE |
Read-only status of every repository: role, folder, branch, upstream, ahead/behind, changed files. Ends with the commits and pushes left, in push order. Ahead/behind is as of your last fetch, and the report says so; a missing folder is reported, not skipped |
MEM WORKSPACE CHECK |
Read-only verification of the layout and of privacy. Reports each finding as error, warning or info, with a verdict of PASS, PASS WITH WARNINGS or FAIL. Run it before pushing a public repository and after any setup or migration |
MEM WORKSPACE INIT |
Detects the repositories around the knowledge base, proposes a role for each, and writes custom/workspace.md after you confirm. Lists the setup steps still missing and performs none of them. Not the core MEM INIT. Run it again when a repository is added, renamed or moved |
What CHECK looks at, in short:
| Area | Checks |
|---|---|
| Layout | the workspace root is not a repository; each role folder is a repository top level; none is nested in another; remotes match the record |
| Knowledge base placement | the knowledge base is tracked in the private repository (an error if it resolves to a public one); no knowledge base file is tracked in, or about to be added to, a public repository |
| Leaks | no public file contains a string that resolves to the private repository (its owner/repo, a ../private/ path, the knowledge base path, or your extra patterns) |
| History | no knowledge base file appears in a public repository's history (a warning: it is still public in every existing clone) |
| Safety nets | the private folder is ignored in each public repository; the wiki folder is not; public files do not link to wiki pages by relative path, which is already broken on the public site |
| Visibility | always reported as info: repository visibility cannot be verified offline |
| Adapter | the checks of the adapter named in the workspace file |
CHECK does not search for the bare word "private", which would bury real findings in noise. It reports and stops: it never fixes a finding, edits an ignore file or moves a file.
There are no extensions_<id>_* options. Configuration is the workspace file, custom/workspace.md, created from WORKSPACE.template.md or by MEM WORKSPACE INIT:
| Section | Contents | Default |
|---|---|---|
| Roles | one row per repository: role, folder, remote, visibility, branch. Exactly one private, at least one public, at most one wiki
|
public, private, wiki folders; visibility marked "recorded, not verified" |
| Push order | the order in which repositories are pushed | public, wiki, private |
| Forbidden in public | extra strings CHECK treats as leaks, added to the built-in ones |
none |
| Exceptions | a path, the check it is exempt from, and a reason a reviewer can judge | none |
| Adapter |
none, visual-studio: <dev solution> or vscode: <workspace file>
|
none |
The file holds relative paths only, so it is true on every machine; the workspace root is never stored, it is derived as the parent of the private repository. A GitHub wiki's branch is master and cannot be renamed, so do not "fix" it.
Precedence is base wins: your workspace file can add forbidden patterns and declare narrow exceptions, but it cannot switch a check off. Every exception in effect is listed in every CHECK report, so a loosened rule is never silent.
The extension declares no executable content, so extensions_allow_executable_content does not apply to it, and no external actions. The only process it starts is git, read-only and local, from a closed list: rev-parse, status, remote get-url, ls-files, grep, log, check-ignore. No fetch, no network, no write. Registering the extension approves that list, and the agent discloses when it runs one.
Its only write is custom/workspace.md, made by INIT after you confirm. An existing file is shown as a diff and never overwritten unasked.
What it never does:
- commit or push unless you ask, or commit as anyone but you;
- create a repository, change a remote, or reach the network;
- write into a public repository a path, link or name that resolves to the private one, including in commit messages;
- fix a
CHECKfinding on its own: it proposes, you decide; - propose a history rewrite or a force-push. For knowledge base files found in public history it states the fact; whether to rewrite history is your decision;
- guess roles: if the workspace file is missing,
CHECKstops and proposesINIT.
| What | Where |
|---|---|
The extension and its workspace file (custom/workspace.md) |
inside the knowledge base, in the private repository |
IDE dev solution or .code-workspace file |
the private repository |
| Container projects for the Visual Studio adapter | at the root of the repository they make committable (for a wiki, visible to anyone who clones it, though it never becomes a page) |
| Agent pointer file, if you use one | the workspace root: in no repository, never published, not versioned |
| Agent temporary files | the workspace root |
Updates write only the base files listed in the manifest, so the workspace file survives every update. custom/index.md appears only if you add more files under custom/.
- Cross-repository commits are not atomic. The extension reminds you what is pending in each repository; it cannot make them land together.
-
Visibility is recorded, never verified. Whether a remote is really public or private cannot be checked offline, so
CHECKalways flags it as unverified. - Ahead/behind is only as fresh as your last fetch, because the extension never fetches.
- Removing the knowledge base from a public tree does not remove it from history, or from existing clones and forks. Rotating any secret it held is the only fix that works.
-
Folder names and adjacency matter for the IDE adapters, which reference siblings by relative path. Re-run
INITafter renaming or moving a repository. -
A public
.gitignoreentry is only a safety net. It guards against a private folder being copied into a public repository; it is not what keeps the knowledge base private. - An agent started inside a public repository alone cannot see the knowledge base.
- Specification: src/extensions/mem-workspace/index.md
- Extensions
Extensions
- mem-commands
- mem-toolbox
- mem-workspace
- mem-stats
- mem-optimize
- mem-cleaner (in development)