types:
  - "@type": LocalBusiness
    required: [name, address, url]
    optional: [telephone, openingHours, geo, image]
  - "@type": Service
    required: [name, provider]
    optional: [serviceType, description, audience]
  - "@type": BreadcrumbList
    required: [itemListElement]
    optional: []
  - "@type": FAQPage
    required: [mainEntity]
    optional: []
  - "@type": CollectionPage
    required: [name, url]
    optional: [hasPart, about, breadcrumb]
  - "@type": Article
    required: [headline, datePublished, author]
    optional: [dateModified, image, articleBody, about, publisher, description, mainEntityOfPage]
  # RFC-0512: Team profile page JSON-LD types
  - "@type": Person
    required: [name, url]
    optional: [jobTitle, description, image, address, knowsAbout, sameAs, affiliation]
  - "@type": SoftwareApplication
    required: [name, applicationCategory, url]
    optional: [description, operatingSystem, provider, offers]
  # RFC-0530: Organization type for entity disambiguation (sameAs projection).
  - "@type": Organization
    required: [name, url]
    optional:
      [
        legalName,
        description,
        foundingDate,
        email,
        address,
        sameAs,
        logo,
        image,
        contactPoint,
        identifier,
        founder,
        member,
        areaServed,
        employee,
        makesOffer,
      ]

# RFC-0498: Per-depth JSON-LD type policy for surface pages.
# Maps surface + depth to required and prohibited JSON-LD types.
surfacePolicy:
  - surface: website-local
    depth: 0
    requiredTypes: [WebPage]
    prohibitedTypes: [LocalBusiness, Service, Offer, BookAction]
  - surface: website-local
    depth: 1
    requiredTypes: [WebPage, BreadcrumbList, Service]
    prohibitedTypes: [LocalBusiness, Electrician, HairSalon, Offer, BookAction, PriceSpecification]
  - surface: website-service
    depth: 1
    requiredTypes: [WebPage, BreadcrumbList, Service]
    prohibitedTypes: [LocalBusiness, Electrician, HairSalon, Offer, BookAction, PriceSpecification]
  - surface: website-local
    depth: 2
    requiredTypes: [WebPage, BreadcrumbList]
    prohibitedTypes: [Service, LocalBusiness, Offer, BookAction]
  - surface: website-local
    depth: 3
    requiredTypes: [WebPage, BreadcrumbList]
    prohibitedTypes: [Service, LocalBusiness, Offer, BookAction]
  - surface: website-local
    depth: 4
    requiredTypes: [WebPage, BreadcrumbList]
    prohibitedTypes: [Service, LocalBusiness, Offer, BookAction]
  - surface: website-local
    depth: 5
    requiredTypes: [WebPage, BreadcrumbList, Service]
    prohibitedTypes: [LocalBusiness, Electrician, HairSalon, Offer, BookAction, PriceSpecification]
  # RFC-0500: ratgeber editorial knowledge hub
  - surface: ratgeber
    depth: 0
    requiredTypes: [CollectionPage, BreadcrumbList]
    prohibitedTypes: [LocalBusiness, Service, Offer, BookAction, Article]
  - surface: ratgeber
    depth: 1
    requiredTypes: [Article, BreadcrumbList]
    prohibitedTypes: [LocalBusiness, Service, Offer, BookAction, CollectionPage, FAQPage]
  # RFC-0512: Team hub and profile page surface policies
  - surface: team-hub
    depth: 0
    requiredTypes: [CollectionPage, BreadcrumbList]
    prohibitedTypes: [LocalBusiness, Service, Offer, BookAction, Article]
  - surface: team-profile-human
    depth: 0
    requiredTypes: [ProfilePage, Person, BreadcrumbList]
    prohibitedTypes: [LocalBusiness, Service, Offer, BookAction, SoftwareApplication]
  - surface: team-profile-ai-agent
    depth: 0
    requiredTypes: [ProfilePage, SoftwareApplication, BreadcrumbList]
    prohibitedTypes: [LocalBusiness, Service, Offer, BookAction, Person]

# RFC-0499: Media metadata leakage prevention policy for surface pages.
# Declares prohibited strings, matching strategies, and required labels.
# Enforced by surface.media-leakage.validate and surface.contract.validate.
mediaLeakagePolicy:
  prohibitedStrings:
    - pattern: Gemini
      matchingStrategy: context-aware
      contextSelector: "[data-credit-context], figcaption, details, dl"
      reason: "AI model name is internal metadata, not visitor-facing"
    - pattern: AIPlatform
      matchingStrategy: whole-word
      reason: Internal enum value (CreditPartyKind)
    - pattern: Organization
      matchingStrategy: context-aware
      contextSelector: "[data-credit-context], figcaption, details, dl"
      reason: Internal enum value (CreditPartyKind) — only as media author label
    - pattern: commissioned-warpgogol-material
      matchingStrategy: whole-word
      reason: Internal enum value (MaterialSourceType)
    - pattern: linked-public-source
      matchingStrategy: whole-word
      reason: Internal enum value
    - pattern: Copyright © 2026 Warpgogol
      matchingStrategy: exact
      contextSelector: ":not(footer):not([data-footer])"
      reason: Repetitive copyright boilerplate — per-material usage status is on /bildnachweise/
  requiredLabels:
    - label: Konzeptillustration
      lang: de
    - label: Концептуальна ілюстрація
      lang: uk
  requiredLinkPattern: "/bildnachweise/#"
  aiImageAttribute: data-ai-generated
