feat: .shared-memory-project file convention for repo-rooted project ID

Replaces "per-machine X-Project-Key header" as the default way to tell
Claude Code which shared-memory project a repo belongs to. Commit a
single-line `.shared-memory-project` text file at the repo root; every
collaborator's Claude Code reads it at session start and attaches all
memories + snippets to the same shared project. No per-machine config
required.

Changes:
- New file convention documented in README (resolution order, format,
  authoring snippet, rationale for plain-text over JSON).
- project.identify tool description now leads with "check
  .shared-memory-project at the repo root", with inference as fallback.
- memory.write description mentions the file as the canonical source for
  project keys.
- Project detail page in the Web UI shows a copy-paste `echo > file`
  command so users see exactly what to add to their repo.
- Added .shared-memory-project to this repo (content: `shared-memory`).

Resolution precedence is: explicit tool arg → .shared-memory-project →
X-Project-Key header → inference. The file beats the header because
repo context is more specific than machine context.

This is a soft convention — Claude has to read the file. Directive tool
descriptions make this very likely; a Claude Code skill would make it
bulletproof, deferred until we see whether the description alone is
enough.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-18 09:17:04 -07:00
co-authored by Claude Opus 4.7
parent 837c43f3d5
commit b6e28b329d
4 changed files with 65 additions and 3 deletions
+41
View File
@@ -302,6 +302,47 @@ to `/plugin install shared-memory`. Other IdPs that already support DCR
---
## Identifying the current project (`.shared-memory-project`)
When Claude Code calls memory.write / memory.search / etc., the server needs
to know *which* project the call belongs to. Resolution order, first match
wins:
1. **Explicit `project` argument** on the tool call.
2. **`.shared-memory-project` file** at the repo root — a single line of
plain text containing the project key. Claude is instructed to read this
first when a project context is present, before inferring or asking. This
is the recommended path for any repo: commit the file, and every
collaborator's Claude Code automatically attaches memories to the same
shared project.
3. **`X-Project-Key` request header** — per-MCP-registration default, set at
`claude mcp add` time with `--header "X-Project-Key: foo"`. Useful when a
machine works in one project across many repos.
4. **Inference** — repo name / git remote slug / working-directory basename,
as a last resort.
### Adding `.shared-memory-project` to your repo
```bash
echo "your-project-key" > .shared-memory-project
git add .shared-memory-project
git commit -m "chore: declare shared-memory project key"
```
The key must match the regex `^[a-zA-Z0-9._\-/]+$` (same constraint as the
`ProjectKey` Zod schema — alphanumerics plus `.`, `_`, `-`, `/`). Pick
something stable; renaming later is fine but breaks the implicit link with
any pre-existing memories you wrote against the old key.
### Why a flat-text file, not JSON
Matches the family of `.python-version`, `.nvmrc`, `.tool-versions` — easy
to grep, easy to author by hand, easy to read from any client without a
parser. If we ever need richer metadata (display name, default tags, etc.)
we'd graduate to a structured format, but the single-key case is the 95%.
---
## HAProxy example
If you run HAProxy at the edge (TLS terminator + reverse proxy), a minimal