Skip to content

mem workspace

Valerio edited this page Oct 16, 2026 · 1 revision

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

Why it exists

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.

How it works

The layout

<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.

The rules it keeps

  1. One repository, one top-level folder. None is nested inside another, and the workspace root is not a repository.
  2. 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.
  3. Each public repository is usable alone. A clone of it is complete.
  4. Privacy comes from the remote. The knowledge base is tracked in the private repository. A .gitignore entry in a public repository is at most a second layer.
  5. 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.

What the agent does while it is active

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.

Installing and first setup

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.

Carrying history across repositories

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.

Pointing the agent at the knowledge base

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.

IDE adapters

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.

Commands

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.

Configuration

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.

Safety and permissions

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 CHECK finding 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, CHECK stops and proposes INIT.

Where its files and data live

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/.

Limits and known issues

  • 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 CHECK always 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 INIT after renaming or moving a repository.
  • A public .gitignore entry 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.

See also

Clone this wiki locally