From 17ce02924754c80a9d69b3c690c5b2769f31344e Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Mon, 17 Aug 2026 23:07:09 +0200 Subject: [PATCH] fix(setup): ignore the snapshot symlink that worktree-init creates The gitignore entries adopt writes use `/.apache-magpie/` and `/.apache-magpie-sources/`. A `dir/`-style pattern matches only directories, and only the main checkout has directories there -- worktree-init deliberately replaces both with symlinks to the main checkout's copies so every worktree shares one framework state and picks up `/magpie-setup upgrade` automatically. The result is that both entries show as untracked in every worktree of every adopter. That is `git status` noise on its own, and one careless `git add -A` away from committing a symlink whose target is a machine-local absolute path. Dropping the trailing slash matches the directory, its contents, and the symlink alike, so the main checkout is unaffected. verify's check 4 is updated to expect the unslashed form and to say that a legacy `/.apache-magpie/` entry is a finding -- it passes in the main checkout and fails in every worktree, so it has to be checked from a worktree to be seen at all. Found while adopting the framework in apache/airflow, where the adopter-side entry is fixed separately. --- docs/setup/install-recipes.md | 6 ++++-- skills/setup/adopt.md | 15 +++++++++++++-- skills/setup/verify.md | 12 +++++++++--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/docs/setup/install-recipes.md b/docs/setup/install-recipes.md index d3e225b9..563e36f3 100644 --- a/docs/setup/install-recipes.md +++ b/docs/setup/install-recipes.md @@ -109,8 +109,10 @@ ln -sf ../../.agents/skills/magpie-setup .github/skills/magpie-setup cat >> .gitignore <<'GITIGNORE' # Magpie — gitignored snapshot of the framework, refreshed -# by /magpie-setup upgrade. Build artefact, not source. -/.apache-magpie/ +# by /magpie-setup upgrade. Build artefact, not source. No trailing +# slash: worktree-init makes this a symlink to the main checkout's +# snapshot, and a directory-only pattern would not match it. +/.apache-magpie # Per-machine local-pin file. Records what THIS machine fetched and # when. Compared against the committed .apache-magpie.lock to diff --git a/skills/setup/adopt.md b/skills/setup/adopt.md index 2da7a534..62c3e22f 100644 --- a/skills/setup/adopt.md +++ b/skills/setup/adopt.md @@ -580,10 +580,10 @@ idempotent — re-add them if they're missing. **Base entries — always needed**: ```text -/.apache-magpie/ +/.apache-magpie /.apache-magpie.local.lock /.apache-magpie-local/ -/.apache-magpie-sources/ +/.apache-magpie-sources /.apache-magpie.sources.local.lock /.claude/settings.local.json /.claude/hooks/agent-guard.py @@ -592,6 +592,17 @@ __pycache__/ *.pyc ``` +`/.apache-magpie` and `/.apache-magpie-sources` carry **no trailing +slash** on purpose. In the main checkout both are directories, but +[`worktree-init`](worktree-init.md#step-1--create-the-snapshot-symlink) +replaces each with a **symlink** to the main checkout's copy so every +worktree shares one framework state. A `dir/`-style pattern matches +only directories, so a trailing slash would leave both entries +untracked-but-not-ignored in every worktree — `git status` noise, and +one `git add -A` away from committing a machine-local absolute-path +symlink. Without the slash the pattern matches the directory, its +contents, and the symlink alike, so the main checkout is unaffected. + The `/.apache-magpie-sources/` and `/.apache-magpie.sources.local.lock` lines keep the gitignored fetch of every [trusted external skill diff --git a/skills/setup/verify.md b/skills/setup/verify.md index 49e12b37..dea9d6f5 100644 --- a/skills/setup/verify.md +++ b/skills/setup/verify.md @@ -150,7 +150,9 @@ Check that the entries from [`adopt.md` Step 7](adopt.md) are present in `/.gitignore`. Required: -- `/.apache-magpie/` (snapshot path) +- `/.apache-magpie` (snapshot path — **no trailing slash**, so the + pattern also matches the symlink `worktree-init` puts there; a + `/.apache-magpie/` entry is a finding, not a pass) - `/.apache-magpie.local.lock` (per-machine state) - `/.claude/settings.local.json` (per-machine project-scope settings — written to by @@ -177,8 +179,12 @@ variation): `.goose/skills/`, …) — the same two-line block keyed on its own dir. -- ✗ if `/.apache-magpie/` is not gitignored — the snapshot - is at risk of being accidentally committed. +- ✗ if `/.apache-magpie` is not gitignored — the snapshot + is at risk of being accidentally committed. Check this from a + **worktree** as well as the main checkout: a legacy + `/.apache-magpie/` entry passes in the main checkout (directory) + and fails in every worktree (symlink). Remediation is dropping the + trailing slash, not adding a second entry. - ✗ if `/.apache-magpie.local.lock` is not gitignored — per-machine state would leak into the repo. - ✗ if `/.claude/settings.local.json` is not gitignored —