{
  "title": "Leafwrit portal implementation review",
  "reviewed_on": "2026-10-24",
  "scope": "Local portal implementation plus the served Rybbit script and public site-13 tracking configuration read on 2026-10-24. Server-only settings and operator policies are owner-supplied and documented in the factory analytics notes, not independently audited here. Production Leafwrit deployment and hosting logs have not been verified.",
  "operator": {
    "name": "Igor Soldatov, an individual based in Argentina",
    "contact": "support@leafwrit.com",
    "source": "https://alpacto.com/privacy/",
    "accessed": "2026-10-23"
  },
  "practices": {
    "purpose": "Pre-registration and one launch notification on the chosen platform, with explicit consent.",
    "fields": [
      "email",
      "platform",
      "country",
      "lang",
      "page",
      "consent_version",
      "consent_text_hash",
      "created_at",
      "ip_hash",
      "token_id"
    ],
    "raw_ip_in_waitlist": false,
    "registration_auto_expiry": false,
    "rate_limits": "Expired windows are cleared on a later request.",
    "deletion": "Signed link and explicit confirmation delete the matching working database row; earlier CSV exports and backups require separate handling.",
    "mail": "No automatic mail sender or CRM forwarder in this implementation. Manual CSV export is available.",
    "tracking": "The portal measures page visits using the operator’s self-hosted Rybbit at hello.alpacto.com, site 13. Analytics data stays on the operator’s servers and is not shared with advertisers (operator policy). The served script does not set cookies; it reads localStorage for identifiers and opt-out settings and persists a valid clickid from the URL as rybbit-anonymous-id. It reuses stored identifiers across later visits. Leafwrit does not call identify(). Fonts and the pre-registration script are local; the analytics script is served from hello.alpacto.com.",
    "operator_policies": [
      "Do not sell registrations or share them with advertising networks.",
      "Support requests for access, correction, withdrawal and deletion via support@leafwrit.com.",
      "Update notices before introducing new purposes, processors or tracking."
    ],
    "infrastructure": "Connection addresses are processed to serve requests; hosting providers, locations, production logs and actual deployment configuration are outside this source audit."
  },
  "evidence": [
    {
      "path": "config.yml",
      "sha256": "93292373681f32ff741891a12bbe83f4ab656279e779dbafc7f8d52afca083d5"
    },
    {
      "path": "server/preregister.py",
      "sha256": "0635b401c39d0de6079aefe19966f5e6dd46facf0bdaf8f4373b6576e0b0a632"
    },
    {
      "path": "server/consent.py",
      "sha256": "90232db22fe588715beefc0dced9c91b0fd380485c415091c30c42d73e7aaa04"
    },
    {
      "path": "assets/preregister.js",
      "sha256": "c8061f262c51bf82318179dcf003523366f66d5e1d3d58962c0c04d2403af41e"
    },
    {
      "path": "templates/base.html",
      "sha256": "79234c5740326c7cfa761b3d516f2dbf0b8928d2719e3e5ee68cc8c2b9ff3304"
    },
    {
      "path": "templates/partials/preregister_form.html",
      "sha256": "d9a65478bd16a5d2a97dbc2d6a31a284d9b4ddb54382feaef7999d531d8c6efc"
    },
    {
      "path": "templates/partials/cta.html",
      "sha256": "56df8dcc1cfd93f37ce2a4574d23cdf574842b15b399b8a29fa98bd1756c3622"
    },
    {
      "path": "deploy/preregister.conf",
      "sha256": "59089492dfacf196c75877dc39606da774e915173d6a63fdea9328a29e8c0461"
    },
    {
      "path": "deploy/preregister-proxy.conf",
      "sha256": "50a09cd9e7aa7f4914f577214d65672c4d0df564e3958d06b8b1a8a7d5d5d125"
    },
    {
      "path": "preregister-i18n.json",
      "sha256": "d391a107ef50dbe520bb681cbaa590ae9d91ad23de41dc4df8f7ef7aad273a46"
    },
    {
      "path": "data/legal-translations.json",
      "sha256": "05a720e1eaf36ed63eb867582991739f69da2175d114f4710dc3f43fd483fa6d"
    },
    {
      "path": "tools/prepare_legal.py",
      "sha256": "6af44ea495cc6b550c5d147bfdcbb006b66e55043e8f452c89cda903dc674239"
    },
    {
      "path": "deploy/security-headers.conf",
      "sha256": "654c20a6573956af472fd41a0f840ff6731176acac89ba25f9a56f0de887d4bd"
    },
    {
      "path": "deploy/_headers",
      "sha256": "7ebd49ba5fdb7469f41d4fb94ca86acac1bd56eb596b0566dcea548d519483c0"
    }
  ],
  "analytics": {
    "script_url": "https://hello.alpacto.com/api/script.js",
    "site_id": 13,
    "panel_url": "https://lens.alpacto.com",
    "ingestion_origin": "https://hello.alpacto.com",
    "purpose": "Understand which pages help readers.",
    "recorded": [
      "page hostname, path, URL parameters and title",
      "referrer",
      "browser/device class",
      "screen dimensions",
      "language",
      "country derived from the request",
      "pseudonymous daily-salted visitor code",
      "outbound clicks",
      "download clicks",
      "technical page errors",
      "bot-detection signals"
    ],
    "cookies_set_by_script": false,
    "browser_storage": "Reads disable-rybbit, rybbit-user-id and rybbit-anonymous-id. A valid clickid URL parameter creates a persistent rybbit-anonymous-id; later visits reuse it. identify() can persist a user id, but Leafwrit does not call it. There is no unconditional no-browser-storage promise.",
    "retention": "Events have no automatic deletion deadline (factory analytics notes).",
    "owner_confirmed_settings": {
      "store_ip": false,
      "daily_salt": true,
      "block_bots": true,
      "session_replay": false,
      "web_vitals": false,
      "allowed_hostnames": [
        "leafwrit.com",
        "www.leafwrit.com"
      ]
    },
    "verification_limit": "The client script and public tracking config do not independently establish backend storage, IP retention, daily salting, data residency, hostname restrictions or bot rejection. Those settings come from the owner and the factory notes.",
    "factory_notes": {
      "path": "fabrika-prilozheniy/docs/ANALITIKA.md",
      "read_on": "2026-10-24",
      "public_source": "https://leafwrit.com/assets/legal/site-practices.json"
    },
    "sources": [
      {
        "url": "https://hello.alpacto.com/api/script.js",
        "accessed": "2026-10-24",
        "snapshot": "docs/rybbit-served-script.js",
        "sha256": "bbcbe8f749345a3467b5659c377d90a58b8b80daec93040d00cca59ee0138507"
      },
      {
        "url": "https://hello.alpacto.com/api/site/tracking-config/13",
        "accessed": "2026-10-24",
        "observed": {
          "type": "web",
          "webVitals": false,
          "trackErrors": true,
          "trackOutbound": true,
          "trackUrlParams": true,
          "trackInitialPageView": true,
          "trackSpaNavigation": true,
          "trackButtonClicks": false,
          "trackCopy": false,
          "trackFormInteractions": false
        }
      }
    ]
  }
}
