From d4d14b4161f97fb1b429ed26a9c36c464895e7f3 Mon Sep 17 00:00:00 2001 From: Michal Landsman Date: Thu, 13 Aug 2026 16:32:56 +0200 Subject: [PATCH] llm instructions: where the repos live, so finding one is not a search Asked to update landsman/config, the agent ran a `find` over $HOME instead of opening ~/projects/landsman/config. The layout was never written down anywhere, so it was guesswork by design. Two things worth banning, and the sweep is both of them at once. It matches worktrees under .claude/worktrees and /private/tmp by name, so it can return a detached copy of a repo and the edits land somewhere nothing will push. And it prints every client folder in ~/projects into the transcript, which nothing outside ~/projects/landsman may carry into a public repo in the first place. --- shared/.claude/CLAUDE.md | 1 + shared/.claude/rules/where-repos-live.md | 43 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 shared/.claude/rules/where-repos-live.md diff --git a/shared/.claude/CLAUDE.md b/shared/.claude/CLAUDE.md index f464838..1176ff0 100644 --- a/shared/.claude/CLAUDE.md +++ b/shared/.claude/CLAUDE.md @@ -8,6 +8,7 @@ fall back to, so they have to be in context before the mistake, not after. | Rule | Applies when | |------|--------------| +| [Where the repos live](rules/where-repos-live.md) | finding a repo on disk, and which ones may be named in public | | [Reporting data and metrics](rules/reporting-data.md) | a number gets reported — a query, a benchmark, a count | | [Localisation](rules/localisation.md) | user-facing text gets written — a label, an error, an email | | [Attribution](rules/attribution.md) | anything leaves the machine or gets committed | diff --git a/shared/.claude/rules/where-repos-live.md b/shared/.claude/rules/where-repos-live.md new file mode 100644 index 0000000..397c196 --- /dev/null +++ b/shared/.claude/rules/where-repos-live.md @@ -0,0 +1,43 @@ +# Where the repos live + +Every checkout on every machine sits under `~/projects/`. That is +`/Users/landsman/projects` on macOS and `/home/landsman/projects` on Kubuntu — +`~` covers both, and nothing outside it is a repo. + +The level below is the owner, not the forge, so `landsman/config` is + + ~/projects/landsman/config + +A client with more than one product gets one level more. `github/` and +`codeberg/` are filed differently on purpose: they hold other people's repos, +cloned to read, sorted by forge because there is no relationship to sort them +under. + +A name like `landsman/config` is therefore already most of a path. Resolve it +with `ls`; if the guess misses, `ls ~/projects` lists every owner in one screen. + +## Only `~/projects/landsman/*` may be named + +The rest of that folder is client and employer work, and my own repos are +public. No other owner folder, repo name, product, domain or client name goes +into anything that leaves the machine — a commit message, a PR title or body, an +issue, a code comment, a doc, a screenshot — in this repo or any other. + +There is always a version that carries the same information without the name: *a +work Go repo*, *a monorepo several agents were working in*, *a client's backend*. +What makes the note worth writing is the shape of the problem, never whose it +is. If only the real path would make the point, drop the point. + +This is not the same rule as pasting a secret. A repo name leaks who I work for +and what they are building, which is theirs to disclose and not mine. + +## Do not sweep `$HOME` with `find` + +It is slow, it walks `Library/`, caches and every `node_modules`, and it answers +wrong: git worktrees live under `.claude/worktrees/` and in `/private/tmp`, so a +search matching on directory name reaches a detached copy of a repo before the +real checkout — and editing a stale worktree that looks right is worse than not +finding it at all. + +It also prints every client folder in `~/projects` into the transcript, which is +what the section above is about. Read the path, do not hunt for it.