# Privacy, Data Residency, and Internationalization (v1.0)

Operator-facing notes on data handling and i18n posture for the Generic
CMS Module. Cross-linked from `MIGRATION.md`.

## Privacy and data residency

This CMS is local-only. There is no automatic off-device sync.

### What this means for operators

- **Data lives in the visitor's browser `localStorage`**, under the
  namespace `cms:admin:*`. Nothing is sent to a remote server.
- **Activity log is per-device.** Each operator who logs in on the
  same admin sees only their own CRUD actions in the log.
- **Backups are operator-controlled.** When the operator clicks
  "Export", they decide where the JSON file goes (download, email,
  cloud drive). The CMS itself never uploads.
- **Recovery phrases are operator-stored.** The 12 words written at
  setup are not stored anywhere digital by the CMS.

### GDPR posture (EU / UK / similar)

- **No data processor relationship** in v1.0 — the operator IS the
  controller. There is no SaaS layer.
- **Right to erasure**: clear localStorage or use the bulk-import
  replace mode to wipe a key.
- **Right to portability**: export backup is the portable format.
  Schema is included in the envelope.
- **Data minimization**: fields are operator-defined. Track only the
  fields your content type needs.
- **Storage key namespace**: `cms:admin:*` is namespaced so it does
  not collide with the host site's own `localStorage` keys.

### Retention

- **Activity log**: capped at 5000 entries (≈1 MB). Oldest trimmed
  on insert. Configurable in `activity.js` (`MAX_ENTRIES`).
- **Auto-backups**: rotated through 4 slots; older rotated out.
- **Manual backups**: persist until the operator deletes them.

### Future (v2.0)

When the `RemoteAdapter` ships, this posture changes:
- Data is replicated server-side (KV / D1 / Supabase).
- A sub-processor relationship may apply.
- A DPA (Data Processing Agreement) will be needed.
- Activity log may be synced across devices.

Until then, **the operator's host application is the data controller
for any content in this CMS.**

## Internationalization (i18n) — limitation

**All UI strings are English-only in v1.0.** This module does not ship
translations for:

- Admin shell UI (nav labels, button text, status messages)
- Schema field labels rendered in the editor
- Error messages
- Help / docs text (English only)

Operators who need non-English admin UIs have two paths:

1. **Fork and translate** — fork the module, replace English strings
   with translated versions, ship as your own variant.
2. **Wait for v2.0** — full i18n with `cms.lang` operator preference
   and `cms/locales/*.json` is scheduled for v2.0.

**Content fields** (the strings inside records) are operator-managed and
can already contain any language. There is no `lang` field per record
in v1.0; operators who need multi-lingual content typically use one of:

- A `locale` field on each record (`locale: 'en'`, `'fr'`, etc.)
- Separate schemas per language (`book_en`, `book_fr`)
- A reference field set keyed by locale

These patterns work today and are out-of-scope to formalize until v2.0.

## See also

- `SECURITY.md` — operator security checklist
- `MIGRATION.md` — recipe for moving into this CMS
- `docs/FAQ.md` — common questions about data handling
- `docs/A11Y.md` — accessibility posture (related: who sees what)
