- Solution pillars (3 cards) : retirer le bloc icône — ne garder que h3 + p
- Bento macro : supprimer la tuile grad-bg, rendre l'icône directement en text-brand-b1, watermark passe à grad-text opacity-20 (famille bleu marque, plus visible que white/[0.04])
- Conformité forteresse (4 cards) : supprimer la tuile grad-bg, rendre l'icône en text-brand-b1
- Bumper toutes les icônes bento (landing + fonctionnalites + default macro) et conformité de w-5 h-5 → w-7 h-7 maintenant qu'elles n'ont plus de backdrop
- Mettre à jour test_bento_uses_flexihub_styling pour refléter la nouvelle structure (grad-text opacity-20 + text-brand-b1 mb-4 au lieu de white/[0.04] + grad-bg rounded-none)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
- Extract 3 pricing tiers to templates/marketing/_partials/_pricing_tiers.html
Single source of truth — landing.html and tarifs.html now {% include %} it.
Prevents price drift (LPC art. 219 risk).
- Sync bento card #2 description across landing + fonctionnalites
(was diverged: 'embeddings' vs 'embeddings vocaux'). Add maintenance
reminder comments in both files.
- Fix OQLF NBSP on '~2 semaines' matrix cells in /tarifs deep-dive table.
- Fix mixed UTF-8/entity 'québécois' -> 'québécois' in tech
specs (consistent with rest of file).
- Calibrate H2 size on /tarifs FAQ to match landing (clamp 2.75rem cap).
- Repair 2 pre-existing test bugs from earlier A-2.x commits:
* 'violent la Loi 25' -> accept both NBSP and plain forms (commit 7c6c6fd
added the NBSP after the test was written)
* 'résilie' -> 'résilie' (Jinja outputs raw UTF-8, not entities)
- Update src/marketing/routes.py module docstring to reflect 2/4 done.
- Drop role="region" from FAQ panels (had no accessible name — axe-core
violation; disclosure pattern with button + aria-controls + aria-expanded
is sufficient per WAI-APG accordion guidance)
- Add focus-visible:outline-2 outline-brand-b1 outline-offset-2 to FAQ
buttons (WCAG 2.2 AA 2.4.7 Focus Not Obscured + 2.4.11 Focus Appearance —
Safari default focus indicator is unreliable)
- Sweep pre-existing text-white/50 on Hero social proof microcopy → /70
(branch-wide WCAG floor; recurring landmine flagged at A-2.7a review)
- Strengthen test_faq_jsonld_schema_present to json.loads() the extracted
block and validate the FAQPage schema shape (regression guard for future
content edits with unescaped backslashes/quotes)
- Reword comparatif row 1 to make Teams ✗ for non-Loi-25-compliant US transfer
(was ⚠ — too soft; territoriality is binary)
- Reword row 2 to positive: 'Souveraineté hors Cloud Act US' (was inverted —
✓ used for bad outcomes, breaking visual scan convention)
- Reword row 4 criterion to match deliverable: 'Diarisation jusqu'à 8 locuteurs'
(was '8+', mismatched DictIA's '✓ Jusqu'à 8' cell)
- Reword row 5 to 'Coût mensuel par utilisateur' (was 'utilisateur/mois' —
awkward French + missing NBSP per OQLF)
- Hedge SOC 2 Type II claim about OVH Beauharnois — third-party certification
scope-dependent; reword to 'conformité documentée selon les services
(ISO 27001, SOC 2 selon le périmètre)' to avoid LPC art. 219 risk
- Replace 🇨🇦 regional indicator pair with 🍁 maple leaf — renders reliably
on Windows + Firefox Linux without color-emoji fonts
- Update existing test for renamed criteria keywords
- Add regression test for ✓-means-good convention + SOC 2 hedge guard
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- ROI payback now returns raw months; template branches to 'moins d'un mois'
for sub-month paybacks and 'Payable dès la première année' when savings≤0
(was rounding up to 'Payback : 1 mois' for ~95% of slider combos)
- Cap sliders: users 1..25 (was 50), hours 0.5..4 (was 8) to keep displayed
savings in a defensible band (~8.8 M$/yr max instead of 35 M$)
- pricing_card href uses cta_url.rstrip('/') to avoid double-slash if caller
passes a trailing slash (preempts A-2.8 / B-2.7 regression)
- aria-live polite + aria-atomic on the savings paragraph so screen readers
announce slider updates
- Cleaner JS module pattern: single window.roiCalculator = function() {...}
- Tests updated for payback ternary; new tests for slider caps, aria-live,
and double-slash guard
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Problème section (light bg-brand-bg, white cards): 3 risk cards
(Cloud Act, Loi 25 biométrie art. 60.1 LPRPSP, sanctions disciplinaires
9 ordres pros). H2 grad-text accent on 'violent la Loi 25' — defensible
legal claim citing CAI + LPRPSP statutes by name. text-brand-navy/70 for
all body text (WCAG AA compliant, no /40 or /50 regression).
- Solution section (bg-brand-navy with single subtle green orb): 3 pillars
(100% local, Conforme Loi 25, Précision FR-CA). H2 grad-text accent on
'par design'. Pillars cite specific tech (WhisperX Large-v3, Mistral 7B,
pyannote, OVH Beauharnois, AGPL v3) — all factually verifiable.
- French typography: NBSP via + |safe before %, $, and within
'Loi 25' to prevent line break separation (OQLF rule).
- 4 new tests verify both sections, 3 cards each, key tech mentions,
and WCAG-safe opacity policy.
- Critical (C1): align 9-ordre list with dictia.ca canonical (Barreau, CNQ,
CPA, ChAD, OACIQ, CMQ, OIIQ, OPQ, OEQ). Drop ambiguous OPPQ; replace M/P
short monograms with disambiguated 3-5 char abbreviations (BAR, CNQ, CPA,
ChAD, OACIQ, CMQ, OIIQ, OPQ, OEQ). Tooltips show full disambiguating names.
- Critical (C2): raise text-brand-navy/40 -> /70 on footnote (2.69:1 -> 9:1
contrast, passes WCAG AAA) and text-[10px] navy/50 -> text-xs navy/70 on
monogram captions (12px minimum + AA contrast). Critical for legal
disclosure legibility.
- Critical (C3): drop unverifiable '50 heures' specific number from
methodology footnote — replaced with 'methodologie disponible sur demande'
(defensible without committing to numbers we can't verify).
- Important (I1): use before %/$ in KPI numbers per OQLF French
typography rules + |safe filter to render entities.
- Important (I2): replace fragile substring-strip test with explicit
forbidden-phrase list (RECONNU PAR, ENDOSSÉ PAR, etc.). Update ordre
list test + footnote test to match new wording.
- Section AFTER hero, white bg with brand-border y-borders
- 9 monogram placeholders (gradient circles with initials, NOT official
logos to avoid licensing issues + false-endorsement exposure)
hover from opacity-50 to opacity-100 for subtle interaction
- Eyebrow phrasing 'MAPPÉ AUX 9 ORDRES PROFESSIONNELS' (factual scope,
not 'CERTIFIÉ PAR' which would be a false-endorsement claim under
LPC art. 219 / Competition Act s. 52)
- 4 KPIs with grad-text numbers: ~5 min/heure, 95%+ FR-CA, 0$ par user,
100% local — each with a 1-line context line and a small subtext
- Methodology footnote: 'Précision mesurée sur 50 heures d'audio
interne, détails sur demande' — defensible disclosure for the 95%
claim (LPC art. 219 hygiene)
- 4 new tests verify ordres list, factual phrasing, KPIs, footnote
- Add @media (prefers-reduced-motion: reduce) override to disable animations
for vestibular-sensitive users (covers hero + future scroll/infinite anims)
- Replace 5-star icon + '27 cabinets' claim with shield + 'Conçu avec 9
ordres professionnels' + 'Pré-inscription ouverte' (LPC art. 219 +
Competition Act s. 52 compliance — pre-launch claims must be factual)
- Convert H1/H2/H3 letter-spacing from absolute px to em-relative (-3px →
-0.028em on H1) so tracking scales correctly with clamp font-size on mobile
- Update test_hero_has_social_proof_microcopy to assert new copy
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>