diff --git a/helpers/Dojo/ExerciceResultsValidation.ts b/helpers/Dojo/ExerciceResultsValidation.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9b91ceed6716ecce08e94d3ca25c0e83451f1f1d
--- /dev/null
+++ b/helpers/Dojo/ExerciceResultsValidation.ts
@@ -0,0 +1,74 @@
+import { TypedEmitter }      from 'tiny-typed-emitter';
+import ExerciceRunningEvents from '../../types/Dojo/ExerciceRunningEvents';
+import ExerciceCheckerError  from '../../../shared/types/Dojo/ExerciceCheckerError';
+import path                  from 'node:path';
+import SharedExerciceHelper  from '../../../shared/helpers/Dojo/SharedExerciceHelper';
+import ClientsSharedConfig   from '../../config/ClientsSharedConfig';
+import Toolbox               from '../../../shared/helpers/Toolbox';
+import * as fs               from 'fs-extra';
+import ExerciceResultsFile   from '../../../shared/types/Dojo/ExerciceResultsFile';
+
+
+class ExerciceResultsValidation {
+    readonly events: TypedEmitter<ExerciceRunningEvents> = new TypedEmitter<ExerciceRunningEvents>();
+
+    public exerciceResults: ExerciceResultsFile | undefined = undefined;
+
+    constructor(private folderResultsDojo: string, private folderResultsExercice: string) { }
+
+    run() {
+        (async () => {
+            let resultsFilePath: string;
+
+
+            // Results file existence
+            {
+                this.events.emit('step', 'CHECK_RESULTS_FILE_EXIST', 'Checking if results file exists');
+                const resultsFileOriginPath = path.join(this.folderResultsExercice, ClientsSharedConfig.filenames.results);
+                resultsFilePath = path.join(this.folderResultsDojo, ClientsSharedConfig.filenames.results);
+
+                if ( !fs.existsSync(resultsFileOriginPath) ) {
+                    this.events.emit('endStep', 'CHECK_RESULTS_FILE_EXIST', `Results file not found`, true);
+                    this.events.emit('finished', false, ExerciceCheckerError.EXERCICE_RESULTS_FILE_NOT_FOUND);
+                    return;
+                }
+                this.events.emit('endStep', 'CHECK_RESULTS_FILE_EXIST', 'Results file found', false);
+
+                fs.moveSync(resultsFileOriginPath, resultsFilePath, { overwrite: true });
+            }
+
+
+            // Results file schema validation
+            {
+                this.events.emit('step', 'VALIDATE_RESULTS_FILE', 'Validating results file schema');
+                const validationResults = SharedExerciceHelper.validateResultFile(resultsFilePath);
+                if ( !validationResults.isValid ) {
+                    this.events.emit('endStep', 'VALIDATE_RESULTS_FILE', `Results file is not valid. Here are the errors :\n${ JSON.stringify(validationResults.errors) }`, true);
+                    this.events.emit('finished', false, ExerciceCheckerError.EXERCICE_RESULTS_FILE_SCHEMA_NOT_VALID);
+                    return;
+                }
+                this.exerciceResults = validationResults.results;
+                this.events.emit('endStep', 'VALIDATE_RESULTS_FILE', 'Results file found', false);
+            }
+
+
+            // Results folder size
+            // ATTENTION: This test is at the end because even if it fail the local execution will continue and we need the other test above to be done
+            {
+                this.events.emit('step', 'CHECK_SIZE', 'Validating results folder size');
+                const resultsFolderSize = await Toolbox.fs.getTotalSize(this.folderResultsExercice);
+                if ( resultsFolderSize > ClientsSharedConfig.exerciceResultsFolderMaxSizeInBytes ) {
+                    this.events.emit('endStep', 'CHECK_SIZE', `Results folder size is too big (bigger than ${ ClientsSharedConfig.exerciceResultsFolderMaxSizeInBytes / 1000000 } MB)`, true);
+                    this.events.emit('finished', false, ExerciceCheckerError.EXERCICE_RESULTS_FOLDER_TOO_BIG);
+                    return;
+                }
+                this.events.emit('endStep', 'CHECK_SIZE', 'Validating results folder size', false);
+            }
+
+            this.events.emit('finished', true, 0);
+        })();
+    }
+}
+
+
+export default ExerciceResultsValidation;
\ No newline at end of file