{
  "language": "en",
  "alternates": {
    "fr": "https://test.each.app/m/pivohub.json",
    "en": "https://test.each.app/en/m/pivohub.json"
  },
  "key_facts": [
    "The brand check is done by Each, with a fuzzy search of the PivoHub catalogue.",
    "The catalogue (brands, products, communities) is a starter catalogue until access to the PivoHub API.",
    "A brand claim stays \"claim pending\" until the brand's PivoHub account confirms it; it is not proof of ownership.",
    "\"Proven\" = backed by a verifiable signed proof; \"declared\" = stated without proof (e.g. an affiliation).",
    "A passkey proves who confirmed, not that the gesture happened.",
    "Brands: checking, claiming, reading and verifying proofs is free; brand plans, pricing to come.",
    "Public vs private, refusals and delays: see the FAQ."
  ],
  "brand": "PivoHub",
  "role": "Each launch partner",
  "environment": "production",
  "url": "https://test.each.app/m/pivohub",
  "catalog_source": "starter catalogue (until access to the PivoHub API)",
  "brands": [
    {
      "id": "pb-001",
      "slug": "brasserie-exemple-nord",
      "name": "Brasserie Exemple du Nord",
      "region": "Québec",
      "updated_at": "2026-10-30T12:00:00Z"
    },
    {
      "id": "pb-002",
      "slug": "cidrerie-exemple-verger",
      "name": "Cidrerie Exemple du Verger",
      "region": "Québec",
      "updated_at": "2026-10-30T12:00:00Z"
    },
    {
      "id": "pb-003",
      "slug": "distillerie-exemple-riviere",
      "name": "Distillerie Exemple de la Rivière",
      "region": "Québec",
      "updated_at": "2026-10-20T12:00:00Z"
    }
  ],
  "products": [
    {
      "id": "pp-001",
      "brand_id": "pb-001",
      "name": "Blonde de démonstration",
      "name_en": "Demo blonde ale",
      "format": "473 ml",
      "updated_at": "2026-10-30T12:00:00Z"
    },
    {
      "id": "pp-002",
      "brand_id": "pb-001",
      "name": "IPA de démonstration",
      "name_en": "Demo IPA",
      "format": "473 ml",
      "updated_at": "2026-10-30T12:00:00Z"
    },
    {
      "id": "pp-003",
      "brand_id": "pb-002",
      "name": "Cidre sec de démonstration",
      "name_en": "Demo dry cider",
      "format": "750 ml",
      "updated_at": "2026-10-30T12:00:00Z"
    },
    {
      "id": "pp-004",
      "brand_id": "pb-003",
      "name": "Gin de démonstration",
      "name_en": "Demo gin",
      "format": "750 ml",
      "updated_at": "2026-10-20T12:00:00Z"
    }
  ],
  "communities": [
    {
      "id": "pc-001",
      "slug": "amateurs-local",
      "name": "Local product fans",
      "updated_at": "2026-10-30T12:00:00Z"
    },
    {
      "id": "pc-002",
      "slug": "detaillants-partenaires",
      "name": "Partner retailers",
      "updated_at": "2026-10-30T12:00:00Z"
    },
    {
      "id": "pc-003",
      "slug": "evenements-degustation",
      "name": "Tasting events",
      "updated_at": "2026-10-30T12:00:00Z"
    }
  ],
  "affiliated_people": 0,
  "proofs": [],
  "brand_check": {
    "get": "https://test.each.app/v1/pivohub/brands/check?name={nom}",
    "note": "recherche approximative dans le catalogue d'exemple; si la marque y est, revendication en un geste confirmée par clé d'accès, puis statut revendication en attente jusqu'à la confirmation par le compte PivoHub de la marque"
  },
  "proofs_note": "No public proof yet: Each proofs come from hidden test accounts. The list fills itself as soon as a real person confirms a gesture.",
  "affiliation_vs_proof": "An affiliation is \"declared\": the person says they belong to the community, with no signed proof. Proofs come only from gestures confirmed with a passkey. So a person can be affiliated without any proof yet.",
  "latest_public_proofs": {
    "items": [],
    "note": "No public proof yet: Each proofs come from hidden test accounts. The list fills itself as soon as a real person confirms a gesture."
  },
  "signing": {
    "algorithm": "ES256 (ECDSA, courbe P-256, SHA-256; signature au format brut r||s de 64 octets, encodée base64url)",
    "kid": "each-test-2026-10-a",
    "public_keys": "https://test.each.app/.well-known/each-keys",
    "canonical_json": "The signature covers the UTF-8 bytes of the canonical JSON of the \"proof\" object: keys sorted alphabetically at every level, no whitespace, arrays kept in order.",
    "self_verify": [
      "GET https://test.each.app/v1/proofs/{id}: you get \"proof\", \"signature\" (alg, kid, value) and \"keys_url\".",
      "GET https://test.each.app/.well-known/each-keys and take the key whose \"kid\" equals signature.kid (EC P-256 JWK, x and y).",
      "Serialize the \"proof\" object as canonical JSON (sorted keys, no whitespace), UTF-8 encode it.",
      "Decode signature.value (base64url) to 64 bytes.",
      "Verify with ECDSA P-256 + SHA-256 (e.g. crypto.subtle.verify). True = issued by Each and unaltered.",
      "Shortcut: GET https://test.each.app/v1/proofs/{id}/verify (server-checked) or the page https://test.each.app/verifier/{id} (checked in your browser)."
    ]
  },
  "proof_fields": [
    {
      "field": "v",
      "fr": "version du format (1)",
      "en": "format version (1)"
    },
    {
      "field": "type",
      "fr": "\"each.proof\"",
      "en": "\"each.proof\""
    },
    {
      "field": "id",
      "fr": "identifiant de la preuve (pr_...)",
      "en": "proof id (pr_...)"
    },
    {
      "field": "issuer",
      "fr": "émetteur: each.app",
      "en": "issuer: each.app"
    },
    {
      "field": "environment",
      "fr": "\"Each\" pour l'Each",
      "en": "\"Each\" in this Each"
    },
    {
      "field": "issued_at",
      "fr": "date ISO 8601 (UTC) de la signature",
      "en": "ISO 8601 (UTC) signing time"
    },
    {
      "field": "person",
      "fr": "handle et nom affiché de la personne",
      "en": "person's handle and display name"
    },
    {
      "field": "brand",
      "fr": "marque liée (slug, nom)",
      "en": "linked brand (slug, name)"
    },
    {
      "field": "community",
      "fr": "communauté (slug, nom) ou null",
      "en": "community (slug, name) or null"
    },
    {
      "field": "tool",
      "fr": "outil qui a produit la preuve (preuve-de-geste)",
      "en": "tool that produced the proof (preuve-de-geste)"
    },
    {
      "field": "gesture",
      "fr": "id, type, description écrite par la personne, date de déclaration",
      "en": "id, kind, person's own description, declaration time"
    },
    {
      "field": "statement",
      "fr": "phrase confirmée par la personne",
      "en": "sentence the person confirmed"
    },
    {
      "field": "statement_lang",
      "fr": "langue de la phrase",
      "en": "statement language"
    },
    {
      "field": "draft_source",
      "fr": "\"ai\" ou \"template\": qui a rédigé le brouillon",
      "en": "\"ai\" or \"template\": who drafted it"
    },
    {
      "field": "statement_edited",
      "fr": "vrai si la personne a modifié le brouillon",
      "en": "true if the person edited the draft"
    },
    {
      "field": "confirmation",
      "fr": "méthode passkey, identifiant de la clé, user_verified, challenge, rp_id",
      "en": "passkey method, credential id, user_verified, challenge, rp_id"
    },
    {
      "field": "claim",
      "fr": "(revendication de marque seulement) marque visée et sens: revendication, pas une preuve de propriété",
      "en": "(brand claims only) target brand and meaning: a claim, not proof of ownership"
    }
  ],
  "brand_check_format": {
    "request": "GET https://test.each.app/v1/pivohub/brands/check?name={nom}",
    "fields": {
      "query": "texte cherché",
      "found": "vrai si au moins une marque ressemble (score >= 0,6)",
      "matches": "jusqu'à 3 marques: id, slug, name, score (0 à 1)",
      "source": "\"sample\" = catalogue de démarrage",
      "source_label": "libellé FR/EN"
    },
    "example_found": {
      "query": "brasserie du nord",
      "found": true,
      "matches": [
        {
          "id": "pb-001",
          "slug": "brasserie-exemple-nord",
          "name": "Brasserie Exemple du Nord",
          "score": 1
        }
      ],
      "source": "sample",
      "source_label": "starter catalogue"
    },
    "example_not_found": {
      "query": "Dieu du Ciel",
      "found": false,
      "matches": [],
      "source": "sample",
      "source_label": "starter catalogue"
    }
  },
  "faq": [
    {
      "q": "Who confirms a brand claim, and how long does it take?",
      "a": "The brand's PivoHub account. The delay is unknown: for now, confirmation is simulated and always stays \"claim pending\"."
    },
    {
      "q": "What happens if a claim is refused?",
      "a": "Not defined yet. The signed claim proof stays (the log is append-only) but never counts as proof of ownership; a refused status is planned, not built yet."
    },
    {
      "q": "How do you stop someone from confirming a fake gesture?",
      "a": "Honestly: today it cannot be prevented. A passkey proves WHO confirmed, not that the gesture happened. An Each proof says \"this person states this and confirmed it themselves\". Writes and gestures are rate-limited. Planned: brand validation, witnesses, moderation and stronger limits. No guarantee that the gesture is true."
    }
  ]
}