{
  "url": "https://www.boyfriendtv.com",
  "auditedAt": "2026-07-28T13:16:53.500Z",
  "mode": "report",
  "status": "blocked",
  "statusDetail": "Mandatory external age verification redirects to Agerify and requires a selfie or government ID. The audit did not submit personal identity data, so listing, video detail/playback, search, account, and post-consent templates remain unexamined.",
  "page": {
    "appType": "mpa",
    "framework": "Server-rendered MPA with jQuery and custom gate scripts",
    "notes": "Only the public age gate was reachable. The core adult-video site is intentionally gated."
  },
  "evidenceUsed": [
    "screenshot",
    "transition-video",
    "dom",
    "layout-metrics",
    "evaluate-probe",
    "trace",
    "har",
    "discoverability",
    "headers",
    "cookies",
    "trackers",
    "secrets",
    "images",
    "lighthouse",
    "curl"
  ],
  "guidanceConsulted": [
    "accessibility",
    "dark-mode",
    "declarative-dialog-popover-control",
    "html",
    "identify-heavy-scripts",
    "optimize-script-priority",
    "performance",
    "privacy",
    "security"
  ],
  "artifacts": [
    {
      "type": "screenshot",
      "path": "evidence/home-desktop.png",
      "caption": "Public age gate at desktop viewport",
      "condition": "desktop",
      "findingIds": [
        "F001",
        "F003",
        "F008"
      ]
    },
    {
      "type": "screenshot",
      "path": "evidence/home-mobile.png",
      "caption": "Responsive public age gate at 360x800",
      "condition": "viewport: 360x800",
      "findingIds": [
        "F003"
      ]
    },
    {
      "type": "screenshot",
      "path": "evidence/home-dark.png",
      "caption": "Gate under dark color-scheme preference",
      "condition": "prefers-color-scheme: dark",
      "findingIds": [
        "F001"
      ]
    },
    {
      "type": "screenshot",
      "path": "evidence/home-forced-colors.png",
      "caption": "Gate under forced colors/high contrast",
      "condition": "forced-colors: active; prefers-contrast: more",
      "findingIds": []
    },
    {
      "type": "dom",
      "path": "evidence/home-dom.json",
      "caption": "Rendered DOM and inline CSS for the public gate",
      "findingIds": [
        "F002",
        "F007",
        "F012",
        "F013",
        "F015"
      ]
    },
    {
      "type": "other",
      "path": "evidence/home-probe.json",
      "caption": "Metadata, links, focus, semantics, media, animation, and platform probe",
      "findingIds": [
        "F001",
        "F002",
        "F003",
        "F007",
        "F008",
        "F010",
        "F011",
        "F012",
        "F016"
      ]
    },
    {
      "type": "layout",
      "path": "evidence/home-mobile-layout.json",
      "caption": "Mobile overflow, CLS, and long-task observations",
      "condition": "viewport: 360x800",
      "findingIds": []
    },
    {
      "type": "lighthouse",
      "path": "evidence/lighthouse.json",
      "caption": "Lighthouse performance, accessibility, best-practices, and SEO evidence",
      "findingIds": [
        "F003",
        "F004",
        "F005",
        "F006",
        "F007",
        "F009",
        "F010",
        "F011",
        "F017"
      ]
    },
    {
      "type": "har",
      "path": "evidence/home.har",
      "caption": "Network capture for the public gate",
      "findingIds": [
        "F005",
        "F006",
        "F016",
        "F017"
      ]
    },
    {
      "type": "har-summary",
      "path": "evidence/home-summary.json",
      "caption": "Compact request, byte, dependency, and hygiene signals",
      "findingIds": [
        "F005",
        "F006",
        "F016",
        "F017"
      ]
    },
    {
      "type": "trace",
      "path": "evidence/home-trace.json",
      "caption": "DevTools performance trace for the gate",
      "findingIds": [
        "F004"
      ]
    },
    {
      "type": "trace-summary",
      "path": "evidence/home-trace-summary.json",
      "caption": "FCP/LCP and main-thread summary",
      "findingIds": [
        "F004"
      ]
    },
    {
      "type": "discoverability",
      "path": "evidence/discoverability.json",
      "caption": "Raw HTML versus rendered discoverability comparison",
      "findingIds": [
        "F015"
      ]
    },
    {
      "type": "screenshot",
      "path": "evidence/discoverability-rendered.png",
      "caption": "Browser-rendered discoverability view",
      "findingIds": []
    },
    {
      "type": "screenshot",
      "path": "evidence/discoverability-crawler.png",
      "caption": "No-JavaScript crawler view",
      "findingIds": [
        "F015"
      ]
    },
    {
      "type": "other",
      "path": "evidence/headers.json",
      "caption": "Security response-header inspection",
      "findingIds": [
        "F013",
        "F014"
      ]
    },
    {
      "type": "other",
      "path": "evidence/cookies.json",
      "caption": "Cookie security inspection",
      "findingIds": []
    },
    {
      "type": "other",
      "path": "evidence/trackers.json",
      "caption": "Third-party/tracker inspection",
      "findingIds": []
    },
    {
      "type": "other",
      "path": "evidence/secrets.json",
      "caption": "Client-exposed secret scan",
      "findingIds": []
    },
    {
      "type": "other",
      "path": "evidence/images.json",
      "caption": "Rendered image inspection",
      "findingIds": []
    },
    {
      "type": "other",
      "path": "evidence/robots.txt",
      "caption": "robots.txt response, which contains age-gate HTML",
      "findingIds": [
        "F010",
        "F011"
      ]
    },
    {
      "type": "other",
      "path": "evidence/sitemap.xml",
      "caption": "sitemap.xml retrieval, challenged by Cloudflare",
      "findingIds": [
        "F011"
      ]
    },
    {
      "type": "video",
      "path": "evidence/age-verification.mp4",
      "caption": "Attempted age-verification journey redirects to external verifier",
      "findingIds": [
        "F014"
      ]
    },
    {
      "type": "screenshot",
      "path": "evidence/age-verification-final.png",
      "caption": "Final frame showing selfie or ID verification requirement",
      "findingIds": [
        "F014"
      ]
    }
  ],
  "config": {
    "loaded": false
  },
  "coverage": {
    "catalogVersion": "modern-web-guidance@0.0.172",
    "catalogChecksum": "sha256:78ccfdb2d483f4c57d9dafed80fd86c6265585a56457c8dcfddc254b80fb44d7",
    "expected": 58,
    "recorded": 58,
    "judged": 31,
    "blocked": 27,
    "notRun": 0,
    "missing": 0,
    "unknown": 0,
    "duplicates": 0,
    "complete": false
  },
  "checkOutcomes": [
    {
      "principleId": "respect-user-preferences",
      "checkId": "respects-color-scheme",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "The normal and prefers-color-scheme: dark screenshots are visually identical, while the computed root color-scheme is \"normal\" and no preference-driven scheme is declared.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-desktop.png",
        "evidence/home-dark.png",
        "evidence/home-probe.json"
      ],
      "findingIds": [
        "F001"
      ]
    },
    {
      "principleId": "respect-user-preferences",
      "checkId": "respects-reduced-motion",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "The gate reports zero active animations and the reduced-motion-sensitive surface is static.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-probe.json"
      ]
    },
    {
      "principleId": "respect-user-preferences",
      "checkId": "respects-contrast",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "The forced-colors screenshot preserves all gate text, links, boundaries, and primary actions.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-forced-colors.png"
      ]
    },
    {
      "principleId": "implement-natural-interactions",
      "checkId": "view-transitions",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned a transition video of a route/state change shows whether it animates; the page source / ::view-transition usage corroborates. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Route, scroll, and gesture interactions exist behind mandatory external age verification, so representative interaction evidence could not be gathered.",
      "reason": "Route, scroll, and gesture interactions exist behind mandatory external age verification, so representative interaction evidence could not be gathered.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "implement-natural-interactions",
      "checkId": "scroll-driven-animations",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned source/CSS inspection for animation-timeline: scroll()/view(); a long-task / scroll-handler probe can flag the main-thread anti-pattern. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Route, scroll, and gesture interactions exist behind mandatory external age verification, so representative interaction evidence could not be gathered.",
      "reason": "Route, scroll, and gesture interactions exist behind mandatory external age verification, so representative interaction evidence could not be gathered.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "implement-natural-interactions",
      "checkId": "physical-gestures",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned CSS inspection for scroll-snap / overscroll-behavior / physics-based easing vs custom pointermove listeners. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Route, scroll, and gesture interactions exist behind mandatory external age verification, so representative interaction evidence could not be gathered.",
      "reason": "Route, scroll, and gesture interactions exist behind mandatory external age verification, so representative interaction evidence could not be gathered.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "provide-guided-navigation",
      "checkId": "scroll-state-aware-chrome",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned a transition video of scrolling, or CSS inspection for scroll-state container queries. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Navigation chrome and content routes are hidden behind mandatory external age verification; only the gate was observable.",
      "reason": "Navigation chrome and content routes are hidden behind mandatory external age verification; only the gate was observable.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "provide-guided-navigation",
      "checkId": "anchored-positioning",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned CSS inspection for anchor-name / position-anchor / position-try on overlays; a screenshot of an open overlay near a viewport edge can show drift. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Navigation chrome and content routes are hidden behind mandatory external age verification; only the gate was observable.",
      "reason": "Navigation chrome and content routes are hidden behind mandatory external age verification; only the gate was observable.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "provide-guided-navigation",
      "checkId": "directs-attention",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned CSS inspection for ::highlight / scroll-marker; a transition video can show whether attention is cued after navigation. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Navigation chrome and content routes are hidden behind mandatory external age verification; only the gate was observable.",
      "reason": "Navigation chrome and content routes are hidden behind mandatory external age verification; only the gate was observable.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "maximize-content-reduce-noise",
      "checkId": "no-intrusive-interruptions",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "The blocking surface is the legally purposeful age gate, is visually restrained, and does not layer ads or unrelated interruptions over it.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-desktop.png"
      ]
    },
    {
      "principleId": "maximize-content-reduce-noise",
      "checkId": "semantic-dismissible-primitives",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "DOM evidence shows #cbDocumentViewer and the chat panel as DIV elements with role=dialog; #cbDocumentViewer is not hidden even when visually closed.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-dom.json",
        "evidence/home-probe.json"
      ],
      "findingIds": [
        "F002"
      ]
    },
    {
      "principleId": "maximize-content-reduce-noise",
      "checkId": "reduced-chrome",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "The gate dedicates the viewport to age notice, verification, and login with minimal decorative chrome.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-desktop.png",
        "evidence/home-mobile.png"
      ]
    },
    {
      "principleId": "adapt-to-the-form-factor",
      "checkId": "responsive-no-horizontal-scroll",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "At 360x800, scrollWidth equals clientWidth (360 px), horizontal overflow is 0, and the gate reflows into one column.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-mobile-layout.json",
        "evidence/home-mobile.png"
      ]
    },
    {
      "principleId": "adapt-to-the-form-factor",
      "checkId": "component-level-responsiveness",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned CSS inspection for @container / container-type; a computed-style probe of the same component in a wide vs narrow container shows whether it adapts. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Representative reusable content components are behind the age-verification wall, preventing container-level comparison.",
      "reason": "Representative reusable content components are behind the age-verification wall, preventing container-level comparison.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "adapt-to-the-form-factor",
      "checkId": "input-modality-aware",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "The visible LOGIN control is an <a> without href. Calling focus() leaves document.activeElement elsewhere and its computed outline is none; Lighthouse also identifies it as a non-crawlable anchor.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-desktop.png",
        "evidence/home-mobile.png",
        "evidence/home-probe.json",
        "evidence/lighthouse.json"
      ],
      "findingIds": [
        "F003"
      ]
    },
    {
      "principleId": "support-core-task-success",
      "checkId": "clear-purpose-and-primary-action",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "The first viewport clearly states Adults Only Website and presents Accept & Verify age as the primary action.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-desktop.png",
        "evidence/home-mobile.png"
      ]
    },
    {
      "principleId": "support-core-task-success",
      "checkId": "primary-flow-completion",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned run the flow manually with screenshots/DOM snapshots at each step; compare expected vs actual path length; inspect form requirements, navigation continuity, and blockers. The model; attempted recon and the age-verification journey.",
      "evidence": "Attempting the primary action redirects to Agerify and requires a selfie or government ID; the audit did not submit personal identity data.",
      "reason": "Attempting the primary action redirects to Agerify and requires a selfie or government ID; the audit did not submit personal identity data.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "support-core-task-success",
      "checkId": "clear-system-state-and-recovery",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned exercise network delay/failure, invalid input, empty data and success states; screenshot the state messaging and recovery controls; inspect whether browser history and focus remain; attempted recon and the age-verification journey.",
      "evidence": "Attempting the primary action redirects to Agerify and requires a selfie or government ID; the audit did not submit personal identity data.",
      "reason": "Attempting the primary action redirects to Agerify and requires a selfie or government ID; the audit did not submit personal identity data.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-fast-and-stable",
      "checkId": "good-core-web-vitals",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "Lighthouse measured LCP/FCP at 2.65 s and the CDP trace measured LCP/FCP at 2.95 s; the good LCP threshold is 2.5 s.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/lighthouse.json",
        "evidence/home-trace-summary.json",
        "evidence/home-trace.json"
      ],
      "findingIds": [
        "F004"
      ]
    },
    {
      "principleId": "be-fast-and-stable",
      "checkId": "visual-stability",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "The mobile layout observer recorded CLS 0 with no layout-shift entries; Lighthouse CLS was effectively 0.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-mobile-layout.json",
        "evidence/lighthouse.json"
      ]
    },
    {
      "principleId": "be-fast-and-stable",
      "checkId": "efficient-main-thread",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "The trace recorded no long tasks and 0 ms TBT; Lighthouse TBT was 3 ms.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-trace-summary.json",
        "evidence/lighthouse.json"
      ]
    },
    {
      "principleId": "be-fast-and-stable",
      "checkId": "efficient-resource-delivery",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "Lighthouse reports the 93 KiB black-blue.min.css as render-blocking with an estimated 1,180 ms saving; the HAR also records the stylesheet as the largest transferred resource.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/lighthouse.json",
        "evidence/home-summary.json",
        "evidence/home.har"
      ],
      "findingIds": [
        "F005"
      ]
    },
    {
      "principleId": "be-fast-and-stable",
      "checkId": "trim-unused-and-duplicate-code",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "Lighthouse estimates 89 KiB unused CSS and 66 KiB unused JavaScript, including about 75% of scripts.min.js and 64% of jQuery.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/lighthouse.json",
        "evidence/home-summary.json",
        "evidence/home.har"
      ],
      "findingIds": [
        "F006"
      ]
    },
    {
      "principleId": "be-inclusive",
      "checkId": "names-roles-labels",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "The Login and Manage Cookies controls are <a> elements without href or an explicit button role; direct DOM inspection shows Login cannot receive programmatic focus.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-probe.json",
        "evidence/home-dom.json",
        "evidence/lighthouse.json"
      ],
      "findingIds": [
        "F007"
      ]
    },
    {
      "principleId": "be-inclusive",
      "checkId": "sufficient-contrast",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "Lighthouse accessibility scored 1.0 and the forced-colors capture retains readable text and control boundaries.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/lighthouse.json",
        "evidence/home-forced-colors.png"
      ]
    },
    {
      "principleId": "be-inclusive",
      "checkId": "structure-and-focus",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "A direct focus probe on .cb-age-login a reports isFocused=false and outline \"none\" because the anchor has no href.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-probe.json",
        "evidence/home-desktop.png"
      ],
      "findingIds": [
        "F008"
      ]
    },
    {
      "principleId": "be-inclusive",
      "checkId": "legible-text",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "Desktop and mobile captures show unclipped copy, comfortable line spacing, and readable wrapping on the gate.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-desktop.png",
        "evidence/home-mobile.png"
      ]
    },
    {
      "principleId": "be-inclusive",
      "checkId": "zoom-reflow-targets-and-media",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned Lighthouse/axe target-size, meta-viewport and media-caption audits are useful signals; screenshots at narrow and zoomed conditions plus DOM/media inspection can corroborate. The mo; attempted recon and the age-verification journey.",
      "evidence": "Videos and other core media are behind mandatory external age verification, so zoom/reflow and caption equivalence could not be judged for them.",
      "reason": "Videos and other core media are behind mandatory external age verification, so zoom/reflow and caption equivalence could not be judged for them.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "follow-best-practices",
      "checkId": "no-console-errors",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "Lighthouse did not report browser console errors or uncaught exceptions during the gate load.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/lighthouse.json"
      ]
    },
    {
      "principleId": "follow-best-practices",
      "checkId": "sound-document-and-assets",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned a DOM/source probe for doctype/charset/img dimensions; CSS inspection for repetition; Lighthouse best-practices audits cover the rest. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "The gate prevents inspection of document/assets across the actual listing, detail, search, and account templates.",
      "reason": "The gate prevents inspection of document/assets across the actual listing, detail, search, and account templates.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "follow-best-practices",
      "checkId": "browser-platform-hygiene",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "Lighthouse reports three deprecation warnings, including Shared Storage, persistent StorageType, and Protected Audience API usage in the Cloudflare challenge script.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/lighthouse.json"
      ],
      "findingIds": [
        "F009"
      ]
    },
    {
      "principleId": "be-discoverable",
      "checkId": "title-and-description",
      "status": "pass",
      "confidence": "high",
      "method": "Direct visual or objective probe of the public age gate.",
      "evidence": "The server-rendered page includes a descriptive title and meta description, both present in raw HTML.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-dom.json",
        "evidence/discoverability.json"
      ]
    },
    {
      "principleId": "be-discoverable",
      "checkId": "crawlable-and-mobile-friendly",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "robots.txt returns age-gate HTML rather than robots directives, producing 13 Lighthouse parse errors; Lighthouse also flags Login and Manage Cookies as non-crawlable anchors.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/robots.txt",
        "evidence/lighthouse.json",
        "evidence/home-probe.json"
      ],
      "findingIds": [
        "F010"
      ]
    },
    {
      "principleId": "be-discoverable",
      "checkId": "canonical-and-indexing-signals",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "The page declares index,follow and hreflang variants but has no canonical link; /robots.txt returns gate prose and /sitemap.xml produced a Cloudflare challenge/noindex response in direct retrieval.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-probe.json",
        "evidence/robots.txt",
        "evidence/sitemap.xml",
        "evidence/lighthouse.json"
      ],
      "findingIds": [
        "F011"
      ]
    },
    {
      "principleId": "be-discoverable",
      "checkId": "structured-and-shareable-metadata",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "The DOM probe found zero JSON-LD blocks and zero Open Graph tags, despite the page being presented as an indexable public video service.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-probe.json",
        "evidence/home-dom.json"
      ],
      "findingIds": [
        "F012"
      ]
    },
    {
      "principleId": "be-private-and-secure",
      "checkId": "secure-transport-and-headers",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "Header evidence records Content-Security-Policy: frame-ancestors 'self' with no default-src, script-src, object-src, or base-uri directives; the page contains many inline scripts.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/headers.json",
        "evidence/home-dom.json"
      ],
      "findingIds": [
        "F013"
      ]
    },
    {
      "principleId": "be-private-and-secure",
      "checkId": "data-minimisation-and-third-parties",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned inspect network requests and third-party origins; a probe of analytics/beacon calls. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Authentication and the external verifier require credentials or biometric/identity data; those flows were not entered.",
      "reason": "Authentication and the external verifier require credentials or biometric/identity data; those flows were not entered.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-private-and-secure",
      "checkId": "in-context-permissions-and-modern-auth",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned a probe for permission requests fired on load; source inspection for passkey / WebAuthn / navigator.credentials usage in auth flows. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Authentication and the external verifier require credentials or biometric/identity data; those flows were not entered.",
      "reason": "Authentication and the external verifier require credentials or biometric/identity data; those flows were not entered.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-private-and-secure",
      "checkId": "defensive-browser-policies",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "The response uses Referrer-Policy: no-referrer-when-downgrade rather than a privacy-preserving strict-origin policy; the mandatory flow navigates to an external age-verification provider.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/headers.json",
        "evidence/age-verification.mp4",
        "evidence/age-verification-final.png"
      ],
      "findingIds": [
        "F014"
      ]
    },
    {
      "principleId": "be-resilient",
      "checkId": "progressive-enhancement",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "Raw HTML includes a noscript warning that the site cannot be used without JavaScript, while the visible verification button relies on onclick=startAgeVerification(); the crawler view can render gate copy but cannot enter.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-dom.json",
        "evidence/discoverability.json",
        "evidence/discoverability-crawler.png"
      ],
      "findingIds": [
        "F015"
      ]
    },
    {
      "principleId": "be-resilient",
      "checkId": "resilient-runtime-behaviour",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned exercise menus near viewport edges with a screenshot; a probe of async/visibility behaviour. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Runtime and network-failure behavior of the core site cannot be exercised before completing external age verification.",
      "reason": "Runtime and network-failure behavior of the core site cannot be exercised before completing external age verification.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-resilient",
      "checkId": "offline-and-installable",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "The page links /manifest.json and declares mobile-web-app-capable, but the HAR records two 403 responses for the manifest and no controlling service worker is present.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-summary.json",
        "evidence/home.har",
        "evidence/home-probe.json"
      ],
      "findingIds": [
        "F016"
      ]
    },
    {
      "principleId": "be-resilient",
      "checkId": "network-and-http-failure-states",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned simulate failed fetches/offline mode or inspect representative 404/500 routes; screenshots and DOM snapshots of error/loading/empty states show whether recovery is possible. The mo; attempted recon and the age-verification journey.",
      "evidence": "Runtime and network-failure behavior of the core site cannot be exercised before completing external age verification.",
      "reason": "Runtime and network-failure behavior of the core site cannot be exercised before completing external age verification.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-internationalised",
      "checkId": "lang-dir-and-logical-properties",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned a DOM probe for <html lang>/dir and CSS inspection for logical vs physical properties. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Localized content templates and locale-sensitive data remain behind mandatory external age verification.",
      "reason": "Localized content templates and locale-sensitive data remain behind mandatory external age verification.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-internationalised",
      "checkId": "locale-aware-data",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned source inspection for Intl.* usage vs hand-rolled formatting; a probe of rendered dates/numbers under a different locale. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Localized content templates and locale-sensitive data remain behind mandatory external age verification.",
      "reason": "Localized content templates and locale-sensitive data remain behind mandatory external age verification.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-internationalised",
      "checkId": "time-zone-correctness",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned source inspection for time-zone-aware date handling vs naive local Date math. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Localized content templates and locale-sensitive data remain behind mandatory external age verification.",
      "reason": "Localized content templates and locale-sensitive data remain behind mandatory external age verification.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-trustworthy",
      "checkId": "no-dark-patterns",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned a screenshot of consent/upsell/cancel flows; source inspection for declarative button actions vs misleading controls. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Error, autofill, commercial, and account flows require external verification or credentials and could not be exercised safely.",
      "reason": "Error, autofill, commercial, and account flows require external verification or credentials and could not be exercised safely.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-trustworthy",
      "checkId": "humane-error-handling",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned exercise a form, submit invalid input, and observe timing and clarity of errors via a screenshot or a :user-invalid / aria-invalid probe. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Error, autofill, commercial, and account flows require external verification or credentials and could not be exercised safely.",
      "reason": "Error, autofill, commercial, and account flows require external verification or credentials and could not be exercised safely.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-trustworthy",
      "checkId": "trustworthy-input-assistance",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned source/DOM inspection for autocomplete attributes on form fields; a probe of autofill affordances. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Error, autofill, commercial, and account flows require external verification or credentials and could not be exercised safely.",
      "reason": "Error, autofill, commercial, and account flows require external verification or credentials and could not be exercised safely.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-trustworthy",
      "checkId": "safe-commercial-and-account-flows",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned walkthrough checkout/subscription/auth/account flows when present; screenshot pricing, confirmation, cancellation and reauthentication states; inspect passkey/autocomplete support ; attempted recon and the age-verification journey.",
      "evidence": "Error, autofill, commercial, and account flows require external verification or credentials and could not be exercised safely.",
      "reason": "Error, autofill, commercial, and account flows require external verification or credentials and could not be exercised safely.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-sustainable",
      "checkId": "optimised-assets",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned inspect transferred image bytes vs displayed size; source inspection for modern formats and resolution handling. The model chooses.; attempted recon and the age-verification journey.",
      "evidence": "Image/video delivery and media budgets cannot be observed before completing external age verification.",
      "reason": "Image/video delivery and media budgets cannot be observed before completing external age verification.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-sustainable",
      "checkId": "no-wasteful-work",
      "status": "issues",
      "confidence": "high",
      "method": "Direct gate evidence using the artifact(s) listed for the linked finding.",
      "evidence": "The gate transfers 262 KiB across 14 requests while Lighthouse finds 89 KiB unused CSS and 66 KiB unused JavaScript; jQuery and the full site bundle load before access is granted.",
      "pathIds": [
        "age-gate"
      ],
      "artifacts": [
        "evidence/home-summary.json",
        "evidence/home.har",
        "evidence/lighthouse.json"
      ],
      "findingIds": [
        "F017"
      ]
    },
    {
      "principleId": "be-sustainable",
      "checkId": "third-party-and-media-budget",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned a HAR summary shows third-party bytes, font/media weight and caching; screenshots/video reveal autoplay and decorative media; trace/layout evidence shows whether media/animation ke; attempted recon and the age-verification journey.",
      "evidence": "Image/video delivery and media budgets cannot be observed before completing external age verification.",
      "reason": "Image/video delivery and media budgets cannot be observed before completing external age verification.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-agent-ready",
      "checkId": "structured-agent-capabilities",
      "status": "not-applicable",
      "confidence": "high",
      "method": "Contextual applicability judgement from recon of the public age-gated site.",
      "evidence": "This age-gated content site exposes no agent-facing transactional capability, and the emerging WebMCP check is contextual rather than an obligation.",
      "reason": "This age-gated content site exposes no agent-facing transactional capability, and the emerging WebMCP check is contextual rather than an obligation."
    },
    {
      "principleId": "be-agent-ready",
      "checkId": "on-device-inference",
      "status": "not-applicable",
      "confidence": "high",
      "method": "Contextual applicability judgement from recon of the public age-gated site.",
      "evidence": "No on-device inference use case is necessary to complete the public age-gate task; absence is a contextual non-issue.",
      "reason": "No on-device inference use case is necessary to complete the public age-gate task; absence is a contextual non-issue."
    },
    {
      "principleId": "be-memory-efficient",
      "checkId": "no-leak-under-repeated-interaction",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned compare heap snapshots for retained growth - a baseline, then one taken after repeating the interaction with `--interact` about 10x (the memory-tracer methodology: baseline -> repe; attempted recon and the age-verification journey.",
      "evidence": "A representative core interaction cannot be repeated without completing external age verification; gate-only memory would not establish the site footprint.",
      "reason": "A representative core interaction cannot be repeated without completing external age verification; gate-only memory would not establish the site footprint.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-memory-efficient",
      "checkId": "bounded-footprint",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned a single `heap` summary's totals (nodeCount, totalSelfSizeBytes, constructor population) plus Performance.getMetrics (Nodes, JSHeapUsedSize) give the current footprint to judge aga; attempted recon and the age-verification journey.",
      "evidence": "A representative core interaction cannot be repeated without completing external age verification; gate-only memory would not establish the site footprint.",
      "reason": "A representative core interaction cannot be repeated without completing external age verification; gate-only memory would not establish the site footprint.",
      "pathIds": [
        "age-verification"
      ]
    },
    {
      "principleId": "be-memory-efficient",
      "checkId": "no-detached-dom-or-unbounded-listeners",
      "status": "blocked",
      "confidence": "high",
      "method": "Planned the `heap` summary by constructor (Detached* nodes) compared across a before/after pair shows a growing detached-DOM population; an `evaluate` probe can sample listener/timer count; attempted recon and the age-verification journey.",
      "evidence": "A representative core interaction cannot be repeated without completing external age verification; gate-only memory would not establish the site footprint.",
      "reason": "A representative core interaction cannot be repeated without completing external age verification; gate-only memory would not establish the site footprint.",
      "pathIds": [
        "age-verification"
      ]
    }
  ],
  "principleOutcomes": [
    {
      "principleId": "respect-user-preferences",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F001"
      ]
    },
    {
      "principleId": "implement-natural-interactions",
      "expectation": "default",
      "status": "incomplete",
      "reason": "3 check(s) blocked by mandatory external age verification."
    },
    {
      "principleId": "provide-guided-navigation",
      "expectation": "default",
      "status": "incomplete",
      "reason": "3 check(s) blocked by mandatory external age verification."
    },
    {
      "principleId": "maximize-content-reduce-noise",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F002"
      ]
    },
    {
      "principleId": "adapt-to-the-form-factor",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F003"
      ]
    },
    {
      "principleId": "support-core-task-success",
      "expectation": "default",
      "status": "incomplete",
      "reason": "2 check(s) blocked by mandatory external age verification."
    },
    {
      "principleId": "be-fast-and-stable",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F004",
        "F005",
        "F006"
      ]
    },
    {
      "principleId": "be-inclusive",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F007",
        "F008"
      ]
    },
    {
      "principleId": "follow-best-practices",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F009"
      ]
    },
    {
      "principleId": "be-discoverable",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F010",
        "F011",
        "F012"
      ]
    },
    {
      "principleId": "be-private-and-secure",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F013",
        "F014"
      ]
    },
    {
      "principleId": "be-resilient",
      "expectation": "contextual",
      "status": "issues",
      "findingIds": [
        "F015",
        "F016"
      ]
    },
    {
      "principleId": "be-internationalised",
      "expectation": "contextual",
      "status": "incomplete",
      "reason": "3 check(s) blocked by mandatory external age verification."
    },
    {
      "principleId": "be-trustworthy",
      "expectation": "default",
      "status": "incomplete",
      "reason": "4 check(s) blocked by mandatory external age verification."
    },
    {
      "principleId": "be-sustainable",
      "expectation": "contextual",
      "status": "issues",
      "findingIds": [
        "F017"
      ]
    },
    {
      "principleId": "be-agent-ready",
      "expectation": "contextual",
      "status": "not-applicable",
      "reason": "This age-gated content site exposes no agent-facing transactional capability, and the emerging WebMCP check is contextual rather than an obligation."
    },
    {
      "principleId": "be-memory-efficient",
      "expectation": "default",
      "status": "incomplete",
      "reason": "3 check(s) blocked by mandatory external age verification."
    }
  ],
  "paths": [
    {
      "id": "age-gate",
      "description": "Public homepage age gate, representing the only reachable unauthenticated surface.",
      "url": "https://www.boyfriendtv.com/",
      "conditions": [
        "desktop",
        "viewport: 360x800",
        "prefers-color-scheme: dark",
        "forced-colors: active",
        "no JavaScript crawler"
      ],
      "result": "issues"
    },
    {
      "id": "age-verification",
      "description": "Primary entry journey. Clicking Accept & Verify age redirects to Agerify and requests a selfie or government ID; stopped before personal-data submission.",
      "url": "https://www.boyfriendtv.com/",
      "conditions": [
        "fresh profile",
        "no identity data supplied"
      ],
      "result": "failed"
    },
    {
      "id": "core-templates",
      "description": "Listing, video detail/playback, category, search, and account templates were not covered because they remain behind mandatory age verification. Sitemap discovery was also challenged.",
      "result": "skipped"
    },
    {
      "id": "localised-templates",
      "description": "English, German, Spanish, Russian, and Japanese content variants advertised by hreflang were not covered because core templates remain behind mandatory age verification.",
      "result": "skipped"
    }
  ],
  "findings": [
    {
      "id": "F001",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "respect-user-preferences",
      "principleCheckId": "respects-color-scheme",
      "guidanceId": "dark-mode",
      "guidanceCategory": "user-experience",
      "severity": "low",
      "confidence": "high",
      "summary": "The gate uses a fixed dark palette instead of responding to the user’s color-scheme preference.",
      "evidence": "The normal and prefers-color-scheme: dark screenshots are visually identical, while the computed root color-scheme is \"normal\" and no preference-driven scheme is declared.",
      "artifacts": [
        "evidence/home-desktop.png",
        "evidence/home-dark.png",
        "evidence/home-probe.json"
      ],
      "suggestedFix": "Declare color-scheme and express surface, text, border, and control colors with prefers-color-scheme or light-dark(), retaining the current dark design as one supported scheme.",
      "effort": "small"
    },
    {
      "id": "F002",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "maximize-content-reduce-noise",
      "principleCheckId": "semantic-dismissible-primitives",
      "guidanceId": "declarative-dialog-popover-control",
      "guidanceCategory": "user-experience",
      "severity": "low",
      "confidence": "high",
      "summary": "Modal surfaces are implemented as custom divs rather than native dialog/popover primitives.",
      "evidence": "DOM evidence shows #cbDocumentViewer and the chat panel as DIV elements with role=dialog; #cbDocumentViewer is not hidden even when visually closed.",
      "artifacts": [
        "evidence/home-dom.json",
        "evidence/home-probe.json"
      ],
      "suggestedFix": "Use <dialog> for modal document and chat surfaces, call showModal()/close(), and rely on native focus containment, Escape handling, and inert background behavior.",
      "effort": "medium"
    },
    {
      "id": "F003",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "adapt-to-the-form-factor",
      "principleCheckId": "input-modality-aware",
      "guidanceId": "accessibility",
      "guidanceCategory": "accessibility",
      "severity": "high",
      "confidence": "high",
      "summary": "The existing-user Login action is not keyboard focusable.",
      "evidence": "The visible LOGIN control is an <a> without href. Calling focus() leaves document.activeElement elsewhere and its computed outline is none; Lighthouse also identifies it as a non-crawlable anchor.",
      "artifacts": [
        "evidence/home-desktop.png",
        "evidence/home-mobile.png",
        "evidence/home-probe.json",
        "evidence/lighthouse.json"
      ],
      "suggestedFix": "Render Login as a real <button type=\"button\"> when it opens a modal, or as an <a href=\"/login/…\"> when it navigates. Preserve a visible :focus-visible style.",
      "effort": "trivial"
    },
    {
      "id": "F004",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-fast-and-stable",
      "principleCheckId": "good-core-web-vitals",
      "guidanceId": "performance",
      "guidanceCategory": "performance",
      "severity": "medium",
      "confidence": "high",
      "summary": "Even the lightweight age gate misses the good LCP threshold.",
      "evidence": "Lighthouse measured LCP/FCP at 2.65 s and the CDP trace measured LCP/FCP at 2.95 s; the good LCP threshold is 2.5 s.",
      "artifacts": [
        "evidence/lighthouse.json",
        "evidence/home-trace-summary.json",
        "evidence/home-trace.json"
      ],
      "suggestedFix": "Prioritize the gate’s critical CSS and HTML, remove gate-unneeded dependencies, and verify LCP under throttled mobile conditions until it remains at or below 2.5 s.",
      "effort": "medium"
    },
    {
      "id": "F005",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-fast-and-stable",
      "principleCheckId": "efficient-resource-delivery",
      "guidanceId": "optimize-script-priority",
      "guidanceCategory": "performance",
      "severity": "medium",
      "confidence": "high",
      "summary": "A large site-wide stylesheet delays rendering of the age gate.",
      "evidence": "Lighthouse reports the 93 KiB black-blue.min.css as render-blocking with an estimated 1,180 ms saving; the HAR also records the stylesheet as the largest transferred resource.",
      "artifacts": [
        "evidence/lighthouse.json",
        "evidence/home-summary.json",
        "evidence/home.har"
      ],
      "suggestedFix": "Inline a minimal gate-critical stylesheet and load the full site stylesheet only after verification or with non-blocking delivery appropriate to the next view.",
      "effort": "medium"
    },
    {
      "id": "F006",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-fast-and-stable",
      "principleCheckId": "trim-unused-and-duplicate-code",
      "guidanceId": "identify-heavy-scripts",
      "guidanceCategory": "performance",
      "severity": "medium",
      "confidence": "high",
      "summary": "The gate downloads substantial code that it does not use.",
      "evidence": "Lighthouse estimates 89 KiB unused CSS and 66 KiB unused JavaScript, including about 75% of scripts.min.js and 64% of jQuery.",
      "artifacts": [
        "evidence/lighthouse.json",
        "evidence/home-summary.json",
        "evidence/home.har"
      ],
      "suggestedFix": "Create a gate-specific entry point and stylesheet; defer jQuery and the full application bundle until verification succeeds.",
      "effort": "medium"
    },
    {
      "id": "F007",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-inclusive",
      "principleCheckId": "names-roles-labels",
      "guidanceId": "accessibility",
      "guidanceCategory": "accessibility",
      "severity": "high",
      "confidence": "high",
      "summary": "Visible onclick-only anchors are not exposed with the semantics of their intended controls.",
      "evidence": "The Login and Manage Cookies controls are <a> elements without href or an explicit button role; direct DOM inspection shows Login cannot receive programmatic focus.",
      "artifacts": [
        "evidence/home-probe.json",
        "evidence/home-dom.json",
        "evidence/lighthouse.json"
      ],
      "suggestedFix": "Use native buttons for script-triggered actions and anchors with href for navigation; retain concise accessible names.",
      "effort": "trivial"
    },
    {
      "id": "F008",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-inclusive",
      "principleCheckId": "structure-and-focus",
      "guidanceId": "accessibility",
      "guidanceCategory": "accessibility",
      "severity": "high",
      "confidence": "high",
      "summary": "Keyboard users cannot reach the visible Login action on the blocking gate.",
      "evidence": "A direct focus probe on .cb-age-login a reports isFocused=false and outline \"none\" because the anchor has no href.",
      "artifacts": [
        "evidence/home-probe.json",
        "evidence/home-desktop.png"
      ],
      "suggestedFix": "Replace the pseudo-link with a native button or valid link and verify a complete Tab sequence with visible focus through Verify, Login, policy, and consent actions.",
      "effort": "trivial"
    },
    {
      "id": "F009",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "follow-best-practices",
      "principleCheckId": "browser-platform-hygiene",
      "guidanceId": "html",
      "guidanceCategory": "html",
      "severity": "low",
      "confidence": "high",
      "summary": "The loaded Cloudflare challenge script triggers deprecated API warnings.",
      "evidence": "Lighthouse reports three deprecation warnings, including Shared Storage, persistent StorageType, and Protected Audience API usage in the Cloudflare challenge script.",
      "artifacts": [
        "evidence/lighthouse.json"
      ],
      "suggestedFix": "Review the enabled Cloudflare challenge/browser-integrity configuration and vendor version; remove or update the integration that injects deprecated APIs.",
      "effort": "small"
    },
    {
      "id": "F010",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-discoverable",
      "principleCheckId": "crawlable-and-mobile-friendly",
      "guidanceId": "html",
      "guidanceCategory": "html",
      "severity": "medium",
      "confidence": "high",
      "summary": "robots.txt is invalid and action-like anchors lack href values.",
      "evidence": "robots.txt returns age-gate HTML rather than robots directives, producing 13 Lighthouse parse errors; Lighthouse also flags Login and Manage Cookies as non-crawlable anchors.",
      "artifacts": [
        "evidence/robots.txt",
        "evidence/lighthouse.json",
        "evidence/home-probe.json"
      ],
      "suggestedFix": "Exempt /robots.txt from the age gate and return valid text/plain directives. Use href-bearing links for navigation and buttons for in-page actions.",
      "effort": "small"
    },
    {
      "id": "F011",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-discoverable",
      "principleCheckId": "canonical-and-indexing-signals",
      "guidanceId": "html",
      "guidanceCategory": "html",
      "severity": "medium",
      "confidence": "high",
      "summary": "Indexing signals are inconsistent at the public entry point.",
      "evidence": "The page declares index,follow and hreflang variants but has no canonical link; /robots.txt returns gate prose and /sitemap.xml produced a Cloudflare challenge/noindex response in direct retrieval.",
      "artifacts": [
        "evidence/home-probe.json",
        "evidence/robots.txt",
        "evidence/sitemap.xml",
        "evidence/lighthouse.json"
      ],
      "suggestedFix": "Serve machine-readable robots and sitemap responses outside the gate, add a self-referencing canonical, and verify all hreflang alternates return reciprocal, indexable pages.",
      "effort": "small"
    },
    {
      "id": "F012",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-discoverable",
      "principleCheckId": "structured-and-shareable-metadata",
      "guidanceId": "html",
      "guidanceCategory": "html",
      "severity": "low",
      "confidence": "high",
      "summary": "The public homepage exposes no structured data or social preview metadata.",
      "evidence": "The DOM probe found zero JSON-LD blocks and zero Open Graph tags, despite the page being presented as an indexable public video service.",
      "artifacts": [
        "evidence/home-probe.json",
        "evidence/home-dom.json"
      ],
      "suggestedFix": "Add accurate Organization/WebSite JSON-LD and Open Graph/Twitter metadata that describes the age-gated homepage without exposing restricted media.",
      "effort": "small"
    },
    {
      "id": "F013",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-private-and-secure",
      "principleCheckId": "secure-transport-and-headers",
      "guidanceId": "security",
      "guidanceCategory": "security",
      "severity": "medium",
      "confidence": "high",
      "summary": "The Content-Security-Policy only controls framing and does not mitigate script injection.",
      "evidence": "Header evidence records Content-Security-Policy: frame-ancestors 'self' with no default-src, script-src, object-src, or base-uri directives; the page contains many inline scripts.",
      "artifacts": [
        "evidence/headers.json",
        "evidence/home-dom.json"
      ],
      "suggestedFix": "Deploy a nonce- or hash-based CSP with default-src, script-src, object-src none, and base-uri restrictions while retaining frame-ancestors.",
      "effort": "large"
    },
    {
      "id": "F014",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-private-and-secure",
      "principleCheckId": "defensive-browser-policies",
      "guidanceId": "security",
      "guidanceCategory": "security",
      "severity": "medium",
      "confidence": "high",
      "summary": "The referrer policy permits full HTTPS URLs to be sent to other HTTPS origins.",
      "evidence": "The response uses Referrer-Policy: no-referrer-when-downgrade rather than a privacy-preserving strict-origin policy; the mandatory flow navigates to an external age-verification provider.",
      "artifacts": [
        "evidence/headers.json",
        "evidence/age-verification.mp4",
        "evidence/age-verification-final.png"
      ],
      "suggestedFix": "Use strict-origin-when-cross-origin (or stricter) and explicitly review the age-verifier handoff so URL paths and query data are not disclosed unnecessarily.",
      "effort": "trivial"
    },
    {
      "id": "F015",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-resilient",
      "principleCheckId": "progressive-enhancement",
      "guidanceId": "html",
      "guidanceCategory": "html",
      "severity": "high",
      "confidence": "high",
      "summary": "The mandatory age-verification flow cannot proceed without JavaScript.",
      "evidence": "Raw HTML includes a noscript warning that the site cannot be used without JavaScript, while the visible verification button relies on onclick=startAgeVerification(); the crawler view can render gate copy but cannot enter.",
      "artifacts": [
        "evidence/home-dom.json",
        "evidence/discoverability.json",
        "evidence/discoverability-crawler.png"
      ],
      "suggestedFix": "Give the verification control a server-handled form action or real navigation URL, then enhance it with JavaScript. Keep policy and recovery routes usable without scripting.",
      "effort": "medium"
    },
    {
      "id": "F016",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-resilient",
      "principleCheckId": "offline-and-installable",
      "guidanceId": "html",
      "guidanceCategory": "html",
      "severity": "medium",
      "confidence": "high",
      "summary": "The site advertises an app manifest that is not reliably retrievable.",
      "evidence": "The page links /manifest.json and declares mobile-web-app-capable, but the HAR records two 403 responses for the manifest and no controlling service worker is present.",
      "artifacts": [
        "evidence/home-summary.json",
        "evidence/home.har",
        "evidence/home-probe.json"
      ],
      "suggestedFix": "Exclude the manifest from challenge/gate rules, return a valid manifest with the correct content type, and either provide a useful offline fallback or remove installability claims.",
      "effort": "small"
    },
    {
      "id": "F017",
      "pathId": "age-gate",
      "url": "https://www.boyfriendtv.com/",
      "principleId": "be-sustainable",
      "principleCheckId": "no-wasteful-work",
      "guidanceId": "identify-heavy-scripts",
      "guidanceCategory": "performance",
      "severity": "medium",
      "confidence": "high",
      "summary": "The pre-verification gate performs avoidable network and code work.",
      "evidence": "The gate transfers 262 KiB across 14 requests while Lighthouse finds 89 KiB unused CSS and 66 KiB unused JavaScript; jQuery and the full site bundle load before access is granted.",
      "artifacts": [
        "evidence/home-summary.json",
        "evidence/home.har",
        "evidence/lighthouse.json"
      ],
      "suggestedFix": "Serve a minimal gate bundle and defer application, analytics, chat, and media dependencies until consent and age verification make them necessary.",
      "effort": "medium"
    }
  ],
  "taskList": [
    {
      "id": "T001",
      "title": "Make every gate action keyboard-operable with native controls",
      "priority": 1,
      "findingIds": [
        "F003",
        "F007",
        "F008"
      ],
      "guidanceId": "accessibility",
      "status": "open"
    },
    {
      "id": "T002",
      "title": "Serve a minimal, fast age-gate entry point",
      "priority": 2,
      "findingIds": [
        "F004",
        "F005",
        "F006",
        "F017"
      ],
      "guidanceId": "performance",
      "status": "open"
    },
    {
      "id": "T003",
      "title": "Fix robots, sitemap, canonical, and public metadata responses",
      "priority": 3,
      "findingIds": [
        "F010",
        "F011",
        "F012"
      ],
      "guidanceId": "html",
      "status": "open"
    },
    {
      "id": "T004",
      "title": "Deploy a restrictive CSP and stricter referrer policy",
      "priority": 4,
      "findingIds": [
        "F013",
        "F014"
      ],
      "guidanceId": "security",
      "status": "open"
    },
    {
      "id": "T005",
      "title": "Provide a server-capable no-JavaScript verification route",
      "priority": 5,
      "findingIds": [
        "F015"
      ],
      "guidanceId": "html",
      "status": "open"
    },
    {
      "id": "T006",
      "title": "Make the declared manifest reliably available",
      "priority": 6,
      "findingIds": [
        "F016"
      ],
      "guidanceId": "html",
      "status": "open"
    },
    {
      "id": "T007",
      "title": "Replace custom modal divs with native dialog semantics",
      "priority": 7,
      "findingIds": [
        "F002"
      ],
      "guidanceId": "declarative-dialog-popover-control",
      "status": "open"
    },
    {
      "id": "T008",
      "title": "Add preference-driven light/dark scheme support",
      "priority": 8,
      "findingIds": [
        "F001"
      ],
      "guidanceId": "dark-mode",
      "status": "open"
    },
    {
      "id": "T009",
      "title": "Review Cloudflare challenge deprecation warnings",
      "priority": 9,
      "findingIds": [
        "F009"
      ],
      "guidanceId": "html",
      "status": "open"
    }
  ],
  "budget": {
    "pathCount": 4,
    "auditPasses": 1
  },
  "agent": "pi",
  "runId": "2026-07-28T13-16-53-500Z"
}
