diff --git a/cmd/joj3/conf/conf.go b/cmd/joj3/conf/conf.go
index a8fe35f..e11ae82 100644
--- a/cmd/joj3/conf/conf.go
+++ b/cmd/joj3/conf/conf.go
@@ -192,7 +192,7 @@ func ParseConfFile(path string) (conf *Conf, err error) {
 	return
 }
 
-func ParseMsg(confRoot, confName, msg string) (confPath, group string, err error) {
+func ParseMsg(confRoot, confName, msg, tag string) (confPath, group string, err error) {
 	slog.Info("parse msg", "msg", msg)
 	conventionalCommit, err := parseConventionalCommit(msg)
 	if err != nil {
@@ -210,6 +210,11 @@ func ParseMsg(confRoot, confName, msg string) (confPath, group string, err error
 		err = fmt.Errorf("invalid scope as path: %s", conventionalCommit.Scope)
 		return
 	}
+	if tag != "" && conventionalCommit.Scope != tag {
+		err = fmt.Errorf("tag does not match scope: %s != %s", tag,
+			conventionalCommit.Scope)
+		return
+	}
 	groupKeywords := []string{"joj"}
 	for _, groupKeyword := range groupKeywords {
 		if strings.Contains(
diff --git a/cmd/joj3/main.go b/cmd/joj3/main.go
index a1d4610..0b9ada8 100644
--- a/cmd/joj3/main.go
+++ b/cmd/joj3/main.go
@@ -15,6 +15,7 @@ var (
 	confRoot    string
 	confName    string
 	msg         string
+	tag         string
 	showVersion *bool
 	Version     string = "debug"
 )
@@ -23,6 +24,7 @@ func init() {
 	flag.StringVar(&confRoot, "conf-root", ".", "root path for all config files")
 	flag.StringVar(&confName, "conf-name", "conf.json", "filename for config files")
 	flag.StringVar(&msg, "msg", "", "message to trigger the running, leave empty to use git commit message on HEAD")
+	flag.StringVar(&tag, "tag", "", "tag to trigger the running, when non-empty, should equal to the scope in msg")
 	showVersion = flag.Bool("version", false, "print current version")
 }
 
@@ -45,7 +47,7 @@ func mainImpl() error {
 			return err
 		}
 	}
-	confPath, group, err := conf.ParseMsg(confRoot, confName, msg)
+	confPath, group, err := conf.ParseMsg(confRoot, confName, msg, tag)
 	if err != nil {
 		slog.Error("parse msg", "error", err)
 		validScopes, scopeErr := conf.ListValidScopes(