0039 — Distribución de la skill de Claude Code: b2g skill add como 2.º comando meta (junto a gui), vendoreada en el wheel con version-lock skill==cli¶
- Estado: Aceptada
- Fecha: 2026-06-28
- Decidido por: Product Owner humano (decisión acordada 2026-06-28). El mecanismo de
distribución (vendoring en el wheel como fuente del paquete, comando
b2g skill addcon--user|--project|--force, version-lock skill==cli) y el descarte del extra[skill]y del camino plugin+marketplace como primario son decisiones del PO. El encuadre —"la mejor forma de usar bib2graph es pedirle a Claude que lo use; la skill es esa puerta, y es un comando meta/admin, no un paso del ciclo"— y la categorización como 2.ª excepción meta junto aguison síntesis de la IA (architect) validada por el PO. - Enmienda a: 0038 (destino de los huérfanos del 0037).
El 0038 estableció la categoría "verbo fuera del set de 10, gobernado por su propio ADR" para
gui(excepción explícita, no un paso del ciclo). Este ADR agrega una 2.ª excepción de la misma clase:skilles un comando meta/distribución, no un verbo del ciclo de investigación. No revierte el 0037 ni el 0038: el conteo de 10 verbos del ciclo sigue siendo verdad; la superficie pasa a leerse como "10 verbos del ciclo +gui(GUI) +skill(meta/distribución)". El envelopeschema="1", los exit codes y el FSM del lazo se preservan (ADR 0021 §C/§D/§F). - Relacionada con: 0037 (la superficie ES el ciclo:
skillno compite constatusni con ningún verbo del ciclo; vive al lado, no dentro), 0028 (precedente del vendoring de assets en el wheel;gui/staticusaforce-includepor ser artefacto gitignored — la skill no lo necesita, ver §Mecanismo), 0010/0021 (CLI agente-native: la skill enseña los 10 verbos del 0037 a un agente end-user), 0029 (skill addes un comando meta global que funciona sin workspace, igual queinitcuando crea uno). - No introduce IA (coherente con 0022): la skill es
markdown (instrucciones +
reference/) que un agente Claude Code lee; bib2graph no embebe ni invoca ningún modelo. La IA está en el cliente del usuario (su Claude Code), no en el producto. - Origen: epic #188. Encuadre de posicionamiento: "el antídoto al sesgo del related work" (#187) — la skill es la forma en que un usuario hispano corre el ciclo one-shot pidiéndole a Claude que use bib2graph.
Contexto¶
El 0037 dejó la superficie CLI consolidada en 10 verbos que mapean el ciclo de investigación,
legibles por un agente sin manual. El 0038 cerró el conteo despachando los huérfanos y fijó la
categoría de la excepción meta: gui se mantiene fuera del set de 10 porque es una
superficie distinta (lanzador de la GUI local), gobernada por su propio ADR (0027/0028), no un
paso del ciclo agents-first.
Falta una pieza del posicionamiento "la mejor forma de usar bib2graph es pedirle a Claude que lo
use": una skill de Claude Code para el usuario final que (1) entreviste al investigador
sobre su pregunta y sus fuentes, y (2) le enseñe al agente la mejor forma de manejar bib2graph
—es decir, los 10 verbos del 0037 y la historia one-shot init→seed→chain→build→read, leyendo
status como mapa—. La skill es markdown sin dependencias Python: un SKILL.md + una carpeta
reference/.
El problema es de distribución y de versionado, no de diseño del ciclo:
- ¿Dónde vive la skill? Si se publica como un paquete/extra aparte, su versión desacopla de la del CLI: una skill v0.10 podría quedar instruyendo a un agente que corre un CLI v0.11 con la superficie ya cambiada (los 9 aliases del 0038 retirados en 0.11.0). La skill enseña los 10 verbos; si enseña verbos que ya no existen, miente.
- ¿Cómo se instala? Claude Code descubre skills en
~/.claude/skills/<nombre>/(user) o.claude/skills/<nombre>/(project). Unpip installno escribe en esas rutas; instalar una skill es copiar archivos a un directorio del cliente, no resolver dependencias Python.
La pregunta de este ADR es: ¿cómo se empaqueta y se instala la skill de modo que su versión quede amarrada a la del CLI, sin agregar superficie al ciclo?
Decisión¶
bib2graph distribuye una skill de Claude Code end-user, vendoreada dentro del wheel bajo
src/bib2graph/skill/, y la instala con un comando meta nuevo b2g skill add que la copia al
directorio de skills del cliente. skill es la 2.ª excepción meta explícita (junto a gui):
un comando meta/distribución, NO un paso del ciclo de investigación. El contrato de salida
(envelope schema="1"/exit/FSM) no cambia.
skill es comando meta, no un verbo del ciclo (2.ª excepción junto a gui)¶
- No mapea ningún paso del ciclo INIT→SEED→CHAIN→CURATE→BUILD→READ→EXPORT/SNAPSHOT. No produce
ni transforma corpus ni redes. No compite con
status(el mapa del ciclo) ni con ningún verbo del 0037: vive al lado de la superficie, no dentro. - Es de la misma clase que
gui: una superficie distinta gobernada por su propio ADR (este). El 0038 categorizóguicomo "se mantiene, fuera del set de 10";skillreusa esa categoría. - Reconciliación del conteo: los 10 verbos del ciclo del 0037 siguen siendo verdad. La
superficie pasa a leerse como "10 verbos del ciclo +
gui(GUI) +skill(meta/distribución)". El conteo de 10 es verificable contrab2g --help; las dos excepciones meta están documentadas, no disimuladas (mismo criterio de honestidad del 0038: excluir explícitamente es más honesto que omitir).
Mecanismo: vendoring + version-lock skill==cli¶
- (M1) La skill vive vendoreada en el wheel bajo
src/bib2graph/skill/(SKILL.md+reference/). Como es fuente commiteada bajo el paquete, la incluyepackages = ["src/bib2graph"]sinforce-include. (El frontendgui/static/sí necesitaforce-includepor ser un artefacto gitignored, ADR 0028 G5; la skill no — y meterla ahí la duplicaría y rompería el build.) (Elpyproject.tomles trabajo delcoder; este ADR fija el mecanismo, no la sintaxis.) - (M2) Garantía central: skill-version == cli-version. Como la skill viaja en el mismo wheel
que el CLI, instalar
bib2graph==X.Y.Ztrae una skill que enseña exactamente los verbos de esa versión. El vendoring en el mismo artefacto es el version-lock; no hay forma de tener una skill v0.10 sobre un CLI v0.11. Esto es lo que cierra el riesgo de "la skill miente". - (M3)
b2g skill add [--user|--project] [--force]copia la skill vendida al directorio de skills del cliente: --user(default) →~/.claude/skills/bib2graph/.--project→.claude/skills/bib2graph/(relativo al cwd).--force→ pisa una instalación existente; sin él, el comando es idempotente (si ya está en la versión vendida, no hace nada y lo reporta).- Funciona sin workspace: es un comando meta global, no requiere
workspace.jsonni resolución de ambiente (comoinital crear, o comogui/resolveque no transicionan). - Emite el envelope
--jsonschema="1"SIN transición de FSM (igual quegui/resolve): es ortogonal al lazo. (Eldataemitido es{install_path, scope, installed, already_present, skill_md, reference_dir, how_to},schema="1"intacto; documentado endocs/API.md.) - Salida agéntica (AgenticExperience): la salida —humana y
--json— es explícita sobre dónde quedó elSKILL.mdy pide leerlo, con un resumenhow_tode cómo opera bib2graph a grandes rasgos. Esto vuelve la skill auto-descubrible por un agente de cualquier proveedor (no solo Claude Code) sin depender del mecanismo de descubrimiento del cliente — el primer puente hacia la distribución agnóstica del 0.11.0 (#193).
La historia de uso (cómo llega la skill al investigador)¶
$ pip install bib2graph # trae el CLI + la skill vendoreada (mismo wheel, misma versión)
$ b2g skill add # copia la skill a ~/.claude/skills/bib2graph/ (--user default)
# en Claude Code: "usá bib2graph para armar la red de citación de estos papers…"
# el agente lee la skill, entrevista al investigador y corre el ciclo one-shot del 0037
La skill es la materialización del mensaje "la mejor forma de usar bib2graph es pedirle a Claude
que lo use": enseña el ciclo (init→seed→chain→build→read, status como mapa) que el 0037 hizo
legible para un agente.
Consecuencias¶
Lo que se gana
- Version-lock por construcción. La skill y el CLI no pueden divergir: viajan en el mismo wheel. La skill siempre enseña los verbos que el CLI realmente expone (incluido el corte de los 9 aliases en 0.11.0, ADR 0038 P1).
- Instalación de un paso, sin Node ni deps extra.
pip install bib2graph && b2g skill add: markdown copiado a~/.claude/skills/, sin tocar[project.dependencies]. - El conteo del ciclo se mantiene honesto. 10 verbos + 2 excepciones meta documentadas
(
gui,skill). El 0037/0038 no se debilita:skillno entra al ciclo, lo acompaña. - Reusa un precedente probado, más simple. El ADR 0028 (G5) ya vendorea assets en el wheel; la
skill se monta sobre la misma idea pero al ser fuente commiteada entra por
packages, sin tocarforce-includeni infraestructura nueva.
Lo que cuesta
docs/API.mddocumenta una 2.ª excepción meta:skillconskill addy sus flags, la reconciliación del conteo ("10 + gui + skill") y la nota de empaquetado (la skill entra porpackages, no porforce-include). Eldatadel envelope es{install_path, scope, installed, already_present, skill_md, reference_dir, how_to}(schema="1"intacto).- El wheel engorda con la skill (markdown, peso menor); al ser fuente del paquete entra por
packagessin config extra. (pyproject.toml/CI son delcoder.) - Mantener la skill al día con el ciclo. Si el ciclo del 0037 cambia (futuro ADR), la skill —que lo enseña— debe actualizarse en el mismo cambio. El version-lock lo hace detectable (van juntas) pero no automático: editar el ciclo sin editar la skill es drift a vigilar.
- Atado a Claude Code — limitación DELIBERADA de 0.10.0.
skill addinstala solo en~/.claude/skills/(ruta/formato de Claude Code). Atar la distribución a un proveedor restringe el acceso y repite la lógica de gatekeeping que el producto quiere evitar (que solo quien tiene Claude pueda pedirle a su agente que use bib2graph). La distribución agnóstica al proveedor —el usuario/agente declara su cliente (Claude Code, OpenCode, …) yskill addinstala en su formato— es prioridad de 0.11.0 (#193), probable enmienda a este ADR (skill addganaría--provider). El version-lock skill==cli se preserva en todos los proveedores.
Alternativas¶
- El extra
pip install bib2graph[skill]. Descartada. Un extra de pip solo agrega dependencias Python; no escribe en~/.claude/skills/. La skill es markdown sin deps: no hay nada que un extra resuelva. El acto de instalar una skill es copiar archivos al directorio del cliente —eso lo haceb2g skill add, nopip—. Un extra[skill]daría la falsa impresión de que instalarlo deja la skill lista, cuando no toca el directorio de Claude Code. - Plugin + marketplace de Claude Code (
/plugin install). Descartada como primaria (dejada como ruta futura mencionable). Un plugin distribuido por marketplace desacopla el versionado: la skill viviría en un repo/marketplace con su propia cadencia de release, y volvería el riesgo que M2 cierra (skill v0.10 sobre CLI v0.11). El vendoring en el wheel da el version-lock gratis; el plugin lo rompería. Si en el futuro se quiere descubribilidad vía marketplace, puede convivir como espejo de la skill vendoreada, no como su fuente de verdad. - Meter
skilldentro del set de 10. Descartada (mismo criterio que el 0038 rechazó paragui):skill addno es un paso del ciclo de investigación; es distribución/admin. Forzarlo al set mezcla dos contratos. Excluirlo explícitamente —2.ª excepción meta documentada— es más honesto que disimularlo en el conteo. - Publicar la skill en un repo aparte / como descarga manual. Descartada: rompe el
version-lock (M2) y agrega un paso de instalación que
b2g skill addresuelve en uno. El usuario que ya tiene el CLI ya tiene la skill correcta.