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/10/25 15:36:31 UTC
(magpie) branch main updated: fix(setup): complete-upgrade write-scope probe and shallow clones (#1817)
This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/magpie.git
The following commit(s) were added to refs/heads/main by this push:
new bba82305f fix(setup): complete-upgrade write-scope probe and shallow clones (#1817)
bba82305f is described below
commit bba82305fe4557bdb43332c9bfb34ffbe9724a41
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Sun Oct 25 16:36:26 2026 +0100
fix(setup): complete-upgrade write-scope probe and shallow clones (#1817)
- The write-scope probe checks a directory that does not exist yet
(a personal layer `setup config` would create) through its nearest
existing parent, so creating it is no longer marked as leaving the
sandbox.
- A shallow framework clone counts as incomplete history: an
unmatched script copy there becomes an item that names the lines it
replaces, instead of being held back as a local edit.
- Eval: two new plan cases (shallow clone, personal layer not yet
created).
Generated-by: Claude Opus 5
---
docs/mode-economics.md | 2 +-
plugins/magpie-setup/skills/complete-upgrade/SKILL.md | 11 ++++++-----
tools/skill-evals/README.md | 2 +-
tools/skill-evals/evals/setup-complete-upgrade/README.md | 4 ++--
.../step-plan/fixtures/case-13-shallow-clone/case-meta.json | 1 +
.../step-plan/fixtures/case-13-shallow-clone/expected.json | 9 +++++++++
.../step-plan/fixtures/case-13-shallow-clone/report.md | 10 ++++++++++
.../fixtures/case-14-personal-layer-absent/case-meta.json | 1 +
.../fixtures/case-14-personal-layer-absent/expected.json | 9 +++++++++
.../fixtures/case-14-personal-layer-absent/report.md | 8 ++++++++
10 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/docs/mode-economics.md b/docs/mode-economics.md
index 47fb2f3da..9cc02c745 100644
--- a/docs/mode-economics.md
+++ b/docs/mode-economics.md
@@ -341,7 +341,7 @@ per machine and project after each Magpie version change:
| Skill | Typical invocation | Planning estimate | Primary cost driver | Replay p50 tokens |
|---|---|---|---|---|
| `committer-onboarding` | One post-vote onboarding walkthrough | 10K–30K | Mostly procedural; podling vs TLP path length | Not measured |
-| `setup-complete-upgrade` | One post-upgrade check, plan and approved apply | 15K–40K | Skill body is 6,170 tokens (`measured_tokens`); the rest is the state gather and one Bash call per applied item. Estimated. | Not measured |
+| `setup-complete-upgrade` | One post-upgrade check, plan and approved apply | 15K–40K | Skill body is 6,250 tokens (`measured_tokens`); the rest is the state gather and one Bash call per applied item. Estimated. | Not measured |
---
diff --git a/plugins/magpie-setup/skills/complete-upgrade/SKILL.md b/plugins/magpie-setup/skills/complete-upgrade/SKILL.md
index ebc0ac31e..ba15a4f3b 100644
--- a/plugins/magpie-setup/skills/complete-upgrade/SKILL.md
+++ b/plugins/magpie-setup/skills/complete-upgrade/SKILL.md
@@ -18,7 +18,7 @@ when_to_use: >-
capability: capability:platform
surface_hash: sha256:bf83981a9df27d35
license: Apache-2.0
-measured_tokens: 6170
+measured_tokens: 6250
---
<!-- Placeholder convention (see AGENTS.md#placeholder-convention-used-in-skill-files):
@@ -116,15 +116,16 @@ In a linked worktree of an adopted project that resolves to the main checkout's
**The sandbox write scope.**
For each directory a plan item would write to (the personal layer, the main checkout's one from a linked worktree, the worktree itself), create a probe file there inside the sandbox, then remove it.
+When the directory does not exist yet (a personal layer `setup config` would create), probe its nearest existing parent instead, since the item creates the directory.
The directories where that works make up the gathered sandbox write scope.
A write outside them carries `[bypass]`.
**Stale script copy or local edits.**
A user-scope script copy that differs from its framework source may be an older shipped version or may carry the user's own edits.
-Where the framework's git history is readable inside the sandbox (a framework checkout), look up the copy's blob hash (`git hash-object`) in `git log --raw --no-abbrev --format= -- <source>`.
+Where the framework's full git history is readable inside the sandbox (a framework checkout for which `git rev-parse --is-shallow-repository` prints `false`), look up the copy's blob hash (`git hash-object`) in `git log --raw --no-abbrev --format= -- <source>`.
A match means the copy is an older shipped version: it is stale.
No match means local edits.
-With no history to look in (a marketplace or snapshot install), the two cannot be told apart: record the lines only the installed copy has, for the plan to show.
+With no history to look in, or only part of it (a marketplace or snapshot install, or a shallow clone), the two cannot be told apart: record the lines only the installed copy has, for the plan to show.
**Magpie installed but not configured here.**
No personal layer (or no checker copy to ask), no `.apache-magpie-overrides/`, no committed lock: the plan carries one *Add* item, run [`setup config`](../setup/config.md) (personal, gitignored, needs nobody's permission).
@@ -157,7 +158,7 @@ Classify each item by the first rule that matches, in this order:
Items are numbered across groups, in discovery order within a group, one line each under about 100 characters.
A loud header line counts and lists the items that leave the sandbox, such as `!!! 3 of 5 items leave the sandbox: 1, 4, 5 !!!`; the *Run these yourself* preview and the isolated-setup offer, when it applies, are in the same message; values that cannot be derived are asked as one batched question.
-An item carries `[bypass]` when its action writes outside the gathered sandbox write scope (the directories where Gather's sandboxed probe write succeeded) or reads a path the sandbox denies: any write to a settings file (each worktree's `.claude/settings.local.json`, `~/.claude/settings.json`), to `~/.claude-config/` or to `~/.claude/scripts/`, and any probe of those or other denied paths.
+An item carries `[bypass]` when its action writes outside the gathered sandbox write scope (the directories where Gather's sandboxed probe write succeeded, in the nearest existing parent for a directory not created yet) or reads a path the sandbox denies: any write to a settings file (each worktree's `.claude/settings.local.json`, `~/.claude/settings.json`), to `~/.claude-config/` or to `~/.claude/scripts/`, and any probe of those or other denied paths.
A write inside the personal layer (including the main checkout's, from a linked worktree) or the worktree needs no bypass when it falls inside the gathered write scope; outside it, it carries `[bypass]`.
A harness without a bypass (see [Other harnesses](#other-harnesses)) lists every such item under *Run these yourself* instead.
@@ -171,7 +172,7 @@ Anything else goes under *Run these yourself* as a re-run of the [`setup-isolate
the `gpg-touch-wrap-*` symlinks and `shims/` are Step K, a `~/.claude/git-hooks/` flavour is Step P.3, the `container_gateway` package is Step L, the `skill_evals` package with `magpie-run-evals.sh` is Step M, and `agent-guard.py` with `guards.d` is the agent-guard wiring of Step P.
A copy Gather found to be an older shipped version is stale: *Update*, or *Fix* when the framework copy carries a security fix.
A copy with local edits goes under *Still open* with its diff path.
-A copy that could not be told apart (no history to compare) is an *Update* or *Fix* item whose line ends `(replaces N lines only this copy has)`.
+A copy that could not be told apart (no history to compare, or only a shallow clone's) is an *Update* or *Fix* item whose line ends `(replaces N lines only this copy has)`.
Its `details <n>` lists those lines, and its bypassed call saves the old copy to the scratch directory before writing.
This deliberately relaxes `setup-isolated-setup-update`'s "never re-`cp`" for plain-content copies only, under the checksum rule.
diff --git a/tools/skill-evals/README.md b/tools/skill-evals/README.md
index 60ed6839b..5d4d65b1f 100644
--- a/tools/skill-evals/README.md
+++ b/tools/skill-evals/README.md
@@ -37,7 +37,7 @@ Suites are currently implemented for:
- **list-skills** — 8 cases across 2 steps (step-1-command, step-2-present)
- **setup-isolated-setup-verify** — 27 cases across 4 steps (runtime-routing, codex-native, step-1-classify, step-2-recommend)
- **setup-isolated-setup-update** — 15 cases across 4 steps (runtime-routing, step-snapshot-drift, step-tool-freshness, step-after-report)
-- **setup-complete-upgrade** — 16 cases across 2 steps (step-plan, step-apply)
+- **setup-complete-upgrade** — 18 cases across 2 steps (step-plan, step-apply)
- **setup-isolated-setup-doctor** — 26 cases across 3 steps (runtime-routing, interpret-probes, after-report)
- **contributor-activity-sweep** — 13 cases across 3 steps (step-0-resolve-inputs, step-1-classify-reviews, step-2-render)
- **optimize-skill** — 7 cases across 1 step (step-diagnose)
diff --git a/tools/skill-evals/evals/setup-complete-upgrade/README.md b/tools/skill-evals/evals/setup-complete-upgrade/README.md
index 181d80e94..56edf5f65 100644
--- a/tools/skill-evals/evals/setup-complete-upgrade/README.md
+++ b/tools/skill-evals/evals/setup-complete-upgrade/README.md
@@ -5,11 +5,11 @@
Behavioral evals for the `setup-complete-upgrade` skill.
-## Suites (16 cases total)
+## Suites (18 cases total)
| Suite | Step | Cases | What it covers |
|---|---|---|---|
-| step-plan | ## Plan | 12 | mixed groups and bypass marking, hard lines to run-yourself, nothing to do, local-only script lines, linked worktree, non-Claude harness, isolated setup unknown vs absent, settings targets, stale shipped copy vs local edits, no history to compare, per-step install routing |
+| step-plan | ## Plan | 14 | mixed groups and bypass marking, hard lines to run-yourself, nothing to do, local-only script lines, linked worktree, non-Claude harness, isolated setup unknown vs absent, settings targets, stale shipped copy vs local edits, no history to compare, per-step install routing, shallow clone, personal layer not created yet |
| step-apply | ## Apply | 4 | drop applies the rest, changed-since-gathering skip, Check findings go to a second plan, one bypassed call per item |
## Run
diff --git a/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-13-shallow-clone/case-meta.json b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-13-shallow-clone/case-meta.json
new file mode 100644
index 000000000..03128a3ee
--- /dev/null
+++ b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-13-shallow-clone/case-meta.json
@@ -0,0 +1 @@
+{"tags":["local-smoke","smoke"]}
diff --git a/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-13-shallow-clone/expected.json b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-13-shallow-clone/expected.json
new file mode 100644
index 000000000..b24ca020c
--- /dev/null
+++ b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-13-shallow-clone/expected.json
@@ -0,0 +1,9 @@
+{
+ "items": [
+ {"group": "fix", "bypass": true, "id": "overlay-script-differs"}
+ ],
+ "run_yourself": [],
+ "still_open": [],
+ "isolated_offer": false,
+ "nothing_to_do": false
+}
diff --git a/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-13-shallow-clone/report.md b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-13-shallow-clone/report.md
new file mode 100644
index 000000000..ef83c426a
--- /dev/null
+++ b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-13-shallow-clone/report.md
@@ -0,0 +1,10 @@
+<!-- SPDX-License-Identifier: Apache-2.0
+ https://www.apache.org/licenses/LICENSE-2.0 -->
+
+Harness: Claude Code. Framework checkout, but a shallow clone: `git rev-parse --is-shallow-repository` prints `true`. Personal layer: `.apache-magpie-local/`. Isolated setup: configured.
+
+Findings:
+- slug: overlay-script-differs. `~/.claude/scripts/gpg-touch-overlay.sh` differs from `tools/agent-isolation/gpg-touch-overlay.sh`.
+ The diff shows 2 lines present in the user-scope copy that the framework copy lacks, and 3 lines the framework copy has that the user-scope copy lacks; the framework copy fixes a security problem.
+ Gather looked the copy's blob hash up in the git log of that file and found no match, but the log covers only the shallow history.
+ Writing `~/.claude/scripts/` is outside the sandbox write scope.
diff --git a/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-14-personal-layer-absent/case-meta.json b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-14-personal-layer-absent/case-meta.json
new file mode 100644
index 000000000..03128a3ee
--- /dev/null
+++ b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-14-personal-layer-absent/case-meta.json
@@ -0,0 +1 @@
+{"tags":["local-smoke","smoke"]}
diff --git a/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-14-personal-layer-absent/expected.json b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-14-personal-layer-absent/expected.json
new file mode 100644
index 000000000..70804d660
--- /dev/null
+++ b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-14-personal-layer-absent/expected.json
@@ -0,0 +1,9 @@
+{
+ "items": [
+ {"group": "add", "bypass": false, "id": "setup-config-needed"}
+ ],
+ "run_yourself": [],
+ "still_open": [],
+ "isolated_offer": false,
+ "nothing_to_do": false
+}
diff --git a/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-14-personal-layer-absent/report.md b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-14-personal-layer-absent/report.md
new file mode 100644
index 000000000..c4e8b892e
--- /dev/null
+++ b/tools/skill-evals/evals/setup-complete-upgrade/step-plan/fixtures/case-14-personal-layer-absent/report.md
@@ -0,0 +1,8 @@
+<!-- SPDX-License-Identifier: Apache-2.0
+ https://www.apache.org/licenses/LICENSE-2.0 -->
+
+Harness: Claude Code. Magpie installed (marketplace), not adopted and not configured: no personal layer yet, no `.apache-magpie-overrides/`, no committed lock. Isolated setup: configured.
+
+Findings:
+- slug: setup-config-needed. The personal layer `<git-common-dir>/apache-magpie/` does not exist yet; `setup config` would create it.
+ Gather's sandboxed probe write into the directory itself failed because it does not exist; the probe write into its nearest existing parent, `<git-common-dir>/`, succeeded.