diff --git a/joj3_config_generator/convert.py b/joj3_config_generator/convert.py
index 6331631..c683ddc 100644
--- a/joj3_config_generator/convert.py
+++ b/joj3_config_generator/convert.py
@@ -45,7 +45,7 @@ def convert(repo_conf: repo.Config, task_conf: task.Config) -> result.Config:
     # Construct healthcheck stage
     if (
         not repo_conf.force_skip_heatlh_check_on_test
-        # or os.environ.get("PYTEST_CURRENT_TEST") is None
+        or os.environ.get("PYTEST_CURRENT_TEST") is None
     ):
         healthcheck_stage = get_healthcheck_config(repo_conf)
         result_conf.stage.stages.append(healthcheck_stage)
diff --git a/tests/convert/clang-tidy/immutable_files/.gitattributes b/tests/convert/clang-tidy/immutable_files/.gitattributes
deleted file mode 100644
index b910c4a..0000000
--- a/tests/convert/clang-tidy/immutable_files/.gitattributes
+++ /dev/null
@@ -1,33 +0,0 @@
-*.avi filter=lfs diff=lfs merge=lfs -text
-*.bz2 filter=lfs diff=lfs merge=lfs -text
-*.djvu filter=lfs diff=lfs merge=lfs -text
-*.doc filter=lfs diff=lfs merge=lfs -text
-*.docx filter=lfs diff=lfs merge=lfs -text
-*.epub filter=lfs diff=lfs merge=lfs -text
-*.gz filter=lfs diff=lfs merge=lfs -text
-*.ipynb filter=lfs diff=lfs merge=lfs -text
-*.jpeg filter=lfs diff=lfs merge=lfs -text
-*.JPEG filter=lfs diff=lfs merge=lfs -text
-*.jpg filter=lfs diff=lfs merge=lfs -text
-*.JPG filter=lfs diff=lfs merge=lfs -text
-*.mkv filter=lfs diff=lfs merge=lfs -text
-*.mp4 filter=lfs diff=lfs merge=lfs -text
-*.ods filter=lfs diff=lfs merge=lfs -text
-*.odt filter=lfs diff=lfs merge=lfs -text
-*.otf filter=lfs diff=lfs merge=lfs -text
-*.pdf filter=lfs diff=lfs merge=lfs -text
-*.PDF filter=lfs diff=lfs merge=lfs -text
-*.png filter=lfs diff=lfs merge=lfs -text
-*.PNG filter=lfs diff=lfs merge=lfs -text
-*.ppt filter=lfs diff=lfs merge=lfs -text
-*.pptx filter=lfs diff=lfs merge=lfs -text
-*.ps filter=lfs diff=lfs merge=lfs -text
-*.rar filter=lfs diff=lfs merge=lfs -text
-*.tar filter=lfs diff=lfs merge=lfs -text
-*.tgz filter=lfs diff=lfs merge=lfs -text
-*.ttf filter=lfs diff=lfs merge=lfs -text
-*.webm filter=lfs diff=lfs merge=lfs -text
-*.xls filter=lfs diff=lfs merge=lfs -text
-*.xlsx filter=lfs diff=lfs merge=lfs -text
-*.xz filter=lfs diff=lfs merge=lfs -text
-*.zip filter=lfs diff=lfs merge=lfs -text
diff --git a/tests/convert/clang-tidy/immutable_files/.gitignore b/tests/convert/clang-tidy/immutable_files/.gitignore
deleted file mode 100644
index 754f776..0000000
--- a/tests/convert/clang-tidy/immutable_files/.gitignore
+++ /dev/null
@@ -1,23 +0,0 @@
-################################
-## White list based gitignore ##
-################################
-
-# forbidden
-*
-.*
-
-# allowed
-!.gitignore
-!.gitattributes
-!.gitea/
-!.gitea/issue_template/
-!.gitea/workflows/
-!*.yaml
-!Makefile
-!CMakeLists.txt
-!h[0-8]/
-!*.m
-!*.c
-!*.cpp
-!*.h
-!*.md
diff --git a/tests/convert/clang-tidy/immutable_files/push.yaml b/tests/convert/clang-tidy/immutable_files/push.yaml
deleted file mode 100644
index 664f371..0000000
--- a/tests/convert/clang-tidy/immutable_files/push.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: Run JOJ3 on Push
-on: [push]
-
-jobs:
-  run:
-    container:
-      image: focs.ji.sjtu.edu.cn:5000/gitea/runner-images:focs-ubuntu-latest-slim
-      volumes:
-        - /home/tt/.config:/home/tt/.config
-        - /home/tt/.cache:/home/tt/.cache
-        - /home/tt/.ssh:/home/tt/.ssh
-    steps:
-      - name: Check out repository code
-        uses: https://gitea.com/BoYanZh/checkout@focs
-        with:
-          fetch-depth: 0
-      - name: run joj3
-        run: |
-          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/homework
diff --git a/tests/convert/clang-tidy/immutable_files/release.yaml b/tests/convert/clang-tidy/immutable_files/release.yaml
deleted file mode 100644
index e740403..0000000
--- a/tests/convert/clang-tidy/immutable_files/release.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Run JOJ3 on Release
-on:
-  release:
-    types: [published]
-
-jobs:
-  run:
-    container:
-      image: focs.ji.sjtu.edu.cn:5000/gitea/runner-images:focs-ubuntu-latest-slim
-      volumes:
-        - /home/tt/.config:/home/tt/.config
-        - /home/tt/.cache:/home/tt/.cache
-        - /home/tt/.ssh:/home/tt/.ssh
-    steps:
-      - name: Check out repository code
-        uses: https://gitea.com/BoYanZh/checkout@focs
-        with:
-          fetch-depth: 0
-      - name: run joj3
-        run: |
-          sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/homework" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"
diff --git a/tests/convert/clang-tidy/task.json b/tests/convert/clang-tidy/task.json
index 5c68e1b..8c8ed9f 100644
--- a/tests/convert/clang-tidy/task.json
+++ b/tests/convert/clang-tidy/task.json
@@ -10,6 +10,111 @@
         "sandboxToken": "",
         "outputPath": "/tmp/joj3_result.json",
         "stages": [
+            {
+                "name": "healthcheck",
+                "group": "",
+                "executor": {
+                    "name": "local",
+                    "with": {
+                        "default": {
+                            "env": [
+                                "PATH=/usr/bin:/bin:/usr/local/bin"
+                            ],
+                            "stdin": {
+                                "content": "",
+                                "max": 419430400
+                            },
+                            "stdout": {
+                                "name": "stdout",
+                                "max": 4096
+                            },
+                            "stderr": {
+                                "name": "stderr",
+                                "max": 4096
+                            },
+                            "cpuLimit": 4000000000000,
+                            "realCpuLimit": 0,
+                            "clockLimit": 8000000000000,
+                            "memoryLimit": 838860800,
+                            "stackLimit": 0,
+                            "procLimit": 50,
+                            "cpuRateLimit": 0,
+                            "cpuSetLimit": "",
+                            "copyIn": {},
+                            "copyInCached": {},
+                            "copyInDir": ".",
+                            "copyOut": [
+                                "stdout",
+                                "stderr"
+                            ],
+                            "copyOutCached": [],
+                            "copyOutMax": 0,
+                            "copyOutDir": "",
+                            "tty": false,
+                            "strictMemoryLimit": false,
+                            "dataSegmentLimit": false,
+                            "addressSpaceLimit": false
+                        },
+                        "cases": [
+                            {
+                                "args": [
+                                    "/usr/local/bin/repo-health-checker",
+                                    "-root=.",
+                                    "-repoSize=10",
+                                    "-checkFileSumList=-checkFileNameList="
+                                ],
+                                "env": [
+                                    "PATH=/usr/bin:/bin:/usr/local/bin"
+                                ],
+                                "cpuLimit": 4000000000000,
+                                "clockLimit": 8000000000000,
+                                "memoryLimit": 838860800,
+                                "procLimit": 50,
+                                "copyOut": [
+                                    "stdout",
+                                    "stderr"
+                                ]
+                            },
+                            {
+                                "args": [
+                                    "/usr/local/bin/joint-teapot",
+                                    "joj3-check-env",
+                                    "/home/tt/.config/teapot/teapot.env",
+                                    "--grading-repo-name",
+                                    "ece280-joj",
+                                    "--group-config",
+                                    "=100:24"
+                                ],
+                                "env": [
+                                    "LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"
+                                ],
+                                "cpuLimit": 4000000000000,
+                                "clockLimit": 8000000000000,
+                                "memoryLimit": 838860800,
+                                "procLimit": 50,
+                                "copyOut": [
+                                    "stdout",
+                                    "stderr"
+                                ]
+                            }
+                        ]
+                    }
+                },
+                "parsers": [
+                    {
+                        "name": "healthcheck",
+                        "with": {
+                            "score": 1
+                        }
+                    },
+                    {
+                        "name": "debug",
+                        "with": {
+                            "score": 0
+                        }
+                    }
+                ]
+            },
             {
                 "name": "[cq] Clang-tidy",
                 "group": "cq",
diff --git a/tests/convert/cppcheck/immutable_files/.gitattributes b/tests/convert/cppcheck/immutable_files/.gitattributes
deleted file mode 100644
index b910c4a..0000000
--- a/tests/convert/cppcheck/immutable_files/.gitattributes
+++ /dev/null
@@ -1,33 +0,0 @@
-*.avi filter=lfs diff=lfs merge=lfs -text
-*.bz2 filter=lfs diff=lfs merge=lfs -text
-*.djvu filter=lfs diff=lfs merge=lfs -text
-*.doc filter=lfs diff=lfs merge=lfs -text
-*.docx filter=lfs diff=lfs merge=lfs -text
-*.epub filter=lfs diff=lfs merge=lfs -text
-*.gz filter=lfs diff=lfs merge=lfs -text
-*.ipynb filter=lfs diff=lfs merge=lfs -text
-*.jpeg filter=lfs diff=lfs merge=lfs -text
-*.JPEG filter=lfs diff=lfs merge=lfs -text
-*.jpg filter=lfs diff=lfs merge=lfs -text
-*.JPG filter=lfs diff=lfs merge=lfs -text
-*.mkv filter=lfs diff=lfs merge=lfs -text
-*.mp4 filter=lfs diff=lfs merge=lfs -text
-*.ods filter=lfs diff=lfs merge=lfs -text
-*.odt filter=lfs diff=lfs merge=lfs -text
-*.otf filter=lfs diff=lfs merge=lfs -text
-*.pdf filter=lfs diff=lfs merge=lfs -text
-*.PDF filter=lfs diff=lfs merge=lfs -text
-*.png filter=lfs diff=lfs merge=lfs -text
-*.PNG filter=lfs diff=lfs merge=lfs -text
-*.ppt filter=lfs diff=lfs merge=lfs -text
-*.pptx filter=lfs diff=lfs merge=lfs -text
-*.ps filter=lfs diff=lfs merge=lfs -text
-*.rar filter=lfs diff=lfs merge=lfs -text
-*.tar filter=lfs diff=lfs merge=lfs -text
-*.tgz filter=lfs diff=lfs merge=lfs -text
-*.ttf filter=lfs diff=lfs merge=lfs -text
-*.webm filter=lfs diff=lfs merge=lfs -text
-*.xls filter=lfs diff=lfs merge=lfs -text
-*.xlsx filter=lfs diff=lfs merge=lfs -text
-*.xz filter=lfs diff=lfs merge=lfs -text
-*.zip filter=lfs diff=lfs merge=lfs -text
diff --git a/tests/convert/cppcheck/immutable_files/.gitignore b/tests/convert/cppcheck/immutable_files/.gitignore
deleted file mode 100644
index 754f776..0000000
--- a/tests/convert/cppcheck/immutable_files/.gitignore
+++ /dev/null
@@ -1,23 +0,0 @@
-################################
-## White list based gitignore ##
-################################
-
-# forbidden
-*
-.*
-
-# allowed
-!.gitignore
-!.gitattributes
-!.gitea/
-!.gitea/issue_template/
-!.gitea/workflows/
-!*.yaml
-!Makefile
-!CMakeLists.txt
-!h[0-8]/
-!*.m
-!*.c
-!*.cpp
-!*.h
-!*.md
diff --git a/tests/convert/cppcheck/immutable_files/push.yaml b/tests/convert/cppcheck/immutable_files/push.yaml
deleted file mode 100644
index 664f371..0000000
--- a/tests/convert/cppcheck/immutable_files/push.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: Run JOJ3 on Push
-on: [push]
-
-jobs:
-  run:
-    container:
-      image: focs.ji.sjtu.edu.cn:5000/gitea/runner-images:focs-ubuntu-latest-slim
-      volumes:
-        - /home/tt/.config:/home/tt/.config
-        - /home/tt/.cache:/home/tt/.cache
-        - /home/tt/.ssh:/home/tt/.ssh
-    steps:
-      - name: Check out repository code
-        uses: https://gitea.com/BoYanZh/checkout@focs
-        with:
-          fetch-depth: 0
-      - name: run joj3
-        run: |
-          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/homework
diff --git a/tests/convert/cppcheck/immutable_files/release.yaml b/tests/convert/cppcheck/immutable_files/release.yaml
deleted file mode 100644
index e740403..0000000
--- a/tests/convert/cppcheck/immutable_files/release.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Run JOJ3 on Release
-on:
-  release:
-    types: [published]
-
-jobs:
-  run:
-    container:
-      image: focs.ji.sjtu.edu.cn:5000/gitea/runner-images:focs-ubuntu-latest-slim
-      volumes:
-        - /home/tt/.config:/home/tt/.config
-        - /home/tt/.cache:/home/tt/.cache
-        - /home/tt/.ssh:/home/tt/.ssh
-    steps:
-      - name: Check out repository code
-        uses: https://gitea.com/BoYanZh/checkout@focs
-        with:
-          fetch-depth: 0
-      - name: run joj3
-        run: |
-          sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/homework" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"
diff --git a/tests/convert/cppcheck/task.json b/tests/convert/cppcheck/task.json
index f88faff..dab704d 100644
--- a/tests/convert/cppcheck/task.json
+++ b/tests/convert/cppcheck/task.json
@@ -10,6 +10,111 @@
         "sandboxToken": "",
         "outputPath": "/tmp/joj3_result.json",
         "stages": [
+            {
+                "name": "healthcheck",
+                "group": "",
+                "executor": {
+                    "name": "local",
+                    "with": {
+                        "default": {
+                            "env": [
+                                "PATH=/usr/bin:/bin:/usr/local/bin"
+                            ],
+                            "stdin": {
+                                "content": "",
+                                "max": 419430400
+                            },
+                            "stdout": {
+                                "name": "stdout",
+                                "max": 4096
+                            },
+                            "stderr": {
+                                "name": "stderr",
+                                "max": 4096
+                            },
+                            "cpuLimit": 4000000000000,
+                            "realCpuLimit": 0,
+                            "clockLimit": 8000000000000,
+                            "memoryLimit": 838860800,
+                            "stackLimit": 0,
+                            "procLimit": 50,
+                            "cpuRateLimit": 0,
+                            "cpuSetLimit": "",
+                            "copyIn": {},
+                            "copyInCached": {},
+                            "copyInDir": ".",
+                            "copyOut": [
+                                "stdout",
+                                "stderr"
+                            ],
+                            "copyOutCached": [],
+                            "copyOutMax": 0,
+                            "copyOutDir": "",
+                            "tty": false,
+                            "strictMemoryLimit": false,
+                            "dataSegmentLimit": false,
+                            "addressSpaceLimit": false
+                        },
+                        "cases": [
+                            {
+                                "args": [
+                                    "/usr/local/bin/repo-health-checker",
+                                    "-root=.",
+                                    "-repoSize=10",
+                                    "-checkFileSumList=-checkFileNameList="
+                                ],
+                                "env": [
+                                    "PATH=/usr/bin:/bin:/usr/local/bin"
+                                ],
+                                "cpuLimit": 4000000000000,
+                                "clockLimit": 8000000000000,
+                                "memoryLimit": 838860800,
+                                "procLimit": 50,
+                                "copyOut": [
+                                    "stdout",
+                                    "stderr"
+                                ]
+                            },
+                            {
+                                "args": [
+                                    "/usr/local/bin/joint-teapot",
+                                    "joj3-check-env",
+                                    "/home/tt/.config/teapot/teapot.env",
+                                    "--grading-repo-name",
+                                    "ece280-joj",
+                                    "--group-config",
+                                    "=100:24"
+                                ],
+                                "env": [
+                                    "LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"
+                                ],
+                                "cpuLimit": 4000000000000,
+                                "clockLimit": 8000000000000,
+                                "memoryLimit": 838860800,
+                                "procLimit": 50,
+                                "copyOut": [
+                                    "stdout",
+                                    "stderr"
+                                ]
+                            }
+                        ]
+                    }
+                },
+                "parsers": [
+                    {
+                        "name": "healthcheck",
+                        "with": {
+                            "score": 1
+                        }
+                    },
+                    {
+                        "name": "debug",
+                        "with": {
+                            "score": 0
+                        }
+                    }
+                ]
+            },
             {
                 "name": "[cq] Cppcheck",
                 "group": "cq",
diff --git a/tests/convert/cpplint/immutable_files/.gitattributes b/tests/convert/cpplint/immutable_files/.gitattributes
deleted file mode 100644
index b910c4a..0000000
--- a/tests/convert/cpplint/immutable_files/.gitattributes
+++ /dev/null
@@ -1,33 +0,0 @@
-*.avi filter=lfs diff=lfs merge=lfs -text
-*.bz2 filter=lfs diff=lfs merge=lfs -text
-*.djvu filter=lfs diff=lfs merge=lfs -text
-*.doc filter=lfs diff=lfs merge=lfs -text
-*.docx filter=lfs diff=lfs merge=lfs -text
-*.epub filter=lfs diff=lfs merge=lfs -text
-*.gz filter=lfs diff=lfs merge=lfs -text
-*.ipynb filter=lfs diff=lfs merge=lfs -text
-*.jpeg filter=lfs diff=lfs merge=lfs -text
-*.JPEG filter=lfs diff=lfs merge=lfs -text
-*.jpg filter=lfs diff=lfs merge=lfs -text
-*.JPG filter=lfs diff=lfs merge=lfs -text
-*.mkv filter=lfs diff=lfs merge=lfs -text
-*.mp4 filter=lfs diff=lfs merge=lfs -text
-*.ods filter=lfs diff=lfs merge=lfs -text
-*.odt filter=lfs diff=lfs merge=lfs -text
-*.otf filter=lfs diff=lfs merge=lfs -text
-*.pdf filter=lfs diff=lfs merge=lfs -text
-*.PDF filter=lfs diff=lfs merge=lfs -text
-*.png filter=lfs diff=lfs merge=lfs -text
-*.PNG filter=lfs diff=lfs merge=lfs -text
-*.ppt filter=lfs diff=lfs merge=lfs -text
-*.pptx filter=lfs diff=lfs merge=lfs -text
-*.ps filter=lfs diff=lfs merge=lfs -text
-*.rar filter=lfs diff=lfs merge=lfs -text
-*.tar filter=lfs diff=lfs merge=lfs -text
-*.tgz filter=lfs diff=lfs merge=lfs -text
-*.ttf filter=lfs diff=lfs merge=lfs -text
-*.webm filter=lfs diff=lfs merge=lfs -text
-*.xls filter=lfs diff=lfs merge=lfs -text
-*.xlsx filter=lfs diff=lfs merge=lfs -text
-*.xz filter=lfs diff=lfs merge=lfs -text
-*.zip filter=lfs diff=lfs merge=lfs -text
diff --git a/tests/convert/cpplint/immutable_files/.gitignore b/tests/convert/cpplint/immutable_files/.gitignore
deleted file mode 100644
index 754f776..0000000
--- a/tests/convert/cpplint/immutable_files/.gitignore
+++ /dev/null
@@ -1,23 +0,0 @@
-################################
-## White list based gitignore ##
-################################
-
-# forbidden
-*
-.*
-
-# allowed
-!.gitignore
-!.gitattributes
-!.gitea/
-!.gitea/issue_template/
-!.gitea/workflows/
-!*.yaml
-!Makefile
-!CMakeLists.txt
-!h[0-8]/
-!*.m
-!*.c
-!*.cpp
-!*.h
-!*.md
diff --git a/tests/convert/cpplint/immutable_files/push.yaml b/tests/convert/cpplint/immutable_files/push.yaml
deleted file mode 100644
index 664f371..0000000
--- a/tests/convert/cpplint/immutable_files/push.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: Run JOJ3 on Push
-on: [push]
-
-jobs:
-  run:
-    container:
-      image: focs.ji.sjtu.edu.cn:5000/gitea/runner-images:focs-ubuntu-latest-slim
-      volumes:
-        - /home/tt/.config:/home/tt/.config
-        - /home/tt/.cache:/home/tt/.cache
-        - /home/tt/.ssh:/home/tt/.ssh
-    steps:
-      - name: Check out repository code
-        uses: https://gitea.com/BoYanZh/checkout@focs
-        with:
-          fetch-depth: 0
-      - name: run joj3
-        run: |
-          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/homework
diff --git a/tests/convert/cpplint/immutable_files/release.yaml b/tests/convert/cpplint/immutable_files/release.yaml
deleted file mode 100644
index e740403..0000000
--- a/tests/convert/cpplint/immutable_files/release.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Run JOJ3 on Release
-on:
-  release:
-    types: [published]
-
-jobs:
-  run:
-    container:
-      image: focs.ji.sjtu.edu.cn:5000/gitea/runner-images:focs-ubuntu-latest-slim
-      volumes:
-        - /home/tt/.config:/home/tt/.config
-        - /home/tt/.cache:/home/tt/.cache
-        - /home/tt/.ssh:/home/tt/.ssh
-    steps:
-      - name: Check out repository code
-        uses: https://gitea.com/BoYanZh/checkout@focs
-        with:
-          fetch-depth: 0
-      - name: run joj3
-        run: |
-          sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/homework" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"
diff --git a/tests/convert/cpplint/task.json b/tests/convert/cpplint/task.json
index 59fffc3..b032a61 100644
--- a/tests/convert/cpplint/task.json
+++ b/tests/convert/cpplint/task.json
@@ -10,6 +10,111 @@
         "sandboxToken": "",
         "outputPath": "/tmp/joj3_result.json",
         "stages": [
+            {
+                "name": "healthcheck",
+                "group": "",
+                "executor": {
+                    "name": "local",
+                    "with": {
+                        "default": {
+                            "env": [
+                                "PATH=/usr/bin:/bin:/usr/local/bin"
+                            ],
+                            "stdin": {
+                                "content": "",
+                                "max": 419430400
+                            },
+                            "stdout": {
+                                "name": "stdout",
+                                "max": 4096
+                            },
+                            "stderr": {
+                                "name": "stderr",
+                                "max": 4096
+                            },
+                            "cpuLimit": 4000000000000,
+                            "realCpuLimit": 0,
+                            "clockLimit": 8000000000000,
+                            "memoryLimit": 838860800,
+                            "stackLimit": 0,
+                            "procLimit": 50,
+                            "cpuRateLimit": 0,
+                            "cpuSetLimit": "",
+                            "copyIn": {},
+                            "copyInCached": {},
+                            "copyInDir": ".",
+                            "copyOut": [
+                                "stdout",
+                                "stderr"
+                            ],
+                            "copyOutCached": [],
+                            "copyOutMax": 0,
+                            "copyOutDir": "",
+                            "tty": false,
+                            "strictMemoryLimit": false,
+                            "dataSegmentLimit": false,
+                            "addressSpaceLimit": false
+                        },
+                        "cases": [
+                            {
+                                "args": [
+                                    "/usr/local/bin/repo-health-checker",
+                                    "-root=.",
+                                    "-repoSize=10",
+                                    "-checkFileSumList=-checkFileNameList="
+                                ],
+                                "env": [
+                                    "PATH=/usr/bin:/bin:/usr/local/bin"
+                                ],
+                                "cpuLimit": 4000000000000,
+                                "clockLimit": 8000000000000,
+                                "memoryLimit": 838860800,
+                                "procLimit": 50,
+                                "copyOut": [
+                                    "stdout",
+                                    "stderr"
+                                ]
+                            },
+                            {
+                                "args": [
+                                    "/usr/local/bin/joint-teapot",
+                                    "joj3-check-env",
+                                    "/home/tt/.config/teapot/teapot.env",
+                                    "--grading-repo-name",
+                                    "ece280-joj",
+                                    "--group-config",
+                                    "=100:24"
+                                ],
+                                "env": [
+                                    "LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"
+                                ],
+                                "cpuLimit": 4000000000000,
+                                "clockLimit": 8000000000000,
+                                "memoryLimit": 838860800,
+                                "procLimit": 50,
+                                "copyOut": [
+                                    "stdout",
+                                    "stderr"
+                                ]
+                            }
+                        ]
+                    }
+                },
+                "parsers": [
+                    {
+                        "name": "healthcheck",
+                        "with": {
+                            "score": 1
+                        }
+                    },
+                    {
+                        "name": "debug",
+                        "with": {
+                            "score": 0
+                        }
+                    }
+                ]
+            },
             {
                 "name": "[cq] Cpplint",
                 "group": "cq",
diff --git a/tests/convert/diff/immutable_files/.gitattributes b/tests/convert/diff/immutable_files/.gitattributes
deleted file mode 100644
index b910c4a..0000000
--- a/tests/convert/diff/immutable_files/.gitattributes
+++ /dev/null
@@ -1,33 +0,0 @@
-*.avi filter=lfs diff=lfs merge=lfs -text
-*.bz2 filter=lfs diff=lfs merge=lfs -text
-*.djvu filter=lfs diff=lfs merge=lfs -text
-*.doc filter=lfs diff=lfs merge=lfs -text
-*.docx filter=lfs diff=lfs merge=lfs -text
-*.epub filter=lfs diff=lfs merge=lfs -text
-*.gz filter=lfs diff=lfs merge=lfs -text
-*.ipynb filter=lfs diff=lfs merge=lfs -text
-*.jpeg filter=lfs diff=lfs merge=lfs -text
-*.JPEG filter=lfs diff=lfs merge=lfs -text
-*.jpg filter=lfs diff=lfs merge=lfs -text
-*.JPG filter=lfs diff=lfs merge=lfs -text
-*.mkv filter=lfs diff=lfs merge=lfs -text
-*.mp4 filter=lfs diff=lfs merge=lfs -text
-*.ods filter=lfs diff=lfs merge=lfs -text
-*.odt filter=lfs diff=lfs merge=lfs -text
-*.otf filter=lfs diff=lfs merge=lfs -text
-*.pdf filter=lfs diff=lfs merge=lfs -text
-*.PDF filter=lfs diff=lfs merge=lfs -text
-*.png filter=lfs diff=lfs merge=lfs -text
-*.PNG filter=lfs diff=lfs merge=lfs -text
-*.ppt filter=lfs diff=lfs merge=lfs -text
-*.pptx filter=lfs diff=lfs merge=lfs -text
-*.ps filter=lfs diff=lfs merge=lfs -text
-*.rar filter=lfs diff=lfs merge=lfs -text
-*.tar filter=lfs diff=lfs merge=lfs -text
-*.tgz filter=lfs diff=lfs merge=lfs -text
-*.ttf filter=lfs diff=lfs merge=lfs -text
-*.webm filter=lfs diff=lfs merge=lfs -text
-*.xls filter=lfs diff=lfs merge=lfs -text
-*.xlsx filter=lfs diff=lfs merge=lfs -text
-*.xz filter=lfs diff=lfs merge=lfs -text
-*.zip filter=lfs diff=lfs merge=lfs -text
diff --git a/tests/convert/diff/immutable_files/.gitignore b/tests/convert/diff/immutable_files/.gitignore
deleted file mode 100644
index 754f776..0000000
--- a/tests/convert/diff/immutable_files/.gitignore
+++ /dev/null
@@ -1,23 +0,0 @@
-################################
-## White list based gitignore ##
-################################
-
-# forbidden
-*
-.*
-
-# allowed
-!.gitignore
-!.gitattributes
-!.gitea/
-!.gitea/issue_template/
-!.gitea/workflows/
-!*.yaml
-!Makefile
-!CMakeLists.txt
-!h[0-8]/
-!*.m
-!*.c
-!*.cpp
-!*.h
-!*.md
diff --git a/tests/convert/diff/immutable_files/push.yaml b/tests/convert/diff/immutable_files/push.yaml
deleted file mode 100644
index 664f371..0000000
--- a/tests/convert/diff/immutable_files/push.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: Run JOJ3 on Push
-on: [push]
-
-jobs:
-  run:
-    container:
-      image: focs.ji.sjtu.edu.cn:5000/gitea/runner-images:focs-ubuntu-latest-slim
-      volumes:
-        - /home/tt/.config:/home/tt/.config
-        - /home/tt/.cache:/home/tt/.cache
-        - /home/tt/.ssh:/home/tt/.ssh
-    steps:
-      - name: Check out repository code
-        uses: https://gitea.com/BoYanZh/checkout@focs
-        with:
-          fetch-depth: 0
-      - name: run joj3
-        run: |
-          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/homework
diff --git a/tests/convert/diff/immutable_files/release.yaml b/tests/convert/diff/immutable_files/release.yaml
deleted file mode 100644
index e740403..0000000
--- a/tests/convert/diff/immutable_files/release.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Run JOJ3 on Release
-on:
-  release:
-    types: [published]
-
-jobs:
-  run:
-    container:
-      image: focs.ji.sjtu.edu.cn:5000/gitea/runner-images:focs-ubuntu-latest-slim
-      volumes:
-        - /home/tt/.config:/home/tt/.config
-        - /home/tt/.cache:/home/tt/.cache
-        - /home/tt/.ssh:/home/tt/.ssh
-    steps:
-      - name: Check out repository code
-        uses: https://gitea.com/BoYanZh/checkout@focs
-        with:
-          fetch-depth: 0
-      - name: run joj3
-        run: |
-          sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/homework" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"
diff --git a/tests/convert/diff/task.json b/tests/convert/diff/task.json
index e34fca4..aae42cc 100644
--- a/tests/convert/diff/task.json
+++ b/tests/convert/diff/task.json
@@ -10,6 +10,111 @@
         "sandboxToken": "",
         "outputPath": "/tmp/joj3_result.json",
         "stages": [
+            {
+                "name": "healthcheck",
+                "group": "",
+                "executor": {
+                    "name": "local",
+                    "with": {
+                        "default": {
+                            "env": [
+                                "PATH=/usr/bin:/bin:/usr/local/bin"
+                            ],
+                            "stdin": {
+                                "content": "",
+                                "max": 419430400
+                            },
+                            "stdout": {
+                                "name": "stdout",
+                                "max": 4096
+                            },
+                            "stderr": {
+                                "name": "stderr",
+                                "max": 4096
+                            },
+                            "cpuLimit": 4000000000000,
+                            "realCpuLimit": 0,
+                            "clockLimit": 8000000000000,
+                            "memoryLimit": 838860800,
+                            "stackLimit": 0,
+                            "procLimit": 50,
+                            "cpuRateLimit": 0,
+                            "cpuSetLimit": "",
+                            "copyIn": {},
+                            "copyInCached": {},
+                            "copyInDir": ".",
+                            "copyOut": [
+                                "stdout",
+                                "stderr"
+                            ],
+                            "copyOutCached": [],
+                            "copyOutMax": 0,
+                            "copyOutDir": "",
+                            "tty": false,
+                            "strictMemoryLimit": false,
+                            "dataSegmentLimit": false,
+                            "addressSpaceLimit": false
+                        },
+                        "cases": [
+                            {
+                                "args": [
+                                    "/usr/local/bin/repo-health-checker",
+                                    "-root=.",
+                                    "-repoSize=10",
+                                    "-checkFileSumList=-checkFileNameList="
+                                ],
+                                "env": [
+                                    "PATH=/usr/bin:/bin:/usr/local/bin"
+                                ],
+                                "cpuLimit": 4000000000000,
+                                "clockLimit": 8000000000000,
+                                "memoryLimit": 838860800,
+                                "procLimit": 50,
+                                "copyOut": [
+                                    "stdout",
+                                    "stderr"
+                                ]
+                            },
+                            {
+                                "args": [
+                                    "/usr/local/bin/joint-teapot",
+                                    "joj3-check-env",
+                                    "/home/tt/.config/teapot/teapot.env",
+                                    "--grading-repo-name",
+                                    "ece280-joj",
+                                    "--group-config",
+                                    "=100:24"
+                                ],
+                                "env": [
+                                    "LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"
+                                ],
+                                "cpuLimit": 4000000000000,
+                                "clockLimit": 8000000000000,
+                                "memoryLimit": 838860800,
+                                "procLimit": 50,
+                                "copyOut": [
+                                    "stdout",
+                                    "stderr"
+                                ]
+                            }
+                        ]
+                    }
+                },
+                "parsers": [
+                    {
+                        "name": "healthcheck",
+                        "with": {
+                            "score": 1
+                        }
+                    },
+                    {
+                        "name": "debug",
+                        "with": {
+                            "score": 0
+                        }
+                    }
+                ]
+            },
             {
                 "name": "[joj] ex2-asan",
                 "group": "joj",
diff --git a/tests/convert/keyword/immutable_files/.gitattributes b/tests/convert/keyword/immutable_files/.gitattributes
deleted file mode 100644
index b910c4a..0000000
--- a/tests/convert/keyword/immutable_files/.gitattributes
+++ /dev/null
@@ -1,33 +0,0 @@
-*.avi filter=lfs diff=lfs merge=lfs -text
-*.bz2 filter=lfs diff=lfs merge=lfs -text
-*.djvu filter=lfs diff=lfs merge=lfs -text
-*.doc filter=lfs diff=lfs merge=lfs -text
-*.docx filter=lfs diff=lfs merge=lfs -text
-*.epub filter=lfs diff=lfs merge=lfs -text
-*.gz filter=lfs diff=lfs merge=lfs -text
-*.ipynb filter=lfs diff=lfs merge=lfs -text
-*.jpeg filter=lfs diff=lfs merge=lfs -text
-*.JPEG filter=lfs diff=lfs merge=lfs -text
-*.jpg filter=lfs diff=lfs merge=lfs -text
-*.JPG filter=lfs diff=lfs merge=lfs -text
-*.mkv filter=lfs diff=lfs merge=lfs -text
-*.mp4 filter=lfs diff=lfs merge=lfs -text
-*.ods filter=lfs diff=lfs merge=lfs -text
-*.odt filter=lfs diff=lfs merge=lfs -text
-*.otf filter=lfs diff=lfs merge=lfs -text
-*.pdf filter=lfs diff=lfs merge=lfs -text
-*.PDF filter=lfs diff=lfs merge=lfs -text
-*.png filter=lfs diff=lfs merge=lfs -text
-*.PNG filter=lfs diff=lfs merge=lfs -text
-*.ppt filter=lfs diff=lfs merge=lfs -text
-*.pptx filter=lfs diff=lfs merge=lfs -text
-*.ps filter=lfs diff=lfs merge=lfs -text
-*.rar filter=lfs diff=lfs merge=lfs -text
-*.tar filter=lfs diff=lfs merge=lfs -text
-*.tgz filter=lfs diff=lfs merge=lfs -text
-*.ttf filter=lfs diff=lfs merge=lfs -text
-*.webm filter=lfs diff=lfs merge=lfs -text
-*.xls filter=lfs diff=lfs merge=lfs -text
-*.xlsx filter=lfs diff=lfs merge=lfs -text
-*.xz filter=lfs diff=lfs merge=lfs -text
-*.zip filter=lfs diff=lfs merge=lfs -text
diff --git a/tests/convert/keyword/immutable_files/.gitignore b/tests/convert/keyword/immutable_files/.gitignore
deleted file mode 100644
index 754f776..0000000
--- a/tests/convert/keyword/immutable_files/.gitignore
+++ /dev/null
@@ -1,23 +0,0 @@
-################################
-## White list based gitignore ##
-################################
-
-# forbidden
-*
-.*
-
-# allowed
-!.gitignore
-!.gitattributes
-!.gitea/
-!.gitea/issue_template/
-!.gitea/workflows/
-!*.yaml
-!Makefile
-!CMakeLists.txt
-!h[0-8]/
-!*.m
-!*.c
-!*.cpp
-!*.h
-!*.md
diff --git a/tests/convert/keyword/immutable_files/push.yaml b/tests/convert/keyword/immutable_files/push.yaml
deleted file mode 100644
index 664f371..0000000
--- a/tests/convert/keyword/immutable_files/push.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: Run JOJ3 on Push
-on: [push]
-
-jobs:
-  run:
-    container:
-      image: focs.ji.sjtu.edu.cn:5000/gitea/runner-images:focs-ubuntu-latest-slim
-      volumes:
-        - /home/tt/.config:/home/tt/.config
-        - /home/tt/.cache:/home/tt/.cache
-        - /home/tt/.ssh:/home/tt/.ssh
-    steps:
-      - name: Check out repository code
-        uses: https://gitea.com/BoYanZh/checkout@focs
-        with:
-          fetch-depth: 0
-      - name: run joj3
-        run: |
-          sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/homework
diff --git a/tests/convert/keyword/immutable_files/release.yaml b/tests/convert/keyword/immutable_files/release.yaml
deleted file mode 100644
index e740403..0000000
--- a/tests/convert/keyword/immutable_files/release.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Run JOJ3 on Release
-on:
-  release:
-    types: [published]
-
-jobs:
-  run:
-    container:
-      image: focs.ji.sjtu.edu.cn:5000/gitea/runner-images:focs-ubuntu-latest-slim
-      volumes:
-        - /home/tt/.config:/home/tt/.config
-        - /home/tt/.cache:/home/tt/.cache
-        - /home/tt/.ssh:/home/tt/.ssh
-    steps:
-      - name: Check out repository code
-        uses: https://gitea.com/BoYanZh/checkout@focs
-        with:
-          fetch-depth: 0
-      - name: run joj3
-        run: |
-          sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/homework" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"
diff --git a/tests/convert/keyword/task.json b/tests/convert/keyword/task.json
index 3ba8c53..c2e2fcb 100644
--- a/tests/convert/keyword/task.json
+++ b/tests/convert/keyword/task.json
@@ -10,6 +10,111 @@
         "sandboxToken": "",
         "outputPath": "/tmp/joj3_result.json",
         "stages": [
+            {
+                "name": "healthcheck",
+                "group": "",
+                "executor": {
+                    "name": "local",
+                    "with": {
+                        "default": {
+                            "env": [
+                                "PATH=/usr/bin:/bin:/usr/local/bin"
+                            ],
+                            "stdin": {
+                                "content": "",
+                                "max": 419430400
+                            },
+                            "stdout": {
+                                "name": "stdout",
+                                "max": 4096
+                            },
+                            "stderr": {
+                                "name": "stderr",
+                                "max": 4096
+                            },
+                            "cpuLimit": 4000000000000,
+                            "realCpuLimit": 0,
+                            "clockLimit": 8000000000000,
+                            "memoryLimit": 838860800,
+                            "stackLimit": 0,
+                            "procLimit": 50,
+                            "cpuRateLimit": 0,
+                            "cpuSetLimit": "",
+                            "copyIn": {},
+                            "copyInCached": {},
+                            "copyInDir": ".",
+                            "copyOut": [
+                                "stdout",
+                                "stderr"
+                            ],
+                            "copyOutCached": [],
+                            "copyOutMax": 0,
+                            "copyOutDir": "",
+                            "tty": false,
+                            "strictMemoryLimit": false,
+                            "dataSegmentLimit": false,
+                            "addressSpaceLimit": false
+                        },
+                        "cases": [
+                            {
+                                "args": [
+                                    "/usr/local/bin/repo-health-checker",
+                                    "-root=.",
+                                    "-repoSize=10",
+                                    "-checkFileSumList=-checkFileNameList="
+                                ],
+                                "env": [
+                                    "PATH=/usr/bin:/bin:/usr/local/bin"
+                                ],
+                                "cpuLimit": 4000000000000,
+                                "clockLimit": 8000000000000,
+                                "memoryLimit": 838860800,
+                                "procLimit": 50,
+                                "copyOut": [
+                                    "stdout",
+                                    "stderr"
+                                ]
+                            },
+                            {
+                                "args": [
+                                    "/usr/local/bin/joint-teapot",
+                                    "joj3-check-env",
+                                    "/home/tt/.config/teapot/teapot.env",
+                                    "--grading-repo-name",
+                                    "ece280-joj",
+                                    "--group-config",
+                                    "=100:24"
+                                ],
+                                "env": [
+                                    "LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"
+                                ],
+                                "cpuLimit": 4000000000000,
+                                "clockLimit": 8000000000000,
+                                "memoryLimit": 838860800,
+                                "procLimit": 50,
+                                "copyOut": [
+                                    "stdout",
+                                    "stderr"
+                                ]
+                            }
+                        ]
+                    }
+                },
+                "parsers": [
+                    {
+                        "name": "healthcheck",
+                        "with": {
+                            "score": 1
+                        }
+                    },
+                    {
+                        "name": "debug",
+                        "with": {
+                            "score": 0
+                        }
+                    }
+                ]
+            },
             {
                 "name": "[cq] Filelength",
                 "group": "cq",