cq_label: Process a list of repos

Process a list of repos instead of a host and a list of projects. This
will make this recipe easier to configure in starlark.

Bug: b/231587812
Change-Id: I21788256708af54a76a898903a65a5faab526d5d
Reviewed-on: https://pigweed-review.googlesource.com/c/infra/recipes/+/93760
Commit-Queue: Rob Mohr <mohrr@google.com>
Reviewed-by: Ted Pudlik <tpudlik@google.com>
diff --git a/recipes/cq_label.expected/clear-dryrun.json b/recipes/cq_label.expected/clear-dryrun.json
index ae26c36..670565e 100644
--- a/recipes/cq_label.expected/clear-dryrun.json
+++ b/recipes/cq_label.expected/clear-dryrun.json
@@ -1,7 +1,21 @@
 [
   {
     "cmd": [],
-    "name": "ensure gerrit"
+    "name": "properties",
+    "~followup_annotations": [
+      "@@@STEP_SUMMARY_TEXT@{'repo': ['https://pigweed.googlesource.com/pigweed'], 'cq_account': 'cq-bot-account@gserviceaccount.com', 'label': 'CQ-Verified', 'dry_run': True, 'recipe': 'cq_label'}@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "pigweed"
+  },
+  {
+    "cmd": [],
+    "name": "pigweed.ensure gerrit",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -15,9 +29,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.read manifest",
+    "name": "pigweed.ensure gerrit.read manifest",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@{@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"path\": \"path/to/gerrit\",@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"version\": \"version:pinned-version\"@@@",
@@ -27,9 +41,9 @@
   },
   {
     "cmd": [],
-    "name": "ensure gerrit.install path/to/gerrit",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -45,9 +59,9 @@
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure package directory",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure package directory",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@"
+      "@@@STEP_NEST_LEVEL@3@@@"
     ]
   },
   {
@@ -64,9 +78,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure_installed",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_NEST_LEVEL@3@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -87,19 +101,20 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get unlabeled changes",
+    "name": "pigweed.get unlabeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_END@json.output (invalid)@@@",
       "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
       "@@@STEP_LOG_END@json.output (exception)@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
@@ -112,13 +127,14 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get labeled changes",
+    "name": "pigweed.get labeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@[@@@",
       "@@@STEP_LOG_LINE@json.output@  {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"_number\": 1, @@@",
@@ -128,7 +144,7 @@
       "@@@STEP_LOG_END@json.output@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
@@ -136,17 +152,18 @@
   },
   {
     "cmd": [],
-    "name": "1",
+    "name": "pigweed.1",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_SUMMARY_TEXT@would clear CQ-Verified@@@",
       "@@@STEP_LINK@1@https://pigweed-review.googlesource.com/1@@@"
     ]
   },
   {
     "cmd": [],
-    "name": "1.would clear CQ-Verified",
+    "name": "pigweed.1.would clear CQ-Verified",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
diff --git a/recipes/cq_label.expected/clear.json b/recipes/cq_label.expected/clear.json
index 7d99ba9..33c1398 100644
--- a/recipes/cq_label.expected/clear.json
+++ b/recipes/cq_label.expected/clear.json
@@ -1,7 +1,21 @@
 [
   {
     "cmd": [],
-    "name": "ensure gerrit"
+    "name": "properties",
+    "~followup_annotations": [
+      "@@@STEP_SUMMARY_TEXT@{'repo': ['https://pigweed.googlesource.com/pigweed'], 'cq_account': 'cq-bot-account@gserviceaccount.com', 'label': 'CQ-Verified', 'recipe': 'cq_label'}@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "pigweed"
+  },
+  {
+    "cmd": [],
+    "name": "pigweed.ensure gerrit",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -15,9 +29,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.read manifest",
+    "name": "pigweed.ensure gerrit.read manifest",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@{@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"path\": \"path/to/gerrit\",@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"version\": \"version:pinned-version\"@@@",
@@ -27,9 +41,9 @@
   },
   {
     "cmd": [],
-    "name": "ensure gerrit.install path/to/gerrit",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -45,9 +59,9 @@
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure package directory",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure package directory",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@"
+      "@@@STEP_NEST_LEVEL@3@@@"
     ]
   },
   {
@@ -64,9 +78,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure_installed",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_NEST_LEVEL@3@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -87,19 +101,20 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get unlabeled changes",
+    "name": "pigweed.get unlabeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_END@json.output (invalid)@@@",
       "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
       "@@@STEP_LOG_END@json.output (exception)@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
@@ -112,13 +127,14 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get labeled changes",
+    "name": "pigweed.get labeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@[@@@",
       "@@@STEP_LOG_LINE@json.output@  {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"_number\": 1, @@@",
@@ -128,7 +144,7 @@
       "@@@STEP_LOG_END@json.output@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
@@ -136,8 +152,9 @@
   },
   {
     "cmd": [],
-    "name": "1",
+    "name": "pigweed.1",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_SUMMARY_TEXT@clear CQ-Verified@@@",
       "@@@STEP_LINK@1@https://pigweed-review.googlesource.com/1@@@"
     ]
@@ -153,10 +170,10 @@
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "1.clear CQ-Verified",
+    "name": "pigweed.1.clear CQ-Verified",
     "timeout": 600,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_END@json.output (invalid)@@@",
       "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
       "@@@STEP_LOG_END@json.output (exception)@@@",
diff --git a/recipes/cq_label.expected/dry-run.json b/recipes/cq_label.expected/dry-run.json
index e55c1ce..27dc73f 100644
--- a/recipes/cq_label.expected/dry-run.json
+++ b/recipes/cq_label.expected/dry-run.json
@@ -1,7 +1,21 @@
 [
   {
     "cmd": [],
-    "name": "ensure gerrit"
+    "name": "properties",
+    "~followup_annotations": [
+      "@@@STEP_SUMMARY_TEXT@{'repo': ['https://pigweed.googlesource.com/pigweed'], 'cq_account': 'cq-bot-account@gserviceaccount.com', 'label': 'CQ-Verified', 'dry_run': True, 'recipe': 'cq_label'}@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "pigweed"
+  },
+  {
+    "cmd": [],
+    "name": "pigweed.ensure gerrit",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -15,9 +29,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.read manifest",
+    "name": "pigweed.ensure gerrit.read manifest",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@{@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"path\": \"path/to/gerrit\",@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"version\": \"version:pinned-version\"@@@",
@@ -27,9 +41,9 @@
   },
   {
     "cmd": [],
-    "name": "ensure gerrit.install path/to/gerrit",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -45,9 +59,9 @@
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure package directory",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure package directory",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@"
+      "@@@STEP_NEST_LEVEL@3@@@"
     ]
   },
   {
@@ -64,9 +78,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure_installed",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_NEST_LEVEL@3@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -87,13 +101,14 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get unlabeled changes",
+    "name": "pigweed.get unlabeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@[@@@",
       "@@@STEP_LOG_LINE@json.output@  {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"_number\": 1, @@@",
@@ -103,7 +118,7 @@
       "@@@STEP_LOG_END@json.output@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
@@ -111,8 +126,9 @@
   },
   {
     "cmd": [],
-    "name": "1",
+    "name": "pigweed.1",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_SUMMARY_TEXT@would set CQ-Verified to 1@@@",
       "@@@STEP_LINK@1@https://pigweed-review.googlesource.com/1@@@"
     ]
@@ -128,10 +144,10 @@
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "1.details",
+    "name": "pigweed.1.details",
     "timeout": 600,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"current_revision\": \"h3110\", @@@",
       "@@@STEP_LOG_LINE@json.output@  \"messages\": [@@@",
@@ -164,16 +180,16 @@
   },
   {
     "cmd": [],
-    "name": "1.passed",
+    "name": "pigweed.1.passed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
     "cmd": [],
-    "name": "1.would set CQ-Verified to 1",
+    "name": "pigweed.1.would set CQ-Verified to 1",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -183,19 +199,20 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get labeled changes",
+    "name": "pigweed.get labeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_END@json.output (invalid)@@@",
       "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
       "@@@STEP_LOG_END@json.output (exception)@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
diff --git a/recipes/cq_label.expected/failed.json b/recipes/cq_label.expected/failed.json
index 3e917ed..fd82404 100644
--- a/recipes/cq_label.expected/failed.json
+++ b/recipes/cq_label.expected/failed.json
@@ -1,7 +1,21 @@
 [
   {
     "cmd": [],
-    "name": "ensure gerrit"
+    "name": "properties",
+    "~followup_annotations": [
+      "@@@STEP_SUMMARY_TEXT@{'repo': ['https://pigweed.googlesource.com/pigweed'], 'cq_account': 'cq-bot-account@gserviceaccount.com', 'label': 'CQ-Verified', 'recipe': 'cq_label'}@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "pigweed"
+  },
+  {
+    "cmd": [],
+    "name": "pigweed.ensure gerrit",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -15,9 +29,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.read manifest",
+    "name": "pigweed.ensure gerrit.read manifest",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@{@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"path\": \"path/to/gerrit\",@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"version\": \"version:pinned-version\"@@@",
@@ -27,9 +41,9 @@
   },
   {
     "cmd": [],
-    "name": "ensure gerrit.install path/to/gerrit",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -45,9 +59,9 @@
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure package directory",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure package directory",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@"
+      "@@@STEP_NEST_LEVEL@3@@@"
     ]
   },
   {
@@ -64,9 +78,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure_installed",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_NEST_LEVEL@3@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -87,13 +101,14 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get unlabeled changes",
+    "name": "pigweed.get unlabeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@[@@@",
       "@@@STEP_LOG_LINE@json.output@  {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"_number\": 1, @@@",
@@ -103,7 +118,7 @@
       "@@@STEP_LOG_END@json.output@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
@@ -111,8 +126,9 @@
   },
   {
     "cmd": [],
-    "name": "1",
+    "name": "pigweed.1",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_SUMMARY_TEXT@set CQ-Verified to -1@@@",
       "@@@STEP_LINK@1@https://pigweed-review.googlesource.com/1@@@"
     ]
@@ -128,10 +144,10 @@
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "1.details",
+    "name": "pigweed.1.details",
     "timeout": 600,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"current_revision\": \"h3110\", @@@",
       "@@@STEP_LOG_LINE@json.output@  \"messages\": [@@@",
@@ -164,9 +180,9 @@
   },
   {
     "cmd": [],
-    "name": "1.failed",
+    "name": "pigweed.1.failed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -180,10 +196,10 @@
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "1.set CQ-Verified to -1",
+    "name": "pigweed.1.set CQ-Verified to -1",
     "timeout": 600,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_END@json.output (invalid)@@@",
       "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
       "@@@STEP_LOG_END@json.output (exception)@@@",
@@ -208,19 +224,20 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get labeled changes",
+    "name": "pigweed.get labeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_END@json.output (invalid)@@@",
       "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
       "@@@STEP_LOG_END@json.output (exception)@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
diff --git a/recipes/cq_label.expected/wrong-project.json b/recipes/cq_label.expected/passed-old.json
similarity index 70%
rename from recipes/cq_label.expected/wrong-project.json
rename to recipes/cq_label.expected/passed-old.json
index edea035..bbee308 100644
--- a/recipes/cq_label.expected/wrong-project.json
+++ b/recipes/cq_label.expected/passed-old.json
@@ -1,7 +1,21 @@
 [
   {
     "cmd": [],
-    "name": "ensure gerrit"
+    "name": "properties",
+    "~followup_annotations": [
+      "@@@STEP_SUMMARY_TEXT@{'host': 'pigweed', 'project': 'pigweed', 'cq_account': 'cq-bot-account@gserviceaccount.com', 'label': 'CQ-Verified', 'recipe': 'cq_label'}@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "pigweed"
+  },
+  {
+    "cmd": [],
+    "name": "pigweed.ensure gerrit",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -15,9 +29,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.read manifest",
+    "name": "pigweed.ensure gerrit.read manifest",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@{@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"path\": \"path/to/gerrit\",@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"version\": \"version:pinned-version\"@@@",
@@ -27,9 +41,9 @@
   },
   {
     "cmd": [],
-    "name": "ensure gerrit.install path/to/gerrit",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -45,9 +59,9 @@
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure package directory",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure package directory",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@"
+      "@@@STEP_NEST_LEVEL@3@@@"
     ]
   },
   {
@@ -64,9 +78,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure_installed",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_NEST_LEVEL@3@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -87,13 +101,14 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get unlabeled changes",
+    "name": "pigweed.get unlabeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@[@@@",
       "@@@STEP_LOG_LINE@json.output@  {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"_number\": 1, @@@",
@@ -103,7 +118,7 @@
       "@@@STEP_LOG_END@json.output@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
@@ -111,8 +126,10 @@
   },
   {
     "cmd": [],
-    "name": "1",
+    "name": "pigweed.1",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_SUMMARY_TEXT@set CQ-Verified to 1@@@",
       "@@@STEP_LINK@1@https://pigweed-review.googlesource.com/1@@@"
     ]
   },
@@ -127,10 +144,10 @@
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "1.details",
+    "name": "pigweed.1.details",
     "timeout": 600,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"current_revision\": \"h3110\", @@@",
       "@@@STEP_LOG_LINE@json.output@  \"messages\": [@@@",
@@ -141,7 +158,7 @@
       "@@@STEP_LOG_LINE@json.output@      \"message\": \"Patch Set 2: Dry run: This CL passed\"@@@",
       "@@@STEP_LOG_LINE@json.output@    }@@@",
       "@@@STEP_LOG_LINE@json.output@  ], @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"project\": \"chromium\", @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"project\": \"pigweed\", @@@",
       "@@@STEP_LOG_LINE@json.output@  \"revisions\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"h3110\": {@@@",
       "@@@STEP_LOG_LINE@json.output@      \"_number\": 2@@@",
@@ -162,25 +179,65 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "pigweed.1.passed",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version/gerrit",
+      "set-review",
+      "-host",
+      "https://pigweed-review.googlesource.com",
+      "-input",
+      "{\"change_id\": \"1\", \"input\": {\"labels\": {\"CQ-Verified\": 1}, \"notify\": \"NONE\"}, \"revision_id\": \"current\"}",
+      "-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "pigweed.1.set CQ-Verified to 1",
+    "timeout": 600,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_LOG_END@json.output (invalid)@@@",
+      "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
+      "@@@STEP_LOG_END@json.output (exception)@@@",
+      "@@@STEP_LOG_LINE@json.input@{@@@",
+      "@@@STEP_LOG_LINE@json.input@  \"change_id\": \"1\", @@@",
+      "@@@STEP_LOG_LINE@json.input@  \"input\": {@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"labels\": {@@@",
+      "@@@STEP_LOG_LINE@json.input@      \"CQ-Verified\": 1@@@",
+      "@@@STEP_LOG_LINE@json.input@    }, @@@",
+      "@@@STEP_LOG_LINE@json.input@    \"notify\": \"NONE\"@@@",
+      "@@@STEP_LOG_LINE@json.input@  }, @@@",
+      "@@@STEP_LOG_LINE@json.input@  \"revision_id\": \"current\"@@@",
+      "@@@STEP_LOG_LINE@json.input@}@@@",
+      "@@@STEP_LOG_END@json.input@@@",
+      "@@@STEP_LINK@gerrit link@https://pigweed-review.googlesource.com/q/1@@@"
+    ]
+  },
+  {
     "cmd": [
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version/gerrit",
       "change-query",
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get labeled changes",
+    "name": "pigweed.get labeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_END@json.output (invalid)@@@",
       "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
       "@@@STEP_LOG_END@json.output (exception)@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
diff --git a/recipes/cq_label.expected/passed.json b/recipes/cq_label.expected/passed.json
index 84ff870..9481805 100644
--- a/recipes/cq_label.expected/passed.json
+++ b/recipes/cq_label.expected/passed.json
@@ -1,7 +1,21 @@
 [
   {
     "cmd": [],
-    "name": "ensure gerrit"
+    "name": "properties",
+    "~followup_annotations": [
+      "@@@STEP_SUMMARY_TEXT@{'repo': ['https://pigweed.googlesource.com/pigweed'], 'cq_account': 'cq-bot-account@gserviceaccount.com', 'label': 'CQ-Verified', 'recipe': 'cq_label'}@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "pigweed"
+  },
+  {
+    "cmd": [],
+    "name": "pigweed.ensure gerrit",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -15,9 +29,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.read manifest",
+    "name": "pigweed.ensure gerrit.read manifest",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@{@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"path\": \"path/to/gerrit\",@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"version\": \"version:pinned-version\"@@@",
@@ -27,9 +41,9 @@
   },
   {
     "cmd": [],
-    "name": "ensure gerrit.install path/to/gerrit",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -45,9 +59,9 @@
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure package directory",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure package directory",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@"
+      "@@@STEP_NEST_LEVEL@3@@@"
     ]
   },
   {
@@ -64,9 +78,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure_installed",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_NEST_LEVEL@3@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -87,13 +101,14 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get unlabeled changes",
+    "name": "pigweed.get unlabeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@[@@@",
       "@@@STEP_LOG_LINE@json.output@  {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"_number\": 1, @@@",
@@ -103,7 +118,7 @@
       "@@@STEP_LOG_END@json.output@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
@@ -111,8 +126,9 @@
   },
   {
     "cmd": [],
-    "name": "1",
+    "name": "pigweed.1",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_SUMMARY_TEXT@set CQ-Verified to 1@@@",
       "@@@STEP_LINK@1@https://pigweed-review.googlesource.com/1@@@"
     ]
@@ -128,10 +144,10 @@
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "1.details",
+    "name": "pigweed.1.details",
     "timeout": 600,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"current_revision\": \"h3110\", @@@",
       "@@@STEP_LOG_LINE@json.output@  \"messages\": [@@@",
@@ -164,9 +180,9 @@
   },
   {
     "cmd": [],
-    "name": "1.passed",
+    "name": "pigweed.1.passed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -180,10 +196,10 @@
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "1.set CQ-Verified to 1",
+    "name": "pigweed.1.set CQ-Verified to 1",
     "timeout": 600,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_END@json.output (invalid)@@@",
       "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
       "@@@STEP_LOG_END@json.output (exception)@@@",
@@ -208,19 +224,20 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get labeled changes",
+    "name": "pigweed.get labeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_END@json.output (invalid)@@@",
       "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
       "@@@STEP_LOG_END@json.output (exception)@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
diff --git a/recipes/cq_label.expected/wrong-author.json b/recipes/cq_label.expected/wrong-author.json
index 5a2bd59..70009cc 100644
--- a/recipes/cq_label.expected/wrong-author.json
+++ b/recipes/cq_label.expected/wrong-author.json
@@ -1,7 +1,21 @@
 [
   {
     "cmd": [],
-    "name": "ensure gerrit"
+    "name": "properties",
+    "~followup_annotations": [
+      "@@@STEP_SUMMARY_TEXT@{'repo': ['https://pigweed.googlesource.com/pigweed'], 'cq_account': 'cq-bot-account@gserviceaccount.com', 'label': 'CQ-Verified', 'recipe': 'cq_label'}@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "pigweed"
+  },
+  {
+    "cmd": [],
+    "name": "pigweed.ensure gerrit",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -15,9 +29,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.read manifest",
+    "name": "pigweed.ensure gerrit.read manifest",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@{@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"path\": \"path/to/gerrit\",@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"version\": \"version:pinned-version\"@@@",
@@ -27,9 +41,9 @@
   },
   {
     "cmd": [],
-    "name": "ensure gerrit.install path/to/gerrit",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -45,9 +59,9 @@
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure package directory",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure package directory",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@"
+      "@@@STEP_NEST_LEVEL@3@@@"
     ]
   },
   {
@@ -64,9 +78,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure_installed",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_NEST_LEVEL@3@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -87,13 +101,14 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get unlabeled changes",
+    "name": "pigweed.get unlabeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@[@@@",
       "@@@STEP_LOG_LINE@json.output@  {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"_number\": 1, @@@",
@@ -103,7 +118,7 @@
       "@@@STEP_LOG_END@json.output@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
@@ -111,8 +126,9 @@
   },
   {
     "cmd": [],
-    "name": "1",
+    "name": "pigweed.1",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_SUMMARY_TEXT@no action@@@",
       "@@@STEP_LINK@1@https://pigweed-review.googlesource.com/1@@@"
     ]
@@ -128,10 +144,10 @@
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "1.details",
+    "name": "pigweed.1.details",
     "timeout": 600,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"current_revision\": \"h3110\", @@@",
       "@@@STEP_LOG_LINE@json.output@  \"messages\": [@@@",
@@ -169,19 +185,20 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get labeled changes",
+    "name": "pigweed.get labeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_END@json.output (invalid)@@@",
       "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
       "@@@STEP_LOG_END@json.output (exception)@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
diff --git a/recipes/cq_label.expected/wrong-patchset.json b/recipes/cq_label.expected/wrong-patchset.json
index e04d352..d37489d 100644
--- a/recipes/cq_label.expected/wrong-patchset.json
+++ b/recipes/cq_label.expected/wrong-patchset.json
@@ -1,7 +1,21 @@
 [
   {
     "cmd": [],
-    "name": "ensure gerrit"
+    "name": "properties",
+    "~followup_annotations": [
+      "@@@STEP_SUMMARY_TEXT@{'repo': ['https://pigweed.googlesource.com/pigweed'], 'cq_account': 'cq-bot-account@gserviceaccount.com', 'label': 'CQ-Verified', 'recipe': 'cq_label'}@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "pigweed"
+  },
+  {
+    "cmd": [],
+    "name": "pigweed.ensure gerrit",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -15,9 +29,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.read manifest",
+    "name": "pigweed.ensure gerrit.read manifest",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@{@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"path\": \"path/to/gerrit\",@@@",
       "@@@STEP_LOG_LINE@tool_manifest.json@  \"version\": \"version:pinned-version\"@@@",
@@ -27,9 +41,9 @@
   },
   {
     "cmd": [],
-    "name": "ensure gerrit.install path/to/gerrit",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -45,9 +59,9 @@
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure package directory",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure package directory",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@"
+      "@@@STEP_NEST_LEVEL@3@@@"
     ]
   },
   {
@@ -64,9 +78,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure gerrit.install path/to/gerrit.ensure_installed",
+    "name": "pigweed.ensure gerrit.install path/to/gerrit.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_NEST_LEVEL@3@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -87,13 +101,14 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get unlabeled changes",
+    "name": "pigweed.get unlabeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@[@@@",
       "@@@STEP_LOG_LINE@json.output@  {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"_number\": 1, @@@",
@@ -103,7 +118,7 @@
       "@@@STEP_LOG_END@json.output@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open -(label:Commit-Queue+1 OR label:Commit-Queue+2) -(label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
@@ -111,8 +126,9 @@
   },
   {
     "cmd": [],
-    "name": "1",
+    "name": "pigweed.1",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_SUMMARY_TEXT@no action@@@",
       "@@@STEP_LINK@1@https://pigweed-review.googlesource.com/1@@@"
     ]
@@ -128,10 +144,10 @@
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "1.details",
+    "name": "pigweed.1.details",
     "timeout": 600,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"current_revision\": \"h3110\", @@@",
       "@@@STEP_LOG_LINE@json.output@  \"messages\": [@@@",
@@ -169,19 +185,20 @@
       "-host",
       "https://pigweed-review.googlesource.com",
       "-input",
-      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"}}",
+      "{\"params\": {\"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"}}",
       "-output",
       "/path/to/tmp/json"
     ],
-    "name": "get labeled changes",
+    "name": "pigweed.get labeled changes",
     "timeout": 30,
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_END@json.output (invalid)@@@",
       "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
       "@@@STEP_LOG_END@json.output (exception)@@@",
       "@@@STEP_LOG_LINE@json.input@{@@@",
       "@@@STEP_LOG_LINE@json.input@  \"params\": {@@@",
-      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) project:pigweed  \"@@@",
+      "@@@STEP_LOG_LINE@json.input@    \"q\": \"is:open (label:Commit-Queue+1 OR label:Commit-Queue+2) (label:CQ-Verified-1 OR label:CQ-Verified+1) (r:cq-bot-account@gserviceaccount.com OR cc:cq-bot-account@gserviceaccount.com) (project:pigweed) \"@@@",
       "@@@STEP_LOG_LINE@json.input@  }@@@",
       "@@@STEP_LOG_LINE@json.input@}@@@",
       "@@@STEP_LOG_END@json.input@@@"
diff --git a/recipes/cq_label.proto b/recipes/cq_label.proto
index 279d1e8..b8e32f1 100644
--- a/recipes/cq_label.proto
+++ b/recipes/cq_label.proto
@@ -17,10 +17,12 @@
 package recipes.pigweed.cq_label;
 
 message InputProperties {
-  // Name of the Gerrit host.
+  // TODO(b/231587812) Remove
+  // [DEPRECATED] Name of the Gerrit host.
   string host = 1;
 
-  // Name of the project on the Gerrit host.
+  // TODO(b/231587812) Remove
+  // [DEPRECATED] Name of the project on the Gerrit host.
   string project = 2;
 
   // The account that posts CQ results.
@@ -31,4 +33,7 @@
 
   // Don't do anything with external effocts.
   bool dry_run = 5;
+
+  // Repositories to watch.
+  repeated string repo = 6;
 }
diff --git a/recipes/cq_label.py b/recipes/cq_label.py
index a143101..c334fd9 100644
--- a/recipes/cq_label.py
+++ b/recipes/cq_label.py
@@ -17,6 +17,7 @@
 of CQ. Also find CLs where CQ is running and clear that +1 or -1.
 """
 
+import collections
 import re
 
 from recipe_engine import post_process, recipe_test_api
@@ -45,18 +46,20 @@
     )
 
 
-def _label_completed_unlabelled(api, host, label, cq_account, project, dry_run):
-    project_part = ''
-    if project:
-        project_part = 'project:{} '.format(project)
-
+def _label_completed_unlabelled(
+    api, host, projects, label, cq_account, dry_run,
+):
     query_string = (
         'is:open '
         '-(label:Commit-Queue+1 OR label:Commit-Queue+2) '
         '-(label:{label}-1 OR label:{label}+1) '
         '(r:{cq_account} OR cc:{cq_account}) '
-        '{project_part} '
-    ).format(label=label, cq_account=cq_account, project_part=project_part,)
+        '({project_part}) '
+    ).format(
+        label=label,
+        cq_account=cq_account,
+        project_part=' OR '.join('project:{}'.format(p) for p in projects),
+    )
 
     changes = (
         api.gerrit.change_query(
@@ -89,9 +92,6 @@
                 .json.output
             )
 
-            if project and project != details['project']:
-                continue
-
             patch = details['revisions'][details['current_revision']]['_number']
             value = 0
             # Look at messages in reverse order so we always set based on the
@@ -144,18 +144,18 @@
                 pres.step_summary_text = 'no action'
 
 
-def _remove_running_labelled(api, host, label, cq_account, project, dry_run):
-    project_part = ''
-    if project:
-        project_part = 'project:{} '.format(project)
-
+def _remove_running_labelled(api, host, projects, label, cq_account, dry_run):
     query_string = (
         'is:open '
         '(label:Commit-Queue+1 OR label:Commit-Queue+2) '
         '(label:{label}-1 OR label:{label}+1) '
         '(r:{cq_account} OR cc:{cq_account}) '
-        '{project_part} '
-    ).format(label=label, cq_account=cq_account, project_part=project_part,)
+        '({project_part}) '
+    ).format(
+        label=label,
+        cq_account=cq_account,
+        project_part=' OR '.join('project:{}'.format(p) for p in projects),
+    )
 
     changes = (
         api.gerrit.change_query(
@@ -202,30 +202,53 @@
     assert re.match(r'^[-\w.@]+$', props.cq_account)
     assert re.match(r'^[-\w./_]*$', props.project)
 
+    with api.step.nest('properties') as pres:
+        pres.step_summary_text = repr(api.properties.thaw())
+
+    repos = list(props.repo)
+
+    # TODO(b/231587812) Remove transition code.
+    if props.host and props.project and not repos:
+        repos.append(
+            'https://{}.googlesource.com/{}'.format(props.host, props.project)
+        )
+
+    projects_by_host = collections.defaultdict(list)
+    for repo in repos:
+        match = re.search(
+            r'^https://(?P<host>.*).googlesource.com/(?P<project>.*)$', repo,
+        )
+        assert match, repo
+        host = match.group('host')
+        project = match.group('project')
+        projects_by_host[host].append(project)
+
     actions = []
 
     with api.step.defer_results():
-        actions.extend(
-            _label_completed_unlabelled(
-                api=api,
-                host=props.host,
-                label=props.label,
-                cq_account=props.cq_account,
-                project=props.project,
-                dry_run=props.dry_run,
-            )
-        )
+        for host, projects in projects_by_host.items():
+            with api.step.nest(host):
+                actions.extend(
+                    _label_completed_unlabelled(
+                        api=api,
+                        host=host,
+                        projects=projects,
+                        label=props.label,
+                        cq_account=props.cq_account,
+                        dry_run=props.dry_run,
+                    )
+                )
 
-        actions.extend(
-            _remove_running_labelled(
-                api=api,
-                host=props.host,
-                label=props.label,
-                cq_account=props.cq_account,
-                project=props.project,
-                dry_run=props.dry_run,
-            )
-        )
+                actions.extend(
+                    _remove_running_labelled(
+                        api=api,
+                        host=host,
+                        projects=projects,
+                        label=props.label,
+                        cq_account=props.cq_account,
+                        dry_run=props.dry_run,
+                    )
+                )
 
     return result.RawResult(
         summary_markdown='\n\n'.join(actions), status=common.SUCCESS,
@@ -237,7 +260,7 @@
     VERIFIED_LABEL = 'CQ-Verified'
     PROJECT = 'pigweed'
 
-    def properties(**kwargs):
+    def old_properties(**kwargs):
         new_kwargs = {
             'host': 'pigweed',
             'project': PROJECT,
@@ -247,15 +270,24 @@
         new_kwargs.update(**kwargs)
         return api.properties(**new_kwargs)
 
+    def properties(**kwargs):
+        new_kwargs = {
+            'repo': ['https://pigweed.googlesource.com/{}'.format(PROJECT)],
+            'cq_account': CQ_BOT_ACCOUNT,
+            'label': VERIFIED_LABEL,
+        }
+        new_kwargs.update(**kwargs)
+        return api.properties(**new_kwargs)
+
     def unlabeled_query_results(project='pigweed'):
         return api.step_data(
-            'get unlabeled changes',
+            'pigweed.get unlabeled changes',
             api.json.output([{'_number': 1, 'project': project}]),
         )
 
     def labeled_query_results(project='pigweed'):
         return api.step_data(
-            'get labeled changes',
+            'pigweed.get labeled changes',
             api.json.output([{'_number': 1, 'project': project}]),
         )
 
@@ -275,51 +307,64 @@
             'project': PROJECT,
         }
         res.update(kwargs)
-        return api.step_data('1.details', api.json.output(res))
+        return api.step_data('pigweed.1.details', api.json.output(res))
 
     def set_passed(label=VERIFIED_LABEL, dry_run=False):
         dry_run_part = 'would ' if dry_run else ''
         return api.post_process(
-            post_process.MustRun, '1.{}set {} to 1'.format(dry_run_part, label),
+            post_process.MustRun,
+            'pigweed.1.{}set {} to 1'.format(dry_run_part, label),
         )
 
     def set_failed(label=VERIFIED_LABEL, dry_run=False):
         dry_run_part = 'would ' if dry_run else ''
         return api.post_process(
             post_process.MustRun,
-            '1.{}set {} to -1'.format(dry_run_part, label),
+            'pigweed.1.{}set {} to -1'.format(dry_run_part, label),
         )
 
     def no_set(label=VERIFIED_LABEL):
         return (
             api.post_process(
-                post_process.DoesNotRun, '1.set {} to 1'.format(label),
+                post_process.DoesNotRun, 'pigweed.1.set {} to 1'.format(label),
             )
             + api.post_process(
-                post_process.DoesNotRun, '1.would set {} to 1'.format(label),
+                post_process.DoesNotRun,
+                'pigweed.1.would set {} to 1'.format(label),
             )
             + api.post_process(
-                post_process.DoesNotRun, '1.set {} to -1'.format(label),
+                post_process.DoesNotRun, 'pigweed.1.set {} to -1'.format(label),
             )
             + api.post_process(
-                post_process.DoesNotRun, '1.would set {} to -1'.format(label),
+                post_process.DoesNotRun,
+                'pigweed.1.would set {} to -1'.format(label),
             )
         )
 
     def does_not_clear(label=VERIFIED_LABEL):
         return api.post_process(
-            post_process.DoesNotRun, '1.clear {}'.format(label),
+            post_process.DoesNotRun, 'pigweed.1.clear {}'.format(label),
         ) + api.post_process(
-            post_process.DoesNotRun, '1.would clear {}'.format(label),
+            post_process.DoesNotRun, 'pigweed.1.would clear {}'.format(label),
         )
 
     def clear(label=VERIFIED_LABEL, dry_run=False):
         dry_run_part = 'would ' if dry_run else ''
         return api.post_process(
-            post_process.MustRun, '1.{}clear {}'.format(dry_run_part, label),
+            post_process.MustRun,
+            'pigweed.1.{}clear {}'.format(dry_run_part, label),
         )
 
     yield (
+        api.status_check.test('passed-old')
+        + old_properties()
+        + unlabeled_query_results()
+        + details(message(2, True))
+        + set_passed()
+        + does_not_clear()
+    )
+
+    yield (
         api.status_check.test('passed')
         + properties()
         + unlabeled_query_results()
@@ -356,15 +401,6 @@
     )
 
     yield (
-        api.status_check.test('wrong-project')
-        + properties()
-        + unlabeled_query_results()
-        + details(message(2, True), project='chromium')
-        + no_set()
-        + does_not_clear()
-    )
-
-    yield (
         api.status_check.test('dry-run')
         + properties(dry_run=True)
         + unlabeled_query_results()