Skip to content

Adopt Apache Magpie (agent-assisted maintainer workflows) + JMeter config#1

Draft
milamberspace wants to merge 10 commits into
trunkfrom
magpie-project-manifest
Draft

Adopt Apache Magpie (agent-assisted maintainer workflows) + JMeter config#1
milamberspace wants to merge 10 commits into
trunkfrom
magpie-project-manifest

Conversation

@milamberspace

@milamberspace milamberspace commented Jul 7, 2026

Copy link
Copy Markdown
Owner

What

Adopts the Apache Magpie framework of
agent skills into JMeter, plus the JMeter-specific configuration, so
maintainers can run structured, auditable workflows (PR triage, issue
triage, stats dashboards, security-issue and release helpers) from their
own AI coding agent.

Draft / for discussion. Opened against my fork's trunk so the diff
and committed footprint are reviewable. It is not proposed to
apache/jmeter yet — see the dev@ DISCUSS thread.
Nothing is merged or run automatically.

Committed footprint (the important part)

19 files. The split:

  • ~485 lines of JMeter-specific config + wiring: project.md, the
    pr-management-* config, .gitignore, a short README section, two
    relay symlinks, .apache-magpie.lock.
  • The one committed magpie-setup bootstrap skill (~4.7k lines of
    Markdown docs, not code) — required so a fresh clone can re-fetch the
    framework.
  • Not committed: the other 68 skills. They live in a gitignored
    snapshot
    (.apache-magpie/), fetched on demand. They never land in
    git and never sit in the agent's context window (skills load on demand;
    only a one-line description per skill is indexed).

Full removal is a single command: /magpie-setup unadopt.

What's wired for JMeter

  • Families enabled: pr-management, issue, security. release-*
    is intentionally not wired yet.
  • Config adapted to JMeter reality: no area:* labels (area grouping
    disabled), no GitHub security tracker / Projects board (those panels are
    N/A), real CI-check names mapped (Validation, Error Prone, the JDK ×
    vendor × OS test matrix), longer grace windows for our slow triage
    cadence.
  • Backends: GitHub Issues, dev@/private@ via the ASF PonyMail
    archive, ASF Vulnogram CVE tooling.

How it stays low-risk

  • Human-in-the-loop: every skill only proposes; a human confirms
    before any comment, label, merge, or commit. No bots posting on their
    own, no CI automation.
  • Local & credential-scoped: runs in each maintainer's own agent under
    their own credentials. No shared service; no project data leaves the
    maintainer's control.
  • Deterministic guardrails: a PreToolUse hook blocks premature
    "ready", maintainer pings, and Co-Authored-By trailers. The hook is
    wired into the gitignored, per-machine .claude/settings.local.json by
    /magpie-setup (nothing hook-related is committed — see
    setup: write the agent-guard hook to gitignored settings.local.json instead of committing it to settings.json apache/magpie#824).

Example output (read-only, nothing posted)

PR-backlog dashboard generated from our 70 open PRs by the
pr-management-stats skill:
https://gistpreview.github.io/?b22eb23da618ff3b17a4e4e921375d72

Commits

  • Add Apache Magpie (snapshot + committed magpie-setup)
  • Finish apache-magpie adoption (locks, symlinks, overrides, hook, docs)
  • Add Apache JMeter project manifest
  • Add pr-management-triage config for JMeter

🤖 Generated with Claude Code

Complete the snapshot-based adoption started in 729551e:

- Pin the framework in .apache-magpie.lock (git-branch, apache/magpie@main)
- Wire security, pr-management, and issue skill families (+ always-on
  setup-*/list-*) as gitignored magpie-* symlinks
- Scaffold .apache-magpie-overrides/
- Wire the agent-guard PreToolUse hook in .claude/settings.json
- Document the adoption in README.md and AGENTS.md

Generated-by: Claude Opus 4.8
Add .apache-magpie-overrides/project.md — the per-project config the
apache-magpie skills read to resolve identity, repositories, mailing
lists, mail sources, and security-workflow knobs for JMeter.

Filled from confirmed facts (upstream apache/jmeter@master, GitHub
Issues, dev@/private@/user@/commits@jmeter.apache.org, ASF Vulnogram
CNA, Gmail+PonyMail mail sources). Security-tracker/board/issue-template
blocks are marked N/A: JMeter runs no dedicated GitHub security tracker
(.asf.yaml projects: false); vulnerabilities go to security@apache.org
and private@jmeter.apache.org.

Generated-by: Claude Opus 4.8
Add the three per-project config files the pr-management-triage skill
reads from .apache-magpie-overrides/:

- pr-management-config.md — identifiers, labels, grace windows (tuned
  longer than framework defaults for JMeter's slow triage cadence),
  workflow choices (pr-body feedback channel).
- pr-management-triage-comment-templates.md — JMeter doc URLs
  (CONTRIBUTING.md, gradle.md, building.html), the fixed quality-criteria
  marker, and the AI-attribution footer.
- pr-management-triage-ci-check-map.md — maps JMeter's real GitHub Actions
  check names (Validation, Error Prone, Matrix Preparation, the JDK x
  vendor x OS x locale test matrix) to categories + gradle.md.

area-grouping is disabled (JMeter uses no area:* labels); the workflow
labels are documented as not-yet-created (PMC decision) so label actions
degrade to feedback-only until then.

Generated-by: Claude Opus 4.8
Match the SPDX-License-Identifier header the four sibling files in
.apache-magpie-overrides/ already carry (project.md, pr-management-config.md,
pr-management-triage-comment-templates.md, pr-management-triage-ci-check-map.md).

AGENTS.md is intentionally left without a header, consistent with JMeter's
other root docs (README.md, CONTRIBUTING.md, SECURITY.md, THREAT_MODEL.md,
gradle.md), which carry none.

Generated-by: Claude Opus 4.8
Comment thread .claude/settings.json Outdated
"hooks": [
{
"type": "command",
"command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/agent-guard.py\"",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this? Why creating a hook without agent-guard.py?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Two parts, then the fix.

What it is: .claude/settings.json wires Magpie's deterministic agent-guard — a Claude Code PreToolUse hook that blocks risky gh/git commands before they run (a commit carrying a Co-Authored-By trailer, an @-mention that would ping a maintainer, marking a PR "ready" while CI is still pending, force-pushing an empty PR…). It's a safety rail, not project logic.

Why agent-guard.py isn't in the PR: same rule as the 68 skills — it's framework code, gitignored on purpose, synced from the Magpie snapshot by /magpie-setup (re-collected on upgrade). We don't vendor it into JMeter's history; only magpie-setup + config are committed.

But your underlying point is valid: the committed wiring referenced a script that isn't there until /magpie-setup runs, so on a fresh clone the hook would try to exec a missing file on every Bash call — and a PreToolUse error can block the tool. That's a footgun.

Fixed in 6ec2d88: the committed command is now a no-op until the script exists —

[ -f "$CLAUDE_PROJECT_DIR/.claude/hooks/agent-guard.py" ] && python3 "$CLAUDE_PROJECT_DIR/.claude/hooks/agent-guard.py" || true

I'll also upstream this to apache/magpie (via setup-upstream-fix), since it affects every adopter. If you'd rather not commit the wiring at all, the alternative is to let /magpie-setup write it into the gitignored settings.local.json instead — happy to switch to that if you prefer.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upstreamed: the guard is now proposed for every adopter in apache/magpie#786 — it updates the committed hook snippet in skills/setup/adopt.md and tools/agent-guard/README.md to the same [ -f … ] && … || true form. Once that merges and we /magpie-setup upgrade, our local 6ec2d88 becomes redundant and can be dropped. Thanks again for catching it.

<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->

# Apache JMeter — project manifest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who and what keeps this up to date?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair question — same one you raised on dev@, so here it is inline too.

These are slow-moving facts (upstream repo, default branch, mailing lists, label names, CI-check names) — a label rename or a new CI job touches one line. Keeping them current isn't a separate chore:

  • /magpie-setup upgrade reconciles these overrides against framework changes and surfaces any drift for review, and setup-upstream-fix pushes our own fixes back upstream.
  • When JMeter itself changes something referenced here (renames a label, adds a CI check), whoever makes that change updates the one line — exactly like .asf.yaml or CODEOWNERS.
  • The skills read this file at runtime, so an obviously-stale value surfaces on the next run.

So: "who" = the maintainers who use the skills, like any config; "what" = reconcile-on-upgrade plus normal review. Not a standing maintenance burden.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CI matrix changes very often. The stale context is worse than no context.

whoever makes that change updates the one line — exactly like .asf.yaml

I would prefer Magpie to source information from .asf.yaml rather than forcing everybody to duplicate the info.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point — you're right, and I've changed it.

I collapsed the CI-check map to a single generic pointer (a6a8908): there are no per-check-name patterns to maintain anymore, so nothing goes stale when the matrix changes. Every failing check just points at gradle.md — and since the old rows all pointed there anyway, we lose nothing. Stale context is worse than no context.

On sourcing from .asf.yaml: agreed in spirit, with one caveat — .asf.yaml doesn't actually carry the CI-check names (those live in .github/workflows/ + matrix.mjs), so it couldn't have fed this particular file. Where it does help is the stable project fields (repo, mailing lists via notifications:, labels), and those rarely change. The remaining project.md values here (repo, default branch, dev@/private@, the CNA org id) are stable too, so the staleness risk is essentially gone.

That said, your underlying request — Magpie should derive adopter config from existing sources instead of making everyone duplicate it — is a good framework-level idea, not a JMeter-local one, so I filed it upstream: apache/magpie#815 (same path as the hook fix → apache/magpie#786). Thanks for pushing on this.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Franlky, I do not see reasons to document ci check names in magpie and/or in other places

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — dropped the per-check-name patterns entirely (a6a8908); the CI-check map is now a single generic pointer to gradle.md, so there are no check names to keep in sync. I also filed the broader "derive adopter config from existing sources instead of duplicating" idea upstream: apache/magpie#815.

Per @vlsi's review on PR #1: .claude/settings.json wires the agent-guard
PreToolUse hook, but agent-guard.py is gitignored (framework code synced by
/magpie-setup, like the skills). On a fresh clone before /magpie-setup runs,
the hook would exec a missing file on every Bash call — and a PreToolUse
error can block the tool.

Guard the command so it is a no-op until the script exists:
  [ -f ".../agent-guard.py" ] && python3 ".../agent-guard.py" || true

Worth upstreaming to apache/magpie (affects every adopter).

Generated-by: Claude Opus 4.8
Per @vlsi's review on PR #1: JMeter's CI matrix job names are generated
dynamically (matrix.mjs) and change often, so the per-check-name patterns
(Validation / Error Prone / vendor substrings / stress-JIT / …) were a
stale-prone surface with no added value — every row pointed at the same
gradle.md anyway.

Collapse the map to a single generic catch-all (+ the merge-conflict and
failing-CI fallbacks). "Stale context is worse than no context."

Generated-by: Claude Opus 4.8
@milamberspace
milamberspace requested a review from vlsi July 11, 2026 08:21

@vlsi vlsi left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not care much about the contents of magpie-setup skill, however I would like to keep only really important entries in agents.md.

Comment thread .claude/settings.json Outdated
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work with windows?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — the [ -f … ] && … || true form is POSIX-only and would break under Windows PowerShell. Fixed in 3d302c3 with a pure-Python existence check that no-ops when the script is absent (fresh clone) and runs the guard otherwise — cross-platform, no shell conditional:

python3 -c "import os,sys,subprocess; p=os.path.join(os.environ.get('CLAUDE_PROJECT_DIR',''),'.claude','hooks','agent-guard.py'); sys.exit(subprocess.call([sys.executable,p]) if os.path.isfile(p) else 0)"

The earlier POSIX form landed upstream in apache/magpie#786 (already merged), so I'll open a follow-up there to make it cross-platform too.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can magpie add the hook entry to claude/settings.local.json on setup?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up opened: apache/magpie#823 makes the committed hook cross-platform (the pure-python3 -c form) upstream too.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — good call; not committing the wiring at all is cleaner than any guard.

The guard is simply inactive in JMeter until apache#824 lands — fine for an opt-in, pending adoption.

Comment thread AGENTS.md Outdated
@@ -1 +1,36 @@
Security model: [SECURITY.md](./SECURITY.md)

## apache-magpie framework

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not include excessive items to agents.md.
They will be injected in all the agent context, so it would distract agent attention and it would consume tokens.
As magpie is optional, I see no reason to mention it here

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — removed the whole apache-magpie section from AGENTS.md in 3d302c3, back to just the Security model line. You're right: AGENTS.md is injected into every agent context and Magpie is opt-in, so it shouldn't sit there. The adoption / setup summary stays in README.md (which is not always-injected).

Comment thread AGENTS.md Outdated
via PR to
[`apache/magpie`](https://github.com/apache/magpie).

### Reviewing pull requests

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not belong to agents.md either

…platform

Per @vlsi's review on PR #1:

- AGENTS.md: drop the whole "apache-magpie framework" section (incl. the
  "Reviewing pull requests" note). AGENTS.md is injected into every agent
  context, so an opt-in-framework advert is a permanent token tax and a
  distraction; the adoption/setup info already lives in README.md (which is
  not always-injected). Back to the single "Security model" line.

- .claude/settings.json: the previous guard used POSIX shell
  (`[ -f … ] && … || true`), which does not work under Windows PowerShell.
  Replace it with a pure-Python command that no-ops when the script is
  absent (fresh clone) and runs the guard otherwise — cross-platform, and
  no shell conditional:
    python3 -c "... sys.exit(subprocess.call([sys.executable,p]) if os.path.isfile(p) else 0)"

Generated-by: Claude Opus 4.8
Per @vlsi's review on PR #1: rather than committing the PreToolUse hook in
.claude/settings.json, the wiring belongs in the gitignored, per-machine
.claude/settings.local.json, written by /magpie-setup when it syncs
agent-guard.py in. Since the script is then always present when the wiring
exists, no fresh-clone guard is needed and the command stays a plain
cross-platform `python3 ".../agent-guard.py"` — no committed footprint, no
Windows shell issue.

Removing the committed settings.json here; the framework-side change (adopt
flow writing settings.local.json) is filed upstream. The guard is simply
inactive in JMeter until that lands — acceptable for an opt-in, pending
adoption.

Generated-by: Claude Opus 4.8
Companion to the previous commit. The agent-guard hook wiring now lives in
the per-machine .claude/settings.local.json, written by /magpie-setup — so
gitignore it (it must never be committed), and refresh the stale comment
that still referred to the removed committed settings.json.

Generated-by: Claude Opus 4.8
@milamberspace
milamberspace requested a review from vlsi July 11, 2026 18:57
Comment thread README.md
- https://github.com/apache/jmeter
- https://gitbox.apache.org/repos/asf/jmeter.git

## Agent-assisted contribution (apache-magpie)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am afraid PR triage and issue triage does require JMeter knowledge, so advising people to install magpie and start triaging PRs might be too much.

It might be ok as a section in CONTRIBUTING.md.

WDYT of listing the rules regarding agent-assisted contribution in the root readme (or contributing.md) instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants