// ======================================== // FICHIER: ErrorGrave.js // RESPONSABILITÉ: Erreurs GRAVES (10% articles max) // Visibles mais crédibles - faute de frappe sérieuse ou distraction // ======================================== const { logSh } = require('../../ErrorReporting'); /** * DÉFINITIONS ERREURS GRAVES * Probabilité globale: 10% des articles * Maximum: 1 erreur grave par article */ const ERREURS_GRAVES = { // ======================================== // ACCORD SUJET-VERBE INCORRECT // ======================================== accord_sujet_verbe: { name: 'Accord sujet-verbe incorrect', probability: 0.3, // 30% si erreur grave sélectionnée examples: [ { pattern: /\bils (est|a)\b/gi, correction: 'ils sont/ont' }, { pattern: /\bnous (est|a)\b/gi, correction: 'nous sommes/avons' }, { pattern: /\belles (est|a)\b/gi, correction: 'elles sont/ont' } ], apply: (content) => { let modified = content; let applied = false; // Chercher "ils sont" ou "ils ont" et les remplacer if (!applied && Math.random() < 0.5) { const regex = /\bils sont\b/gi; if (modified.match(regex)) { modified = modified.replace(regex, 'ils est'); applied = true; logSh(` ❌ Erreur grave: "ils sont" → "ils est"`, 'DEBUG'); } } if (!applied && Math.random() < 0.5) { const regex = /\bils ont\b/gi; if (modified.match(regex)) { modified = modified.replace(regex, 'ils a'); applied = true; logSh(` ❌ Erreur grave: "ils ont" → "ils a"`, 'DEBUG'); } } return { content: modified, applied }; } }, // ======================================== // MOT MANQUANT (omission) // ======================================== mot_manquant: { name: 'Mot manquant (omission)', probability: 0.25, // 25% si erreur grave examples: [ { pattern: 'pour garantir la qualité', error: 'pour garantir qualité' }, { pattern: 'dans le but de', error: 'dans but de' }, { pattern: 'il est important de', error: 'il important de' } ], apply: (content) => { let modified = content; let applied = false; // Supprimer article défini aléatoirement const patterns = [ { from: /\bpour garantir la qualité\b/gi, to: 'pour garantir qualité' }, { from: /\bdans le but de\b/gi, to: 'dans but de' }, { from: /\bil est important de\b/gi, to: 'il important de' }, { from: /\bpour la durabilité\b/gi, to: 'pour durabilité' } ]; for (const pattern of patterns) { if (applied) break; if (modified.match(pattern.from) && Math.random() < 0.5) { modified = modified.replace(pattern.from, pattern.to); applied = true; logSh(` ❌ Erreur grave: mot manquant`, 'DEBUG'); break; } } return { content: modified, applied }; } }, // ======================================== // DOUBLE MOT (copier-coller raté) // ======================================== double_mot: { name: 'Double mot (répétition)', probability: 0.25, // 25% si erreur grave examples: [ { pattern: 'pour garantir', error: 'pour pour garantir' }, { pattern: 'de la qualité', error: 'de de la qualité' } ], apply: (content) => { let modified = content; let applied = false; // Insérer doublon sur mots courants const words = content.split(' '); const targetWords = ['pour', 'de', 'la', 'le', 'et', 'dans']; for (let i = 0; i < words.length && !applied; i++) { const word = words[i].toLowerCase(); if (targetWords.includes(word) && Math.random() < 0.3) { words.splice(i, 0, words[i]); // Dupliquer le mot applied = true; logSh(` ❌ Erreur grave: "${word}" dupliqué`, 'DEBUG'); break; } } if (applied) { modified = words.join(' '); } return { content: modified, applied }; } }, // ======================================== // NÉGATION OUBLIÉE // ======================================== negation_oubliee: { name: 'Négation oubliée', probability: 0.20, // 20% si erreur grave examples: [ { pattern: "n'est pas nécessaire", error: "est pas nécessaire" }, { pattern: "ne sont pas", error: "sont pas" } ], apply: (content) => { let modified = content; let applied = false; // Supprimer "ne" ou "n'" dans négations const patterns = [ { from: /\bn'est pas\b/gi, to: 'est pas' }, { from: /\bne sont pas\b/gi, to: 'sont pas' }, { from: /\bn'ont pas\b/gi, to: 'ont pas' } ]; for (const pattern of patterns) { if (applied) break; if (modified.match(pattern.from) && Math.random() < 0.5) { modified = modified.replace(pattern.from, pattern.to); applied = true; logSh(` ❌ Erreur grave: négation oubliée`, 'DEBUG'); break; } } return { content: modified, applied }; } } }; /** * APPLIQUER UNE ERREUR GRAVE * @param {string} content - Contenu à modifier * @param {object} tracker - HumanSimulationTracker instance * @returns {object} - { content, applied, errorType } */ function applyErrorGrave(content, tracker = null) { // Vérifier avec tracker si erreur grave déjà appliquée if (tracker && tracker.graveErrorApplied) { logSh(`🚫 Erreur grave bloquée: déjà 1 erreur grave dans cet article`, 'DEBUG'); return { content, applied: false, errorType: null }; } // Sélectionner type d'erreur aléatoirement selon probabilités const errorTypes = Object.keys(ERREURS_GRAVES); const selectedType = errorTypes[Math.floor(Math.random() * errorTypes.length)]; const errorDefinition = ERREURS_GRAVES[selectedType]; logSh(`🎲 Tentative erreur grave: ${errorDefinition.name}`, 'DEBUG'); // Appliquer l'erreur const result = errorDefinition.apply(content); if (result.applied) { logSh(`✅ Erreur grave appliquée: ${errorDefinition.name}`, 'DEBUG'); // Marquer dans tracker if (tracker) { tracker.graveErrorApplied = true; } } return { content: result.content, applied: result.applied, errorType: result.applied ? selectedType : null }; } /** * OBTENIR STATISTIQUES ERREURS GRAVES */ function getErrorGraveStats() { return { totalTypes: Object.keys(ERREURS_GRAVES).length, types: Object.keys(ERREURS_GRAVES), globalProbability: '10%', maxPerArticle: 1 }; } // ============= EXPORTS ============= module.exports = { ERREURS_GRAVES, applyErrorGrave, getErrorGraveStats };