$activation->state()->value, 'execute' => (bool) $this->option('execute'), 'depth' => 10, 'provider' => 'dataforseo']; if (! $this->option('execute')) { $base['status'] = 'dry_run'; $this->output($base); return self::SUCCESS; }try { $activation->assertPaid(true); $circuit->assertClosed(); $count = SerpOperationAudit::where('action', 'canary_executed')->where('created_at', '>=', now('UTC')->startOfDay())->count(); if ($count >= (int) config('serp.canary.daily_limit')) { throw new OperationBlockedException('canary_limit'); }$key = 'canary:'.now('UTC')->format('Y-m-d'); $budget->reserve($key, 'live'); $q = new SerpQuery((string) config('serp.canary.keyword'), 'google', (string) config('serp.canary.country'), (string) config('serp.canary.language'), (string) config('serp.canary.device'), 10); $started = microtime(true); $r = $providers->resolve('dataforseo')->search($q); $budget->reconcile($key, $r->cost, $r->referenceId); $circuit->success(); $audit->record('canary_executed', ['provider' => 'dataforseo', 'mode' => 'live', 'duration_ms' => (int) ((microtime(true) - $started) * 1000), 'result_count' => count($r->results)]); $base += ['status' => 'completed', 'result_count' => count($r->results), 'duration_ms' => (int) ((microtime(true) - $started) * 1000)]; $this->output($base); return self::SUCCESS; } catch (Throwable $e) { $base += ['status' => 'blocked_or_failed', 'category' => $e instanceof SerpProviderException ? $e->safeCode() : 'unexpected']; $this->output($base); return self::FAILURE; } } private function output(array $data): void { $this->option('json') ? $this->line(json_encode($data)) : $this->info('Canary: '.$data['status']); } }