Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/labels-and-capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ it implements multiple contracts (e.g. `tools/gmail` provides both
| [`tools/jira`](../tools/jira/) | `contract:tracker` | JIRA REST substrate (read-only today; write subcommands tracked in [#301](https://github.com/apache/magpie/issues/301)) |
| [`tools/mail-archive`](../tools/mail-archive/) | `contract:mail-archive` | Adapter contract for public mail-archive backends (PonyMail, Hyperkitty, Discourse, Google Groups, GitHub Discussions). Pure interface spec. |
| [`tools/mail-source`](../tools/mail-source/) | `contract:mail-source` | Mail-source backend abstraction (mbox / IMAP / Mailman 3) feeding a uniform inbound thread/message view to the intake pipeline |
| [`tools/ponymail`](../tools/ponymail/) | `contract:mail-archive` | PonyMail public mail-archive substrate (ASF `lists.apache.org`); implements the `tools/mail-archive/` contract |
| [`tools/ponymail`](../tools/ponymail/) | `contract:mail-archive` + `contract:mail-source` | PonyMail public mail-archive substrate (ASF `lists.apache.org`); implements the `tools/mail-archive/` contract for archive reads and the `tools/mail-source/` contract for inbound list-traffic ingestion |
| [`tools/scan-format`](../tools/scan-format/) | `contract:scan-format` | Adapter contract for security-scanner report formats (ASVS reference); reads a scan's finding index + per-finding evidence for the `security-issue-import-from-scan` pipeline. |
| [`tools/permission-audit`](../tools/permission-audit/) | `substrate:sandbox` | Audit + atomically edit Claude Code `permissions.allow[]` entries; backs `/magpie-setup verify --apply-permission-audit` (check 8d) |
| [`tools/pr-management-stats`](../tools/pr-management-stats/) | `substrate:analytics` | PR-backlog analytics engine |
Expand All @@ -258,6 +258,7 @@ it implements multiple contracts (e.g. `tools/gmail` provides both
| [`tools/skill-evals`](../tools/skill-evals/) | `substrate:framework-dev` | Eval harness for skills; framework-dev infrastructure whose run output is governance evidence |
| [`tools/skill-and-tool-validator`](../tools/skill-and-tool-validator/) | `substrate:framework-dev` | Skill-frontmatter and convention validator |
| [`tools/spec-status-index`](../tools/spec-status-index/) | `substrate:framework-dev` + `substrate:analytics` | Index of spec / RFC implementation status — framework-dev substrate that also doubles as a governance/stats view (`analytics`) |
| [`tools/vendor-neutrality-score`](../tools/vendor-neutrality-score/) | `substrate:framework-dev` + `substrate:analytics` | Deterministic vendor-neutrality score — reads each contract tool's `**Kind:**` / `**Vendor:**` metadata and scores per-contract + per-skill neutrality (`analytics`); backs the score block in [`docs/vendor-neutrality.md`](vendor-neutrality.md) |
| [`tools/spec-validator`](../tools/spec-validator/) | `substrate:framework-dev` | Spec-frontmatter and body-section validator — counterpart to `skill-and-tool-validator` for `tools/spec-loop/specs/` |
| [`tools/symlink-lint`](../tools/symlink-lint/) | `substrate:framework-dev` | Self-adoption symlink hygiene — rejects cyclic symlinks and misdirected skill relays (canonical/relay target-correctness) |
| [`tools/pilot-report-validator`](../tools/pilot-report-validator/) | `substrate:framework-dev` | Adopter pilot-report validator — required frontmatter keys, no unfilled placeholders, valid profile, and required body sections; counterpart to `spec-validator` for `docs/pilot-report-template.md` |
Expand Down Expand Up @@ -286,7 +287,7 @@ backend the adopter wired in. The framework consumes four:
|---|---|---|---|---|
| GitHub MCP | `mcp__github__*` | [`tools/github`](../tools/github/) | `contract:tracker` + `contract:source-control` | — |
| Gmail MCP (claude.ai) | `mcp__claude_ai_Gmail__*` | [`tools/gmail`](../tools/gmail/) | `contract:mail-source` + `contract:mail-draft` + `contract:mail-archive` | — |
| PonyMail MCP (`apache/comdev`) | `mcp__ponymail__*` | [`tools/ponymail`](../tools/ponymail/) | `contract:mail-archive` | ASF |
| PonyMail MCP (`apache/comdev`) | `mcp__ponymail__*` | [`tools/ponymail`](../tools/ponymail/) | `contract:mail-archive` + `contract:mail-source` | ASF |
| apache-projects MCP (`apache/comdev`) | `mcp__apache-projects__*` | [`tools/apache-projects`](../tools/apache-projects/) | `contract:project-metadata` | ASF |

Non-MCP backends fulfil the same contracts: JIRA is reached over REST
Expand Down
86 changes: 86 additions & 0 deletions docs/vendor-neutrality.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
- [What keeps it neutral over time](#what-keeps-it-neutral-over-time)
- [The contribution model — neutrality as an invitation](#the-contribution-model--neutrality-as-an-invitation)
- [Status at a glance](#status-at-a-glance)
- [Vendor-neutrality score](#vendor-neutrality-score)
- [How the score is computed](#how-the-score-is-computed)
- [What the number means](#what-the-number-means)
- [What "vendor neutral" does and does not claim](#what-vendor-neutral-does-and-does-not-claim)
- [See also](#see-also)

Expand Down Expand Up @@ -490,6 +493,89 @@ coverage without pretending one team can implement an open-ended set.
adding a backend is an adapter against a documented contract, not a
change to any skill.

## Vendor-neutrality score

The six axes above are the *narrative*. This section is the
*measurement* — a deterministic score computed straight from repository
metadata by
[`tools/vendor-neutrality-score`](../tools/vendor-neutrality-score/), so
the number is reproducible from the source tree and cannot quietly drift
from the code.

### How the score is computed

Neutrality is measured per **capability contract** — the `contract:*`
verbs a skill depends on. Substrate tools (Magpie's own machinery:
sandboxing, analytics, framework-dev) are excluded, because they are not
a vendor choice.

Every contract tool declares three fields in its README: `**Capability:**`
(the contract it fulfils), `**Kind:**` (`interface` for a pure spec,
`implementation` for a concrete backend), and `**Vendor:**` (the backend
identity). The scorer reads them and applies one rule per contract
**class**:

- **vendor-backed** → GREEN once **two or more distinct backend vendors**
implement it. One backend, however good, is a *default*, not
neutrality. Interface specs do not count — only shipping backends do.
- **agnostic** → GREEN by construction: a single vendor-neutral spec
serves every backend, so there is no vendor to be neutral *between*.
- **single-organisation** → GREEN by exemption: the capability is bound
to one organisation's data model (e.g. ASF governance rosters); there
is no vendor choice to make.

The overall score is `green contracts / total contracts` — a hard,
falsifiable number. Add a second outbound-mail backend and `mail-draft`
flips to green on the next run; remove a backend and its contract flips
back. The same rule then classifies every **skill**: *capability-pure*
if it names no backend, *portable* if every backend it invokes has an
alternative, and *vendor-coupled* only if it reaches for the sole
implementation of a capability.

<!-- BEGIN vendor-neutrality-score — generated by `uv run --project tools/vendor-neutrality-score vendor-neutrality-score --markdown`; do not edit by hand -->
**Overall vendor-neutrality score: 8/9 capability contracts (89%).** Generated by [`tools/vendor-neutrality-score`](../tools/vendor-neutrality-score/); re-run it to refresh this section.

| Capability contract | Neutral? | Class | Backends today | Basis |
|---|---|---|---|---|
| `contract:tracker` | ✅ | vendor-backed | Atlassian, GitHub | 2 backend vendors: Atlassian, GitHub |
| `contract:source-control` | ✅ | vendor-backed | Git, GitHub, Subversion | 3 backend vendors: Git, GitHub, Subversion |
| `contract:mail-archive` | ✅ | vendor-backed | Google, PonyMail | 2 backend vendors: Google, PonyMail |
| `contract:mail-source` | ✅ | vendor-backed | Google, PonyMail | 2 backend vendors: Google, PonyMail |
| `contract:mail-draft` | ❌ | vendor-backed | Google | only 1 backend vendor (Google); needs 1 more |
| `contract:cve-authority` | ✅ | vendor-backed | CVE.org, Vulnogram | 2 backend vendors: CVE.org, Vulnogram |
| `contract:report-relay` | ✅ | agnostic | — | vendor-neutral by construction — one spec serves every backend |
| `contract:scan-format` | ✅ | agnostic | — | vendor-neutral by construction — one spec serves every backend |
| `contract:project-metadata` | ✅ | single-org | ASF | single-organisation capability (ASF); no vendor choice to make |

**Per-skill assessment: 59/63 skills carry no vendor lock-in.** A skill is *capability-pure* when it names no backend at all, *portable* when every backend it names has an alternative (its contract is green), and *vendor-coupled* only when it reaches for a backend that is the sole implementation of a capability.

| Skill neutrality | Count |
|---|---|
| capability-pure (names no backend) | 9 |
| portable (named backends are swappable) | 50 |
| vendor-coupled (sole-backend dependency) | 4 |

Organization scope (declared, orthogonal to vendor): ASF = 14, agnostic = 49.

Vendor-coupled skills (the only lock-ins today):

- `security-issue-import` — `Google` → `contract:mail-draft`
- `security-issue-import-via-forwarder` — `Google` → `contract:mail-draft`
- `security-issue-invalidate` — `Google` → `contract:mail-draft`
- `security-issue-sync` — `Google` → `contract:mail-draft`
<!-- END vendor-neutrality-score -->

### What the number means

89% is not "89% done." It reads as: **eight of nine capabilities already
work across more than one vendor, and the ninth — outbound mail drafting
— is one adapter away.** The architecture privileges no vendor on any of
the nine axes; the single red cell is a missing *implementation* (a
second `mail-draft` backend), tracked in the open, not a design that
assumes Gmail. Likewise only four skills touch that one lock-in, and each
does so through the `mail-draft` contract — swap in a second backend and
all four become portable without a line of skill code changing.

## What "vendor neutral" does and does not claim

To keep the marketing honest and the engineering claim precise:
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,5 @@ members = [
"tools/spec-validator",
"tools/symlink-lint",
"tools/vcs",
"tools/vendor-neutrality-score",
]
4 changes: 4 additions & 0 deletions tools/apache-projects/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

**Capability:** contract:project-metadata

**Kind:** implementation

**Vendor:** ASF

**Organization:** ASF

ASF project-metadata substrate. Read-only, unauthenticated client
Expand Down
4 changes: 4 additions & 0 deletions tools/asf-svn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@

**Capability:** contract:source-control

**Kind:** implementation

**Vendor:** Subversion

**Organization:** ASF

ASF SVN tool adapter — the Subversion counterpart to
Expand Down
4 changes: 4 additions & 0 deletions tools/cve-org/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

**Capability:** contract:cve-authority

**Kind:** implementation

**Vendor:** CVE.org

CVE.org publication client. Submits CVE records via the CVE.org REST API; consumed by `security-cve-allocate` once a CVE has been allocated via the ASF Vulnogram path. See [`tool.md`](tool.md) for the protocol detail and `cve.org` field mapping.

## Prerequisites
Expand Down
4 changes: 4 additions & 0 deletions tools/cve-tool-vulnogram/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

**Capability:** contract:cve-authority

**Kind:** implementation

**Vendor:** Vulnogram

**Organization:** ASF

ASF Vulnogram CVE-allocation client. OAuth-authenticated API that allocates a CVE ID through the ASF's Vulnogram instance and publishes the CVE record. Consumed by `security-cve-allocate`. See [`allocation.md`](allocation.md), [`record.md`](record.md), and [`bot-credits-policy.md`](bot-credits-policy.md) for the protocol.
Expand Down
4 changes: 4 additions & 0 deletions tools/cve-tool/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@

**Capability:** contract:cve-authority

**Kind:** interface

**Vendor:** agnostic

## Prerequisites

- **Runtime:** None — this directory is a Markdown contract spec; no executable code ships here. It is read by the framework, not run.
Expand Down
4 changes: 4 additions & 0 deletions tools/forwarder-relay/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@

**Capability:** contract:report-relay

**Kind:** interface

**Vendor:** agnostic

A forwarder-relay adapter is a pluggable seam that teaches the
security skills how to recognise an inbound report that arrived
**through a relay** (someone else forwarded the original
Expand Down
4 changes: 4 additions & 0 deletions tools/github-body-field/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@

**Capability:** contract:tracker

**Kind:** implementation

**Vendor:** GitHub

Read or rewrite a single `### Field` section of a GitHub issue
body **without bringing the body into agent context**.

Expand Down
4 changes: 4 additions & 0 deletions tools/github-rollup/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

**Capability:** contract:tracker

**Kind:** implementation

**Vendor:** GitHub

Append to (or create) the status-rollup comment on a GitHub
issue **without bringing the rollup body into agent context**.

Expand Down
4 changes: 4 additions & 0 deletions tools/github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

**Capability:** contract:tracker + contract:source-control

**Kind:** implementation

**Vendor:** GitHub

GitHub REST + GraphQL substrate. Pure read/write wrapper used by every lifecycle phase (triage / intake / fix / resolve / stats). See [`tool.md`](tool.md) for the operation catalogue and the per-area files ([`issue-template.md`](issue-template.md), [`labels.md`](labels.md), [`operations.md`](operations.md), [`project-board.md`](project-board.md), [`status-rollup.md`](status-rollup.md)) for specifics.

## Prerequisites
Expand Down
4 changes: 4 additions & 0 deletions tools/gmail/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

**Capability:** contract:mail-source + contract:mail-draft + contract:mail-archive

**Kind:** implementation

**Vendor:** Google

Gmail API substrate. Read + draft-only — never sends. Provides two
contracts: `mail-source` for inbound report intake (search / read a
uniform thread/message view) and `mail-draft` for outbound courtesy-reply
Expand Down
4 changes: 4 additions & 0 deletions tools/jira/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@

**Capability:** contract:tracker

**Kind:** implementation

**Vendor:** Atlassian

JIRA REST helpers for the `issue-*` skill family.
Adopters with JIRA-based issue trackers wire this in as their
tracker bridge; adopters using GitHub Issues or other trackers
Expand Down
4 changes: 4 additions & 0 deletions tools/mail-archive/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@

**Capability:** contract:mail-archive

**Kind:** interface

**Vendor:** agnostic

This file defines the adapter contract for **public mail-archive
backends** — the seam that lets adopting projects plug a non-ASF
archive system (Hyperkitty, Discourse, Google Groups, GitHub
Expand Down
4 changes: 4 additions & 0 deletions tools/mail-source/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

**Capability:** contract:mail-source

**Kind:** interface

**Vendor:** agnostic

Mail-source backend abstraction. Pluggable backends (mbox, IMAP, the Gmail API via [`tools/gmail`](../gmail/), future Mailman 3 / Hyperkitty) that feed the security-issue-import intake pipeline a uniform thread/message view. See [`contract.md`](contract.md) for the backend interface.

## Prerequisites
Expand Down
6 changes: 5 additions & 1 deletion tools/ponymail/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@

# `tools/ponymail/`

**Capability:** contract:mail-archive
**Capability:** contract:mail-archive + contract:mail-source

**Kind:** implementation

**Vendor:** PonyMail

**Organization:** ASF

Expand Down
4 changes: 4 additions & 0 deletions tools/scan-format/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@

**Capability:** contract:scan-format

**Kind:** interface

**Vendor:** agnostic

A **scan-format adapter** teaches
[`security-issue-import-from-scan`](../../skills/security-issue-import-from-scan/SKILL.md)
how to read one security scanner's report layout. The skill is
Expand Down
4 changes: 4 additions & 0 deletions tools/vcs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

**Capability:** contract:source-control

**Kind:** implementation

**Vendor:** Git

Runnable implementation of the **source-control (VCS) capability**
documented in
[`tools/github/source-control.md`](../github/source-control.md). It
Expand Down
Loading
Loading