docs(license): document activation flow, tier system, dev bypass

- USER-GUIDE EN + ES gain a §0 "First launch — activation" section
  covering paid blob activation, 1-year trial, renewal, file
  location, and device-swap.
- REQUIREMENTS §17a "Licensing" — storage path, activation model,
  lifetime, tier list, dev bypass env var. Test count: 1995.
- DEVELOPER gains a "Licensing" recipe in the Extension recipes
  section: public API, feature-flag add, tier add, minting via the
  creator-only script.
- DECISIONS §9b — log the offline-HMAC choice with the threat-model
  trade-off (motivated piracy not stopped; honor-system + 30-day
  refund covers casual sharing).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-13 16:54:30 +00:00
parent e435103113
commit e612c751a8
5 changed files with 141 additions and 4 deletions

View File

@@ -174,11 +174,13 @@ and proceeds.
- **Dev**: pytest, tox.
## 16. Test coverage
- 1,916 tests passing, 0 skipped, 0 xfailed.
- 1,777 core + CLI tests (run with `pytest -m 'not gui'` for a quick loop).
- 139 GUI tests under `tests/gui/` driving Streamlit pages via `AppTest`
- 1,995 tests passing, 0 skipped, 0 xfailed.
- 1,843 core + CLI tests (run with `pytest -m 'not gui'` for a quick loop).
Includes 40 license-layer unit tests + 26 license-CLI tests.
- 152 GUI tests under `tests/gui/` driving Streamlit pages via `AppTest`
(smoke + EN/ES localization, chrome, gate, workflows, dedup review,
advanced panels, error paths, findings panel). Marked `gui`.
advanced panels, error paths, findings panel, activation + license
gate). Marked `gui`.
- Includes 15 perf-shape regression tests.
- Fixture corpora: text-cleaner (21), encodings (31), reference UTF-8 (9), format-cleaner (199 buyer cases + 20-row international stress fixture), missing-handler (3 use cases + 16 edge cases), column-mapper (3 use cases + 5 edge cases).
- Run: `python run_tests.py [--tool …] [--fixtures] [--coverage]`.
@@ -189,6 +191,29 @@ and proceeds.
- Original input never modified.
- Audit logs: `logs/` next to each run (timestamped).
## 17a. Licensing
- **Storage**: ``~/.datatools/license.json`` (or
``$DATATOOLS_LICENSE_PATH`` override). Signed locally with
HMAC-SHA256.
- **Activation**: buyer pastes a base64-encoded license blob
(``DTLIC1:...``) on first launch; app verifies the signature
offline + matches the buyer-entered name/email to the embedded
values.
- **Lifetime**: every license is 1 year by default. Renewal applies a
fresh blob without losing the embedded buyer identity.
- **Tiers**: ``trial``, ``core`` (the v1 SKU — all 9 tools), ``pro``,
``enterprise``. PRO and ENTERPRISE are scaffolded for future SKUs;
they currently unlock the same feature set as CORE.
- **Feature flags**: every tool has a stable feature id matching its
``tool_id`` in :mod:`src.gui.tools_registry`. Adding a future per-
tool SKU is a one-line change to ``FEATURES_BY_TIER`` — no consumer
code edits.
- **Dev bypass**: ``DATATOOLS_DEV_MODE=1`` skips every check (used by
the test suite and during development).
- **No internet**: signature verification is fully offline. The
shipped binary embeds the verification secret; see
``docs/DECISIONS.md`` for the threat-model discussion.
## 18. Error handling
- Structured hierarchy: `DataToolsError` → `InputValidationError`, `ConfigError`, `FileFormatError`, `FileAccessError`.
- Subclasses extend stdlib `ValueError` / `OSError` so existing handlers still catch them.