Commit Graph

3 Commits

Author SHA1 Message Date
Allison
924d127ab4 feat(legal): polished UX for 5 legal pages + AGPL external link (sticky TOC, prev/next, breadcrumb)
Refonte visuelle et accessibilité (WCAG 2.2 AA) de la section /legal/
sans toucher au contenu juridique signé (dc4ac97).

Templates :
- templates/legal/index.html : grille 6 cartes (5 internes + AGPL externe)
  avec icônes SVG sémantiques, hero gradient, bloc info sous-processeurs,
  carte AGPL ↗ (target=_blank, rel=noopener noreferrer).
- templates/legal/_layout.html : breadcrumb sticky, TOC sticky desktop +
  collapsible mobile (Alpine.js + IntersectionObserver), prev/next nav
  entre les 6 docs, skip link, landmarks (main / aside / nav), typographie
  améliorée (h2 avec accent gradient, tables zebrées, blockquotes), print
  stylesheet (cache header/breadcrumb/TOC/prev-next).

Routes (src/legal/routes.py) :
- DISPLAY_ORDER + EXTERNAL_LINKS + PAGE_ICONS exposés.
- legal_page() calcule prev/next via _neighbour() helper.
- legal_index() concatène pages internes + EXTERNAL_LINKS dans `pages`.

Footer : lien AGPL déjà présent depuis dc4ac97 (col 4 Compte, ligne 49).

Tests (tests/test_legal_pages.py) : 9 anciens + 9 nouveaux = 18/18 PASS
- AGPL external link (target+rel)
- 5 internes + 1 externe sur l'index
- Skip link présent partout
- Prev/next existe sur chaque page
- Conditions (1ère) sans prev / Mentions (dernière) sans next
- Landmarks aside aria-label="Table des matières"
- Landmark main role + id="main-content"
- Breadcrumb avec aria-current="page"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 09:39:40 -04:00
Allison
dc4ac9754b fix(legal): conform site to signed master legal documents (PDC, CGU, EFVP, DPA)
Audit conducted 2026-04-27 against signed PDFs in DOCS_DictIA/. All 6 legal
markdown files + 3 marketing templates aligned on the contractual ground truth
(documents signed by Allison Rioux + Jean-David Lévesque-Rioux 9 mars 2026).

CRITICAL DISCREPANCIES FIXED (D1-D9 — Loi 25 / contractual)

D1. Entity identity: removed false "filiale d'InnovA AI S.E.N.C." claim.
    Canonical (PDC §1.1, CGU §1, RPRP doc): DictIA Inc. is a standalone SPA
    constituted 22 mars 2026 (LSAQ), 50/50 owned by Allison Rioux + Jean-David
    Lévesque-Rioux. NOT a subsidiary of InnovA AI.

D2. NEQ: replaced placeholder with canonical NEQ 1181949562 (DictIA Inc.).

D3. Sub-processors list: PDC §6.2 declares 5 sub-processors. Site listed only
    OVH, Stripe, Resend (the latter two not in canonical). Now aligned:
    OVH Beauharnois QC + GCP Toronto ON (RAM-only, 5min) + Cloudflare US (CDN)
    + HubSpot US (CRM) + Stripe US (paiements). Resend removed.

D4. GCP Toronto disclosure: NEW. PDC §6.2, §11.2, EFVP_GCP all declare GPU
    processing on GCP Toronto Ontario as a transfer hors-Québec under art. 17
    LSP. Site previously claimed "100 % au Québec" without GCP disclosure.
    Now declared in confidentialite.md §6, §7 + conditions.md §2.4, §9 +
    conformite.html pillar.

D5. Biometrics: NEW dedicated section. PDC §12, CGU §6, EFVP_BIOVOCAL all
    require disclosure of voice biometrics (pyannote.audio embeddings) per
    LCCJTI art. 44-45 + CAI declaration K1. Site had ZERO mention. Now
    documented in confidentialite.md §12 + conditions.md §8.

D6. Wrong article number: landing.html cited "art. 60.1 LPRPSP" for biometric
    sanctions — that article does NOT exist. Replaced with canonical citation:
    "art. 44-45 LCCJTI + art. 12 LSP".

D7. Speakr fork attribution: CGU §13.1.1 explicitly requires the AGPL §13
    disclosure URL to be gitea.dictia.ca (not gitea.innova-ai.ca). Mentions.md
    + conformite.html + footer normalized.

D8. Conservation periods: aligned to canonical CGU §8.1.2 + PDC §7.2.
    Audio: 30 jours par défaut (extensible 12 mois opt-in) — was "indéfinie".
    Biométrie inter-sessions: max 12 mois — était absent.
    Facturation: 7 ans — était "6 ans".
    Sauvegardes: 30 jours OVH QC.

D9. RPRP contact: confirmed canonical rprp@dictia.ca (per PDC §1.2 + RPRP
    designation §1.3) — was already correct on site, kept as-is.

MEDIUM (M1-M3)

M1. Cookies categories: aligned to PDC §5.1 (5 categories: essentiels +
    Cloudflare + perf + fonctionnels + HubSpot). Removed "Plausible Analytics
    auto-hébergé" claim (not in any signed doc).

M2. DPA status: noted as "signed" for OVH + HubSpot (signed PDFs verified),
    "in vigueur" for Stripe.

M3. Footer mentions légales link: added (was missing).

MINOR (N1-N2)

N1. Stripe entity: "Stripe Inc., San Francisco CA" (canonical PDC §2.6),
    not "Stripe Payments Canada Ltd." (which doesn't appear in any signed doc).

N2. Engagement de non-entraînement IA: added to conditions.md §10 (canonical
    CGU §10).

NOT MODIFIED (per scope boundaries)

- src/api/auth.py, src/billing/*.py, src/models/*.py — code not touched.
- templates/marketing/{tarifs,fonctionnalites}.html — frontend A-2.x final.
- landing.html — only minimal art. 60.1 → art. 44-45 fix (factual law error).

PENDING ALLISON REVIEW

- landing.html line 167-174 marketing claim "Vos données ne sortent jamais
  de vos murs ou nos serveurs OVH Beauharnois" is technically inaccurate for
  DictIA Cloud users (audio briefly transits to GCP Toronto for GPU processing,
  RAM-only, 5min, zero persistence — encadré par EFVP signée). Decision
  required: rephrase OR add asterisk pointing to /conformite for Cloud
  architecture caveat.

- CAI form (CAI_FO_Declaration_Biometrie_DictIA_COMPLET_signé.pdf) declares
  90 jours retention for inter-sessions vectors, while PDC + CGU + EFVP
  all say 12 mois. Site uses 12 mois (latest, contractual). Allison should
  verify CAI form needs amendment before submission.

TESTS

9/9 test_legal_pages.py passing (added biometrics + decisions automatisees
to required_topics; corrected "transfert hors-québec" → "transferts hors
québec" to match canonical PDC §11 OQLF wording).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 09:27:04 -04:00
Allison
55569366f4 feat(legal): B-2.9 6 pages légales (CGU, Loi 25, cookies, remboursement, accessibilité, mentions)
- src/legal/__init__.py: define canonical LEGAL_VERSION='2026-04-27' constant
  (single source of truth — auth.py now imports it as SIGNUP_LEGAL_VERSION).
- src/legal/routes.py: add /legal/<page> + /legal/ index routes; markdown rendered
  from src/legal/content/*.md with toc, tables, fenced_code, attr_list extensions.
- src/legal/content/: 6 French (Québec) markdown documents — DictIA Inc. /
  InnovA AI S.E.N.C. branding, Loi 25-compliant 12-section privacy policy,
  WCAG 2.2 AA accessibility statement, AGPL-3.0 attribution. All marked
  DRAFT v1.0 pending legal review by Allison Rioux.
- templates/legal/_layout.html + index.html: extends marketing/base.html;
  inline .legal-content typographic styles (no CSS rebuild required).
- .gitignore: allow-rule for src/legal/content/*.md so markdown is tracked
  despite the global *.md ignore.
- tests/test_legal_pages.py: 9 tests covering 200 responses, DictIA branding,
  rprp@dictia.ca presence, 12 mandatory Loi 25 sections, public indexability
  (no X-Robots-Tag noindex), shared layout, marketing/base.html extension,
  DRAFT callout, and LEGAL_VERSION/SIGNUP_LEGAL_VERSION equivalence.
- tests/_run_legal_pages_windows.py: manual driver (Windows fcntl stub).
- static/css/marketing.css: regenerated by `npm run build:css` to include
  new utility classes referenced from templates/legal/*.html.

Tests: 9/9 pass. No off-limits files modified beyond the 2-line auth.py
constant move spec'd in B-2.9. No schema changes; markdown==3.5.1 already
pinned in requirements.txt (B-1.1). Pages publicly indexable by design
(Loi 25 transparency).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 08:57:36 -04:00