# EXP-004 — QuantumDev Site Summary Ability

## Objectif

Créer et tester une Ability métier minimale, strictement en lecture, exposée en PHP et via MCP mais isolée de REST.

## Hypothèse

Une Ability namespacée peut retourner un contrat limité et déterministe à un Subscriber disposant seulement de `read`, sans écriture WordPress.

## Environnement

WordPress 7.0.4, PHP 8.4.24, WP-CLI 2.12.0, MCP Adapter 0.5.0, transport STDIO, client `exp-003-stdio-probe` 1.0, site canonique `https://www.lab.quantumdev.fr`.

## Préconditions

Le rollback EXP-003 était disponible. L’état avant test comptait 11 Abilities, 2 pages totales, 1 article, 2 utilisateurs et un site HTTP/REST 200. Aucun compte ou credential n’a été créé pour EXP-004.

## Architecture retenue

Plugin isolé `quantumdev-lab-abilities`, sans modification du thème, du core, de MCP Adapter ou de la base. Une seule Ability est enregistrée sur `wp_abilities_api_init`.

## Code de l’Ability

Le plugin `QuantumDev Lab Abilities` version 0.1.0 enregistre `quantumdev/site-summary`. Le callback lit uniquement `get_bloginfo()`, `home_url()` et `wp_count_posts()`. Aucun SQL, appel HTTP externe, option, contenu ou utilisateur n’est écrit.

## Contrat d’entrée

L’Ability ne prend aucun argument. WordPress 7.0.4 exige toutefois un schéma d’entrée pour l’exécution ; un objet vide explicite (`properties: []`, `additionalProperties: false`) a donc été ajouté, sans paramètre métier.

## Contrat de sortie

Objet fermé contenant exactement `site_title` (string), `site_url` (string), `wordpress_version` (string), `published_pages` (integer) et `published_posts` (integer).

## Permission

Le permission callback est `current_user_can('read')`. Sans utilisateur WordPress (ID 0), il retourne false ; avec `quantumdev_mcp_lab` (Subscriber, ID 2), il retourne true.

## Annotations

`readonly=true`, `destructive=false`, `idempotent=true`; `show_in_rest=false`; `meta.mcp.public=true` et `meta.mcp.type=tool`.

## Exposition

### PHP

Présente dans le registre via `wp_get_ability()` et exécutable avec le Subscriber.

### REST

Non présente dans la collection REST authentifiée et URL directe en 404 `rest_ability_not_found`, conformément à `show_in_rest=false`. La collection REST elle-même reste protégée aux anonymes (401).

### MCP

Découverte par `mcp-adapter-discover-abilities`; le nombre MCP-public passe de 2 à 3. Les outils du serveur par défaut restent les trois meta-tools de l’adaptateur.

## Test sans utilisateur WordPress

`current_user_id=0`, `current_user_can_read=false`, permission callback false.

## Test Subscriber

`current_user_id=2`, capability `read` vraie, permission callback vraie, sans élévation de rôle.

## Exécution PHP

Une exécution contrôlée a retourné : `My Blog`, `https://www.lab.quantumdev.fr/`, `7.0.4`, 1 page publiée et 1 article publié.

## Découverte MCP

Le client STDIO a négocié MCP `2025-06-18`; `quantumdev/site-summary` apparaît avec ses schémas, annotations et métadonnées MCP publiques.

## Exécution MCP

Après revue du risque du meta-tool générique (annoté destructif), une seule exécution ciblée de l’Ability readonly a été réalisée avec le Subscriber. Elle a réussi et n’a produit aucune écriture.

## Comparaison PHP / MCP

Les cinq champs sont identiques entre [php-execution.json](../../lab/output/EXP-004/php-execution.json) et [mcp-execution.json](../../lab/output/EXP-004/mcp-execution.json).

## Logs / preuves

Les preuves sont archivées sous `lab/output/EXP-004/`. Le client, l’Ability, les paramètres vides et le résultat sont démontrés ; aucun journal serveur persistant ni timestamp applicatif n’a été démontré.

## État avant / après

Après test : plugin QuantumDev actif et 12 Abilities (+1 attendu), contenu, utilisateurs, plugins existants, HTTP et REST inchangés. La différence entre 2 pages totales et 1 page publiée est explicitée dans les preuves.

## Risques

Le meta-tool `mcp-adapter-execute-ability` est générique et annoté destructif ; l’exécution a donc été limitée à l’Ability dont le callback et les annotations étaient inspectés. La surface reste dépendante des métadonnées MCP publiques.

## Rollback

READY : désactiver `quantumdev-lab-abilities`, vérifier la disparition de l’Ability, supprimer son seul dossier si nécessaire, puis confirmer le retour à l’état EXP-003. Aucun credential ou utilisateur n’a été ajouté.

## Conclusion

L’Ability est correctement enregistrée par le plugin QuantumDev, protégée par `read`, non exposée via REST, découverte et exécutée via MCP avec un Subscriber. Le résultat est strictement limité aux cinq champs contractuels et cohérent entre PHP et MCP.

## Niveau de confiance

fort

## Production

acceptable sous conditions

## Matière éditoriale

### Fait

Une Ability custom peut être PHP/MCP-public tout en restant REST-isolée.

### Surprise

Même une Ability sans entrée nécessite un schéma objet vide pour être exécutable sur cette version de WordPress.

### Chiffre

5 champs retournés ; 3 Abilities MCP-public après EXP-004.

### Erreur

La première version sans `input_schema` a été refusée par le runtime (`ability_missing_input_schema`) ; elle a été corrigée avant toute exécution réussie.

### Décision QuantumDev

Conserver un plugin expérimental isolé et des contrats fermés, avec permission WordPress standard et exposition MCP explicite.

### Capture exploitable

La comparaison tabulaire PHP/MCP dans `result-comparison.md` et la réponse JSON de l’exécution MCP.

### Angle LinkedIn

Une capacité utile n’a pas besoin d’un accès administrateur : un Subscriber peut fournir un résumé borné lorsque le contrat et la permission sont explicites.

### Niveau de preuve

démontré
