# Laravel Telescope (dev-only) Local debugging dashboard for queries, jobs, mails, redis, events, exceptions. **Never registered in production.** ## Access - Local URL: - Auth requirement: authenticated user with `super_admin` role (Spatie Permission). The `viewTelescope` gate is the access control; even in `local`, only super_admin can view. ## Production safety — three-layer defense Crewli runs Laravel 11 (no `Kernel.php`; routing/schedule live in `bootstrap/app.php` + `routes/console.php`). The defense layers adapted to that layout are: 1. **`composer.json` `extra.laravel.dont-discover`** lists `laravel/telescope`, so Laravel's auto-discovery never registers the vendor `Laravel\Telescope\TelescopeServiceProvider`. After editing this list, run `php artisan package:discover` once to refresh `bootstrap/cache/packages.php`. 2. **`AppServiceProvider::register()`** gates manual registration to `local` + `testing` only, and registers BOTH the vendor provider (routes/migrations/publishing) and the project's `App\Providers\TelescopeServiceProvider` (gate + filter): ```php if ($this->app->environment('local', 'testing')) { $this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class); $this->app->register(\App\Providers\TelescopeServiceProvider::class); } ``` `bootstrap/providers.php` deliberately does NOT list either Telescope provider — both registrations live behind this environment gate. 3. **`.env` `TELESCOPE_ENABLED` flag.** `false` in `.env.example`. Runtime toggle that disables Telescope even when the providers are registered (e.g. to silence Telescope locally during a profiling session). If you ever see Telescope on production: revert immediately, audit the three layers above, and treat as a security incident. The dashboard exposes every query, payload, and job — including secrets in payloads. ### Verifying production safety ```bash APP_ENV=production php -r " require 'vendor/autoload.php'; \$app = require 'bootstrap/app.php'; \$app->make('Illuminate\Contracts\Console\Kernel')->bootstrap(); foreach (array_keys(\$app->getLoadedProviders()) as \$p) { if (stripos(\$p, 'telescope') !== false) echo 'LOADED: ' . \$p . PHP_EOL; } " ``` Expected output: nothing. Any line means a layer is breached. ## Pruning Scheduled in `routes/console.php` (Laravel 11 layout): ```php Schedule::command('telescope:prune --hours=48') ->daily() ->environments(['local', 'testing']); ``` 48-hour retention. Adjust if dev DB is filling up. ## What Telescope captures - All Eloquent queries with bindings + execution time (N+1 detection) - Background jobs with payload + status + retry history - Sent mails with rendered HTML + plaintext + recipient - Redis commands - Cache reads/writes - Events fired with listeners - Exceptions with stack traces - HTTP requests with headers + payload ## What NOT to use Telescope for - Production debugging — never enabled there - Long-term audit trails — Spatie ActivityLog handles that (see ARCH-FORM-BUILDER §17.1) - Performance benchmarking — use APM tools designed for it ## Disabling temporarily If Telescope is slowing down a specific dev workflow: ```bash TELESCOPE_ENABLED=false php artisan serve ``` Or set globally in `.env` and restart your server. Re-enable when done.