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/19 19:42:58 UTC
(magpie) branch main updated: feat(setup): add pairing family first-run welcome guide (#1706)
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 34c77a9f feat(setup): add pairing family first-run welcome guide (#1706)
34c77a9f is described below
commit 34c77a9f8a3f9bdc19de77be723d6a562d36dea1
Author: Kavya Katal <KA...@GMAIL.COM>
AuthorDate: Tue Oct 20 01:12:52 2026 +0530
feat(setup): add pairing family first-run welcome guide (#1706)
* feat(setup): add pairing family first-run welcome guide
* docs(pairing): align welcome guide link with family README layout
* docs(setup): pairing guide configures, not installs; drop unused config bullet
`/magpie-setup:setup config` configures the installed skills for the
user; it installs nothing, so the guide now says "Configure it for
yourself". The "Adversarial reviewers" bullet pointed at
`adversarial-review.md`, which neither pairing skill reads, and called
the passes "three independent review passes", which holds only for
multi-agent-review, so it is dropped. The case-11 fixture that embeds
the guide is re-rendered.
Generated-by: Claude Opus 5
---------
Co-authored-by: Jarek Potiuk <po...@apache.org>
---
docs/pairing/README.md | 6 +++
.../skills/setup/setup_preflight/guides/pairing.md | 47 ++++++++++++++++++++++
tools/setup-preflight/tests/test_welcome.py | 19 +++++++--
tools/skill-evals/README.md | 2 +-
tools/skill-evals/evals/setup/README.md | 4 +-
.../case-12-pairing-first-run/case-meta.json | 1 +
.../case-12-pairing-first-run/expected.json | 1 +
.../fixtures/case-12-pairing-first-run/report.md | 37 +++++++++++++++++
.../fixtures/case-12-pairing-first-run/state.json | 24 +++++++++++
.../fixtures/case-9-first-magpie-run/report.md | 2 +-
10 files changed, 136 insertions(+), 7 deletions(-)
diff --git a/docs/pairing/README.md b/docs/pairing/README.md
index c1c03fd5..f62c0afb 100644
--- a/docs/pairing/README.md
+++ b/docs/pairing/README.md
@@ -66,6 +66,12 @@ New to Magpie? The [quick start](../quick-start.md) walks the whole path in
one place โ install, the first `/magpie-setup:setup` run, and a recording of it
happening โ plus the other agents and the secure-isolation setup to run next.
+The first pairing skill you run opens with a one-minute
+[welcome guide](../../plugins/magpie-setup/skills/setup/setup_preflight/guides/pairing.md):
+the typical flow, what needs configuring, what to ask it, and how to make it yours.
+Dismiss it, or hide it for good, from its last line;
+*"show the pairing welcome again"* or `/magpie-setup:welcome-guide pairing` brings it back.
+
### Before the first run
<!-- BEGIN generated: skill-config (tools/dev/check-skill-config.py --fix) -->
diff --git a/plugins/magpie-setup/skills/setup/setup_preflight/guides/pairing.md b/plugins/magpie-setup/skills/setup/setup_preflight/guides/pairing.md
new file mode 100644
index 00000000..1ffb0953
--- /dev/null
+++ b/plugins/magpie-setup/skills/setup/setup_preflight/guides/pairing.md
@@ -0,0 +1,47 @@
+<!-- SPDX-License-Identifier: Apache-2.0
+ https://www.apache.org/licenses/LICENSE-2.0 -->
+
+# ๐ฆ Magpie here โ your pre-PR review sidekick
+
+A one-minute tour, then straight back to what you asked for.
+
+## ๐ The typical flow
+
+1. ๐ **Self-review** your local diff before pushing โ *"review my diff before I push"*
+2. ๐ก๏ธ **Multi-agent review** the diff with independent correctness, security, and conventions passes โ *"run independent reviews of my branch"*
+
+Both skills return review reports. They never edit files, post comments, open PRs, push, or merge.
+
+## โ๏ธ Configure it
+
+Nothing is required before your first review:
+
+- ๐ **Project context** โ optionally use `project.md` for project-scoped references; otherwise the skills use their defaults
+- ๐ฏ **Review scope** โ choose a base ref, staged changes, or a path filter when needed
+
+Configure it for yourself with `/magpie-setup:setup config`.
+Adopting shared configuration with `/magpie-setup:setup adopt` is a project maintainer decision.
+
+## ๐ฌ Just ask
+
+Talk to Magpie in plain language:
+
+- *"review my diff before I push"*
+- *"check my staged changes for correctness and security"*
+- *"review only the files under this directory"*
+- *"run three independent review passes on my branch"*
+- *"compare the correctness, security, and conventions findings"*
+
+For an already-open PR, use the PR-management code-review workflow instead.
+
+## ๐จ Make it yours
+
+Describe how you want the review workflow to behave:
+
+- *"focus my self-review on error handling and security risks"*
+- *"make the conventions review check our project's documented style"*
+
+Review the proposed skill override before applying it.
+Useful to others? Ask *"upstream this change to Magpie"* to prepare a reusable contribution for your review.
+
+<!-- welcome footer: generated from guides/_footer.md -->
diff --git a/tools/setup-preflight/tests/test_welcome.py b/tools/setup-preflight/tests/test_welcome.py
index 72e2b628..d5f4d77f 100644
--- a/tools/setup-preflight/tests/test_welcome.py
+++ b/tools/setup-preflight/tests/test_welcome.py
@@ -103,6 +103,16 @@ def test_the_mentoring_family_guide_comes_on_the_next_run(project: Path, version
assert due(project, "welcome") == [("general", "again")]
+def test_the_pairing_family_guide_comes_on_the_next_run(project: Path, version) -> None:
+ assert welcome.family_of("self-review") == "pairing"
+ assert welcome.family_of("multi-agent-review") == "pairing"
+ assert due(project, "self-review") == [("general", "first-run")]
+ welcome.record(project, "general", "seen")
+ assert due(project, "self-review") == [("pairing", "first-run")]
+ welcome.record(project, "pairing", "seen")
+ assert due(project, "self-review") == [("general", "again")]
+
+
def test_at_most_one_guide_per_run(project: Path, version) -> None:
for _ in range(8):
found = welcome_findings(project, SECURITY_SKILL)
@@ -400,11 +410,11 @@ def test_show_without_color_prints_the_markdown(capsys) -> None:
def test_the_rules_section_and_both_guides_ship() -> None:
assert welcome.SECTION in sections.available()
- assert {"general", "security", "utilities", "mentoring"} <= set(welcome.guides())
+ assert {"general", "security", "utilities", "mentoring", "pairing"} <= set(welcome.guides())
assert welcome.family_guides() == [g for g in welcome.guides() if g != "general"]
-@pytest.mark.parametrize("name", ["general", "security", "utilities", "mentoring"])
+@pytest.mark.parametrize("name", ["general", "security", "utilities", "mentoring", "pairing"])
def test_each_guide_is_short_and_ends_with_the_way_back(name: str) -> None:
text = welcome.guide(name) or ""
assert not text.startswith("<!--")
@@ -427,7 +437,8 @@ def test_the_footer_is_shared_and_filled_in_per_guide() -> None:
general = welcome.guide("general") or ""
utilities = welcome.guide("utilities") or ""
mentoring = welcome.guide("mentoring") or ""
- for text in (security, general, utilities, mentoring):
+ pairing = welcome.guide("pairing") or ""
+ for text in (security, general, utilities, mentoring, pairing):
assert "{{" not in text
assert "welcome footer: generated" not in text
assert "`/magpie-setup:welcome-guide security`" in security
@@ -438,6 +449,8 @@ def test_the_footer_is_shared_and_filled_in_per_guide() -> None:
assert "--family utilities --color=always" in utilities
assert "`/magpie-setup:welcome-guide mentoring`" in mentoring
assert "--family mentoring --color=always" in mentoring
+ assert "`/magpie-setup:welcome-guide pairing`" in pairing
+ assert "--family pairing --color=always" in pairing
def test_list_prints_every_guide(capsys) -> None:
diff --git a/tools/skill-evals/README.md b/tools/skill-evals/README.md
index a3211a52..473c9cb4 100644
--- a/tools/skill-evals/README.md
+++ b/tools/skill-evals/README.md
@@ -11,7 +11,7 @@ Behavioral eval harness for Apache Magpie skills. Each eval suite tests a skill
Suites are currently implemented for:
-- **setup** โ 131 cases across 30 steps (step-verify-drift, step-overrides-surface, step-override-bypass, step-m3-baseline-pick, step-m4-install-gates, step-m5-no-repo-offer, step-m5-companion-offer, step-upgrade-companion-offer, step-adopt-settings-merge, verify-default-set, uninstall-default-set, lock-marketplace-parse, adopt-write-floor, setup-prefill-from-floor, preflight-floor, upgrade-adoption-split, verify-floor, adopt-review-process, adopt-security-list, step-reconcile, step-veri [...]
+- **setup** โ 132 cases across 30 steps (step-verify-drift, step-overrides-surface, step-override-bypass, step-m3-baseline-pick, step-m4-install-gates, step-m5-no-repo-offer, step-m5-companion-offer, step-upgrade-companion-offer, step-adopt-settings-merge, verify-default-set, uninstall-default-set, lock-marketplace-parse, adopt-write-floor, setup-prefill-from-floor, preflight-floor, upgrade-adoption-split, verify-floor, adopt-review-process, adopt-security-list, step-reconcile, step-veri [...]
- **setup-isolated-setup-install** โ 19 cases across 5 steps (runtime-routing, step-snapshot-drift, step-scope-confirm, step-hardware-key, step-roborev-exclusion)
- **setup-privacy-llm** โ 6 cases across 2 steps (step-1-resolve, step-4-gate)
- **setup-shared-config-sync** โ 12 cases across 2 steps (step-3-decide-action, step-5-draft-commit)
diff --git a/tools/skill-evals/evals/setup/README.md b/tools/skill-evals/evals/setup/README.md
index 68909156..24adaa28 100644
--- a/tools/skill-evals/evals/setup/README.md
+++ b/tools/skill-evals/evals/setup/README.md
@@ -5,7 +5,7 @@
Behavioral evals for the `setup` skill.
-## Suites (131 cases total)
+## Suites (132 cases total)
| Suite | Step | Cases | What it covers |
|---|---|---|---|
@@ -25,7 +25,7 @@ Behavioral evals for the `setup` skill.
| adopt-review-process | adopt.md ยง Step 4c | 5 | a fresh adopt finding two deviations in the confirmed documents where one is accepted and one rejected, and a release policy left alone because that family is not in the floor; a re-adoption reviewing only the one family the floor diff added; a re-adoption that adds no family, where edited process documents are still not re-read; a sentence that would weaken a merge confirmation gate, dropped and named while a label deviation beside it is [...]
| adopt-security-list | adopt.md ยง Step 4b | 4 | an ASF project whose dedicated security list is in its docs and on the ASF page (recommend `security@`); an ASF project with no dedicated list (no recommendation, `private@` only as a flagged fallback); a non-ASF project, which is not asked; and conflicting evidence between `SECURITY.md` and the ASF page (no recommendation, flagged fallback) |
| setup-prefill-from-floor | install.md ยง Step M0b | 4 | adopted (propose the floor), unadopted (framework defaults), a foreign marketplace called out, and a snapshot lock falling through |
-| preflight-floor | preflight-block.md ยง Pre-flight | 11 | at floor (silent), below floor (update), plugin missing (install), foreign marketplace (ask first, run nothing), no `claude` CLI (print), unadopted (propose setup), `apache/magpie` in an alarming context (update anyway, unasked), unreadable `claude plugin list --json` (silent, treated as unknown not absent), first Magpie run (show the general welcome guide, record it, carry on), first utilities run (show the utilities welcome gui [...]
+| preflight-floor | preflight-block.md ยง Pre-flight | 12 | at floor (silent), below floor (update), plugin missing (install), foreign marketplace (ask first, run nothing), no `claude` CLI (print), unadopted (propose setup), `apache/magpie` in an alarming context (update anyway, unasked), unreadable `claude plugin list --json` (silent, treated as unknown not absent), first Magpie run (show the general welcome guide, record it, carry on), first utilities run (show the utilities welcome gui [...]
| upgrade-adoption-split | upgrade.md ยง Step 0b | 4 | not adopted (nothing staged), adopted (floor raised and staged), already ahead (floor unchanged), snapshot method (falls through) |
| verify-floor | verify.md ยง Adoption floor | 4 | no lock (not a fault), ahead of floor with extra plugins (not a fault), a shortfall (a fault), a floor plugin the marketplace no longer ships (a fault, not installed around) |
| step-reconcile | reconcile.md ยง The sweep | 3 | a clean sweep on a pinned-snapshot install (anchor present, config resolved โ stamp written, nothing proposed), a renamed step heading stranding an override's anchor (one re-anchor proposal named), a marketplace install whose plugin cache is sandbox-denied (anchor resolution left `unchecked`, config resolution still completes) |
diff --git a/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/case-meta.json b/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/case-meta.json
new file mode 100644
index 00000000..88c1f39a
--- /dev/null
+++ b/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/case-meta.json
@@ -0,0 +1 @@
+{"tags":["local-smoke"]}
diff --git a/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/expected.json b/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/expected.json
new file mode 100644
index 00000000..2adc36df
--- /dev/null
+++ b/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/expected.json
@@ -0,0 +1 @@
+{"action": "welcome", "commands": [], "blocks": false}
diff --git a/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/report.md b/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/report.md
new file mode 100644
index 00000000..75865659
--- /dev/null
+++ b/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/report.md
@@ -0,0 +1,37 @@
+<!-- SPDX-License-Identifier: Apache-2.0
+ https://www.apache.org/licenses/LICENSE-2.0 -->
+
+There is no `.apache-magpie.lock`, no `.apache-magpie-overrides/` and no
+`.apache-magpie-local/` at the repo root. The running agent is Claude Code
+with magpie-setup 0.4.0 and magpie-pairing 0.4.0 installed.
+
+The user has already seen the initial general welcome guide on an earlier run.
+The invoked skill's own frontmatter reads `name: self-review` and
+`surface_hash: sha256:ea0a2e29bb2aa0e0`; it belongs to the pairing family.
+This is the first time a pairing skill has run here.
+The user asked it to "review my diff before I push".
+
+The pre-flight command printed:
+
+```json
+{
+ "findings": [
+ {
+ "code": "welcome",
+ "facts": {
+ "family": "pairing",
+ "guide": "# \ud83d\udc26 Magpie here \u2014 your pre-PR review sidekick\n\nA one-minute tour, then straight back to what you asked for.\n\n## \ud83d\udd04 The typical flow\n\n1. \ud83d\udd0d **Self-review** your local diff before pushing \u2014 *\"review my diff before I push\"*\n2. \ud83d\udee1\ufe0f **Multi-agent review** the diff with independent correctness, security, and conventions passes \u2014 *\"run independent reviews of my branch\"*\n\nBoth skills return review reports [...]
+ "max_shown": 3,
+ "reason": "first-run",
+ "shown": 0
+ },
+ "scope": "family",
+ "section": "welcome"
+ }
+ ],
+ "rules": {
+ "welcome": "## welcome \u2014 a first-run welcome guide is due\n\nA welcome guide is due on this run: `facts.family` names it\n(`general`, for the first Magpie skill this user runs here, or the skill's own family),\nand `facts.reason` says why (`first-run`, `again`, or `upgraded` after a dismissal).\n`facts.guide` is the guide. The checker shows at most one guide per run and has already picked it.\n\n1. **Show `facts.guide` to the user verbatim**, as Markdown, before the work they as [...]
+ },
+ "verdict": "action"
+}
+```
diff --git a/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/state.json b/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/state.json
new file mode 100644
index 00000000..703247cf
--- /dev/null
+++ b/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-12-pairing-first-run/state.json
@@ -0,0 +1,24 @@
+{
+ "lock": null,
+ "plugins": [
+ [
+ "magpie-setup",
+ "0.4.0"
+ ],
+ [
+ "magpie-pairing",
+ "0.4.0"
+ ]
+ ],
+ "reconciled": {
+ "welcome": {
+ "general": {
+ "choice": "seen",
+ "shown": 1
+ }
+ }
+ },
+ "skill": "self-review",
+ "welcome": true,
+ "hash": "sha256:ea0a2e29bb2aa0e0"
+}
diff --git a/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-9-first-magpie-run/report.md b/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-9-first-magpie-run/report.md
index f7a217d1..66f7d419 100644
--- a/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-9-first-magpie-run/report.md
+++ b/tools/skill-evals/evals/setup/preflight-floor/fixtures/case-9-first-magpie-run/report.md
@@ -20,7 +20,7 @@ The pre-flight command printed:
"code": "welcome",
"facts": {
"family": "general",
- "guide": "# \ud83d\udc26 Hello from Magpie \u2014 your project's maintainer sidekick\n\nOne minute, then straight back to what you asked for.\n\n## \ud83d\ude80 Getting started\n\n- \ud83d\udce6 **Install** from your agent's marketplace (Claude Code shown):\n `/plugin marketplace add apache/magpie`,\n then `/plugin install magpie-setup@apache-magpie` and one `/plugin install magpie-<family>@apache-magpie` per family you want\n- \ud83d\ude4b **Configure it for yourself** \u2014 [...]
+ "guide": "# \ud83d\udc26 Hello from Magpie \u2014 your project's maintainer sidekick\n\nOne minute, then straight back to what you asked for.\n\n## \ud83d\ude80 Getting started\n\n- \ud83d\udce6 **Install** from your agent's marketplace (Claude Code shown):\n `/plugin marketplace add apache/magpie`,\n then `/plugin install magpie-setup@apache-magpie` and one `/plugin install magpie-<family>@apache-magpie` per family you want\n- \ud83d\ude4b **Configure it for yourself** \u2014 [...]
"max_shown": 3,
"reason": "first-run",
"shown": 0