diff --git a/joj3_config_generator/convert.py b/joj3_config_generator/convert.py
index 84da0bb..d522871 100644
--- a/joj3_config_generator/convert.py
+++ b/joj3_config_generator/convert.py
@@ -91,7 +91,6 @@ def convert(repo_conf: repo.Config, task_conf: task.Config) -> result.Config:
         conf_stage = fix_result_detail(task_stage, conf_stage)
         conf_stage = fix_comment(task_stage, conf_stage)
         conf_stage = fix_keyword(task_stage, conf_stage)
-        # TODO: fix diff parser here
         conf_stage = fix_diff(task_stage, conf_stage)
         result_conf.stage.stages.append(conf_stage)
 
diff --git a/joj3_config_generator/lib/task.py b/joj3_config_generator/lib/task.py
index d8d2f78..35aa92b 100644
--- a/joj3_config_generator/lib/task.py
+++ b/joj3_config_generator/lib/task.py
@@ -1,5 +1,6 @@
 import rtoml
 
+from joj3_config_generator.models.result import CmdFile, OptionalCmd
 from joj3_config_generator.models.result import Stage as ResultStage
 from joj3_config_generator.models.task import Stage as TaskStage
 
@@ -78,5 +79,73 @@ def fix_comment(task_stage: TaskStage, conf_stage: ResultStage) -> ResultStage:
 
 
 def fix_diff(task_stage: TaskStage, conf_stage: ResultStage) -> ResultStage:
+    if task_stage.parsers is not None and "diff" in task_stage.parsers:
+        diff_parser = next((p for p in conf_stage.parsers if p.name == "diff"), None)
+        skip = task_stage.skip or []
+        cases = task_stage.cases or {}
+        finalized_cases = [case for case in cases if case not in skip]
+
+        stage_cases = []
+        parser_cases = []
+
+        for case in finalized_cases:
+            case_stage = task_stage.cases.get(case) if task_stage.cases else None
+            if not case_stage:
+                continue
+
+            # Ensure case_stage.limit is defined before accessing .cpu and .mem
+            cpu_limit = (
+                case_stage.limit.cpu * 1_000_000_000
+                if case_stage.limit and case_stage.limit.cpu is not None
+                else 0
+            )
+            clock_limit = (
+                2 * case_stage.limit.cpu * 1_000_000_000
+                if case_stage.limit and case_stage.limit.cpu is not None
+                else 0
+            )
+            memory_limit = (
+                case_stage.limit.mem * 1_024 * 1_024
+                if case_stage.limit and case_stage.limit.mem is not None
+                else 0
+            )
+
+            stage_cases.append(
+                OptionalCmd(
+                    stdin=CmdFile(
+                        src=f"/home/tt/.config/joj/{conf_stage.name}/{case}.in"
+                    ),
+                    cpu_limit=cpu_limit,
+                    clock_limit=clock_limit,
+                    memory_limit=memory_limit,
+                    proc_limit=50,
+                )
+            )
+
+            # Ensure case_stage.diff and case_stage.diff.output are defined
+            diff_output = (
+                case_stage.diff.output
+                if case_stage.diff and case_stage.diff.output
+                else None
+            )
+            if diff_output:
+                parser_cases.append(
+                    {
+                        "outputs": [
+                            {
+                                "score": diff_output.score,
+                                "fileName": "stdout",
+                                "answerPath": f"/home/tt/.config/joj/{conf_stage.name}/{case}.out",
+                                "forceQuitOnDiff": diff_output.forcequit,
+                                "alwaysHide": diff_output.hide,
+                                "compareSpace": not diff_output.ignorespaces,
+                            }
+                        ]
+                    }
+                )
+
+        if diff_parser and task_stage.diff is not None:
+            diff_parser.with_.update({"name": "diff", "cases": parser_cases})
+            conf_stage.executor.with_.cases = stage_cases
 
     return conf_stage
diff --git a/joj3_config_generator/models/task.py b/joj3_config_generator/models/task.py
index cef87f1..e77b9d8 100644
--- a/joj3_config_generator/models/task.py
+++ b/joj3_config_generator/models/task.py
@@ -52,7 +52,7 @@ class Stage(BaseModel):
     files: Optional[Files] = None
     score: Optional[int] = 0
     parsers: Optional[list[str]] = []  # list of parsers
-    limit: Optional[Limit] = None
+    limit: Optional[Limit] = Limit()
     dummy: Optional[ParserDummy] = ParserDummy()
     result_status: Optional[ParserDummy] = Field(ParserDummy(), alias="result-status")
     keyword: Optional[ParserKeyword] = ParserKeyword()
diff --git a/tests/convert/basic/task.json b/tests/convert/basic/task.json
index 7ce0682..65a21ff 100644
--- a/tests/convert/basic/task.json
+++ b/tests/convert/basic/task.json
@@ -18,7 +18,7 @@
                                 "/<function",
                                 "get_temp_directory",
                                 "at",
-                                "0x7f932c5e31a0>/repo-health-checker",
+                                "0x7f67094f3240>/repo-health-checker",
                                 "-root=.",
                                 "-repoSize=50.5",
                                 "-meta=main.py",
@@ -71,8 +71,8 @@
                             "cpuRateLimit": 0,
                             "cpuSetLimit": "",
                             "copyIn": {
-                                "//tmp/repo-checker-tw0902sa/repo-health-checker": {
-                                    "src": "//tmp/repo-checker-4sy3g0ro/repo-health-checker",
+                                "//tmp/repo-checker-9gy9931v/repo-health-checker": {
+                                    "src": "//tmp/repo-checker-kjnt9uw0/repo-health-checker",
                                     "content": null,
                                     "fileId": null,
                                     "name": null,
@@ -886,13 +886,168 @@
                             "dataSegmentLimit": false,
                             "addressSpaceLimit": false
                         },
-                        "cases": []
+                        "cases": [
+                            {
+                                "args": null,
+                                "env": [
+                                    "PATH=/usr/bin:/bin:/usr/local/bin"
+                                ],
+                                "stdin": {
+                                    "src": "/home/tt/.config/joj/judge-base/case4.in",
+                                    "content": null,
+                                    "fileId": null,
+                                    "name": null,
+                                    "max": 4194304,
+                                    "symlink": null,
+                                    "streamIn": false,
+                                    "streamOut": false,
+                                    "pipe": false
+                                },
+                                "stdout": null,
+                                "stderr": null,
+                                "cpuLimit": 30000000000,
+                                "realCpuLimit": null,
+                                "clockLimit": 60000000000,
+                                "memoryLimit": 10485760,
+                                "stackLimit": null,
+                                "procLimit": 50,
+                                "cpuRateLimit": null,
+                                "cpuSetLimit": null,
+                                "copyIn": null,
+                                "copyInCached": null,
+                                "copyInDir": null,
+                                "copyOut": null,
+                                "copyOutCached": null,
+                                "copyOutMax": null,
+                                "copyOutDir": null,
+                                "tty": null,
+                                "strictMemoryLimit": null,
+                                "dataSegmentLimit": null,
+                                "addressSpaceLimit": null
+                            },
+                            {
+                                "args": null,
+                                "env": [
+                                    "PATH=/usr/bin:/bin:/usr/local/bin"
+                                ],
+                                "stdin": {
+                                    "src": "/home/tt/.config/joj/judge-base/case5.in",
+                                    "content": null,
+                                    "fileId": null,
+                                    "name": null,
+                                    "max": 4194304,
+                                    "symlink": null,
+                                    "streamIn": false,
+                                    "streamOut": false,
+                                    "pipe": false
+                                },
+                                "stdout": null,
+                                "stderr": null,
+                                "cpuLimit": 4000000000,
+                                "realCpuLimit": null,
+                                "clockLimit": 8000000000,
+                                "memoryLimit": 4194304,
+                                "stackLimit": null,
+                                "procLimit": 50,
+                                "cpuRateLimit": null,
+                                "cpuSetLimit": null,
+                                "copyIn": null,
+                                "copyInCached": null,
+                                "copyInDir": null,
+                                "copyOut": null,
+                                "copyOutCached": null,
+                                "copyOutMax": null,
+                                "copyOutDir": null,
+                                "tty": null,
+                                "strictMemoryLimit": null,
+                                "dataSegmentLimit": null,
+                                "addressSpaceLimit": null
+                            },
+                            {
+                                "args": null,
+                                "env": [
+                                    "PATH=/usr/bin:/bin:/usr/local/bin"
+                                ],
+                                "stdin": {
+                                    "src": "/home/tt/.config/joj/judge-base/case8.in",
+                                    "content": null,
+                                    "fileId": null,
+                                    "name": null,
+                                    "max": 4194304,
+                                    "symlink": null,
+                                    "streamIn": false,
+                                    "streamOut": false,
+                                    "pipe": false
+                                },
+                                "stdout": null,
+                                "stderr": null,
+                                "cpuLimit": 4000000000,
+                                "realCpuLimit": null,
+                                "clockLimit": 8000000000,
+                                "memoryLimit": 4194304,
+                                "stackLimit": null,
+                                "procLimit": 50,
+                                "cpuRateLimit": null,
+                                "cpuSetLimit": null,
+                                "copyIn": null,
+                                "copyInCached": null,
+                                "copyInDir": null,
+                                "copyOut": null,
+                                "copyOutCached": null,
+                                "copyOutMax": null,
+                                "copyOutDir": null,
+                                "tty": null,
+                                "strictMemoryLimit": null,
+                                "dataSegmentLimit": null,
+                                "addressSpaceLimit": null
+                            }
+                        ]
                     }
                 },
                 "parsers": [
                     {
                         "name": "diff",
-                        "with": {}
+                        "with": {
+                            "name": "diff",
+                            "cases": [
+                                {
+                                    "outputs": [
+                                        {
+                                            "score": 0,
+                                            "fileName": "stdout",
+                                            "answerPath": "/home/tt/.config/joj/judge-base/case4.out",
+                                            "forceQuitOnDiff": true,
+                                            "alwaysHide": false,
+                                            "compareSpace": true
+                                        }
+                                    ]
+                                },
+                                {
+                                    "outputs": [
+                                        {
+                                            "score": 0,
+                                            "fileName": "stdout",
+                                            "answerPath": "/home/tt/.config/joj/judge-base/case5.out",
+                                            "forceQuitOnDiff": true,
+                                            "alwaysHide": false,
+                                            "compareSpace": true
+                                        }
+                                    ]
+                                },
+                                {
+                                    "outputs": [
+                                        {
+                                            "score": 0,
+                                            "fileName": "stdout",
+                                            "answerPath": "/home/tt/.config/joj/judge-base/case8.out",
+                                            "forceQuitOnDiff": true,
+                                            "alwaysHide": false,
+                                            "compareSpace": true
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
                     },
                     {
                         "name": "dummy",
@@ -982,13 +1137,168 @@
                             "dataSegmentLimit": false,
                             "addressSpaceLimit": false
                         },
-                        "cases": []
+                        "cases": [
+                            {
+                                "args": null,
+                                "env": [
+                                    "PATH=/usr/bin:/bin:/usr/local/bin"
+                                ],
+                                "stdin": {
+                                    "src": "/home/tt/.config/joj/judge-msan/case4.in",
+                                    "content": null,
+                                    "fileId": null,
+                                    "name": null,
+                                    "max": 4194304,
+                                    "symlink": null,
+                                    "streamIn": false,
+                                    "streamOut": false,
+                                    "pipe": false
+                                },
+                                "stdout": null,
+                                "stderr": null,
+                                "cpuLimit": 30000000000,
+                                "realCpuLimit": null,
+                                "clockLimit": 60000000000,
+                                "memoryLimit": 10485760,
+                                "stackLimit": null,
+                                "procLimit": 50,
+                                "cpuRateLimit": null,
+                                "cpuSetLimit": null,
+                                "copyIn": null,
+                                "copyInCached": null,
+                                "copyInDir": null,
+                                "copyOut": null,
+                                "copyOutCached": null,
+                                "copyOutMax": null,
+                                "copyOutDir": null,
+                                "tty": null,
+                                "strictMemoryLimit": null,
+                                "dataSegmentLimit": null,
+                                "addressSpaceLimit": null
+                            },
+                            {
+                                "args": null,
+                                "env": [
+                                    "PATH=/usr/bin:/bin:/usr/local/bin"
+                                ],
+                                "stdin": {
+                                    "src": "/home/tt/.config/joj/judge-msan/case5.in",
+                                    "content": null,
+                                    "fileId": null,
+                                    "name": null,
+                                    "max": 4194304,
+                                    "symlink": null,
+                                    "streamIn": false,
+                                    "streamOut": false,
+                                    "pipe": false
+                                },
+                                "stdout": null,
+                                "stderr": null,
+                                "cpuLimit": 4000000000,
+                                "realCpuLimit": null,
+                                "clockLimit": 8000000000,
+                                "memoryLimit": 4194304,
+                                "stackLimit": null,
+                                "procLimit": 50,
+                                "cpuRateLimit": null,
+                                "cpuSetLimit": null,
+                                "copyIn": null,
+                                "copyInCached": null,
+                                "copyInDir": null,
+                                "copyOut": null,
+                                "copyOutCached": null,
+                                "copyOutMax": null,
+                                "copyOutDir": null,
+                                "tty": null,
+                                "strictMemoryLimit": null,
+                                "dataSegmentLimit": null,
+                                "addressSpaceLimit": null
+                            },
+                            {
+                                "args": null,
+                                "env": [
+                                    "PATH=/usr/bin:/bin:/usr/local/bin"
+                                ],
+                                "stdin": {
+                                    "src": "/home/tt/.config/joj/judge-msan/case6.in",
+                                    "content": null,
+                                    "fileId": null,
+                                    "name": null,
+                                    "max": 4194304,
+                                    "symlink": null,
+                                    "streamIn": false,
+                                    "streamOut": false,
+                                    "pipe": false
+                                },
+                                "stdout": null,
+                                "stderr": null,
+                                "cpuLimit": 4000000000,
+                                "realCpuLimit": null,
+                                "clockLimit": 8000000000,
+                                "memoryLimit": 4194304,
+                                "stackLimit": null,
+                                "procLimit": 50,
+                                "cpuRateLimit": null,
+                                "cpuSetLimit": null,
+                                "copyIn": null,
+                                "copyInCached": null,
+                                "copyInDir": null,
+                                "copyOut": null,
+                                "copyOutCached": null,
+                                "copyOutMax": null,
+                                "copyOutDir": null,
+                                "tty": null,
+                                "strictMemoryLimit": null,
+                                "dataSegmentLimit": null,
+                                "addressSpaceLimit": null
+                            }
+                        ]
                     }
                 },
                 "parsers": [
                     {
                         "name": "diff",
-                        "with": {}
+                        "with": {
+                            "name": "diff",
+                            "cases": [
+                                {
+                                    "outputs": [
+                                        {
+                                            "score": 0,
+                                            "fileName": "stdout",
+                                            "answerPath": "/home/tt/.config/joj/judge-msan/case4.out",
+                                            "forceQuitOnDiff": true,
+                                            "alwaysHide": false,
+                                            "compareSpace": true
+                                        }
+                                    ]
+                                },
+                                {
+                                    "outputs": [
+                                        {
+                                            "score": 0,
+                                            "fileName": "stdout",
+                                            "answerPath": "/home/tt/.config/joj/judge-msan/case5.out",
+                                            "forceQuitOnDiff": true,
+                                            "alwaysHide": false,
+                                            "compareSpace": true
+                                        }
+                                    ]
+                                },
+                                {
+                                    "outputs": [
+                                        {
+                                            "score": 0,
+                                            "fileName": "stdout",
+                                            "answerPath": "/home/tt/.config/joj/judge-msan/case6.out",
+                                            "forceQuitOnDiff": true,
+                                            "alwaysHide": true,
+                                            "compareSpace": true
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
                     },
                     {
                         "name": "dummy",