Communitygithub.com

laravel-security

Práticas recomendadas de segurança para Laravel — autenticação, autorização, segurança no Eloquent, CSRF, prevenção de XSS, segurança de API e configurações de deploy seguras. Use ao revisar autenticação Laravel, segurança no Eloquent, CSRF, XSS, segurança de API ou configuração de deploy.

O que é laravel-security?

Essa skill fornece um guia completo de segurança para aplicações Laravel, cobrindo autenticação (Sanctum, Passport, Jetstream, Breeze), autorização (Gates e Policies), proteção contra CSRF, XSS, injeção SQL, atribuição em massa e configuração segura de produção. Ela inclui exemplos práticos de código, como configuração de middleware HTTPS, validação de senhas com regras do Password::min, e uso de escopos globais para soft deletes. A skill é ativada automaticamente quando o agente detecta contexto relacionado a implementação de autenticação/autorização, revisão de vulnerabilidades, configuração de ambiente de produção ou escrita de queries Eloquent seguras. Ela funciona em qualquer terminal ou IDE que suporte a skill, não sendo específica para uma plataforma de agente, e documenta boas práticas como nunca usar `$guarded = []` em produção e sempre regenerar a sessão após login.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/laravel-security

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Práticas Recomendadas de Segurança no Laravel

Diretrizes de segurança abrangentes para aplicações Laravel para proteger contra vulnerabilidades comuns.

Quando Ativar

  • Configurando autenticação e autorização no Laravel (Sanctum, Passport, Jetstream, Breeze)
  • Implementando funções de usuário, permissões e políticas
  • Configurando configurações de segurança de produção e variáveis de ambiente
  • Revisando aplicações Laravel em busca de vulnerabilidades de segurança
  • Implantando aplicações Laravel em produção
  • Escrevendo queries e migrações Eloquent seguras

Configuração de Produção

Configurações Essenciais de Produção

// config/app.php
'env' => env('APP_ENV', 'production'),
'debug' => (bool) env('APP_DEBUG', false), // CRÍTICO: Nunca true em produção
'key' => env('APP_KEY'), // Deve ser definido: php artisan key:generate

// config/session.php
'secure' => env('SESSION_SECURE_COOKIE', true),
'http_only' => true,
'same_site' => 'lax',

// Verificar se APP_KEY está definido na inicialização
// bootstrap/app.php ou um service provider
if (empty(config('app.key'))) {
    throw new RuntimeException('APP_KEY não está definido. Execute: php artisan key:generate');
}

Segurança do Arquivo de Ambiente

# NUNCA commitar .env no controle de versão
# .gitignore já inclui .env por padrão

# Use .env.example com placeholders
DB_PASSWORD=
APP_KEY=
SANCTUM_TOKEN_PREFIX=

# Validar variáveis obrigatórias na inicialização
// Em AppServiceProvider::boot()
$requiredKeys = ['app.key', 'database.connections.mysql.database', 'database.connections.mysql.username'];
foreach ($requiredKeys as $key) {
    if (empty(config($key))) {
        throw new RuntimeException("Chave de configuração obrigatória ausente: {$key}");
    }
}

Forçar HTTPS

// AppServiceProvider::boot() ou middleware
if (app()->environment('production')) {
    URL::forceScheme('https');
    request()->server->set('HTTPS', 'on');
}

// config/app.php para proxies confiáveis (load balancers)
// Use faixas de IP específicas — * confia em todos, permitindo falsificação X-Forwarded-*
// AWS: '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'
'trusted_proxies' => ['10.0.0.0/8', '172.16.0.0/12'],

// Forçar HTTPS em produção via middleware
// app/Http/Middleware/ForceHttps.php
public function handle($request, Closure $next)
{
    if (!$request->secure() && app()->environment('production')) {
        return redirect()->secure($request->getRequestUri());
    }
    return $next($request);
}

Autenticação

Sanctum (Autenticação por Token de API)

// config/sanctum.php
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
    '%s%s',
    'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
    env('APP_URL') ? ',' . parse_url(env('APP_URL'), PHP_URL_HOST) : ''
)));

'expiration' => 60 * 24, // Expiração do token em minutos (null = nunca)
'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),

// Emitindo tokens com habilidades
$token = $user->createToken('api-token', ['read', 'write'])->plainTextToken;

// Validar habilidades nas rotas
Route::middleware('auth:sanctum')->group(function () {
    Route::get('/orders', function () {
        // Usuário deve ter habilidade 'read'
        abort_unless(Auth::user()->tokenCan('read'), 403);
        // ...
    })->middleware('abilities:read');

    Route::post('/orders', function () {
        // Usuário deve ter habilidade 'write'
        abort_unless(Auth::user()->tokenCan('write'), 403);
        // ...
    })->middleware('abilities:write');
});

Segurança de Senhas

// config/hashing.php
// O padrão é bcrypt. Argon2id é mais forte.
'bcrypt' => [
    'rounds' => env('BCRYPT_ROUNDS', 12), // Aumente para hash mais forte
],

'argon' => [
    'memory' => 65536,
    'threads' => 4,
    'time' => 4,
],

// Validação de senha em RegisterRequest
public function rules(): array
{
    return [
        'password' => [
            'required',
            'confirmed',
            Password::min(12)
                ->letters()
                ->mixedCase()
                ->numbers()
                ->symbols()
                ->uncompromised(), // Verifica haveibeenpwned
        ],
    ];
}

// Limitar tentativas de login
// App\Http\Controllers\Auth\AuthenticatedSessionController
protected function authenticated(Request $request, $user)
{
    if ($user->wasRecentlyLockedOut()) {
        // Notificar usuário sobre login suspeito
        $user->notify(new SuspiciousLoginNotification($request->ip()));
    }
}

Gerenciamento de Sessão

// config/session.php
'driver' => env('SESSION_DRIVER', 'database'), // database/redis > file
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false),
'encrypt' => env('SESSION_ENCRYPT', false),

// Regenerar sessão no login
// App\Http\Controllers\Auth\AuthenticatedSessionController
public function store(LoginRequest $request): RedirectResponse
{
    $request->authenticate();
    $request->session()->regenerate(); // CRÍTICO: previne fixação de sessão
    return redirect()->intended(RouteServiceProvider::HOME);
}

// Invalidar sessão no logout
public function destroy(Request $request): RedirectResponse
{
    Auth::guard('web')->logout();
    $request->session()->invalidate();
    $request->session()->regenerateToken();
    return redirect('/');
}

Autorização

Gates

// App\Providers\AuthServiceProvider
use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Gate;

public function boot(): void
{
    Gate::define('update-post', function (User $user, Post $post): bool {
        return $user->id === $post->user_id;
    });

    Gate::define('publish-post', function (User $user): bool {
        return $user->role === 'editor' || $user->role === 'admin';
    });

    // Usando before() para sobrescrita de super-admin
    Gate::before(function (User $user, string $ability): ?bool {
        if ($user->role === 'super-admin') {
            return true; // Concede todas as habilidades
        }
        return null; // Continua para verificações normais
    });
}

// Uso em controllers
public function update(Request $request, Post $post): RedirectResponse
{
    Gate::authorize('update-post', $post);
    // Ou: $this->authorize('update-post', $post);
    // Ou: abort_unless(Auth::user()->can('update-post', $post), 403);
    // ...
}

Policies

// App\Policies\PostPolicy
class PostPolicy
{
    use HandlesAuthorization;

    public function viewAny(?User $user): bool
    {
        return true; // Listagem pública
    }

    public function view(?User $user, Post $post): bool
    {
        return $post->is_published || ($user && $user->id === $post->user_id);
    }

    public function create(User $user): bool
    {
        return $user->hasVerifiedEmail(); // Deve verificar email primeiro
    }

    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }

    public function delete(User $user, Post $post): bool
    {
        return $user->id === $post->user_id && $post->created_at->diffInDays(now()) <= 30;
    }

    public function restore(User $user, Post $post): bool
    {
        return $user->role === 'admin';
    }

    public function forceDelete(User $user, Post $post): bool
    {
        return $user->role === 'super-admin';
    }
}

// Registrar em AuthServiceProvider
protected $policies = [
    Post::class => PostPolicy::class,
];

// Uso em controller
public function show(Post $post): View
{
    $this->authorize('view', $post);
    return view('posts.show', compact('post'));
}

// Uso no Blade
@can('update', $post)
    <a href="{{ route('posts.edit', $post) }}">Editar</a>
@endcan

@cannot('update', $post)
    <span>Você não pode editar este post</span>
@endcannot

Autorização via Middleware

// Usando middleware nas rotas
Route::put('/posts/{post}', [PostController::class, 'update'])
    ->middleware('can:update,post');

Route::get('/posts/create', [PostController::class, 'create'])
    ->middleware('can:create,App\Models\Post');

// Middleware de autorização personalizado
// app/Http/Middleware/CheckRole.php
class CheckRole
{
    public function handle(Request $request, Closure $next, string $role): mixed
    {
        if (!$request->user() || $request->user()->role !== $role) {
            abort(403, 'Não autorizado. Esta área requer a função: ' . $role);
        }
        return $next($request);
    }
}

// Registrar em Kernel
protected $routeMiddleware = [
    'role' => \App\Http\Middleware\CheckRole::class,
];

// Uso em rota
Route::middleware(['auth', 'role:admin'])->group(function () {
    Route::get('/admin', [AdminController::class, 'index']);
});

Segurança no Eloquent

Proteção contra Atribuição em Massa

// RUIM: $guarded = [] permite que TODAS as colunas sejam atribuídas em massa
// NUNCA use $guarded = [] em produção

// BOM: Lista branca de atributos fillable
final class User extends Authenticatable
{
    protected $fillable = [
        'name',
        'email',
        'phone',
        'avatar',
    ];
    // NUNCA adicione 'role', 'is_admin', 'is_verified' aqui
}

// BOM: Controle explícito de quais campos podem ser preenchidos nas requisições
public function store(StoreUserRequest $request): RedirectResponse
{
    $user = User::create($request->safe()->only([
        'name', 'email', 'phone', 'avatar'
    ]));
    // $request->safe() usa apenas dados validados
    // $request->only() NÃO é seguro por si só sem regras de validação
}

// RUIM: Criando usuário com dados da requisição diretamente
User::create($request->all()); // VULNERÁVEL a atribuição em massa!

// MELHOR: Use DTOs para criação
$user = User::create($request->validated()); // Apenas campos validados

Prevenção contra Injeção SQL

// BOM: Eloquent parametriza queries automaticamente
User::where('email', $userInput)->first();
User::whereRaw('email = ?', [$userInput])->first();

// BOM: Query Builder também parametriza
DB::table('users')->where('email', $userInput)->first();
DB::select('SELECT * FROM users WHERE email = ?', [$userInput]);

// RUIM: Interpolação direta de string
DB::select("SELECT * FROM users WHERE email = '{$userInput}'"); // VULNERÁVEL!
User::whereRaw("email = '{$userInput}'")->first(); // VULNERÁVEL!

// RUIM: whereRaw/orderByRaw com entrada sem escape
User::orderByRaw($userInput); // VULNERÁVEL!
User::groupByRaw($userInput); // VULNERÁVEL!

// RUIM: DB::statement com concatenação
DB::statement("INSERT INTO users (email) VALUES ('{$userInput}')"); // VULNERÁVEL!

Casting de Atributos

final class User extends Authenticatable
{
    protected $casts = [
        'email_verified_at' => 'datetime',
        'is_admin' => 'boolean', // Cast para booleano previne injeção de string
        'settings' => 'array', // Automaticamente json_encode/json_decode
        'metadata' => 'encrypted:array', // Laravel 11+ casting criptografado
        'password' => 'hashed', // Laravel 10+ auto-hash ao definir
    ];
}

Segurança do Modelo

final class User extends Authenticatable
{
    // Ocultar atributos sensíveis de respostas JSON/API
    protected $hidden = [
        'password',
        'remember_token',
        'two_factor_secret',
        'two_factor_recovery_codes',
    ];

    // Adicionar apenas atributos computados seguros
    protected $appends = ['full_name']; // seguro
    // NUNCA adicionar dados computados sensíveis
}

final class Post extends Model
{
    // Escopo global para filtrar registros com soft delete
    use SoftDeletes;

    // Prevenir N+1 restringindo lazy loading (modo estrito opcional)
    // AppServiceProvider::boot()
    // Model::preventLazyLoading(!app()->isProduction());
}

Proteção CSRF

Proteção Padrão

// CSRF do Laravel está habilitado por padrão via middleware VerifyCsrfToken
// app/Http/Kernel.php (protected $middlewareGroups['web'])

// Todos os formulários POST/PUT/PATCH/DELETE devem incluir @csrf
<form method="POST" action="/posts">
    @csrf
    <input type="text" name="title">
    <button type="submit">Criar</button>
</form>

Excluindo Rotas (Com Cuidado)

// app/Http/Middleware/VerifyCsrfToken.php
class VerifyCsrfToken extends Middleware
{
    // Apenas exclua rotas que têm proteção CSRF externa (webhooks, etc.)
    protected $except = [
        'stripe/*', // Webhooks do Stripe usam sua própria verificação de assinatura
        // Evite 'api/*' genérico — rotas stateful do Sanctum precisam de CSRF.
        // Exclua apenas rotas específicas de webhook/endpoint stateless.
    ];
}

CSRF com JavaScript

<meta name="csrf-token" content="{{ csrf_token() }}">

<script>
// Exemplo com Axios (Laravel acompanha Axios)
axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector(
    'meta[name="csrf-token"]'
).getAttribute('content');

// Exemplo com Fetch
fetch('/posts', {
    method: 'POST',
    headers: {
        'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
        'Content-Type': 'application/json',
    },
    body: JSON.stringify(data),
});
</script>

Prevenção de XSS

Segurança no Blade Templating

{{-- SEGURO: Escapado automaticamente pelo Blade --}}
{{ $userInput }}

{{-- PERIGOSO: Saída bruta — NUNCA use com entrada do usuário --}}
{!! $userInput !!}

{{-- SEGURO: Use {!! !!} apenas com conteúdo confiável que você controla --}}
{!! $trustedHtmlFromYourServer !!}

{{-- BOM: Use diretivas de escape específicas --}}
@js($data) {{-- Codifica JSON para JavaScript --}}
@json($data) {{-- Codifica JSON em templates --}}

{{-- RUIM: Entrada direta do usuário em HTML bruto --}}
<div>{!! $user->bio !!}</div> {{-- VULNERÁVEL se usuário fornece bio --}}

Manipulação Segura de HTML

// Quando precisar permitir algum HTML, use uma abordagem de lista branca
use HTMLPurifier; // Requer: composer require ezyang/htmlpurifier

public function sanitizeHtml(string $dirty): string
{
    $config = \HTMLPurifier_Config::createDefault();
    $config->set('HTML.Allowed', 'p,b,i,a[href],ul,ol,li,br');
    $config->set('URI.AllowedSchemes', ['http', 'https', 'mailto']);
    $purifier = new \HTMLPurifier($config);
    return $purifier->purify($dirty);
}

// No blade:
<div>{!! $sanitizedHtml !!}</div>

Content Security Policy (CSP)

// app/Http/Middleware/CspMiddleware.php
class CspMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);
        
        if (!app()->environment('production')) {
            return $response;
        }

        $response->headers->set('Content-Security-Policy', implode('; ', [
            "default-src 'self'",
            "script-src 'self' 'nonce-" . base64_encode(random_bytes(16)) . "'",
            "style-src 'self' 'unsafe-inline'",
            "img-src 'self' data: https:",
            "font-src 'self'",
            "form-action 'self'",
            "frame-ancestors 'none'",
            "base-uri 'self'",
        ]));

        return $response;
    }
}

// Registrar em Kernel
protected $middleware = [
    \App\Http\Middleware\CspMiddleware::class,
];

Segurança de API

Rate Limiting

// app/Http/Kernel.php ou specific route files

// Definir limitadores de taxa
RateLimiter::for('api', function (Request $request) {
    return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});

RateLimiter::for('login', function (Request $request) {
    return Limit::perMinute(5)->by($request->input('email') . '|' . $request->ip());
});

RateLimiter::for('register', function (Request $request) {
    return Limit::perHour(3)->by($request->ip());
});

// Usar em rotas
Route::middleware(['throttle:api'])->group(function () {
    Route::get('/user', function () { /* ... */ });
});

Route::post('/login', [LoginController::class, 'store'])
    ->middleware('throttle:login');

CORS (Cross-Origin Resource Sharing)

// config/cors.php
return [
    'paths' => ['api/*', 'sanctum/csrf-cookie'],
    'allowed_methods' => ['*'],
    'allowed_origins' => env('CORS_ALLOWED_ORIGINS')
        ? explode(',', env('CORS_ALLOWED_ORIGINS'))
        : [env('APP_FRONTEND_URL', 'http://localhost:3000')],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true, // Necessário para Sanctum SPA
];

Headers de Resposta de Segurança

// app/Http/Middleware/SecurityHeadersMiddleware.php
class SecurityHeadersMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);

        $response->headers->set('X-Content-Type-Options', 'nosniff');
        $response->headers->set('X-Frame-Options', 'DENY');
        $response->headers->set('X-XSS-Protection', '0'); // Desativar legado
        $response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
        $response->headers->set('Permissions-Policy', implode(', ', [
            'camera=()',
            'microphone=()',
            'geolocation=()',
        ]));
        
        // HSTS (Apenas HTTPS): Descomente após confirmar HTTPS
        // $response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');

        return $response;
    }
}

Validação de Entrada de API

// app/Http/Requests/StoreOrderRequest.php
class StoreOrderRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'items' => ['required', 'array', 'min:1', 'max:50'],
            'items.*.product_id' => ['required', 'exists:products,id', 'integer'],
            'items.*.quantity' => ['required', 'integer', 'min:1', 'max:100'],
            'shipping_address' => ['required', 'string', 'max:500'],
            'payment_method' => ['required', Rule::in(['credit_card', 'paypal', 'stripe'])],
            'coupon_code' => ['nullable', 'string', 'max:20', 'exists:coupons,code'],
        ];
    }

    public function messages(): array
    {
        return [
            'items.*.product_id.exists' => 'Um ou mais produtos são inválidos.',
            'items.max' => 'Máximo de :max itens por pedido.',
        ];
    }

    protected function failedValidation(Validator $validator)
    {
        // Responder com JSON estruturado para APIs
        throw new HttpResponseException(response()->json([
            'message' => 'Erro de validação.',
            'errors' => $validator->errors(),
        ], 422));
    }
}

Configuração Segura de Deploy

Checklist de Ambiente

  • APP_DEBUG está false
  • APP_ENV está production
  • APP_KEY está definido (gerado via php artisan key:generate)
  • HTTPS está forçado em produção
  • Cookies de sessão são secure, http_only, same_site=lax
  • .env nunca é commitado
  • CORS está restrito a origens confiáveis
  • Rate limiting está configurado para endpoints de API
  • Headers de segurança estão aplicados via middleware
  • Cache de configuração: php artisan config:cache
  • Cache de rotas: php artisan route:cache
  • Debug bar removida ou desativada em produção
  • Logs de erro não são expostos ao usuário final

Configuração de Cache

# Otimizar para produção — execute como parte do script de deploy
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache

# Limpar cache após atualizações de configuração
php artisan optimize:clear

Configuração de Banco de Dados

// config/database.php
// Usar variáveis de ambiente apenas, nunca valores fixos
'mysql' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => true, // Modo estrito do MySQL
    'engine' => 'InnoDB', // Sempre usar InnoDB para integridade referencial
    'options' => extension_loaded('pdo_mysql') ? array_filter([
        PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
        PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true,
    ]) : [],
],

Dependências e Atualizações

Monitoramento de Vulnerabilidades

# Verificar dependências em busca de vulnerabilidades conhecidas
composer audit

# Ou usar ferramentas SaaS:
# - GitHub Dependabot
# - GitLab Dependency Scan
# - Snyk
# - Laravel Forge (inclui segurança)

# Atualizar dependências regularmente
composer update --no-dev -W

Versões Suportadas do Laravel

  • Sempre use a versão mais recente estável do Laravel
  • Aplique patches de segurança prontamente
  • Monitore o Laravel Security Advisories
  • Teste atualizações em staging antes do deploy para produção

Leitura Adicional

Individual skills in this repo

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

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

Habilidades Relacionadas