{
    "schema": "https://saferpage.de/schemas/dach-crawler-timer-runner.v1",
    "generated_at": "2026-06-09T21:18:01+00:00",
    "available": true,
    "health": "operational",
    "summary": "Crawler-Timer-Runner: systemd alle 30 Minuten, maximal 8 Hosts pro Lauf, 702 DACH-/DE-Checks, Queue 626, letzter Batch 8 Host(s), Fehlerquote 2,95%.",
    "metrics": {
        "gate_count": 11,
        "passed_gate_count": 11,
        "warning_gate_count": 0,
        "blocked_gate_count": 0,
        "german_count": 702,
        "queue_count": 626,
        "visited_count": 921,
        "skipped_count": 194,
        "error_count": 28,
        "error_rate_percent": 2.95,
        "last_batch_scanned": 8,
        "last_run_refreshed": 0,
        "last_run_refresh_candidates": 0,
        "seed_file_host_count": 86,
        "seed_host_count": 110,
        "seed_new_count": 0,
        "seed_existing_count": 110,
        "seed_queue_added_count": 0,
        "recent_report_count": 36,
        "queue_preview_count": 12,
        "run_history_count": 10
    },
    "timer_contract": {
        "manager": "systemd",
        "unit": "saferpage-crawler.service",
        "timer": "saferpage-crawler.timer",
        "on_boot_after": "10min",
        "cadence": "30min after previous unit activation",
        "randomized_delay": "8min",
        "persistent": true,
        "service_exec_summary": "python3 scripts/crawl-german-sites.py --from-recent --seed-file config/dach-seed-domains.txt --refresh-days 7 --refresh-limit 2000 --max 8 --concurrency 2 --timeout 90 --delay 1",
        "resource_policy": "Nice=10 und IO-Scheduling im systemd-Service; kleine Batches statt breiter Crawls."
    },
    "execution_policy": {
        "max_hosts_per_run": 8,
        "concurrency": 2,
        "timeout_seconds": 90,
        "delay_between_batches_seconds": 1,
        "refresh_days": 7,
        "refresh_limit": 2000,
        "market_focus": "deutschsprachiger Raum: .de, .at, .ch, .li, .lu und relevante deutschsprachige Inhalte.",
        "user_agent": "SaferPageCrawler/0.3 (+https://saferpage.de/bot; schedules passive DACH website checks; report examples: https://saferpage.de/tests)",
        "robots_policy": "SaferPageCrawler respektiert robots.txt; Betreiber finden Opt-out und Zweck unter /bot.",
        "browser_policy": "Headless Chromium nur fuer Screenshot-, Cookie-, Storage- und Consent-Nachweise, nicht fuer jeden Link blind.",
        "canonical_report_policy": "Jeder gespeicherte Check wird unter /{domain} verlinkt; keine .php-Reportlinks und keine Duplicate-Content-Varianten."
    },
    "seed_manifest": {
        "generated_at": "2026-06-09T20:51:46+00:00",
        "seed_file": "config/dach-seed-domains.txt",
        "seed_file_host_count": 86,
        "cli_seed_count": 0,
        "recent_seed_count": 24,
        "seed_host_count": 110,
        "seed_new_count": 0,
        "seed_existing_count": 110,
        "seed_queue_added_count": 0,
        "refresh_candidate_count": 0,
        "include_generic": false,
        "market_tlds": [
            ".de",
            ".at",
            ".ch",
            ".li",
            ".lu"
        ],
        "source_policy": "Versioned DACH seed file plus recent public checks; bounded timer batch keeps discovery controlled.",
        "seed_preview": [
            "7sentidos.de",
            "abokiste24.de",
            "adac.de",
            "adlerkroenert.de",
            "aldi-sued.de",
            "alter-pflege-demenz-nrw.de",
            "angel-minerals.de",
            "aok.de",
            "apo-coach.de",
            "araonline.de",
            "arbeitsagentur.de",
            "awa7.de",
            "ayurveda-tut-gut.de",
            "bahn.de",
            "barmer.de",
            "berlin.de",
            "bfdi.bund.de",
            "bmw.de",
            "br.de",
            "bremen.de",
            "bsi.bund.de",
            "bund.de",
            "bundesnetzagentur.de",
            "bundesregierung.de"
        ]
    },
    "readiness_gates": [
        {
            "id": "state_available",
            "label": "Runner-State erreichbar",
            "status": "passed",
            "evidence": "Die lokale Crawler-API liefert Queue, Laufhistorie und Fehlerstatus.",
            "action": "Bei blocked: API-Service, Port 8092 und Crawler-State prüfen."
        },
        {
            "id": "recent_run_recorded",
            "label": "Letzter Lauf protokolliert",
            "status": "passed",
            "evidence": "finished_at=2026-06-09T20:52:49+00:00",
            "action": "Timer manuell prüfen und nach dem nächsten Lauf erneut abrufen."
        },
        {
            "id": "schedule_contract_present",
            "label": "systemd-Timer-Vertrag vorhanden",
            "status": "passed",
            "evidence": "saferpage-crawler.timer: OnBootSec=10min, OnUnitActiveSec=30min, RandomizedDelaySec=8min, Persistent=true.",
            "action": "Nach Deploy mit systemctl list-timers saferpage-crawler.timer verifizieren."
        },
        {
            "id": "bounded_batch",
            "label": "Batch und Parallelität begrenzt",
            "status": "passed",
            "evidence": "max=8, concurrency=2, timeout=90s.",
            "action": "Grenzen nur nach Last-, Fehler- und robots.txt-Auswertung erhöhen."
        },
        {
            "id": "versioned_seed_source",
            "label": "Versionierte DACH-Seedquelle",
            "status": "passed",
            "evidence": "config/dach-seed-domains.txt: 86 Host(s), 0 neu in der Queue.",
            "action": "Timer mit --seed-file config/dach-seed-domains.txt laufen lassen und Runner-State erneut prüfen."
        },
        {
            "id": "public_user_agent",
            "label": "User-Agent mit Betreiberlink",
            "status": "passed",
            "evidence": "SaferPageCrawler/0.3 (+https://saferpage.de/bot; schedules passive DACH website checks; report examples: https://saferpage.de/tests)",
            "action": "User-Agent muss /bot und Beispielreports nennen."
        },
        {
            "id": "robots_policy",
            "label": "robots.txt-Respekt",
            "status": "passed",
            "evidence": "Runner nutzt einen eigenen SaferPageCrawler und dokumentiert Opt-out unter /bot und /crawler.",
            "action": "Bei erhöhter Skiprate Seed-Liste und robots.txt-Regeln prüfen."
        },
        {
            "id": "error_rate_guard",
            "label": "Fehlerquote unter Stop-Schwelle",
            "status": "passed",
            "evidence": "2,95% bei 28 Fehlern.",
            "action": "Über 20 Prozent: Timeout, DNS, API-Log und robots.txt-Skiprate prüfen, Parallelität nicht erhöhen."
        },
        {
            "id": "queue_pressure_guard",
            "label": "Queue-Druck kontrolliert",
            "status": "passed",
            "evidence": "626 Hosts in der Queue.",
            "action": "Bei hoher Queue zusätzliche Seeds priorisieren und Batchgröße erst nach Lastprüfung erhöhen."
        },
        {
            "id": "recent_reports_linked",
            "label": "Zuletzt geprüfte Reports verlinkt",
            "status": "passed",
            "evidence": "36 direkte Kurz-URL-Links im Export.",
            "action": "Recent-Checks und Sitemap prüfen, wenn keine Links erscheinen."
        },
        {
            "id": "no_secret_export",
            "label": "No-Secret-/No-Visitor-Log-Export",
            "status": "passed",
            "evidence": "Der Timer-Runner-Export enthält Betriebsdaten, Reportlinks und Runbook, aber keine Secrets oder Besucherlogs.",
            "action": "Neue Felder vor Veröffentlichung auf Rohpayloads, IPs und Tokens prüfen."
        }
    ],
    "last_run": {
        "started_at": "2026-06-09T20:51:46+00:00",
        "finished_at": "2026-06-09T20:52:49+00:00",
        "scanned": 8,
        "queued_after_run": 626,
        "refreshed": 0,
        "refresh_candidates": 0,
        "errors": 28,
        "include_generic": false,
        "user_agent": "SaferPageCrawler/0.3 (+https://saferpage.de/bot; schedules passive DACH website checks; report examples: https://saferpage.de/tests)"
    },
    "run_history": [
        {
            "started_at": "2026-06-09T15:58:47+00:00",
            "finished_at": "2026-06-09T15:59:46+00:00",
            "scanned": 8,
            "refreshed": 0,
            "queued": 579,
            "german": 658,
            "errors": 30
        },
        {
            "started_at": "2026-06-09T16:30:24+00:00",
            "finished_at": "2026-06-09T16:31:40+00:00",
            "scanned": 8,
            "refreshed": 0,
            "queued": 574,
            "german": 663,
            "errors": 28
        },
        {
            "started_at": "2026-06-09T17:02:27+00:00",
            "finished_at": "2026-06-09T17:03:09+00:00",
            "scanned": 8,
            "refreshed": 0,
            "queued": 583,
            "german": 669,
            "errors": 27
        },
        {
            "started_at": "2026-06-09T17:37:19+00:00",
            "finished_at": "2026-06-09T17:38:10+00:00",
            "scanned": 8,
            "refreshed": 0,
            "queued": 580,
            "german": 672,
            "errors": 28
        },
        {
            "started_at": "2026-06-09T18:10:09+00:00",
            "finished_at": "2026-06-09T18:11:01+00:00",
            "scanned": 8,
            "refreshed": 0,
            "queued": 575,
            "german": 678,
            "errors": 26
        },
        {
            "started_at": "2026-06-09T18:40:16+00:00",
            "finished_at": "2026-06-09T18:41:55+00:00",
            "scanned": 8,
            "refreshed": 0,
            "queued": 577,
            "german": 683,
            "errors": 26
        },
        {
            "started_at": "2026-06-09T19:10:22+00:00",
            "finished_at": "2026-06-09T19:11:17+00:00",
            "scanned": 8,
            "refreshed": 0,
            "queued": 572,
            "german": 687,
            "errors": 26
        },
        {
            "started_at": "2026-06-09T19:44:07+00:00",
            "finished_at": "2026-06-09T19:44:57+00:00",
            "scanned": 8,
            "refreshed": 0,
            "queued": 589,
            "german": 692,
            "errors": 26
        },
        {
            "started_at": "2026-06-09T20:17:10+00:00",
            "finished_at": "2026-06-09T20:18:48+00:00",
            "scanned": 8,
            "refreshed": 0,
            "queued": 641,
            "german": 698,
            "errors": 28
        },
        {
            "started_at": "2026-06-09T20:51:46+00:00",
            "finished_at": "2026-06-09T20:52:49+00:00",
            "scanned": 8,
            "refreshed": 0,
            "queued": 626,
            "german": 702,
            "errors": 28
        }
    ],
    "queue_preview": [
        {
            "host": "blowerdoor-unlimited.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/blowerdoor-unlimited.de"
        },
        {
            "host": "bund-stuttgart.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/bund-stuttgart.de"
        },
        {
            "host": "bund.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/bund.de"
        },
        {
            "host": "bundesnetzagentur.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/bundesnetzagentur.de"
        },
        {
            "host": "bundesregierung.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/bundesregierung.de"
        },
        {
            "host": "bundestag.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/bundestag.de"
        },
        {
            "host": "check24.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/check24.de"
        },
        {
            "host": "comdirect.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/comdirect.de"
        },
        {
            "host": "connect.haendlerbund.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/connect.haendlerbund.de"
        },
        {
            "host": "consolar.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/consolar.de"
        },
        {
            "host": "dasguteruft.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/dasguteruft.de"
        },
        {
            "host": "datev.de",
            "priority": "de_first",
            "report_url": "https://saferpage.de/datev.de"
        }
    ],
    "recent_reports": [
        {
            "host": "agf.de",
            "score": 0,
            "checked_at": "2026-06-09 23:11:34.698281+02",
            "report_url": "https://saferpage.de/agf.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "agb.lexware.de",
            "score": 0,
            "checked_at": "2026-06-09 23:11:28.08091+02",
            "report_url": "https://saferpage.de/agb.lexware.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "aerztezeitung.de",
            "score": 0,
            "checked_at": "2026-06-09 23:11:22.129763+02",
            "report_url": "https://saferpage.de/aerztezeitung.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "afgis.de",
            "score": 0,
            "checked_at": "2026-06-09 23:11:19.340955+02",
            "report_url": "https://saferpage.de/afgis.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "adfc.de",
            "score": 0,
            "checked_at": "2026-06-09 23:11:10.920311+02",
            "report_url": "https://saferpage.de/adfc.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "admin.verwaltungsportal.de",
            "score": 0,
            "checked_at": "2026-06-09 23:11:10.895294+02",
            "report_url": "https://saferpage.de/admin.verwaltungsportal.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "admin.dsv.de",
            "score": 0,
            "checked_at": "2026-06-09 23:11:06.238586+02",
            "report_url": "https://saferpage.de/admin.dsv.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "adenauercampus.de",
            "score": 0,
            "checked_at": "2026-06-09 23:11:00.861933+02",
            "report_url": "https://saferpage.de/adenauercampus.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "addf-kassel.de",
            "score": 0,
            "checked_at": "2026-06-09 23:10:48.475719+02",
            "report_url": "https://saferpage.de/addf-kassel.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "adacreisen.de",
            "score": 0,
            "checked_at": "2026-06-09 23:10:39.632691+02",
            "report_url": "https://saferpage.de/adacreisen.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "adac.de",
            "score": 0,
            "checked_at": "2026-06-09 23:10:36.668593+02",
            "report_url": "https://saferpage.de/adac.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "accounts.ard.de",
            "score": 0,
            "checked_at": "2026-06-09 23:10:29.252439+02",
            "report_url": "https://saferpage.de/accounts.ard.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "absolventa.de",
            "score": 0,
            "checked_at": "2026-06-09 23:10:26.882458+02",
            "report_url": "https://saferpage.de/absolventa.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "account.golem.de",
            "score": 8,
            "checked_at": "2026-06-09 23:10:24.117167+02",
            "report_url": "https://saferpage.de/account.golem.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "academy.brigitte.de",
            "score": 0,
            "checked_at": "2026-06-09 23:10:18.90859+02",
            "report_url": "https://saferpage.de/academy.brigitte.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "about.alex-berlin.de",
            "score": 0,
            "checked_at": "2026-06-09 23:10:08.020377+02",
            "report_url": "https://saferpage.de/about.alex-berlin.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "abo.spiegel.de",
            "score": 0,
            "checked_at": "2026-06-09 23:10:01.81453+02",
            "report_url": "https://saferpage.de/abo.spiegel.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "aboshop.harzkurier.de",
            "score": 0,
            "checked_at": "2026-06-09 23:09:56.458128+02",
            "report_url": "https://saferpage.de/aboshop.harzkurier.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "aboshop.morgenpost.de",
            "score": 0,
            "checked_at": "2026-06-09 23:09:56.139573+02",
            "report_url": "https://saferpage.de/aboshop.morgenpost.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "aboservice.harzkurier.de",
            "score": 0,
            "checked_at": "2026-06-09 23:09:46.647636+02",
            "report_url": "https://saferpage.de/aboservice.harzkurier.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "aboservice.morgenpost.de",
            "score": 0,
            "checked_at": "2026-06-09 23:09:46.564563+02",
            "report_url": "https://saferpage.de/aboservice.morgenpost.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "abo.manager-magazin.de",
            "score": 0,
            "checked_at": "2026-06-09 23:09:36.553675+02",
            "report_url": "https://saferpage.de/abo.manager-magazin.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "abendblatt.de",
            "score": 0,
            "checked_at": "2026-06-09 23:09:36.49675+02",
            "report_url": "https://saferpage.de/abendblatt.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "abo.11freunde.de",
            "score": 0,
            "checked_at": "2026-06-09 23:09:28.648473+02",
            "report_url": "https://saferpage.de/abo.11freunde.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "abda.de",
            "score": 0,
            "checked_at": "2026-06-09 23:03:11.003686+02",
            "report_url": "https://saferpage.de/abda.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "4p.de",
            "score": 0,
            "checked_at": "2026-06-09 23:01:30.442858+02",
            "report_url": "https://saferpage.de/4p.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "4players.de",
            "score": 0,
            "checked_at": "2026-06-09 23:01:28.967551+02",
            "report_url": "https://saferpage.de/4players.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "3sat.de",
            "score": 0,
            "checked_at": "2026-06-09 23:01:17.194518+02",
            "report_url": "https://saferpage.de/3sat.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "2020.demokratie-leben.de",
            "score": 0,
            "checked_at": "2026-06-09 23:01:10.543797+02",
            "report_url": "https://saferpage.de/2020.demokratie-leben.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "1.ard.de",
            "score": 0,
            "checked_at": "2026-06-09 23:01:03.318094+02",
            "report_url": "https://saferpage.de/1.ard.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "11freunde.de",
            "score": 0,
            "checked_at": "2026-06-09 23:01:00.841181+02",
            "report_url": "https://saferpage.de/11freunde.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "116117-termine.de",
            "score": 32,
            "checked_at": "2026-06-09 23:00:54.308395+02",
            "report_url": "https://saferpage.de/116117-termine.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "115.de",
            "score": 0,
            "checked_at": "2026-06-09 23:00:52.433977+02",
            "report_url": "https://saferpage.de/115.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "116117.de",
            "score": 0,
            "checked_at": "2026-06-09 23:00:49.001713+02",
            "report_url": "https://saferpage.de/116117.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "blowerdoor.de",
            "score": 0,
            "checked_at": "2026-06-09 22:52:49.448603+02",
            "report_url": "https://saferpage.de/blowerdoor.de",
            "summary": "Nur mit Vorsicht nutzen"
        },
        {
            "host": "bio-tierkost.de",
            "score": 0,
            "checked_at": "2026-06-09 22:52:34.943049+02",
            "report_url": "https://saferpage.de/bio-tierkost.de",
            "summary": "Nur mit Vorsicht nutzen"
        }
    ],
    "error_preview": [
        {
            "host": "otto.de",
            "error": "Remote end closed connection without response",
            "at": "2026-06-07T06:02:10+00:00",
            "report_url": "https://saferpage.de/otto.de"
        },
        {
            "host": "live.manager-magazin.de",
            "error": "Remote end closed connection without response",
            "at": "2026-06-07T08:21:25+00:00",
            "report_url": "https://saferpage.de/live.manager-magazin.de"
        },
        {
            "host": "kurs.manage-forward.de",
            "error": "Remote end closed connection without response",
            "at": "2026-06-07T08:21:25+00:00",
            "report_url": "https://saferpage.de/kurs.manage-forward.de"
        },
        {
            "host": "mobile-university-fernstudium.de",
            "error": "<urlopen error [Errno 111] Connection refused>",
            "at": "2026-06-07T08:21:28+00:00",
            "report_url": "https://saferpage.de/mobile-university-fernstudium.de"
        },
        {
            "host": "mobile-university.de",
            "error": "<urlopen error [Errno 111] Connection refused>",
            "at": "2026-06-07T08:21:28+00:00",
            "report_url": "https://saferpage.de/mobile-university.de"
        },
        {
            "host": "reisewelt.spiegel.de",
            "error": "<urlopen error [Errno 111] Connection refused>",
            "at": "2026-06-07T08:21:29+00:00",
            "report_url": "https://saferpage.de/reisewelt.spiegel.de"
        },
        {
            "host": "presseportal-fuer-schulen.de",
            "error": "<urlopen error [Errno 111] Connection refused>",
            "at": "2026-06-07T08:21:30+00:00",
            "report_url": "https://saferpage.de/presseportal-fuer-schulen.de"
        },
        {
            "host": "leading-medicine-guide.de",
            "error": "Remote end closed connection without response",
            "at": "2026-06-07T09:33:01+00:00",
            "report_url": "https://saferpage.de/leading-medicine-guide.de"
        },
        {
            "host": "promoting-fsnd.de",
            "error": "Remote end closed connection without response",
            "at": "2026-06-07T10:08:24+00:00",
            "report_url": "https://saferpage.de/promoting-fsnd.de"
        },
        {
            "host": "shop.t3n.de",
            "error": "Remote end closed connection without response",
            "at": "2026-06-07T10:08:24+00:00",
            "report_url": "https://saferpage.de/shop.t3n.de"
        },
        {
            "host": "taz.de",
            "error": "<urlopen error [Errno 111] Connection refused>",
            "at": "2026-06-07T10:08:25+00:00",
            "report_url": "https://saferpage.de/taz.de"
        },
        {
            "host": "telepolis.de",
            "error": "<urlopen error [Errno 111] Connection refused>",
            "at": "2026-06-07T10:08:25+00:00",
            "report_url": "https://saferpage.de/telepolis.de"
        }
    ],
    "operations_runbook": {
        "purpose": "Nachweis fuer geplante, begrenzte und datenschutzschonende DACH-Recrawls mit direkter Report-Verlinkung.",
        "systemd_checks": [
            {
                "label": "Timer sichtbar",
                "command": "systemctl list-timers saferpage-crawler.timer --no-pager",
                "expected": "NEXT, LAST und saferpage-crawler.timer sind sichtbar."
            },
            {
                "label": "Service-Vertrag",
                "command": "systemctl cat saferpage-crawler.service saferpage-crawler.timer --no-pager",
                "expected": "ExecStart enthaelt --seed-file config/dach-seed-domains.txt, --max 8, --concurrency 2, --timeout 90, --delay 1; Timer enthaelt OnUnitActiveSec=30min."
            },
            {
                "label": "Letzte Logs",
                "command": "journalctl -u saferpage-crawler.service -n 80 --no-pager",
                "expected": "Abschluss mit scanned/refreshed/errors; keine Secret- oder Besucherlog-Ausgabe."
            },
            {
                "label": "Oeffentlicher Runner-State",
                "command": "curl -fsS https://saferpage.de/crawler/timer-runner-json",
                "expected": "JSON enthaelt metrics, readiness_gates, last_run, recent_reports und queue_preview."
            }
        ],
        "operator_sequence": [
            "Vor Seed-Ausbau /crawler/timer-runner-json und /crawler/ops-json pruefen.",
            "Versionierte DACH-Seedliste pflegen, dann mit kleiner Batchgroesse starten und Queue-/Fehlerquote beobachten.",
            "Parallelitaet nur erhoehen, wenn API-Latenz, Fehlerquote und robots.txt-Skiprate stabil bleiben.",
            "Alle gespeicherten Checks muessen in /tests, A-Z-Sitemaps und unter /{domain} erreichbar sein.",
            "Endnutzertexte im Report priorisieren Datenschutzrisiko, Tracking, Consent, Betreiberfix und Re-Scan-Link."
        ],
        "stop_conditions": [
            "Fehlerquote ueber 20 Prozent oder wiederholte DNS-/Timeout-Fehler.",
            "Queue ueber 5000 ohne Priorisierung oder ohne Betreiber-/Seed-Plan.",
            "robots.txt-Skiprate steigt sichtbar nach Seed-Import.",
            "Headless-Chromium-/Screenshot-Worker blockiert API-Antwortzeiten.",
            "Oeffentliche Exports enthalten Rohpayloads, interne Pfade, Tokens, IPs oder Besucherlogs.",
            "Reports sind nicht mehr ueber die kanonische Kurz-URL /{domain} erreichbar."
        ],
        "public_contract": [
            "Der Crawler identifiziert sich mit SaferPageCrawler und verweist auf /bot sowie /tests.",
            "Der Timer laeuft in kleinen Batches und priorisiert deutschsprachige Domains.",
            "Screenshots bleiben kleine Vorschauen im Report; der Runner-Export verlinkt Reports, speichert aber keine privaten Rohdaten.",
            "Betreiber koennen Abrufe per robots.txt blockieren.",
            "Crawler-Evidence ist als HTML, JSON, CSV und Markdown verfuegbar."
        ]
    },
    "links": {
        "html": "https://saferpage.de/crawler/timer-runner",
        "json": "https://saferpage.de/crawler/timer-runner-json",
        "csv": "https://saferpage.de/crawler/timer-runner-csv",
        "markdown": "https://saferpage.de/crawler/timer-runner-md",
        "crawler_ops": "https://saferpage.de/crawler/ops-json",
        "portfolio_schedule": "https://saferpage.de/portfolio/schedule-json",
        "portfolio_dispatch": "https://saferpage.de/portfolio/dispatch-json",
        "domain_intake": "https://saferpage.de/portfolio/domain-intake-json",
        "tests": "https://saferpage.de/tests",
        "bot": "https://saferpage.de/bot",
        "monitoring_feed": "https://saferpage.de/monitoring/feed.json",
        "comparison": "https://saferpage.de/vergleich/features-json"
    },
    "disclaimer": "Dieser Nachweis zeigt Timervertrag, Runner-State, Queue, letzte Reports und Betriebsregeln. Er veroeffentlicht keine Secrets, keine internen IPs, keine Rohpayloads und keine personenbezogenen Besucherlogs."
}
