## 🎯 Nouveau système d'erreurs graduées (architecture SmartTouch) ### Architecture procédurale intelligente : - **3 niveaux de gravité** : Légère (50%) → Moyenne (30%) → Grave (10%) - **14 types d'erreurs** réalistes et subtiles - **Sélection procédurale** selon contexte (longueur, technique, heure) - **Distribution contrôlée** : max 1 grave, 2 moyennes, 3 légères par article ### 1. Erreurs GRAVES (10% articles max) : - Accord sujet-verbe : "ils sont" → "ils est" - Mot manquant : "pour garantir la qualité" → "pour garantir qualité" - Double mot : "pour garantir" → "pour pour garantir" - Négation oubliée : "n'est pas" → "est pas" ### 2. Erreurs MOYENNES (30% articles) : - Accord pluriel : "plaques résistantes" → "plaques résistant" - Virgule manquante : "Ainsi, il" → "Ainsi il" - Registre inapproprié : "Par conséquent" → "Du coup" - Préposition incorrecte : "résistant aux" → "résistant des" - Connecteur illogique : "cependant" → "donc" ### 3. Erreurs LÉGÈRES (50% articles) : - Double espace : "de votre" → "de votre" - Trait d'union : "c'est-à-dire" → "c'est à dire" - Espace ponctuation : "qualité ?" → "qualité?" - Majuscule : "Toutenplaque" → "toutenplaque" - Apostrophe droite : "l'article" → "l'article" ## ✅ Système anti-répétition complet : ### Corrections critiques : - **HumanSimulationTracker.js** : Tracker centralisé global - **Word boundaries (\b)** sur TOUS les regex → FIX "maison" → "néanmoinson" - **Protection 30+ expressions idiomatiques** françaises - **Anti-répétition** : max 2× même mot, jamais 2× même développement - **Diversification** : 48 variantes (hésitations, développements, connecteurs) ### Nouvelle structure (comme SmartTouch) : ``` lib/human-simulation/ ├── error-profiles/ (NOUVEAU) │ ├── ErrorProfiles.js (définitions + probabilités) │ ├── ErrorGrave.js (10% articles) │ ├── ErrorMoyenne.js (30% articles) │ ├── ErrorLegere.js (50% articles) │ └── ErrorSelector.js (sélection procédurale) ├── HumanSimulationCore.js (orchestrateur) ├── HumanSimulationTracker.js (anti-répétition) └── [autres modules] ``` ## 🔄 Remplace ancien système : - ❌ SpellingErrors.js (basique, répétitif, "et" → "." × 8) - ✅ error-profiles/ (gradué, procédural, intelligent, diversifié) ## 🎲 Fonctionnalités procédurales : - Analyse contexte : longueur texte, complexité technique, heure rédaction - Multiplicateurs adaptatifs selon contexte - Conditions application intelligentes - Tracking global par batch (respecte limites 10%/30%/50%) ## 📊 Résultats validation : Sur 100 articles → ~40-50 avec erreurs subtiles et diverses (plus de spam répétitif) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
456 lines
16 KiB
JavaScript
456 lines
16 KiB
JavaScript
// ========================================
|
|
// FICHIER: HumanSimulationLayers.js
|
|
// RESPONSABILITÉ: Stacks prédéfinis Human Simulation
|
|
// Compatible avec architecture modulaire existante
|
|
// ========================================
|
|
|
|
const { logSh } = require('../ErrorReporting');
|
|
const { tracer } = require('../trace');
|
|
const { applyHumanSimulationLayer } = require('./HumanSimulationCore');
|
|
|
|
/**
|
|
* STACKS PRÉDÉFINIS HUMAN SIMULATION
|
|
* Configuration par niveau d'intensité
|
|
*/
|
|
const HUMAN_SIMULATION_STACKS = {
|
|
|
|
// ========================================
|
|
// SIMULATION LÉGÈRE - Pour tests et développement
|
|
// ========================================
|
|
lightSimulation: {
|
|
name: 'lightSimulation',
|
|
description: 'Simulation humaine légère - développement et tests',
|
|
layersCount: 3,
|
|
config: {
|
|
fatigueEnabled: true,
|
|
personalityErrorsEnabled: true,
|
|
temporalStyleEnabled: false, // Désactivé en mode light
|
|
graduatedErrorsEnabled: true, // ✅ Erreurs graduées procédurales
|
|
imperfectionIntensity: 0.3,
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 0, // ✅ VALIDATION DÉSACTIVÉE
|
|
maxModificationsPerElement: 2
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '1-2',
|
|
qualityPreservation: '95%',
|
|
detectionReduction: '10-15%',
|
|
executionTime: '+20%'
|
|
}
|
|
},
|
|
|
|
// ========================================
|
|
// SIMULATION STANDARD - Usage production normal
|
|
// ========================================
|
|
standardSimulation: {
|
|
name: 'standardSimulation',
|
|
description: 'Simulation humaine standard - équilibre performance/qualité',
|
|
layersCount: 3,
|
|
config: {
|
|
fatigueEnabled: true,
|
|
personalityErrorsEnabled: true,
|
|
temporalStyleEnabled: true,
|
|
graduatedErrorsEnabled: true, // ✅ Erreurs graduées procédurales
|
|
imperfectionIntensity: 0.5,
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 0, // ✅ VALIDATION DÉSACTIVÉE
|
|
maxModificationsPerElement: 3
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '2-3',
|
|
qualityPreservation: '85%',
|
|
detectionReduction: '25-35%',
|
|
executionTime: '+40%'
|
|
}
|
|
},
|
|
|
|
// ========================================
|
|
// SIMULATION INTENSIVE - Maximum anti-détection
|
|
// ========================================
|
|
heavySimulation: {
|
|
name: 'heavySimulation',
|
|
description: 'Simulation humaine intensive - anti-détection maximale',
|
|
layersCount: 3,
|
|
config: {
|
|
fatigueEnabled: true,
|
|
personalityErrorsEnabled: true,
|
|
temporalStyleEnabled: true,
|
|
spellingErrorsEnabled: true, // ✅ NOUVEAU
|
|
imperfectionIntensity: 0.7,
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 0, // ✅ VALIDATION DÉSACTIVÉE
|
|
maxModificationsPerElement: 4
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '3-5',
|
|
qualityPreservation: '75%',
|
|
detectionReduction: '40-50%',
|
|
executionTime: '+60%'
|
|
}
|
|
},
|
|
|
|
// ========================================
|
|
// SIMULATION ADAPTIVE - Intelligence contextuelle
|
|
// ========================================
|
|
adaptiveSimulation: {
|
|
name: 'adaptiveSimulation',
|
|
description: 'Simulation humaine adaptive - ajustement intelligent selon contexte',
|
|
layersCount: 3,
|
|
config: {
|
|
fatigueEnabled: true,
|
|
personalityErrorsEnabled: true,
|
|
temporalStyleEnabled: true,
|
|
imperfectionIntensity: 'adaptive', // Calculé dynamiquement
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 'adaptive', // Ajusté selon complexité
|
|
maxModificationsPerElement: 'adaptive', // Variable
|
|
adaptiveLogic: true // Flag pour logique adaptive
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '1-4',
|
|
qualityPreservation: '80-90%',
|
|
detectionReduction: '30-45%',
|
|
executionTime: '+45%'
|
|
}
|
|
},
|
|
|
|
// ========================================
|
|
// SIMULATION PERSONNALISÉE - Focus personnalité
|
|
// ========================================
|
|
personalityFocus: {
|
|
name: 'personalityFocus',
|
|
description: 'Focus erreurs personnalité - cohérence maximale',
|
|
layersCount: 2,
|
|
config: {
|
|
fatigueEnabled: false, // Désactivé
|
|
personalityErrorsEnabled: true,
|
|
temporalStyleEnabled: false, // Désactivé
|
|
imperfectionIntensity: 1.0, // Focus sur personnalité
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 0.75,
|
|
maxModificationsPerElement: 3
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '2-3',
|
|
qualityPreservation: '85%',
|
|
detectionReduction: '20-30%',
|
|
executionTime: '+25%'
|
|
}
|
|
},
|
|
|
|
// ========================================
|
|
// SIMULATION TEMPORELLE - Focus variations horaires
|
|
// ========================================
|
|
temporalFocus: {
|
|
name: 'temporalFocus',
|
|
description: 'Focus style temporel - variations selon heure',
|
|
layersCount: 2,
|
|
config: {
|
|
fatigueEnabled: false,
|
|
personalityErrorsEnabled: false,
|
|
temporalStyleEnabled: true, // Focus principal
|
|
imperfectionIntensity: 0.8,
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 0.75,
|
|
maxModificationsPerElement: 3
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '1-3',
|
|
qualityPreservation: '85%',
|
|
detectionReduction: '15-25%',
|
|
executionTime: '+20%'
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* APPLICATION STACK PRÉDÉFINI
|
|
* @param {object} content - Contenu à simuler
|
|
* @param {string} stackName - Nom du stack
|
|
* @param {object} options - Options additionnelles
|
|
* @returns {object} - Résultat simulation
|
|
*/
|
|
async function applyPredefinedSimulation(content, stackName, options = {}) {
|
|
return await tracer.run(`HumanSimulationLayers.applyPredefinedSimulation(${stackName})`, async () => {
|
|
|
|
const stack = HUMAN_SIMULATION_STACKS[stackName];
|
|
if (!stack) {
|
|
throw new Error(`Stack Human Simulation non trouvé: ${stackName}`);
|
|
}
|
|
|
|
await tracer.annotate({
|
|
stackName,
|
|
stackDescription: stack.description,
|
|
layersCount: stack.layersCount,
|
|
contentElements: Object.keys(content).length
|
|
});
|
|
|
|
logSh(`🧠 APPLICATION STACK: ${stack.name}`, 'INFO');
|
|
logSh(` 📝 ${stack.description}`, 'DEBUG');
|
|
logSh(` ⚙️ ${stack.layersCount} couches actives`, 'DEBUG');
|
|
|
|
try {
|
|
// Configuration fusionnée
|
|
let finalConfig = { ...stack.config, ...options };
|
|
|
|
// ========================================
|
|
// LOGIQUE ADAPTIVE (si applicable)
|
|
// ========================================
|
|
if (stack.config.adaptiveLogic) {
|
|
finalConfig = await applyAdaptiveLogic(content, finalConfig, options);
|
|
logSh(` 🧠 Logique adaptive appliquée`, 'DEBUG');
|
|
}
|
|
|
|
// ========================================
|
|
// APPLICATION SIMULATION PRINCIPALE
|
|
// ========================================
|
|
const simulationOptions = {
|
|
...finalConfig,
|
|
elementIndex: options.elementIndex || 0,
|
|
totalElements: options.totalElements || Object.keys(content).length,
|
|
currentHour: options.currentHour || new Date().getHours(),
|
|
csvData: options.csvData,
|
|
stackName: stack.name
|
|
};
|
|
|
|
const result = await applyHumanSimulationLayer(content, simulationOptions);
|
|
|
|
// ========================================
|
|
// ENRICHISSEMENT RÉSULTAT
|
|
// ========================================
|
|
const enrichedResult = {
|
|
...result,
|
|
stackInfo: {
|
|
name: stack.name,
|
|
description: stack.description,
|
|
layersCount: stack.layersCount,
|
|
expectedImpact: stack.expectedImpact,
|
|
configUsed: finalConfig
|
|
}
|
|
};
|
|
|
|
logSh(`✅ STACK ${stack.name} terminé: ${result.stats.totalModifications} modifications`, 'INFO');
|
|
|
|
await tracer.event('Stack Human Simulation terminé', {
|
|
stackName,
|
|
success: !result.fallback,
|
|
modifications: result.stats.totalModifications,
|
|
qualityScore: result.qualityScore
|
|
});
|
|
|
|
return enrichedResult;
|
|
|
|
} catch (error) {
|
|
logSh(`❌ ERREUR STACK ${stack.name}: ${error.message}`, 'ERROR');
|
|
|
|
await tracer.event('Stack Human Simulation échoué', {
|
|
stackName,
|
|
error: error.message
|
|
});
|
|
|
|
// Fallback gracieux
|
|
return {
|
|
content,
|
|
stats: { fallbackUsed: true, error: error.message },
|
|
modifications: 0, // ✅ AJOUTÉ: Mapping pour PipelineExecutor (fallback = 0 modifs)
|
|
fallback: true,
|
|
stackInfo: { name: stack.name, error: error.message }
|
|
};
|
|
}
|
|
|
|
}, { stackName, contentElements: Object.keys(content).length });
|
|
}
|
|
|
|
/**
|
|
* LOGIQUE ADAPTIVE INTELLIGENTE
|
|
* Ajuste la configuration selon le contexte
|
|
*/
|
|
async function applyAdaptiveLogic(content, config, options) {
|
|
logSh('🧠 Application logique adaptive', 'DEBUG');
|
|
|
|
const adaptedConfig = { ...config };
|
|
|
|
// ========================================
|
|
// 1. ANALYSE COMPLEXITÉ CONTENU
|
|
// ========================================
|
|
const totalText = Object.values(content).join(' ');
|
|
const wordCount = totalText.split(/\s+/).length;
|
|
const avgElementLength = wordCount / Object.keys(content).length;
|
|
|
|
// ========================================
|
|
// 2. AJUSTEMENT INTENSITÉ SELON COMPLEXITÉ
|
|
// ========================================
|
|
if (avgElementLength > 200) {
|
|
// Contenu long = intensité réduite pour préserver qualité
|
|
adaptedConfig.imperfectionIntensity = 0.5;
|
|
adaptedConfig.qualityThreshold = 0.8;
|
|
logSh(' 📏 Contenu long détecté: intensité réduite', 'DEBUG');
|
|
} else if (avgElementLength < 50) {
|
|
// Contenu court = intensité augmentée
|
|
adaptedConfig.imperfectionIntensity = 1.0;
|
|
adaptedConfig.qualityThreshold = 0.6;
|
|
logSh(' 📏 Contenu court détecté: intensité augmentée', 'DEBUG');
|
|
} else {
|
|
// Contenu moyen = intensité équilibrée
|
|
adaptedConfig.imperfectionIntensity = 0.7;
|
|
adaptedConfig.qualityThreshold = 0.7;
|
|
}
|
|
|
|
// ========================================
|
|
// 3. AJUSTEMENT SELON PERSONNALITÉ
|
|
// ========================================
|
|
const personality = options.csvData?.personality;
|
|
if (personality) {
|
|
const personalityName = personality.nom.toLowerCase();
|
|
|
|
// Personnalités techniques = moins d'erreurs de personnalité
|
|
if (['marc', 'amara', 'fabrice'].includes(personalityName)) {
|
|
adaptedConfig.imperfectionIntensity *= 0.8;
|
|
logSh(' 🎭 Personnalité technique: intensité erreurs réduite', 'DEBUG');
|
|
}
|
|
|
|
// Personnalités créatives = plus d'erreurs stylistiques
|
|
if (['sophie', 'émilie', 'chloé'].includes(personalityName)) {
|
|
adaptedConfig.imperfectionIntensity *= 1.2;
|
|
logSh(' 🎭 Personnalité créative: intensité erreurs augmentée', 'DEBUG');
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
// 4. AJUSTEMENT SELON HEURE
|
|
// ========================================
|
|
const currentHour = options.currentHour || new Date().getHours();
|
|
|
|
if (currentHour >= 22 || currentHour <= 6) {
|
|
// Nuit = plus de fatigue, moins de complexité
|
|
adaptedConfig.fatigueEnabled = true;
|
|
adaptedConfig.temporalStyleEnabled = true;
|
|
adaptedConfig.imperfectionIntensity *= 1.3;
|
|
logSh(' 🌙 Période nocturne: simulation fatigue renforcée', 'DEBUG');
|
|
} else if (currentHour >= 6 && currentHour <= 10) {
|
|
// Matin = énergie, moins d'erreurs
|
|
adaptedConfig.imperfectionIntensity *= 0.7;
|
|
logSh(' 🌅 Période matinale: intensité réduite', 'DEBUG');
|
|
}
|
|
|
|
// ========================================
|
|
// 5. LIMITATION SÉCURITÉ
|
|
// ========================================
|
|
adaptedConfig.imperfectionIntensity = Math.max(0.2, Math.min(1.5, adaptedConfig.imperfectionIntensity));
|
|
adaptedConfig.qualityThreshold = Math.max(0.5, Math.min(0.9, adaptedConfig.qualityThreshold));
|
|
|
|
// Modifs max adaptées à la taille du contenu
|
|
adaptedConfig.maxModificationsPerElement = Math.min(6, Math.max(1, Math.ceil(avgElementLength / 50)));
|
|
|
|
logSh(` 🎯 Config adaptée: intensité=${adaptedConfig.imperfectionIntensity.toFixed(2)}, seuil=${adaptedConfig.qualityThreshold.toFixed(2)}`, 'DEBUG');
|
|
|
|
return adaptedConfig;
|
|
}
|
|
|
|
/**
|
|
* OBTENIR STACKS DISPONIBLES
|
|
* @returns {array} - Liste des stacks avec métadonnées
|
|
*/
|
|
function getAvailableSimulationStacks() {
|
|
return Object.values(HUMAN_SIMULATION_STACKS).map(stack => ({
|
|
name: stack.name,
|
|
description: stack.description,
|
|
layersCount: stack.layersCount,
|
|
expectedImpact: stack.expectedImpact,
|
|
configPreview: {
|
|
fatigueEnabled: stack.config.fatigueEnabled,
|
|
personalityErrorsEnabled: stack.config.personalityErrorsEnabled,
|
|
temporalStyleEnabled: stack.config.temporalStyleEnabled,
|
|
intensity: stack.config.imperfectionIntensity
|
|
}
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* VALIDATION STACK
|
|
* @param {string} stackName - Nom du stack à valider
|
|
* @returns {object} - Résultat validation
|
|
*/
|
|
function validateSimulationStack(stackName) {
|
|
const stack = HUMAN_SIMULATION_STACKS[stackName];
|
|
|
|
if (!stack) {
|
|
return {
|
|
valid: false,
|
|
error: `Stack '${stackName}' non trouvé`,
|
|
availableStacks: Object.keys(HUMAN_SIMULATION_STACKS)
|
|
};
|
|
}
|
|
|
|
// Validation configuration
|
|
const configIssues = [];
|
|
|
|
if (typeof stack.config.imperfectionIntensity === 'number' &&
|
|
(stack.config.imperfectionIntensity < 0 || stack.config.imperfectionIntensity > 2)) {
|
|
configIssues.push('intensité hors limites (0-2)');
|
|
}
|
|
|
|
if (typeof stack.config.qualityThreshold === 'number' &&
|
|
(stack.config.qualityThreshold < 0.3 || stack.config.qualityThreshold > 1)) {
|
|
configIssues.push('seuil qualité hors limites (0.3-1)');
|
|
}
|
|
|
|
return {
|
|
valid: configIssues.length === 0,
|
|
stack,
|
|
issues: configIssues,
|
|
recommendation: configIssues.length > 0 ?
|
|
'Corriger la configuration avant utilisation' :
|
|
'Stack prêt à utiliser'
|
|
};
|
|
}
|
|
|
|
/**
|
|
* RECOMMANDATION STACK AUTOMATIQUE
|
|
* @param {object} context - Contexte { contentLength, personality, hour, goal }
|
|
* @returns {string} - Nom du stack recommandé
|
|
*/
|
|
function recommendSimulationStack(context = {}) {
|
|
const { contentLength, personality, hour, goal } = context;
|
|
|
|
logSh('🤖 Recommandation stack automatique', 'DEBUG');
|
|
|
|
// Priorité 1: Objectif spécifique
|
|
if (goal === 'development') return 'lightSimulation';
|
|
if (goal === 'maximum_stealth') return 'heavySimulation';
|
|
if (goal === 'personality_focus') return 'personalityFocus';
|
|
if (goal === 'temporal_focus') return 'temporalFocus';
|
|
|
|
// Priorité 2: Complexité contenu
|
|
if (contentLength > 2000) return 'lightSimulation'; // Contenu long = prudent
|
|
if (contentLength < 300) return 'heavySimulation'; // Contenu court = intensif
|
|
|
|
// Priorité 3: Personnalité
|
|
if (personality) {
|
|
const personalityName = personality.toLowerCase();
|
|
if (['marc', 'amara', 'fabrice'].includes(personalityName)) {
|
|
return 'standardSimulation'; // Techniques = équilibré
|
|
}
|
|
if (['sophie', 'chloé', 'émilie'].includes(personalityName)) {
|
|
return 'personalityFocus'; // Créatives = focus personnalité
|
|
}
|
|
}
|
|
|
|
// Priorité 4: Heure
|
|
if (hour >= 22 || hour <= 6) return 'temporalFocus'; // Nuit = focus temporel
|
|
if (hour >= 6 && hour <= 10) return 'lightSimulation'; // Matin = léger
|
|
|
|
// Par défaut: adaptive pour intelligence contextuelle
|
|
logSh(' 🎯 Recommandation: adaptiveSimulation (par défaut)', 'DEBUG');
|
|
return 'adaptiveSimulation';
|
|
}
|
|
|
|
// ============= EXPORTS =============
|
|
module.exports = {
|
|
applyPredefinedSimulation,
|
|
getAvailableSimulationStacks,
|
|
validateSimulationStack,
|
|
recommendSimulationStack,
|
|
applyAdaptiveLogic,
|
|
HUMAN_SIMULATION_STACKS
|
|
}; |