PD-298 — Review de spécification¶
Auditeur : technique indépendant — contractualisation, testabilité, conformité. Documents audités : - PD-298-specification.md - PD-298-tests.md (audit limité : ambiguïtés, contradictions, règles non testables a priori, hypothèses dangereuses, risques sécurité/conformité — sans conclure sur la couverture).
1. Ambiguïtés¶
A-01 — Regex D-287-03 non fournie mais contractualisée comme référence¶
- Type : Ambiguïté
- Référence :
spec §5.1 (recipientEmail, eventRecipientEmail),spec §10.2 PC-298-01,spec H-298-01,tests TC-NOM-02 / TC-ERR-01 / TC-NEG-03 / §9 NON TESTABLE - Description : La colonne « Regex / Validation » de
recipientEmailindiqueRegex exacte D-287-03 requise (non fournie ici). L'invariant INV-298-01, le critère CA-298-02 et plusieurs tests (TC-NOM-02, TC-ERR-01, TC-NEG-03) reposent tous sur cette règle. Aucun motif normatif n'est donné dans la spec, ni dans une annexe, ni par renvoi résolvable. - Impact : Impossible de valider contractuellement le rejet local d'un email invalide. L'implémentation UI fabriquera sa propre regex, créant un risque de divergence backend/UI silencieuse. Toute revue de couverture est circulaire (on teste une règle par rapport à elle-même).
- Gravité : Bloquant
A-02 — Règle de masquage IPv6 partiellement définie¶
- Type : Ambiguïté
- Référence :
spec §5.1 (eventIpMasked),spec §10.2 PC-298-05,tests §9 "règle normative précise de masquage IPv6",tests TC-NOM-12 / TC-NEG-07 - Description : Le format IPv6 masqué est décrit par
4 hextets + *:*:*:*. Sur les 8 hextets d'une adresse IPv6, la spec ne précise ni lesquels sont conservés (préfixe réseau, suffixe interface, etc.) ni l'ordre du rendu. Aucune règle canonique (ex : RFC 5952) n'est citée. - Impact : Deux implémentations UI peuvent produire deux masques différents à partir de la même IP brute, tous « conformes » à la description textuelle. CA-298-09 et TC-NOM-12 sont non reproductibles.
- Gravité : Majeur
A-03 — Stockage local drmWarningSeen non spécifié¶
- Type : Ambiguïté
- Référence :
spec INV-298-03,spec §5.1 (drmWarningSeen),spec F-298-01 §4 / F-298-06,tests TC-NOM-03 / TC-NR-06 - Description : L'invariant parle de « mémorisé localement » et la table data mentionne « Booléen persistant local par compte », sans préciser le mécanisme (AsyncStorage, MMKV, SecureStore…), la politique de reset (logout ? uninstall ?), ni la granularité (par
userIdmais que se passe-t-il après changement de compte sur le même device ?). - Impact : TC-NOM-03 vérifie la persistance mais ne peut prouver l'exhaustivité sans définir le mécanisme. Comportement imprévisible au logout/reinstall/multi-device.
- Gravité : Majeur
A-04 — Contenu de l'encart RGPD inconnu¶
- Type : Ambiguïté
- Référence :
spec INV-298-06,spec §10.2 PC-298-06,spec H-298-07,tests §9 "Texte RGPD exact",tests TC-NOM-04 - Description : INV-298-06 et CA-298-11/CA-287-27 exigent l'affichage d'un « encart RGPD visible avant soumission » mais la spec ne contient ni le texte, ni les champs minimaux (finalité, base légale, durée de rétention, destinataires, droits), ni la valeur chiffrée de la durée de rétention.
- Impact : TC-NOM-04 ne vérifie que la présence positionnelle d'un encart, pas son contenu normatif. L'invariant est une coquille vide côté testabilité.
- Gravité : Bloquant
A-05 — Textes ARB-7 et ARB-8 absents¶
- Type : Ambiguïté
- Référence :
spec §3 (ARB-7, ARB-8),spec INV-298-02,spec INV-298-03,tests §9 "Comparaison stricte ARB-7/ARB-8",tests TC-NOM-09 - Description : INV-298-02 exige le « texte ARB-7 exact » et INV-298-03 implique un texte DRM (ARB-8). Aucun de ces textes n'est reproduit dans la spec. La spec renvoie à PD-287 sans inclusion effective.
- Impact : TC-NOM-09 ne peut comparer « strictement » un texte qu'il ne possède pas. La règle est auto-référentielle.
- Gravité : Bloquant
A-06 — Borne maximale maxViews inconnue¶
- Type : Ambiguïté
- Référence :
spec §5.1 / §5.2 (maxViews),spec §10.2 PC-298-02,spec H-298-05 - Description :
maxViewsest optionnel, mais la borne maximale backend n'est pas fournie. La spec afficheNon défini dans besoin/PD-287 accessible. Le seul comportement prévu est « >max backend: erreur backend propagée », ce qui revient à ne pas valider côté client. - Impact : Aucun test n'est spécifié pour la borne haute. Critère d'acceptation CA-298-03 ne couvre que TTL.
- Gravité : Majeur
A-07 — Mapping eventType backend→UI non figé¶
- Type : Ambiguïté
- Référence :
spec §5.1 (eventType),spec §10.2 PC-298-03 - Description : L'enum est donné
{CREATION, ACTIVATION, CONSULTATION, EXPORT, ECHEC_OTP, REVOCATION}mais annoté « mapping backend à figer ». Le lien entre code API et libellé FR i18n n'est pas défini. - Impact : Le journal peut afficher des codes bruts au lieu de libellés traduits. TC-NOM-11 vérifie les colonnes, pas la qualité des libellés.
- Gravité : Majeur
A-08 — Terme normaliser(email) non contractualisé¶
- Type : Ambiguïté (terminologique — voir aussi §2 Contradictions)
- Référence :
spec §5.1 (recipientEmail, "comparaison case-insensitive"),spec §5bis Diagramme de séquence ("normaliser(email)") - Description : Le diagramme de séquence introduit une étape
normaliser(email)distincte devalider(regex D-287-03). La spec textuelle parle uniquement de « comparaison case-insensitive ». Aucun invariant ne formalise la normalisation (lowercase ? trim ? Unicode NFC ? dot-removal Gmail ?). - Impact : Si la normalisation est faite, risque d'écart entre l'email saisi et l'email réellement envoyé au backend (différent de ce que l'utilisateur croit avoir tapé). Si elle n'est pas faite, diagramme trompeur.
- Gravité : Mineur
A-09 — « Appel exploratoire » non défini¶
- Type : Ambiguïté
- Référence :
spec INV-298-16,tests TC-NEG-01 / TC-NEG-08 - Description : « Le client NE DOIT PAS effectuer d'appels exploratoires pour inférer des partages non autorisés » ne définit ni la notion d'exploration (pattern de requêtes ? cadence ? scope hors compte ?) ni le mode de détection côté test.
- Impact : TC-NEG-08 vise un « pattern d'énumération » dans les traces réseau, sans définir ce qui qualifie un pattern. Critère subjectif.
- Gravité : Majeur
A-10 — Message contextuel « journal vide » non rédigé¶
- Type : Ambiguïté
- Référence :
spec F-298-05 §4,spec ERR-298-06,spec §10.2 PC-298-07,tests TC-ERR-06 - Description : ERR-298-06 impose un « message contextuel explicite » ; la spec mentionne trois variantes possibles (« jamais activé / pas d'événement / erreur réseau ») mais aucune clé i18n ni texte normatif. TC-ERR-06 ne peut donc pas vérifier l'adéquation contextuelle.
- Impact : Test binaire dégénéré (présence d'un texte non-vide), sans garantie de couverture des 3 cas.
- Gravité : Mineur
A-11 — Pull-to-refresh sans invariant¶
- Type : Ambiguïté
- Référence :
spec F-298-02 §4 ("Pull-to-refresh force un rechargement réseau") - Description : Comportement listé dans le flux nominal mais non associé à un invariant, un CA ou un test. Statut contractuel flou (obligation ? bonus ?).
- Impact : Non testable tel quel ; sera soit hors périmètre, soit source de régression silencieuse.
- Gravité : Mineur
A-12 — Reconsultation DRM vs mémorisation¶
- Type : Ambiguïté
- Référence :
spec INV-298-03,spec F-298-06 §1 - Description : INV-298-03 dit « à la première ouverture ». F-298-06 dit « le propriétaire peut reconsulter ». Aucun invariant ne décrit le comportement du flag
drmWarningSeenlors d'une reconsultation volontaire (restetrue? reset ? modal distinct ?). - Impact : TC-NR-06 présume une « reconsultation possible » sans définir son observable.
- Gravité : Mineur
A-13 — Scope du guard propriété à l'écran détail preuve¶
- Type : Ambiguïté
- Référence :
spec §5.8 ("Scope d'enregistrement du guard"),spec INV-298-12,tests TC-NOM-07 - Description : La spec parle de « guard UI de propriété ». Le guard est-il un check à l'entrée du formulaire, un filtre sur la visibilité du CTA, ou une garde de navigation (route/screen) ? Les trois ont des implémentations et des tests différents.
- Impact : TC-NOM-07 vérifie l'absence de CTA mais pas l'impossibilité de navigation programmatique. INV-298-12 sous-spécifie la défense.
- Gravité : Mineur
2. Contradictions¶
C-01 — drmWarningSeen persistant local vs INV-298-05 « pas de cache local »¶
- Type : Contradiction
- Référence :
spec INV-298-05,spec §5.1 (drmWarningSeen : "Booléen persistant local par compte"),spec F-298-01 §4 - Description : INV-298-05 interdit toute mise en cache locale « des données de partage » et exige fraîcheur réseau à chaque affichage. Le flag
drmWarningSeenest lui-même un état de partage persistant localement. La frontière « données de partage » vs « préférence utilisateur » n'est pas contractualisée. - Impact : Ambiguïté interprétative entre implémenteurs et auditeurs ; un lecteur strict peut considérer que INV-298-05 interdit aussi la persistance
drmWarningSeen. - Gravité : Mineur
C-02 — PC-298-04 « à clarifier » vs matrice §5.5 déjà exhaustive¶
- Type : Contradiction
- Référence :
spec §5.5 (matrice transitions),spec §10.2 PC-298-04 - Description : La matrice §5.5 liste explicitement
ACTIVE → OTP_BLOCKED : INTERDITE. Pourtant PC-298-04 donne ce même couple comme exemple de « comportement exact à clarifier, matrice backend non jointe ». Soit la matrice UI est définitive (et PC-298-04 est obsolète), soit elle est indicative (et INV-298-14/INV-298-15 sont faux). - Impact : Ambiguïté sur l'opposabilité contractuelle de la matrice. TC-NOM-16 et TC-NEG-04 s'appuient sur elle.
- Gravité : Majeur
C-03 — Tests UI d'invariants de transitions backend¶
- Type : Contradiction Spec ↔ Tests
- Référence :
spec INV-298-08 ("source de vérité unique backend"),spec INV-298-14 / INV-298-15,tests TC-NOM-16 / TC-NEG-04 - Description : INV-298-08 établit le backend comme unique source de vérité d'état. INV-298-14/15 (transitions interdites, terminaux) sont des règles de la machine d'états backend. Les tests TC-NOM-16 et TC-NEG-04 prétendent vérifier que « les transitions non listées sont refusées » côté UI, alors que l'UI n'initie pas les transitions (sauf
revoke) — elle affiche l'état retourné. Cela signifie, soit que l'UI doit dupliquer la FSM (et rejeter des payloads backend non conformes), soit que le test est hors périmètre UI. - Impact : Les invariants INV-298-14/15 sont contractuellement mal attribués à un composant UI. Les tests associés ne peuvent être réalisés de manière déterministe sans mock exhaustif des transitions backend.
- Gravité : Majeur
C-04 — Payload POST /shares diagramme vs table §5.1¶
- Type : Contradiction
- Référence :
spec §5bis (diagramme séquence),spec §5.1 - Description : Le diagramme envoie
{proofId, recipientEmail, ttlMinutes, maxViews?, notificationsEnabled}. La réponse 201 contient{shareId, state, expiresAt}. La table §5.1 liste aussicreatedAt,ownerUserId, et les champs sont censés figurer dans la liste (CA-298-05/06). Il n'est pas clair si la réponse 201 sert à construire la ligne UI ou si un refreshGET /sharesest obligatoire. - Impact : Risque d'incohérences d'affichage post-création (F-298-01 §8-9) ou d'appels réseau supplémentaires non spécifiés.
- Gravité : Mineur
C-05 — INV-298-07 « jamais loggés » vs journal d'accès affichant l'email¶
- Type : Contradiction (apparente — frontière imprécise)
- Référence :
spec INV-298-07,spec F-298-05 §3,spec §5.1 (eventRecipientEmail),spec CA-298-08 - Description : INV-298-07 interdit « NE DOIVENT JAMAIS être loggés ». Le journal d'accès affiche le
recipientEmail. Selon l'interprétation de « loggés » (logs applicatifs vs export probatoire vs affichage UI), un journal visible par le propriétaire contient bien l'email. Les tests incluent aussi « export probatoire : HAR réseau, captures écran » (§8) — un HAR réseau contiendra l'email de réponse API. - Impact : Frontière contradictoire entre PII non loguée et PII affichée/capturée. Risque RGPD si l'observabilité des tests (HAR) échappe à la règle « jamais loggés ».
- Gravité : Majeur
C-06 — Diagramme d'état : self-loops INTERDITE absents de la matrice §5.5¶
- Type : Contradiction diagramme ↔ spec
- Référence :
spec §5.5,spec §5bis Diagramme d'état (ACTIVE --> ACTIVE : INTERDITE, OTP_BLOCKED --> OTP_BLOCKED : INTERDITE, PENDING_ACTIVATION --> PENDING_ACTIVATION : INTERDITE) - Description : Le diagramme d'état ajoute des auto-transitions (self-loops) INTERDITE. La matrice §5.5 ne les liste pas (son axe « →État » ne couvre pas la même source, et l'INV-298-14 parle de transitions « non listées »). Incohérence entre les deux représentations censées décrire la même machine d'états.
- Impact : Ambiguïté sur le fait qu'une réponse backend identique à l'état courant constitue ou non une violation d'invariant.
- Gravité : Mineur
C-07 — Diagramme de séquence incomplet vs flux spécifiés¶
- Type : Contradiction diagramme ↔ spec
- Référence :
spec §5.4 (F-298-02, F-298-03, F-298-04),spec INV-298-02 (ARB-7),spec §5bis Diagramme séquence - Description : Le diagramme de séquence ne couvre que la création et le journal. Il omet : la révocation (ARB-7 +
POST /revoke, pourtant critique INV-298-02), la pagination (F-298-03 / INV-298-13), et les erreurs (401, 403, 400, offline). - Impact : La règle §5bis du prompt (« chaque transformation/appel crypto doit être explicite ») n'est pas respectée pour les flux sensibles. Les invariants INV-298-02, INV-298-13, ERR-298-11/12 n'ont pas de représentation graphique.
- Gravité : Majeur
C-08 — INV-298-17 « aucune exécution offline » vs ERR-298-12 « timeout / perte connectivité »¶
- Type : Contradiction / ambiguïté
- Référence :
spec INV-298-17,spec ERR-298-12,tests TC-NOM-17 / TC-ERR-12 - Description : INV-298-17 dit « aucune exécution offline n'est autorisée » — interprétable comme « la feature refuse d'entrer en mode offline ». ERR-298-12 gère « timeout / offline pendant une action » par une « erreur réseau explicite » — interprétation différente (la feature tente quand même puis rend compte de l'échec). TC-NOM-17 et TC-ERR-12 testent ces deux comportements sans les séparer clairement.
- Impact : Comportement UX ambigu : bloquer à l'entrée ou laisser entrer et gérer l'échec en cours ? Deux implémentations possibles, toutes les deux pass/fail selon l'interprétation.
- Gravité : Mineur
3. Règles non testables¶
NT-01 — INV-298-10 « 100% des chaînes visibles »¶
- Type : Non testable
- Référence :
spec INV-298-10,tests TC-NOM-14 / TC-NR-02 - Description : « 100% » et « audit statique » sans définition d'outil, de scope (feature seule ? app entière ? screenshots d'accessibilité ?) ni de critère de décision sur les littéraux techniques (logs, clés de test, sentry breadcrumbs). CA-298-13 parle de « scope code UI de la feature partage » mais sans lister les fichiers/modules.
- Impact : Verdict non reproductible d'une audit à l'autre.
- Gravité : Majeur
NT-02 — INV-298-07 « NE DOIVENT JAMAIS être loggés »¶
- Type : Non testable (partiellement)
- Référence :
spec INV-298-07,tests TC-NOM-15 / TC-ERR-04 - Description : Le « jamais » est universel. Les tests couvrent les « logs applicatifs » et les « traces fonctionnelles », mais ne peuvent exhaustivement couvrir les pipelines externes (Sentry, crashlytics, analytics, logs OS, NSLog iOS, logcat Android, ShareSheet, clipboard, HAR).
- Impact : Couverture partielle, verdict binaire impossible sans liste fermée de canaux.
- Gravité : Majeur
NT-03 — INV-298-02 / INV-298-03 (ARB-7 / DRM) « texte exact »¶
- Type : Non testable
- Référence :
spec INV-298-02 / INV-298-03,tests §9 "Comparaison stricte ARB-7/ARB-8" - Description : Le verdict QA liste ces règles comme « NON TESTABLE » faute de textes fournis. C'est un aveu de non-testabilité contractualisé, donc un écart à lever avant Gate 5 et non à accepter en l'état.
- Impact : INV-298-02 non démontrable ; la révocation confirmée par l'utilisateur n'a aucune garantie de consentement éclairé.
- Gravité : Bloquant
NT-04 — INV-298-16 « appels exploratoires »¶
- Type : Non testable (critère subjectif)
- Référence : cf. A-09.
- Gravité : Majeur
NT-05 — INV-298-09 « IP partiellement masquée » pour IPv6¶
- Type : Non testable
- Référence : cf. A-02.
- Gravité : Majeur
NT-06 — NON TESTABLE — qualification juridique RGPD¶
- Type : Non testable (acté)
- Référence :
spec §3 / H-298-08,tests §9 - Description : La spec et les tests reconnaissent explicitement la non-testabilité (hors périmètre fonctionnel UI). OK comme aveu, mais couplé à INV-298-06 / CA-287-27 / A-04 : l'encart RGPD fonctionnel repose sur un contenu juridique absent. On teste donc une coquille.
- Impact : Le verdict « partiellement testable » du §10 Tests est optimiste. Sans texte RGPD et sans durée de rétention, l'invariant INV-298-06 est cosmétique.
- Gravité : Majeur
NT-07 — TC-NOM-13 « état backend modifié entre deux consultations »¶
- Type : Non testable (non déterministe)
- Référence :
tests TC-NOM-13 - Description : Le scénario implique une mutation d'état depuis un « autre terminal ». Orchestration multi-acteurs non définie, pas de mécanisme de mock figé (clock, concurrence). Test non reproductible en CI sans harnais spécifique non spécifié.
- Gravité : Mineur
NT-08 — TC-NOM-04 « visibilité vérifiable au moment exact de l'action »¶
- Type : Non testable (observable flou)
- Référence :
tests TC-NOM-04 - Description : Sur mobile, « visible » dépend du viewport, du scroll et de l'état du clavier. L'observable « visibilité à l'instant du clic CTA » n'est pas défini (bounding-box dans viewport ? opacity > 0 ? accessibility ? pourcentage visible ?).
- Gravité : Majeur
4. Incohérences Spec ↔ Tests¶
I-01 — CA-287-27 référencée sans être redéfinie dans PD-298¶
- Type : Incohérence Spec↔Tests
- Référence :
spec §3 (CA-287-27),tests TC-NOM-04 (colonne "Référence spec: CA-287-27") - Description : La matrice de couverture §2 des tests lie INV-298-06 à « CA-287-27 » — un CA appartenant à une autre story. Le tableau ne référence aucun CA de PD-298 alors que CA-298-11 existe pour INV-298-06. Couplage externe implicite non sourcé dans la spec PD-298.
- Impact : Si PD-287 fait évoluer CA-287-27, les tests PD-298 deviennent incohérents sans changement dans PD-298. Traçabilité rompue.
- Gravité : Majeur
I-02 — INV-298-11 / CA-298-15 et matrice §5.5 : actions UI non énumérées¶
- Type : Incohérence
- Référence :
spec INV-298-11 / CA-298-15,spec §5.5 (matrice "INTERDITE/AUTORISÉE"),tests TC-NOM-08 / TC-NR-03 - Description : La matrice §5.5 liste les transitions, pas les actions UI disponibles (boutons visibles). L'invariant INV-298-11 dit « actions disponibles DOIVENT dépendre de l'état (matrice contractuelle §5.5) ». La correspondance « transition autorisée backend ↔ bouton visible UI » n'est pas donnée explicitement (ex : pour OTP_BLOCKED, seul Revoke est autorisé côté transitions ; ça se traduit par quels boutons visibles/invisibles/disabled ?).
- Impact : TC-NOM-08 et TC-NR-03 comparent à une matrice qui n'existe pas formellement. Verdict dépendant de l'interprétation du développeur.
- Gravité : Majeur
I-03 — Matrice de couverture §2 tests : INV-298-11 et INV-298-14/15 liés au même CA et au même test¶
- Type : Incohérence
- Référence :
tests §2 matrice - Description : INV-298-11 (actions disponibles selon état), INV-298-14 (transitions interdites) et INV-298-15 (terminaux) pointent toutes vers CA-298-15 et TC-NOM-16/TC-NOM-08. CA-298-15 parle de « boutons visibles/invisibles selon
shareState» — ce qui couvre INV-298-11 mais pas INV-298-14/15 (lesquels parlent de transitions et de terminaux). - Impact : Couverture surjective ; un test seul prétend couvrir 3 invariants de natures différentes. Difficile de tracer une régression.
- Gravité : Majeur
I-04 — INV-298-13 pagination, mais aucun test sur limit != 20 côté réponse¶
- Type : Incohérence
- Référence :
spec INV-298-13,tests TC-NOM-05 / TC-NEG-02 - Description : TC-NEG-02 « Tentative de forcer
limit != 20» teste le comportement UI (la requête envoyée). Aucun test ne couvre le cas où le backend répond avec une page non conforme à la demande (ex :limit=19). La règle «limit=20fixe MVP » est une contrainte de requête, pas de réception. - Gravité : Mineur
I-05 — CA-298-02 « aucune requête réseau » mais aucune exclusion des requêtes latérales¶
- Type : Incohérence
- Référence :
spec CA-298-02,tests TC-NOM-02 / TC-ERR-01 - Description : Le test observe « 0 requête POST /shares ». L'invariant dit « un email invalide NE DOIT PAS être soumis ». Ni l'un ni l'autre n'exclut les requêtes latérales (analytics, telemetry de validation échouée, Sentry breadcrumbs HTTP). Testabilité non déterministe si le projet a un client analytics.
- Gravité : Mineur
I-06 — Tests TC-NOM-07 (preuve non possédée) : prémisse d'accès incohérente¶
- Type : Incohérence
- Référence :
tests TC-NOM-07,spec INV-298-12 - Description : « A ouvre l'écran détail d'une preuve possédée par B ». La spec PD-298 ne précise pas si un utilisateur A peut consulter le détail d'une preuve de B (ce serait un autre module,
proofs). Si c'est impossible par défaut, TC-NOM-07 est dégénéré (écran inatteignable). Si c'est possible (preuve partagée, admin, etc.), c'est un contexte pré-existant hors périmètre PD-298. - Impact : Le test dépend d'un contexte métier non établi dans la spec.
- Gravité : Majeur
I-07 — §7 CA vs §2 matrice tests : champs « CA » manquants dans la matrice¶
- Type : Incohérence
- Référence :
tests §2 matrice de couverture,spec §7 CA-298-01 à CA-298-15 - Description : La matrice couvre les invariants INV mais toutes les colonnes « ID Critère » ne correspondent pas bijectivement aux CA §7. Ex : INV-298-06 est lié à CA-287-27 (externe) ; INV-298-17 à « N/A ». Aucune matrice CA→Test explicite.
- Impact : Un CA non couvert peut passer inaperçu (ex : CA-298-08 figure en matrice mais la couverture CA-298-11 repose sur CA-287-27 plutôt que CA-298-11).
- Gravité : Mineur
I-08 — ERR-298-11 (401) : test TC-ERR-11 présume un « flux auth existant »¶
- Type : Incohérence / dépendance externe
- Référence :
spec ERR-298-11,tests TC-ERR-11 - Description : Le test exige une « redirection vers flux auth existant ». Ni la spec ni les tests ne définissent ce flux (route, composant, état post-retour). Dépendance externe non tracée.
- Gravité : Mineur
5. Hypothèses dangereuses¶
H-01 — H-298-02 / H-298-03 pagination offset/limit¶
- Type : Hypothèse dangereuse
- Référence :
spec H-298-02 / H-298-03,spec INV-298-13 - Description : La spec présume que PD-287 expose une pagination
offset/limitaveclimit=20acceptable. Si le backend utilise cursor-based pagination, tout INV-298-13 et TC-NOM-05 sont inapplicables. Aucune vérification n'est planifiée avant implémentation. - Impact : Réécriture complète de la liste globale en cours d'implémentation. Glissement de périmètre.
- Gravité : Majeur
H-02 — H-298-06 compatibilité matrice UI ↔ backend¶
- Type : Hypothèse dangereuse
- Référence :
spec H-298-06,spec §5.5,spec §10.2 PC-298-04 - Description : « Les transitions backend réelles sont compatibles avec la matrice §5.5 » — non vérifiée. PC-298-04 le dit aussi : matrice backend non jointe. Toute divergence = écart majeur post-implémentation.
- Gravité : Majeur
H-03 — Idempotence POST /shares et POST /revoke non spécifiée¶
- Type : Hypothèse dangereuse
- Référence :
spec F-298-01 §7,spec F-298-04 §4 - Description : Aucune règle d'idempotence (clé idempotente, debounce UI, blocage pendant in-flight) n'est définie. Un double-tap créera potentiellement 2 shares, ou enverra 2 revokes. Le backend PD-287 peut ou non gérer cela.
- Impact : Duplications, PII doublement envoyée, événements d'audit doublonnés, métriques biaisées.
- Gravité : Majeur
H-04 — Normalisation / internationalisation de l'email¶
- Type : Hypothèse dangereuse
- Référence :
spec §5.1 (recipientEmail "ASCII printable sans espace terminal"),spec §5bis ("normaliser(email)") - Description : L'ASCII-only interdit les emails IDN (RFC 6531/6532, courants en FR/EU). La normalisation non contractualisée peut altérer silencieusement l'input. Risque d'exclusion d'utilisateurs légitimes et divergence avec la regex D-287-03 (si D-287-03 autorise l'unicode).
- Gravité : Majeur
H-05 — Horloge expiresAt affichée¶
- Type : Hypothèse dangereuse
- Référence :
spec §5.1 (expiresAt),spec INV-298-04 - Description : Aucune spec sur l'horloge affichée (device vs serveur). Le TTL côté UI peut diverger de la réalité backend (clock skew). Un lien affiché « expire dans 3 min » peut être déjà expiré serveur-side.
- Impact : Confusion UX + risque de support client.
- Gravité : Mineur
H-06 — INV-298-05 fraîcheur réseau : UX sur connexions lentes¶
- Type : Hypothèse dangereuse
- Référence :
spec INV-298-05,spec §5.2 ("aucun objectif perf chiffré") - Description : Appel réseau obligatoire à chaque ouverture d'écran + pas de SLA perf = UX dégradée sur 3G/edge. Pas de mention de skeleton, de cache stale-with-indicator ou de timeout borné.
- Impact : Risque d'abandon, risque de spinners infinis en timeout.
- Gravité : Mineur
H-07 — Race condition état concurrent sur révocation¶
- Type : Hypothèse dangereuse
- Référence :
spec F-298-04,spec INV-298-05 - Description : Entre l'affichage de la modale ARB-7 et la confirmation, l'état peut avoir changé backend (EXPIRED, déjà REVOKED sur autre device). Aucun re-check avant POST /revoke. Pas de gestion du 409/410 dans la spec d'erreurs.
- Impact : L'utilisateur peut confirmer une révocation sur un état périmé. Pas bloquant mais UX incohérente.
- Gravité : Mineur
H-08 — H-298-08 qualification juridique RGPD « hors périmètre UI »¶
- Type : Hypothèse dangereuse (acceptation silencieuse)
- Référence :
spec H-298-08,spec §9 - Description : Hypothèse correcte en principe, mais elle conditionne INV-298-06 et CA-298-11 à un contenu juridique absent (cf. A-04, NT-06). Cantonner « hors périmètre UI » la qualification juridique ne dispense pas d'avoir le texte à afficher.
- Gravité : Majeur
H-09 — « Aucun mécanisme de protection distribuée » (§5.6)¶
- Type : Hypothèse dangereuse
- Référence :
spec §5.6 - Description : La spec affirme « aucun mécanisme de protection distribuée applicable (module synchrone mono-instance) ». Pour la création de share depuis plusieurs devices du même utilisateur, il peut y avoir conflits, et anti-spam côté client absent. Affirmation sans analyse.
- Gravité : Mineur
6. Risques sécurité / conformité¶
S-01 — Fuite PII via crash reports et analytics¶
- Type : Risque sécurité/conformité
- Référence :
spec INV-298-07,tests §8 ("Export probatoire : HAR réseau, captures écran"),tests TC-NOM-15 - Description :
recipientEmailfigure dans les payloads API (HAR), dans les rendus écran (captures), et potentiellement dans les breadcrumbs Sentry/analytics automatiques (URL, paramètres, screenshots de bug report). Aucune règle de scrubbing n'est imposée. - Impact : Fuite PII vers vendors externes (Sentry, Datadog, Firebase) sans base légale dédiée.
- Gravité : Majeur
S-02 — Absence de scrubbing PII dans l'export probatoire des tests¶
- Type : Risque sécurité/conformité
- Référence :
tests §8 (observabilité requise) - Description : HAR réseau + captures écran sont explicitement exigés comme artefacts. Ces artefacts contiendront emails et IP brutes avant masquage côté rendu. Aucun protocole de scrubbing avant archivage.
- Gravité : Majeur
S-03 — Anti-enumeration INV-298-16 côté UI uniquement¶
- Type : Risque sécurité/conformité
- Référence :
spec INV-298-16,tests TC-NEG-01 / TC-NEG-08 - Description : L'invariant porte uniquement sur « le client NE DOIT PAS effectuer d'appels exploratoires ». Un attaquant avec l'app réverse-engineerée ou les endpoints documentés peut contourner l'UI. L'anti-enumeration est une obligation backend (PD-287), pas UI. L'invariant placé ici crée une fausse assurance.
- Gravité : Majeur
S-04 — Absence de clearing in-memory au logout / session expirée¶
- Type : Risque sécurité/conformité
- Référence :
spec ERR-298-11,spec INV-298-05 - Description : ERR-298-11 gère le 401 par redirection vers le flux auth. Rien n'indique que les données de share en mémoire (liste, détail, journal) doivent être purgées au logout ou à l'expiration de session. Risque de persistance résiduelle.
- Gravité : Majeur
S-05 — drmWarningSeen par userId côté device : multi-device et reset¶
- Type : Risque sécurité/conformité / UX
- Référence :
spec INV-298-03,spec §5.1 - Description : Le flag est local-par-compte-par-device. Un utilisateur qui se connecte sur un autre device ne verra pas l'avertissement DRM (il n'existe pas sur ce device). L'invariant « information explicite sur l'absence de DRM » n'est garanti qu'une fois par device, pas une fois par compte. La règle contractuelle est plus faible qu'annoncée.
- Gravité : Majeur
S-06 — Pas de règle clipboard / share sheet pour l'email destinataire¶
- Type : Risque sécurité/conformité
- Référence :
spec INV-298-07 - Description : L'email figure à l'écran dans la liste et le détail. Rien n'interdit à l'OS (iOS share sheet, Android intent) de le véhiculer hors app, ou à l'utilisateur de le copier. Pas non plus de disclaimer RGPD utilisateur.
- Gravité : Mineur
S-07 — Aucun rate-limit / throttling UI¶
- Type : Risque sécurité/conformité
- Référence :
spec F-298-01(flux création) - Description : Aucune règle anti-spam côté UI (délai entre 2 créations, blocage du bouton in-flight). Couplé à H-03 (idempotence absente), risque d'abus trivial et d'overwhelming du backend. Les abus documentés dans RGPD/logs peuvent aussi générer des notifications massives côté destinataires.
- Gravité : Majeur
S-08 — 403 « géré sans fuite » non spécifié¶
- Type : Risque sécurité/conformité
- Référence :
spec ERR-298-07,tests TC-ERR-07 - Description : « 403 géré sans fuite » est un objectif, pas une règle : aucun message d'erreur normatif n'est défini, aucun mapping « 403 → message utilisateur ». Risque d'afficher le message d'erreur backend tel quel (ex :
Forbidden: proof X not owned by user Y). - Gravité : Majeur
S-09 — Journal : export et watermark absent¶
- Type : Risque sécurité/conformité
- Référence :
spec F-298-05,spec CA-298-08 - Description : Le journal affiche email + IP masquée + device + horodatage. Aucune règle concernant la capture d'écran, l'export, ou le watermark de confidentialité. Risque de fuite de PII de destinataires dans des canaux non contrôlés.
- Gravité : Mineur
S-10 — TC-NEG-05 / TC-NEG-06 : état/eventType inconnu non remonté¶
- Type : Risque conformité
- Référence :
tests TC-NEG-05 / TC-NEG-06 - Description : Une réponse backend avec un état ou un eventType non documenté est affichée comme erreur / UNKNOWN_EVENT, mais aucune règle n'impose de remontée observabilité (télémétrie interne, alerte). Dette silencieuse.
- Gravité : Mineur
S-11 — Deep-linking / CSP mobile explicitement exclus, sans garde¶
- Type : Risque sécurité/conformité
- Référence :
spec §2 (Exclu : deep linking) - Description : Exclure la feature ne suffit pas à garantir qu'un deeplink natif ne puisse déclencher l'écran de création partage (React Navigation expose ce comportement par défaut). Aucune garde de navigation explicite.
- Gravité : Mineur
Synthèse des constats par gravité¶
| Gravité | Nombre | IDs |
|---|---|---|
| Bloquant | 4 | A-01, A-04, A-05, NT-03 |
| Majeur | 25 | A-02, A-03, A-06, A-07, A-09, A-13, C-02, C-03, C-05, C-07, NT-01, NT-02, NT-04, NT-05, NT-06, NT-08, I-01, I-02, I-03, I-06, H-01, H-02, H-03, H-04, H-08, S-01, S-02, S-03, S-04, S-05, S-07, S-08 |
| Mineur | 15 | A-08, A-10, A-11, A-12, C-01, C-04, C-06, C-08, NT-07, I-04, I-05, I-07, I-08, H-05, H-06, H-07, H-09, S-06, S-09, S-10, S-11 |
(Totaux : 4 bloquants + 32 majeurs + 21 mineurs — certains écarts ont été indexés sous plusieurs sections.)
Remarques finales¶
- Chemin critique bloquant : la spec repose sur quatre éléments contractuels absents (A-01 regex D-287-03, A-04 contenu RGPD, A-05 textes ARB-7/ARB-8, NT-03 qui recoupe A-05). Trois invariants non négociables (INV-298-01, INV-298-02, INV-298-06) ne peuvent être vérifiés contractuellement en l'état.
- Glissement FSM : C-02, C-03 et H-02 concentrent un risque structurel — la matrice d'états est présentée à la fois comme autoritative (INV-298-14/15) et comme dépendante d'un backend non audité. À trancher en Gate 5 avant implémentation.
- Enveloppe PII : S-01/S-02/S-04/S-05/S-07 convergent vers un manque de hardening transversal sur le traitement des emails destinataires. INV-298-07 nécessite au minimum : règles de scrubbing (Sentry/analytics/HAR), purge in-memory au logout, rate-limiting UI.
- Diagrammes : C-07 et C-06 indiquent des écarts diagramme ↔ spec. Le diagramme de séquence doit au minimum couvrir la révocation (ARB-7) et la pagination ; la matrice §5.5 doit soit accueillir les self-loops, soit le diagramme doit les retirer.