grahama1970/agentic-evals

Evaluación agéntica de habilidades utilizando pruebas con múltiples ensayos, aserciones de comandos deterministas, comprobaciones de trayectoria, restricciones de seguridad y puntuación de preparación respaldada por evidencia. Úselo cuando los usuarios soliciten evaluaciones agénticas, evaluación de habilidades con múltiples ensayos, validación de trayectoria de habilidades o puntuación de preparación para un flujo de trabajo de habilidades.

¿Qué es agentic-evals?

Esta habilidad proporciona un ejecutor de pruebas determinista para la evaluación de habilidades de agentes de IA, diseñado para escenarios donde una prueba de humo única es insuficiente. Ejecuta cada caso de prueba múltiples veces (ensayos), registra stdout/stderr/código de salida/duración, verifica expectativas explícitas (códigos de salida, contenidos de salida, artefactos) y emite un resumen de preparación legible por máquina. Soporta múltiples subcomandos como `run.sh run` para ejecutar evaluaciones, `audit-skills` para auditorías de brechas, `scaffold-fixture` para generar esqueletos de pruebas, `plan-journeys` para planificación de trayectorias y `regressions`/`coverage` para manejo de regresiones y cobertura basada en riesgos. Está diseñado para ser usado con habilidades o flujos de trabajo de agentes de IA, y es ideal para equipos que necesitan una evaluación rigurosa y repetible con evidencia clara de preparación. Las plataformas incluyen herramientas de desarrollo y flujos de CI/CD, y su mecanismo central se basa en un contrato de fixture con versión, ensayos, casos (positivos, negativos, adversariales), y un sistema de puntuación de preparación (READY, USABLE_WITH_GAPS, NOT_READY, NOT_ESTABLISHED) que falla si no se alcanza READY. También incluye un contrato anti-slop para evitar evaluaciones triviales y un modo de cumplimiento para pipelines críticos.

Compatible con~Claude Code~Codex CLI~Cursor✓Antigravity
npx skills add https://github.com/grahama1970/agent-skills/tree/main/skills/agentic-evals

Installed? Explore more Productividad y colaboración skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace agentic-evals?

Utilice esta habilidad cuando una prueba de humo única sea demasiado débil y la tarea requiera una evaluación repetible y respaldada por evidencia de una habilidad o flujo de trabajo de agente.

Alcance Actual

Este paquete inicial proporciona un ejecutor de fixtures determinista para casos basados en comandos. Ejecuta cada caso múltiples veces, registra stdout/stderr/estado de salida y duración, verifica expectativas explícitas y emite un resumen de preparación legible por máquina.

Esto solo prueba el comportamiento declarado del fixture. No prueba la corrección semántica, la integración real de servicios, la calidad de un juez LLM ni la preparación para el lanzamiento, a menos que los propios comandos del fixture ejerciten esas rutas en vivo.

Uso

./run.sh run fixtures/agentic_eval.json
./run.sh run fixtures/agentic_eval.json --output /tmp/agentic-evals-report.json
./run.sh audit-skills ../ --output /tmp/agentic-evals-baseline-gap-report.json
./run.sh scaffold-fixture ../some-skill --output ../some-skill/fixtures/agentic_eval.json
./run.sh apply-scaffolds ../ --write --output /tmp/agentic-evals-apply-scaffolds.json
# planificación de requisitos a trayectoria sobre descubrimiento en vivo (issue #1629)
./run.sh plan-journeys --fixture fixtures/agentic_eval.json \
  --requirements requirements.json \
  --interaction-inventory discovery/discovery-inventory.json \
  --state-graph discovery/state-graph.json \
  --output journey-plan.json [--scaffold-output fragment.json] [--report-only]
# reclamo / evidencia / regresión / cobertura (issues #1445-#1448)
./run.sh regressions audit ../ --output /tmp/agentic-evals-regressions.json
./run.sh regressions show . && ./run.sh regressions verify .
./run.sh coverage audit ../ --output /tmp/agentic-evals-coverage.json
./run.sh coverage show .

Preparación basada en reclamos (#1445)

Las pruebas deterministas prueban mecanismos; las E2E reales prueban capacidades. Un montón de casos deterministas que pasan nunca debe parecerse a la preparación para una capacidad en vivo que nunca fue ejercitada. Por lo tanto, la preparación se calcula por reclamo de capacidad declarado, luego se agrega, no a partir de un recuento de casos.

Declare capability_claims (mantenidos separados de la prosa de ámbito de prueba claims para que los fixtures v2 sigan siendo válidos). Cada caso que respalda un reclamo se etiqueta:

{
  "capability_claims": [
    {"id": "ask.roundtable.mixed_provider", "description": "...",
     "criticality": "critical",
     "evidence_required": {"deterministic": true, "live_e2e": true}}
  ],
  "cases": [
    {"name": "roundtable-live", "type": "positive", "evidence_class": "live_e2e",
     "supports_claims": ["ask.roundtable.mixed_provider"],
     "command": ["bash", "run.sh", "..."],
     "expected": {"exit_code": 0, "artifacts": [{"path": "out/join.json", "json_pointer": "/settled", "equals": true}]}}
  ]
}

Clases de evidencia: deterministic, property_or_fuzz, fault_injected_deterministic, live_e2e, adversarial_live_e2e, human_evaluation. Veredictos por reclamo: PROVEN, PARTIALLY_PROVEN, BLOCKED_EXTERNAL, FAILED, NOT_ESTABLISHED. Una habilidad está READY solo cuando cada reclamo crítico requerido está PROVEN bajo sus propios requisitos de evidencia. Cuando se declaran reclamos, la compuerta de run es el peor de la preparación basada en casos y basada en reclamos, por lo que veinte casos deterministas verdes con una ranura live_e2e requerida insatisfecha no pueden alcanzar READY. Un caso en vivo que respalde más de un reclamo debe llevar artefactos independientes por reclamo, de lo contrario no cuenta para ninguno de ellos. report["capability_readiness"] contiene el desglose por reclamo.

Reclamos derivados de invariantes (nunca apuntar una respuesta) — operador 2026-09-11

La prueba de oai se perdió por una omisión: el requisito "ningún PII llega a la salida" se redujo silenciosamente a "ningún PII en forma de cadena llega a la salida". Cada evaluación, verificador y ejecución de calificación demostró el reclamo reducido como verde mientras que los números de teléfono de tipo entero pasaban sin ser tocados. El cliente leyó el invariante en el ámbito del dominio; nosotros lo probamos en el ámbito del mecanismo. REGLAS:

  1. Los reclamos se derivan del invariante del dominio, no de lo que el código ya hace. Antes de declarar capability_claims, escriba el invariante en las palabras del cliente ("ninguna X llega a la salida en NINGUNA representación"), luego declare eso, textualmente, como el reclamo crítico. Un reclamo que describe el comportamiento actual es un apunte.
  2. La matriz de representación es obligatoria para reclamos que llevan valor. Cualquier reclamo sobre valores de datos (PII, dinero, identificadores, secretos) debe enumerar las representaciones que admite el formato de entrada — cadena JSON/entero/flotante/notación científica, comillas CSV, tipos SQL — y llevar al menos un caso adversarial por representación, cada uno capaz de fallar. Un reclamo de valor sin una matriz de representación no puede ser PROVEN.
  3. Se requiere un seam de cobertura denominado value-representation (criticality: critical) para cualquier pipeline que transforme, filtre o redacte valores de datos. La auditoría debe mostrar un guardia capaz en ese seam.
  4. Los verificadores independientes no deben compartir el generador de datos del productor. Los fixtures del verificador deben incluir representaciones que los propios fixtures de la transformación no incluyen, o la independencia es nominal.
  5. Cuando una brecha de representación se envía a producción, regístrela en fixtures/regressions.json (incidente → guardia retenido) y en el seam value-representation — el mismo tipo de error debe ser detectable para siempre.

El contrato anti-slop rechaza la plomería auto-servicial; estas reglas rechazan las suposiciones auto-serviciales — el conjunto que es honesto, adversarial, de múltiples ensayos y aún ciego porque cada fixture comparte una condición previa invisible sobre la forma de los datos.

Contrato de evidencia de extremo a extremo real (#1446)

evidence_class no se infiere de un comando que contenga run.sh o curl. Un caso que declara una clase en vivo (live_e2e/adversarial_live_e2e) es calificado estructuralmente y degradado (nunca aceptado silenciosamente) si:

  • se alimenta a sí mismo con entradas de fixtures//stub/mocked como la autoridad del límite;
  • no alcanza un punto de entrada de producción sustancial;
  • no tiene un oráculo de lectura independiente (expected.artifacts, readback: true, o stdout_excludes) — un código de salida más la prosa de éxito del propio comando no es prueba; o
  • reclama evidencia en vivo para los controladores tau-dag/compete del navegador $ask sin --execute y lectura de artefactos de ejecución del navegador/proveedor como node-receipt.json, response.md, response.meta.json, browser-tab-lifecycle.json, execution-status.json, roundtable-summary.md, o compete-scorecard.json. Los casos $ask solo de compilación/pre-vuelo son evidencia de mecanismo determinista, nunca live_e2e.

Un caso degradado se convierte en fault_injected_deterministic (falla en una ruta real) o deterministic, y el informe registra evidence_disqualifiers. Una ranura en vivo requerida cumplida solo por un caso BLOCKED_EXTERNAL deja el reclamo como no PROVEN.

Las exenciones son explícitas y con vencimiento. Un reclamo puede llevar exemptions nombrando evidence_class, reason_code, justification, owner y expires. Una exención válida se muestra en el informe (exempt_evidence) pero nunca hace que un reclamo sea PROVEN; una exención vencida o incompleta se ignora. No hay una eval_not_required general que satisfaga una capacidad operativa ejecutable.

Incidente → regresión retenida (#1447)

Una falla en vivo se convierte en evidencia permanente en fixtures/regressions.json (agentic_evals.regressions.v1). Cada registro vincula el incidente con los reclamos y los seams que amenazó, nombra el caso de guardia retenido (retained_case / retained_fixture) y lleva un fail_before_fix.proof_command.

  • regressions show <skill> / regressions audit <root> informan: regresiones no protegidas (caso retenido faltante/renombrado), regresiones nunca probadas (posiblemente vacuas), prueba en vivo obsoleta, regresiones retiradas e incidentes abiertos sin mapeo de regresión.
  • regressions verify <skill> vuelve a ejecutar cada comando de prueba y confirma que el guardia realmente falla contra el comportamiento roto (sale con código distinto de cero) — una prueba de no vacuidad, no una bandera auto-reportada. Sale con código distinto de cero si algún guardia de regresión activa no puede demostrar falla-antes-de-la-corrección.

Arreglar un error editando la expectativa de la evaluación para que coincida con la salida rota es exactamente lo que detecta la prueba de no vacuidad. Retirar una regresión requiere una razón de retirement.

Suficiencia de cobertura basada en riesgos (#1448)

Contar casos es manipulable. coverage audit/coverage show preguntan, por seam declarado: ¿hay al menos un caso capaz de detectar una regresión en ese seam, en cada clase de evidencia que el riesgo del seam requiere? Declare seams con seam_id, seam_type, criticality y required_evidence; etiquete casos con seams. Un caso cubre un seam solo cuando enumera ese seam y lleva un oráculo que puede fallar — un exit 0 positivo simple es weak_only y no cuenta. La auditoría informa seams cubiertos/descubiertos, cobertura solo débil, cobertura en vivo vs determinista, regresiones de incidentes mapeadas y próximas evaluaciones priorizadas. La cobertura (se declara un guardia capaz) y la frescura (una prueba en vivo está actualizada) son dimensiones separadas; el ejecutor no ejecuta los casos del seam aquí.

Contrato de Fixture

{
  "version": 2,
  "skill": "example-skill",
  "trials": 3,
  "proof_scope": "fixture wiring smoke",
  "claims": {
    "proves": "the declared command exits with the expected status",
    "does_not_prove": "semantic correctness, live service behavior, or full skill readiness"
  },
  "cases": [
    {
      "name": "happy-path",
      "type": "positive",
      "command": ["echo", "success"],
      "expected": {
        "exit_code": 0,
        "stdout_contains": ["success"]
      }
    }
  ]
}

Cada caso debe declarar:

  • name
  • type: positive, negative o adversarial
  • command: una lista argv no vacía
  • expected.exit_code

Expectativas opcionales:

  • expected.stdout_contains
  • expected.stderr_contains
  • must_exercise: lista de subcadenas de comando de contrato descendente que deben aparecer en el comando de nivel superior del caso. Utilícelo cuando un envoltorio podría falsificar el éxito; por ejemplo, una evaluación que reclama enrutabilidad $ticket/$project-watchdog debe incluir "skills/ticket/run.sh feature", no solo un script auxiliar que imprima OK.

Contrato Anti-Slop (fallo cerrado)

Un fixture de evaluación de habilidad es RECHAZADO en el momento de la carga (salida distinta de cero, sin ejecución) si es plomería determinista auto-servicial en lugar de una prueba del mundo real. Para pasar, un fixture de habilidad DEBE:

  • establecer trials >= 2 (un solo ensayo no es evidencia);
  • incluir al menos un caso negative o adversarial (un fixture completamente positivo es auto-servicial);
  • incluir al menos un caso del mundo real: "real_world": true cuyo comando ejercite una ruta en vivo (el run.sh de la habilidad / un script / HTTP en vivo / un ejecutor de pruebas) y NO se alimente a sí mismo con entradas stub de fixtures/;
  • no contener casos triviales de echo/constantes que no demuestren nada.

El mensaje de rechazo nombra cada violación. Esto evita una evaluación que pase trivialmente mientras no prueba nada sobre si la habilidad realmente funciona.

Nivel de cumplimiento ("eval_tier": "compliance")

Un fixture que protege una etapa de pipeline de cumplimiento declara "eval_tier": "compliance" y el ejecutor entonces EXIGE el contrato fuerte además de la línea base (directiva del operador 2026-08-12, "esto es un pipeline de cumplimiento y debe estar robustamente endurecido"). Dicho fixture es RECHAZADO a menos que:

  • una mayoría estricta de los casos sean adversarial/negative (más de la mitad, no exactamente la mitad — los controles positivos son la minoría);
  • al menos un caso sea no determinista: su comando muestrea entradas frescas cada ejecución mediante --samples, --seed o un $RANDOM de shell (un script de sonda con una clave fija no cuenta);
  • cada caso no determinista nombre --samples >= 50, de modo que la cobertura de cada etapa sea de cientos a miles de aserciones por ejecución, apuntando a ~1000 por etapa en todos sus modos.

La declaración no puede ser relajada silenciosamente: los propios fixtures del pipeline de cumplimiento establecen el nivel, por lo que eliminarlo para evitar la compuerta es en sí mismo una regresión. tests/test_compliance_tier_gate.py fija cada regla contra su debilitamiento.

Dos exenciones declaradas honestamente evitan la compuerta — nunca válidas para una evaluación de habilidad real:

  • "eval_kind": "runner_selftest" — un fixture que prueba al propio ejecutor o es un ejemplo de documentación.
  • "eval_kind": "scaffold" — el fixture mecánico de primera postura emitido por scaffold-fixture / apply-scaffolds, que la auditoría aún marca como necesitando casos reales.

Mapeo de Preparación

La preparación se puntúa sobre los casos requeridos solamente ("required": false excluye un caso). Un caso BLOCKED requerido no puede alcanzar READY: una condición previa no cumplida es ausencia de evidencia, no evidencia de éxito.

  • READY: cada caso requerido pasó todos los ensayos.
  • USABLE_WITH_GAPS: al menos un ensayo pasó y al menos uno no.
  • NOT_READY: los ensayos se ejecutaron pero ningún caso requerido pasó completamente.
  • NOT_ESTABLISHED: no se ejecutaron casos.

Salida de fallo cerrado

run sale con código distinto de cero a menos que la preparación sea READY. Un ejecutor que sale con 0 en USABLE_WITH_GAPS permite que un trabajo de CI externo se vuelva verde con casos fallidos, que es el fallo completo que esta compuerta existe para prevenir. Pase --report-only cuando desee el informe sin la compuerta.

Resultados de casos

Cada caso informa un outcome, porque estos significan cosas diferentes para una compuerta:

ResultadoSignificado
PASScada ensayo cumplió cada expectativa
FAILun defecto, o un tiempo de espera, o un ensayo que dejó un proceso hijo atrás
BLOCKEDuna condición previa no se cumplió; declare marcadores mediante blocked_when_stdout_contains
NOT_TESTEDno se ejecutaron ensayos

Aserciones de artefactos

La coincidencia de subcadenas de stdout no puede expresar "estos dos recibos nombran la misma sesión" o "la ejecución no dejó nada atrás". Declare expected.artifacts:

"expected": {
  "exit_code": 0,
  "artifacts": [
    {"path": "out/session.json", "json_pointer": "/sessionId",
     "equals_artifact": {"path": "out/detach.json", "json_pointer": "/sessionId"}},
    {"path": "out/attach.json", "json_pointer": "/sessionId",
     "exists": true},
    {"path": "out/session.json", "json_pointer": "/sessionId",
     "type": "string", "length_gte": 1},
    {"path": "out/session.json", "json_pointer": "/participants/0/anonymous",
     "equals": false},
    {"path": "/tmp/skill-runner-*/", "glob": "**/*.tmp", "count_lte": 0}
  ]
}

Aserciones de artefactos soportadas:

AserciónSemántica
exists: true/falseel archivo existe / no existe
equals: <value>el valor en la ruta JSON-pointer es exactamente <value>
equals_artifactdos archivos en punteros diferentes tienen el mismo valor
matches: <re>el valor coincide con la expresión regular
type: <type>string, number, boolean, null, array, object
length_gte: Nla cadena o array tiene longitud >= N
deep_match: <json>coincidencia JSON profunda contra un objeto/array literal
glob / count_gte / count_ltecoincidencia de patrón de archivo y recuento
json_pointer: ""la raíz completa del documento

Una aserción equals_artifact entre dos archivos de salida prueba que un valor de sesión es compartido a través de los límites del proceso o del tiempo, sin requerir un fixture de entrada stub.

Diferencia de fixture v1 → v2

Todos los campos de fixture en la parte superior ahora son opcionales si se declara version: 2. skill, trials y proof_scope tienen valores predeterminados sensibles. El único campo estrictamente requerido en un fixture v2 es cases (no vacío).

Registro

Pase --log-level debug para ver por qué falló un fixture; --log-level trace para ver cada iteración de ensayo.

Salida de estado de prueba en vivo (--progress)

Con --progress el ejecutor imprime una línea [FAIL], [PASS], [BLOCK], [SKIP] por caso a stderr tan pronto como se conoce el resultado. Los resultados de casos lentos aparecen a medida que finalizan, no en un lote al final. Sin --progress el ejecutor permanece en silencio excepto en caso de error.

Formato de informe

El reporte JSON (--output) es la única salida garantizada estable entre versiones. La salida a stdout es para legibilidad humana y puede cambiar.

Dependencias

  • jq (manejo JSON en shell)
  • python3 (análisis de artefactos complejos JSON-pointer)
  • bash 4+
  • coreutils (timeout, mktemp, etc.)

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

grahama1970/acceptance-contract

Turn a client brief, zip bundle, directory, or single requirements file into a typed acceptance-contract bundle with extracted requirements, acceptance checks, open questions, an immutable-goal draft, and a create-report-backed decision report. Use when users say acceptance contract, brief to requirements, freeze the goal, create immutable goal, amend immutable goal, build a Battle requirements bundle, or extract requirements from this bundle.

grahama1970/agent-ecosystem

Canonical map and shared contracts for the agent-governance ecosystem: the pi.receipt_envelope.v1 boundary envelope, the component graph, and the rules for which component owns which schema. Use when wiring a skill or extension into the shared receipt world, when asking how shame, triage-error, tau, ask, project-watchdog, ops-herdr, ponytail, and Memory fit together, or when validating an envelope.

grahama1970/agent-inbox

File-based inter-agent messaging with headless dispatch. Check inbox, send bugs/requests to other projects, automatically spawn headless agents to fix bugs, and track progress via task-monitor.

grahama1970/agents-registry

Generate and query the centralized agent identity registry. Scans .pi/agents/*/AGENTS.md, parses frontmatter, outputs agents-registry.json and optionally syncs to /memory for semantic search.

grahama1970/agent-status

Artifact-driven status surfaces for long-running project-agent work. Maintains status.json, events.jsonl, proof manifests, and a stale-aware STATUS.html so humans can tell where the agent is, what passed, what is still unproven, and what decision or action is next — without dashboard theater.

grahama1970/align

Round-based context alignment before execution. Use when the human, project agent, WebGPT, scillm, ask, dogpile, memory, or project-knowledge may each hold different facts about a task; especially before ambiguous design, infographic, product workflow, high-stakes implementation, plan-iterate, project-infographic, or multi-review work.

grahama1970/analytics

Flexible data science analytics for any dataset. Auto-discovers schema, recommends charts, exports to create-figure. Works with JSONL, JSON, CSV from any source.

grahama1970/analyze-chatterbox-emotions

Evaluate generated Chatterbox voice files as voice-quality artifacts: affect match, arousal/valence proxies, pause placement, intelligibility inputs, clipping, loudness, and discontinuity flags. Use when reviewing Chatterbox emotional tags, pauses, Turbo/base affect delivery, Persona Dream utterance renders, or whether generated speech matches an intended product-facing affect.

grahama1970/analyze-elf

Reverse-engineer features from ELF binaries. Extracts CLI commands, state machines, protocols, Zod schemas, and data models. Automatically generates a /create-walkthrough prosecution brief with Mermaid diagrams. Uses /treesitter for AST analysis of bundled JS/TS source.

grahama1970/animation-vocabulary

Reverse-lookup glossary that turns a vague description of a web animation or motion effect into its exact term ("the bouncy thing when a popover opens" → Pop in; "the iOS rubber-band scroll" → Rubber-banding). Use when the user asks "what's it called when…", or describes a motion effect without knowing its name and wants the right word to prompt an AI or designer with. For naming an effect, not designing or building one.

grahama1970/anonymize-data

Anonymize supported CSV, JSON, UTF-8 text, and SQLite files using an explicit policy through the oai-trial project. Use for anonymize data, pseudonymize exports, redact policy literals, or discover and explicitly approve fuzzy name aliases. The skill is a thin CLI/Docker interface, not another engine.

grahama1970/anvil

Heavy-duty "No-Vibes" debugging and hardening orchestrator. Use this for complex, stubborn bugs where `review-code` has failed, or for "Red Teaming" (hardening) a codebase. Runs multiple agents in parallel (Thunderdome) using git worktree isolation.

grahama1970/apple-design

Apple's approach to interface design and fluid, physical motion, translated for the web. Use when building or reviewing gesture-driven UI, spring animations, drag/swipe/sheet interactions, momentum and interruptible transitions, translucent materials and depth, typography (optical sizing, tracking, leading), reduced-motion, or the design foundations (feedback, spatial consistency, restraint) behind Apple-style interfaces.

grahama1970/argue

Multi-persona structured debate orchestrator. Personas research via /dogpile, consult colleagues via /ask, and argue toward nuanced synthesis on complex questions.

grahama1970/arxiv

Search arXiv for papers and extract knowledge into memory. Use `search` to find papers, `learn` to extract knowledge.

grahama1970/ask

Use when the user asks to query project memory, ask an oracle, use supported browser-backed reviewers, run Tau roundtable/single-handler workflows, ask Pi-native subagents from within Pi, run persona/deep-review workflows, generate image prompts, check OS/project health through composed skills, or run an ask DAG. This skill is the executable /ask runtime; do not replace it with an informal subagent, plain web search, or hand-written review; inside Pi, explicit Pi-native subagent targets are routed through the pi-subagents tool as an Ask target type.

grahama1970/assess

Step back and critically reassess project state. Use when asked to "assess", "step back", "fresh eyes", "check alignment", "sanity check", "health check", "prune documentation", or "evaluate what's working". Offers documentation pruning and doc-code alignment analysis. Offer to run after major changes (don't auto-run).

grahama1970/assistant

Shared GPT + classifier inference gateway for persona monitor tasks. Routes validation and classification through a 4-tier cascade: heuristic → classifier → local GPT → scillm.

grahama1970/assistant-lab

Self-improvement workbench for /assistant. All the tools needed to diagnose, train, evaluate, and promote models in a continuous loop. The "warm pond" where /assistant evolves its own inference stack.

grahama1970/batch-quality

Pre-flight validation and quality gates for batch LLM operations. ACTUALLY tests samples through LLM before burning tokens. Uses SPARTA contracts for DuckDB validation queries. Integrates with task-monitor for enforced quality gates.

Skills relacionados