diff --git a/_example/simple/conf.toml b/_example/simple/conf.toml
index c90b7be..c09afe9 100644
--- a/_example/simple/conf.toml
+++ b/_example/simple/conf.toml
@@ -1,4 +1,4 @@
-logLevel = 0
+logLevel = 8
 [[stages]]
 name = "compile"
 [stages.executor]
@@ -21,7 +21,7 @@ max = 4_096
 name = "stderr"
 max = 4_096
 [stages.parser]
-name = "dummy"
+name = "result-status"
 [stages.parser.with]
 score = 100
 comment = "compile done"
diff --git a/internal/parsers/all.go b/internal/parsers/all.go
index 4319ac6..ecc658c 100644
--- a/internal/parsers/all.go
+++ b/internal/parsers/all.go
@@ -3,6 +3,7 @@ package parsers
 import (
 	_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff"
 	_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/dummy"
+	_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/resultstatus"
 )
 
 // this file does nothing but imports to ensure all the init() functions
diff --git a/internal/parsers/diff/parser.go b/internal/parsers/diff/parser.go
index 0608e50..c93e780 100644
--- a/internal/parsers/diff/parser.go
+++ b/internal/parsers/diff/parser.go
@@ -16,15 +16,15 @@ type Config struct {
 
 type Diff struct{}
 
-func (e *Diff) Run(results []stage.ExecutorResult, configAny any) (
-	[]stage.ParserResult, error,
+func (*Diff) Run(results []stage.ExecutorResult, configAny any) (
+	[]stage.ParserResult, bool, error,
 ) {
 	config, err := stage.DecodeConfig[Config](configAny)
 	if err != nil {
-		return nil, err
+		return nil, true, err
 	}
 	if len(config.Cases) != len(results) {
-		return nil, fmt.Errorf("cases number not match")
+		return nil, true, fmt.Errorf("cases number not match")
 	}
 	var res []stage.ParserResult
 	for i, caseConfig := range config.Cases {
@@ -32,7 +32,7 @@ func (e *Diff) Run(results []stage.ExecutorResult, configAny any) (
 		score := 0
 		stdout, err := os.ReadFile(caseConfig.StdoutPath)
 		if err != nil {
-			return nil, err
+			return nil, true, err
 		}
 		// TODO: more compare strategies
 		if string(stdout) == result.Files["stdout"] {
@@ -46,5 +46,5 @@ func (e *Diff) Run(results []stage.ExecutorResult, configAny any) (
 			),
 		})
 	}
-	return res, nil
+	return res, false, nil
 }
diff --git a/internal/parsers/dummy/meta.go b/internal/parsers/dummy/meta.go
index fd9ba75..4312dfd 100644
--- a/internal/parsers/dummy/meta.go
+++ b/internal/parsers/dummy/meta.go
@@ -2,7 +2,7 @@ package dummy
 
 import "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
 
-var name = "dummy"
+var name = "result status"
 
 func init() {
 	stage.RegisterParser(name, &Dummy{})
diff --git a/internal/parsers/dummy/parser.go b/internal/parsers/dummy/parser.go
index d1bd509..a572eb5 100644
--- a/internal/parsers/dummy/parser.go
+++ b/internal/parsers/dummy/parser.go
@@ -13,12 +13,12 @@ type Config struct {
 
 type Dummy struct{}
 
-func (e *Dummy) Run(results []stage.ExecutorResult, configAny any) (
-	[]stage.ParserResult, error,
+func (*Dummy) Run(results []stage.ExecutorResult, configAny any) (
+	[]stage.ParserResult, bool, error,
 ) {
 	config, err := stage.DecodeConfig[Config](configAny)
 	if err != nil {
-		return nil, err
+		return nil, true, err
 	}
 	var res []stage.ParserResult
 	for _, result := range results {
@@ -30,5 +30,5 @@ func (e *Dummy) Run(results []stage.ExecutorResult, configAny any) (
 			),
 		})
 	}
-	return res, nil
+	return res, false, nil
 }
diff --git a/internal/parsers/resultstatus/meta.go b/internal/parsers/resultstatus/meta.go
new file mode 100644
index 0000000..60be167
--- /dev/null
+++ b/internal/parsers/resultstatus/meta.go
@@ -0,0 +1,9 @@
+package resultstatus
+
+import "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
+
+var name = "result-status"
+
+func init() {
+	stage.RegisterParser(name, &ResultStatus{})
+}
diff --git a/internal/parsers/resultstatus/parser.go b/internal/parsers/resultstatus/parser.go
new file mode 100644
index 0000000..f38a5c9
--- /dev/null
+++ b/internal/parsers/resultstatus/parser.go
@@ -0,0 +1,38 @@
+package resultstatus
+
+import (
+	"fmt"
+
+	"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
+	"github.com/criyle/go-judge/envexec"
+)
+
+type Config struct{}
+
+type ResultStatus struct{}
+
+func (*ResultStatus) Run(results []stage.ExecutorResult, configAny any) (
+	[]stage.ParserResult, bool, error,
+) {
+	// TODO: more config options
+	_, err := stage.DecodeConfig[Config](configAny)
+	if err != nil {
+		return nil, true, err
+	}
+	end := false
+	var res []stage.ParserResult
+	for _, result := range results {
+		comment := ""
+		if result.Status != stage.Status(envexec.StatusAccepted) {
+			end = true
+			comment = fmt.Sprintf(
+				"Unexpected executor status: %s.", result.Status,
+			)
+		}
+		res = append(res, stage.ParserResult{
+			Score:   0,
+			Comment: comment,
+		})
+	}
+	return res, end, nil
+}
diff --git a/internal/stage/parser.go b/internal/stage/parser.go
index 8a56a2c..a4f5548 100644
--- a/internal/stage/parser.go
+++ b/internal/stage/parser.go
@@ -3,7 +3,7 @@ package stage
 var parserMap = map[string]Parser{}
 
 type Parser interface {
-	Run([]ExecutorResult, any) ([]ParserResult, error)
+	Run([]ExecutorResult, any) ([]ParserResult, bool, error)
 }
 
 func RegisterParser(name string, parser Parser) {
diff --git a/internal/stage/run.go b/internal/stage/run.go
index 0132c69..176a308 100644
--- a/internal/stage/run.go
+++ b/internal/stage/run.go
@@ -18,7 +18,7 @@ func Run(stages []Stage) []StageResult {
 		slog.Info("executor run done", "results", executorResults)
 		slog.Info("parser run start", "config", stage.ParserConfig)
 		parser := parserMap[stage.ParserName]
-		parserResults, err := parser.Run(executorResults, stage.ParserConfig)
+		parserResults, end, err := parser.Run(executorResults, stage.ParserConfig)
 		if err != nil {
 			slog.Error("parser run error", "name", stage.ExecutorName, "error", err)
 			break
@@ -28,6 +28,9 @@ func Run(stages []Stage) []StageResult {
 			Name:          stage.Name,
 			ParserResults: parserResults,
 		})
+		if end {
+			break
+		}
 	}
 	return stageResults
 }