You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@magpie.apache.org by po...@apache.org on 2026/09/14 12:37:04 UTC

(magpie) branch docs/post-checkout-hook-scope created (now 899546db)

This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a change to branch docs/post-checkout-hook-scope
in repository https://gitbox.apache.org/repos/asf/magpie.git


      at 899546db docs(setup): the post-checkout hook stopped delivering skills; say so

This branch includes the following new commits:

     new 899546db docs(setup): the post-checkout hook stopped delivering skills; say so

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(magpie) 01/01: docs(setup): the post-checkout hook stopped delivering skills; say so

Posted by po...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch docs/post-checkout-hook-scope
in repository https://gitbox.apache.org/repos/asf/magpie.git

commit 899546db928a3ea79e9889b0cf810b9eb7f2ed9c
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Mon Sep 14 14:36:20 2026 +0200

    docs(setup): the post-checkout hook stopped delivering skills; say so
    
    The repo-local post-checkout hook once re-created gitignored
    runtime state and seeded a per-worktree agent-guard copy. Both
    jobs are gone — the template is now one guarded call to
    sandbox-add-project-root.sh — but nine places still described the
    old behaviour, and the marketplace path (which writes no hook at
    all) was never folded into any of them.
    
    The hook no longer delivers framework skills:
    
    - setup/SKILL.md: the failure-mode row named the wrong sub-action
      (adopt installs no hook) and the wrong mechanism (it re-runs no
      snapshot install). Rewritten, plus a second row for the
      sandbox-allowlist symptom, which is the one that survives on
      the marketplace path.
    - setup/install.md: the adopter-facing doc template, so the stale
      claim was propagating into other projects' docs.
    - setup/verify.md: said --auto-fix-symlinks is called by the hook,
      contradicting check 8 in the same file, which rejects a hook
      carrying that line.
    - setup/upgrade.md: "the post-checkout hook covers the next
      checkout case" in the symlink-refresh context. It does not,
      which strengthens the case for Step 6c.
    - other-install-methods.md: manual recipe step 5.
    
    A hook the marketplace path never writes:
    
    - secure-agent-setup.md lifecycle item 4 and the per-project scope
      row, and isolated-setup-install Step P, all asserted the hook
      exists. They now name the snapshot-install-only condition and
      say what to do with neither hook present (worktree-init). Item 4
      is restructured rather than patched — its closing sentence
      promised automatic inheritance.
    
    Same staleness in one field:
    
    - collect_status.py's has_verify_recipe tested for a line the
      current template deliberately omits, so it read False on a
      correct hook and True on a stale one. Replaced with
      has_sandbox_helper + has_stale_verify_line; collect.md's schema
      row follows. Nothing consumed the old key.
    
    Co-Authored-By: Claude Opus 5 (1M context) <no...@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01VAJ5GbXnv4LWMfDdvDNJKE
---
 docs/quick-start/other-install-methods.md          |  6 ++++--
 docs/setup/secure-agent-setup.md                   | 22 ++++++++++++++--------
 .../skills/isolated-setup-install/SKILL.md         | 12 ++++++++----
 plugins/magpie-setup/skills/setup/SKILL.md         |  3 ++-
 plugins/magpie-setup/skills/setup/install.md       |  9 ++++++---
 plugins/magpie-setup/skills/setup/upgrade.md       |  7 ++++---
 plugins/magpie-setup/skills/setup/verify.md        | 12 +++++++-----
 plugins/magpie-setup/skills/status/collect.md      |  2 +-
 .../skills/status/scripts/collect_status.py        |  7 ++++++-
 9 files changed, 52 insertions(+), 28 deletions(-)

diff --git a/docs/quick-start/other-install-methods.md b/docs/quick-start/other-install-methods.md
index 5d11efcf..928833df 100644
--- a/docs/quick-start/other-install-methods.md
+++ b/docs/quick-start/other-install-methods.md
@@ -284,8 +284,10 @@ the rest:
    (gitignored — they target the gitignored snapshot).
 4. **Scaffold `.apache-magpie-overrides/`** (committed) for
    any local workflow modifications.
-5. **Install a `post-checkout` git hook** so worktrees
-   re-create the gitignored runtime state.
+5. **Install a `post-checkout` git hook** so each new
+   worktree adds itself to the sandbox allowlist. It does
+   *not* re-create the gitignored runtime state — a new
+   worktree gets that from `/magpie-setup worktree-init`.
 6. **Update your project documentation** with a brief mention
    of the framework adoption.
 
diff --git a/docs/setup/secure-agent-setup.md b/docs/setup/secure-agent-setup.md
index f7ea827b..4e8e66ac 100644
--- a/docs/setup/secure-agent-setup.md
+++ b/docs/setup/secure-agent-setup.md
@@ -853,13 +853,19 @@ The helper is invoked from four points in the framework's lifecycle:
    the per-worktree `worktree-init` chain, runs the helper with
    `--all-worktrees` so any worktree added since adopt has its
    path written into its own settings.local.json.
-4. **Per worktree, on creation** — the `post-checkout` git hook
-   installed by `/magpie-setup install` runs the helper *without*
-   `--all-worktrees`, picking up only the new worktree's path.
-   `git worktree add` fires `post-checkout` in the new working
-   tree, so every worktree added after adoption inherits sandbox
-   access automatically — landing its abs path in its own
-   `.claude/settings.local.json`.
+4. **Per worktree, on creation — where a `post-checkout` hook
+   exists.** `git worktree add` fires `post-checkout` in the new
+   working tree; the hook runs the helper *without*
+   `--all-worktrees`, so the new worktree lands its own abs path
+   in its own `.claude/settings.local.json` with no operator
+   action.
+
+   Two things install such a hook, and a host may have **neither**:
+   `/magpie-setup install` writes a repo-local one **on the pinned
+   snapshot install only** — the marketplace path writes no hook —
+   and whole-user scope installs a global one covering every repo.
+   With neither, this point does not fire, and a new worktree needs
+   `/magpie-setup worktree-init` to get its path written.
 
 The verification surface:
 
@@ -890,7 +896,7 @@ the other scope.
 
 | Scope | What it covers | Mechanism | Reversal |
 |---|---|---|---|
-| **Per-project** | The single adopter repo the operator is sitting in when running the install skill. Each subsequent adopter project needs the install skill re-run there. | The helper runs once with `--all-worktrees` against the current repo; nothing global is touched. The per-repo `post-checkout` hook (installed by `/magpie-setup install` in Magpie-adopted repos) chains into the helper on future `git checkout` operations within that repo. | None needed — per-project scope is inert out [...]
+| **Per-project** | The single adopter repo the operator is sitting in when running the install skill. Each subsequent adopter project needs the install skill re-run there. | The helper runs once with `--all-worktrees` against the current repo; nothing global is touched. The per-repo `post-checkout` hook chains into the helper on future `git checkout` operations within that repo — but `/magpie-setup install` writes that hook **only on the pinned snapshot install**, so under a marketplace [...]
 | **Whole-user (global)** (recommended default when not yet set up) | Every git repo on the operator's host, existing and future. Includes non-Magpie Claude-Code-aware projects (any project with a `.claude/` directory). | Walks the operator's existing checkouts under prompted root dirs and writes each one's `settings.local.json`; sets `git config --global core.hooksPath ~/.claude/git-hooks/` and installs the universal [`git-global-post-checkout.sh`](../../tools/agent-isolation/git-global [...]
 
 #### Important trade-off — `core.hooksPath` shadows per-repo hooks
diff --git a/plugins/magpie-setup/skills/isolated-setup-install/SKILL.md b/plugins/magpie-setup/skills/isolated-setup-install/SKILL.md
index 9a56c7f4..aa066bed 100644
--- a/plugins/magpie-setup/skills/isolated-setup-install/SKILL.md
+++ b/plugins/magpie-setup/skills/isolated-setup-install/SKILL.md
@@ -545,10 +545,14 @@ have no business in a file shared across contributors).
 
 The helper is also invoked by `setup install`,
 `setup upgrade`, and `setup worktree-init` for
-the same reason. The `post-checkout` git hook installed by
-`setup install` chains into the helper too, so new
-worktrees added via `git worktree add` after this install pass
-inherit access automatically — no operator action needed.
+the same reason. The repo-local `post-checkout` git hook chains
+into the helper too, so new worktrees added via `git worktree add`
+inherit access automatically — but `setup install` writes that hook
+**only on the pinned snapshot install**; the marketplace path
+writes no hook. On a marketplace install under per-project scope,
+a new worktree therefore needs `setup worktree-init` to get its
+path written. Whole-user scope closes that gap for every repo on
+the host.
 
 ### Step V — The vetted-ops split and exclusion
 
diff --git a/plugins/magpie-setup/skills/setup/SKILL.md b/plugins/magpie-setup/skills/setup/SKILL.md
index 4ea76fa8..d2707b67 100644
--- a/plugins/magpie-setup/skills/setup/SKILL.md
+++ b/plugins/magpie-setup/skills/setup/SKILL.md
@@ -471,7 +471,8 @@ first, then continue.
 |---|---|---|
 | `setup verify` reports drift between committed and local locks | Project lead bumped `<committed-lock>` since this machine last fetched, or local snapshot is stale on a `main`-tracking adopter | `setup upgrade` |
 | Snapshot present but symlinks dangle | Adopter ran `git clone` but not `setup` after — symlinks are gitignored but persist in their target's absence on disk | `setup verify --auto-fix-symlinks` (or `setup install`, idempotent) |
-| Worktree off the adopter repo can't find framework skills | Worktrees off the adopter don't auto-inherit the gitignored snapshot | The `adopt` sub-action installs a `post-checkout` git hook that re-runs the snapshot install on worktree creation; verify the hook is present (`setup verify`) |
+| Worktree off the adopter repo can't find framework skills | Only reachable on the pinned snapshot install: the snapshot and its `magpie-*` symlinks are gitignored, so git carries neither into a new worktree. A marketplace install is user-scope and needs nothing here | `setup worktree-init` in the worktree — it links the worktree's `<snapshot-dir>` to the main checkout's and recreates the per-worktree symlinks. The `post-checkout` hook does **not** cover this; it only syncs the sandbox  [...]
+| New worktree's sandboxed session can't read its own working directory | The worktree's absolute path is missing from its own `.claude/settings.local.json`, which is gitignored — so git carries it into no worktree, whichever install path you are on | `setup worktree-init` (Step 1c). For this to happen automatically on `git worktree add`, you need either the repo-local `post-checkout` hook (installed by the snapshot install only) or whole-user scope from [`setup-isolated-setup-install`]( [...]
 | The agent offers no `/plugin` (or equivalent) command | That agent has no marketplace — the one case the pinned snapshot install exists for | `setup install method:git-branch` (or `svn-zip` for the signed release) — see [`docs/setup/install-recipes.md`](../../../../docs/quick-start/other-install-methods.md) |
 | Every Magpie skill appears twice, under both `/magpie-<skill>` and `/magpie-<family>:<skill>` | Both install paths are live on this machine — a snapshot install underneath a marketplace one | Keep one ([Golden rule 10](#golden-rules)): `setup uninstall` to drop the repo-side snapshot, or uninstall the plugins if the project needs the committed pin |
 | `git clone` of an upstream PR sees no framework skills | Expected — the snapshot is gitignored, so a fresh clone has no `<snapshot-dir>`. The clone needs `setup` once before any framework skill is invocable | `setup` |
diff --git a/plugins/magpie-setup/skills/setup/install.md b/plugins/magpie-setup/skills/setup/install.md
index 66dabf06..8d2c8217 100644
--- a/plugins/magpie-setup/skills/setup/install.md
+++ b/plugins/magpie-setup/skills/setup/install.md
@@ -1582,8 +1582,8 @@ Same hands-off contract as 9c — **surface, do not run**:
 
 Install `<repo-root>/.git/hooks/post-checkout` — a best-effort
 per-worktree reconciler that fires on `git checkout` and on
-`git worktree add`. It carries **two** responsibilities, each
-guarded independently so neither can gate the git operation:
+`git worktree add`. It carries exactly **one** responsibility,
+guarded so it cannot gate the git operation:
 
 1. **Sandbox allowlist.** Chain into the sandbox-allowlist helper
    installed by `setup-isolated-setup-install`, so the new
@@ -1705,7 +1705,10 @@ framework before they hit a "skill not found" error:
    (or follow [`.agents/skills/magpie-setup/`](.agents/skills/magpie-setup/))
    to fetch the snapshot per the committed lock, scaffold the
    gitignored symlinks, and install the post-checkout hook
-   that re-creates them on each worktree checkout.
+   that adds each new worktree to the sandbox allowlist.
+   In a worktree, run `setup worktree-init` instead — it
+   shares the main checkout's snapshot rather than fetching
+   a second one.
 
    Adopter-specific modifications to framework workflows live
    in [`.apache-magpie-overrides/`](.apache-magpie-overrides/)
diff --git a/plugins/magpie-setup/skills/setup/upgrade.md b/plugins/magpie-setup/skills/setup/upgrade.md
index c6dec7ea..1729f2c1 100644
--- a/plugins/magpie-setup/skills/setup/upgrade.md
+++ b/plugins/magpie-setup/skills/setup/upgrade.md
@@ -535,9 +535,10 @@ even when the worktree looks "already wired", because
 `worktree-init` is idempotent (a no-op when state is
 correct) and the cost of running it unnecessarily is
 trivially small. Conversely, *not* running it leaves worktree
-state inconsistent with the new framework version. The
-post-checkout hook covers the "next checkout" case, but
-upgrade re-aligns the existing worktrees **now**.
+state inconsistent with the new framework version. Nothing
+else covers it: the `post-checkout` hook only syncs the sandbox
+allowlist and never touches symlinks, so upgrade re-aligning
+the existing worktrees **now** is the only thing that does.
 
 Procedure:
 
diff --git a/plugins/magpie-setup/skills/setup/verify.md b/plugins/magpie-setup/skills/setup/verify.md
index 998305b5..a2bee881 100644
--- a/plugins/magpie-setup/skills/setup/verify.md
+++ b/plugins/magpie-setup/skills/setup/verify.md
@@ -15,11 +15,13 @@ default — surfaces gaps and remediation commands.
   snapshot is present but symlinks are missing or dangling
   in **any active target dir** ([`agents.md`](agents.md) —
   `.agents/skills/`, `.claude/skills/`, `.github/skills/`, plus
-  any present holdout), recreate them across all of them. Used
-  by the post-checkout hook
-  ([`install.md` Step 10](install.md)) on a fresh worktree
-  where the gitignored symlinks didn't follow the
-  checkout.
+  any present holdout), recreate them across all of them. For
+  a fresh worktree whose gitignored symlinks didn't follow the
+  checkout, prefer [`worktree-init`](worktree-init.md), which
+  shares the main checkout's snapshot as well as relinking. The
+  `post-checkout` hook does **not** call this — a slash command
+  is not shell-callable (check 8 below rejects a hook that
+  carries the long-removed `--auto-fix-symlinks` line).
 
 ## Pre-flight
 
diff --git a/plugins/magpie-setup/skills/status/collect.md b/plugins/magpie-setup/skills/status/collect.md
index 4a61ef29..19161360 100644
--- a/plugins/magpie-setup/skills/status/collect.md
+++ b/plugins/magpie-setup/skills/status/collect.md
@@ -37,7 +37,7 @@ python3 <framework>/skills/setup-status/scripts/collect_status.py --format json
 | `families` | The installed-skill roster grouped by family (see below). |
 | `overrides` | `{present, has_readme, skill_count}` for `.apache-magpie-overrides/` (committed, shared). |
 | `local_overrides` | `{present, has_readme, skill_count}` for `.apache-magpie-local/` (gitignored, personal). Always reported; `present: false` when the directory does not exist. |
-| `post_checkout_hook` | `{present, executable, has_verify_recipe}`. |
+| `post_checkout_hook` | `{present, executable, has_sandbox_helper, has_stale_verify_line}`. `has_stale_verify_line` true means the hook still carries the long-removed `--auto-fix-symlinks` line — remediation is `setup upgrade`. |
 | `gitignore` | Coverage flags (see below). |
 
 ## `agent_targets[]`
diff --git a/plugins/magpie-setup/skills/status/scripts/collect_status.py b/plugins/magpie-setup/skills/status/scripts/collect_status.py
index cd395c2a..6b87c6fe 100644
--- a/plugins/magpie-setup/skills/status/scripts/collect_status.py
+++ b/plugins/magpie-setup/skills/status/scripts/collect_status.py
@@ -379,7 +379,12 @@ def hook_status(root: Path) -> dict:
     return {
         "present": True,
         "executable": os.access(hook, os.X_OK),
-        "has_verify_recipe": "magpie-setup verify" in content,
+        "has_sandbox_helper": "sandbox-add-project-root.sh" in content,
+        # The hook template dropped `<slash-command> verify --auto-fix-symlinks`
+        # long ago (a slash command is not shell-callable, so it errored on
+        # every checkout). A hook still carrying it is stale — `setup upgrade`
+        # re-installs the current template.
+        "has_stale_verify_line": "--auto-fix-symlinks" in content,
     }