Automatic compilation
diff --git a/.ci.yaml b/.ci.yaml
deleted file mode 100644
index ca2ee9f..0000000
--- a/.ci.yaml
+++ /dev/null
@@ -1,162 +0,0 @@
-# Describes the targets run in continuous integration environment.
-#
-# Flutter infra uses this file to generate a checklist of tasks to be performed
-# for every commit.
-#
-# More information at:
-#  * https://github.com/flutter/cocoon/blob/main/CI_YAML.md
-enabled_branches:
-  - main
-
-platform_properties:
-  linux:
-    properties:
-      os: Linux
-      device_type: "none"
-  mac:
-    properties:
-      os: "Mac-12|Mac-13"
-      cpu: x86
-  mac_arm64:
-    properties:
-      os: "Mac-12|Mac-13"
-      cpu: arm64
-  windows:
-    properties:
-      os: Windows
-      device_type: "none"
-
-targets:
-  - name: Linux Cocoon
-    recipe: cocoon/cocoon
-    properties:
-      add_recipes_cq: "true"
-    runIf:
-      - .ci.yaml
-      - analyze/**
-      - app_dart/**
-      - auto_submit/**
-      - cipd_packages/**
-      - cloud_build/**
-      - dashboard/**
-      - dev/**
-      - licenses/**
-      - packages/**
-      - test_utilities/**
-      - tooling/**
-
-  - name: Linux device_doctor
-    recipe: cocoon/cipd
-    properties:
-      script: cipd_packages/device_doctor/tool/build.sh
-      cipd_name: flutter/device_doctor/linux-amd64
-    runIf:
-      - cipd_packages/device_doctor/**
-      - .ci.yaml
-
-  - name: Mac device_doctor
-    recipe: cocoon/cipd
-    properties:
-      script: cipd_packages/device_doctor/tool/build.sh
-      cipd_name: flutter/device_doctor/mac-amd64
-      device_type: none
-    runIf:
-      - cipd_packages/device_doctor/**
-      - .ci.yaml
-
-  - name: Mac_arm64 device_doctor
-    recipe: cocoon/cipd
-    properties:
-      script: cipd_packages/device_doctor/tool/build.sh
-      cipd_name: flutter/device_doctor/mac-arm64
-      device_type: none
-    runIf:
-      - cipd_packages/device_doctor/**
-      - .ci.yaml
-
-  - name: Windows device_doctor
-    recipe: cocoon/cipd
-    properties:
-      script: cipd_packages\device_doctor\tool\build.bat
-      cipd_name: flutter/device_doctor/windows-amd64
-    runIf:
-      - cipd_packages/device_doctor/**
-      - .ci.yaml
-
-  - name: Linux doxygen
-    recipe: cocoon/cipd
-    properties:
-      script: cipd_packages/doxygen/tool/build.sh
-      cipd_name: flutter/doxygen/linux-amd64
-      dependencies: >-
-        [
-          {"dependency": "cmake", "version": "build_id:8787856497187628321"}
-        ]
-    runIf:
-      - cipd_packages/doxygen/**
-      - .ci.yaml
-
-  - name: Mac codesign
-    recipe: cocoon/cipd
-    properties:
-      script: cipd_packages/codesign/tool/build.sh
-      cipd_name: flutter/codesign/mac-amd64
-      device_type: none
-    runIf:
-      - cipd_packages/codesign/**
-      - .ci.yaml
-
-  - name: Mac_arm64 codesign
-    recipe: cocoon/cipd
-    properties:
-      script: cipd_packages/codesign/tool/build.sh
-      cipd_name: flutter/codesign/mac-arm64
-      device_type: none
-    runIf:
-      - cipd_packages/codesign/**
-      - .ci.yaml
-
-  - name: Mac ruby
-    recipe: cocoon/cipd
-    timeout: 60
-    properties:
-      script: cipd_packages/ruby/tools/build.sh
-      cipd_name: flutter/ruby/mac-amd64
-      device_os: iOS
-      contexts: >-
-        [
-          "osx_sdk_devicelab"
-        ]
-      $flutter/osx_sdk : >-
-        {
-          "sdk_version": "14e300c"
-        }
-    runIf:
-      - cipd_packages/ruby/**
-      - .ci.yaml
-
-  - name: Mac_arm64 ruby
-    recipe: cocoon/cipd
-    timeout: 60
-    properties:
-      script: cipd_packages/ruby/tools/build.sh
-      cipd_name: flutter/ruby/mac-arm64
-      device_os: iOS
-      contexts: >-
-        [
-          "osx_sdk_devicelab"
-        ]
-      $flutter/osx_sdk : >-
-        {
-          "sdk_version": "14e300c"
-        }
-    runIf:
-      - cipd_packages/ruby/**
-      - .ci.yaml
-
-  - name: Linux ci_yaml roller
-    recipe: infra/ci_yaml
-    properties:
-      backfill: "false"
-    runIf:
-      - .ci.yaml
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index 9642af8..0000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,89 +0,0 @@
-# See Dependabot documentation for all configuration options:
-# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
-
-version: 2
-enable-beta-ecosystems: true
-updates:
-  # Github actions ecosystem.
-  - package-ecosystem: "github-actions"
-    directory: "/"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-  # Pub ecosystem.
-  - package-ecosystem: "pub"
-    directory: "/analyze"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-  - package-ecosystem: "pub"
-    directory: "/app_dart"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-  - package-ecosystem: "pub"
-    directory: "/auto_submit"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-  - package-ecosystem: "pub"
-    directory: "/cipd_packages/codesign"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-  - package-ecosystem: "pub"
-    directory: "/dashboard"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-  - package-ecosystem: "pub"
-    directory: "/cipd_packages/device_doctor"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-  - package-ecosystem: "pub"
-    directory: "/test_utilities"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-  - package-ecosystem: "pub"
-    directory: "/licenses"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-  # Docker ecosystem.
-  - package-ecosystem: "docker"
-    directory: "/app_dart"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-  - package-ecosystem: "docker"
-    directory: "/auto_submit"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-  # Go ecosystem.
-  - package-ecosystem: "gomod"
-    directory: "/tooling"
-    schedule:
-      interval: "daily"
-    labels:
-      - "autosubmit"
-    allow:
-      - dependency-name: "github.com/slsa-framework/slsa-verifier/v2"
-  # Npm ecosystem.
-  - package-ecosystem: 'npm'
-    directory: '/gh_actions/third_party/no-response'
-    schedule:
-      interval: 'daily'
diff --git a/.github/workflows/no-response_publish.yaml b/.github/workflows/no-response_publish.yaml
deleted file mode 100644
index fc3d0b4..0000000
--- a/.github/workflows/no-response_publish.yaml
+++ /dev/null
@@ -1,40 +0,0 @@
-name: no-response-publish
-
-# Declare default permissions as read only.
-permissions: read-all
-
-on:
-  release:
-    types: [published, edited]
-    branches:
-      - main
-    paths:
-      - 'gh_actions/third_party/no-response/**'
-      - '.github/workflows/no-response_test.yaml'
-      - '.github/workflows/no-response_publish.yaml'
-jobs:
-  build:
-    runs-on: ubuntu-latest
-    permissions:
-      contents: write
-    if: ${{ github.repository == 'flutter/cocoon' }}
-    steps:
-      - name: Checkout
-        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
-        with:
-          ref: ${{ github.event.release.tag_name }}
-          sparse-checkout: 'gh_actions/third_party/no-response'
-          sparse-checkout-cone-mode: false
-      - name: move_package_to_root
-        run: |
-          mv -f gh_actions/third_party/no-response/{.[!.],}* ./
-          rm -rf gh_actions
-      - name: ls
-        run: ls -la
-      - name: npm_ci
-        run: npm ci
-      - name: npm_run_build
-        run: npm run build
-      - uses: JasonEtco/build-and-tag-action@dd5e4991048c325f6d85b4155e586fc211c644da
-        env:
-          GITHUB_TOKEN: ${{ secrets.FLUTTERGITHUBBOT_TOKEN }}
diff --git a/.github/workflows/no-response_test.yaml b/.github/workflows/no-response_test.yaml
deleted file mode 100644
index f82627e..0000000
--- a/.github/workflows/no-response_test.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-name: no-response-test
-
-# Declare default permissions as read only.
-permissions: read-all
-
-on:
-  pull_request:
-    paths:
-      - 'gh_actions/third_party/no-response/**'
-      - '.github/workflows/no-response_test.yaml'
-      - '.github/workflows/no-response_publish.yaml'
-jobs:
-  unitTest:
-    runs-on: ubuntu-latest
-    if: ${{ github.repository == 'flutter/cocoon' }}
-    steps:
-      - name: Checkout
-        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
-        with:
-          ref: ${{ github.event.release.tag_name }}
-          sparse-checkout: 'gh_actions/third_party/no-response'
-          sparse-checkout-cone-mode: false
-      - name: move_package_to_root
-        run: |
-          mv -f gh_actions/third_party/no-response/{.[!.],}* ./
-          rm -rf gh_actions
-      - name: ls
-        run: ls -la
-      - name: npm_ci
-        run: npm ci
-      - name: npm_run_ci
-        run: npm run ci
-      - name: npm_run_build
-        run: npm run build
diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml
deleted file mode 100644
index 1cc1c8f..0000000
--- a/.github/workflows/scorecards-analysis.yml
+++ /dev/null
@@ -1,56 +0,0 @@
-name: Scorecards supply-chain security
-on:
-  # Only the default branch is supported.
-  branch_protection_rule:
-  push:
-    branches: [ main ]
-
-# Declare default permissions as read only.
-permissions: read-all
-
-jobs:
-  analysis:
-    name: Scorecards analysis
-    runs-on: ubuntu-latest
-    if: ${{ github.repository == 'flutter/cocoon' }}
-    permissions:
-      # Needed to upload the results to code-scanning dashboard.
-      security-events: write
-      actions: read
-      contents: read
-      # Needed to access OIDC token.
-      id-token: write
-
-    steps:
-      - name: "Checkout code"
-        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
-        with:
-          persist-credentials: false
-
-      - name: "Run analysis"
-        uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736
-        with:
-          results_file: results.sarif
-          results_format: sarif
-          # Read-only PAT token. To create it,
-          # follow the steps in https://github.com/ossf/scorecard-action#pat-token-creation.
-          repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}
-          # Publish the results to enable scorecard badges. For more details, see
-          # https://github.com/ossf/scorecard-action#publishing-results.
-          # For private repositories, `publish_results` will automatically be set to `false`,
-          # regardless of the value entered here.
-          publish_results: true
-
-      # Upload the results as artifacts (optional).
-      - name: "Upload artifact"
-        uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
-        with:
-          name: SARIF file
-          path: results.sarif
-          retention-days: 5
-
-      # Upload the results to GitHub's code scanning dashboard.
-      - name: "Upload to code-scanning"
-        uses: github/codeql-action/upload-sarif@cdcdbb579706841c47f7063dda365e292e5cad7a
-        with:
-          sarif_file: results.sarif
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 2466d2f..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-.dart_tool
-.DS_Store
-*~
-.packages
-.pub
-**/pubspec.lock
-.flutter-plugins-dependencies
-# IntelliJ
-.idea
-*.iml
-
-# VSCode
-.vscode/
diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index 5a547b7..0000000
--- a/AUTHORS
+++ /dev/null
@@ -1,7 +0,0 @@
-# Below is a list of people and organizations that have contributed
-# to the Sky project. Names should be added to the list like so:
-#
-#   Name/Organization <email address>
-
-Google Inc.
-Chromium authors.
diff --git a/CI_YAML.md b/CI_YAML.md
deleted file mode 100644
index a8efb1e..0000000
--- a/CI_YAML.md
+++ /dev/null
@@ -1,310 +0,0 @@
-# Cocoon Scheduler
-
-This Dart project contains logic for constructing infrastructure configs
-to validate commits in the repositories owned by Flutter.
-
-## ci.yaml
-
-This is the config file in a repository used to tell Cocoon what tasks are used
-to validate commits. It includes both the tasks used in presubmit and postsubmit.
-
-In addition, it supports tasks from different infrastructures as long as cocoon
-supports that `scheduler`. Only `luci` and `cocoon` are supported, but contributions
-are welcome.
-
-Example config:
-```yaml
-# /.ci.yaml
-
-# Enabled branches is a list of regexes, with the assumption that these are full line matches.
-# Internally, Cocoon prefixes these with $ and suffixes with ^ to enable matches.
-enabled_branches:
-  - main
-  - flutter-\\d+\\.\\d+-candidate\\.\\d+
-
-# Platform properties defines common properties shared among targets from the same platform.
-platform_properties:
-  linux:
-    properties:
-      # os will be inherited by all Linux targets, but it can be overrided at the target level
-      os: Linux
-
-targets:
-# A Target is an individual unit of work that is scheduled by Flutter infra
-# Target's are composed of the following properties:
-# name: A human readable string to uniquely identify this target.
-#       The first word indicates the platform this test will be run on. This should match
-#       to an existing platform under platform_properties.
-# recipes: LUCI recipes the target follows to run tests
-#          https://flutter.googlesource.com/recipes/+/refs/heads/main/recipes/
-# bringup: Whether this target is under active development and should not block the tree.
-#          If true, will not run in presubmit and will not block postsubmit.
-# presubmit: Whether to run this target on presubmit (defaults to true).
-# postsubmit: Whether to run this target on postsubmit (defaults to true).
-# run_if: List of path regexes that can trigger this target on presubmit.
-#         If none are passed, it will evaluare run_if_not. If both are empty the target
-#         will always run in presubmit.
-# run_if_not: List of path regexes used to filter out presubmit targets. The target will
-#         be run only if the files changed do not match any paths in this list. If run_if
-#         is provided and not empty run_if_not will be ignored.
-# enabled_branches: List of strings of branches this target can run on.
-#                   This overrides the global enabled_branches.
-# properties: A map of string, string. Values are parsed to their closest data model.
-# postsubmit_properties: Properties that are only run on postsubmit.
-# timeout: Integer defining whole build execution time limit for all steps in minutes.
-#
-# Minimal example:
-# Linux analyze will run on all presubmit and in postsubmit.
- - name: Linux analyze
-#
-# Bringup example:
-# Linux licenses will run on postsubmit, but it also passes the properties
-# `analyze=true` to the builder. Since `bringup=true`, presubmit is not run,
-# and postsubmit runs will not block the tree.
- - name: Linux licenses
-   bringup: true
-   properties:
-     - analyze: license
-
-#
-# Tags example:
-# This test will be categorized as host only framework test.
-# Postsubmit runs will be passed "upload_metrics: true".
- - name: Linux analyze
-   properties:
-     tags: >-
-       ["framework", "hostonly"]
-   postsubmit_properties:
-     - upload_metrics: "true"
-
-#
-# Devicelab example:
-# For tests that are located https://github.com/flutter/flutter/tree/master/dev/devicelab/bin/tasks:
-# 1) target name follows format of `<platform> <taskname>`
-# 2) properties
-#    2.1) update `tags` based on hosts, devices, and tests type. These tags will be used for statistic analysis.
-#    2.2) a `taskname` property is required, which should match the task name
-#
-# Here is the target config for a task named: `analyzer_benchmark.dart`.
- - name: Linux_android analyzer_benchmark
-   recipe: devicelab/devicelab_drone
-   presubmit: false
-   properties:
-     tags: >
-       ["devicelab", "android", "linux"]
-     task_name: analyzer_benchmark
-```
-
-### Adding new targets
-
-All new targets should be added as `bringup: true` to ensure they do not block the tree.
-
-Targets first need to be mirrored to flutter/infra before they will be run.
-This propagation takes about 30 minutes, and will only run as non-blocking in postsubmit.
-
-The target will show runs in https://ci.chromium.org/p/flutter (under the repo). See
-https://github.com/flutter/flutter/wiki/Adding-a-new-Test-Shard for up to date information
-on the steps to promote your target to blocking.
-
-For flutter/flutter, there's a GitHub bot that will
-promote a test that has been passing for the past 50 runs.
-
-### Test Ownership
-
-**This only applies to flutter/flutter**
-
-To prevent tests from rotting, all targets are required to have a clear owner. Add an
-owner in [TESTOWNERS](https://github.com/flutter/flutter/blob/master/TESTOWNERS)
-
-### Properties
-
-Targets support specifying properties that can be passed throughout infrastructure. The
-following are a list of keys that are reserved for special use.
-
-**Properties is a Map<String, String> and any special values must be JSON encoded
-(i.e. no trailing commas). Additionally, these strings must be compatible with YAML multiline strings**
-
-**$flutter/osx_sdk**: xcode configs including sdk and runtime. **Note**: support on legacy `xcode`/`runtime`
-properties and `xcode` dependency has been deprecated.
-
-Example:
-``` yaml
-$flutter/osx_sdk : >-
-  {
-    "sdk_version": "14e222b",
-    "runtime_versions":
-      [
-        "ios-16-4_14e222b",
-        "ios-16-2_14c18"
-      ]
-  }
-```
-
-**add_recipes_cq**: String boolean whether to add this target to flutter/recipes CQ. This ensures
-changes to flutter/recipes pass on this target before landing.
-
-**dependencies**: JSON list of objects with "dependency" and optionally "version".
-The list of supported deps is in [flutter_deps recipe_module](https://cs.opensource.google/flutter/recipes/+/master:recipe_modules/flutter_deps/api.py).
-Dependencies generate a corresponding swarming cache that can be used in the
-recipe code. The path of the cache will be the name of the dependency.
-
-Versions can be located in [CIPD](https://chrome-infra-packages.appspot.com/)
-
-Example
-``` yaml
-dependencies: >-
-  [
-    {"dependency": "android_sdk"},
-    {"dependency": "chrome_and_driver", "version": "latest"},
-    {"dependency": "clang"},
-    {"dependency": "goldctl"}
-  ]
-```
-
-**tags**: JSON list of strings. These are currently only used in flutter/flutter to help
-with TESTOWNERSHIP and test flakiness.
-
-Example
-```yaml
-tags: >
-  ["devicelab","hostonly"]
-```
-
-**test_timeout_secs** String determining seconds before timeout for an individual test step.
-Note that this is the timeout for a single test step rather than the entire build execution
-timeout.
-
-Example
-``` yaml
-test_timeout_secs: "2700"
-```
-
-**presubmit_max_attempts** The max attempts the target will be auto executed in presubmit. If it is
-not specified, the default value is `1` and it means no auto rerun will happen. If explicitly defined,
-it controls the max number of attempts. For example: `3` means it will be auto rescheduled two more times.
-
-Example
-``` yaml
-presubmit_max_attempts: "3"
-```
-
-### Updating targets
-
-#### Properties
-1. Find the cipd ref to upgrade to
-    - If this is a Flutter managed package, look up its docs on uploading a new version
-    - For example, JDK is at https://chrome-infra-packages.appspot.com/p/flutter_internal/java/openjdk/linux-amd64
-2. In `ci.yaml`, find a target that would be impacted by this change
-    - Override the `version` specified in dependencies
-      ```yaml
-      - name: Linux Host Engine
-        recipe: engine
-        properties:
-          build_host: "true"
-          dependencies: >-
-          [
-              {"dependency": "open_jdk", "version": "11"}
-          ]
-        timeout: 60
-      ```
-    - Send PR, wait for the checks to go green (**the change takes effect on both presubmit and postsubmit as cocoon scheduling**
-    **fetches latest change and applies it to new builds immediately**)
-3. If the check is red, add patches to get it green
-4. Once the PR has landed, infrastructure may take 1 or 2 commits to apply the latest properties
-   1. PRs/commits that have rebased on the changing PR do not need to wait
-   2. PRs/commits that have not rebased on the changing PR need to wait
-   3. Local LUCI runs need to wait
-   4. Package cache needs to wait for roll out
-
-**Note:** updates on other entries except `properties` will not take effect immediately. Ths PR needs
-to be landed first to wait for changes propagated in infrastructure.
-
-#### Update target platform
-
-Target depends on the prefix platform in its `name` to decide which platform to run on. This should match
-to an existing platform under `platform_properties`.
-
-If one target needs to switch running platforms, e.g. from a devicelab bot to a host only bot:
-1. Keep the old target entry
-2. Add a new entry under the new platform with
-  1. `bringup: true`
-  2. necessary dependencies
-  3. corresponding tags (tags will only be used for infra metrics analysis)
-3. Land the change with the new entry
-4. If the new target under the new platform passes in postsubmit
-  1. Remove the old target entry and mark the new target as `bringup: false`
-
-Example: say one wants to switch `Linux_android web_size__compile_test` to a vm.
-
-Existing config:
-```yaml
-- name: Linux_android web_size__compile_test
-  properties:
-    tags: >
-        ["devicelab", "android", "linux"]
-```
-
-Add a new config:
-```yaml
-- name: Linux web_size__compile_test
-  bringup: true # new target
-  properties:
-    dependencies: >- # optional
-      [
-        {"dependency": "new-dependency", "version": "new-dependency-version"}
-      ]
-    tags: >
-      ["devicelab", "hostonly", "linux"]
-```
-
-After validating the new target passes, lands the clean up change by removing the config of old target
-`Linux_android web_size__compile_test` and removing the `bringup: true` for the new target.
-
-Note: this change may affect benchmark metrics. Notify the metrics sherrif to monitor potential regression.
-
-### External Tests
-
-Cocoon supports tests that are not owned by Flutter infrastructure. By default, these should not block the tree but act as FYI to the gardeners.
-
-1. Contact flutter-infra@ with your request (go/flutter-infra-office-hours)
-2. Add your system to SchedulerSystem (https://github.com/flutter/cocoon/blob/master/app_dart/lib/src/model/proto/internal/scheduler.proto)
-3. Add your service account to https://github.com/flutter/cocoon/blob/master/app_dart/lib/src/request_handling/swarming_authentication.dart
-4. Add a custom frontend icon - https://github.com/flutter/cocoon/blob/master/dashboard/lib/widgets/task_icon.dart
-5. Add a custom log link - https://github.com/flutter/cocoon/blob/master/dashboard/lib/logic/qualified_task.dart
-6. Wait for the next prod roll (every weekday)
-7. Add a target to `.ci.yaml`
-   ```yaml
-   # .ci.yaml
-   # Name is an arbitrary string that will show on the build dashboard
-   - name: my_external_test_a
-     # External tests should not block the tree
-     bringup: true
-     presubmit: false
-     # Scheduler must match what was added to scheduler.proto (any unique name works)
-     scheduler: my_external_location
-   ```
-8. Send updates to `https://flutter-dashboard.appspot.com/api/update-task-status` - https://github.com/flutter/cocoon/blob/master/app_dart/lib/src/request_handlers/update_task_status.dart
-
-
-## Scheduling Targets
-
-For targets using the Cocoon scheduler, they can run on:
- * Presubmit (via GitHub checks)
- * Postsubmit (via [build dashboard](https://flutter-dashboard.appspot.com/#/build))
-
-By default, all targets should use the Cocoon scheduler.
-
-### Presubmit Features
-
-1. GitHub checks enable targets to run immediately, and are available on the pull request page.
-2. Changes to the ci.yaml will be applied during those presubmit runs.
-3. New targets are required to be brought up with `bringup: true`
-
-### Postsubmit Features
-
-1. Targets are immediately triggered on GitHub webhooks for merged pull requests
-2. Updates are made immediate via LUCI PubSub notifications
-3. Prioritizes recently failed targets (to unblock the tree quicker)
-4. Backfills targets at a low swarming priority when nothing is actively running
-5. Batches targets that have a high queue time, and backfills in off peak hours
-6. Flakiness monitoring
diff --git a/CODEOWNERS b/CODEOWNERS
deleted file mode 100644
index b38f42c..0000000
--- a/CODEOWNERS
+++ /dev/null
@@ -1,44 +0,0 @@
-# Below is a list of Flutter team members' GitHub handles who are
-# suggested reviewers for contributions to this repository.
-#
-# These names are just suggestions. It is fine to have your changes
-# reviewed by someone else.
-
-## app_dart APIs
-app_dart/lib/src/request_handlers/check_flaky_builders.dart                 @keyonghan
-app_dart/lib/src/request_handlers/create_branch.dart                        @CaseyHillers
-app_dart/lib/src/request_handlers/dart_internal_subscription.dart           @drewroengoogle
-app_dart/lib/src/request_handlers/file_flaky_issue_and_pr.dart              @keyonghan
-app_dart/lib/src/request_handlers/flush_cache.dart                          @keyonghan
-app_dart/lib/src/request_handlers/get_build_status.dart                     @keyonghan
-app_dart/lib/src/request_handlers/get_release_branches.dart                 @CaseyHillers
-app_dart/lib/src/request_handlers/get_repos.dart                            @keyonghan
-app_dart/lib/src/request_handlers/get_status.dart                           @keyonghan
-app_dart/lib/src/request_handlers/get_green_commits.dart                    @XilaiZhang
-app_dart/lib/src/request_handlers/github_rate_limit_status.dart             @keyonghan
-app_dart/lib/src/request_handlers/github_webhook.dart                       @keyonghan
-app_dart/lib/src/request_handlers/github/webhook_subscription.dart          @keyonghan
-app_dart/lib/src/request_handlers/presubmit_luci_subscription.dart          @keyonghan
-app_dart/lib/src/request_handlers/postsubmit_luci_subscription.dart         @keyonghan
-app_dart/lib/src/request_handlers/push_build_status_to_github.dart          @keyonghan
-app_dart/lib/src/request_handlers/push_gold_status_to_github.dart           @Piinks
-app_dart/lib/src/request_handlers/reset_prod_task.dart                      @keyonghan
-app_dart/lib/src/request_handlers/reset_try_task.dart                       @keyonghan
-app_dart/lib/src/request_handlers/scheduler/batch_backfiller.dart           @keyonghan
-app_dart/lib/src/request_handlers/scheduler/request_subscription.dart       @keyonghan
-app_dart/lib/src/request_handlers/scheduler/vacuum_stale_tasks.dart         @keyonghan
-app_dart/lib/src/request_handlers/update_existing_flaky_issues.dart         @keyonghan
-app_dart/lib/src/request_handlers/update_task_status.dart                   @keyonghan
-app_dart/lib/src/request_handlers/vacuum_github_commits.dart                @keyonghan
-
-## auto_submit app
-auto_submit                                                                 @ricardoamador
-
-## cipd packages
-cipd_packages/codesign/**                                                   @XilaiZhang
-cipd_packages/device_doctor/**                                              @yusuf-goog
-cipd_packages/doxygen/**                                                    @gspencergoog
-cipd_packages/ruby/**                                                       @godofredoc
-
-## gh_actions
-gh_actions/third_party/no-response/**                                       @godofredoc
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 3bf36c8..0000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,37 +0,0 @@
-Want to contribute? Great! First, read this page (including the small print at
-the end).
-
-### Before you contribute
-
-Before we can use your code, you must sign the
-[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
-(CLA), which you can do online. The CLA is necessary mainly because you own the
-copyright to your changes, even after your contribution becomes part of our
-codebase, so we need your permission to use and distribute your code. We also
-need to be sure of various other things—for instance that you'll tell us if you
-know that your code infringes on other people's patents. You don't have to sign
-the CLA until after you've submitted your code for review and a member has
-approved it, but you must do it before we can put your code into our codebase.
-
-Before you start working on a larger contribution, you should get in touch with
-us first through the issue tracker with your idea so that we can help out and
-possibly guide you. Coordinating up front makes it much easier to avoid
-frustration later on.
-
-### Code reviews
-
-All submissions, including submissions by project members, require review.
-
-### File headers
-
-All files in the project must start with the following header.
-
-    // Copyright (c) 2016, the Flutter project authors.  Please see the AUTHORS file
-    // for details. All rights reserved. Use of this source code is governed by a
-    // BSD-style license that can be found in the LICENSE file.
-
-### The small print
-
-Contributions made by corporations are covered by a different agreement than the
-one above, the
-[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate).
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index d5384ca..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright 2016 The Flutter Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
deleted file mode 100644
index 07eb0f8..0000000
--- a/README.md
+++ /dev/null
@@ -1,126 +0,0 @@
-<a href="https://github.com/flutter/cocoon">
-  <h1 align="center">
-    <picture>
-      <source media="(prefers-color-scheme: dark)" srcset="https://storage.googleapis.com/cms-storage-bucket/6e19fee6b47b36ca613f.png">
-      <img alt="Flutter" src="https://storage.googleapis.com/cms-storage-bucket/c823e53b3a1a7b0d36a9.png">
-    </picture>
-  </h1>
-</a>
-
-
-[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/flutter/cocoon/badge)](https://api.securityscorecards.dev/projects/github.com/flutter/cocoon)
-[![SLSA 3](https://slsa.dev/images/gh-badge-level3.svg)](https://slsa.dev)
-
-**Cocoon** is a Dart App Engine custom runtime (backend) with a frontend
-of Flutter apps (build and repository dashboard). Cocoon coordinates
-and aggregates the results of [flutter/flutter](https://github.com/flutter/flutter)
-builds.
-
-It is not designed to help developers build Flutter apps.
-
-Cocoon is not a Google product.
-
-
-# Using Cocoon
-
-## Forcing a refresh from GitHub
-
-The server is driven by commits made to
-https://github.com/flutter/flutter repo. It periodically syncs new
-commits. If you need to manually force a refresh, query
-`https://flutter-dashboard.appspot.com/api/refresh-github-commits`.
-
-You will need to be authenticated with Cocoon to do this.
-
-
-# Developing Cocoon
-
-Cocoon has several components:
-
-* A server, which coordinates everything. This is a Dart App Engine
-  application. If you have never used that before, you may want to
-  [peruse the samples for Dart App
-  Engine](https://github.com/dart-lang/appengine_samples). The server
-  is found in [app_dart](app_dart/).
-
-* A Flutter app (generally used as a Web app) for the build
-  dashboards. The dashboard is found in [dashboard](dashboard/).
-
-Cocoon creates a _checklist_ for each Flutter commit. A checklist is
-made of multiple _tasks_. Tasks are _performed_ by _LUCI bots_.
-
-
-## Getting started
-
-First, [set up a Flutter development
-environment](https://github.com/flutter/flutter/blob/master/CONTRIBUTING.md#developing-for-flutter).
-This will, as a side-effect, provide you with a Dart SDK. Your life
-will be easier if you add that (`.../flutter/bin/cache/dart-sdk/bin/`)
-to your path.
-
-To update the production server, you will need the [Google Cloud
-SDK](https://cloud.google.com/sdk/docs/quickstarts). Since there is no
-Dart SDK, we just use the command line tools.
-
-
-## Developing the server
-
-All the commands in this section assume that you are in the
-`app_dart/` directory.
-
-### Running a local dev server
-
-**This is for legacy users who were granted old security keys. Due to overground, this is no longer supported.**
-
-```sh
-$ export GOOGLE_CLOUD_PROJECT=flutter-dashboard-dev # or flutter-dashboard for prod data
-$ export GCLOUD_KEY=#your_secret # Required for reading/writing from Google Cloud
-$ export COCOON_USE_IN_MEMORY_CACHE=true # Use an in memory cache locally instead of redis to prevent corruption
-$ dart bin/server.dart
-```
-This will output `Serving requests at 0.0.0.0:8080` indicating the server is working.
-
-New requests will be logged to the console.
-
-To develop and test some features, you need to have a local service
-account(key.json) with access to the project you will be connecting to.
-
-If you work for Google you can use the key with flutter-dashboard project
-via [internal doc](https://g3doc.corp.google.com/company/teams/flutter/infrastructure/cocoon/local_development.md?cl=head#test-with-flutter-dashboard-dev-project).
-
-### Deploying a test version on Google Cloud
-
-To run live tests, build the app, and provide instructions for deploying to
-Google App Engine, run this command:
-
-```sh
-dart dev/deploy.dart --project {PROJECT} --version {VERSION}
-```
-
-You can test the new version by accessing
-`{VERSION}-dot-flutter-dashboard.appspot.com` in your browser. If the
-result is satisfactory, the new version can be activated by using the
-Cloud Console UI:
-<https://console.cloud.google.com/appengine/versions?project=flutter-dashboard&serviceId=default>
-
-#### Optional flags
-
-`--profile`: Deploy a profile mode of `dashboard` application for debugging purposes.
-
-`--ignore-version-check`: Ignore the version of Flutter on path (expects to be relatively recent)
-
-
-## Developing the dashboard
-
-The dashboard application will use dummy data when it is not connected
-to the server, so it can be developed locally without a dev server.
-
-To run the dashboard locally, go into the `dashboard` directory and
-run `flutter run -d chrome`. The dashboard will be served from localhost
-(the exact address will be given on the console); copy the URL into
-your browser to view the application. (The dashboard should also be
-able to run on non-Web platforms, but since the Web is our main target
-that is the one that should generally be used for development.)
-
-You can run `flutter packages upgrade` to update the dependencies.
-This may be necessary if you see a failure in the dependencies.
diff --git a/gh_actions/third_party/no-response/action.yml b/action.yml
similarity index 100%
rename from gh_actions/third_party/no-response/action.yml
rename to action.yml
diff --git a/analysis_options.yaml b/analysis_options.yaml
deleted file mode 100644
index d7f6f0f..0000000
--- a/analysis_options.yaml
+++ /dev/null
@@ -1,52 +0,0 @@
-# Specify analysis options for all of flutter/cocoon
-#
-# Until there are meta linter rules, each desired lint must be explicitly enabled.
-# See: https://github.com/dart-lang/linter/issues/288
-#
-# For a list of lints, see: http://dart-lang.github.io/linter/lints/
-# See the configuration guide for more
-# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer
-#
-# There are other similar analysis options files in the flutter repos,
-# which should be kept in sync with this file:
-#
-#   - analysis_options.yaml (this file)
-#   - packages/flutter/lib/analysis_options_user.yaml
-#   - https://github.com/flutter/packages/blob/main/analysis_options.yaml
-#   - https://github.com/flutter/engine/blob/main/analysis_options.yaml
-#
-# This file contains the analysis options used by Flutter tools, such as IntelliJ,
-# Android Studio, and the `flutter analyze` command.
-include: package:flutter_lints/flutter.yaml
-
-analyzer:
-  language:
-    strict-casts: false
-    strict-raw-types: true
-  errors:
-    # treat missing required parameters as a warning (not a hint)
-    missing_required_param: warning
-    # treat missing returns as a warning (not a hint)
-    missing_return: warning
-    # allow having TODOs in the code
-    todo: ignore
-  exclude:
-    - ".dart_tool/**"
-    - "**/*.g.dart"
-    - "**/*.pb.dart"
-    - "**/*.pbjson.dart"
-    - "**/*.pbgrpc.dart"
-    - "**/*.pbserver.dart"
-    - "**/*.pbenum.dart"
-    - "lib/generated_plugin_registrant.dart"
-    - "test/**/mocks.mocks.dart"
-
-linter:
-  rules:
-    use_super_parameters: true
-    prefer_final_fields: true
-    prefer_final_locals: true
-    prefer_single_quotes: true
-    require_trailing_commas: true
-    unawaited_futures: true
-    unnecessary_await_in_return: true
diff --git a/analyze/analyze.dart b/analyze/analyze.dart
deleted file mode 100644
index 5cf5f25..0000000
--- a/analyze/analyze.dart
+++ /dev/null
@@ -1,308 +0,0 @@
-// Copyright 2020 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:core';
-import 'dart:io';
-
-import 'package:file/file.dart';
-import 'package:file/local.dart';
-import 'package:path/path.dart' as path;
-
-const FileSystem fs = LocalFileSystem();
-
-// Cocoon's root is the parent of the current working directory,
-final Directory cocoonRoot = fs.currentDirectory.parent;
-
-Future<void> main(List<String> arguments) async {
-  print('STARTING ANALYSIS');
-  print('cocoonRoot: ${cocoonRoot.path}');
-  await run(arguments);
-  print('Analysis successful.');
-}
-
-Future<void> run(List<String> arguments) async {
-  bool assertsEnabled = false;
-  assert(() {
-    assertsEnabled = true;
-    return true;
-  }());
-  if (!assertsEnabled) {
-    exitWithError(<String>['The analyze.dart script must be run with --enable-asserts.']);
-  }
-
-  print('Trailing spaces...');
-  await verifyNoTrailingSpaces(cocoonRoot.path);
-
-  print('Executable allowlist...');
-  await _checkForNewExecutables();
-
-  print('Proto analysis...');
-  await verifyProtos(cocoonRoot);
-}
-
-// TESTS
-
-Future<void> verifyNoTrailingSpaces(
-  String workingDirectory, {
-  int minimumMatches = 100,
-}) async {
-  final List<File> files = await _allFiles(workingDirectory, null, minimumMatches: minimumMatches)
-      .where((File file) => path.basename(file.path) != 'serviceaccount.enc')
-      .where((File file) => path.basename(file.path) != 'Ahem.ttf')
-      .where((File file) => path.extension(file.path) != '.snapshot')
-      .where((File file) => path.extension(file.path) != '.png')
-      .where((File file) => path.extension(file.path) != '.jpg')
-      .where((File file) => path.extension(file.path) != '.ico')
-      .where((File file) => path.extension(file.path) != '.jar')
-      .where((File file) => path.extension(file.path) != '.swp')
-      .where((File file) => !path.basename(file.path).endsWith('pbserver.dart'))
-      .where((File file) => !path.basename(file.path).endsWith('pb.dart'))
-      .where((File file) => !path.basename(file.path).endsWith('pbenum.dart'))
-      .toList();
-  final List<String> problems = <String>[];
-  for (final File file in files) {
-    final List<String> lines = file.readAsLinesSync();
-    for (int index = 0; index < lines.length; index += 1) {
-      if (lines[index].endsWith(' ')) {
-        problems.add('${file.path}:${index + 1}: trailing U+0020 space character');
-      } else if (lines[index].endsWith('\t')) {
-        problems.add('${file.path}:${index + 1}: trailing U+0009 tab character');
-      }
-    }
-    if (lines.isNotEmpty && lines.last == '') problems.add('${file.path}:${lines.length}: trailing blank line');
-  }
-  if (problems.isNotEmpty) exitWithError(problems);
-}
-
-Future<void> verifyProtos(Directory workingDirectory) async {
-  final List<String> errors = <String>[];
-  final List<File> protos = await _allFiles(workingDirectory.path, 'proto', minimumMatches: 1).toList();
-  for (final File proto in protos) {
-    final String content = proto.readAsStringSync();
-    if (!content.contains(RegExp(r'package\ \w+;'))) {
-      errors.add('${proto.path} requires a package (https://protobuf.dev/programming-guides/proto2/#packages)');
-    }
-  }
-
-  if (errors.isNotEmpty) {
-    exitWithError(<String>[
-      'The following files are missing package declarations:',
-      ...errors,
-    ]);
-  }
-}
-
-// UTILITY FUNCTIONS
-
-Future<List<File>> _gitFiles(String workingDirectory, {bool runSilently = true}) async {
-  final EvalResult evalResult = await _evalCommand(
-    'git',
-    <String>['ls-files', '-z'],
-    workingDirectory: workingDirectory,
-    runSilently: runSilently,
-  );
-  if (evalResult.exitCode != 0) {
-    exitWithError(<String>[
-      'git ls-files failed with exit code ${evalResult.exitCode}',
-      'stdout:',
-      evalResult.stdout,
-      'stderr:',
-      evalResult.stderr,
-    ]);
-  }
-  final List<String> filenames = evalResult.stdout.split('\x00');
-  assert(filenames.last.isEmpty); // git ls-files gives a trailing blank 0x00
-  filenames.removeLast();
-  return filenames.map<File>((String filename) => fs.file(path.join(workingDirectory, filename))).toList();
-}
-
-Stream<File> _allFiles(String workingDirectory, String? extension, {required int minimumMatches}) async* {
-  final Set<String> gitFileNamesSet = <String>{};
-  gitFileNamesSet.addAll((await _gitFiles(workingDirectory)).map((File f) => path.canonicalize(f.absolute.path)));
-
-  assert(extension == null || !extension.startsWith('.'), 'Extension argument should not start with a period.');
-  final Set<FileSystemEntity> pending = <FileSystemEntity>{fs.directory(workingDirectory)};
-  int matches = 0;
-  while (pending.isNotEmpty) {
-    final FileSystemEntity entity = pending.first;
-    pending.remove(entity);
-    if (path.extension(entity.path) == '.tmpl') continue;
-    if (entity is File) {
-      if (!gitFileNamesSet.contains(path.canonicalize(entity.absolute.path))) continue;
-      if (path.basename(entity.path) == 'flutter_export_environment.sh') continue;
-      if (path.basename(entity.path) == 'gradlew.bat') continue;
-      if (path.basename(entity.path) == '.DS_Store') continue;
-      if (extension == null || path.extension(entity.path) == '.$extension') {
-        matches += 1;
-        yield entity;
-      }
-    } else if (entity is Directory) {
-      if (fs.file(path.join(entity.path, '.dartignore')).existsSync()) continue;
-      if (path.basename(entity.path) == '.git') continue;
-      if (path.basename(entity.path) == '.idea') continue;
-      if (path.basename(entity.path) == '.gradle') continue;
-      if (path.basename(entity.path) == '.dart_tool') continue;
-      if (path.basename(entity.path) == '.idea') continue;
-      if (path.basename(entity.path) == 'build') continue;
-      pending.addAll(entity.listSync());
-    }
-  }
-  assert(
-    matches >= minimumMatches,
-    'Expected to find at least $minimumMatches files with extension ".$extension" in "$workingDirectory", but only found $matches.',
-  );
-}
-
-class EvalResult {
-  EvalResult({
-    required this.stdout,
-    required this.stderr,
-    this.exitCode = 0,
-  });
-
-  final String stdout;
-  final String stderr;
-  final int exitCode;
-}
-
-Future<EvalResult> _evalCommand(
-  String executable,
-  List<String> arguments, {
-  required String workingDirectory,
-  Map<String, String>? environment,
-  bool allowNonZeroExit = false,
-  bool runSilently = false,
-}) async {
-  final String commandDescription = '${path.relative(executable, from: workingDirectory)} ${arguments.join(' ')}';
-  final String relativeWorkingDir = path.relative(workingDirectory);
-
-  if (!runSilently) {
-    print('RUNNING $relativeWorkingDir $commandDescription');
-  }
-
-  final Stopwatch time = Stopwatch()..start();
-  final Process process = await Process.start(
-    executable,
-    arguments,
-    workingDirectory: workingDirectory,
-    environment: environment,
-  );
-
-  final Future<List<List<int>>> savedStdout = process.stdout.toList();
-  final Future<List<List<int>>> savedStderr = process.stderr.toList();
-  final int exitCode = await process.exitCode;
-  final EvalResult result = EvalResult(
-    stdout: utf8.decode((await savedStdout).expand<int>((List<int> ints) => ints).toList()),
-    stderr: utf8.decode((await savedStderr).expand<int>((List<int> ints) => ints).toList()),
-    exitCode: exitCode,
-  );
-
-  if (!runSilently) {
-    print('ELAPSED TIME: ${time.elapsed} for $commandDescription in $relativeWorkingDir');
-  }
-
-  if (exitCode != 0 && !allowNonZeroExit) {
-    stderr.write(result.stderr);
-    exitWithError(<String>[
-      'ERROR: Last command exited with $exitCode.',
-      'Command: $commandDescription',
-      'Relative working directory: $relativeWorkingDir',
-    ]);
-  }
-
-  return result;
-}
-
-// These files legitimately require executable permissions
-const Set<String> kExecutableAllowlist = <String>{
-  'app_dart/tool/build.sh',
-  'cipd_packages/codesign/tool/build.sh',
-  'cipd_packages/device_doctor/tool/build.sh',
-  'cipd_packages/doxygen/tool/build.sh',
-  'cloud_build/dashboard_build.sh',
-  'cloud_build/deploy_app_dart.sh',
-  'cloud_build/deploy_auto_submit.sh',
-  'cloud_build/deploy_cron_jobs.sh',
-  'cloud_build/get_docker_image_provenance.sh',
-  'cloud_build/verify_provenance.sh',
-  'dashboard/regen_mocks.sh',
-  'dev/provision_salt.sh',
-  'dev/prs_to_main.sh',
-  'format.sh',
-  'packages/buildbucket-dart/tool/regenerate.sh',
-  'test_utilities/bin/analyze.sh',
-  'test_utilities/bin/config_test_runner.sh',
-  'test_utilities/bin/dart_test_runner.sh',
-  'test_utilities/bin/flutter_test_runner.sh',
-  'test_utilities/bin/global_test_runner.dart',
-  'test_utilities/bin/licenses.sh',
-  'test_utilities/bin/prepare_environment.sh',
-};
-
-const String kShebangRegex = r'#!/usr/bin/env (bash|sh)';
-
-Future<void> _checkForNewExecutables() async {
-  // 0b001001001
-  const int executableBitMask = 0x49;
-  final List<File> files = await _gitFiles(cocoonRoot.path);
-  final List<String> relativePaths = files.map<String>((File file) {
-    return path.relative(
-      file.path,
-      from: cocoonRoot.path,
-    );
-  }).toList();
-  for (String allowed in kExecutableAllowlist) {
-    if (!relativePaths.contains(allowed)) {
-      throw Exception(
-        'File $allowed in kExecutableAllowlist in analyze/analyze.dart '
-        'does not exist. Please fix path or remove from kExecutableAllowlist.',
-      );
-    }
-  }
-  int unexpectedExecutableCount = 0;
-  int unexpectedShebangShellCount = 0;
-  for (final File file in files) {
-    final String relativePath = path.relative(
-      file.path,
-      from: cocoonRoot.path,
-    );
-    final FileStat stat = file.statSync();
-    final bool isExecutable = stat.mode & executableBitMask != 0x0;
-    final bool inAllowList = kExecutableAllowlist.contains(relativePath);
-    if (isExecutable && !inAllowList) {
-      unexpectedExecutableCount += 1;
-      print('$relativePath is executable: ${(stat.mode & 0x1FF).toRadixString(2)}');
-    }
-    if (inAllowList && file.path.endsWith('.sh')) {
-      final String shebang = file.readAsLinesSync().first;
-      if (!shebang.startsWith(RegExp(kShebangRegex))) {
-        unexpectedShebangShellCount += 1;
-        print("$relativePath has the initial line of $shebang, which doesn't match '$kShebangRegex'");
-      }
-    }
-  }
-  if (unexpectedExecutableCount > 0) {
-    throw Exception(
-      'found $unexpectedExecutableCount unexpected executable file'
-      '${unexpectedExecutableCount == 1 ? '' : 's'}! If this was intended, you '
-      'must add this file to kExecutableAllowlist in analyze/analyze.dart',
-    );
-  }
-  if (unexpectedShebangShellCount > 0) {
-    throw Exception(
-      'found $unexpectedShebangShellCount unexpected shell #! line'
-      '${unexpectedShebangShellCount == 1 ? '' : 's'}! If this was intended, you '
-      'must modify kShebangRegex in analyze/analyze.dart',
-    );
-  }
-}
-
-void exitWithError(List<String> messages) {
-  final String line = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━';
-  print(line);
-  messages.forEach(print);
-  print(line);
-  exit(1);
-}
diff --git a/analyze/pubspec.yaml b/analyze/pubspec.yaml
deleted file mode 100644
index 46bce17..0000000
--- a/analyze/pubspec.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: cocoon_analyze
-description: Cocoon static analysis scripts
-publish_to: none
-
-environment:
-  sdk: ">=2.18.0 <4.0.0"
-
-dependencies:
-  file: 7.0.0
-  path: 1.8.3
-  platform: 3.1.3
-
-dev_dependencies:
-  mockito: 5.4.2
-  test_api: 0.6.1
diff --git a/app_dart/.gitignore b/app_dart/.gitignore
deleted file mode 100644
index 3c8a157..0000000
--- a/app_dart/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-# Files and directories created by pub.
-.dart_tool/
-.packages
-
-# Conventional directory for build output.
-build/
diff --git a/app_dart/Dockerfile b/app_dart/Dockerfile
deleted file mode 100644
index 27652a3..0000000
--- a/app_dart/Dockerfile
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2022 The Flutter Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-# Dart Docker official images can be found here: https://hub.docker.com/_/dart
-FROM dart:beta@sha256:88ced76ff4a63e565872df26fe2442f060e3ecf828a272090ad10c79e9d044af
-
-WORKDIR /app
-
-# Copy app source code (except anything in .dockerignore).
-COPY . .
-RUN dart pub get
-
-# Start server.
-EXPOSE 8080
-CMD ["/usr/lib/dart/bin/dart", "/app/bin/server.dart"]
diff --git a/app_dart/LICENSE b/app_dart/LICENSE
deleted file mode 100644
index d5384ca..0000000
--- a/app_dart/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright 2016 The Flutter Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/app_dart/README.md b/app_dart/README.md
deleted file mode 100644
index d135d79..0000000
--- a/app_dart/README.md
+++ /dev/null
@@ -1,166 +0,0 @@
-# Dart backend for cocoon
-
-This folder contains a Dart based backend for Cocoon.
-
-## Building and running
-
-### Prerequisites
-
-* Install the Google Cloud Developer Tools Command Line Interface
-([`gcloud`](https://cloud.google.com/sdk/docs/quickstarts)). Then initialize it
-and authenticate yourself by running:
-
-```sh
-gcloud auth login
-gcloud init
-```
-* [Install Flutter](https://flutter.dev/docs/get-started/install )
-```sh
-export PATH="$PATH":"path/to/flutter/bin/"
-flutter upgrade
-flutter pub get
-export PATH="$PATH":"path/to/flutter/bin/cache/dart-sdk/bin/"
-```
-
-### Running the tests
-
-```sh
-$ dart test
-```
-
-### Running codegen
-
-#### JSON
-
-To update the JSON serialization generated code, run:
-
-```sh
-$ dart run build_runner build
-```
-
-Any updates should be checked into source control.
-
-#### Protobuf
-
-To update the Protocol Buffer generated code:
-
-1. [Download](https://github.com/protocolbuffers/protobuf/releases) and install
-   the protocol buffer compiler (`protoc`). Once installed, update your `PATH`
-   to include the path to the `protoc` binary.
-
-   On Linux, use `sudo apt-get install protocol-compiler` to install.
-   On macOS, use `brew install protobuf`
-
-2. Install the [`protoc_plugin`](https://pub.dev/packages/protoc_plugin) Dart
-   package. Once installed, update your `PATH` to include the path to the
-   `protoc_plugin/bin` directory (or `$HOME/.pub-cache/bin` if you used
-   `pub global activate protoc_plugin`).
-
-3. Run the following command:
-
-   ```sh
-   $ protoc --dart_out=. lib/src/model/proto/**/*.proto
-   ```
-
-4. Remove the unused generated files:
-
-   ```sh
-   $ find . -regex '.*\.\(pbjson\|pbserver\)\.dart' -delete
-   ```
-   (you can remove the `*.pbenum.dart` files too, except for protobuffers that actually define enums,
-   like `build_status_response.proto`)
-
-### Generating cloud datastore indexes
-
-To update the indexes in the App Engine project, run:
-
-```sh
-$ gcloud datastore indexes create index.yaml
-```
-
-### Local development
-
-#### Using physical machine
-
-* Setting up the environment
-
-```sh
-export COCOON_USE_IN_MEMORY_CACHE=true
-```
-
-This environment is needed as you don't have access to the remote redis
-instance during local development.
-
-* Starting server
-
-```sh
-export COCOON_USE_IN_MEMORY_CACHE=true
-dart bin/server.dart
-```
-
-If you see Serving requests at 0.0.0.0:8080 the dev server is working.
-
-#### Using Docker
-
-* Running a local development instance
-
-Once you've installed Docker and have the `docker` command-line tool in
-your path, then you can use the following commands to build, run, stop,
-and kill a local development instance.
-
-```sh
-# Build the docker image
-$ docker build -t local .
-
-# Start the local container, clearing the console buffer and tailing the logs
-$ container_id="$(docker run -d -p 8080:8080 local)" && \
-    clear && \
-    printf '\e[3J' && \
-    docker logs $container_id -f
-
-# Stop the local Docker container
-$ docker container ls|grep local|tr -s ' '|cut -d' ' -f1|xargs docker container stop
-
-# Remove the local Docker image
-$ docker images|grep local|tr -s ' '|cut -d' ' -f3|xargs docker rmi -f
-```
-
-* ssh into instance
-
-```sh
-$ docker exec -it <container name> /bin/bash
-```
-
-### Deploying a release to App Engine
-
-#### [Auto-deploy](go/cocoon-cloud-build#auto-deploy)
-Cocoon auto deployment has been set up via
-[Google Cloud Build](https://console.cloud.google.com/cloud-build/triggers?project=flutter-dashboard)
-daily on Workdays.
-
-#### [Manual-deploy(go/cocoon-cloud-build#manual-deploy)
-
-* Using the cloud build
-
-This is easy to deploy if you simply want a new version based on
-the latest commit. Open
-[Cloud Build dashboard](https://console.cloud.google.com/cloud-build/triggers?project=flutter-dashboard)
-and click run in the push-master trigger ([example](https://screenshot.googleplex.com/4DDy4XdVQxMKqCd))
-
-* Using a cocoon checkout
-Let `PROJECT_ID` be the Google Cloud Project ID and `VERSION` be the version you're deploying to App Engine. Visit
-https://console.cloud.google.com/appengine/versions?project=flutter-dashboard
-for the list of current versions.
-
-```sh
-$ dart dev/deploy.dart --version version-$(git rev-parse --short HEAD) --project flutter-dashboard
-```
-
-The deploy script will build the Flutter project and copy it over for deployment.
-Then it will use the Google Cloud CLI to deploy the project to AppEngine.
-
-For more options run:
-
-```sh
-$ dart dev/deploy.dart --help
-```
diff --git a/app_dart/analysis_options.yaml b/app_dart/analysis_options.yaml
deleted file mode 100644
index f4cf71f..0000000
--- a/app_dart/analysis_options.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-include: ../analysis_options.yaml
-
-linter:
-  rules:
-    # a few rules listed below are the ones we would like to exclude from flutter_lint package, for app_dart
-    # reasons for exclusions are provided in the comments to the right
-    avoid_print: false # we have necessary print calls in the code
-    constant_identifier_names: false # we have all capitalized enums in check_for_waiting_pull_requests_test.dart
diff --git a/app_dart/app.yaml b/app_dart/app.yaml
deleted file mode 100644
index 2a3ec5b..0000000
--- a/app_dart/app.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2019 The Flutter Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-runtime: custom
-env: flex
-service: default
-
-readiness_check:
-  path: "/readiness_check"
-  check_interval_sec: 20
-  timeout_sec: 20
-  failure_threshold: 10
-  success_threshold: 2
-  app_start_timeout_sec: 600
-
-resources:
-  memory_gb: 4.0
-
-handlers:
-# The Dart server handles all requests. However, this is used to ensure the
-# assets the dart server needs are uploaded to AppEngine.
-- url: /v2/(.*\.(html|css|js|ico|svg|png|jpg|map))$
-  application_readable: true # So the dart server can read the files
-  # If the Dart custom runtime changes and starts using this handler,
-  # we want to know. This will have the app only serve HTML and we
-  # will know we can remove the Dart handling code. Just swap
-  # index.html to \1
-  static_files: build/web/index.html
-  # app_flutter's build files needed to be copied over to this project. This
-  # is because the Google Cloud utility cannot go outside the scope of app_dart.
-  # Navigating to ../app_flutter/build/web will silently error.
-  upload: build/web/.*\.(html|css|js|ico|svg|png|jpg|map)$
diff --git a/app_dart/bin/generate_jspb.dart b/app_dart/bin/generate_jspb.dart
deleted file mode 100644
index f48082b..0000000
--- a/app_dart/bin/generate_jspb.dart
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2021 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:cocoon_service/protos.dart' as pb;
-import 'package:github/github.dart';
-import 'package:http/http.dart' as http;
-import 'package:yaml/yaml.dart';
-
-Future<String> githubFileContent(
-  RepositorySlug slug,
-  String filePath, {
-  String ref = 'master',
-  Duration timeout = const Duration(seconds: 5),
-}) async {
-  final Uri githubUrl = Uri.https('raw.githubusercontent.com', '${slug.fullName}/$ref/$filePath');
-  return getUrl(githubUrl);
-}
-
-FutureOr<String> getUrl(Uri url) async {
-  final http.Client client = http.Client();
-  try {
-    final http.Response response = await client.get(url);
-
-    if (response.statusCode == HttpStatus.ok) {
-      return response.body;
-    } else {
-      throw HttpException('HTTP ${response.statusCode}: $url');
-    }
-  } finally {
-    client.close();
-  }
-}
-
-Future<String> getRemoteConfigContent(String repo, String ref) async {
-  final String configContent = await githubFileContent(
-    RepositorySlug('flutter', repo),
-    '.ci.yaml',
-    ref: ref,
-  );
-  return configContent;
-}
-
-String getLocalConfigContent(String path) {
-  final File configFile = File(path);
-  return configFile.readAsStringSync();
-}
-
-Future<void> main(List<String> args) async {
-  if (args.length != 1 && args.length != 2) {
-    print('generate_jspb.dart \$local_ci_yaml');
-    print('generate_jspb.dart \$repo \$sha');
-    exit(1);
-  }
-  String configContent;
-  if (args.length == 2) {
-    configContent = await getRemoteConfigContent(args[0], args[1]);
-  } else {
-    configContent = getLocalConfigContent(args[0]);
-  }
-
-  final YamlMap configYaml = loadYaml(configContent) as YamlMap;
-  final pb.SchedulerConfig schedulerConfig = pb.SchedulerConfig()..mergeFromProto3Json(configYaml);
-
-  print(jsonEncode(schedulerConfig.toProto3Json()));
-}
diff --git a/app_dart/bin/server.dart b/app_dart/bin/server.dart
deleted file mode 100644
index e278599..0000000
--- a/app_dart/bin/server.dart
+++ /dev/null
@@ -1,320 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:io';
-import 'dart:math';
-
-import 'package:appengine/appengine.dart';
-import 'package:cocoon_service/cocoon_service.dart';
-import 'package:cocoon_service/src/service/commit_service.dart';
-import 'package:gcloud/db.dart';
-
-/// For local development, you might want to set this to true.
-const String _kCocoonUseInMemoryCache = 'COCOON_USE_IN_MEMORY_CACHE';
-
-Future<void> main() async {
-  await withAppEngineServices(() async {
-    useLoggingPackageAdaptor();
-
-    final bool inMemoryCache = Platform.environment[_kCocoonUseInMemoryCache] == 'true';
-    final CacheService cache = CacheService(inMemory: inMemoryCache);
-
-    final Config config = Config(dbService, cache);
-    final AuthenticationProvider authProvider = AuthenticationProvider(config: config);
-    final AuthenticationProvider swarmingAuthProvider = SwarmingAuthenticationProvider(config: config);
-    final BuildBucketClient buildBucketClient = BuildBucketClient(
-      accessTokenService: AccessTokenService.defaultProvider(config),
-    );
-
-    /// LUCI service class to communicate with buildBucket service.
-    final LuciBuildService luciBuildService = LuciBuildService(
-      config: config,
-      cache: cache,
-      buildBucketClient: buildBucketClient,
-      pubsub: const PubSub(),
-    );
-
-    /// Github checks api service used to provide luci test execution status on the Github UI.
-    final GithubChecksService githubChecksService = GithubChecksService(
-      config,
-    );
-
-    // Gerrit service class to communicate with GoB.
-    final GerritService gerritService = GerritService(config: config);
-
-    /// Cocoon scheduler service to manage validating commits in presubmit and postsubmit.
-    final Scheduler scheduler = Scheduler(
-      cache: cache,
-      config: config,
-      githubChecksService: githubChecksService,
-      luciBuildService: luciBuildService,
-    );
-
-    final BranchService branchService = BranchService(
-      config: config,
-      gerritService: gerritService,
-    );
-
-    final CommitService commitService = CommitService(config: config);
-
-    final Map<String, RequestHandler<dynamic>> handlers = <String, RequestHandler<dynamic>>{
-      '/api/check_flaky_builders': CheckFlakyBuilders(
-        config: config,
-        authenticationProvider: authProvider,
-      ),
-      '/api/create-branch': CreateBranch(
-        branchService: branchService,
-        config: config,
-        authenticationProvider: authProvider,
-      ),
-      '/api/dart-internal-subscription': DartInternalSubscription(
-        cache: cache,
-        config: config,
-        buildBucketClient: buildBucketClient,
-      ),
-      '/api/file_flaky_issue_and_pr': FileFlakyIssueAndPR(
-        config: config,
-        authenticationProvider: authProvider,
-      ),
-      '/api/flush-cache': FlushCache(
-        config: config,
-        authenticationProvider: authProvider,
-        cache: cache,
-      ),
-      '/api/github-webhook-pullrequest': GithubWebhook(
-        config: config,
-        pubsub: const PubSub(),
-        secret: config.webhookKey,
-        topic: 'github-webhooks',
-      ),
-      // TODO(chillers): Move to release service. https://github.com/flutter/flutter/issues/132082
-      '/api/github/frob-webhook': GithubWebhook(
-        config: config,
-        pubsub: const PubSub(),
-        secret: config.frobWebhookKey,
-        topic: 'frob-webhooks',
-      ),
-      '/api/github/webhook-subscription': GithubWebhookSubscription(
-        config: config,
-        cache: cache,
-        gerritService: gerritService,
-        githubChecksService: githubChecksService,
-        scheduler: scheduler,
-        commitService: commitService,
-      ),
-      '/api/presubmit-luci-subscription': PresubmitLuciSubscription(
-        cache: cache,
-        config: config,
-        buildBucketClient: buildBucketClient,
-        luciBuildService: luciBuildService,
-        githubChecksService: githubChecksService,
-        scheduler: scheduler,
-      ),
-      '/api/postsubmit-luci-subscription': PostsubmitLuciSubscription(
-        cache: cache,
-        config: config,
-        scheduler: scheduler,
-        githubChecksService: githubChecksService,
-      ),
-      '/api/push-build-status-to-github': PushBuildStatusToGithub(
-        config: config,
-        authenticationProvider: authProvider,
-      ),
-      '/api/push-gold-status-to-github': PushGoldStatusToGithub(
-        config: config,
-        authenticationProvider: authProvider,
-      ),
-      '/api/reset-prod-task': ResetProdTask(
-        config: config,
-        authenticationProvider: authProvider,
-        luciBuildService: luciBuildService,
-        scheduler: scheduler,
-      ),
-      '/api/reset-try-task': ResetTryTask(
-        config: config,
-        authenticationProvider: authProvider,
-        scheduler: scheduler,
-      ),
-      '/api/scheduler/batch-backfiller': BatchBackfiller(
-        config: config,
-        scheduler: scheduler,
-      ),
-      '/api/scheduler/batch-request-subscription': SchedulerRequestSubscription(
-        cache: cache,
-        config: config,
-        buildBucketClient: buildBucketClient,
-      ),
-      '/api/scheduler/vacuum-stale-tasks': VacuumStaleTasks(
-        config: config,
-      ),
-      '/api/update_existing_flaky_issues': UpdateExistingFlakyIssue(
-        config: config,
-        authenticationProvider: authProvider,
-      ),
-
-      /// Updates task related details.
-      ///
-      /// This API updates task status in datastore and
-      /// pushes performance metrics to skia-perf.
-      ///
-      /// POST: /api-update-status
-      ///
-      /// Parameters:
-      ///   CommitBranch: (string in body). Branch of commit.
-      ///   CommitSha: (string in body). Sha of commit.
-      ///   BuilderName: (string in body). Name of the luci builder.
-      ///   NewStatus: (string in body) required. Status of the task.
-      ///   ResultData: (string in body) optional. Benchmark data.
-      ///   BenchmarkScoreKeys: (string in body) optional. Benchmark data.
-      ///
-      /// Response: Status 200 OK
-      '/api/update-task-status': UpdateTaskStatus(
-        config: config,
-        authenticationProvider: swarmingAuthProvider,
-      ),
-      '/api/vacuum-github-commits': VacuumGithubCommits(
-        config: config,
-        authenticationProvider: authProvider,
-        scheduler: scheduler,
-      ),
-
-      /// Returns status of the framework tree.
-      ///
-      /// Returns serialized proto with enum representing the
-      /// status of the tree and list of offending tasks.
-      ///
-      /// GET: /api/public/build-status
-      ///
-      /// Parameters:
-      ///   branch: (string in query) default: 'master'. Name of the repo branch.
-      ///
-      /// Response: Status 200 OK
-      /// Returns [BuildStatusResponse]:
-      ///  {
-      ///    1: 2,
-      ///    2: [ "win_tool_tests_commands", "win_build_test", "win_module_test"]
-      ///   }
-      '/api/public/build-status': CacheRequestHandler<Body>(
-        cache: cache,
-        config: config,
-        delegate: GetBuildStatus(config: config),
-        ttl: const Duration(seconds: 15),
-      ),
-      '/api/public/get-release-branches': CacheRequestHandler<Body>(
-        cache: cache,
-        config: config,
-        delegate: GetReleaseBranches(config: config, branchService: branchService),
-        ttl: const Duration(hours: 1),
-      ),
-
-      /// Returns task results for commits.
-      ///
-      /// Returns result details about each task in each checklist for every commit.
-      ///
-      /// GET: /api/public/get-status
-      ///
-      /// Parameters:
-      ///   branch: (string in query) default: 'master'. Name of the repo branch.
-      ///   lastCommitKey: (string in query) optional. Encoded commit key for the last commit to return resutls.
-      ///
-      /// Response: Status: 200 OK
-      ///   {"Statuses":[
-      ///     {"Checklist":{
-      ///        "Key":"ah..jgM",
-      ///        "Checklist":{"FlutterRepositoryPath":"flutter/flutter",
-      ///        "CreateTimestamp":1620134239000,
-      ///        "Commit":{"Sha":"7f1d1414cc5f0b0317272ced49a9c0b44e5c3af8",
-      ///        "Message":"Revert \"Migrate to ChannelBuffers.push\"",
-      ///        "Author":{"Login":"renyou","avatar_url":"https://avatars.githubusercontent.com/u/666474?v=4"}},"Branch":"master"}},
-      ///        "Stages":[{"Name":"chromebot",
-      ///          "Tasks":[
-      ///            {"Task":{
-      ///            "ChecklistKey":"ahF..jgM",
-      ///            "CreateTimestamp":1620134239000,
-      ///            "StartTimestamp":0,
-      ///            "EndTimestamp":1620136203757,
-      ///            "Name":"linux_cubic_bezier_perf__e2e_summary",
-      ///            "Attempts":1,
-      ///            "Flaky":false,
-      ///            "TimeoutInMinutes":0,
-      ///            "Reason":"",
-      ///            "BuildNumber":null,
-      ///            "BuildNumberList":"1279",
-      ///            "BuilderName":"Linux cubic_bezier_perf__e2e_summary",
-      ///            "luciBucket":"luci.flutter.prod",
-      ///            "RequiredCapabilities":["can-update-github"],
-      ///            "ReservedForAgentID":"",
-      ///            "StageName":"chromebot",
-      ///            "Status":"Succeeded"
-      ///            },
-      ///          ],
-      ///          "Status": "InProgress",
-      ///        ]},
-      ///       },
-      ///     }
-      '/api/public/get-status': CacheRequestHandler<Body>(
-        cache: cache,
-        config: config,
-        delegate: GetStatus(config: config),
-      ),
-
-      '/api/public/get-green-commits': GetGreenCommits(config: config),
-
-      /// Record GitHub API quota usage in BigQuery.
-      ///
-      /// Pushes data to BigQuery for metric collection to
-      /// analyze usage over time.
-      ///
-      /// This api is called via cron job.
-      ///
-      /// GET: /api/public/github-rate-limit-status
-      ///
-      /// Response: Status 200 OK
-      '/api/public/github-rate-limit-status': CacheRequestHandler<Body>(
-        config: config,
-        cache: cache,
-        ttl: const Duration(minutes: 1),
-        delegate: GithubRateLimitStatus(config: config),
-      ),
-      '/api/public/repos': GetRepos(config: config),
-
-      /// Handler for AppEngine to identify when dart server is ready to serve requests.
-      '/readiness_check': ReadinessCheck(config: config),
-    };
-
-    return runAppEngine(
-      (HttpRequest request) async {
-        if (handlers.containsKey(request.uri.path)) {
-          final RequestHandler<dynamic> handler = handlers[request.uri.path]!;
-          await handler.service(request);
-        } else {
-          /// Requests with query parameters and anchors need to be trimmed to get the file path.
-          // TODO(chillers): Use toFilePath(), https://github.com/dart-lang/sdk/issues/39373
-          final int queryIndex =
-              request.uri.path.contains('?') ? request.uri.path.indexOf('?') : request.uri.path.length;
-          final int anchorIndex =
-              request.uri.path.contains('#') ? request.uri.path.indexOf('#') : request.uri.path.length;
-
-          /// Trim to the first instance of an anchor or query.
-          final int trimIndex = min(queryIndex, anchorIndex);
-          final String filePath = request.uri.path.substring(0, trimIndex);
-
-          const Map<String, String> redirects = <String, String>{
-            '/build.html': '/#/build',
-          };
-          if (redirects.containsKey(filePath)) {
-            request.response.statusCode = HttpStatus.permanentRedirect;
-            return request.response.redirect(Uri.parse(redirects[filePath]!));
-          }
-
-          await StaticFileHandler(filePath, config: config).service(request);
-        }
-      },
-      onAcceptingConnections: (InternetAddress address, int port) {
-        final String host = address.isLoopback ? 'localhost' : address.host;
-        print('Serving requests at http://$host:$port/');
-      },
-    );
-  });
-}
diff --git a/app_dart/bin/validate_scheduler_config.dart b/app_dart/bin/validate_scheduler_config.dart
deleted file mode 100644
index 3b3fb11..0000000
--- a/app_dart/bin/validate_scheduler_config.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2021 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:cocoon_service/protos.dart' as pb;
-import 'package:cocoon_service/src/model/ci_yaml/ci_yaml.dart';
-import 'package:cocoon_service/src/service/config.dart';
-import 'package:yaml/yaml.dart';
-
-void main(List<String> args) async {
-  if (args.length != 1) {
-    print('validate_scheduler_config.dart configPath');
-    exit(1);
-  }
-  final String configPath = args.first;
-  final File configFile = File(configPath);
-  if (!configFile.existsSync()) {
-    print('validate_scheduler_config.dart configPath');
-    exit(1);
-  }
-
-  final YamlMap configYaml = loadYaml(configFile.readAsStringSync()) as YamlMap;
-  final pb.SchedulerConfig unCheckedSchedulerConfig = pb.SchedulerConfig()..mergeFromProto3Json(configYaml);
-  print(
-    CiYaml(
-      slug: Config.flutterSlug,
-      branch: Config.defaultBranch(Config.flutterSlug),
-      config: unCheckedSchedulerConfig,
-    ).config,
-  );
-}
diff --git a/app_dart/bin/validate_task_ownership.dart b/app_dart/bin/validate_task_ownership.dart
deleted file mode 100644
index f3e18c4..0000000
--- a/app_dart/bin/validate_task_ownership.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2021 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:io' as io;
-
-import 'package:cocoon_service/cocoon_service.dart';
-import 'package:cocoon_service/src/foundation/utils.dart';
-import 'package:file/file.dart';
-import 'package:file/local.dart';
-import 'package:github/github.dart';
-import 'package:http/http.dart' as http;
-
-/// Remote check based on flutter `repo` and the commit `ref`.
-///
-/// This currently supports `flutter/flutter` only.
-Future<List<String>> remoteCheck(String repo, String ref) async {
-  final String ciYamlContent = await githubFileContent(
-    RepositorySlug('flutter', repo),
-    kCiYamlPath,
-    httpClientProvider: () => http.Client(),
-    ref: ref,
-  );
-  final String testOwnersContent = await githubFileContent(
-    RepositorySlug('flutter', repo),
-    kTestOwnerPath,
-    httpClientProvider: () => http.Client(),
-    ref: ref,
-  );
-
-  final List<String> noOwnerBuilders = validateOwnership(ciYamlContent, testOwnersContent, unfilteredTargets: true);
-  return noOwnerBuilders;
-}
-
-/// Local check is based on paths to the local `.ci.yaml` and `TESTOWNERS` files.
-List<String> localCheck(String ciYamlPath, String testOwnersPath) {
-  const FileSystem fs = LocalFileSystem();
-  final File ciYamlFile = fs.file(ciYamlPath);
-  final File testOwnersFile = fs.file(testOwnersPath);
-  if (!ciYamlFile.existsSync() || !testOwnersFile.existsSync()) {
-    print('Make sure ciYamlPath and testOwnersPath exist.');
-    io.exit(1);
-  }
-  final List<String> noOwnerBuilders =
-      validateOwnership(ciYamlFile.readAsStringSync(), testOwnersFile.readAsStringSync(), unfilteredTargets: true);
-  return noOwnerBuilders;
-}
-
-/// Validates task ownership.
-///
-/// It expects two parameters for remote validation: the flutter `repo` and the `commit`.
-///
-/// It expects three parameters for local validation: `local` arg, the full path to the config
-/// file (`.ci.yaml`), and the full pathto the `TESTOWNERS` file.
-Future<void> main(List<String> args) async {
-  if (args.length != 2 && args.length != 3) {
-    print('validate_task_ownership.dart \$repo \$sha');
-    print('validate_task_ownership.dart local \$local_ci_yaml \$local_TESTOWNERS');
-    io.exit(1);
-  }
-  List<String> noOwnerBuilders;
-  if (args.length == 2) {
-    noOwnerBuilders = await remoteCheck(args[0], args[1]);
-  } else {
-    noOwnerBuilders = localCheck(args[1], args[2]);
-  }
-  if (noOwnerBuilders.isNotEmpty) {
-    print('# Test ownership check failed.');
-    print('Builders missing owner: $noOwnerBuilders');
-    print('Please define ownership in https://github.com/flutter/flutter/blob/master/TESTOWNERS');
-    io.exit(1);
-  } else {
-    print('# Test ownership check succeeded.');
-  }
-}
diff --git a/app_dart/build.yaml b/app_dart/build.yaml
deleted file mode 100644
index aaf332d..0000000
--- a/app_dart/build.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-targets:
-  $default:
-    builders:
-      source_gen|combining_builder:
-        options:
-          ignore_for_file:
-            - always_specify_types
-            - implicit_dynamic_parameter
diff --git a/app_dart/cloudbuild_app_dart.yaml b/app_dart/cloudbuild_app_dart.yaml
deleted file mode 100644
index 6f10220..0000000
--- a/app_dart/cloudbuild_app_dart.yaml
+++ /dev/null
@@ -1,40 +0,0 @@
-# Provide instructions for google Cloud Build to auto-build flutter
-# dashboard to flutter-dashboard project. Auto-build will be triggered
-# by daily schedule on `main` branch. This cloudbuild calls an additional
-# cloudbuild configuration responsible for deployment.
-#
-# This job is for generating the docker image with build provenance,
-# and the deployment job uses the generated docker image and deploys it to
-# App Engine.
-
-steps:
-  # Build dashboard.
-  # This step generates the dashboard files using flutter, then moves the
-  # generated files into the app_dart folder, where a docker image is then
-  # created in the next step.
-  - name: us-docker.pkg.dev/$PROJECT_ID/flutter/flutter
-    entrypoint: '/bin/bash'
-    args: ['cloud_build/dashboard_build.sh']
-
-  # Build docker image
-  - name: 'us-docker.pkg.dev/cloud-builders/ga/v1/docker'
-    args: ['build', '-t', 'us-docker.pkg.dev/$PROJECT_ID/appengine/default.version-$SHORT_SHA', 'app_dart']
-
-  # Trigger the cloud build that deploys the docker image
-  - name: gcr.io/cloud-builders/gcloud
-    entrypoint: '/bin/bash'
-    args:
-      - '-c'
-      - |-
-        gcloud builds submit \
-          --config app_dart/cloudbuild_app_dart_deploy.yaml \
-          --substitutions="SHORT_SHA=$SHORT_SHA" \
-          --async
-
-timeout: 1200s
-
-images: ['us-docker.pkg.dev/$PROJECT_ID/appengine/default.version-$SHORT_SHA']
-
-# If build provenance is not generated, the docker deployment will fail.
-options:
-  requestedVerifyOption: VERIFIED
diff --git a/app_dart/cloudbuild_app_dart_deploy.yaml b/app_dart/cloudbuild_app_dart_deploy.yaml
deleted file mode 100644
index ab31d39..0000000
--- a/app_dart/cloudbuild_app_dart_deploy.yaml
+++ /dev/null
@@ -1,41 +0,0 @@
-# Provide instructions for google Cloud Build to auto-build flutter
-# dashboard to flutter-dashboard project. Auto-build will be triggered
-# by daily schedule on `main` branch.
-#
-# The auto-build will be skipped if no new commits since last deployment.
-
-steps:
-  # Get recently pushed docker image and associated provenance, along with the
-  # correct docker digest url, including the hash.
-  - name: gcr.io/cloud-builders/gcloud
-    entrypoint: '/bin/bash'
-    args:
-      - '-c'
-      - |-
-        cloud_build/get_docker_image_provenance.sh \
-          us-docker.pkg.dev/$PROJECT_ID/appengine/default.version-$SHORT_SHA:latest \
-          unverified_provenance.json
-
-  # Verify provenance is valid before proceeding with deployment.
-  - name: 'golang:1.20'
-    entrypoint: '/bin/bash'
-    args:
-      - '-c'
-      - |-
-        cloud_build/verify_provenance.sh unverified_provenance.json
-
-  # Deploy a new version to google cloud.
-  - name: gcr.io/cloud-builders/gcloud
-    entrypoint: '/bin/bash'
-    args:
-      - '-c'
-      - |-
-        gcloud config set project $PROJECT_ID
-        latest_version=$(gcloud app versions list --hide-no-traffic --format 'value(version.id)')
-        if [ "$latest_version" = "version-$SHORT_SHA" ]; then
-          echo "No updates since last deployment."
-        else
-          bash cloud_build/deploy_app_dart.sh $PROJECT_ID $SHORT_SHA
-        fi
-
-timeout: 1200s
diff --git a/app_dart/dev/deploy.dart b/app_dart/dev/deploy.dart
deleted file mode 100644
index 6e74186..0000000
--- a/app_dart/dev/deploy.dart
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:args/args.dart';
-
-const String cloudbuildDirectory = 'cloud_build';
-const String workspaceDirectory = '../';
-
-const String gcloudProjectIdFlag = 'project';
-const String gcloudProjectIdAbbrFlag = 'p';
-
-const String gcloudProjectVersionFlag = 'version';
-const String gcloudProjectVersionAbbrFlag = 'v';
-
-const String ignoreVersionFlag = 'ignore-version-check';
-const String helpFlag = 'help';
-
-String? _gcloudProjectId;
-String? _gcloudProjectVersion;
-
-late bool _ignoreVersion;
-
-/// Check if [gcloudProjectIdFlag] and [gcloudProjectVersionFlag]
-/// were passed as arguments. If they were, also set [_gcloudProjectId]
-/// and [_gcloudProjectVersion] accordingly.
-bool _getArgs(ArgParser argParser, List<String> arguments) {
-  final ArgResults args = argParser.parse(arguments);
-
-  final bool printHelpMessage = args[helpFlag] as bool;
-  if (printHelpMessage) {
-    return false;
-  }
-
-  _gcloudProjectId = args[gcloudProjectIdFlag] as String?;
-  _gcloudProjectVersion = args[gcloudProjectVersionFlag] as String?;
-  _ignoreVersion = args[ignoreVersionFlag] as bool;
-
-  if (_gcloudProjectId == null) {
-    stderr.write('--$gcloudProjectIdFlag must be defined\n');
-    return false;
-  }
-
-  if (_gcloudProjectVersion == null) {
-    stderr.write('--$gcloudProjectVersionFlag must be defined\n');
-    return false;
-  }
-
-  return true;
-}
-
-/// Check the Flutter version installed and make sure it is a recent version
-/// from the past 21 days.
-///
-/// Flutter tools handles the rest of the checks (e.g. Dart version) when
-/// building the project.
-Future<bool> _checkDependencies() async {
-  if (_ignoreVersion) {
-    return true;
-  }
-
-  stdout.writeln('Checking Flutter version via flutter --version');
-  final ProcessResult result = await Process.run('flutter', <String>['--version']);
-  final String flutterVersionOutput = result.stdout as String;
-
-  // This makes an assumption that only the framework will have its version
-  // printed out with the date in YYYY-MM-DD format.
-  final RegExp dateRegExp = RegExp(r'([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))');
-  final String flutterVersionDateRaw = dateRegExp.allMatches(flutterVersionOutput).first.group(0)!;
-
-  final DateTime flutterVersionDate = DateTime.parse(flutterVersionDateRaw);
-  final DateTime now = DateTime.now();
-  final Duration lastUpdateToFlutter = now.difference(flutterVersionDate);
-
-  return lastUpdateToFlutter.inDays < 21;
-}
-
-/// Run the Google Cloud CLI tool to deploy to [_gcloudProjectId] under
-/// version [_gcloudProjectVersion].
-Future<bool> _deployToAppEngine() async {
-  stdout.writeln('Deploying to AppEngine');
-
-  /// The Google Cloud deployment command is an interactive process. It will
-  /// print out what it is about to do, and ask for confirmation (Y/n).
-  final Process process = await Process.start(
-    'gcloud',
-    <String>[
-      'app',
-      'deploy',
-      '--project',
-      _gcloudProjectId!,
-      '--version',
-      _gcloudProjectVersion!,
-      '--no-promote',
-      '--no-stop-previous-version',
-      '--quiet',
-    ],
-  );
-
-  /// Let this user confirm the details before Google Cloud sends for deployment.
-  unawaited(stdin.pipe(process.stdin));
-
-  await process.stderr.pipe(stderr);
-  await process.stdout.pipe(stdout);
-
-  return await process.exitCode == 0;
-}
-
-/// Run [args] in bash shell and validate it finshes with exit code 0.
-Future<void> shellCommand(List<String> args) async {
-  final ProcessResult result = await Process.run(
-    'bash',
-    args,
-    workingDirectory: workspaceDirectory,
-  );
-
-  if (result.exitCode != 0) {
-    print('$args failed with exit code ${result.exitCode}');
-    print('stdout: ${result.stdout}');
-    print('stderr: ${result.stderr}');
-    exit(1);
-  }
-}
-
-Future<void> main(List<String> arguments) async {
-  final ArgParser argParser = ArgParser()
-    ..addOption(gcloudProjectIdFlag, abbr: gcloudProjectIdAbbrFlag)
-    ..addOption(gcloudProjectVersionFlag, abbr: gcloudProjectVersionAbbrFlag)
-    ..addFlag(ignoreVersionFlag)
-    ..addFlag(helpFlag);
-
-  if (!_getArgs(argParser, arguments)) {
-    stdout.write('Required flags:\n'
-        '--$gcloudProjectIdFlag gcp-id\n'
-        '--$gcloudProjectVersionFlag version\n\n'
-        'Optional flags:\n'
-        '--$ignoreVersionFlag\tForce deploy with current Flutter version\n');
-    exit(1);
-  }
-
-  if (!await _checkDependencies()) {
-    stderr.writeln('Update Flutter to a version on master from the past 3 weeks to deploy Cocoon');
-    exit(1);
-  }
-
-  await shellCommand(<String>['$cloudbuildDirectory/dashboard_build.sh']);
-
-  if (!await _deployToAppEngine()) {
-    stderr.writeln('Failed to deploy to AppEngine');
-    exit(1);
-  }
-}
diff --git a/app_dart/index.yaml b/app_dart/index.yaml
deleted file mode 100644
index b036efd..0000000
--- a/app_dart/index.yaml
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (c) 2016 The Flutter Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-indexes:
-- kind: Checklist
-  ancestor: yes
-  properties:
-  - name: CreateTimestamp
-    direction: desc
-- kind: Checklist
-  properties:
-  - name: Branch
-  - name: CreateTimestamp
-    direction: desc
-- kind: Checklist
-  properties:
-  - name: FlutterRepositoryPath
-  - name: Branch
-  - name: CreateTimestamp
-    direction: desc
-- kind: Task
-  ancestor: yes
-  properties:
-    - name: StageName
-      direction: desc
-- kind: Task
-  properties:
-  - name: Status
-  - name: CreateTimestamp
-    direction: desc
-- kind: Task
-  ancestor: yes
-  properties:
-  - name: Name
-  - name: CreateTimestamp
-    direction: desc
-- kind: Task
-  ancestor: yes
-  properties:
-  - name: CreateTimestamp
-    direction: desc
-- kind: LogChunk
-  ancestor: no
-  properties:
-  - name: OwnerKey
-  - name: CreateTimestamp
-    direction: asc
diff --git a/app_dart/integration_test/common.dart b/app_dart/integration_test/common.dart
deleted file mode 100644
index a266851..0000000
--- a/app_dart/integration_test/common.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2021 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:github/github.dart';
-import 'package:test/test.dart';
-
-/// Validates the local tree has no outstanding changes.
-void expectNoDiff(String path) {
-  final ProcessResult gitResult = Process.runSync('git', <String>['diff', '--exit-code', path]);
-  if (gitResult.exitCode != 0) {
-    final ProcessResult gitDiffOutput = Process.runSync('git', <String>['diff', path]);
-    fail('The working tree has a diff. Ensure changes are checked in:\n${gitDiffOutput.stdout}');
-  }
-}
-
-/// Wrapper class to make it easy to add new repos + branches to the validation suite.
-class SupportedConfig {
-  SupportedConfig(this.slug, [this.branch = 'master']);
-
-  final RepositorySlug slug;
-  final String branch;
-
-  @override
-  String toString() => '${slug.fullName}/$branch';
-}
diff --git a/app_dart/integration_test/data/cocoon_config.json b/app_dart/integration_test/data/cocoon_config.json
deleted file mode 100644
index 8186011..0000000
--- a/app_dart/integration_test/data/cocoon_config.json
+++ /dev/null
@@ -1 +0,0 @@
-{"targets":[{"name":"Linux Cocoon","properties":{"add_recipes_cq":"true"},"runIf":[".ci.yaml","analyze/**","app_dart/**","auto_submit/**","cipd_packages/**","cloud_build/**","dashboard/**","dev/**","licenses/**","packages/**","test_utilities/**","tooling/**"],"recipe":"cocoon/cocoon"},{"name":"Linux device_doctor","properties":{"script":"cipd_packages/device_doctor/tool/build.sh","cipd_name":"flutter/device_doctor/linux-amd64"},"runIf":["cipd_packages/device_doctor/**",".ci.yaml"],"recipe":"cocoon/cipd"},{"name":"Mac device_doctor","properties":{"script":"cipd_packages/device_doctor/tool/build.sh","cipd_name":"flutter/device_doctor/mac-amd64","device_type":"none"},"runIf":["cipd_packages/device_doctor/**",".ci.yaml"],"recipe":"cocoon/cipd"},{"name":"Mac_arm64 device_doctor","properties":{"script":"cipd_packages/device_doctor/tool/build.sh","cipd_name":"flutter/device_doctor/mac-arm64","device_type":"none"},"runIf":["cipd_packages/device_doctor/**",".ci.yaml"],"recipe":"cocoon/cipd"},{"name":"Windows device_doctor","properties":{"script":"cipd_packages\\device_doctor\\tool\\build.bat","cipd_name":"flutter/device_doctor/windows-amd64"},"runIf":["cipd_packages/device_doctor/**",".ci.yaml"],"recipe":"cocoon/cipd"},{"name":"Linux doxygen","properties":{"script":"cipd_packages/doxygen/tool/build.sh","cipd_name":"flutter/doxygen/linux-amd64","dependencies":"[\n  {\"dependency\": \"cmake\", \"version\": \"build_id:8787856497187628321\"}\n]"},"runIf":["cipd_packages/doxygen/**",".ci.yaml"],"recipe":"cocoon/cipd"},{"name":"Mac codesign","properties":{"script":"cipd_packages/codesign/tool/build.sh","cipd_name":"flutter/codesign/mac-amd64","device_type":"none"},"runIf":["cipd_packages/codesign/**",".ci.yaml"],"recipe":"cocoon/cipd"},{"name":"Mac_arm64 codesign","properties":{"script":"cipd_packages/codesign/tool/build.sh","cipd_name":"flutter/codesign/mac-arm64","device_type":"none"},"runIf":["cipd_packages/codesign/**",".ci.yaml"],"recipe":"cocoon/cipd"},{"name":"Mac ruby","timeout":60,"properties":{"script":"cipd_packages/ruby/tools/build.sh","cipd_name":"flutter/ruby/mac-amd64","device_os":"iOS","contexts":"[\n  \"osx_sdk_devicelab\"\n]","$flutter/osx_sdk":"{\n  \"sdk_version\": \"14e300c\"\n}"},"runIf":["cipd_packages/ruby/**",".ci.yaml"],"recipe":"cocoon/cipd"},{"name":"Mac_arm64 ruby","timeout":60,"properties":{"script":"cipd_packages/ruby/tools/build.sh","cipd_name":"flutter/ruby/mac-arm64","device_os":"iOS","contexts":"[\n  \"osx_sdk_devicelab\"\n]","$flutter/osx_sdk":"{\n  \"sdk_version\": \"14e300c\"\n}"},"runIf":["cipd_packages/ruby/**",".ci.yaml"],"recipe":"cocoon/cipd"},{"name":"Linux ci_yaml roller","properties":{"backfill":"false"},"runIf":[".ci.yaml"],"recipe":"infra/ci_yaml"}],"enabledBranches":["main"],"platformProperties":{"linux":{"properties":{"os":"Linux","device_type":"none"}},"mac":{"properties":{"os":"Mac-12|Mac-13","cpu":"x86"}},"mac_arm64":{"properties":{"os":"Mac-12|Mac-13","cpu":"arm64"}},"windows":{"properties":{"os":"Windows","device_type":"none"}}}}
diff --git a/app_dart/integration_test/generate_jspb_test.dart b/app_dart/integration_test/generate_jspb_test.dart
deleted file mode 100644
index 2938181..0000000
--- a/app_dart/integration_test/generate_jspb_test.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2021 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:test/test.dart';
-
-import 'common.dart';
-
-/// Validates `bin/generate_jspb.dart` which is used in the ci.yaml roller script.
-Future<void> main() async {
-  test('validate cocoon ci.yaml generates jspb', () async {
-    final ProcessResult generateResult =
-        Process.runSync('dart', <String>['run', 'bin/generate_jspb.dart', '../.ci.yaml']);
-    if (generateResult.exitCode != 0) {
-      fail('generate_jspb.dart failed with exit code ${generateResult.exitCode}\n'
-          'stderr: ${generateResult.stderr}\n'
-          'stdout: ${generateResult.stdout}');
-    }
-
-    // Update expectations file
-    final File jspbExpectationsFile = File('integration_test/data/cocoon_config.json');
-    jspbExpectationsFile.writeAsStringSync(generateResult.stdout as String);
-
-    expectNoDiff(jspbExpectationsFile.path);
-  });
-}
diff --git a/app_dart/integration_test/validate_all_ci_configs_test.dart b/app_dart/integration_test/validate_all_ci_configs_test.dart
deleted file mode 100644
index 2032f56..0000000
--- a/app_dart/integration_test/validate_all_ci_configs_test.dart
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2021 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:core';
-import 'dart:io';
-
-import 'package:cocoon_service/cocoon_service.dart';
-import 'package:cocoon_service/src/model/ci_yaml/ci_yaml.dart';
-import 'package:cocoon_service/src/model/proto/internal/scheduler.pbserver.dart' as pb;
-import 'package:github/github.dart';
-import 'package:http/http.dart' as http;
-import 'package:process/process.dart';
-import 'package:test/test.dart';
-import 'package:yaml/yaml.dart';
-
-import 'common.dart';
-
-/// List of repositories that have supported .ci.yaml config files.
-final List<SupportedConfig> configs = <SupportedConfig>[
-  SupportedConfig(RepositorySlug('flutter', 'cocoon'), 'main'),
-  SupportedConfig(RepositorySlug('flutter', 'engine'), 'main'),
-  SupportedConfig(RepositorySlug('flutter', 'flutter')),
-  SupportedConfig(RepositorySlug('flutter', 'packages'), 'main'),
-];
-
-Future<void> main() async {
-  for (final SupportedConfig config in configs) {
-    test('validate config file of $config', () async {
-      final String configContent = await githubFileContent(
-        config.slug,
-        kCiYamlPath,
-        httpClientProvider: () => http.Client(),
-        ref: config.branch,
-      );
-      final YamlMap configYaml = loadYaml(configContent) as YamlMap;
-      final pb.SchedulerConfig currentSchedulerConfig = pb.SchedulerConfig()..mergeFromProto3Json(configYaml);
-      try {
-        CiYaml(
-          slug: config.slug,
-          branch: Config.defaultBranch(config.slug),
-          config: currentSchedulerConfig,
-        );
-      } on FormatException catch (e) {
-        fail(e.message);
-      }
-    });
-
-    test(
-      'validate enabled branches of $config',
-      () async {
-        final String configContent = await githubFileContent(
-          config.slug,
-          kCiYamlPath,
-          httpClientProvider: () => http.Client(),
-          ref: config.branch,
-        );
-        final YamlMap configYaml = loadYaml(configContent) as YamlMap;
-        final pb.SchedulerConfig schedulerConfig = pb.SchedulerConfig()..mergeFromProto3Json(configYaml);
-
-        final List<String> githubBranches = getBranchesForRepository(config.slug);
-
-        final Map<String, bool> validEnabledBranches = <String, bool>{};
-        // Add config wide enabled branches
-        for (String enabledBranch in schedulerConfig.enabledBranches) {
-          validEnabledBranches[enabledBranch] = false;
-        }
-        // Add all target specific enabled branches
-        for (pb.Target target in schedulerConfig.targets) {
-          for (String enabledBranch in target.enabledBranches) {
-            validEnabledBranches[enabledBranch] = false;
-          }
-        }
-
-        // N^2 scan to verify all enabled branch patterns match an exist branch on the repo.
-        for (String enabledBranch in validEnabledBranches.keys) {
-          for (String githubBranch in githubBranches) {
-            if (CiYaml.enabledBranchesMatchesCurrentBranch(<String>[enabledBranch], githubBranch)) {
-              validEnabledBranches[enabledBranch] = true;
-            }
-          }
-        }
-
-        if (config.slug.name == 'engine') {
-          print(githubBranches);
-          print(validEnabledBranches);
-        }
-
-        // Verify the enabled branches
-        for (String enabledBranch in validEnabledBranches.keys) {
-          expect(
-            validEnabledBranches[enabledBranch],
-            isTrue,
-            reason: '$enabledBranch does not match to a branch in ${config.slug.fullName}',
-          );
-        }
-      },
-      skip: config.slug.name == 'flutter',
-    );
-  }
-}
-
-/// Gets all branches for [slug].
-///
-/// Internally, uses the git on path to get the branches from the remote for [slug].
-List<String> getBranchesForRepository(RepositorySlug slug) {
-  const ProcessManager processManager = LocalProcessManager();
-  final ProcessResult result =
-      processManager.runSync(<String>['git', 'ls-remote', '--head', 'https://github.com/${slug.fullName}']);
-  final List<String> lines = (result.stdout as String).split('\n');
-
-  final List<String> githubBranches = <String>[];
-  for (String line in lines) {
-    if (line.isEmpty) {
-      continue;
-    }
-    // Lines follow the format of `$sha\t$ref`
-    final String ref = line.split('\t')[1];
-    final String branch = ref.replaceAll('refs/heads/', '');
-    githubBranches.add(branch);
-  }
-
-  return githubBranches;
-}
diff --git a/app_dart/integration_test/validate_test_ownership_test.dart b/app_dart/integration_test/validate_test_ownership_test.dart
deleted file mode 100644
index 6710c62..0000000
--- a/app_dart/integration_test/validate_test_ownership_test.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2021 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:github/github.dart';
-import 'package:process/process.dart';
-import 'package:test/test.dart';
-
-import 'common.dart';
-
-/// List of supported repositories with TESTOWNERS.
-final List<SupportedConfig> configs = <SupportedConfig>[
-  SupportedConfig(RepositorySlug('flutter', 'flutter')),
-];
-
-Future<void> main() async {
-  for (final SupportedConfig config in configs) {
-    test('validate test ownership for $config', () async {
-      const String dart = 'dart';
-      const String taskExecutable = 'bin/validate_task_ownership.dart';
-      final List<String> taskArgs = <String>[config.slug.name, config.branch];
-
-      const ProcessManager processManager = LocalProcessManager();
-      final Process process = await processManager.start(
-        <String>[dart, taskExecutable, ...taskArgs],
-        workingDirectory: Directory.current.path,
-      );
-
-      final List<String> output = <String>[];
-      final List<String> error = <String>[];
-
-      process.stdout
-          .transform<String>(const Utf8Decoder())
-          .transform<String>(const LineSplitter())
-          .listen((String line) {
-        stdout.writeln('[STDOUT] $line');
-        output.add(line);
-      });
-
-      process.stderr
-          .transform<String>(const Utf8Decoder())
-          .transform<String>(const LineSplitter())
-          .listen((String line) {
-        stderr.writeln('[STDERR] $line');
-        error.add(line);
-      });
-
-      final int exitCode = await process.exitCode;
-      if (exitCode != 0) {
-        for (String line in error) {
-          print(line);
-        }
-        fail('An error has occurred.');
-      }
-    });
-  }
-}
diff --git a/app_dart/lib/ci_yaml.dart b/app_dart/lib/ci_yaml.dart
deleted file mode 100644
index 756415a..0000000
--- a/app_dart/lib/ci_yaml.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export 'src/model/ci_yaml/ci_yaml.dart';
-export 'src/model/ci_yaml/target.dart';
diff --git a/app_dart/lib/cocoon_service.dart b/app_dart/lib/cocoon_service.dart
deleted file mode 100644
index d0137b3..0000000
--- a/app_dart/lib/cocoon_service.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export 'src/foundation/utils.dart';
-export 'src/model/appengine/service_account_info.dart';
-export 'src/request_handlers/check_flaky_builders.dart';
-export 'src/request_handlers/create_branch.dart';
-export 'src/request_handlers/dart_internal_subscription.dart';
-export 'src/request_handlers/file_flaky_issue_and_pr.dart';
-export 'src/request_handlers/flush_cache.dart';
-export 'src/request_handlers/get_build_status.dart';
-export 'src/request_handlers/get_release_branches.dart';
-export 'src/request_handlers/get_repos.dart';
-export 'src/request_handlers/get_status.dart';
-export 'src/request_handlers/get_green_commits.dart';
-export 'src/request_handlers/github_rate_limit_status.dart';
-export 'src/request_handlers/github_webhook.dart';
-export 'src/request_handlers/github/webhook_subscription.dart';
-export 'src/request_handlers/postsubmit_luci_subscription.dart';
-export 'src/request_handlers/presubmit_luci_subscription.dart';
-export 'src/request_handlers/push_build_status_to_github.dart';
-export 'src/request_handlers/push_gold_status_to_github.dart';
-export 'src/request_handlers/readiness_check.dart';
-export 'src/request_handlers/reset_prod_task.dart';
-export 'src/request_handlers/reset_try_task.dart';
-export 'src/request_handlers/scheduler/batch_backfiller.dart';
-export 'src/request_handlers/scheduler/request_subscription.dart';
-export 'src/request_handlers/scheduler/vacuum_stale_tasks.dart';
-export 'src/request_handlers/update_existing_flaky_issues.dart';
-export 'src/request_handlers/update_task_status.dart';
-export 'src/request_handlers/vacuum_github_commits.dart';
-export 'src/request_handling/authentication.dart';
-export 'src/request_handling/body.dart';
-export 'src/request_handling/cache_request_handler.dart';
-export 'src/request_handling/pubsub.dart';
-export 'src/request_handling/pubsub_authentication.dart';
-export 'src/request_handling/request_handler.dart';
-export 'src/request_handling/static_file_handler.dart';
-export 'src/request_handling/swarming_authentication.dart';
-export 'src/service/access_token_provider.dart';
-export 'src/service/buildbucket.dart';
-export 'src/service/branch_service.dart';
-export 'src/service/cache_service.dart';
-export 'src/service/config.dart';
-export 'src/service/gerrit_service.dart';
-export 'src/service/github_checks_service.dart';
-export 'src/service/luci_build_service.dart';
-export 'src/service/scheduler.dart';
diff --git a/app_dart/lib/protos.dart b/app_dart/lib/protos.dart
deleted file mode 100644
index 5288e7f..0000000
--- a/app_dart/lib/protos.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export 'src/model/proto/protos.dart';
diff --git a/app_dart/lib/src/foundation/github_checks_util.dart b/app_dart/lib/src/foundation/github_checks_util.dart
deleted file mode 100644
index 7880c35..0000000
--- a/app_dart/lib/src/foundation/github_checks_util.dart
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2020 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:core';
-import 'dart:io';
-
-import 'package:github/github.dart' as github;
-import 'package:github/hooks.dart';
-import 'package:retry/retry.dart';
-
-import '../service/config.dart';
-import '../service/logging.dart';
-
-/// Wrapper class for github checkrun service. This is used to simplify
-/// mocking during testing because some of the subclasses are private.
-class GithubChecksUtil {
-  const GithubChecksUtil();
-  Future<Map<String, github.CheckRun>> allCheckRuns(
-    github.GitHub gitHubClient,
-    CheckSuiteEvent checkSuiteEvent,
-  ) async {
-    final List<github.CheckRun> allCheckRuns = await gitHubClient.checks.checkRuns
-        .listCheckRunsInSuite(
-          checkSuiteEvent.repository!.slug(),
-          checkSuiteId: checkSuiteEvent.checkSuite!.id!,
-        )
-        .toList();
-    return {for (github.CheckRun check in allCheckRuns) check.name as String: check};
-  }
-
-  Future<github.CheckSuite> getCheckSuite(
-    github.GitHub gitHubClient,
-    github.RepositorySlug slug,
-    int checkSuiteId,
-  ) async {
-    return gitHubClient.checks.checkSuites.getCheckSuite(
-      slug,
-      checkSuiteId: checkSuiteId,
-    );
-  }
-
-  /// Finds all check suites that are associated with a given git [ref].
-  Future<List<github.CheckSuite>> listCheckSuitesForRef(
-    github.GitHub gitHubClient,
-    github.RepositorySlug slug, {
-    required String ref,
-    int? appId,
-    String? checkName,
-  }) async {
-    const RetryOptions r = RetryOptions(
-      maxAttempts: 3,
-      delayFactor: Duration(seconds: 2),
-    );
-    return r.retry(
-      () async {
-        return gitHubClient.checks.checkSuites
-            .listCheckSuitesForRef(
-              slug,
-              ref: ref,
-              appId: appId,
-              checkName: checkName,
-            )
-            .toList();
-      },
-      retryIf: (Exception e) => e is github.GitHubError || e is SocketException,
-    );
-  }
-
-  /// Sends a request to github checks api to update a [CheckRun] with a given
-  /// [status] and [conclusion].
-  Future<void> updateCheckRun(
-    Config config,
-    github.RepositorySlug slug,
-    github.CheckRun checkRun, {
-    github.CheckRunStatus status = github.CheckRunStatus.queued,
-    github.CheckRunConclusion? conclusion,
-    String? detailsUrl,
-    github.CheckRunOutput? output,
-  }) async {
-    const RetryOptions r = RetryOptions(
-      maxAttempts: 3,
-      delayFactor: Duration(seconds: 2),
-    );
-    return r.retry(
-      () async {
-        final github.GitHub gitHubClient = await config.createGitHubClient(slug: slug);
-        await gitHubClient.checks.checkRuns.updateCheckRun(
-          slug,
-          checkRun,
-          status: status,
-          conclusion: conclusion,
-          detailsUrl: detailsUrl,
-          output: output,
-        );
-      },
-      retryIf: (Exception e) => e is github.GitHubError || e is SocketException,
-    );
-  }
-
-  Future<github.CheckRun> getCheckRun(
-    Config config,
-    github.RepositorySlug slug,
-    int? id,
-  ) async {
-    const RetryOptions r = RetryOptions(
-      maxAttempts: 3,
-      delayFactor: Duration(seconds: 2),
-    );
-    return r.retry(
-      () async {
-        final github.GitHub gitHubClient = await config.createGitHubClient(slug: slug);
-        return gitHubClient.checks.checkRuns.getCheckRun(
-          slug,
-          checkRunId: id!,
-        );
-      },
-      retryIf: (Exception e) => e is github.GitHubError || e is SocketException,
-    );
-  }
-
-  /// Sends a request to GitHub's Checks API to create a new [github.CheckRun].
-  ///
-  /// The newly created checkrun will be associated in [slug] to [sha] as [name].
-  ///
-  /// Optionally, will have [output] to give information to users.
-  Future<github.CheckRun> createCheckRun(
-    Config config,
-    github.RepositorySlug slug,
-    String sha,
-    String name, {
-    github.CheckRunOutput? output,
-  }) async {
-    const RetryOptions r = RetryOptions(
-      maxAttempts: 3,
-      delayFactor: Duration(seconds: 2),
-    );
-    return r.retry(
-      () async {
-        return _createCheckRun(
-          config,
-          slug,
-          sha,
-          name,
-          output: output,
-        );
-      },
-      retryIf: (Exception e) => true,
-      onRetry: (Exception e) => log.warning(
-        'createCheckRun fails for slug: ${slug.fullName}, sha: $sha, name: $name. Exception: ${e.toString()}',
-      ),
-    );
-  }
-
-  Future<github.CheckRun> _createCheckRun(
-    Config config,
-    github.RepositorySlug slug,
-    String sha,
-    String name, {
-    github.CheckRunOutput? output,
-  }) async {
-    final github.GitHub gitHubClient = await config.createGitHubClient(slug: slug);
-    return gitHubClient.checks.checkRuns.createCheckRun(
-      slug,
-      name: name,
-      headSha: sha,
-      output: output,
-    );
-  }
-}
diff --git a/app_dart/lib/src/foundation/providers.dart b/app_dart/lib/src/foundation/providers.dart
deleted file mode 100644
index 3c28318..0000000
--- a/app_dart/lib/src/foundation/providers.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:appengine/appengine.dart' as gae;
-import 'package:http/http.dart' as http;
-
-import 'typedefs.dart';
-
-/// Class that holds static default providers.
-class Providers {
-  const Providers._();
-
-  /// Default [http.Client] provider.
-  ///
-  /// See also:
-  ///
-  ///  * [HttpClientProvider], which defines this interface.
-  static http.Client freshHttpClient() => http.Client();
-
-  /// Default [gae.Logging] provider.
-  ///
-  /// See also:
-  ///
-  ///  * [LoggingProvider], which defines this interface.
-  static gae.Logging serviceScopeLogger() => gae.loggingService;
-
-  /// Default [gae.ClientContext] provider.
-  ///
-  /// See also:
-  ///
-  ///  * [ClientContextProvider], which defines this interface.
-  static gae.ClientContext serviceScopeContext() => gae.context;
-}
diff --git a/app_dart/lib/src/foundation/typedefs.dart b/app_dart/lib/src/foundation/typedefs.dart
deleted file mode 100644
index fe0ddc5..0000000
--- a/app_dart/lib/src/foundation/typedefs.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:appengine/appengine.dart';
-import 'package:http/http.dart' as http;
-
-/// Signature for a function that returns an App Engine [ClientContext].
-///
-/// This is used in [AuthenticationProvider] to provide the client context
-/// as part of the [AuthenticatedContext].
-typedef ClientContextProvider = ClientContext Function();
-
-/// Signature for a function that returns an [HttpClient].
-///
-/// This is used by [AuthenticationProvider] to provide the HTTP client that
-/// will be used (if necessary) to verify OAuth ID tokens (JWT tokens).
-typedef HttpClientProvider = http.Client Function();
diff --git a/app_dart/lib/src/foundation/utils.dart b/app_dart/lib/src/foundation/utils.dart
deleted file mode 100644
index 346ccd7..0000000
--- a/app_dart/lib/src/foundation/utils.dart
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2020 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:cocoon_service/cocoon_service.dart';
-import 'package:github/github.dart';
-import 'package:googleapis/bigquery/v2.dart';
-import 'package:http/http.dart' as http;
-import 'package:retry/retry.dart';
-import 'package:yaml/yaml.dart';
-
-import '../../protos.dart' as pb;
-import '../foundation/typedefs.dart';
-import '../model/ci_yaml/ci_yaml.dart';
-import '../model/ci_yaml/target.dart';
-import '../request_handlers/flaky_handler_utils.dart';
-import '../request_handling/exceptions.dart';
-import '../service/logging.dart';
-
-const String kCiYamlPath = '.ci.yaml';
-const String kTestOwnerPath = 'TESTOWNERS';
-
-/// Signature for a function that calculates the backoff duration to wait in
-/// between requests when GitHub responds with an error.
-///
-/// The [attempt] argument is zero-based, so if the first attempt to request
-/// from GitHub fails, and we're backing off before making the second attempt,
-/// the [attempt] argument will be zero.
-typedef GitHubBackoffCalculator = Duration Function(int attempt);
-
-/// Default backoff calculator.
-Duration twoSecondLinearBackoff(int attempt) {
-  return const Duration(seconds: 2) * (attempt + 1);
-}
-
-/// Get content of [filePath] from GitHub CDN.
-Future<String> githubFileContent(
-  RepositorySlug slug,
-  String filePath, {
-  required HttpClientProvider httpClientProvider,
-  String ref = 'master',
-  Duration timeout = const Duration(seconds: 5),
-  RetryOptions retryOptions = const RetryOptions(
-    maxAttempts: 3,
-    delayFactor: Duration(seconds: 3),
-  ),
-}) async {
-  final Uri githubUrl = Uri.https('raw.githubusercontent.com', '${slug.fullName}/$ref/$filePath');
-  // git-on-borg has a different path for shas and refs to github
-  final String gobRef = (ref.length < 40) ? 'refs/heads/$ref' : ref;
-  final Uri gobUrl = Uri.https(
-    'flutter.googlesource.com',
-    'mirrors/${slug.name}/+/$gobRef/$filePath',
-    <String, String>{
-      'format': 'text',
-    },
-  );
-  late String content;
-  try {
-    await retryOptions.retry(
-      () async => content = await getUrl(githubUrl, httpClientProvider, timeout: timeout),
-      retryIf: (Exception e) => e is HttpException || e is NotFoundException,
-    );
-  } catch (e) {
-    await retryOptions.retry(
-      () async =>
-          content = String.fromCharCodes(base64Decode(await getUrl(gobUrl, httpClientProvider, timeout: timeout))),
-      retryIf: (Exception e) => e is HttpException,
-    );
-  }
-  return content;
-}
-
-/// Return [String] of response from [url] if status is [HttpStatus.ok].
-///
-/// If [url] returns [HttpStatus.notFound] throw [NotFoundException].
-/// Otherwise, throws [HttpException].
-FutureOr<String> getUrl(
-  Uri url,
-  HttpClientProvider httpClientProvider, {
-  Duration timeout = const Duration(seconds: 5),
-}) async {
-  log.info('Making HTTP GET request for $url');
-  final http.Client client = httpClientProvider();
-  try {
-    final http.Response response = await client.get(url).timeout(timeout);
-
-    if (response.statusCode == HttpStatus.ok) {
-      return response.body;
-    } else if (response.statusCode == HttpStatus.notFound) {
-      throw NotFoundException('HTTP ${response.statusCode}: $url');
-    } else {
-      log.warning('HTTP ${response.statusCode}: $url');
-      throw HttpException('HTTP ${response.statusCode}: $url');
-    }
-  } finally {
-    client.close();
-  }
-}
-
-/// Expands globs string to a regex for evaluation.
-Future<RegExp> parseGlob(String glob) async {
-  glob = glob.replaceAll('**', '[A-Za-z0-9_/.]+');
-  glob = glob.replaceAll('*', '[A-Za-z0-9_.]+');
-  return RegExp('^$glob\$');
-}
-
-/// Returns a LUCI [builder] list that covers changed [files].
-///
-/// [builders]: enabled luci builders.
-/// [files]: changed files in corresponding PRs.
-///
-/// [builder] format with run_if:
-/// {
-///   "name":"yyy",
-///   "repo":"flutter",
-///   "taskName":"zzz",
-///   "enabled":true,
-///   "run_if":["a/b/", "c/d_e/**", "f", "g*h/"]
-/// }
-/// [builder] format with run_if_not:
-/// {
-///   "name":"yyy",
-///   "repo":"flutter",
-///   "taskName":"zzz",
-///   "enabled":true,
-///   "run_if_not":["a/b/", "c/d_e/**", "f", "g*h/"]
-/// }
-/// Note: if both [run_if] and [run_if_not] are provided and not empty only
-/// [run_if] is evaluated.
-///
-/// [file] is based on repo root: `a/b/c.dart`.
-Future<List<Target>> getTargetsToRun(Iterable<Target> targets, List<String?> files) async {
-  log.info('Getting targets to run from diff.');
-  final List<Target> targetsToRun = <Target>[];
-  for (Target target in targets) {
-    final List<String> globs = target.value.runIf;
-    // Handle case where [Target] initializes empty runif
-    if (globs.isEmpty) {
-      // Evaluate run_if_not.
-      final List<String> negativeGlobs = target.value.runIfNot;
-      if (negativeGlobs.isEmpty) {
-        targetsToRun.add(target);
-        continue;
-      }
-      bool shouldAdd = true;
-      for (String glob in negativeGlobs) {
-        final RegExp regExp = await parseGlob(glob);
-        // if the file is not in any of the paths then add the target.
-        if (files.any((String? file) => regExp.hasMatch(file!))) {
-          shouldAdd = false;
-          break;
-        }
-      }
-      if (shouldAdd) {
-        targetsToRun.add(target);
-      }
-    } else {
-      for (String glob in globs) {
-        // If a file is found within a pre-set dir, the builder needs to run. No need to check further.
-        final RegExp regExp = await parseGlob(glob);
-        if (glob.isEmpty || files.any((String? file) => regExp.hasMatch(file!))) {
-          targetsToRun.add(target);
-          break;
-        }
-      }
-    }
-  }
-
-  log.info('Collected the following targets to run:');
-  for (var target in targetsToRun) {
-    log.info(target.value.name);
-  }
-
-  return targetsToRun;
-}
-
-Future<void> insertBigquery(String tableName, Map<String, dynamic> data, TabledataResource tabledataResourceApi) async {
-  // Define const variables for [BigQuery] operations.
-  const String projectId = 'flutter-dashboard';
-  const String dataset = 'cocoon';
-  final String table = tableName;
-  final List<Map<String, Object>> requestRows = <Map<String, Object>>[];
-
-  requestRows.add(<String, Object>{
-    'json': data,
-  });
-
-  // Obtain [rows] to be inserted to [BigQuery].
-  final TableDataInsertAllRequest request = TableDataInsertAllRequest.fromJson(<String, dynamic>{'rows': requestRows});
-
-  try {
-    await tabledataResourceApi.insertAll(request, projectId, dataset, table);
-  } on ApiRequestError catch (error) {
-    log.warning('Failed to add to BigQuery: $error');
-  }
-}
-
-/// Validate test ownership defined in [testOwnersContent] for tests configured in `ciYamlContent`.
-List<String> validateOwnership(String ciYamlContent, String testOwnersContent, {bool unfilteredTargets = false}) {
-  final List<String> noOwnerBuilders = <String>[];
-  final YamlMap? ciYaml = loadYaml(ciYamlContent) as YamlMap?;
-  final pb.SchedulerConfig unCheckedSchedulerConfig = pb.SchedulerConfig()..mergeFromProto3Json(ciYaml);
-
-  final CiYaml ciYamlFromProto = CiYaml(
-    slug: Config.flutterSlug,
-    branch: Config.defaultBranch(Config.flutterSlug),
-    config: unCheckedSchedulerConfig,
-  );
-
-  final pb.SchedulerConfig schedulerConfig = ciYamlFromProto.config;
-
-  for (pb.Target target in schedulerConfig.targets) {
-    final String builder = target.name;
-    final BuilderType builderType = getTypeForBuilder(
-      builder,
-      ciYamlFromProto,
-      unfilteredTargets: unfilteredTargets,
-    );
-
-    final String? owner = getTestOwnership(
-      target,
-      builderType,
-      testOwnersContent,
-    ).owner;
-    print('$builder: $owner');
-    if (owner == null) {
-      noOwnerBuilders.add(builder);
-    }
-  }
-  return noOwnerBuilders;
-}
-
-/// Utility to class to wrap related objects in.
-class Tuple<S, T, U> {
-  const Tuple(this.first, this.second, this.third);
-
-  final S first;
-  final T second;
-  final U third;
-}
diff --git a/app_dart/lib/src/model/appengine/allowed_account.dart b/app_dart/lib/src/model/appengine/allowed_account.dart
deleted file mode 100644
index 120f129..0000000
--- a/app_dart/lib/src/model/appengine/allowed_account.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:gcloud/db.dart';
-
-/// Class that represents a non-Google account that has been allowlisted to
-/// make API requests to the Flutter dashboard.
-///
-/// By default, only App Engine cronjobs, and users
-/// authenticated as "@google.com" accounts are allowed to make API requests
-/// to the Cocooon backend. This class represents instances where non-Google
-/// users have been explicitly allowlisted to make such requests.
-@Kind(name: 'AllowedAccount')
-class AllowedAccount extends Model<int> {
-  /// Creates a new [AllowedAccount].
-  AllowedAccount({
-    Key<int>? key,
-    required this.email,
-  }) {
-    parentKey = key?.parent;
-    id = key?.id;
-  }
-
-  /// The email address of the account that has been allowlisted.
-  @StringProperty(propertyName: 'Email', required: true)
-  String email;
-
-  @override
-  String toString() {
-    final StringBuffer buf = StringBuffer()
-      ..write('$runtimeType(')
-      ..write('id: $id')
-      ..write(', parentKey: ${parentKey?.id}')
-      ..write(', key: ${parentKey == null ? null : key.id}')
-      ..write(', email: $email')
-      ..write(')');
-    return buf.toString();
-  }
-}
diff --git a/app_dart/lib/src/model/appengine/branch.dart b/app_dart/lib/src/model/appengine/branch.dart
deleted file mode 100644
index 04d2786..0000000
--- a/app_dart/lib/src/model/appengine/branch.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2021 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:gcloud/db.dart';
-import 'package:github/github.dart';
-
-@Kind(name: 'Branch', idType: IdType.String)
-class Branch extends Model<String> {
-  Branch({Key<String>? key, this.lastActivity, this.channel}) {
-    parentKey = key?.parent;
-    id = key?.id;
-  }
-
-  /// The timestamp (in milliseconds since the Epoch) of the last time
-  /// when current branch had activity.
-  @IntProperty(propertyName: 'lastActivity', required: false)
-  int? lastActivity;
-
-  /// The channel of current branch
-  @StringProperty(propertyName: 'channel', required: false)
-  String? channel;
-
-  /// [RepositorySlug] of where this commit exists.
-  RepositorySlug get slug => RepositorySlug.full(repository);
-
-  String get repository => key.id!.substring(0, key.id!.lastIndexOf('/'));
-
-  String get name => key.id!.substring(key.id!.lastIndexOf('/') + 1);
-
-  @override
-  String toString() {
-    final StringBuffer buf = StringBuffer()
-      ..write('$runtimeType(')
-      ..write('id: $id')
-      ..write(', key: ${parentKey == null ? null : key.id}')
-      ..write(', branch: $name')
-      ..write(', channel: $channel')
-      ..write(', repository: $repository')
-      ..write(', lastActivity: $lastActivity')
-      ..write(')');
-    return buf.toString();
-  }
-
-  Map<String, dynamic> toJson() {
-    return <String, dynamic>{
-      'id': id,
-      'branch': <String, dynamic>{
-        'branch': name,
-        'repository': repository,
-      },
-    };
-  }
-}
diff --git a/app_dart/lib/src/model/appengine/cocoon_config.dart b/app_dart/lib/src/model/appengine/cocoon_config.dart
deleted file mode 100644
index 25705c1..0000000
--- a/app_dart/lib/src/model/appengine/cocoon_config.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:gcloud/db.dart';
-
-@Kind(name: 'CocoonConfig', idType: IdType.String)
-class CocoonConfig extends Model<String> {
-  @StringProperty(propertyName: 'ParameterValue')
-  late String value;
-}
diff --git a/app_dart/lib/src/model/appengine/commit.dart b/app_dart/lib/src/model/appengine/commit.dart
deleted file mode 100644
index 592934e..0000000
--- a/app_dart/lib/src/model/appengine/commit.dart
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:gcloud/db.dart';
-import 'package:github/github.dart';
-import 'package:json_annotation/json_annotation.dart';
-
-import '../../service/datastore.dart';
-import '../../service/logging.dart';
-import 'key_converter.dart';
-
-part 'commit.g.dart';
-
-/// Class that represents a commit that has landed on the master branch of a
-/// Flutter repository.
-@Kind(name: 'Checklist', idType: IdType.String)
-class Commit extends Model<String> {
-  Commit({
-    Key<String>? key,
-    this.sha,
-    this.timestamp,
-    this.author,
-    this.authorAvatarUrl,
-    this.message,
-    this.repository,
-    this.branch = 'master',
-  }) {
-    parentKey = key?.parent;
-    id = key?.id;
-  }
-
-  /// Create a [Key] that can be used to lookup a [Commit] from Datastore.
-  static Key<String> createKey({
-    required DatastoreDB db,
-    required RepositorySlug slug,
-    required String gitBranch,
-    required String sha,
-  }) {
-    return db.emptyKey.append(
-      Commit,
-      id: '${slug.fullName}/$gitBranch/$sha',
-    );
-  }
-
-  /// Lookup [Commit] from Datastore.
-  static Future<Commit> fromDatastore({
-    required DatastoreService datastore,
-    required Key<String> key,
-  }) async {
-    log.fine('Looking up commit by key with id: ${key.id}');
-    return datastore.lookupByValue<Commit>(key);
-  }
-
-  /// The timestamp (in milliseconds since the Epoch) of when the commit
-  /// landed.
-  @IntProperty(propertyName: 'CreateTimestamp', required: true)
-  int? timestamp;
-
-  /// The SHA1 hash of the commit.
-  @StringProperty(propertyName: 'Commit.Sha', required: true)
-  String? sha;
-
-  /// The GitHub username of the commit author.
-  @StringProperty(propertyName: 'Commit.Author.Login')
-  String? author;
-
-  /// URL of the [author]'s profile image / avatar.
-  ///
-  /// The bytes loaded from the URL are expected to be encoded image bytes.
-  @StringProperty(propertyName: 'Commit.Author.AvatarURL')
-  String? authorAvatarUrl;
-
-  /// The commit message.
-  ///
-  /// This may be null, since we didn't always load/store this property in
-  /// the datastore, so historical entries won't have this information.
-  @StringProperty(propertyName: 'Commit.Message', required: false)
-  String? message;
-
-  /// A serializable form of [slug].
-  ///
-  /// This will be of the form `<org>/<repo>`. e.g. `flutter/flutter`.
-  @StringProperty(propertyName: 'FlutterRepositoryPath', required: true)
-  String? repository;
-
-  /// The branch of the commit.
-  @StringProperty(propertyName: 'Branch')
-  String? branch;
-
-  /// [RepositorySlug] of where this commit exists.
-  RepositorySlug get slug => RepositorySlug.full(repository!);
-
-  @override
-  String toString() {
-    final StringBuffer buf = StringBuffer()
-      ..write('$runtimeType(')
-      ..write('id: $id')
-      ..write(', parentKey: ${parentKey?.id}')
-      ..write(', key: ${parentKey == null ? null : key.id}')
-      ..write(', timestamp: $timestamp')
-      ..write(', sha: $sha')
-      ..write(', author: $author')
-      ..write(', authorAvatarUrl: $authorAvatarUrl')
-      ..write(', message: ${message?.split("\n").first}')
-      ..write(', repository: $repository')
-      ..write(', branch: $branch')
-      ..write(')');
-    return buf.toString();
-  }
-}
-
-/// The serialized representation of a [Commit].
-// TODO(tvolkert): Directly serialize [Commit] once frontends migrate to new serialization format.
-@JsonSerializable(createFactory: false, ignoreUnannotated: true)
-class SerializableCommit {
-  const SerializableCommit(this.commit);
-
-  final Commit commit;
-
-  @JsonKey(name: 'Key')
-  @StringKeyConverter()
-  Key<String>? get key => commit.key;
-
-  @JsonKey(name: 'Checklist')
-  Map<String, dynamic> get facade {
-    return <String, dynamic>{
-      'FlutterRepositoryPath': commit.repository,
-      'CreateTimestamp': commit.timestamp,
-      'Commit': <String, dynamic>{
-        'Sha': commit.sha,
-        'Message': commit.message,
-        'Author': <String, dynamic>{
-          'Login': commit.author,
-          'avatar_url': commit.authorAvatarUrl,
-        },
-      },
-      'Branch': commit.branch,
-    };
-  }
-
-  /// Serializes this object to a JSON primitive.
-  Map<String, dynamic> toJson() => _$SerializableCommitToJson(this);
-}
diff --git a/app_dart/lib/src/model/appengine/commit.g.dart b/app_dart/lib/src/model/appengine/commit.g.dart
deleted file mode 100644
index 84969e7..0000000
--- a/app_dart/lib/src/model/appengine/commit.g.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-// ignore_for_file: always_specify_types, implicit_dynamic_parameter
-
-part of 'commit.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-Map<String, dynamic> _$SerializableCommitToJson(SerializableCommit instance) => <String, dynamic>{
-      'Key': const StringKeyConverter().toJson(instance.key),
-      'Checklist': instance.facade,
-    };
diff --git a/app_dart/lib/src/model/appengine/github_build_status_update.dart b/app_dart/lib/src/model/appengine/github_build_status_update.dart
deleted file mode 100644
index 63ff03c..0000000
--- a/app_dart/lib/src/model/appengine/github_build_status_update.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:gcloud/db.dart';
-
-/// Class that represents an update having been posted to a GitHub PR on the
-/// status of the Flutter build.
-@Kind(name: 'GithubBuildStatusUpdate')
-class GithubBuildStatusUpdate extends Model<int> {
-  GithubBuildStatusUpdate({
-    Key<int>? key,
-    this.repository,
-    this.pr,
-    this.head,
-    this.status,
-    this.updates,
-    this.updateTimeMillis,
-  }) {
-    parentKey = key?.parent;
-    id = key?.id;
-  }
-
-  static const String statusSuccess = 'success';
-
-  static const String statusFailure = 'failure';
-
-  @StringProperty(propertyName: 'Repository', required: true)
-  String? repository;
-
-  @IntProperty(propertyName: 'PR', required: true)
-  int? pr;
-
-  @StringProperty(propertyName: 'Head')
-  String? head;
-
-  @StringProperty(propertyName: 'Status', required: true)
-  String? status;
-
-  @IntProperty(propertyName: 'Updates', required: true)
-  int? updates;
-
-  /// The last time when the status is updated for the PR.
-  @IntProperty(propertyName: 'UpdateTimeMillis')
-  int? updateTimeMillis;
-
-  @override
-  String toString() {
-    final StringBuffer buf = StringBuffer()
-      ..write('$runtimeType(')
-      ..write('id: $id')
-      ..write(', parentKey: ${parentKey?.id}')
-      ..write(', key: ${parentKey == null ? null : key.id}')
-      ..write(', repository: $repository')
-      ..write(', pr: $pr')
-      ..write(', head: $head')
-      ..write(', lastStatus: $status')
-      ..write(', updates: $updates')
-      ..write(', updateTimeMillis: $updateTimeMillis')
-      ..write(')');
-    return buf.toString();
-  }
-}
diff --git a/app_dart/lib/src/model/appengine/github_gold_status_update.dart b/app_dart/lib/src/model/appengine/github_gold_status_update.dart
deleted file mode 100644
index 603407a..0000000
--- a/app_dart/lib/src/model/appengine/github_gold_status_update.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2020 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:gcloud/db.dart';
-
-/// Class that represents an update having been posted to a GitHub
-/// flutter/flutter PR on the status of tryjobs generated on Flutter Gold.
-@Kind(name: 'GithubGoldStatusUpdate')
-class GithubGoldStatusUpdate extends Model<int> {
-  GithubGoldStatusUpdate({
-    Key<int>? key,
-    this.pr,
-    this.head,
-    this.status,
-    this.description,
-    this.updates,
-    this.repository,
-  }) {
-    parentKey = key?.parent;
-    id = key?.id;
-  }
-
-  // The flutter-gold status cannot report a `failure` status
-  // due to auto-rollers. This is why we hold a `pending` status
-  // when there are image changes. This provides the opportunity
-  // for images to be triaged, and the auto-roller to proceed.
-  // For more context, see: https://github.com/flutter/flutter/issues/48744
-
-  static const String statusCompleted = 'success';
-
-  static const String statusRunning = 'pending';
-
-  @IntProperty(propertyName: 'PR', required: true)
-  int? pr;
-
-  @StringProperty(propertyName: 'Head')
-  String? head;
-
-  @StringProperty(propertyName: 'Status', required: true)
-  String? status;
-
-  @StringProperty(propertyName: 'Description', required: true)
-  String? description;
-
-  @IntProperty(propertyName: 'Updates', required: true)
-  int? updates;
-
-  @StringProperty(propertyName: 'Repository', required: true)
-  String? repository;
-
-  @override
-  String toString() {
-    final StringBuffer buf = StringBuffer()
-      ..write('$runtimeType(')
-      ..write('id: $id')
-      ..write(', parentKey: ${parentKey?.id}')
-      ..write(', key: ${parentKey == null ? null : key.id}')
-      ..write(', pr: $pr')
-      ..write(', head: $head')
-      ..write(', lastStatus: $status')
-      ..write(', description $description')
-      ..write(', updates: $updates')
-      ..write(', repository: $repository')
-      ..write(')');
-    return buf.toString();
-  }
-}
diff --git a/app_dart/lib/src/model/appengine/key_converter.dart b/app_dart/lib/src/model/appengine/key_converter.dart
deleted file mode 100644
index 60aba60..0000000
--- a/app_dart/lib/src/model/appengine/key_converter.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:gcloud/db.dart';
-import 'package:json_annotation/json_annotation.dart';
-
-import 'key_helper.dart';
-
-/// A converter for [Key]s encoded as strings.
-class StringKeyConverter implements JsonConverter<Key<String>?, String> {
-  const StringKeyConverter();
-
-  @override
-  Key<String>? fromJson(String? json) =>
-      (json == null || json.isEmpty) ? null : KeyHelper().decode(json) as Key<String>;
-
-  @override
-  String toJson(Key<String>? key) => key == null ? '' : KeyHelper().encode(key);
-}
-
-/// A converter for [Key]s encoded as strings.
-class IntKeyConverter implements JsonConverter<Key<int>, String> {
-  const IntKeyConverter();
-
-  @override
-  Key<int> fromJson(String json) => KeyHelper().decode(json) as Key<int>;
-
-  @override
-  String toJson(Key<int?> key) => KeyHelper().encode(key);
-}
diff --git a/app_dart/lib/src/model/appengine/key_helper.dart b/app_dart/lib/src/model/appengine/key_helper.dart
deleted file mode 100644
index f5d6be4..0000000
--- a/app_dart/lib/src/model/appengine/key_helper.dart
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:mirrors';
-import 'dart:typed_data';
-
-import 'package:appengine/appengine.dart';
-import 'package:appengine/appengine.dart' as gae show context;
-import 'package:fixnum/fixnum.dart';
-import 'package:gcloud/db.dart';
-import 'package:meta/meta.dart';
-
-import 'allowed_account.dart';
-import 'commit.dart';
-import 'github_build_status_update.dart';
-import 'key_helper.pb.dart';
-import 'task.dart';
-
-const Set<Type> _defaultTypes = <Type>{
-  Commit,
-  GithubBuildStatusUpdate,
-  Task,
-  AllowedAccount,
-};
-
-/// Class used to encode and decode [Key] objects.
-///
-/// The encoding uses binary-encoded protocol buffers that are then base-64 URL
-/// encoded (and the decoding reverses that process).
-///
-/// This encoding scheme is necessary to match the behavior of the Go AppEngine
-/// datastore library. This parity is required while Cocoon operates with
-/// two backends, because the serialized values vended by one backend must
-/// be deserializable by the other backend.
-@immutable
-class KeyHelper {
-  KeyHelper({
-    AppEngineContext? applicationContext,
-    Set<Type> types = _defaultTypes,
-  })  : applicationContext = applicationContext ?? gae.context.applicationContext,
-        types = _populateTypes(types);
-
-  /// Metadata about the App Engine application.
-  final AppEngineContext applicationContext;
-
-  /// Maps Dart [Model] classes to their corresponding App Engine datastore
-  /// type names.
-  ///
-  /// This is initialized when the [KeyHelper] is created by iterating over
-  /// the `types` argument to the [KeyHelper.new] constructor and looking for
-  /// `@`[Kind] annotations on those classes.
-  final Map<Type, Kind> types;
-
-  /// Encodes the specified [key] as a base-64 encoded protocol buffer
-  /// representation of the key.
-  ///
-  /// See also:
-  ///
-  ///  * <https://github.com/golang/appengine/blob/b2f4a3cf3c67576a2ee09e1fe62656a5086ce880/datastore/key.go#L231>
-  String encode(Key<dynamic> key) {
-    final Reference reference = Reference()
-      ..app = applicationContext.applicationID
-      ..path = _asPath(key);
-    if (applicationContext.partition.isNotEmpty) {
-      reference.nameSpace = applicationContext.partition;
-    }
-    final Uint8List buffer = reference.writeToBuffer();
-    final String base64Encoded = base64Url.encode(buffer);
-    return base64Encoded.split('=').first;
-  }
-
-  /// Decodes the specified [encoded] string into its [Key] representation.
-  ///
-  /// See also:
-  ///
-  ///  * [encode], which is the complement to this method.
-  ///  * <https://github.com/golang/appengine/blob/b2f4a3cf3c67576a2ee09e1fe62656a5086ce880/datastore/key.go#L244>
-  Key<dynamic> decode(String encoded) {
-    // Re-add padding.
-    final int remainder = encoded.length % 4;
-    if (remainder != 0) {
-      final String padding = '=' * (4 - remainder);
-      encoded += padding;
-    }
-
-    final Uint8List decoded = base64Url.decode(encoded);
-    final Reference reference = Reference.fromBuffer(decoded);
-    return reference.path.element.fold<Key<dynamic>>(
-      Key<int>.emptyKey(Partition(reference.nameSpace.isEmpty ? null : reference.nameSpace)),
-      (Key<dynamic> previous, Path_Element element) {
-        final Iterable<MapEntry<Type, Kind>> entries =
-            types.entries.where((MapEntry<Type, Kind> entry) => entry.value.name == element.type);
-        if (entries.isEmpty) {
-          throw StateError('Unknown type: ${element.type}');
-        }
-        final MapEntry<Type, Kind> entry = entries.single;
-        if (entry.value.idType == IdType.String) {
-          return previous.append<String>(entry.key, id: element.name);
-        } else {
-          return previous.append<int>(entry.key, id: element.id.toInt());
-        }
-      },
-    );
-  }
-
-  static Map<Type, Kind> _populateTypes(Set<Type> types) {
-    final Map<Type, Kind> result = <Type, Kind>{};
-
-    for (Type type in types) {
-      final ClassMirror classMirror = reflectClass(type);
-      final List<InstanceMirror> kindAnnotations = classMirror.metadata
-          .where((InstanceMirror annotation) => annotation.hasReflectee)
-          .where((InstanceMirror annotation) => annotation.reflectee.runtimeType == Kind)
-          .toList();
-      if (kindAnnotations.isEmpty) {
-        throw StateError('Class $type has no @Kind annotation');
-      }
-      final Kind annotation = kindAnnotations.single.reflectee as Kind;
-      result[type] = Kind(
-        name: annotation.name ?? type.toString(),
-        idType: annotation.idType,
-      );
-    }
-
-    return Map<Type, Kind>.unmodifiable(result);
-  }
-
-  Path _asPath(Key<dynamic> key) {
-    final List<Key<dynamic>> path = <Key<dynamic>>[];
-    for (Key<dynamic>? current = key; current != null && !current.isEmpty; current = current.parent) {
-      path.insert(0, current);
-    }
-    return Path()
-      ..element.addAll(
-        path.map<Path_Element>((Key<dynamic> key) {
-          final Path_Element element = Path_Element();
-          if (key.type != null) {
-            element.type = types.containsKey(key.type) ? types[key.type!]!.name! : key.type.toString();
-          }
-          final Object? id = key.id;
-          if (id is String) {
-            element.name = id;
-          } else if (id is int) {
-            element.id = Int64(id);
-          }
-          return element;
-        }),
-      );
-  }
-}
diff --git a/app_dart/lib/src/model/appengine/key_helper.pb.dart b/app_dart/lib/src/model/appengine/key_helper.pb.dart
deleted file mode 100644
index 57bc0fb..0000000
--- a/app_dart/lib/src/model/appengine/key_helper.pb.dart
+++ /dev/null
@@ -1,229 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/appengine/key_helper.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
-
-import 'dart:core' as $core;
-
-import 'package:fixnum/fixnum.dart' as $fixnum;
-import 'package:protobuf/protobuf.dart' as $pb;
-
-class Path_Element extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
-      const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Path.Element',
-      createEmptyInstance: create)
-    ..aQS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'type')
-    ..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
-    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name');
-
-  Path_Element._() : super();
-  factory Path_Element({
-    $core.String? type,
-    $fixnum.Int64? id,
-    $core.String? name,
-  }) {
-    final _result = create();
-    if (type != null) {
-      _result.type = type;
-    }
-    if (id != null) {
-      _result.id = id;
-    }
-    if (name != null) {
-      _result.name = name;
-    }
-    return _result;
-  }
-  factory Path_Element.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory Path_Element.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
-      'Will be removed in next major version')
-  Path_Element clone() => Path_Element()..mergeFromMessage(this);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-      'Will be removed in next major version')
-  Path_Element copyWith(void Function(Path_Element) updates) =>
-      super.copyWith((message) => updates(message as Path_Element)) as Path_Element; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static Path_Element create() => Path_Element._();
-  Path_Element createEmptyInstance() => create();
-  static $pb.PbList<Path_Element> createRepeated() => $pb.PbList<Path_Element>();
-  @$core.pragma('dart2js:noInline')
-  static Path_Element getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Path_Element>(create);
-  static Path_Element? _defaultInstance;
-
-  @$pb.TagNumber(2)
-  $core.String get type => $_getSZ(0);
-  @$pb.TagNumber(2)
-  set type($core.String v) {
-    $_setString(0, v);
-  }
-
-  @$pb.TagNumber(2)
-  $core.bool hasType() => $_has(0);
-  @$pb.TagNumber(2)
-  void clearType() => clearField(2);
-
-  @$pb.TagNumber(3)
-  $fixnum.Int64 get id => $_getI64(1);
-  @$pb.TagNumber(3)
-  set id($fixnum.Int64 v) {
-    $_setInt64(1, v);
-  }
-
-  @$pb.TagNumber(3)
-  $core.bool hasId() => $_has(1);
-  @$pb.TagNumber(3)
-  void clearId() => clearField(3);
-
-  @$pb.TagNumber(4)
-  $core.String get name => $_getSZ(2);
-  @$pb.TagNumber(4)
-  set name($core.String v) {
-    $_setString(2, v);
-  }
-
-  @$pb.TagNumber(4)
-  $core.bool hasName() => $_has(2);
-  @$pb.TagNumber(4)
-  void clearName() => clearField(4);
-}
-
-class Path extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
-      const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Path',
-      createEmptyInstance: create)
-    ..pc<Path_Element>(
-        1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'element', $pb.PbFieldType.PG,
-        subBuilder: Path_Element.create)
-    ..hasRequiredFields = false;
-
-  Path._() : super();
-  factory Path({
-    $core.Iterable<Path_Element>? element,
-  }) {
-    final _result = create();
-    if (element != null) {
-      _result.element.addAll(element);
-    }
-    return _result;
-  }
-  factory Path.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory Path.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
-      'Will be removed in next major version')
-  Path clone() => Path()..mergeFromMessage(this);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-      'Will be removed in next major version')
-  Path copyWith(void Function(Path) updates) =>
-      super.copyWith((message) => updates(message as Path)) as Path; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static Path create() => Path._();
-  Path createEmptyInstance() => create();
-  static $pb.PbList<Path> createRepeated() => $pb.PbList<Path>();
-  @$core.pragma('dart2js:noInline')
-  static Path getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Path>(create);
-  static Path? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.List<Path_Element> get element => $_getList(0);
-}
-
-class Reference extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
-      const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Reference',
-      createEmptyInstance: create)
-    ..aQS(13, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'app')
-    ..aQM<Path>(14, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'path',
-        subBuilder: Path.create)
-    ..aOS(20, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'nameSpace');
-
-  Reference._() : super();
-  factory Reference({
-    $core.String? app,
-    Path? path,
-    $core.String? nameSpace,
-  }) {
-    final _result = create();
-    if (app != null) {
-      _result.app = app;
-    }
-    if (path != null) {
-      _result.path = path;
-    }
-    if (nameSpace != null) {
-      _result.nameSpace = nameSpace;
-    }
-    return _result;
-  }
-  factory Reference.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory Reference.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
-      'Will be removed in next major version')
-  Reference clone() => Reference()..mergeFromMessage(this);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-      'Will be removed in next major version')
-  Reference copyWith(void Function(Reference) updates) =>
-      super.copyWith((message) => updates(message as Reference)) as Reference; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static Reference create() => Reference._();
-  Reference createEmptyInstance() => create();
-  static $pb.PbList<Reference> createRepeated() => $pb.PbList<Reference>();
-  @$core.pragma('dart2js:noInline')
-  static Reference getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Reference>(create);
-  static Reference? _defaultInstance;
-
-  @$pb.TagNumber(13)
-  $core.String get app => $_getSZ(0);
-  @$pb.TagNumber(13)
-  set app($core.String v) {
-    $_setString(0, v);
-  }
-
-  @$pb.TagNumber(13)
-  $core.bool hasApp() => $_has(0);
-  @$pb.TagNumber(13)
-  void clearApp() => clearField(13);
-
-  @$pb.TagNumber(14)
-  Path get path => $_getN(1);
-  @$pb.TagNumber(14)
-  set path(Path v) {
-    setField(14, v);
-  }
-
-  @$pb.TagNumber(14)
-  $core.bool hasPath() => $_has(1);
-  @$pb.TagNumber(14)
-  void clearPath() => clearField(14);
-  @$pb.TagNumber(14)
-  Path ensurePath() => $_ensure(1);
-
-  @$pb.TagNumber(20)
-  $core.String get nameSpace => $_getSZ(2);
-  @$pb.TagNumber(20)
-  set nameSpace($core.String v) {
-    $_setString(2, v);
-  }
-
-  @$pb.TagNumber(20)
-  $core.bool hasNameSpace() => $_has(2);
-  @$pb.TagNumber(20)
-  void clearNameSpace() => clearField(20);
-}
diff --git a/app_dart/lib/src/model/appengine/key_helper.pbenum.dart b/app_dart/lib/src/model/appengine/key_helper.pbenum.dart
deleted file mode 100644
index eef0c46..0000000
--- a/app_dart/lib/src/model/appengine/key_helper.pbenum.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/appengine/key_helper.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
diff --git a/app_dart/lib/src/model/appengine/key_helper.pbjson.dart b/app_dart/lib/src/model/appengine/key_helper.pbjson.dart
deleted file mode 100644
index 793f8d9..0000000
--- a/app_dart/lib/src/model/appengine/key_helper.pbjson.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/appengine/key_helper.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
-
-import 'dart:core' as $core;
-import 'dart:convert' as $convert;
-import 'dart:typed_data' as $typed_data;
-
-@$core.Deprecated('Use pathDescriptor instead')
-const Path$json = {
-  '1': 'Path',
-  '2': [
-    {'1': 'element', '3': 1, '4': 3, '5': 10, '6': '.Path.Element', '10': 'element'},
-  ],
-  '3': [Path_Element$json],
-};
-
-@$core.Deprecated('Use pathDescriptor instead')
-const Path_Element$json = {
-  '1': 'Element',
-  '2': [
-    {'1': 'type', '3': 2, '4': 2, '5': 9, '10': 'type'},
-    {'1': 'id', '3': 3, '4': 1, '5': 3, '10': 'id'},
-    {'1': 'name', '3': 4, '4': 1, '5': 9, '10': 'name'},
-  ],
-};
-
-/// Descriptor for `Path`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List pathDescriptor = $convert.base64Decode(
-    'CgRQYXRoEicKB2VsZW1lbnQYASADKAoyDS5QYXRoLkVsZW1lbnRSB2VsZW1lbnQaQQoHRWxlbWVudBISCgR0eXBlGAIgAigJUgR0eXBlEg4KAmlkGAMgASgDUgJpZBISCgRuYW1lGAQgASgJUgRuYW1l');
-@$core.Deprecated('Use referenceDescriptor instead')
-const Reference$json = {
-  '1': 'Reference',
-  '2': [
-    {'1': 'app', '3': 13, '4': 2, '5': 9, '10': 'app'},
-    {'1': 'name_space', '3': 20, '4': 1, '5': 9, '10': 'nameSpace'},
-    {'1': 'path', '3': 14, '4': 2, '5': 11, '6': '.Path', '10': 'path'},
-  ],
-};
-
-/// Descriptor for `Reference`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List referenceDescriptor = $convert.base64Decode(
-    'CglSZWZlcmVuY2USEAoDYXBwGA0gAigJUgNhcHASHQoKbmFtZV9zcGFjZRgUIAEoCVIJbmFtZVNwYWNlEhkKBHBhdGgYDiACKAsyBS5QYXRoUgRwYXRo');
diff --git a/app_dart/lib/src/model/appengine/key_helper.pbserver.dart b/app_dart/lib/src/model/appengine/key_helper.pbserver.dart
deleted file mode 100644
index fd4acbd..0000000
--- a/app_dart/lib/src/model/appengine/key_helper.pbserver.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/appengine/key_helper.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
-
-export 'key_helper.pb.dart';
diff --git a/app_dart/lib/src/model/appengine/key_helper.proto b/app_dart/lib/src/model/appengine/key_helper.proto
deleted file mode 100644
index 9a0313d..0000000
--- a/app_dart/lib/src/model/appengine/key_helper.proto
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package cocoon;
-
-// Message used in the serialization of [Key] objects.
-//
-// These are serialized to protocol buffers to match the behavior of the Go
-// AppEngine datastore library. This parity is required while Cocoon operates
-// with two backends, because the serialized values vended by one backend must
-// be deserializable by the other backend.
-//
-// See also:
-//
-//  * <https://github.com/golang/appengine/blob/b2f4a3cf3c67576a2ee09e1fe62656a5086ce880/internal/datastore/datastore_v3.proto#L89>
-message Path {
-    repeated group Element = 1 {
-        required string type = 2;
-        optional int64 id = 3;
-        optional string name = 4;
-    }
-}
-
-// Message used in the serialization of [Key] objects.
-//
-// These are serialized to protocol buffers to match the behavior of the Go
-// AppEngine datastore library. This parity is required while Cocoon operates
-// with two backends, because the serialized values vended by one backend must
-// be deserializable by the other backend.
-//
-// See also:
-//
-//  * <https://github.com/golang/appengine/blob/b2f4a3cf3c67576a2ee09e1fe62656a5086ce880/internal/datastore/datastore_v3.proto#L97>
-message Reference {
-    required string app = 13;
-    optional string name_space = 20;
-    required Path path = 14;
-}
diff --git a/app_dart/lib/src/model/appengine/key_wrapper.dart b/app_dart/lib/src/model/appengine/key_wrapper.dart
deleted file mode 100644
index c594176..0000000
--- a/app_dart/lib/src/model/appengine/key_wrapper.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:fixnum/fixnum.dart';
-import 'package:gcloud/db.dart';
-
-import '../proto/protos.dart' as pb;
-
-import 'key_helper.dart';
-
-class KeyWrapper {
-  const KeyWrapper(this.key);
-
-  factory KeyWrapper.fromProto(pb.RootKey root) {
-    Key<dynamic> result = Key<dynamic>.emptyKey(Partition(root.namespace));
-    for (pb.Key key = root.child; key.hasChild(); key = key.child) {
-      final Type type = _typeFromString(key.type);
-      switch (key.whichId()) {
-        case pb.Key_Id.uid:
-          result = result.append<int>(type, id: key.uid.toInt());
-          break;
-        case pb.Key_Id.name:
-          result = result.append<String>(type, id: key.name);
-          break;
-        case pb.Key_Id.notSet:
-          result = result.append<dynamic>(type);
-          break;
-      }
-    }
-
-    return KeyWrapper(result);
-  }
-
-  final Key<dynamic> key;
-
-  pb.RootKey toProto() {
-    pb.Key? previous;
-    for (Key<dynamic>? slice = key; slice != null; slice = key.parent) {
-      final pb.Key current = pb.Key();
-      if (slice.type != null) {
-        current.type = slice.type.toString();
-      }
-      final Object? id = slice.id;
-      if (id is String) {
-        current.name = id;
-      } else if (id is int) {
-        current.uid = Int64(id);
-      }
-      if (previous != null) {
-        current.child = previous;
-      }
-      previous = current;
-
-      if (slice.isEmpty) {
-        return pb.RootKey()
-          ..namespace = slice.partition.namespace!
-          ..child = previous;
-      }
-    }
-
-    return pb.RootKey()..child = previous!;
-  }
-
-  static Type _typeFromString(String value) {
-    final KeyHelper keyHelper = KeyHelper();
-    return keyHelper.types.keys.singleWhere((Type type) => type.toString() == value);
-  }
-}
diff --git a/app_dart/lib/src/model/appengine/service_account_info.dart b/app_dart/lib/src/model/appengine/service_account_info.dart
deleted file mode 100644
index 6c2d46a..0000000
--- a/app_dart/lib/src/model/appengine/service_account_info.dart
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:googleapis_auth/googleapis_auth.dart';
-import 'package:json_annotation/json_annotation.dart';
-
-part 'service_account_info.g.dart';
-
-/// Class that represents authentication information that enables callers to
-/// execute environment-specific tasks on behalf of their apps.
-///
-/// See also:
-///
-///  * <https://cloud.google.com/appengine/docs/flexible/python/service-account>
-///
-///  * `package:googleapis_auth`, which can make use of the service account
-///    information to obtain an OAuth 2.0 access token on behalf of the
-///    application.
-@JsonSerializable()
-class ServiceAccountInfo {
-  /// Creates a new [ServiceAccountInfo] object.
-  const ServiceAccountInfo({
-    this.type,
-    this.projectId,
-    this.privateKeyId,
-    this.privateKey,
-    this.email,
-    this.clientId,
-    this.authUrl,
-    this.tokenUrl,
-    this.authCertUrl,
-    this.clientCertUrl,
-  });
-
-  /// Create a new [ServiceAccountInfo] object from its JSON representation.
-  factory ServiceAccountInfo.fromJson(Map<String, dynamic> json) => _$ServiceAccountInfoFromJson(json);
-
-  @JsonKey(name: 'type')
-  final String? type;
-
-  @JsonKey(name: 'project_id')
-  final String? projectId;
-
-  @JsonKey(name: 'private_key_id')
-  final String? privateKeyId;
-
-  @JsonKey(name: 'private_key')
-  final String? privateKey;
-
-  @JsonKey(name: 'client_email')
-  final String? email;
-
-  @JsonKey(name: 'client_id')
-  final String? clientId;
-
-  @JsonKey(name: 'auth_uri')
-  final String? authUrl;
-
-  @JsonKey(name: 'token_uri')
-  final String? tokenUrl;
-
-  @JsonKey(name: 'auth_provider_x509_cert_url')
-  final String? authCertUrl;
-
-  @JsonKey(name: 'client_x509_cert_url')
-  final String? clientCertUrl;
-
-  /// Serializes this object to a JSON primitive.
-  Map<String, dynamic> toJson() => _$ServiceAccountInfoToJson(this);
-
-  /// Returns this object in its [ServiceAccountCredentials] form.
-  ServiceAccountCredentials asServiceAccountCredentials() {
-    return ServiceAccountCredentials(email!, ClientId(clientId!, null), privateKey!);
-  }
-}
diff --git a/app_dart/lib/src/model/appengine/service_account_info.g.dart b/app_dart/lib/src/model/appengine/service_account_info.g.dart
deleted file mode 100644
index be7b228..0000000
--- a/app_dart/lib/src/model/appengine/service_account_info.g.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-// ignore_for_file: always_specify_types, implicit_dynamic_parameter
-
-part of 'service_account_info.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-ServiceAccountInfo _$ServiceAccountInfoFromJson(Map<String, dynamic> json) => ServiceAccountInfo(
-      type: json['type'] as String?,
-      projectId: json['project_id'] as String?,
-      privateKeyId: json['private_key_id'] as String?,
-      privateKey: json['private_key'] as String?,
-      email: json['client_email'] as String?,
-      clientId: json['client_id'] as String?,
-      authUrl: json['auth_uri'] as String?,
-      tokenUrl: json['token_uri'] as String?,
-      authCertUrl: json['auth_provider_x509_cert_url'] as String?,
-      clientCertUrl: json['client_x509_cert_url'] as String?,
-    );
-
-Map<String, dynamic> _$ServiceAccountInfoToJson(ServiceAccountInfo instance) => <String, dynamic>{
-      'type': instance.type,
-      'project_id': instance.projectId,
-      'private_key_id': instance.privateKeyId,
-      'private_key': instance.privateKey,
-      'client_email': instance.email,
-      'client_id': instance.clientId,
-      'auth_uri': instance.authUrl,
-      'token_uri': instance.tokenUrl,
-      'auth_provider_x509_cert_url': instance.authCertUrl,
-      'client_x509_cert_url': instance.clientCertUrl,
-    };
diff --git a/app_dart/lib/src/model/appengine/stage.dart b/app_dart/lib/src/model/appengine/stage.dart
deleted file mode 100644
index c09b2ef..0000000
--- a/app_dart/lib/src/model/appengine/stage.dart
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:json_annotation/json_annotation.dart';
-import 'package:meta/meta.dart';
-
-import 'commit.dart';
-import 'task.dart';
-
-part 'stage.g.dart';
-
-/// A group of related [Task]s run against a particular [Commit].
-///
-/// Stages are grouped by the infrastructure family that runs them, such as
-/// LUCI, DeviceLab on Linux, DeviceLab on Windows, etc.
-@immutable
-@JsonSerializable(createFactory: false, ignoreUnannotated: true)
-class Stage implements Comparable<Stage> {
-  const Stage(this.name, this.commit, this.tasks, this.taskStatus);
-
-  const Stage._(this.name, this.commit, this.tasks, this.taskStatus);
-
-  /// The fixed ordering of the stages (by name).
-  ///
-  /// Unknown stages will be placed at the end of any ordering.
-  static const List<String?> _order = <String?>[
-    'chromebot',
-    'devicelab',
-    'devicelab_win',
-    'devicelab_ios',
-  ];
-
-  /// Arbitrarily large index to represent the "end of the ordering".
-  static const int _endOfList = 1000000;
-
-  /// The name of the stage (e.g. 'devicelab', 'devicelab_win').
-  ///
-  /// This is guaranteed to be non-null.
-  @JsonKey(name: 'Name')
-  final String? name;
-
-  /// The commit that owns this stage.
-  ///
-  /// All [tasks] will be run against this commit.
-  final Commit? commit;
-
-  /// The list of tasks in this stage.
-  ///
-  /// These tasks will be run against [commit]. This list is guaranteed to be
-  /// non-empty.
-  final List<Task> tasks;
-
-  /// Representation of [tasks] used for JSON serialization.
-  @JsonKey(name: 'Tasks')
-  List<SerializableTask> get serializableTasks {
-    return tasks.map<SerializableTask>((Task task) => SerializableTask(task)).toList();
-  }
-
-  /// The aggregate status, accounting for all [tasks] in this stage.
-  ///
-  /// The status is defined as follows:
-  ///
-  ///  * If all tasks in this stage succeeded, then [Task.statusSucceeded]
-  ///  * If at least one task in this stage failed, then [Task.statusFailed]
-  ///  * If all tasks have the same status, then that status
-  ///  * Else [Task.statusInProgress]
-  @JsonKey(name: 'Status')
-  final String taskStatus;
-
-  /// Whether this stage is managed by the Flutter device lab.
-  ///
-  /// Stages such as 'chromebot' are not managed by the Flutter
-  /// device lab.
-  bool get isManagedByDeviceLab => name!.startsWith('devicelab');
-
-  @override
-  int compareTo(Stage other) => _orderIndex(this).compareTo(_orderIndex(other));
-
-  static int _orderIndex(Stage stage) {
-    int index = _order.indexOf(stage.name);
-    if (index == -1) {
-      // Put unknown stages last.
-      index = _endOfList;
-    }
-    return index;
-  }
-
-  /// Serializes this object to a JSON primitive.
-  Map<String, dynamic> toJson() => _$StageToJson(this);
-
-  @override
-  String toString() {
-    final StringBuffer buf = StringBuffer()
-      ..write('$runtimeType(')
-      ..write('name: $name')
-      ..write(', commit: ${commit?.sha}')
-      ..write(', tasks: ${tasks.length}')
-      ..write(', taskStatus: $taskStatus')
-      ..write(')');
-    return buf.toString();
-  }
-}
-
-/// A mutable class used to build instances of [Stage].
-class StageBuilder {
-  /// The name of the stage.
-  ///
-  /// See also:
-  ///  * [Stage.name]
-  String? name;
-
-  /// The commit that owns the stage.
-  ///
-  /// See also:
-  ///  * [Stage.commit]
-  Commit? commit;
-
-  /// The tasks within the stage, run against [commit].
-  ///
-  /// See also:
-  ///  * [Stage.commit]
-  List<Task> tasks = <Task>[];
-
-  /// Builds a [Stage] from the information in this builder.
-  ///
-  /// Throws a [StateError] if [name] is null, [commit] is null, or [tasks] is
-  /// empty.
-  Stage build() {
-    if (name == null) {
-      throw StateError('Cannot build a stage with no name');
-    }
-    if (commit == null) {
-      throw StateError('Cannot build a stage with no commit ($name)');
-    }
-    if (tasks.isEmpty) {
-      throw StateError('Cannot build a stage with no tasks ($name)');
-    }
-    return Stage._(name, commit, List<Task>.unmodifiable(tasks), _taskStatus);
-  }
-
-  String get _taskStatus {
-    assert(tasks.isNotEmpty);
-    bool isSucceeded(Task task) => task.status == Task.statusSucceeded;
-    bool isFailed(Task task) => task.status == Task.statusFailed;
-
-    if (tasks.every(isSucceeded)) {
-      return Task.statusSucceeded;
-    }
-
-    if (tasks.any(isFailed)) {
-      return Task.statusFailed;
-    }
-
-    final String? commonStatus =
-        tasks.map<String?>((Task task) => task.status).reduce((String? a, String? b) => a == b ? a : null);
-    return commonStatus ?? Task.statusInProgress;
-  }
-}
diff --git a/app_dart/lib/src/model/appengine/stage.g.dart b/app_dart/lib/src/model/appengine/stage.g.dart
deleted file mode 100644
index 09d4849..0000000
--- a/app_dart/lib/src/model/appengine/stage.g.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-// ignore_for_file: always_specify_types, implicit_dynamic_parameter
-
-part of 'stage.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-Map<String, dynamic> _$StageToJson(Stage instance) => <String, dynamic>{
-      'Name': instance.name,
-      'Tasks': instance.serializableTasks,
-      'Status': instance.taskStatus,
-    };
diff --git a/app_dart/lib/src/model/appengine/task.dart b/app_dart/lib/src/model/appengine/task.dart
deleted file mode 100644
index 3bcce62..0000000
--- a/app_dart/lib/src/model/appengine/task.dart
+++ /dev/null
@@ -1,548 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:gcloud/db.dart';
-import 'package:github/github.dart';
-import 'package:json_annotation/json_annotation.dart';
-
-import '../../request_handling/exceptions.dart';
-import '../../service/datastore.dart';
-import '../../service/logging.dart';
-import '../ci_yaml/target.dart';
-import '../luci/push_message.dart';
-import 'commit.dart';
-import 'key_converter.dart';
-
-import 'package:cocoon_service/src/model/luci/buildbucket.dart' as bb;
-part 'task.g.dart';
-
-/// Class that represents the intersection of a test at a particular [Commit].
-///
-/// Tasks are tests that have been run N (possibly zero) times against a
-/// particular commit.
-@JsonSerializable(createFactory: false, ignoreUnannotated: true)
-@Kind(name: 'Task')
-class Task extends Model<int> {
-  /// Creates a new [Task].
-  Task({
-    Key<int>? key,
-    this.commitKey,
-    this.createTimestamp = 0,
-    this.startTimestamp = 0,
-    this.endTimestamp = 0,
-    this.name,
-    this.attempts = 0,
-    this.isFlaky = false,
-    this.isTestFlaky = false,
-    this.timeoutInMinutes,
-    this.reason = '',
-    this.requiredCapabilities,
-    this.reservedForAgentId = '',
-    this.stageName,
-    this.buildNumber,
-    this.buildNumberList,
-    this.builderName,
-    this.luciBucket,
-    String? status,
-  }) : _status = status {
-    if (status != null && !legalStatusValues.contains(status)) {
-      throw ArgumentError('Invalid state: "$status"');
-    }
-    parentKey = key?.parent;
-    id = key?.id;
-  }
-
-  /// Construct [Task] from a [Target].
-  factory Task.fromTarget({
-    required Commit commit,
-    required Target target,
-  }) {
-    return Task(
-      attempts: 1,
-      builderName: target.value.name,
-      commitKey: commit.key,
-      createTimestamp: commit.timestamp!,
-      isFlaky: target.value.bringup,
-      key: commit.key.append(Task),
-      name: target.value.name,
-      requiredCapabilities: <String>[target.value.testbed],
-      stageName: target.value.scheduler.toString(),
-      status: Task.statusNew,
-      timeoutInMinutes: target.value.timeout,
-    );
-  }
-
-  /// Lookup [Task] from Datastore from its parent key and name.
-  static Future<Task> fromCommitKey({
-    required DatastoreService datastore,
-    required Key<String> commitKey,
-    required String name,
-  }) async {
-    if (name.isEmpty) {
-      throw const BadRequestException('task name is null');
-    }
-    final Query<Task> query = datastore.db.query<Task>(ancestorKey: commitKey)..filter('name =', name);
-    final List<Task> tasks = await query.run().toList();
-    if (tasks.length != 1) {
-      log.severe('Found ${tasks.length} entries for builder $name');
-      throw InternalServerError('Expected to find 1 task for $name, but found ${tasks.length}');
-    }
-    return tasks.single;
-  }
-
-  /// Lookup [Task] from its [key].
-  ///
-  /// This is the fastest way to lookup [Task], but requires [id] to be passed
-  /// as it is generated from Datastore.
-  static Future<Task> fromKey({
-    required DatastoreService datastore,
-    required Key<String> commitKey,
-    required int id,
-  }) {
-    log.fine('Looking up key...');
-    final Key<int> key = Key<int>(commitKey, Task, id);
-    return datastore.lookupByValue<Task>(key);
-  }
-
-  /// Lookup [Task] from Datastore.
-  ///
-  /// Either name or id must be given to lookup [Task].
-  ///
-  /// Prefer passing [id] when possible as it is a faster lookup.
-  static Future<Task> fromDatastore({
-    required DatastoreService datastore,
-    required Key<String> commitKey,
-    String? name,
-    String? id,
-  }) {
-    if (id == null) {
-      return Task.fromCommitKey(
-        datastore: datastore,
-        commitKey: commitKey,
-        name: name!,
-      );
-    }
-
-    return Task.fromKey(
-      datastore: datastore,
-      commitKey: commitKey,
-      id: int.parse(id),
-    );
-  }
-
-  /// Creates a [Task] based on a buildbucket [bb.Build].
-  static Future<Task> fromBuildbucketBuild(
-    bb.Build build,
-    DatastoreService datastore, {
-    String? customName,
-  }) async {
-    log.fine('Creating task from buildbucket result: ${build.toString()}');
-    // Example: Getting "flutter" from "mirrors/flutter".
-    final String repository = build.input!.gitilesCommit!.project!.split('/')[1];
-    log.fine('Repository: $repository');
-
-    // Example: Getting "stable" from "refs/heads/stable".
-    final String branch = build.input!.gitilesCommit!.ref!.split('/')[2];
-    log.fine('Branch: $branch');
-
-    final String hash = build.input!.gitilesCommit!.hash!;
-    log.fine('Hash: $hash');
-
-    final RepositorySlug slug = RepositorySlug('flutter', repository);
-    log.fine('Slug: ${slug.toString()}');
-
-    final int startTime = build.startTime?.millisecondsSinceEpoch ?? 0;
-    final int endTime = build.endTime?.millisecondsSinceEpoch ?? 0;
-    log.fine('Start/end time (ms): $startTime, $endTime');
-
-    final String id = '${slug.fullName}/$branch/$hash';
-    final Key<String> commitKey = datastore.db.emptyKey.append<String>(Commit, id: id);
-    final Commit commit = await datastore.db.lookupValue<Commit>(commitKey);
-    final task = Task(
-      attempts: 1,
-      buildNumber: build.number,
-      buildNumberList: build.number.toString(),
-      builderName: build.builderId.builder,
-      commitKey: commitKey,
-      createTimestamp: startTime,
-      endTimestamp: endTime,
-      luciBucket: build.builderId.bucket,
-      name: customName ?? build.builderId.builder,
-      stageName: build.builderId.project,
-      startTimestamp: startTime,
-      status: convertBuildbucketStatusToString(build.status!),
-      key: commit.key.append(Task),
-      timeoutInMinutes: 0,
-      reason: '',
-      requiredCapabilities: [],
-      reservedForAgentId: '',
-    );
-    return task;
-  }
-
-  /// Converts a buildbucket status to a task status.
-  static String convertBuildbucketStatusToString(bb.Status status) {
-    switch (status) {
-      case bb.Status.success:
-        return statusSucceeded;
-      case bb.Status.canceled:
-        return statusCancelled;
-      case bb.Status.infraFailure:
-        return statusInfraFailure;
-      case bb.Status.started:
-        return statusInProgress;
-      case bb.Status.scheduled:
-        return statusNew;
-      default:
-        return statusFailed;
-    }
-  }
-
-  /// The task was cancelled.
-  static const String statusCancelled = 'Cancelled';
-
-  /// The task is yet to be run.
-  static const String statusNew = 'New';
-
-  /// The task failed to run due to an unexpected issue.
-  static const String statusInfraFailure = 'Infra Failure';
-
-  /// The task is currently running.
-  static const String statusInProgress = 'In Progress';
-
-  /// The task was run successfully.
-  static const String statusSucceeded = 'Succeeded';
-
-  /// The task failed to run successfully.
-  static const String statusFailed = 'Failed';
-
-  /// The task was skipped or canceled while running.
-  ///
-  /// This status is only used by LUCI tasks.
-  static const String statusSkipped = 'Skipped';
-
-  /// The list of legal values for the [status] property.
-  static const List<String> legalStatusValues = <String>[
-    statusCancelled,
-    statusFailed,
-    statusInfraFailure,
-    statusInProgress,
-    statusNew,
-    statusSkipped,
-    statusSucceeded,
-  ];
-
-  static const List<String> finishedStatusValues = <String>[
-    statusCancelled,
-    statusFailed,
-    statusInfraFailure,
-    statusSkipped,
-    statusSucceeded,
-  ];
-
-  /// The key of the commit that owns this task.
-  @ModelKeyProperty(propertyName: 'ChecklistKey')
-  @JsonKey(name: 'ChecklistKey')
-  @StringKeyConverter()
-  Key<String>? commitKey;
-
-  /// The timestamp (in milliseconds since the Epoch) that this task was
-  /// created.
-  ///
-  /// This is _not_ when the task first started running, as tasks start out in
-  /// the 'New' state until they've been picked up by an [Agent].
-  @IntProperty(propertyName: 'CreateTimestamp', required: true)
-  @JsonKey(name: 'CreateTimestamp')
-  int? createTimestamp;
-
-  /// The timestamp (in milliseconds since the Epoch) that this task started
-  /// running.
-  ///
-  /// Tasks may be run more than once. If this task has been run more than
-  /// once, this timestamp represents when the task was most recently started.
-  @IntProperty(propertyName: 'StartTimestamp', required: true)
-  @JsonKey(name: 'StartTimestamp')
-  int? startTimestamp;
-
-  /// The timestamp (in milliseconds since the Epoch) that this task last
-  /// finished running.
-  @IntProperty(propertyName: 'EndTimestamp', required: true)
-  @JsonKey(name: 'EndTimestamp')
-  int? endTimestamp;
-
-  /// The name of the task.
-  ///
-  /// This is a human-readable name, typically a test name (e.g.
-  /// "hello_world__memory").
-  @StringProperty(propertyName: 'Name', required: true)
-  @JsonKey(name: 'Name')
-  String? name;
-
-  /// The number of attempts that have been made to run this task successfully.
-  ///
-  /// New tasks that have not yet been picked up by an [Agent] will have zero
-  /// attempts.
-  @IntProperty(propertyName: 'Attempts', required: true)
-  @JsonKey(name: 'Attempts')
-  int? attempts;
-
-  /// Whether this task has been marked flaky by .ci.yaml.
-  ///
-  /// See also:
-  ///
-  ///  * <https://github.com/flutter/flutter/blob/master/.ci.yaml>
-  ///
-  /// A flaky (`bringup: true`) task will not block the tree.
-  @BoolProperty(propertyName: 'Flaky')
-  @JsonKey(name: 'Flaky')
-  bool? isFlaky;
-
-  /// Whether the test execution of this task shows flake.
-  ///
-  /// Test runner supports rerun, and this flag tracks if a flake happens.
-  ///
-  /// See also:
-  ///  * <https://github.com/flutter/flutter/blob/master/dev/devicelab/lib/framework/runner.dart>
-  @BoolProperty(propertyName: 'TestFlaky')
-  @JsonKey(name: 'TestFlaky')
-  bool? isTestFlaky;
-
-  /// The timeout of the task, or zero if the task has no timeout.
-  @IntProperty(propertyName: 'TimeoutInMinutes', required: true)
-  @JsonKey(name: 'TimeoutInMinutes')
-  int? timeoutInMinutes;
-
-  /// Currently unset and unused.
-  @StringProperty(propertyName: 'Reason')
-  @JsonKey(name: 'Reason')
-  String? reason;
-
-  /// The build number of luci build: https://chromium.googlesource.com/infra/luci/luci-go/+/master/buildbucket/proto/build.proto#146
-  @IntProperty(propertyName: 'BuildNumber')
-  @JsonKey(name: 'BuildNumber')
-  int? buildNumber;
-
-  /// The build number list of luci builds: comma joined string of
-  /// different build numbers.
-  ///
-  /// For the case with single run 123, [buildNumberList] = '123';
-  /// For the case with multiple reruns 123, 456, 789,
-  /// [buildNumberList] = '123,456,789'.
-  @StringProperty(propertyName: 'BuildNumberList')
-  @JsonKey(name: 'BuildNumberList')
-  String? buildNumberList;
-
-  /// The builder name of luci build.
-  @StringProperty(propertyName: 'BuilderName')
-  @JsonKey(name: 'BuilderName')
-  String? builderName;
-
-  /// The luci pool where the luci task runs.
-  @StringProperty(propertyName: 'LuciBucket')
-  @JsonKey(name: 'luciBucket')
-  String? luciBucket;
-
-  /// The list of capabilities that agents are required to have to run this
-  /// task.
-  ///
-  /// See also:
-  ///
-  ///  * [Agent.capabilities], which list the capabilities of an agent.
-  @StringListProperty(propertyName: 'RequiredCapabilities')
-  @JsonKey(name: 'RequiredCapabilities')
-  List<String>? requiredCapabilities;
-
-  /// Set to the ID of the agent that's responsible for running this task.
-  ///
-  /// This will be null until an agent has reserved this task.
-  @StringProperty(propertyName: 'ReservedForAgentID')
-  @JsonKey(name: 'ReservedForAgentID')
-  String? reservedForAgentId;
-
-  /// The name of the [Stage] that groups this task with other tasks that are
-  /// related to it.
-  @StringProperty(propertyName: 'StageName', required: true)
-  @JsonKey(name: 'StageName')
-  String? stageName;
-
-  /// The status of the task.
-  ///
-  /// Legal values and their meanings are defined in [legalStatusValues].
-  @StringProperty(propertyName: 'Status', required: true)
-  @JsonKey(name: 'Status')
-  String get status => _status ?? statusNew;
-  String? _status;
-  set status(String value) {
-    if (!legalStatusValues.contains(value)) {
-      throw ArgumentError('Invalid state: "$value"');
-    }
-    _status = value;
-  }
-
-  /// Update [Task] fields based on a LUCI [Build].
-  void updateFromBuild(Build build) {
-    final List<String>? tags = build.tags;
-    // Example tag: build_address:luci.flutter.prod/Linux Cocoon/271
-    final String? buildAddress = tags?.firstWhere((String tag) => tag.contains('build_address'));
-    if (buildAddress == null) {
-      log.warning('Tags: $tags');
-      throw const BadRequestException('build_address does not contain build number');
-    }
-
-    final int currentBuildNumber = int.parse(buildAddress.split('/').last);
-    if (buildNumber == null || buildNumber! < currentBuildNumber) {
-      buildNumber = currentBuildNumber;
-    } else if (currentBuildNumber < buildNumber!) {
-      log.fine('Skipping message as build number is before the current task');
-      return;
-    }
-
-    if (buildNumberList == null) {
-      buildNumberList = '$buildNumber';
-    } else {
-      final Set<String> buildNumberSet = buildNumberList!.split(',').toSet();
-      buildNumberSet.add(buildNumber.toString());
-      buildNumberList = buildNumberSet.join(',');
-    }
-
-    createTimestamp = build.createdTimestamp?.millisecondsSinceEpoch ?? 0;
-    startTimestamp = build.startedTimestamp?.millisecondsSinceEpoch ?? 0;
-    endTimestamp = build.completedTimestamp?.millisecondsSinceEpoch ?? 0;
-
-    _setStatusFromLuciStatus(build);
-  }
-
-  /// Updates [Task] based on a Buildbucket [Build].
-  void updateFromBuildbucketBuild(bb.Build build) {
-    buildNumber = build.number!;
-
-    if (buildNumberList == null) {
-      buildNumberList = '$buildNumber';
-    } else {
-      final Set<String> buildNumberSet = buildNumberList!.split(',').toSet();
-      buildNumberSet.add(buildNumber.toString());
-      buildNumberList = buildNumberSet.join(',');
-    }
-
-    createTimestamp = build.startTime?.millisecondsSinceEpoch ?? 0;
-    startTimestamp = build.startTime?.millisecondsSinceEpoch ?? 0;
-    endTimestamp = build.endTime?.millisecondsSinceEpoch ?? 0;
-
-    attempts = buildNumberList!.split(',').length;
-
-    status = convertBuildbucketStatusToString(build.status!);
-  }
-
-  /// Get a [Task] status from a LUCI [Build] status/result.
-  String _setStatusFromLuciStatus(Build build) {
-    // Updates can come out of order. Ensure completed statuses are kept.
-    if (_isStatusCompleted()) {
-      return status;
-    }
-
-    if (build.status == Status.started) {
-      return status = statusInProgress;
-    }
-    switch (build.result) {
-      case Result.success:
-        return status = statusSucceeded;
-      case Result.canceled:
-        return status = statusCancelled;
-      case Result.failure:
-        // Note that `Result` does not support `infraFailure`:
-        // https://github.com/luci/luci-go/blob/main/common/api/buildbucket/buildbucket/v1/buildbucket-gen.go#L247-L251
-        // To determine an infra failure status, we need to combine `Result.failure` and `FailureReason.infraFailure`.
-        if (build.failureReason == FailureReason.infraFailure) {
-          return status = statusInfraFailure;
-        } else {
-          return status = statusFailed;
-        }
-      default:
-        throw BadRequestException('${build.result} is unknown');
-    }
-  }
-
-  bool _isStatusCompleted() {
-    const List<String> completedStatuses = <String>[
-      statusCancelled,
-      statusFailed,
-      statusInfraFailure,
-      statusSucceeded,
-    ];
-    return completedStatuses.contains(status);
-  }
-
-  /// Comparator that sorts tasks by fewest attempts first.
-  static int byAttempts(Task a, Task b) => a.attempts!.compareTo(b.attempts!);
-
-  /// Serializes this object to a JSON primitive.
-  Map<String, dynamic> toJson() => _$TaskToJson(this);
-
-  @override
-  String toString() {
-    final StringBuffer buf = StringBuffer()
-      ..write('$runtimeType(')
-      ..write('id: $id')
-      ..write(', parentKey: ${parentKey?.id}')
-      ..write(', key: ${parentKey == null ? null : key.id}')
-      ..write(', commitKey: ${commitKey?.id}')
-      ..write(', createTimestamp: $createTimestamp')
-      ..write(', startTimestamp: $startTimestamp')
-      ..write(', endTimestamp: $endTimestamp')
-      ..write(', name: $name')
-      ..write(', attempts: $attempts')
-      ..write(', isFlaky: $isFlaky')
-      ..write(', isTestRunFlaky: $isTestFlaky')
-      ..write(', timeoutInMinutes: $timeoutInMinutes')
-      ..write(', reason: $reason')
-      ..write(', requiredCapabilities: $requiredCapabilities')
-      ..write(', reservedForAgentId: $reservedForAgentId')
-      ..write(', stageName: $stageName')
-      ..write(', status: $status')
-      ..write(', buildNumber: $buildNumber')
-      ..write(', buildNumberList: $buildNumberList')
-      ..write(', builderName: $builderName')
-      ..write(', luciBucket: $luciBucket')
-      ..write(')');
-    return buf.toString();
-  }
-}
-
-Iterable<Task> targetsToTask(Commit commit, List<Target> targets) =>
-    targets.map((Target target) => Task.fromTarget(commit: commit, target: target));
-
-/// The serialized representation of a [Task].
-// TODO(tvolkert): Directly serialize [Task] once frontends migrate to new serialization format.
-@JsonSerializable(createFactory: false)
-class SerializableTask {
-  const SerializableTask(this.task);
-
-  @JsonKey(name: 'Task')
-  final Task task;
-
-  @JsonKey(name: 'Key')
-  @IntKeyConverter()
-  Key<int> get key => task.key;
-
-  /// Serializes this object to a JSON primitive.
-  Map<String, dynamic> toJson() => _$SerializableTaskToJson(this);
-}
-
-/// A [Task], paired with its associated parent [Commit].
-///
-/// The [Task] model object references its parent [Commit] through the
-/// [Task.commitKey] field, but it does not hold a reference to the associated
-/// [Commit] object (just the relational mapping). This class exists for those
-/// times when the caller has loaded the associated commit from the datastore
-/// and would like to pass both the task its commit around.
-class FullTask {
-  /// Creates a new [FullTask].
-  const FullTask(this.task, this.commit);
-
-  /// The [Task] object.
-  final Task task;
-
-  ///  The [Commit] object references by this [task]'s [Task.commitKey].
-  final Commit commit;
-}
diff --git a/app_dart/lib/src/model/appengine/task.g.dart b/app_dart/lib/src/model/appengine/task.g.dart
deleted file mode 100644
index 9ef04d6..0000000
--- a/app_dart/lib/src/model/appengine/task.g.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-// ignore_for_file: always_specify_types, implicit_dynamic_parameter
-
-part of 'task.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-Map<String, dynamic> _$TaskToJson(Task instance) => <String, dynamic>{
-      'ChecklistKey': const StringKeyConverter().toJson(instance.commitKey),
-      'CreateTimestamp': instance.createTimestamp,
-      'StartTimestamp': instance.startTimestamp,
-      'EndTimestamp': instance.endTimestamp,
-      'Name': instance.name,
-      'Attempts': instance.attempts,
-      'Flaky': instance.isFlaky,
-      'TestFlaky': instance.isTestFlaky,
-      'TimeoutInMinutes': instance.timeoutInMinutes,
-      'Reason': instance.reason,
-      'BuildNumber': instance.buildNumber,
-      'BuildNumberList': instance.buildNumberList,
-      'BuilderName': instance.builderName,
-      'luciBucket': instance.luciBucket,
-      'RequiredCapabilities': instance.requiredCapabilities,
-      'ReservedForAgentID': instance.reservedForAgentId,
-      'StageName': instance.stageName,
-      'Status': instance.status,
-    };
-
-Map<String, dynamic> _$SerializableTaskToJson(SerializableTask instance) => <String, dynamic>{
-      'Task': instance.task,
-      'Key': const IntKeyConverter().toJson(instance.key),
-    };
diff --git a/app_dart/lib/src/model/ci_yaml/ci_yaml.dart b/app_dart/lib/src/model/ci_yaml/ci_yaml.dart
deleted file mode 100644
index 46f1832..0000000
--- a/app_dart/lib/src/model/ci_yaml/ci_yaml.dart
+++ /dev/null
@@ -1,308 +0,0 @@
-// Copyright 2021 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-
-import 'package:cocoon_service/cocoon_service.dart';
-import 'package:github/github.dart';
-
-import '../proto/internal/scheduler.pb.dart' as pb;
-import 'target.dart';
-
-/// This is a wrapper class around S[pb.SchedulerConfig].
-///
-/// See //CI_YAML.md for high level documentation.
-class CiYaml {
-  /// Creates [CiYaml] from a [RepositorySlug], [branch], [pb.SchedulerConfig] and an optional [CiYaml] of tip of tree CiYaml.
-  ///
-  /// If [totConfig] is passed, the validation will verify no new targets have been added that may temporarily break the LUCI infrastructure (such as new prod or presubmit targets).
-  CiYaml({
-    required this.slug,
-    required this.branch,
-    required this.config,
-    CiYaml? totConfig,
-    bool validate = false,
-  }) {
-    if (validate) {
-      _validate(config, branch, totSchedulerConfig: totConfig?.config);
-    }
-    // Do not filter bringup targets. They are required for backward compatibility
-    // with release candidate branches.
-    final Iterable<Target> totTargets = totConfig?._targets ?? <Target>[];
-    final List<Target> totEnabledTargets = _filterEnabledTargets(totTargets);
-    totTargetNames = totEnabledTargets.map((Target target) => target.value.name).toList();
-    totPostsubmitTargetNames =
-        totConfig?.postsubmitTargets.map((Target target) => target.value.name).toList() ?? <String>[];
-  }
-
-  /// List of target names used to filter target from release candidate branches
-  /// that were already removed from main.
-  List<String>? totTargetNames;
-
-  /// List of postsubmit target names used to filter target from release candidate branches
-  /// that were already removed from main.
-  List<String>? totPostsubmitTargetNames;
-
-  /// The underlying protobuf that contains the raw data from .ci.yaml.
-  pb.SchedulerConfig config;
-
-  /// The [RepositorySlug] that [config] is from.
-  final RepositorySlug slug;
-
-  /// The git branch currently being scheduled against.
-  final String branch;
-
-  /// Gets all [Target] that run on presubmit for this config.
-  List<Target> get presubmitTargets {
-    final Iterable<Target> presubmitTargets =
-        _targets.where((Target target) => target.value.presubmit && !target.value.bringup);
-    List<Target> enabledTargets = _filterEnabledTargets(presubmitTargets);
-
-    if (enabledTargets.isEmpty) {
-      throw Exception('$branch is not enabled for this .ci.yaml.\nAdd it to run tests against this PR.');
-    }
-    // Filter targets removed from main.
-    if (totTargetNames!.isNotEmpty) {
-      enabledTargets = filterOutdatedTargets(slug, enabledTargets, totTargetNames);
-    }
-    return enabledTargets;
-  }
-
-  /// Gets all [Target] that run on postsubmit for this config.
-  List<Target> get postsubmitTargets {
-    final Iterable<Target> postsubmitTargets = _targets.where((Target target) => target.value.postsubmit);
-
-    List<Target> enabledTargets = _filterEnabledTargets(postsubmitTargets);
-    // Filter targets removed from main.
-    if (totPostsubmitTargetNames!.isNotEmpty) {
-      enabledTargets = filterOutdatedTargets(slug, enabledTargets, totPostsubmitTargetNames);
-    }
-    // filter if release_build true if current branch is a release candidate branch.
-    enabledTargets = _filterReleaseBuildTargets(enabledTargets);
-    return enabledTargets;
-  }
-
-  /// Filters post submit targets to remove targets we do not want backfilled.
-  List<Target> get backfillTargets {
-    final List<Target> filteredTargets = <Target>[];
-    for (Target target in postsubmitTargets) {
-      final Map<String, Object> properties = target.getProperties();
-      if (!properties.containsKey('backfill') || properties['backfill'] as bool) {
-        filteredTargets.add(target);
-      }
-    }
-    return filteredTargets;
-  }
-
-  /// Filters targets with release_build = true on release candidate branches.
-  List<Target> _filterReleaseBuildTargets(List<Target> targets) {
-    final List<Target> results = <Target>[];
-    final bool releaseBranch = branch.contains(RegExp('^flutter-'));
-    if (!releaseBranch) {
-      return targets;
-    }
-    for (Target target in targets) {
-      final Map<String, Object> properties = target.getProperties();
-      if (!properties.containsKey('release_build') || !(properties['release_build'] as bool)) {
-        if (!target.value.bringup) results.add(target);
-      }
-    }
-    return results;
-  }
-
-  /// Filters targets that were removed from main. [slug] is the gihub
-  /// slug for branch under test, [targets] is the list of targets from
-  /// the branch under test and [totTargetNames] is the list of target
-  /// names enabled on the default branch.
-  List<Target> filterOutdatedTargets(slug, targets, totTargetNames) {
-    final String defaultBranch = Config.defaultBranch(slug);
-    return targets
-        .where(
-          (Target target) =>
-              (target.value.enabledBranches.isNotEmpty && !target.value.enabledBranches.contains(defaultBranch)) ||
-              totTargetNames!.contains(target.value.name),
-        )
-        .toList();
-  }
-
-  /// Filters [targets] to those that should be started immediately.
-  ///
-  /// Targets with a dependency are triggered when there dependency pushes a notification that it has finished.
-  /// This shouldn't be confused for targets that have the property named dependency, which is used by the
-  /// flutter_deps recipe module on LUCI.
-  List<Target> getInitialTargets(List<Target> targets) {
-    Iterable<Target> initialTargets = targets.where((Target target) => target.value.dependencies.isEmpty).toList();
-    if (branch != Config.defaultBranch(slug)) {
-      // Filter out bringup targets for release branches
-      initialTargets = initialTargets.where((Target target) => !target.value.bringup);
-    }
-
-    return initialTargets.toList();
-  }
-
-  Iterable<Target> get _targets => config.targets.map(
-        (pb.Target target) => Target(
-          schedulerConfig: config,
-          value: target,
-          slug: slug,
-        ),
-      );
-
-  /// Get an unfiltered list of all [targets] that are found in the ci.yaml file.
-  List<Target> get targets => _targets.toList();
-
-  /// Filter [targets] to only those that are expected to run for [branch].
-  ///
-  /// A [Target] is expected to run if:
-  ///   1. [Target.enabledBranches] exists and matches [branch].
-  ///   2. Otherwise, [config.enabledBranches] matches [branch].
-  List<Target> _filterEnabledTargets(Iterable<Target> targets) {
-    final List<Target> filteredTargets = <Target>[];
-
-    // 1. Add targets with local definition
-    final Iterable<Target> overrideBranchTargets =
-        targets.where((Target target) => target.value.enabledBranches.isNotEmpty);
-    final Iterable<Target> enabledTargets = overrideBranchTargets
-        .where((Target target) => enabledBranchesMatchesCurrentBranch(target.value.enabledBranches, branch));
-    filteredTargets.addAll(enabledTargets);
-
-    // 2. Add targets with global definition (this is the majority of targets)
-    if (enabledBranchesMatchesCurrentBranch(config.enabledBranches, branch)) {
-      final Iterable<Target> defaultBranchTargets =
-          targets.where((Target target) => target.value.enabledBranches.isEmpty);
-      filteredTargets.addAll(defaultBranchTargets);
-    }
-
-    return filteredTargets;
-  }
-
-  /// Whether any of the possible [RegExp] in [enabledBranches] match [branch].
-  static bool enabledBranchesMatchesCurrentBranch(List<String> enabledBranches, String branch) {
-    final List<String> regexes = <String>[];
-    for (String enabledBranch in enabledBranches) {
-      // Prefix with start of line and suffix with end of line
-      regexes.add('^$enabledBranch\$');
-    }
-    final String rawRegexp = regexes.join('|');
-    final RegExp regexp = RegExp(rawRegexp);
-
-    return regexp.hasMatch(branch);
-  }
-
-  /// Validates [pb.SchedulerConfig] extracted from [CiYaml] files.
-  ///
-  /// A [pb.SchedulerConfig] file is considered good if:
-  ///   1. It has at least one [pb.Target] in [pb.SchedulerConfig.targets]
-  ///   2. It has at least one [branch] in [pb.SchedulerConfig.enabledBranches]
-  ///   3. If a second [pb.SchedulerConfig] is passed in,
-  ///   we compare the current list of [pb.Target] inside the current [pb.SchedulerConfig], i.e., [schedulerConfig],
-  ///   with the list of [pb.Target] from tip of the tree [pb.SchedulerConfig], i.e., [totSchedulerConfig].
-  ///   If a [pb.Target] is indentified as a new target compared to target list from tip of the tree, The new target
-  ///   should have its field [pb.Target.bringup] set to true.
-  ///   4. no cycle should exist in the dependency graph, as tracked by map [targetGraph]
-  ///   5. [pb.Target] should not depend on self
-  ///   6. [pb.Target] cannot have more than 1 dependency
-  ///   7. [pb.Target] should depend on target that already exist in depedency graph, and already recorded in map [targetGraph]
-  void _validate(pb.SchedulerConfig schedulerConfig, String branch, {pb.SchedulerConfig? totSchedulerConfig}) {
-    if (schedulerConfig.targets.isEmpty) {
-      throw const FormatException('Scheduler config must have at least 1 target');
-    }
-
-    if (schedulerConfig.enabledBranches.isEmpty) {
-      throw const FormatException('Scheduler config must have at least 1 enabled branch');
-    }
-
-    final Map<String, List<pb.Target>> targetGraph = <String, List<pb.Target>>{};
-    final List<String> exceptions = <String>[];
-    final Set<String> totTargets = <String>{};
-    if (totSchedulerConfig != null) {
-      for (pb.Target target in totSchedulerConfig.targets) {
-        totTargets.add(target.name);
-      }
-    }
-    // Construct [targetGraph]. With a one scan approach, cycles in the graph
-    // cannot exist as it only works forward.
-    for (final pb.Target target in schedulerConfig.targets) {
-      if (targetGraph.containsKey(target.name)) {
-        exceptions.add('ERROR: ${target.name} already exists in graph');
-      } else {
-        // a new build without "bringup: true"
-        // link to wiki - https://github.com/flutter/flutter/wiki/Reducing-Test-Flakiness#adding-a-new-devicelab-test
-        if (totTargets.isNotEmpty && !totTargets.contains(target.name) && target.bringup != true) {
-          exceptions.add(
-            'ERROR: ${target.name} is a new builder added. it needs to be marked bringup: true\nIf ci.yaml wasn\'t changed, try `git fetch upstream && git merge upstream/master`',
-          );
-          continue;
-        }
-        targetGraph[target.name] = <pb.Target>[];
-        // Add edges
-        if (target.dependencies.isNotEmpty) {
-          if (target.dependencies.length != 1) {
-            exceptions
-                .add('ERROR: ${target.name} has multiple dependencies which is not supported. Use only one dependency');
-          } else {
-            if (target.dependencies.first == target.name) {
-              exceptions.add('ERROR: ${target.name} cannot depend on itself');
-            } else if (targetGraph.containsKey(target.dependencies.first)) {
-              targetGraph[target.dependencies.first]!.add(target);
-            } else {
-              exceptions.add('ERROR: ${target.name} depends on ${target.dependencies.first} which does not exist');
-            }
-          }
-        }
-      }
-
-      /// Check the dependencies for the current target if it is viable and to
-      /// be added to graph. Temporarily this is only being done on non-release
-      /// branches.
-      if (branch == Config.defaultBranch(slug)) {
-        final String? dependencyJson = target.properties['dependencies'];
-        if (dependencyJson != null) {
-          DependencyValidator.hasVersion(dependencyJsonString: dependencyJson);
-        }
-      }
-    }
-    _checkExceptions(exceptions);
-  }
-
-  void _checkExceptions(List<String> exceptions) {
-    if (exceptions.isNotEmpty) {
-      final String fullException = exceptions.reduce((String exception, _) => '$exception\n');
-      throw FormatException(fullException);
-    }
-  }
-}
-
-/// Class to verify the version of the dependencies in the ci.yaml config file
-/// for each target we are going to execute.
-class DependencyValidator {
-  /// dependencyJsonString is guaranteed to be non empty as it must be found
-  /// before this method is called.
-  ///
-  /// Checks a dependency string for a pinned version.
-  /// If a version is found then it must not be empty or 'latest.'
-  static void hasVersion({required String dependencyJsonString}) {
-    final List<String> exceptions = <String>[];
-
-    /// Decoded will contain a list of maps for the dependencies found.
-    final List<dynamic> decoded = json.decode(dependencyJsonString) as List<dynamic>;
-
-    for (Map<String, dynamic> depMap in decoded) {
-      if (!depMap.containsKey('version')) {
-        exceptions.add('ERROR: dependency ${depMap['dependency']} must have a version.');
-      } else {
-        final String version = depMap['version'] as String;
-        if (version.isEmpty || version == 'latest') {
-          exceptions
-              .add('ERROR: dependency ${depMap['dependency']} must have a non empty, non "latest" version supplied.');
-        }
-      }
-    }
-
-    if (exceptions.isNotEmpty) {
-      final String fullException = exceptions.reduce((String exception, _) => '$exception\n');
-      throw FormatException(fullException);
-    }
-  }
-}
diff --git a/app_dart/lib/src/model/ci_yaml/target.dart b/app_dart/lib/src/model/ci_yaml/target.dart
deleted file mode 100644
index 4fa65e1..0000000
--- a/app_dart/lib/src/model/ci_yaml/target.dart
+++ /dev/null
@@ -1,281 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-
-import 'package:cocoon_service/src/service/scheduler/policy.dart';
-import 'package:github/github.dart';
-
-import '../../service/config.dart';
-import '../luci/buildbucket.dart';
-import '../proto/internal/scheduler.pb.dart' as pb;
-
-/// Wrapper class around [pb.Target] to support aggregate properties.
-///
-/// Changes here may also need to be upstreamed in:
-///  * https://flutter.googlesource.com/infra/+/refs/heads/main/config/lib/ci_yaml/ci_yaml.star
-class Target {
-  Target({
-    required this.value,
-    required this.schedulerConfig,
-    required this.slug,
-  });
-
-  /// Underlying [Target] this is based on.
-  final pb.Target value;
-
-  /// The [SchedulerConfig] [value] is from.
-  ///
-  /// This is passed for necessary lookups to platform level details.
-  final pb.SchedulerConfig schedulerConfig;
-
-  /// The [RepositorySlug] this [Target] is run for.
-  final RepositorySlug slug;
-
-  /// Target prefixes that indicate it will run on an ios device.
-  static const List<String> iosPlatforms = <String>['mac_ios', 'mac_arm64_ios'];
-
-  /// Dimension list defined in .ci.yaml.
-  static List<String> dimensionList = <String>['os', 'device_os', 'device_type', 'mac_model', 'cores', 'cpu'];
-
-  static String kIgnoreFlakiness = 'ignore_flakiness';
-
-  /// Gets assembled dimensions for this [pb.Target].
-  ///
-  /// Swarming dimension doc: https://chromium.googlesource.com/infra/luci/luci-go/+/HEAD/lucicfg/doc/README.md#swarming.dimension
-  ///
-  /// Target dimensions are prioritized in:
-  ///   1. [pb.Target.dimensions]
-  ///   1. [pb.Target.properties]
-  ///   2. [schedulerConfig.platformDimensions]
-  List<RequestedDimension> getDimensions() {
-    final Map<String, RequestedDimension> dimensionsMap = <String, RequestedDimension>{};
-
-    final Map<String, Object> platformDimensions = _getPlatformDimensions();
-    for (String key in platformDimensions.keys) {
-      final String value = platformDimensions[key].toString();
-      dimensionsMap[key] = RequestedDimension(key: key, value: value);
-    }
-
-    final Map<String, Object> properties = getProperties();
-    // TODO(xilaizhang): https://github.com/flutter/flutter/issues/103557
-    // remove this logic after dimensions are supported in ci.yaml files
-    for (String dimension in dimensionList) {
-      if (properties.containsKey(dimension)) {
-        final String value = properties[dimension].toString();
-        dimensionsMap[dimension] = RequestedDimension(key: dimension, value: value);
-      }
-    }
-
-    final Map<String, Object> targetDimensions = _getTargetDimensions();
-    for (String key in targetDimensions.keys) {
-      final String value = targetDimensions[key].toString();
-      dimensionsMap[key] = RequestedDimension(key: key, value: value);
-    }
-
-    return dimensionsMap.values.toList();
-  }
-
-  /// [SchedulerPolicy] this target follows.
-  ///
-  /// Targets not triggered by Cocoon will not be triggered.
-  ///
-  /// All targets except from [Config.guaranteedSchedulingRepos] run with [BatchPolicy] to reduce queue time.
-  SchedulerPolicy get schedulerPolicy {
-    if (value.scheduler != pb.SchedulerSystem.cocoon) {
-      return OmitPolicy();
-    }
-    if (Config.guaranteedSchedulingRepos.contains(slug)) {
-      return GuaranteedPolicy();
-    }
-    return BatchPolicy();
-  }
-
-  /// Get the tags from the defined properties in the ci.
-  ///
-  /// Return an empty list if no tags are found.
-  List<String> get tags {
-    final Map<String, Object> properties = getProperties();
-    return (properties.containsKey('tags')) ? (properties['tags'] as List).map((e) => e as String).toList() : [];
-  }
-
-  String get getTestName {
-    final List<String> words = value.name.split(' ');
-    return words.length < 2 ? words[0] : words[1];
-  }
-
-  /// Gets the assembled properties for this [pb.Target].
-  ///
-  /// Target properties are prioritized in:
-  ///   1. [schedulerConfig.platformProperties]
-  ///   2. [pb.Target.properties]
-  Map<String, Object> getProperties() {
-    final Map<String, Object> platformProperties = _getPlatformProperties();
-    final Map<String, Object> properties = _getTargetProperties();
-    final Map<String, Object> mergedProperties = <String, Object>{}
-      ..addAll(platformProperties)
-      ..addAll(properties);
-
-    final List<Dependency> targetDependencies = <Dependency>[];
-    if (properties.containsKey('dependencies')) {
-      final List<dynamic> rawDeps = properties['dependencies'] as List<dynamic>;
-      final Iterable<Dependency> deps = rawDeps.map((dynamic rawDep) => Dependency.fromJson(rawDep as Object));
-      targetDependencies.addAll(deps);
-    }
-    final List<Dependency> platformDependencies = <Dependency>[];
-    if (platformProperties.containsKey('dependencies')) {
-      final List<dynamic> rawDeps = platformProperties['dependencies'] as List<dynamic>;
-      final Iterable<Dependency> deps = rawDeps.map((dynamic rawDep) => Dependency.fromJson(rawDep as Object));
-      platformDependencies.addAll(deps);
-    }
-    // Lookup map to make merging [targetDependencies] and [platformDependencies] simpler.
-    final Map<String, Dependency> mergedDependencies = <String, Dependency>{};
-    for (Dependency dep in platformDependencies) {
-      mergedDependencies[dep.name] = dep;
-    }
-    for (Dependency dep in targetDependencies) {
-      mergedDependencies[dep.name] = dep;
-    }
-    mergedProperties['dependencies'] = mergedDependencies.values.map((Dependency dep) => dep.toJson()).toList();
-    mergedProperties['bringup'] = value.bringup;
-
-    return mergedProperties;
-  }
-
-  Map<String, Object> _getTargetDimensions() {
-    final Map<String, Object> dimensions = <String, Object>{};
-    for (String key in value.dimensions.keys) {
-      dimensions[key] = _parseProperty(key, value.dimensions[key]!);
-    }
-
-    return dimensions;
-  }
-
-  Map<String, Object> _getTargetProperties() {
-    final Map<String, Object> properties = <String, Object>{};
-    for (String key in value.properties.keys) {
-      properties[key] = _parseProperty(key, value.properties[key]!);
-    }
-
-    return properties;
-  }
-
-  Map<String, Object> _getPlatformProperties() {
-    if (!schedulerConfig.platformProperties.containsKey(getPlatform())) {
-      return <String, Object>{};
-    }
-
-    final Map<String, String> platformProperties = schedulerConfig.platformProperties[getPlatform()]!.properties;
-    final Map<String, Object> properties = <String, Object>{};
-    for (String key in platformProperties.keys) {
-      properties[key] = _parseProperty(key, platformProperties[key]!);
-    }
-
-    return properties;
-  }
-
-  Map<String, Object> _getPlatformDimensions() {
-    if (!schedulerConfig.platformProperties.containsKey(getPlatform())) {
-      return <String, Object>{};
-    }
-
-    final Map<String, String> platformDimensions = schedulerConfig.platformProperties[getPlatform()]!.dimensions;
-    final Map<String, Object> dimensions = <String, Object>{};
-    for (String key in platformDimensions.keys) {
-      dimensions[key] = _parseProperty(key, platformDimensions[key]!);
-    }
-
-    return dimensions;
-  }
-
-  /// Converts property strings to their correct type.
-  ///
-  /// Changes made here should also be made to [_platform_properties] and [_properties] in:
-  ///  * https://cs.opensource.google/flutter/infra/+/main:config/lib/ci_yaml/ci_yaml.star
-  Object _parseProperty(String key, String value) {
-    // Yaml will escape new lines unnecessarily for strings.
-    final List<String> newLineIssues = <String>['android_sdk_license', 'android_sdk_preview_license'];
-    if (value == 'true') {
-      return true;
-    } else if (value == 'false') {
-      return false;
-    } else if (value.startsWith('[') || value.startsWith('{')) {
-      return jsonDecode(value) as Object;
-    } else if (newLineIssues.contains(key)) {
-      return value.replaceAll('\\n', '\n');
-    } else if (int.tryParse(value) != null) {
-      return int.parse(value);
-    }
-
-    return value;
-  }
-
-  /// Get the platform of this [Target].
-  ///
-  /// Platform is extracted as the first word in a target's name.
-  String getPlatform() {
-    return value.name.split(' ').first.toLowerCase();
-  }
-
-  /// Indicates whether this target should be scheduled via batches.
-  ///
-  /// DeviceLab targets are special as they run on a host + physical device, and there is limited
-  /// capacity in the labs to run them. Their platforms contain one of `android`, `ios`, and `samsung`.
-  ///
-  /// Mac host only targets are scheduled via patches due to high queue time. This can be relieved
-  /// when we have capacity support in Q4/2022.
-  bool get shouldBatchSchedule {
-    final String platform = getPlatform();
-    return platform.contains('android') ||
-        platform.contains('ios') ||
-        platform.contains('samsung') ||
-        platform == 'mac';
-  }
-
-  /// Get the associated LUCI bucket to run this [Target] in.
-  String getBucket() {
-    return value.bringup ? 'staging' : 'prod';
-  }
-
-  /// Returns value of ignore_flakiness property.
-  ///
-  /// Returns the value of ignore_flakiness property if
-  /// it has been specified, else default returns false.
-  bool getIgnoreFlakiness() {
-    final Map<String, Object> properties = getProperties();
-    if (properties.containsKey(kIgnoreFlakiness)) {
-      return properties[kIgnoreFlakiness] as bool;
-    }
-    return false;
-  }
-}
-
-/// Representation of a Flutter dependency.
-///
-/// See more:
-///   * https://flutter.googlesource.com/recipes/+/refs/heads/main/recipe_modules/flutter_deps/api.py
-class Dependency {
-  Dependency(this.name, this.version);
-
-  /// Constructor for converting from the flutter_deps format.
-  factory Dependency.fromJson(Object json) {
-    final Map<String, dynamic> map = json as Map<String, dynamic>;
-    return Dependency(map['dependency']! as String, map['version'] as String?);
-  }
-
-  /// Human readable name of the dependency.
-  final String name;
-
-  /// CIPD tag to use.
-  ///
-  /// If null, will use the version set in the flutter_deps recipe_module.
-  final String? version;
-
-  Map<String, Object> toJson() {
-    return <String, Object>{
-      'dependency': name,
-      if (version != null) 'version': version!,
-    };
-  }
-}
diff --git a/app_dart/lib/src/model/common/json_converters.dart b/app_dart/lib/src/model/common/json_converters.dart
deleted file mode 100644
index f10d6ac..0000000
--- a/app_dart/lib/src/model/common/json_converters.dart
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert' hide json;
-import 'dart:convert' as convert show json;
-
-import 'package:json_annotation/json_annotation.dart';
-
-/// A converter for tags.
-///
-/// The JSON format is:
-///
-/// ```json
-/// [
-///   {
-///     "key": "tag_key",
-///     "value": "tag_value"
-///   }
-/// ]
-/// ```
-///
-/// Which is flattened out as a `Map<String, List<String>>`.
-class TagsConverter implements JsonConverter<Map<String?, List<String?>>?, List<dynamic>?> {
-  const TagsConverter();
-
-  @override
-  Map<String?, List<String?>>? fromJson(List<dynamic>? json) {
-    if (json == null) {
-      return null;
-    }
-    final Map<String?, List<String?>> result = <String?, List<String?>>{};
-    for (Map<String, dynamic> tag in json.cast<Map<String, dynamic>>()) {
-      final String? key = tag['key'] as String?;
-      result[key] ??= <String?>[];
-      result[key]!.add(tag['value'] as String?);
-    }
-    return result;
-  }
-
-  @override
-  List<Map<String, dynamic>>? toJson(Map<String?, List<String?>>? object) {
-    if (object == null) {
-      return null;
-    }
-    if (object.isEmpty) {
-      return const <Map<String, List<String>>>[];
-    }
-    final List<Map<String, String>> result = <Map<String, String>>[];
-    for (String? key in object.keys) {
-      if (key == null) {
-        continue;
-      }
-      final List<String?>? values = object[key];
-      if (values == null) {
-        continue;
-      }
-      for (String? value in values) {
-        if (value == null) {
-          continue;
-        }
-        result.add(<String, String>{
-          'key': key,
-          'value': value,
-        });
-      }
-    }
-    return result;
-  }
-}
-
-/// A converter for a "binary" JSON field.
-///
-/// Encodes and decodes a String to and from base64.
-class Base64Converter implements JsonConverter<String, String> {
-  const Base64Converter();
-
-  @override
-  String fromJson(String json) {
-    return utf8.decode(base64.decode(json));
-  }
-
-  @override
-  String toJson(String object) {
-    return base64.encode(utf8.encode(object));
-  }
-}
-
-/// A converter for "timestamp" fields encoded as microseconds since epoch.
-class MicrosecondsSinceEpochConverter implements JsonConverter<DateTime?, String?> {
-  const MicrosecondsSinceEpochConverter();
-
-  @override
-  DateTime? fromJson(String? json) {
-    if (json == null) {
-      return null;
-    }
-    return DateTime.fromMicrosecondsSinceEpoch(int.parse(json));
-  }
-
-  @override
-  String? toJson(DateTime? object) {
-    if (object == null) {
-      return null;
-    }
-    return object.microsecondsSinceEpoch.toString();
-  }
-}
-
-/// A converter for "timestamp" fields encoded as seconds since epoch.
-class SecondsSinceEpochConverter implements JsonConverter<DateTime?, String?> {
-  const SecondsSinceEpochConverter();
-
-  @override
-  DateTime? fromJson(String? json) {
-    if (json == null) {
-      return null;
-    }
-    return DateTime.fromMillisecondsSinceEpoch(int.parse(json) * 1000);
-  }
-
-  @override
-  String? toJson(DateTime? dateTime) {
-    if (dateTime == null) {
-      return null;
-    }
-    final int secondsSinceEpoch = dateTime.millisecondsSinceEpoch ~/ 1000;
-    return secondsSinceEpoch.toString();
-  }
-}
-
-/// A converter for boolean fields encoded as strings.
-class BoolConverter implements JsonConverter<bool?, String?> {
-  const BoolConverter();
-
-  @override
-  bool? fromJson(String? json) {
-    if (json == null) {
-      return null;
-    }
-    return json.toLowerCase() == 'true';
-  }
-
-  @override
-  String? toJson(bool? value) {
-    if (value == null) {
-      return null;
-    }
-    return '$value';
-  }
-}
-
-/// A converter for fields with nested JSON objects in String format.
-class NestedJsonConverter implements JsonConverter<Map<String, dynamic>?, String?> {
-  const NestedJsonConverter();
-
-  @override
-  Map<String, dynamic>? fromJson(String? json) {
-    if (json == null) {
-      return null;
-    }
-    return convert.json.decode(json) as Map<String, dynamic>?;
-  }
-
-  @override
-  String? toJson(Map<String, dynamic>? object) {
-    if (object == null) {
-      return null;
-    }
-    return convert.json.encode(object);
-  }
-}
-
-const Map<String, int> _months = <String, int>{
-  'Jan': 1,
-  'Feb': 2,
-  'Mar': 3,
-  'Apr': 4,
-  'May': 5,
-  'Jun': 6,
-  'Jul': 7,
-  'Aug': 8,
-  'Sep': 9,
-  'Oct': 10,
-  'Nov': 11,
-  'Dec': 12,
-};
-
-/// Convert a DateTime format from Gerrit to [DateTime].
-///
-/// Example format is "Wed Jun 07 22:54:06 2023 +0000"
-class GerritDateTimeConverter implements JsonConverter<DateTime?, String?> {
-  const GerritDateTimeConverter();
-
-  @override
-  DateTime? fromJson(String? json) {
-    if (json == null) {
-      return null;
-    }
-
-    final DateTime? date = DateTime.tryParse(json);
-    if (date != null) {
-      return date;
-    }
-
-    json = json.substring(4); // Trim day of the week
-    final List<String> parts = json.split(' ');
-    final int month = _months[parts[0]]!;
-    final int year = int.parse(parts[3]);
-    final int day = int.parse(parts[1]);
-    final List<String> time = parts[2].split(':');
-    final int hours = int.parse(time[0]);
-    final int minutes = int.parse(time[1]);
-    final int seconds = int.parse(time[2]);
-
-    return DateTime(year, month, day, hours, minutes, seconds);
-  }
-
-  @override
-  String? toJson(DateTime? object) {
-    return object?.toIso8601String();
-  }
-}
diff --git a/app_dart/lib/src/model/gerrit/commit.dart b/app_dart/lib/src/model/gerrit/commit.dart
deleted file mode 100644
index 9b3a16c..0000000
--- a/app_dart/lib/src/model/gerrit/commit.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-
-import 'package:cocoon_service/src/model/common/json_converters.dart';
-import 'package:json_annotation/json_annotation.dart';
-
-import '../../request_handling/body.dart';
-
-part 'commit.g.dart';
-
-/// Representation of a commit on Gerrit.
-///
-/// See more:
-///   * https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#commit-info
-@JsonSerializable()
-class GerritCommit extends JsonBody {
-  const GerritCommit({
-    this.commit,
-    this.tree,
-    this.author,
-    this.committer,
-    this.message,
-  });
-
-  static GerritCommit fromJson(Map<String, dynamic> json) => _$GerritCommitFromJson(json);
-
-  final String? commit;
-  final String? tree;
-  final GerritUser? author;
-  final GerritUser? committer;
-  final String? message;
-
-  @override
-  Map<String, dynamic> toJson() => _$GerritCommitToJson(this);
-
-  @override
-  String toString() => jsonEncode(toJson());
-}
-
-/// Gerrit info containing the author/comitter of a commit.
-///
-/// See more:
-///   * https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#git-person-info
-@JsonSerializable()
-class GerritUser extends JsonBody {
-  const GerritUser({
-    this.name,
-    this.email,
-    this.time,
-  });
-
-  static GerritUser fromJson(Map<String, dynamic> json) => _$GerritUserFromJson(json);
-
-  final String? name;
-  final String? email;
-
-  @GerritDateTimeConverter()
-  final DateTime? time;
-
-  @override
-  Map<String, dynamic> toJson() => _$GerritUserToJson(this);
-
-  @override
-  String toString() => jsonEncode(toJson());
-}
diff --git a/app_dart/lib/src/model/gerrit/commit.g.dart b/app_dart/lib/src/model/gerrit/commit.g.dart
deleted file mode 100644
index a12615d..0000000
--- a/app_dart/lib/src/model/gerrit/commit.g.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-// ignore_for_file: always_specify_types, implicit_dynamic_parameter
-
-part of 'commit.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-GerritCommit _$GerritCommitFromJson(Map<String, dynamic> json) => GerritCommit(
-      commit: json['commit'] as String?,
-      tree: json['tree'] as String?,
-      author: json['author'] == null ? null : GerritUser.fromJson(json['author'] as Map<String, dynamic>),
-      committer: json['committer'] == null ? null : GerritUser.fromJson(json['committer'] as Map<String, dynamic>),
-      message: json['message'] as String?,
-    );
-
-Map<String, dynamic> _$GerritCommitToJson(GerritCommit instance) => <String, dynamic>{
-      'commit': instance.commit,
-      'tree': instance.tree,
-      'author': instance.author,
-      'committer': instance.committer,
-      'message': instance.message,
-    };
-
-GerritUser _$GerritUserFromJson(Map<String, dynamic> json) => GerritUser(
-      name: json['name'] as String?,
-      email: json['email'] as String?,
-      time: const GerritDateTimeConverter().fromJson(json['time'] as String?),
-    );
-
-Map<String, dynamic> _$GerritUserToJson(GerritUser instance) => <String, dynamic>{
-      'name': instance.name,
-      'email': instance.email,
-      'time': const GerritDateTimeConverter().toJson(instance.time),
-    };
diff --git a/app_dart/lib/src/model/github/checks.dart b/app_dart/lib/src/model/github/checks.dart
deleted file mode 100644
index 8bd4f3e..0000000
--- a/app_dart/lib/src/model/github/checks.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2020 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:github/github.dart' show CheckSuite, PullRequest, User, Repository;
-import 'package:github/hooks.dart' show HookEvent;
-import 'package:json_annotation/json_annotation.dart';
-
-part 'checks.g.dart';
-
-/// Data models for json messages coming from GitHub Checks API.
-///
-/// See more:
-///  * https://developer.com/v3/checks/.
-@JsonSerializable(fieldRename: FieldRename.snake)
-class CheckRunEvent extends HookEvent {
-  CheckRunEvent({
-    this.action,
-    this.checkRun,
-    this.sender,
-    this.repository,
-  });
-
-  factory CheckRunEvent.fromJson(Map<String, dynamic> input) => _$CheckRunEventFromJson(input);
-  CheckRun? checkRun;
-  String? action;
-  User? sender;
-  Repository? repository;
-
-  Map<String, dynamic> toJson() => _$CheckRunEventToJson(this);
-}
-
-@JsonSerializable(fieldRename: FieldRename.snake)
-class CheckRun {
-  const CheckRun({
-    this.conclusion,
-    this.headSha,
-    this.id,
-    this.pullRequests,
-    this.name,
-    this.checkSuite,
-  });
-
-  factory CheckRun.fromJson(Map<String, dynamic> input) => _$CheckRunFromJson(input);
-  final int? id;
-  final String? headSha;
-  final String? conclusion;
-  final String? name;
-  final CheckSuite? checkSuite;
-  @JsonKey(name: 'pull_requests', defaultValue: <PullRequest>[])
-  final List<PullRequest>? pullRequests;
-
-  Map<String, dynamic> toJson() => _$CheckRunToJson(this);
-}
diff --git a/app_dart/lib/src/model/github/checks.g.dart b/app_dart/lib/src/model/github/checks.g.dart
deleted file mode 100644
index 1c80026..0000000
--- a/app_dart/lib/src/model/github/checks.g.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-// ignore_for_file: always_specify_types, implicit_dynamic_parameter
-
-part of 'checks.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-CheckRunEvent _$CheckRunEventFromJson(Map<String, dynamic> json) => CheckRunEvent(
-      action: json['action'] as String?,
-      checkRun: json['check_run'] == null ? null : CheckRun.fromJson(json['check_run'] as Map<String, dynamic>),
-      sender: json['sender'] == null ? null : User.fromJson(json['sender'] as Map<String, dynamic>),
-      repository: json['repository'] == null ? null : Repository.fromJson(json['repository'] as Map<String, dynamic>),
-    );
-
-Map<String, dynamic> _$CheckRunEventToJson(CheckRunEvent instance) => <String, dynamic>{
-      'check_run': instance.checkRun,
-      'action': instance.action,
-      'sender': instance.sender,
-      'repository': instance.repository,
-    };
-
-CheckRun _$CheckRunFromJson(Map<String, dynamic> json) => CheckRun(
-      conclusion: json['conclusion'] as String?,
-      headSha: json['head_sha'] as String?,
-      id: json['id'] as int?,
-      pullRequests: (json['pull_requests'] as List<dynamic>?)
-              ?.map((e) => PullRequest.fromJson(e as Map<String, dynamic>))
-              .toList() ??
-          [],
-      name: json['name'] as String?,
-      checkSuite: json['check_suite'] == null ? null : CheckSuite.fromJson(json['check_suite'] as Map<String, dynamic>),
-    );
-
-Map<String, dynamic> _$CheckRunToJson(CheckRun instance) => <String, dynamic>{
-      'id': instance.id,
-      'head_sha': instance.headSha,
-      'conclusion': instance.conclusion,
-      'name': instance.name,
-      'check_suite': instance.checkSuite,
-      'pull_requests': instance.pullRequests,
-    };
diff --git a/app_dart/lib/src/model/google/grpc.dart b/app_dart/lib/src/model/google/grpc.dart
deleted file mode 100644
index c3593eb..0000000
--- a/app_dart/lib/src/model/google/grpc.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:json_annotation/json_annotation.dart';
-
-import '../../request_handling/body.dart';
-
-part 'grpc.g.dart';
-
-/// [Status] defines a logical error model that is suitable for
-/// different programming environments, including REST APIs and RPC APIs. It is
-/// used by [gRPC](https://github.com/grpc). Each [Status] message contains
-/// three pieces of data: error code, error message, and error details.
-///
-/// Resources:
-/// * https://cloud.google.com/apis/design/errors
-@JsonSerializable(includeIfNull: false)
-class GrpcStatus extends JsonBody {
-  const GrpcStatus({required this.code, this.message, this.details});
-
-  /// Creates a [Status] from JSON.
-  static GrpcStatus fromJson(Map<String, dynamic> json) => _$GrpcStatusFromJson(json);
-
-  /// The status code, which should be an enum value of [google.rpc.Code][].
-  final int code;
-
-  /// A developer-facing error message, which should be in English. Any
-  /// user-facing error message should be localized and sent in the
-  /// [google.rpc.Status.details][] field, or localized by the client.
-  final String? message;
-
-  /// A list of messages that carry the error details.  There is a common set of
-  /// message types for APIs to use.
-  final dynamic details;
-
-  @override
-  String toString() => 'Response #$code: $message, $details';
-
-  @override
-  Map<String, dynamic> toJson() => _$GrpcStatusToJson(this);
-}
diff --git a/app_dart/lib/src/model/google/grpc.g.dart b/app_dart/lib/src/model/google/grpc.g.dart
deleted file mode 100644
index a690c98..0000000
--- a/app_dart/lib/src/model/google/grpc.g.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-// ignore_for_file: always_specify_types, implicit_dynamic_parameter
-
-part of 'grpc.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-GrpcStatus _$GrpcStatusFromJson(Map<String, dynamic> json) => GrpcStatus(
-      code: json['code'] as int,
-      message: json['message'] as String?,
-      details: json['details'],
-    );
-
-Map<String, dynamic> _$GrpcStatusToJson(GrpcStatus instance) {
-  final val = <String, dynamic>{
-    'code': instance.code,
-  };
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('message', instance.message);
-  writeNotNull('details', instance.details);
-  return val;
-}
diff --git a/app_dart/lib/src/model/google/token_info.dart b/app_dart/lib/src/model/google/token_info.dart
deleted file mode 100644
index 6406699..0000000
--- a/app_dart/lib/src/model/google/token_info.dart
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:json_annotation/json_annotation.dart';
-
-import '../common/json_converters.dart';
-
-part 'token_info.g.dart';
-
-@JsonSerializable()
-class TokenInfo {
-  /// Creates a new [TokenInfo].
-  const TokenInfo({
-    this.issuer,
-    this.authorizedParty,
-    this.audience,
-    this.subject,
-    this.hostedDomain,
-    this.email,
-    this.emailIsVerified,
-    this.accessTokenHash,
-    this.fullName,
-    this.profilePictureUrl,
-    this.givenName,
-    this.familyName,
-    this.locale,
-    this.issued,
-    this.expiration,
-    this.jwtId,
-    this.algorithm,
-    this.keyId,
-    this.encoding,
-  });
-
-  /// Create a new [TokenInfo] object from its JSON representation.
-  factory TokenInfo.fromJson(Map<String, dynamic> json) => _$TokenInfoFromJson(json);
-
-  /// The issuer of the token (e.g. "accounts.google.com").
-  @JsonKey(name: 'iss')
-  final String? issuer;
-
-  /// The party to which the ID Token was issued.
-  @JsonKey(name: 'azp')
-  final String? authorizedParty;
-
-  /// The token's intended audience.
-  ///
-  /// This should be compared against the expected OAuth client ID.
-  @JsonKey(name: 'aud')
-  final String? audience;
-
-  /// The principal (subject) of the token.
-  @JsonKey(name: 'sub')
-  final String? subject;
-
-  /// The user's domain.
-  ///
-  /// https://developers.google.com/identity/protocols/OpenIDConnect#hd-param
-  @JsonKey(name: 'hd')
-  final String? hostedDomain;
-
-  /// The user's email address.
-  @JsonKey(name: 'email')
-  final String? email;
-
-  /// Boolean indicating whether the user has verified their email address.
-  @JsonKey(name: 'email_verified')
-  @BoolConverter()
-  final bool? emailIsVerified;
-
-  /// Access token hash value.
-  @JsonKey(name: 'at_hash')
-  final String? accessTokenHash;
-
-  /// The user's full name.
-  @JsonKey(name: 'name')
-  final String? fullName;
-
-  /// URL of the user's profile picture.
-  @JsonKey(name: 'picture')
-  final String? profilePictureUrl;
-
-  /// The user's given name.
-  @JsonKey(name: 'given_name')
-  final String? givenName;
-
-  /// The user's family name / surname.
-  @JsonKey(name: 'family_name')
-  final String? familyName;
-
-  /// The user's local code (e.g. "en")
-  @JsonKey(name: 'locale')
-  final String? locale;
-
-  /// Token issuance date.
-  @JsonKey(name: 'iat')
-  @SecondsSinceEpochConverter()
-  final DateTime? issued;
-
-  /// Token expiration.
-  @JsonKey(name: 'exp')
-  @SecondsSinceEpochConverter()
-  final DateTime? expiration;
-
-  /// Unique identifier for the token itself.
-  @JsonKey(name: 'jti')
-  final String? jwtId;
-
-  /// Encryption algorithm used to encrypt the token (e.g. "RS256").
-  @JsonKey(name: 'alg')
-  final String? algorithm;
-
-  /// Key identifier.
-  @JsonKey(name: 'kid')
-  final String? keyId;
-
-  /// The encoding that was used to encode the unverified token (e.g. "JWT")
-  @JsonKey(name: 'typ')
-  final String? encoding;
-
-  /// Serializes this object to a JSON primitive.
-  Map<String, dynamic> toJson() => _$TokenInfoToJson(this);
-}
diff --git a/app_dart/lib/src/model/google/token_info.g.dart b/app_dart/lib/src/model/google/token_info.g.dart
deleted file mode 100644
index 9d8de29..0000000
--- a/app_dart/lib/src/model/google/token_info.g.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-// ignore_for_file: always_specify_types, implicit_dynamic_parameter
-
-part of 'token_info.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-TokenInfo _$TokenInfoFromJson(Map<String, dynamic> json) => TokenInfo(
-      issuer: json['iss'] as String?,
-      authorizedParty: json['azp'] as String?,
-      audience: json['aud'] as String?,
-      subject: json['sub'] as String?,
-      hostedDomain: json['hd'] as String?,
-      email: json['email'] as String?,
-      emailIsVerified: const BoolConverter().fromJson(json['email_verified'] as String?),
-      accessTokenHash: json['at_hash'] as String?,
-      fullName: json['name'] as String?,
-      profilePictureUrl: json['picture'] as String?,
-      givenName: json['given_name'] as String?,
-      familyName: json['family_name'] as String?,
-      locale: json['locale'] as String?,
-      issued: const SecondsSinceEpochConverter().fromJson(json['iat'] as String?),
-      expiration: const SecondsSinceEpochConverter().fromJson(json['exp'] as String?),
-      jwtId: json['jti'] as String?,
-      algorithm: json['alg'] as String?,
-      keyId: json['kid'] as String?,
-      encoding: json['typ'] as String?,
-    );
-
-Map<String, dynamic> _$TokenInfoToJson(TokenInfo instance) => <String, dynamic>{
-      'iss': instance.issuer,
-      'azp': instance.authorizedParty,
-      'aud': instance.audience,
-      'sub': instance.subject,
-      'hd': instance.hostedDomain,
-      'email': instance.email,
-      'email_verified': const BoolConverter().toJson(instance.emailIsVerified),
-      'at_hash': instance.accessTokenHash,
-      'name': instance.fullName,
-      'picture': instance.profilePictureUrl,
-      'given_name': instance.givenName,
-      'family_name': instance.familyName,
-      'locale': instance.locale,
-      'iat': const SecondsSinceEpochConverter().toJson(instance.issued),
-      'exp': const SecondsSinceEpochConverter().toJson(instance.expiration),
-      'jti': instance.jwtId,
-      'alg': instance.algorithm,
-      'kid': instance.keyId,
-      'typ': instance.encoding,
-    };
diff --git a/app_dart/lib/src/model/luci/buildbucket.dart b/app_dart/lib/src/model/luci/buildbucket.dart
deleted file mode 100644
index 903639e..0000000
--- a/app_dart/lib/src/model/luci/buildbucket.dart
+++ /dev/null
@@ -1,928 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:json_annotation/json_annotation.dart';
-
-import '../../request_handling/body.dart';
-import '../common/json_converters.dart';
-import '../google/grpc.dart';
-
-part 'buildbucket.g.dart';
-
-// The classes in this file are based on protos found in:
-// https://chromium.googlesource.com/infra/luci/luci-go/+/master/buildbucket/proto/build.proto
-// https://chromium.googlesource.com/infra/luci/luci-go/+/master/buildbucket/proto/common.proto
-// https://chromium.googlesource.com/infra/luci/luci-go/+/master/buildbucket/proto/rpc.proto
-//
-// The `fromJson` methods in this class are static rather than factories so that
-// they can be passed as arguments to other functions looking for a parser.
-
-/// A request for the Batch RPC.
-///
-/// This message can be used to find, get, schedule, or cancel multiple builds.
-@JsonSerializable(includeIfNull: false)
-class BatchRequest extends JsonBody {
-  /// Creates a request for the Batch RPC.
-  const BatchRequest({
-    this.requests,
-  });
-
-  /// Creates a [BatchRequest] from JSON.
-  static BatchRequest fromJson(Map<String, dynamic> json) => _$BatchRequestFromJson(json);
-
-  /// The batch of [Request]s to make.
-  final List<Request>? requests;
-
-  @override
-  Map<String, dynamic> toJson() => _$BatchRequestToJson(this);
-
-  @override
-  String toString() {
-    return requests.toString();
-  }
-}
-
-/// A container for one request in a batch.
-///
-/// A single request must contain only one object.
-@JsonSerializable(includeIfNull: false)
-class Request extends JsonBody {
-  /// Creates a request for the Batch RPC.
-  ///
-  /// One and only one argument should be set.
-  const Request({
-    this.getBuild,
-    this.searchBuilds,
-    this.scheduleBuild,
-    this.cancelBuild,
-  }) : assert(
-          (getBuild != null && searchBuilds == null && scheduleBuild == null && cancelBuild == null) ||
-              (getBuild == null && searchBuilds != null && scheduleBuild == null && cancelBuild == null) ||
-              (getBuild == null && searchBuilds == null && scheduleBuild != null && cancelBuild == null) ||
-              (getBuild == null && searchBuilds == null && scheduleBuild == null && cancelBuild != null),
-        );
-
-  /// Creates a [Request] object from JSON.
-  static Request fromJson(Map<String, dynamic> json) => _$RequestFromJson(json);
-
-  /// A request to get build information.
-  final GetBuildRequest? getBuild;
-
-  /// A request to find builds.
-  final SearchBuildsRequest? searchBuilds;
-
-  /// A request to schedule a build.
-  ///
-  /// All schedule build requests are executed before other requests by LUCI.
-  final ScheduleBuildRequest? scheduleBuild;
-
-  /// A request to cancel a build.
-  final CancelBuildRequest? cancelBuild;
-
-  @override
-  Map<String, dynamic> toJson() => _$RequestToJson(this);
-
-  @override
-  String toString() {
-    return getBuild?.toString() ??
-        searchBuilds?.toString() ??
-        scheduleBuild?.toString() ??
-        cancelBuild?.toString() ??
-        'Unknown build';
-  }
-}
-
-/// A response from the Batch RPC.
-@JsonSerializable(includeIfNull: false)
-class BatchResponse extends JsonBody {
-  /// Creates a response for the Batch RPC.
-  const BatchResponse({
-    this.responses,
-  });
-
-  /// Creates a [BatchResponse] from JSON.
-  static BatchResponse fromJson(Map<String, dynamic>? json) => _$BatchResponseFromJson(json!);
-
-  /// The collected responses from the Batch request.
-  final List<Response>? responses;
-
-  @override
-  Map<String, dynamic> toJson() => _$BatchResponseToJson(this);
-}
-
-/// An individual response from a batch request.
-@JsonSerializable(includeIfNull: false)
-class Response extends JsonBody {
-  /// Creates a response for the response from the Batch RPC.
-  ///
-  /// One and only one of these should be set.
-  const Response({
-    this.getBuild,
-    this.searchBuilds,
-    this.scheduleBuild,
-    this.cancelBuild,
-    this.error,
-  }) : assert(
-          getBuild != null || searchBuilds != null || scheduleBuild != null || cancelBuild != null || error != null,
-        );
-
-  /// Creates a [Response] from JSON.
-  static Response fromJson(Map<String, dynamic> json) => _$ResponseFromJson(json);
-
-  /// The [Build] response corresponding to a getBuild request.
-  final Build? getBuild;
-
-  /// The [SearchBuildsResponse] corresponding to a searchBuilds request.
-  final SearchBuildsResponse? searchBuilds;
-
-  /// The [Build] response corresponding to a scheduleBuild request.
-  final Build? scheduleBuild;
-
-  /// The [Build] response corresponding to a cancelBuild request.
-  final Build? cancelBuild;
-
-  /// Error code of the unsuccessful request.
-  final GrpcStatus? error;
-
-  @override
-  String toString() {
-    if (getBuild != null) {
-      return 'getBuild: $getBuild; status: $error';
-    } else if (searchBuilds != null) {
-      return 'searchBuilds: $searchBuilds; status: $error';
-    } else if (scheduleBuild != null) {
-      return 'scheduleBuild: $scheduleBuild; status: $error';
-    } else if (cancelBuild != null) {
-      return 'cancelBuild: $cancelBuild; status: $error';
-    }
-
-    return 'No response';
-  }
-
-  @override
-  Map<String, dynamic> toJson() => _$ResponseToJson(this);
-}
-
-/// A request for the GetBuild RPC.
-@JsonSerializable(includeIfNull: false)
-class GetBuildRequest extends JsonBody {
-  /// Creates a request for the GetBuild RPC.
-  const GetBuildRequest({
-    this.id,
-    this.builderId,
-    this.buildNumber,
-    this.fields,
-  }) : assert(
-          (id == null && builderId != null && buildNumber != null) ||
-              (id != null && builderId == null && buildNumber == null),
-        );
-
-  /// Creates a [GetBuildRequest] from JSON.
-  static GetBuildRequest fromJson(Map<String, dynamic> json) => _$GetBuildRequestFromJson(json);
-
-  /// The BuildBucket build ID.
-  ///
-  /// If specified, [builderId] and [buildNumber] must be null.
-  final String? id;
-
-  /// The BuildBucket [BuilderId].
-  ///
-  /// If specified, [buildNumber] must be specified, and [id] must be null.
-  @JsonKey(name: 'builder')
-  final BuilderId? builderId;
-
-  /// The BuildBucket build number.
-  ///
-  /// If specified, [builderId] must be specified, and [id] must be null.
-  final int? buildNumber;
-
-  /// The list fields to be included in the response.
-  ///
-  /// This is a comma separated list of Build proto fields to get included
-  /// in the response.
-  final String? fields;
-
-  @override
-  Map<String, dynamic> toJson() => _$GetBuildRequestToJson(this);
-
-  @override
-  String toString() {
-    return 'getBuild(id: $id, buildNumber: $buildNumber, field: $fields, builderId: $builderId)';
-  }
-}
-
-/// A request for the GetBuilder RPC.
-@JsonSerializable(includeIfNull: false)
-class GetBuilderRequest extends JsonBody {
-  /// Creates a request for the GetBuild RPC.
-  const GetBuilderRequest({
-    this.builderId,
-  }) : assert(builderId != null);
-
-  /// Creates a [GetBuilderRequest] from JSON.
-  static GetBuilderRequest fromJson(Map<String, dynamic> json) => _$GetBuilderRequestFromJson(json);
-
-  /// The BuildBucket builder ID.
-  final BuilderId? builderId;
-
-  @override
-  Map<String, dynamic> toJson() => _$GetBuilderRequestToJson(this);
-
-  @override
-  String toString() {
-    return 'getBuild(builderId: $builderId)';
-  }
-}
-
-/// Configs of a builder.
-@JsonSerializable(includeIfNull: false)
-class BuilderConfig extends JsonBody {
-  /// Creates a request for the GetBuild RPC.
-  const BuilderConfig({
-    this.name,
-  }) : assert(name != null);
-
-  /// Creates a [GetBuilderRequest] from JSON.
-  static BuilderConfig fromJson(Map<String, dynamic> json) => _$BuilderConfigFromJson(json);
-
-  /// The BuildBucket builder ID.
-  final String? name;
-
-  @override
-  Map<String, dynamic> toJson() => _$BuilderConfigToJson(this);
-
-  @override
-  String toString() {
-    return 'BuilderConfig(name: $name)';
-  }
-}
-
-/// A configured builder.
-///
-/// https://chromium.googlesource.com/infra/luci/luci-go/+/main/buildbucket/proto/builder_common.proto
-@JsonSerializable(includeIfNull: false)
-class BuilderItem extends JsonBody {
-  /// Creates a request for the GetBuild RPC.
-  const BuilderItem({
-    this.id,
-    this.config,
-  });
-
-  /// Creates a [GetBuilderRequest] from JSON.
-  static BuilderItem fromJson(Map<String, dynamic>? json) => _$BuilderItemFromJson(json!);
-
-  /// The BuildBucket builder ID.
-  final BuilderId? id;
-
-  /// The BuildBucket builder config.
-  final BuilderConfig? config;
-
-  @override
-  Map<String, dynamic> toJson() => _$BuilderItemToJson(this);
-
-  @override
-  String toString() {
-    return 'BuilderItem(builderID: $id, builderConfig: $config)';
-  }
-}
-
-/// A requrst for the ListBuilders RPC.
-@JsonSerializable(includeIfNull: false)
-class ListBuildersRequest extends JsonBody {
-  /// Creates a request object for the ListBuilders RPC.
-  const ListBuildersRequest({
-    required this.project,
-    this.bucket,
-    this.pageSize = 1000,
-    this.pageToken,
-  });
-
-  /// Creates a [ListBuildersRequest] from JSON.
-  static ListBuildersRequest fromJson(Map<String, dynamic> json) => _$ListBuildersRequestFromJson(json);
-
-  /// LUCI project, e.g. "flutter".
-  @JsonKey(required: true)
-  final String project;
-
-  /// A bucket in the project, e.g. "prod".
-  ///
-  /// Omit to list all builders or all builders in a project.
-  @JsonKey(required: false)
-  final String? bucket;
-
-  /// The maximum number of builders to return.
-  ///
-  /// The service may return fewer than this value.
-  /// If unspecified, at most 100 builders will be returned.
-  /// The maximum value is 1000; values above 1000 will be coerced to 1000.
-  @JsonKey(required: false)
-  final int? pageSize;
-
-  // A page token, received from a previous `ListBuilders` call.
-  // Provide this to retrieve the subsequent page.
-  //
-  // When paginating, all other parameters provided to `ListBuilders` MUST
-  // match the call that provided the page token.
-  @JsonKey(required: false)
-  final String? pageToken;
-
-  @override
-  Map<String, dynamic> toJson() => _$ListBuildersRequestToJson(this);
-
-  @override
-  String toString() {
-    return 'listBuilders(project: $project, bucket: $bucket, pageSize: $pageSize, pageToken: $pageToken)';
-  }
-}
-
-/// The response object from a ListBuilders RPC.
-@JsonSerializable(includeIfNull: false)
-class ListBuildersResponse extends JsonBody {
-  /// Creates a new response object from the ListBuilders RPC.
-  ///
-  /// The [nextPageToken] can be used to coninue searching if there are more
-  /// builds available than the [pageSize] of the request (which is always
-  /// capped at 1000). It will be null if no further builders are available.
-  const ListBuildersResponse({
-    this.builders,
-    this.nextPageToken,
-  });
-
-  /// Creates a [ListBuildersResponse] from JSON.
-  static ListBuildersResponse fromJson(Map<String, dynamic>? json) => _$ListBuildersResponseFromJson(json!);
-
-  /// The [Builders]s returned by the search.
-  final List<BuilderItem>? builders;
-
-  /// A token that can be used as the [ListBuildersRequest.pageToken].
-  ///
-  /// This value will only be specified if further results are available;
-  /// otherwise, it will be null.
-  final String? nextPageToken;
-
-  @override
-  Map<String, dynamic> toJson() => _$ListBuildersResponseToJson(this);
-
-  @override
-  String toString() => builders.toString();
-}
-
-/// A request for the CancelBuild RPC.
-@JsonSerializable(includeIfNull: false)
-class CancelBuildRequest extends JsonBody {
-  /// Creates a request object for the CancelBuild RPC.
-  ///
-  /// Both [id] and [summaryMarkdown] are required.
-  const CancelBuildRequest({
-    required this.id,
-    required this.summaryMarkdown,
-  });
-
-  /// Creates a [CancelBuildRequest] from JSON.
-  static CancelBuildRequest fromJson(Map<String, dynamic> json) => _$CancelBuildRequestFromJson(json);
-
-  /// The BuildBucket ID for the build to cancel.
-  @JsonKey(required: true)
-  final String id;
-
-  /// A summary of the reason for canceling.
-  @JsonKey(required: true)
-  final String summaryMarkdown;
-
-  @override
-  Map<String, dynamic> toJson() => _$CancelBuildRequestToJson(this);
-
-  @override
-  String toString() {
-    return 'cancelBuild(id: $id, summaryMarkdown: $summaryMarkdown)';
-  }
-}
-
-/// A request object for the SearchBuilds RPC.
-@JsonSerializable(includeIfNull: false)
-class SearchBuildsRequest extends JsonBody {
-  /// Creates a request object for the SearchBuilds RPC.
-  ///
-  /// The [predicate] is required.
-  ///
-  /// The [pageSize] defaults to 100 if not specified.
-  ///
-  /// The [pageToken] from a previous request can be used to page through
-  /// results.
-  const SearchBuildsRequest({
-    required this.predicate,
-    this.pageSize,
-    this.pageToken,
-    this.fields,
-  });
-
-  /// Creates a [SearchBuildsReqeuest] object from JSON.
-  static SearchBuildsRequest fromJson(Map<String, dynamic> json) => _$SearchBuildsRequestFromJson(json);
-
-  /// The predicate for searching.
-  final BuildPredicate predicate;
-
-  /// The number of builds to return per request.  Defaults to 100.
-  ///
-  /// Any value over 1000 is treated as 1000.
-  final int? pageSize;
-
-  /// The value of the [SearchBuildsResponse.nextPageToken] from a previous ]
-  /// request.
-  ///
-  /// This can be used to continue paging through results when there are more
-  /// than [pageSize] builds available.
-  final String? pageToken;
-
-  /// The list fields to be included in the response.
-  ///
-  /// This is a comma separated list of Build proto fields to get included
-  /// in the response.
-  final String? fields;
-
-  @override
-  Map<String, dynamic> toJson() => _$SearchBuildsRequestToJson(this);
-
-  @override
-  String toString() {
-    return 'searchBuild(predicate: $predicate, pageSize: $pageSize, pageToken: $pageToken, fields: $fields)';
-  }
-}
-
-/// A predicate to apply when searching for builds in the SearchBuilds RPC.
-@JsonSerializable(includeIfNull: false)
-class BuildPredicate extends JsonBody {
-  /// Creates a predicate to apply when searching for builds in the SearchBuilds
-  /// RPC.
-  ///
-  /// All items specified must match for the predicate to return.
-  const BuildPredicate({
-    this.builderId,
-    this.status,
-    this.createdBy,
-    this.tags,
-    this.includeExperimental,
-  });
-
-  /// Creates a [BuildPredicate] from JSON.
-  static BuildPredicate fromJson(Map<String, dynamic> json) => _$BuildPredicateFromJson(json);
-
-  /// The [BuilderId] to search for.
-  @JsonKey(name: 'builder')
-  final BuilderId? builderId;
-
-  /// The [Status] to search for.
-  final Status? status;
-
-  /// Used to find builds created by the specified user.
-  final String? createdBy;
-
-  /// Used to return builds containing all of the specified tags.
-  @TagsConverter()
-  final Map<String?, List<String?>>? tags;
-
-  /// Determines whether to include experimental builds in the result.
-  ///
-  /// Defaults to false.
-  final bool? includeExperimental;
-
-  @override
-  Map<String, dynamic> toJson() => _$BuildPredicateToJson(this);
-
-  @override
-  String toString() {
-    return 'buildPredicate(builderId: $builderId, status: $status, createdBy: $createdBy, tags: $tags, includeExperimental: $includeExperimental)';
-  }
-}
-
-/// The response object from a SearchBuilds RPC.
-@JsonSerializable(includeIfNull: false)
-class SearchBuildsResponse extends JsonBody {
-  /// Creates a new response object from the SearchBuilds RPC.
-  ///
-  /// The [nextPageToken] can be used to coninue searching if there are more
-  /// builds available than the [pageSize] of the request (which is always
-  /// capped at 1000). It will be null if no further builds are available.
-  const SearchBuildsResponse({
-    this.builds,
-    this.nextPageToken,
-  });
-
-  /// Creates a [SearchBuildsResponse] from JSON.
-  static SearchBuildsResponse fromJson(Map<String, dynamic>? json) => _$SearchBuildsResponseFromJson(json!);
-
-  /// The [Build]s returned by the search.
-  final List<Build>? builds;
-
-  /// A token that can be used as the [SearchBuildsRequest.pageToken].
-  ///
-  /// This value will only be specified if further results are available;
-  /// otherwise, it will be null.
-  final String? nextPageToken;
-
-  @override
-  Map<String, dynamic> toJson() => _$SearchBuildsResponseToJson(this);
-
-  @override
-  String toString() => builds.toString();
-}
-
-/// A request object for the ScheduleBuild RPC.
-@JsonSerializable(includeIfNull: false)
-class ScheduleBuildRequest extends JsonBody {
-  /// Creates a new request object for the ScheduleBuild RPC.
-  ///
-  /// The [requestId] is "strongly recommended", and is used by the back end to
-  /// deduplicate recent requests.
-  ///
-  /// The [builderId] is required.
-  const ScheduleBuildRequest({
-    this.requestId,
-    required this.builderId,
-    this.canary,
-    this.experimental,
-    this.gitilesCommit,
-    this.properties,
-    this.dimensions,
-    this.priority,
-    this.tags,
-    this.notify,
-    this.fields,
-    this.exe,
-  });
-
-  /// Creates a [ScheduleBuildRequest] from JSON.
-  static ScheduleBuildRequest fromJson(Map<String, dynamic> json) => _$ScheduleBuildRequestFromJson(json);
-
-  /// A unique identifier per request that is used by the backend to deduplicate
-  /// requests.
-  ///
-  /// This is "strongly recommended", but not required.
-  final String? requestId;
-
-  /// The [BuilderId] to schedule on. Required.
-  @JsonKey(name: 'builder')
-  final BuilderId builderId;
-
-  /// If specified, overrides the server-defined value of
-  /// Build.infra.buildbucket.canary.
-  final bool? canary;
-
-  /// If specified, overrides the server-defined value of
-  /// Build.input.experimental.
-  ///
-  /// This value comes into the recipe as `api.runtime.is_experimental`.
-  final Trinary? experimental;
-
-  /// Properties to include in Build.input.properties.
-  /// Input properties of the created build are result of merging server-defined
-  /// properties and properties in this field.
-  /// Each property in this field defines a new or replaces an existing property
-  /// on the server.
-  /// If the server config does not allow overriding/adding the property, the
-  /// request will fail with InvalidArgument error code.
-  /// A server-defined property cannot be removed, but its value can be
-  /// replaced with null.
-  ///
-  /// Reserved property paths:
-  /// * ["buildbucket"]
-  /// * ["buildername"]
-  /// * ["blamelist""]
-  /// * ["$recipe_engine/runtime", "is_luci"]
-  /// * ["$recipe_engine/runtime", "is_experimental"]
-  final Map<String, Object>? properties;
-
-  /// The value for Build.input.gitiles_commit.
-  ///
-  /// Setting this field will cause the created build to have a "buildset"
-  /// tag with value "commit/gitiles/{hostname}/{project}/+/{id}".
-  ///
-  /// GitilesCommit objects MUST have host, project, ref fields set.
-  final GitilesCommit? gitilesCommit;
-
-  /// Tags to include in Build.tags of the created build.
-  ///
-  /// Note: tags of the created build may include other tags defined on the
-  /// server.
-  @TagsConverter()
-  final Map<String?, List<String?>>? tags;
-
-  /// Overrides default dimensions defined by builder config or template build.
-  ///
-  /// A set of entries with the same key defines a new or replaces an existing
-  /// dimension with the same key.
-  final List<RequestedDimension>? dimensions;
-
-  // If not zero, overrides swarming task priority.
-  // See also Build.infra.swarming.priority.
-  final int? priority;
-
-  /// The topic and user data to send build status updates to.
-  final NotificationConfig? notify;
-
-  /// The list fields to be included in the response.
-  ///
-  /// This is a comma separated list of Build proto fields to get included
-  /// in the response.
-  final String? fields;
-
-  /// The CIPD package with the recipes.
-  final Map<String, dynamic>? exe;
-
-  @override
-  Map<String, dynamic> toJson() => _$ScheduleBuildRequestToJson(this);
-
-  @override
-  String toString() {
-    return 'scheduleBuildRequest(requestId: $requestId, builderId: $builderId, gitilesCommit: $gitilesCommit, fields: $fields, notify: $notify, exe: $exe)';
-  }
-}
-
-/// A single build, identified by an int64 [id], belonging to a builder.
-///
-/// See also:
-///   * [BuilderId]
-///   * [GetBuildRequest]
-@JsonSerializable(includeIfNull: false)
-class Build extends JsonBody {
-  /// Creates a build object.
-  ///
-  /// The [id] and [builderId] parameter is required.
-  const Build({
-    required this.id,
-    required this.builderId,
-    this.number,
-    this.createdBy,
-    this.canceledBy,
-    this.startTime,
-    this.endTime,
-    this.status,
-    this.tags,
-    this.input,
-    this.summaryMarkdown,
-    this.critical,
-  });
-
-  /// Creates a [Build] object from JSON.
-  static Build fromJson(Map<String, dynamic>? json) => _$BuildFromJson(json!);
-
-  /// The BuildBucket ID for the build. Required.
-  final String id;
-
-  /// The [BuilderId] for the build.  Required.
-  @JsonKey(name: 'builder')
-  final BuilderId builderId;
-
-  /// The LUCI build number for the build.
-  ///
-  /// This number corresponds to the order of builds, but build numbers may have
-  /// gaps.
-  final int? number;
-
-  /// The verified LUCI identity that created the build.
-  final String? createdBy;
-
-  /// The verified LUCI identity that canceled the build.
-  final String? canceledBy;
-
-  /// The start time of the build.
-  ///
-  /// Required if and only if the [status] is [Status.started], [Status.success],
-  /// or [Status.failure].
-  final DateTime? startTime;
-
-  /// The end time of the build.
-  ///
-  /// Required if and only if the [status] is terminal. Must not be before
-  /// [startTime].
-  final DateTime? endTime;
-
-  /// The build status.
-  ///
-  /// Must be specified, and must not be [Status.unspecified].
-  final Status? status;
-
-  /// Human readable summary of the build in Markdown format.
-  ///
-  /// Up to 4kb.
-  final String? summaryMarkdown;
-
-  /// Arbitrary annotations for the build.
-  ///
-  /// The same key for a tag may be used multiple times.
-  @TagsConverter()
-  final Map<String?, List<String?>>? tags;
-
-  /// If [Trinary.no], then the build status should not be used to assess the
-  /// correctness of the input gitilesCommit or gerritChanges.
-  final Trinary? critical;
-
-  /// The build input values.
-  final Input? input;
-
-  @override
-  Map<String, dynamic> toJson() => _$BuildToJson(this);
-
-  @override
-  String toString() => 'build(id: $id, builderId: $builderId, number: $number, status: $status, tags: $tags)';
-}
-
-/// A unique handle to a builder on BuildBucket.
-@JsonSerializable(includeIfNull: false)
-class BuilderId extends JsonBody {
-  /// Creates a unique handle to a builder on BuildBucket.
-  ///
-  /// The bucket and builder control what ACLs for the infra, as specified in
-  /// cr-buildbucket.cfg.
-  const BuilderId({
-    this.project,
-    this.bucket,
-    this.builder,
-  });
-
-  /// Creates a [BuilderId] object from JSON.
-  static BuilderId fromJson(Map<String, dynamic> json) => _$BuilderIdFromJson(json);
-
-  /// The project, e.g. "flutter", for the builder.
-  final String? project;
-
-  /// The bucket, e.g. "try" or "prod", for the builder.
-  ///
-  /// By convention, "prod" is for assets that will be released, "ci" is for
-  /// reviewed code, and "try" is for untrusted code.
-  final String? bucket;
-
-  /// The builder from cr-buildbucket.cfg, e.g. "Linux" or "Linux Host Engine".
-  final String? builder;
-
-  @override
-  Map<String, dynamic> toJson() => _$BuilderIdToJson(this);
-
-  @override
-  String toString() => '$project/$bucket/$builder';
-
-  @override
-  bool operator ==(Object other) =>
-      other is BuilderId && other.bucket == bucket && other.builder == builder && other.project == project;
-
-  @override
-  int get hashCode => toString().hashCode;
-}
-
-/// Specifies a Cloud PubSub topic to send notification updates to from a
-/// [ScheduleBuildRequest].
-@JsonSerializable(includeIfNull: false)
-class NotificationConfig extends JsonBody {
-  const NotificationConfig({this.pubsubTopic, this.userData});
-
-  static NotificationConfig fromJson(Map<String, dynamic> json) => _$NotificationConfigFromJson(json);
-
-  /// The Cloud PubSub topic to use, e.g.
-  /// `projects/flutter-dashboard/topics/luci-builds`.
-  final String? pubsubTopic;
-
-  /// An optional user data field that will be delivered with the message.
-  ///
-  /// May be omitted.
-  @Base64Converter()
-  final String? userData;
-
-  @override
-  Map<String, dynamic> toJson() => _$NotificationConfigToJson(this);
-
-  @override
-  String toString() => 'NotificationConfig(pubsubTopic: $pubsubTopic, userData: $userData)';
-}
-
-/// The build inputs for a build.
-@JsonSerializable(includeIfNull: false)
-class Input extends JsonBody {
-  /// Creates a set of build inputs for a build.
-  const Input({
-    this.properties,
-    this.gitilesCommit,
-    this.experimental,
-  });
-
-  /// Creates an [Input] object from JSON.
-  static Input fromJson(Map<String, dynamic> json) => _$InputFromJson(json);
-
-  /// The build properties of a build.
-  final Map<String, Object>? properties;
-
-  /// The [GitilesCommit] information for a build.
-  final GitilesCommit? gitilesCommit;
-
-  /// Whether the build is experimental or not. Passed into the recipe as
-  /// `api.runtime.is_experimental`.
-  final bool? experimental;
-
-  @override
-  Map<String, dynamic> toJson() => _$InputToJson(this);
-}
-
-/// A landed Git commit hosted on Gitiles.
-@JsonSerializable(includeIfNull: false)
-class GitilesCommit extends JsonBody {
-  /// Creates a object corresponding to a landed Git commit hosted on Gitiles.
-  const GitilesCommit({
-    this.host,
-    this.project,
-    this.ref,
-    this.hash,
-  });
-
-  /// Creates a [GitilesCommit] object from JSON.
-  static GitilesCommit fromJson(Map<String, dynamic> json) => _$GitilesCommitFromJson(json);
-
-  /// The Gitiles host name, e.g. "chromium.googlesource.com"
-  final String? host;
-
-  /// The repository name on the host, e.g. "external/github.com/flutter/flutter".
-  final String? project;
-
-  /// The Git hash of the commit.
-  @JsonKey(name: 'id')
-  final String? hash;
-
-  /// The Git ref of the commit, e.g. "refs/heads/master".
-  final String? ref;
-
-  @override
-  Map<String, dynamic> toJson() => _$GitilesCommitToJson(this);
-}
-
-/// Build status values.
-enum Status {
-  /// Should not be used.
-  @JsonValue('STATUS_UNSPECIFIED')
-  unspecified,
-
-  /// The status of a scheduled or pending build.
-  @JsonValue('SCHEDULED')
-  scheduled,
-
-  /// The status of a started (running) build.
-  @JsonValue('STARTED')
-  started,
-
-  /// A mask of `succes | failure | infraFailure | canceled`.
-  @JsonValue('ENDED_MASK')
-  ended,
-
-  /// The build has successfully completed.
-  @JsonValue('SUCCESS')
-  success,
-
-  /// The build has failed to complete some step due to a faulty test or commit.
-  @JsonValue('FAILURE')
-  failure,
-
-  /// The build has failed due to an infrastructure related failure.
-  @JsonValue('INFRA_FAILURE')
-  infraFailure,
-
-  /// The build was canceled.
-  @JsonValue('CANCELED')
-  canceled,
-}
-
-/// This type doesn't quite map to a bool, because there are actually four states
-/// when you include whether it's present or not.
-enum Trinary {
-  /// A true value.
-  @JsonValue('YES')
-  yes,
-
-  /// A false value.
-  @JsonValue('NO')
-  no,
-
-  /// An explicit null value, which may or may not be treated differently from
-  /// setting the JSON field to null.
-  @JsonValue('UNSET')
-  unset,
-}
-
-/// A requested dimension. Looks like StringPair, but also has an expiration.
-@JsonSerializable(includeIfNull: false)
-class RequestedDimension extends JsonBody {
-  const RequestedDimension({
-    required this.key,
-    this.value,
-    this.expiration,
-  });
-
-  static RequestedDimension fromJson(Map<String, dynamic> json) => _$RequestedDimensionFromJson(json);
-
-  final String key;
-  final String? value;
-
-  /// If set, ignore this dimension after this duration. Must be a multiple of 1 minute. The format is '<seconds>s',
-  /// e.g. '120s' represents 120 seconds.
-  final String? expiration;
-
-  @override
-  Map<String, dynamic> toJson() => _$RequestedDimensionToJson(this);
-}
diff --git a/app_dart/lib/src/model/luci/buildbucket.g.dart b/app_dart/lib/src/model/luci/buildbucket.g.dart
deleted file mode 100644
index 6cb274c..0000000
--- a/app_dart/lib/src/model/luci/buildbucket.g.dart
+++ /dev/null
@@ -1,532 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-// ignore_for_file: always_specify_types, implicit_dynamic_parameter
-
-part of 'buildbucket.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-BatchRequest _$BatchRequestFromJson(Map<String, dynamic> json) => BatchRequest(
-      requests: (json['requests'] as List<dynamic>?)?.map((e) => Request.fromJson(e as Map<String, dynamic>)).toList(),
-    );
-
-Map<String, dynamic> _$BatchRequestToJson(BatchRequest instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('requests', instance.requests);
-  return val;
-}
-
-Request _$RequestFromJson(Map<String, dynamic> json) => Request(
-      getBuild: json['getBuild'] == null ? null : GetBuildRequest.fromJson(json['getBuild'] as Map<String, dynamic>),
-      searchBuilds: json['searchBuilds'] == null
-          ? null
-          : SearchBuildsRequest.fromJson(json['searchBuilds'] as Map<String, dynamic>),
-      scheduleBuild: json['scheduleBuild'] == null
-          ? null
-          : ScheduleBuildRequest.fromJson(json['scheduleBuild'] as Map<String, dynamic>),
-      cancelBuild:
-          json['cancelBuild'] == null ? null : CancelBuildRequest.fromJson(json['cancelBuild'] as Map<String, dynamic>),
-    );
-
-Map<String, dynamic> _$RequestToJson(Request instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('getBuild', instance.getBuild);
-  writeNotNull('searchBuilds', instance.searchBuilds);
-  writeNotNull('scheduleBuild', instance.scheduleBuild);
-  writeNotNull('cancelBuild', instance.cancelBuild);
-  return val;
-}
-
-BatchResponse _$BatchResponseFromJson(Map<String, dynamic> json) => BatchResponse(
-      responses:
-          (json['responses'] as List<dynamic>?)?.map((e) => Response.fromJson(e as Map<String, dynamic>)).toList(),
-    );
-
-Map<String, dynamic> _$BatchResponseToJson(BatchResponse instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('responses', instance.responses);
-  return val;
-}
-
-Response _$ResponseFromJson(Map<String, dynamic> json) => Response(
-      getBuild: json['getBuild'] == null ? null : Build.fromJson(json['getBuild'] as Map<String, dynamic>),
-      searchBuilds: json['searchBuilds'] == null
-          ? null
-          : SearchBuildsResponse.fromJson(json['searchBuilds'] as Map<String, dynamic>),
-      scheduleBuild:
-          json['scheduleBuild'] == null ? null : Build.fromJson(json['scheduleBuild'] as Map<String, dynamic>),
-      cancelBuild: json['cancelBuild'] == null ? null : Build.fromJson(json['cancelBuild'] as Map<String, dynamic>),
-      error: json['error'] == null ? null : GrpcStatus.fromJson(json['error'] as Map<String, dynamic>),
-    );
-
-Map<String, dynamic> _$ResponseToJson(Response instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('getBuild', instance.getBuild);
-  writeNotNull('searchBuilds', instance.searchBuilds);
-  writeNotNull('scheduleBuild', instance.scheduleBuild);
-  writeNotNull('cancelBuild', instance.cancelBuild);
-  writeNotNull('error', instance.error);
-  return val;
-}
-
-GetBuildRequest _$GetBuildRequestFromJson(Map<String, dynamic> json) => GetBuildRequest(
-      id: json['id'] as String?,
-      builderId: json['builder'] == null ? null : BuilderId.fromJson(json['builder'] as Map<String, dynamic>),
-      buildNumber: json['buildNumber'] as int?,
-      fields: json['fields'] as String?,
-    );
-
-Map<String, dynamic> _$GetBuildRequestToJson(GetBuildRequest instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('id', instance.id);
-  writeNotNull('builder', instance.builderId);
-  writeNotNull('buildNumber', instance.buildNumber);
-  writeNotNull('fields', instance.fields);
-  return val;
-}
-
-GetBuilderRequest _$GetBuilderRequestFromJson(Map<String, dynamic> json) => GetBuilderRequest(
-      builderId: json['builderId'] == null ? null : BuilderId.fromJson(json['builderId'] as Map<String, dynamic>),
-    );
-
-Map<String, dynamic> _$GetBuilderRequestToJson(GetBuilderRequest instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('builderId', instance.builderId);
-  return val;
-}
-
-BuilderConfig _$BuilderConfigFromJson(Map<String, dynamic> json) => BuilderConfig(
-      name: json['name'] as String?,
-    );
-
-Map<String, dynamic> _$BuilderConfigToJson(BuilderConfig instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('name', instance.name);
-  return val;
-}
-
-BuilderItem _$BuilderItemFromJson(Map<String, dynamic> json) => BuilderItem(
-      id: json['id'] == null ? null : BuilderId.fromJson(json['id'] as Map<String, dynamic>),
-      config: json['config'] == null ? null : BuilderConfig.fromJson(json['config'] as Map<String, dynamic>),
-    );
-
-Map<String, dynamic> _$BuilderItemToJson(BuilderItem instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('id', instance.id);
-  writeNotNull('config', instance.config);
-  return val;
-}
-
-ListBuildersRequest _$ListBuildersRequestFromJson(Map<String, dynamic> json) {
-  $checkKeys(
-    json,
-    requiredKeys: const ['project'],
-  );
-  return ListBuildersRequest(
-    project: json['project'] as String,
-    bucket: json['bucket'] as String?,
-    pageSize: json['pageSize'] as int? ?? 1000,
-    pageToken: json['pageToken'] as String?,
-  );
-}
-
-Map<String, dynamic> _$ListBuildersRequestToJson(ListBuildersRequest instance) {
-  final val = <String, dynamic>{
-    'project': instance.project,
-  };
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('bucket', instance.bucket);
-  writeNotNull('pageSize', instance.pageSize);
-  writeNotNull('pageToken', instance.pageToken);
-  return val;
-}
-
-ListBuildersResponse _$ListBuildersResponseFromJson(Map<String, dynamic> json) => ListBuildersResponse(
-      builders:
-          (json['builders'] as List<dynamic>?)?.map((e) => BuilderItem.fromJson(e as Map<String, dynamic>)).toList(),
-      nextPageToken: json['nextPageToken'] as String?,
-    );
-
-Map<String, dynamic> _$ListBuildersResponseToJson(ListBuildersResponse instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('builders', instance.builders);
-  writeNotNull('nextPageToken', instance.nextPageToken);
-  return val;
-}
-
-CancelBuildRequest _$CancelBuildRequestFromJson(Map<String, dynamic> json) {
-  $checkKeys(
-    json,
-    requiredKeys: const ['id', 'summaryMarkdown'],
-  );
-  return CancelBuildRequest(
-    id: json['id'] as String,
-    summaryMarkdown: json['summaryMarkdown'] as String,
-  );
-}
-
-Map<String, dynamic> _$CancelBuildRequestToJson(CancelBuildRequest instance) => <String, dynamic>{
-      'id': instance.id,
-      'summaryMarkdown': instance.summaryMarkdown,
-    };
-
-SearchBuildsRequest _$SearchBuildsRequestFromJson(Map<String, dynamic> json) => SearchBuildsRequest(
-      predicate: BuildPredicate.fromJson(json['predicate'] as Map<String, dynamic>),
-      pageSize: json['pageSize'] as int?,
-      pageToken: json['pageToken'] as String?,
-      fields: json['fields'] as String?,
-    );
-
-Map<String, dynamic> _$SearchBuildsRequestToJson(SearchBuildsRequest instance) {
-  final val = <String, dynamic>{
-    'predicate': instance.predicate,
-  };
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('pageSize', instance.pageSize);
-  writeNotNull('pageToken', instance.pageToken);
-  writeNotNull('fields', instance.fields);
-  return val;
-}
-
-BuildPredicate _$BuildPredicateFromJson(Map<String, dynamic> json) => BuildPredicate(
-      builderId: json['builder'] == null ? null : BuilderId.fromJson(json['builder'] as Map<String, dynamic>),
-      status: $enumDecodeNullable(_$StatusEnumMap, json['status']),
-      createdBy: json['createdBy'] as String?,
-      tags: const TagsConverter().fromJson(json['tags'] as List?),
-      includeExperimental: json['includeExperimental'] as bool?,
-    );
-
-Map<String, dynamic> _$BuildPredicateToJson(BuildPredicate instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('builder', instance.builderId);
-  writeNotNull('status', _$StatusEnumMap[instance.status]);
-  writeNotNull('createdBy', instance.createdBy);
-  writeNotNull('tags', const TagsConverter().toJson(instance.tags));
-  writeNotNull('includeExperimental', instance.includeExperimental);
-  return val;
-}
-
-const _$StatusEnumMap = {
-  Status.unspecified: 'STATUS_UNSPECIFIED',
-  Status.scheduled: 'SCHEDULED',
-  Status.started: 'STARTED',
-  Status.ended: 'ENDED_MASK',
-  Status.success: 'SUCCESS',
-  Status.failure: 'FAILURE',
-  Status.infraFailure: 'INFRA_FAILURE',
-  Status.canceled: 'CANCELED',
-};
-
-SearchBuildsResponse _$SearchBuildsResponseFromJson(Map<String, dynamic> json) => SearchBuildsResponse(
-      builds: (json['builds'] as List<dynamic>?)?.map((e) => Build.fromJson(e as Map<String, dynamic>)).toList(),
-      nextPageToken: json['nextPageToken'] as String?,
-    );
-
-Map<String, dynamic> _$SearchBuildsResponseToJson(SearchBuildsResponse instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('builds', instance.builds);
-  writeNotNull('nextPageToken', instance.nextPageToken);
-  return val;
-}
-
-ScheduleBuildRequest _$ScheduleBuildRequestFromJson(Map<String, dynamic> json) => ScheduleBuildRequest(
-      requestId: json['requestId'] as String?,
-      builderId: BuilderId.fromJson(json['builder'] as Map<String, dynamic>),
-      canary: json['canary'] as bool?,
-      experimental: $enumDecodeNullable(_$TrinaryEnumMap, json['experimental']),
-      gitilesCommit:
-          json['gitilesCommit'] == null ? null : GitilesCommit.fromJson(json['gitilesCommit'] as Map<String, dynamic>),
-      properties: (json['properties'] as Map<String, dynamic>?)?.map(
-        (k, e) => MapEntry(k, e as Object),
-      ),
-      dimensions: (json['dimensions'] as List<dynamic>?)
-          ?.map((e) => RequestedDimension.fromJson(e as Map<String, dynamic>))
-          .toList(),
-      priority: json['priority'] as int?,
-      tags: const TagsConverter().fromJson(json['tags'] as List?),
-      notify: json['notify'] == null ? null : NotificationConfig.fromJson(json['notify'] as Map<String, dynamic>),
-      fields: json['fields'] as String?,
-      exe: json['exe'] as Map<String, dynamic>?,
-    );
-
-Map<String, dynamic> _$ScheduleBuildRequestToJson(ScheduleBuildRequest instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('requestId', instance.requestId);
-  val['builder'] = instance.builderId;
-  writeNotNull('canary', instance.canary);
-  writeNotNull('experimental', _$TrinaryEnumMap[instance.experimental]);
-  writeNotNull('properties', instance.properties);
-  writeNotNull('gitilesCommit', instance.gitilesCommit);
-  writeNotNull('tags', const TagsConverter().toJson(instance.tags));
-  writeNotNull('dimensions', instance.dimensions);
-  writeNotNull('priority', instance.priority);
-  writeNotNull('notify', instance.notify);
-  writeNotNull('fields', instance.fields);
-  writeNotNull('exe', instance.exe);
-  return val;
-}
-
-const _$TrinaryEnumMap = {
-  Trinary.yes: 'YES',
-  Trinary.no: 'NO',
-  Trinary.unset: 'UNSET',
-};
-
-Build _$BuildFromJson(Map<String, dynamic> json) => Build(
-      id: json['id'] as String,
-      builderId: BuilderId.fromJson(json['builder'] as Map<String, dynamic>),
-      number: json['number'] as int?,
-      createdBy: json['createdBy'] as String?,
-      canceledBy: json['canceledBy'] as String?,
-      startTime: json['startTime'] == null ? null : DateTime.parse(json['startTime'] as String),
-      endTime: json['endTime'] == null ? null : DateTime.parse(json['endTime'] as String),
-      status: $enumDecodeNullable(_$StatusEnumMap, json['status']),
-      tags: const TagsConverter().fromJson(json['tags'] as List?),
-      input: json['input'] == null ? null : Input.fromJson(json['input'] as Map<String, dynamic>),
-      summaryMarkdown: json['summaryMarkdown'] as String?,
-      critical: $enumDecodeNullable(_$TrinaryEnumMap, json['critical']),
-    );
-
-Map<String, dynamic> _$BuildToJson(Build instance) {
-  final val = <String, dynamic>{
-    'id': instance.id,
-    'builder': instance.builderId,
-  };
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('number', instance.number);
-  writeNotNull('createdBy', instance.createdBy);
-  writeNotNull('canceledBy', instance.canceledBy);
-  writeNotNull('startTime', instance.startTime?.toIso8601String());
-  writeNotNull('endTime', instance.endTime?.toIso8601String());
-  writeNotNull('status', _$StatusEnumMap[instance.status]);
-  writeNotNull('summaryMarkdown', instance.summaryMarkdown);
-  writeNotNull('tags', const TagsConverter().toJson(instance.tags));
-  writeNotNull('critical', _$TrinaryEnumMap[instance.critical]);
-  writeNotNull('input', instance.input);
-  return val;
-}
-
-BuilderId _$BuilderIdFromJson(Map<String, dynamic> json) => BuilderId(
-      project: json['project'] as String?,
-      bucket: json['bucket'] as String?,
-      builder: json['builder'] as String?,
-    );
-
-Map<String, dynamic> _$BuilderIdToJson(BuilderId instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('project', instance.project);
-  writeNotNull('bucket', instance.bucket);
-  writeNotNull('builder', instance.builder);
-  return val;
-}
-
-NotificationConfig _$NotificationConfigFromJson(Map<String, dynamic> json) => NotificationConfig(
-      pubsubTopic: json['pubsubTopic'] as String?,
-      userData: _$JsonConverterFromJson<String, String>(json['userData'], const Base64Converter().fromJson),
-    );
-
-Map<String, dynamic> _$NotificationConfigToJson(NotificationConfig instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('pubsubTopic', instance.pubsubTopic);
-  writeNotNull('userData', _$JsonConverterToJson<String, String>(instance.userData, const Base64Converter().toJson));
-  return val;
-}
-
-Value? _$JsonConverterFromJson<Json, Value>(
-  Object? json,
-  Value? Function(Json json) fromJson,
-) =>
-    json == null ? null : fromJson(json as Json);
-
-Json? _$JsonConverterToJson<Json, Value>(
-  Value? value,
-  Json? Function(Value value) toJson,
-) =>
-    value == null ? null : toJson(value);
-
-Input _$InputFromJson(Map<String, dynamic> json) => Input(
-      properties: (json['properties'] as Map<String, dynamic>?)?.map(
-        (k, e) => MapEntry(k, e as Object),
-      ),
-      gitilesCommit:
-          json['gitilesCommit'] == null ? null : GitilesCommit.fromJson(json['gitilesCommit'] as Map<String, dynamic>),
-      experimental: json['experimental'] as bool?,
-    );
-
-Map<String, dynamic> _$InputToJson(Input instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('properties', instance.properties);
-  writeNotNull('gitilesCommit', instance.gitilesCommit);
-  writeNotNull('experimental', instance.experimental);
-  return val;
-}
-
-GitilesCommit _$GitilesCommitFromJson(Map<String, dynamic> json) => GitilesCommit(
-      host: json['host'] as String?,
-      project: json['project'] as String?,
-      ref: json['ref'] as String?,
-      hash: json['id'] as String?,
-    );
-
-Map<String, dynamic> _$GitilesCommitToJson(GitilesCommit instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('host', instance.host);
-  writeNotNull('project', instance.project);
-  writeNotNull('id', instance.hash);
-  writeNotNull('ref', instance.ref);
-  return val;
-}
-
-RequestedDimension _$RequestedDimensionFromJson(Map<String, dynamic> json) => RequestedDimension(
-      key: json['key'] as String,
-      value: json['value'] as String?,
-      expiration: json['expiration'] as String?,
-    );
-
-Map<String, dynamic> _$RequestedDimensionToJson(RequestedDimension instance) {
-  final val = <String, dynamic>{
-    'key': instance.key,
-  };
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('value', instance.value);
-  writeNotNull('expiration', instance.expiration);
-  return val;
-}
diff --git a/app_dart/lib/src/model/luci/push_message.dart b/app_dart/lib/src/model/luci/push_message.dart
deleted file mode 100644
index d7c1502..0000000
--- a/app_dart/lib/src/model/luci/push_message.dart
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:typed_data';
-
-import 'package:json_annotation/json_annotation.dart';
-
-import '../../request_handling/body.dart';
-import '../../service/logging.dart';
-import '../common/json_converters.dart';
-
-part 'push_message.g.dart';
-
-/// A Cloud PubSub push message.
-///
-/// For example:
-/// ```json
-/// {
-///   "message": {
-///     "attributes": {
-///       "key": "value"
-///     },
-///     "data": "SGVsbG8gQ2xvdWQgUHViL1N1YiEgSGVyZSBpcyBteSBtZXNzYWdlIQ==",
-///     "messageId": "136969346945"
-///   },
-///   "subscription": "projects/myproject/subscriptions/mysubscription"
-/// }
-/// ```
-///
-/// Where `data` is base64 encoded.
-///
-/// See https://cloud.google.com/pubsub/docs/push#receiving_push_messages
-@JsonSerializable(includeIfNull: false)
-class PushMessageEnvelope extends JsonBody {
-  const PushMessageEnvelope({
-    this.message,
-    this.subscription,
-  });
-
-  static PushMessageEnvelope fromJson(Map<String, dynamic> json) => _$PushMessageEnvelopeFromJson(json);
-
-  /// The message contents.
-  final PushMessage? message;
-
-  /// The name of the subscription associated with the delivery.
-  final String? subscription;
-
-  @override
-  Map<String, dynamic> toJson() => _$PushMessageEnvelopeToJson(this);
-}
-
-/// A PubSub push message payload.
-@JsonSerializable(includeIfNull: false)
-class PushMessage extends JsonBody {
-  const PushMessage({
-    this.attributes,
-    this.data,
-    this.messageId,
-    this.publishTime,
-  });
-
-  static PushMessage fromJson(Map<String, dynamic> json) => _$PushMessageFromJson(json);
-
-  /// PubSub attributes on the message.
-  final Map<String, String>? attributes;
-
-  /// The raw string data of the message.
-  @Base64Converter()
-  final String? data;
-
-  /// A identifier for the message from PubSub.
-  final String? messageId;
-
-  /// The time at which the message was published, populated by the server when
-  /// it receives the topics.publish call.
-  ///
-  /// A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and
-  /// up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and
-  /// "2014-10-02T15:01:23.045123456Z".
-  final String? publishTime;
-
-  @override
-  Map<String, dynamic> toJson() => _$PushMessageToJson(this);
-}
-
-/// The LUCI build data from a PubSub push message payload.
-@JsonSerializable(includeIfNull: false, fieldRename: FieldRename.snake)
-class BuildPushMessage extends JsonBody {
-  const BuildPushMessage({
-    this.build,
-    this.hostname,
-    String? userData,
-  }) : rawUserData = userData;
-
-  /// Create [BuildPushMessage] from [PushMessage].
-  factory BuildPushMessage.fromPushMessage(PushMessage message) {
-    final data = message.data;
-    if (data == null) {
-      throw const FormatException('Cannot create BuildPushMessage from null data');
-    }
-
-    try {
-      final String decodedData = String.fromCharCodes(base64.decode(data));
-      log.info('Result message from base64: $decodedData');
-      return BuildPushMessage.fromJson(json.decode(decodedData) as Map<String, dynamic>);
-    } on FormatException {
-      log.info('Result message: $data');
-      return BuildPushMessage.fromJson(json.decode(data) as Map<String, dynamic>);
-    }
-  }
-
-  static BuildPushMessage fromJson(Map<String, dynamic> json) => _$BuildPushMessageFromJson(json);
-
-  /// The Build this message is for.
-  final Build? build;
-
-  /// The hostname for the build, e.g. `cr-buildbucket.appspot.com`.
-  final String? hostname;
-
-  /// Do not use this value for anything.
-  ///
-  /// This value cannot be marked private due to json_serializable not
-  /// generating on private fields.
-  ///
-  /// This value is used to generate [userData].
-  @JsonKey(name: 'user_data')
-  final String? rawUserData;
-
-  /// User data that was included in the LUCI build request.
-  Map<String, dynamic> get userData {
-    if (rawUserData == null) {
-      return <String, dynamic>{};
-    }
-
-    try {
-      return json.decode(rawUserData!) as Map<String, dynamic>;
-    } on FormatException {
-      final Uint8List bytes = base64.decode(rawUserData!);
-      final String rawJson = String.fromCharCodes(bytes);
-      if (rawJson.isEmpty) {
-        return <String, dynamic>{};
-      }
-      return json.decode(rawJson) as Map<String, dynamic>;
-    }
-  }
-
-  @override
-  Map<String, dynamic> toJson() => _$BuildPushMessageToJson(this);
-}
-
-/// See https://github.com/luci/luci-go/blob/master/common/api/buildbucket/buildbucket/v1/buildbucket-gen.go#L332ƒ
-@JsonSerializable(includeIfNull: false)
-class Build extends JsonBody {
-  const Build({
-    this.bucket,
-    this.canary,
-    this.canaryPreference,
-    this.cancelationReason,
-    this.completedTimestamp,
-    this.createdBy,
-    this.createdTimestamp,
-    this.failureReason,
-    this.experimental,
-    this.id,
-    this.buildParameters,
-    this.project,
-    this.result,
-    this.resultDetails,
-    this.serviceAccount,
-    this.startedTimestamp,
-    this.status,
-    this.tags,
-    this.updatedTimestamp,
-    this.utcNowTimestamp,
-    this.url,
-  });
-
-  static Build fromJson(Map<String, dynamic> json) => _$BuildFromJson(json);
-
-  /// The BuildBucket name.
-  final String? bucket;
-
-  /// Whether carnary hardware was used.
-  final bool? canary;
-
-  /// The canary preference for `canary`.
-  @JsonKey(name: 'canary_preference')
-  final CanaryPreference? canaryPreference;
-
-  /// The reason for canceling the build.
-  @JsonKey(name: 'cancelation_reason')
-  final CancelationReason? cancelationReason;
-
-  /// The completion time of the build.
-  @JsonKey(name: 'completed_ts')
-  @MicrosecondsSinceEpochConverter()
-  final DateTime? completedTimestamp;
-
-  /// The user who created the build.
-  @JsonKey(name: 'created_by')
-  final String? createdBy;
-
-  /// The creation time of the build.
-  @JsonKey(name: 'created_ts')
-  @MicrosecondsSinceEpochConverter()
-  final DateTime? createdTimestamp;
-
-  /// Whether the build was experimental or not.
-  final bool? experimental;
-
-  /// The reason the build failed, if it failed.
-  @JsonKey(name: 'failure_reason')
-  final FailureReason? failureReason;
-
-  /// The unique BuildBucket ID for the build.
-  final String? id;
-
-  /// Parameters passed to the build.
-  @JsonKey(name: 'parameters_json')
-  @NestedJsonConverter()
-  final Map<String, dynamic>? buildParameters;
-
-  /// The BuildBucket project for the build, e.g. `flutter`.
-  final String? project;
-
-  /// The result of the build.
-  ///
-  /// If [Result.canceled], [cancelationReason] will be populated.
-  ///
-  /// If [Result.failure], [failureReason] will be populated.
-  final Result? result;
-
-  /// A JSON object that contains additional build information based on the
-  /// result.
-  @JsonKey(name: 'result_details_json')
-  @NestedJsonConverter()
-  final Map<String, dynamic>? resultDetails;
-
-  /// The service account used for the build.
-  @JsonKey(name: 'service_account')
-  final String? serviceAccount;
-
-  /// The time of the build start.
-  @JsonKey(name: 'started_ts')
-  @MicrosecondsSinceEpochConverter()
-  final DateTime? startedTimestamp;
-
-  /// The [Status] of the build.
-  ///
-  /// If [Status.completed], [result] will be populated.
-  final Status? status;
-
-  /// The swarming tags for the build.
-  final List<String>? tags;
-
-  /// Returns all tags matching the prefix.
-  ///
-  /// For example, to get the `buildset` tag(s), call `tagsByName('buildset')`;
-  /// to get the `swarming_tag:os`, call `tagsByName('swarming_tag:os')`.
-  List<String> tagsByName(String prefix) {
-    return tags!
-        .where((String tag) => tag.startsWith('$prefix:'))
-        .map<String>((String tag) => tag.substring(prefix.length + 1))
-        .toList();
-  }
-
-  /// The time of the last update to this information.
-  @JsonKey(name: 'updated_ts')
-  @MicrosecondsSinceEpochConverter()
-  final DateTime? updatedTimestamp;
-
-  /// The URL of the build.
-  final String? url;
-
-  /// The time used as UTC now for reference to other times in this message.
-  @JsonKey(name: 'utcnow_ts')
-  @MicrosecondsSinceEpochConverter()
-  final DateTime? utcNowTimestamp;
-
-  @override
-  Map<String, dynamic> toJson() => _$BuildToJson(this);
-}
-
-/// The method to select whether canary hardware was chosen for a build.
-enum CanaryPreference {
-  @JsonValue('AUTO')
-  auto,
-  @JsonValue('CANARY')
-  canary,
-  @JsonValue('PROD')
-  prod,
-}
-
-/// The reason for canceling a build.
-enum CancelationReason {
-  @JsonValue('CANCELED_EXPLICITLY')
-  canceledExplicitly,
-  @JsonValue('TIMEOUT')
-  timeout,
-}
-
-/// The reason a build failed.
-enum FailureReason {
-  @JsonValue('BUILDBUCKET_FAILURE')
-  buildbucketFailure,
-  @JsonValue('BUILD_FAILURE')
-  buildFailure,
-  @JsonValue('INFRA_FAILURE')
-  infraFailure,
-  @JsonValue('INVALID_BUILD_DEFINITION')
-  invalidBuildDefinition,
-}
-
-/// The final result of a build, if its [Status] is [Status.completed].
-enum Result {
-  @JsonValue('CANCELED')
-  canceled,
-  @JsonValue('FAILURE')
-  failure,
-  @JsonValue('SUCCESS')
-  success,
-}
-
-/// The current status of a build.
-///
-/// If [Status.completed], then a [Result] will be present as well.
-enum Status {
-  @JsonValue('COMPLETED')
-  completed,
-  @JsonValue('SCHEDULED')
-  scheduled,
-  @JsonValue('STARTED')
-  started,
-}
diff --git a/app_dart/lib/src/model/luci/push_message.g.dart b/app_dart/lib/src/model/luci/push_message.g.dart
deleted file mode 100644
index 963d7b6..0000000
--- a/app_dart/lib/src/model/luci/push_message.g.dart
+++ /dev/null
@@ -1,173 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-// ignore_for_file: always_specify_types, implicit_dynamic_parameter
-
-part of 'push_message.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-PushMessageEnvelope _$PushMessageEnvelopeFromJson(Map<String, dynamic> json) => PushMessageEnvelope(
-      message: json['message'] == null ? null : PushMessage.fromJson(json['message'] as Map<String, dynamic>),
-      subscription: json['subscription'] as String?,
-    );
-
-Map<String, dynamic> _$PushMessageEnvelopeToJson(PushMessageEnvelope instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('message', instance.message);
-  writeNotNull('subscription', instance.subscription);
-  return val;
-}
-
-PushMessage _$PushMessageFromJson(Map<String, dynamic> json) => PushMessage(
-      attributes: (json['attributes'] as Map<String, dynamic>?)?.map(
-        (k, e) => MapEntry(k, e as String),
-      ),
-      data: _$JsonConverterFromJson<String, String>(json['data'], const Base64Converter().fromJson),
-      messageId: json['messageId'] as String?,
-      publishTime: json['publishTime'] as String?,
-    );
-
-Map<String, dynamic> _$PushMessageToJson(PushMessage instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('attributes', instance.attributes);
-  writeNotNull('data', _$JsonConverterToJson<String, String>(instance.data, const Base64Converter().toJson));
-  writeNotNull('messageId', instance.messageId);
-  writeNotNull('publishTime', instance.publishTime);
-  return val;
-}
-
-Value? _$JsonConverterFromJson<Json, Value>(
-  Object? json,
-  Value? Function(Json json) fromJson,
-) =>
-    json == null ? null : fromJson(json as Json);
-
-Json? _$JsonConverterToJson<Json, Value>(
-  Value? value,
-  Json? Function(Value value) toJson,
-) =>
-    value == null ? null : toJson(value);
-
-BuildPushMessage _$BuildPushMessageFromJson(Map<String, dynamic> json) => BuildPushMessage(
-      build: json['build'] == null ? null : Build.fromJson(json['build'] as Map<String, dynamic>),
-      hostname: json['hostname'] as String?,
-      userData: json['user_data'] as String?,
-    );
-
-Map<String, dynamic> _$BuildPushMessageToJson(BuildPushMessage instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('build', instance.build);
-  writeNotNull('hostname', instance.hostname);
-  val['user_data'] = instance.userData;
-  return val;
-}
-
-Build _$BuildFromJson(Map<String, dynamic> json) => Build(
-      bucket: json['bucket'] as String?,
-      canary: json['canary'] as bool?,
-      canaryPreference: $enumDecodeNullable(_$CanaryPreferenceEnumMap, json['canary_preference']),
-      cancelationReason: $enumDecodeNullable(_$CancelationReasonEnumMap, json['cancelation_reason']),
-      completedTimestamp: const MicrosecondsSinceEpochConverter().fromJson(json['completed_ts'] as String?),
-      createdBy: json['created_by'] as String?,
-      createdTimestamp: const MicrosecondsSinceEpochConverter().fromJson(json['created_ts'] as String?),
-      failureReason: $enumDecodeNullable(_$FailureReasonEnumMap, json['failure_reason']),
-      experimental: json['experimental'] as bool?,
-      id: json['id'] as String?,
-      buildParameters: const NestedJsonConverter().fromJson(json['parameters_json'] as String?),
-      project: json['project'] as String?,
-      result: $enumDecodeNullable(_$ResultEnumMap, json['result']),
-      resultDetails: const NestedJsonConverter().fromJson(json['result_details_json'] as String?),
-      serviceAccount: json['service_account'] as String?,
-      startedTimestamp: const MicrosecondsSinceEpochConverter().fromJson(json['started_ts'] as String?),
-      status: $enumDecodeNullable(_$StatusEnumMap, json['status']),
-      tags: (json['tags'] as List<dynamic>?)?.map((e) => e as String).toList(),
-      updatedTimestamp: const MicrosecondsSinceEpochConverter().fromJson(json['updated_ts'] as String?),
-      utcNowTimestamp: const MicrosecondsSinceEpochConverter().fromJson(json['utcnow_ts'] as String?),
-      url: json['url'] as String?,
-    );
-
-Map<String, dynamic> _$BuildToJson(Build instance) {
-  final val = <String, dynamic>{};
-
-  void writeNotNull(String key, dynamic value) {
-    if (value != null) {
-      val[key] = value;
-    }
-  }
-
-  writeNotNull('bucket', instance.bucket);
-  writeNotNull('canary', instance.canary);
-  writeNotNull('canary_preference', _$CanaryPreferenceEnumMap[instance.canaryPreference]);
-  writeNotNull('cancelation_reason', _$CancelationReasonEnumMap[instance.cancelationReason]);
-  writeNotNull('completed_ts', const MicrosecondsSinceEpochConverter().toJson(instance.completedTimestamp));
-  writeNotNull('created_by', instance.createdBy);
-  writeNotNull('created_ts', const MicrosecondsSinceEpochConverter().toJson(instance.createdTimestamp));
-  writeNotNull('experimental', instance.experimental);
-  writeNotNull('failure_reason', _$FailureReasonEnumMap[instance.failureReason]);
-  writeNotNull('id', instance.id);
-  writeNotNull('parameters_json', const NestedJsonConverter().toJson(instance.buildParameters));
-  writeNotNull('project', instance.project);
-  writeNotNull('result', _$ResultEnumMap[instance.result]);
-  writeNotNull('result_details_json', const NestedJsonConverter().toJson(instance.resultDetails));
-  writeNotNull('service_account', instance.serviceAccount);
-  writeNotNull('started_ts', const MicrosecondsSinceEpochConverter().toJson(instance.startedTimestamp));
-  writeNotNull('status', _$StatusEnumMap[instance.status]);
-  writeNotNull('tags', instance.tags);
-  writeNotNull('updated_ts', const MicrosecondsSinceEpochConverter().toJson(instance.updatedTimestamp));
-  writeNotNull('url', instance.url);
-  writeNotNull('utcnow_ts', const MicrosecondsSinceEpochConverter().toJson(instance.utcNowTimestamp));
-  return val;
-}
-
-const _$CanaryPreferenceEnumMap = {
-  CanaryPreference.auto: 'AUTO',
-  CanaryPreference.canary: 'CANARY',
-  CanaryPreference.prod: 'PROD',
-};
-
-const _$CancelationReasonEnumMap = {
-  CancelationReason.canceledExplicitly: 'CANCELED_EXPLICITLY',
-  CancelationReason.timeout: 'TIMEOUT',
-};
-
-const _$FailureReasonEnumMap = {
-  FailureReason.buildbucketFailure: 'BUILDBUCKET_FAILURE',
-  FailureReason.buildFailure: 'BUILD_FAILURE',
-  FailureReason.infraFailure: 'INFRA_FAILURE',
-  FailureReason.invalidBuildDefinition: 'INVALID_BUILD_DEFINITION',
-};
-
-const _$ResultEnumMap = {
-  Result.canceled: 'CANCELED',
-  Result.failure: 'FAILURE',
-  Result.success: 'SUCCESS',
-};
-
-const _$StatusEnumMap = {
-  Status.completed: 'COMPLETED',
-  Status.scheduled: 'SCHEDULED',
-  Status.started: 'STARTED',
-};
diff --git a/app_dart/lib/src/model/proto/internal/build_status_response.pb.dart b/app_dart/lib/src/model/proto/internal/build_status_response.pb.dart
deleted file mode 100644
index dc5a7eb..0000000
--- a/app_dart/lib/src/model/proto/internal/build_status_response.pb.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/build_status_response.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-import 'dart:core' as $core;
-
-import 'package:protobuf/protobuf.dart' as $pb;
-
-import 'build_status_response.pbenum.dart';
-
-export 'build_status_response.pbenum.dart';
-
-class BuildStatusResponse extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
-      const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildStatusResponse',
-      package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'cocoon'),
-      createEmptyInstance: create)
-    ..e<EnumBuildStatus>(
-        1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'buildStatus', $pb.PbFieldType.OE,
-        defaultOrMaker: EnumBuildStatus.success, valueOf: EnumBuildStatus.valueOf, enumValues: EnumBuildStatus.values)
-    ..pPS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'failingTasks')
-    ..hasRequiredFields = false;
-
-  BuildStatusResponse._() : super();
-  factory BuildStatusResponse({
-    EnumBuildStatus? buildStatus,
-    $core.Iterable<$core.String>? failingTasks,
-  }) {
-    final _result = create();
-    if (buildStatus != null) {
-      _result.buildStatus = buildStatus;
-    }
-    if (failingTasks != null) {
-      _result.failingTasks.addAll(failingTasks);
-    }
-    return _result;
-  }
-  factory BuildStatusResponse.fromBuffer($core.List<$core.int> i,
-          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory BuildStatusResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
-      'Will be removed in next major version')
-  BuildStatusResponse clone() => BuildStatusResponse()..mergeFromMessage(this);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-      'Will be removed in next major version')
-  BuildStatusResponse copyWith(void Function(BuildStatusResponse) updates) =>
-      super.copyWith((message) => updates(message as BuildStatusResponse))
-          as BuildStatusResponse; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static BuildStatusResponse create() => BuildStatusResponse._();
-  BuildStatusResponse createEmptyInstance() => create();
-  static $pb.PbList<BuildStatusResponse> createRepeated() => $pb.PbList<BuildStatusResponse>();
-  @$core.pragma('dart2js:noInline')
-  static BuildStatusResponse getDefault() =>
-      _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BuildStatusResponse>(create);
-  static BuildStatusResponse? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  EnumBuildStatus get buildStatus => $_getN(0);
-  @$pb.TagNumber(1)
-  set buildStatus(EnumBuildStatus v) {
-    setField(1, v);
-  }
-
-  @$pb.TagNumber(1)
-  $core.bool hasBuildStatus() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearBuildStatus() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.List<$core.String> get failingTasks => $_getList(1);
-}
diff --git a/app_dart/lib/src/model/proto/internal/build_status_response.pbenum.dart b/app_dart/lib/src/model/proto/internal/build_status_response.pbenum.dart
deleted file mode 100644
index 7663ad3..0000000
--- a/app_dart/lib/src/model/proto/internal/build_status_response.pbenum.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/build_status_response.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-// ignore_for_file: UNDEFINED_SHOWN_NAME
-import 'dart:core' as $core;
-import 'package:protobuf/protobuf.dart' as $pb;
-
-class EnumBuildStatus extends $pb.ProtobufEnum {
-  static const EnumBuildStatus success =
-      EnumBuildStatus._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'success');
-  static const EnumBuildStatus failure =
-      EnumBuildStatus._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'failure');
-
-  static const $core.List<EnumBuildStatus> values = <EnumBuildStatus>[
-    success,
-    failure,
-  ];
-
-  static final $core.Map<$core.int, EnumBuildStatus> _byValue = $pb.ProtobufEnum.initByValue(values);
-  static EnumBuildStatus? valueOf($core.int value) => _byValue[value];
-
-  const EnumBuildStatus._($core.int v, $core.String n) : super(v, n);
-}
diff --git a/app_dart/lib/src/model/proto/internal/build_status_response.pbjson.dart b/app_dart/lib/src/model/proto/internal/build_status_response.pbjson.dart
deleted file mode 100644
index 768fc3a..0000000
--- a/app_dart/lib/src/model/proto/internal/build_status_response.pbjson.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/build_status_response.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-import 'dart:core' as $core;
-import 'dart:convert' as $convert;
-import 'dart:typed_data' as $typed_data;
-
-@$core.Deprecated('Use enumBuildStatusDescriptor instead')
-const EnumBuildStatus$json = const {
-  '1': 'EnumBuildStatus',
-  '2': const [
-    const {'1': 'success', '2': 1},
-    const {'1': 'failure', '2': 2},
-  ],
-};
-
-/// Descriptor for `EnumBuildStatus`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List enumBuildStatusDescriptor =
-    $convert.base64Decode('Cg9FbnVtQnVpbGRTdGF0dXMSCwoHc3VjY2VzcxABEgsKB2ZhaWx1cmUQAg==');
-@$core.Deprecated('Use buildStatusResponseDescriptor instead')
-const BuildStatusResponse$json = const {
-  '1': 'BuildStatusResponse',
-  '2': const [
-    const {'1': 'build_status', '3': 1, '4': 1, '5': 14, '6': '.cocoon.EnumBuildStatus', '10': 'buildStatus'},
-    const {'1': 'failing_tasks', '3': 2, '4': 3, '5': 9, '10': 'failingTasks'},
-  ],
-};
-
-/// Descriptor for `BuildStatusResponse`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List buildStatusResponseDescriptor = $convert.base64Decode(
-    'ChNCdWlsZFN0YXR1c1Jlc3BvbnNlEjoKDGJ1aWxkX3N0YXR1cxgBIAEoDjIXLmNvY29vbi5FbnVtQnVpbGRTdGF0dXNSC2J1aWxkU3RhdHVzEiMKDWZhaWxpbmdfdGFza3MYAiADKAlSDGZhaWxpbmdUYXNrcw==');
diff --git a/app_dart/lib/src/model/proto/internal/build_status_response.pbserver.dart b/app_dart/lib/src/model/proto/internal/build_status_response.pbserver.dart
deleted file mode 100644
index 9115ba5..0000000
--- a/app_dart/lib/src/model/proto/internal/build_status_response.pbserver.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/build_status_response.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-export 'build_status_response.pb.dart';
diff --git a/app_dart/lib/src/model/proto/internal/build_status_response.proto b/app_dart/lib/src/model/proto/internal/build_status_response.proto
deleted file mode 100644
index a562744..0000000
--- a/app_dart/lib/src/model/proto/internal/build_status_response.proto
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package cocoon;
-
-enum EnumBuildStatus {
-  success = 1;
-  failure = 2;
-}
-
-message BuildStatusResponse {
-    optional EnumBuildStatus build_status = 1;
-    repeated string failing_tasks = 2;
-}
\ No newline at end of file
diff --git a/app_dart/lib/src/model/proto/internal/github_webhook.pb.dart b/app_dart/lib/src/model/proto/internal/github_webhook.pb.dart
deleted file mode 100644
index 2f5fafe..0000000
--- a/app_dart/lib/src/model/proto/internal/github_webhook.pb.dart
+++ /dev/null
@@ -1,83 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/github_webhook.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-import 'dart:core' as $core;
-
-import 'package:protobuf/protobuf.dart' as $pb;
-
-class GithubWebhookMessage extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
-      const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GithubWebhookMessage',
-      package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'cocoon'),
-      createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'event')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'payload')
-    ..hasRequiredFields = false;
-
-  GithubWebhookMessage._() : super();
-  factory GithubWebhookMessage({
-    $core.String? event,
-    $core.String? payload,
-  }) {
-    final _result = create();
-    if (event != null) {
-      _result.event = event;
-    }
-    if (payload != null) {
-      _result.payload = payload;
-    }
-    return _result;
-  }
-  factory GithubWebhookMessage.fromBuffer($core.List<$core.int> i,
-          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory GithubWebhookMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
-      'Will be removed in next major version')
-  GithubWebhookMessage clone() => GithubWebhookMessage()..mergeFromMessage(this);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-      'Will be removed in next major version')
-  GithubWebhookMessage copyWith(void Function(GithubWebhookMessage) updates) =>
-      super.copyWith((message) => updates(message as GithubWebhookMessage))
-          as GithubWebhookMessage; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static GithubWebhookMessage create() => GithubWebhookMessage._();
-  GithubWebhookMessage createEmptyInstance() => create();
-  static $pb.PbList<GithubWebhookMessage> createRepeated() => $pb.PbList<GithubWebhookMessage>();
-  @$core.pragma('dart2js:noInline')
-  static GithubWebhookMessage getDefault() =>
-      _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GithubWebhookMessage>(create);
-  static GithubWebhookMessage? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.String get event => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set event($core.String v) {
-    $_setString(0, v);
-  }
-
-  @$pb.TagNumber(1)
-  $core.bool hasEvent() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearEvent() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.String get payload => $_getSZ(1);
-  @$pb.TagNumber(2)
-  set payload($core.String v) {
-    $_setString(1, v);
-  }
-
-  @$pb.TagNumber(2)
-  $core.bool hasPayload() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearPayload() => clearField(2);
-}
diff --git a/app_dart/lib/src/model/proto/internal/github_webhook.pbenum.dart b/app_dart/lib/src/model/proto/internal/github_webhook.pbenum.dart
deleted file mode 100644
index ef33917..0000000
--- a/app_dart/lib/src/model/proto/internal/github_webhook.pbenum.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/github_webhook.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
diff --git a/app_dart/lib/src/model/proto/internal/github_webhook.pbjson.dart b/app_dart/lib/src/model/proto/internal/github_webhook.pbjson.dart
deleted file mode 100644
index 718d1b9..0000000
--- a/app_dart/lib/src/model/proto/internal/github_webhook.pbjson.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/github_webhook.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-import 'dart:core' as $core;
-import 'dart:convert' as $convert;
-import 'dart:typed_data' as $typed_data;
-
-@$core.Deprecated('Use githubWebhookMessageDescriptor instead')
-const GithubWebhookMessage$json = const {
-  '1': 'GithubWebhookMessage',
-  '2': const [
-    const {'1': 'event', '3': 1, '4': 1, '5': 9, '10': 'event'},
-    const {'1': 'payload', '3': 2, '4': 1, '5': 9, '10': 'payload'},
-  ],
-};
-
-/// Descriptor for `GithubWebhookMessage`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List githubWebhookMessageDescriptor = $convert
-    .base64Decode('ChRHaXRodWJXZWJob29rTWVzc2FnZRIUCgVldmVudBgBIAEoCVIFZXZlbnQSGAoHcGF5bG9hZBgCIAEoCVIHcGF5bG9hZA==');
diff --git a/app_dart/lib/src/model/proto/internal/github_webhook.pbserver.dart b/app_dart/lib/src/model/proto/internal/github_webhook.pbserver.dart
deleted file mode 100644
index 8e8dfb9..0000000
--- a/app_dart/lib/src/model/proto/internal/github_webhook.pbserver.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/github_webhook.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-export 'github_webhook.pb.dart';
diff --git a/app_dart/lib/src/model/proto/internal/github_webhook.proto b/app_dart/lib/src/model/proto/internal/github_webhook.proto
deleted file mode 100644
index 5c28bef..0000000
--- a/app_dart/lib/src/model/proto/internal/github_webhook.proto
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package cocoon;
-
-// For full spec, see:
-//   * https://docs.github.com/webhooks-and-events/webhooks/webhook-events-and-payloads
-message GithubWebhookMessage {
-    // X-GitHub-Event HTTP Header indicating the webhook action.
-    optional string event = 1;
-    // JSON encoded webhook payload from GitHub.
-    optional string payload = 2;
-}
\ No newline at end of file
diff --git a/app_dart/lib/src/model/proto/internal/key.pb.dart b/app_dart/lib/src/model/proto/internal/key.pb.dart
deleted file mode 100644
index 76d26db..0000000
--- a/app_dart/lib/src/model/proto/internal/key.pb.dart
+++ /dev/null
@@ -1,196 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/key.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-import 'dart:core' as $core;
-
-import 'package:fixnum/fixnum.dart' as $fixnum;
-import 'package:protobuf/protobuf.dart' as $pb;
-
-enum Key_Id { uid, name, notSet }
-
-class Key extends $pb.GeneratedMessage {
-  static const $core.Map<$core.int, Key_Id> _Key_IdByTag = {2: Key_Id.uid, 3: Key_Id.name, 0: Key_Id.notSet};
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
-      const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Key',
-      package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'cocoon'),
-      createEmptyInstance: create)
-    ..oo(0, [2, 3])
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'type')
-    ..aInt64(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'uid')
-    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
-    ..aOM<Key>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'child', subBuilder: Key.create)
-    ..hasRequiredFields = false;
-
-  Key._() : super();
-  factory Key({
-    $core.String? type,
-    $fixnum.Int64? uid,
-    $core.String? name,
-    Key? child,
-  }) {
-    final _result = create();
-    if (type != null) {
-      _result.type = type;
-    }
-    if (uid != null) {
-      _result.uid = uid;
-    }
-    if (name != null) {
-      _result.name = name;
-    }
-    if (child != null) {
-      _result.child = child;
-    }
-    return _result;
-  }
-  factory Key.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory Key.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
-      'Will be removed in next major version')
-  Key clone() => Key()..mergeFromMessage(this);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-      'Will be removed in next major version')
-  Key copyWith(void Function(Key) updates) =>
-      super.copyWith((message) => updates(message as Key)) as Key; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static Key create() => Key._();
-  Key createEmptyInstance() => create();
-  static $pb.PbList<Key> createRepeated() => $pb.PbList<Key>();
-  @$core.pragma('dart2js:noInline')
-  static Key getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Key>(create);
-  static Key? _defaultInstance;
-
-  Key_Id whichId() => _Key_IdByTag[$_whichOneof(0)]!;
-  void clearId() => clearField($_whichOneof(0));
-
-  @$pb.TagNumber(1)
-  $core.String get type => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set type($core.String v) {
-    $_setString(0, v);
-  }
-
-  @$pb.TagNumber(1)
-  $core.bool hasType() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearType() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $fixnum.Int64 get uid => $_getI64(1);
-  @$pb.TagNumber(2)
-  set uid($fixnum.Int64 v) {
-    $_setInt64(1, v);
-  }
-
-  @$pb.TagNumber(2)
-  $core.bool hasUid() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearUid() => clearField(2);
-
-  @$pb.TagNumber(3)
-  $core.String get name => $_getSZ(2);
-  @$pb.TagNumber(3)
-  set name($core.String v) {
-    $_setString(2, v);
-  }
-
-  @$pb.TagNumber(3)
-  $core.bool hasName() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearName() => clearField(3);
-
-  @$pb.TagNumber(4)
-  Key get child => $_getN(3);
-  @$pb.TagNumber(4)
-  set child(Key v) {
-    setField(4, v);
-  }
-
-  @$pb.TagNumber(4)
-  $core.bool hasChild() => $_has(3);
-  @$pb.TagNumber(4)
-  void clearChild() => clearField(4);
-  @$pb.TagNumber(4)
-  Key ensureChild() => $_ensure(3);
-}
-
-class RootKey extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
-      const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RootKey',
-      package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'cocoon'),
-      createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'namespace')
-    ..aOM<Key>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'child', subBuilder: Key.create)
-    ..hasRequiredFields = false;
-
-  RootKey._() : super();
-  factory RootKey({
-    $core.String? namespace,
-    Key? child,
-  }) {
-    final _result = create();
-    if (namespace != null) {
-      _result.namespace = namespace;
-    }
-    if (child != null) {
-      _result.child = child;
-    }
-    return _result;
-  }
-  factory RootKey.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory RootKey.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
-      'Will be removed in next major version')
-  RootKey clone() => RootKey()..mergeFromMessage(this);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-      'Will be removed in next major version')
-  RootKey copyWith(void Function(RootKey) updates) =>
-      super.copyWith((message) => updates(message as RootKey)) as RootKey; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static RootKey create() => RootKey._();
-  RootKey createEmptyInstance() => create();
-  static $pb.PbList<RootKey> createRepeated() => $pb.PbList<RootKey>();
-  @$core.pragma('dart2js:noInline')
-  static RootKey getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RootKey>(create);
-  static RootKey? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.String get namespace => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set namespace($core.String v) {
-    $_setString(0, v);
-  }
-
-  @$pb.TagNumber(1)
-  $core.bool hasNamespace() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearNamespace() => clearField(1);
-
-  @$pb.TagNumber(2)
-  Key get child => $_getN(1);
-  @$pb.TagNumber(2)
-  set child(Key v) {
-    setField(2, v);
-  }
-
-  @$pb.TagNumber(2)
-  $core.bool hasChild() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearChild() => clearField(2);
-  @$pb.TagNumber(2)
-  Key ensureChild() => $_ensure(1);
-}
diff --git a/app_dart/lib/src/model/proto/internal/key.pbenum.dart b/app_dart/lib/src/model/proto/internal/key.pbenum.dart
deleted file mode 100644
index 1c5e28e..0000000
--- a/app_dart/lib/src/model/proto/internal/key.pbenum.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/key.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
diff --git a/app_dart/lib/src/model/proto/internal/key.pbjson.dart b/app_dart/lib/src/model/proto/internal/key.pbjson.dart
deleted file mode 100644
index 315a58e..0000000
--- a/app_dart/lib/src/model/proto/internal/key.pbjson.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/key.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-import 'dart:core' as $core;
-import 'dart:convert' as $convert;
-import 'dart:typed_data' as $typed_data;
-
-@$core.Deprecated('Use keyDescriptor instead')
-const Key$json = const {
-  '1': 'Key',
-  '2': const [
-    const {'1': 'type', '3': 1, '4': 1, '5': 9, '10': 'type'},
-    const {'1': 'uid', '3': 2, '4': 1, '5': 3, '9': 0, '10': 'uid'},
-    const {'1': 'name', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'name'},
-    const {'1': 'child', '3': 4, '4': 1, '5': 11, '6': '.cocoon.Key', '10': 'child'},
-  ],
-  '8': const [
-    const {'1': 'id'},
-  ],
-};
-
-/// Descriptor for `Key`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List keyDescriptor = $convert.base64Decode(
-    'CgNLZXkSEgoEdHlwZRgBIAEoCVIEdHlwZRISCgN1aWQYAiABKANIAFIDdWlkEhQKBG5hbWUYAyABKAlIAFIEbmFtZRIhCgVjaGlsZBgEIAEoCzILLmNvY29vbi5LZXlSBWNoaWxkQgQKAmlk');
-@$core.Deprecated('Use rootKeyDescriptor instead')
-const RootKey$json = const {
-  '1': 'RootKey',
-  '2': const [
-    const {'1': 'namespace', '3': 1, '4': 1, '5': 9, '10': 'namespace'},
-    const {'1': 'child', '3': 2, '4': 1, '5': 11, '6': '.cocoon.Key', '10': 'child'},
-  ],
-};
-
-/// Descriptor for `RootKey`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List rootKeyDescriptor = $convert.base64Decode(
-    'CgdSb290S2V5EhwKCW5hbWVzcGFjZRgBIAEoCVIJbmFtZXNwYWNlEiEKBWNoaWxkGAIgASgLMgsuY29jb29uLktleVIFY2hpbGQ=');
diff --git a/app_dart/lib/src/model/proto/internal/key.pbserver.dart b/app_dart/lib/src/model/proto/internal/key.pbserver.dart
deleted file mode 100644
index 92721a9..0000000
--- a/app_dart/lib/src/model/proto/internal/key.pbserver.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/key.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-export 'key.pb.dart';
diff --git a/app_dart/lib/src/model/proto/internal/key.proto b/app_dart/lib/src/model/proto/internal/key.proto
deleted file mode 100644
index 262418f..0000000
--- a/app_dart/lib/src/model/proto/internal/key.proto
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package cocoon;
-
-message Key {
-    optional string type = 1;
-
-    oneof id {
-        int64 uid = 2;
-        string name = 3;
-    }
-
-    optional Key child = 4;
-}
-
-message RootKey {
-    optional string namespace = 1;
-    optional Key child = 2;
-}
diff --git a/app_dart/lib/src/model/proto/internal/scheduler.pb.dart b/app_dart/lib/src/model/proto/internal/scheduler.pb.dart
deleted file mode 100644
index f79eede..0000000
--- a/app_dart/lib/src/model/proto/internal/scheduler.pb.dart
+++ /dev/null
@@ -1,437 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/scheduler.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-import 'dart:core' as $core;
-
-import 'package:protobuf/protobuf.dart' as $pb;
-
-import 'scheduler.pbenum.dart';
-
-export 'scheduler.pbenum.dart';
-
-class SchedulerConfig_PlatformProperties extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
-      const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SchedulerConfig.PlatformProperties',
-      package:
-          const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'scheduler'),
-      createEmptyInstance: create)
-    ..m<$core.String, $core.String>(
-        1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'properties',
-        entryClassName: 'SchedulerConfig.PlatformProperties.PropertiesEntry',
-        keyFieldType: $pb.PbFieldType.OS,
-        valueFieldType: $pb.PbFieldType.OS,
-        packageName: const $pb.PackageName('scheduler'))
-    ..m<$core.String, $core.String>(
-        2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dimensions',
-        entryClassName: 'SchedulerConfig.PlatformProperties.DimensionsEntry',
-        keyFieldType: $pb.PbFieldType.OS,
-        valueFieldType: $pb.PbFieldType.OS,
-        packageName: const $pb.PackageName('scheduler'))
-    ..hasRequiredFields = false;
-
-  SchedulerConfig_PlatformProperties._() : super();
-  factory SchedulerConfig_PlatformProperties({
-    $core.Map<$core.String, $core.String>? properties,
-    $core.Map<$core.String, $core.String>? dimensions,
-  }) {
-    final _result = create();
-    if (properties != null) {
-      _result.properties.addAll(properties);
-    }
-    if (dimensions != null) {
-      _result.dimensions.addAll(dimensions);
-    }
-    return _result;
-  }
-  factory SchedulerConfig_PlatformProperties.fromBuffer($core.List<$core.int> i,
-          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory SchedulerConfig_PlatformProperties.fromJson($core.String i,
-          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
-      'Will be removed in next major version')
-  SchedulerConfig_PlatformProperties clone() => SchedulerConfig_PlatformProperties()..mergeFromMessage(this);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-      'Will be removed in next major version')
-  SchedulerConfig_PlatformProperties copyWith(void Function(SchedulerConfig_PlatformProperties) updates) =>
-      super.copyWith((message) => updates(message as SchedulerConfig_PlatformProperties))
-          as SchedulerConfig_PlatformProperties; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static SchedulerConfig_PlatformProperties create() => SchedulerConfig_PlatformProperties._();
-  SchedulerConfig_PlatformProperties createEmptyInstance() => create();
-  static $pb.PbList<SchedulerConfig_PlatformProperties> createRepeated() =>
-      $pb.PbList<SchedulerConfig_PlatformProperties>();
-  @$core.pragma('dart2js:noInline')
-  static SchedulerConfig_PlatformProperties getDefault() =>
-      _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SchedulerConfig_PlatformProperties>(create);
-  static SchedulerConfig_PlatformProperties? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.Map<$core.String, $core.String> get properties => $_getMap(0);
-
-  @$pb.TagNumber(2)
-  $core.Map<$core.String, $core.String> get dimensions => $_getMap(1);
-}
-
-class SchedulerConfig extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
-      const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SchedulerConfig',
-      package:
-          const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'scheduler'),
-      createEmptyInstance: create)
-    ..pc<Target>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'targets', $pb.PbFieldType.PM,
-        subBuilder: Target.create)
-    ..pPS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'enabledBranches')
-    ..m<$core.String, SchedulerConfig_PlatformProperties>(
-        3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'platformProperties',
-        entryClassName: 'SchedulerConfig.PlatformPropertiesEntry',
-        keyFieldType: $pb.PbFieldType.OS,
-        valueFieldType: $pb.PbFieldType.OM,
-        valueCreator: SchedulerConfig_PlatformProperties.create,
-        packageName: const $pb.PackageName('scheduler'))
-    ..hasRequiredFields = false;
-
-  SchedulerConfig._() : super();
-  factory SchedulerConfig({
-    $core.Iterable<Target>? targets,
-    $core.Iterable<$core.String>? enabledBranches,
-    $core.Map<$core.String, SchedulerConfig_PlatformProperties>? platformProperties,
-  }) {
-    final _result = create();
-    if (targets != null) {
-      _result.targets.addAll(targets);
-    }
-    if (enabledBranches != null) {
-      _result.enabledBranches.addAll(enabledBranches);
-    }
-    if (platformProperties != null) {
-      _result.platformProperties.addAll(platformProperties);
-    }
-    return _result;
-  }
-  factory SchedulerConfig.fromBuffer($core.List<$core.int> i,
-          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory SchedulerConfig.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
-      'Will be removed in next major version')
-  SchedulerConfig clone() => SchedulerConfig()..mergeFromMessage(this);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-      'Will be removed in next major version')
-  SchedulerConfig copyWith(void Function(SchedulerConfig) updates) =>
-      super.copyWith((message) => updates(message as SchedulerConfig))
-          as SchedulerConfig; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static SchedulerConfig create() => SchedulerConfig._();
-  SchedulerConfig createEmptyInstance() => create();
-  static $pb.PbList<SchedulerConfig> createRepeated() => $pb.PbList<SchedulerConfig>();
-  @$core.pragma('dart2js:noInline')
-  static SchedulerConfig getDefault() =>
-      _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SchedulerConfig>(create);
-  static SchedulerConfig? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.List<Target> get targets => $_getList(0);
-
-  @$pb.TagNumber(2)
-  $core.List<$core.String> get enabledBranches => $_getList(1);
-
-  @$pb.TagNumber(3)
-  $core.Map<$core.String, SchedulerConfig_PlatformProperties> get platformProperties => $_getMap(2);
-}
-
-class Target extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
-      const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Target',
-      package:
-          const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'scheduler'),
-      createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
-    ..pPS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dependencies')
-    ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'bringup')
-    ..a<$core.int>(
-        4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeout', $pb.PbFieldType.O3,
-        defaultOrMaker: 30)
-    ..a<$core.String>(
-        5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'testbed', $pb.PbFieldType.OS,
-        defaultOrMaker: 'linux-vm')
-    ..m<$core.String, $core.String>(
-        6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'properties',
-        entryClassName: 'Target.PropertiesEntry',
-        keyFieldType: $pb.PbFieldType.OS,
-        valueFieldType: $pb.PbFieldType.OS,
-        packageName: const $pb.PackageName('scheduler'))
-    ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'builder')
-    ..e<SchedulerSystem>(
-        8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scheduler', $pb.PbFieldType.OE,
-        defaultOrMaker: SchedulerSystem.cocoon, valueOf: SchedulerSystem.valueOf, enumValues: SchedulerSystem.values)
-    ..a<$core.bool>(
-        9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'presubmit', $pb.PbFieldType.OB,
-        defaultOrMaker: true)
-    ..a<$core.bool>(
-        10, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'postsubmit', $pb.PbFieldType.OB,
-        defaultOrMaker: true)
-    ..pPS(11, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'runIf')
-    ..pPS(12, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'enabledBranches')
-    ..aOS(13, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'recipe')
-    ..m<$core.String, $core.String>(
-        15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'postsubmitProperties',
-        entryClassName: 'Target.PostsubmitPropertiesEntry',
-        keyFieldType: $pb.PbFieldType.OS,
-        valueFieldType: $pb.PbFieldType.OS,
-        packageName: const $pb.PackageName('scheduler'))
-    ..m<$core.String, $core.String>(
-        16, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dimensions',
-        entryClassName: 'Target.DimensionsEntry',
-        keyFieldType: $pb.PbFieldType.OS,
-        valueFieldType: $pb.PbFieldType.OS,
-        packageName: const $pb.PackageName('scheduler'))
-    ..pPS(17, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'droneDimensions')
-    ..pPS(18, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'runIfNot')
-    ..hasRequiredFields = false;
-
-  Target._() : super();
-  factory Target({
-    $core.String? name,
-    $core.Iterable<$core.String>? dependencies,
-    $core.bool? bringup,
-    $core.int? timeout,
-    $core.String? testbed,
-    $core.Map<$core.String, $core.String>? properties,
-    @$core.Deprecated('This field is deprecated.') $core.String? builder,
-    SchedulerSystem? scheduler,
-    $core.bool? presubmit,
-    $core.bool? postsubmit,
-    $core.Iterable<$core.String>? runIf,
-    $core.Iterable<$core.String>? enabledBranches,
-    $core.String? recipe,
-    $core.Map<$core.String, $core.String>? postsubmitProperties,
-    $core.Map<$core.String, $core.String>? dimensions,
-    $core.Iterable<$core.String>? droneDimensions,
-    $core.Iterable<$core.String>? runIfNot,
-  }) {
-    final _result = create();
-    if (name != null) {
-      _result.name = name;
-    }
-    if (dependencies != null) {
-      _result.dependencies.addAll(dependencies);
-    }
-    if (bringup != null) {
-      _result.bringup = bringup;
-    }
-    if (timeout != null) {
-      _result.timeout = timeout;
-    }
-    if (testbed != null) {
-      _result.testbed = testbed;
-    }
-    if (properties != null) {
-      _result.properties.addAll(properties);
-    }
-    if (builder != null) {
-      // ignore: deprecated_member_use_from_same_package
-      _result.builder = builder;
-    }
-    if (scheduler != null) {
-      _result.scheduler = scheduler;
-    }
-    if (presubmit != null) {
-      _result.presubmit = presubmit;
-    }
-    if (postsubmit != null) {
-      _result.postsubmit = postsubmit;
-    }
-    if (runIf != null) {
-      _result.runIf.addAll(runIf);
-    }
-    if (enabledBranches != null) {
-      _result.enabledBranches.addAll(enabledBranches);
-    }
-    if (recipe != null) {
-      _result.recipe = recipe;
-    }
-    if (postsubmitProperties != null) {
-      _result.postsubmitProperties.addAll(postsubmitProperties);
-    }
-    if (dimensions != null) {
-      _result.dimensions.addAll(dimensions);
-    }
-    if (droneDimensions != null) {
-      _result.droneDimensions.addAll(droneDimensions);
-    }
-    if (runIfNot != null) {
-      _result.runIfNot.addAll(runIfNot);
-    }
-    return _result;
-  }
-  factory Target.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory Target.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
-      'Will be removed in next major version')
-  Target clone() => Target()..mergeFromMessage(this);
-  @$core.Deprecated('Using this can add significant overhead to your binary. '
-      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-      'Will be removed in next major version')
-  Target copyWith(void Function(Target) updates) =>
-      super.copyWith((message) => updates(message as Target)) as Target; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static Target create() => Target._();
-  Target createEmptyInstance() => create();
-  static $pb.PbList<Target> createRepeated() => $pb.PbList<Target>();
-  @$core.pragma('dart2js:noInline')
-  static Target getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Target>(create);
-  static Target? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.String get name => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set name($core.String v) {
-    $_setString(0, v);
-  }
-
-  @$pb.TagNumber(1)
-  $core.bool hasName() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearName() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.List<$core.String> get dependencies => $_getList(1);
-
-  @$pb.TagNumber(3)
-  $core.bool get bringup => $_getBF(2);
-  @$pb.TagNumber(3)
-  set bringup($core.bool v) {
-    $_setBool(2, v);
-  }
-
-  @$pb.TagNumber(3)
-  $core.bool hasBringup() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearBringup() => clearField(3);
-
-  @$pb.TagNumber(4)
-  $core.int get timeout => $_getI(3, 30);
-  @$pb.TagNumber(4)
-  set timeout($core.int v) {
-    $_setSignedInt32(3, v);
-  }
-
-  @$pb.TagNumber(4)
-  $core.bool hasTimeout() => $_has(3);
-  @$pb.TagNumber(4)
-  void clearTimeout() => clearField(4);
-
-  @$pb.TagNumber(5)
-  $core.String get testbed => $_getS(4, 'linux-vm');
-  @$pb.TagNumber(5)
-  set testbed($core.String v) {
-    $_setString(4, v);
-  }
-
-  @$pb.TagNumber(5)
-  $core.bool hasTestbed() => $_has(4);
-  @$pb.TagNumber(5)
-  void clearTestbed() => clearField(5);
-
-  @$pb.TagNumber(6)
-  $core.Map<$core.String, $core.String> get properties => $_getMap(5);
-
-  @$core.Deprecated('This field is deprecated.')
-  @$pb.TagNumber(7)
-  $core.String get builder => $_getSZ(6);
-  @$core.Deprecated('This field is deprecated.')
-  @$pb.TagNumber(7)
-  set builder($core.String v) {
-    $_setString(6, v);
-  }
-
-  @$core.Deprecated('This field is deprecated.')
-  @$pb.TagNumber(7)
-  $core.bool hasBuilder() => $_has(6);
-  @$core.Deprecated('This field is deprecated.')
-  @$pb.TagNumber(7)
-  void clearBuilder() => clearField(7);
-
-  @$pb.TagNumber(8)
-  SchedulerSystem get scheduler => $_getN(7);
-  @$pb.TagNumber(8)
-  set scheduler(SchedulerSystem v) {
-    setField(8, v);
-  }
-
-  @$pb.TagNumber(8)
-  $core.bool hasScheduler() => $_has(7);
-  @$pb.TagNumber(8)
-  void clearScheduler() => clearField(8);
-
-  @$pb.TagNumber(9)
-  $core.bool get presubmit => $_getB(8, true);
-  @$pb.TagNumber(9)
-  set presubmit($core.bool v) {
-    $_setBool(8, v);
-  }
-
-  @$pb.TagNumber(9)
-  $core.bool hasPresubmit() => $_has(8);
-  @$pb.TagNumber(9)
-  void clearPresubmit() => clearField(9);
-
-  @$pb.TagNumber(10)
-  $core.bool get postsubmit => $_getB(9, true);
-  @$pb.TagNumber(10)
-  set postsubmit($core.bool v) {
-    $_setBool(9, v);
-  }
-
-  @$pb.TagNumber(10)
-  $core.bool hasPostsubmit() => $_has(9);
-  @$pb.TagNumber(10)
-  void clearPostsubmit() => clearField(10);
-
-  @$pb.TagNumber(11)
-  $core.List<$core.String> get runIf => $_getList(10);
-
-  @$pb.TagNumber(12)
-  $core.List<$core.String> get enabledBranches => $_getList(11);
-
-  @$pb.TagNumber(13)
-  $core.String get recipe => $_getSZ(12);
-  @$pb.TagNumber(13)
-  set recipe($core.String v) {
-    $_setString(12, v);
-  }
-
-  @$pb.TagNumber(13)
-  $core.bool hasRecipe() => $_has(12);
-  @$pb.TagNumber(13)
-  void clearRecipe() => clearField(13);
-
-  @$pb.TagNumber(15)
-  $core.Map<$core.String, $core.String> get postsubmitProperties => $_getMap(13);
-
-  @$pb.TagNumber(16)
-  $core.Map<$core.String, $core.String> get dimensions => $_getMap(14);
-
-  @$pb.TagNumber(17)
-  $core.List<$core.String> get droneDimensions => $_getList(15);
-
-  @$pb.TagNumber(18)
-  $core.List<$core.String> get runIfNot => $_getList(16);
-}
diff --git a/app_dart/lib/src/model/proto/internal/scheduler.pbenum.dart b/app_dart/lib/src/model/proto/internal/scheduler.pbenum.dart
deleted file mode 100644
index 8e09bd7..0000000
--- a/app_dart/lib/src/model/proto/internal/scheduler.pbenum.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/scheduler.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-// ignore_for_file: UNDEFINED_SHOWN_NAME
-import 'dart:core' as $core;
-import 'package:protobuf/protobuf.dart' as $pb;
-
-class SchedulerSystem extends $pb.ProtobufEnum {
-  static const SchedulerSystem cocoon =
-      SchedulerSystem._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'cocoon');
-  static const SchedulerSystem luci =
-      SchedulerSystem._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'luci');
-  static const SchedulerSystem google_internal =
-      SchedulerSystem._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'google_internal');
-  static const SchedulerSystem release =
-      SchedulerSystem._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'release');
-
-  static const $core.List<SchedulerSystem> values = <SchedulerSystem>[
-    cocoon,
-    luci,
-    google_internal,
-    release,
-  ];
-
-  static final $core.Map<$core.int, SchedulerSystem> _byValue = $pb.ProtobufEnum.initByValue(values);
-  static SchedulerSystem? valueOf($core.int value) => _byValue[value];
-
-  const SchedulerSystem._($core.int v, $core.String n) : super(v, n);
-}
diff --git a/app_dart/lib/src/model/proto/internal/scheduler.pbjson.dart b/app_dart/lib/src/model/proto/internal/scheduler.pbjson.dart
deleted file mode 100644
index 5e04860..0000000
--- a/app_dart/lib/src/model/proto/internal/scheduler.pbjson.dart
+++ /dev/null
@@ -1,186 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/scheduler.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-import 'dart:core' as $core;
-import 'dart:convert' as $convert;
-import 'dart:typed_data' as $typed_data;
-
-@$core.Deprecated('Use schedulerSystemDescriptor instead')
-const SchedulerSystem$json = const {
-  '1': 'SchedulerSystem',
-  '2': const [
-    const {'1': 'cocoon', '2': 1},
-    const {'1': 'luci', '2': 2},
-    const {'1': 'google_internal', '2': 3},
-    const {'1': 'release', '2': 4},
-  ],
-};
-
-/// Descriptor for `SchedulerSystem`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List schedulerSystemDescriptor = $convert.base64Decode(
-    'Cg9TY2hlZHVsZXJTeXN0ZW0SCgoGY29jb29uEAESCAoEbHVjaRACEhMKD2dvb2dsZV9pbnRlcm5hbBADEgsKB3JlbGVhc2UQBA==');
-@$core.Deprecated('Use schedulerConfigDescriptor instead')
-const SchedulerConfig$json = const {
-  '1': 'SchedulerConfig',
-  '2': const [
-    const {'1': 'targets', '3': 1, '4': 3, '5': 11, '6': '.scheduler.Target', '10': 'targets'},
-    const {'1': 'enabled_branches', '3': 2, '4': 3, '5': 9, '10': 'enabledBranches'},
-    const {
-      '1': 'platform_properties',
-      '3': 3,
-      '4': 3,
-      '5': 11,
-      '6': '.scheduler.SchedulerConfig.PlatformPropertiesEntry',
-      '10': 'platformProperties'
-    },
-  ],
-  '3': const [SchedulerConfig_PlatformPropertiesEntry$json, SchedulerConfig_PlatformProperties$json],
-};
-
-@$core.Deprecated('Use schedulerConfigDescriptor instead')
-const SchedulerConfig_PlatformPropertiesEntry$json = const {
-  '1': 'PlatformPropertiesEntry',
-  '2': const [
-    const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
-    const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.scheduler.SchedulerConfig.PlatformProperties', '10': 'value'},
-  ],
-  '7': const {'7': true},
-};
-
-@$core.Deprecated('Use schedulerConfigDescriptor instead')
-const SchedulerConfig_PlatformProperties$json = const {
-  '1': 'PlatformProperties',
-  '2': const [
-    const {
-      '1': 'properties',
-      '3': 1,
-      '4': 3,
-      '5': 11,
-      '6': '.scheduler.SchedulerConfig.PlatformProperties.PropertiesEntry',
-      '10': 'properties'
-    },
-    const {
-      '1': 'dimensions',
-      '3': 2,
-      '4': 3,
-      '5': 11,
-      '6': '.scheduler.SchedulerConfig.PlatformProperties.DimensionsEntry',
-      '10': 'dimensions'
-    },
-  ],
-  '3': const [
-    SchedulerConfig_PlatformProperties_PropertiesEntry$json,
-    SchedulerConfig_PlatformProperties_DimensionsEntry$json
-  ],
-};
-
-@$core.Deprecated('Use schedulerConfigDescriptor instead')
-const SchedulerConfig_PlatformProperties_PropertiesEntry$json = const {
-  '1': 'PropertiesEntry',
-  '2': const [
-    const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
-    const {'1': 'value', '3': 2, '4': 1, '5': 9, '10': 'value'},
-  ],
-  '7': const {'7': true},
-};
-
-@$core.Deprecated('Use schedulerConfigDescriptor instead')
-const SchedulerConfig_PlatformProperties_DimensionsEntry$json = const {
-  '1': 'DimensionsEntry',
-  '2': const [
-    const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
-    const {'1': 'value', '3': 2, '4': 1, '5': 9, '10': 'value'},
-  ],
-  '7': const {'7': true},
-};
-
-/// Descriptor for `SchedulerConfig`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List schedulerConfigDescriptor = $convert.base64Decode(
-    'Cg9TY2hlZHVsZXJDb25maWcSKwoHdGFyZ2V0cxgBIAMoCzIRLnNjaGVkdWxlci5UYXJnZXRSB3RhcmdldHMSKQoQZW5hYmxlZF9icmFuY2hlcxgCIAMoCVIPZW5hYmxlZEJyYW5jaGVzEmMKE3BsYXRmb3JtX3Byb3BlcnRpZXMYAyADKAsyMi5zY2hlZHVsZXIuU2NoZWR1bGVyQ29uZmlnLlBsYXRmb3JtUHJvcGVydGllc0VudHJ5UhJwbGF0Zm9ybVByb3BlcnRpZXMadAoXUGxhdGZvcm1Qcm9wZXJ0aWVzRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSQwoFdmFsdWUYAiABKAsyLS5zY2hlZHVsZXIuU2NoZWR1bGVyQ29uZmlnLlBsYXRmb3JtUHJvcGVydGllc1IFdmFsdWU6AjgBGtACChJQbGF0Zm9ybVByb3BlcnRpZXMSXQoKcHJvcGVydGllcxgBIAMoCzI9LnNjaGVkdWxlci5TY2hlZHVsZXJDb25maWcuUGxhdGZvcm1Qcm9wZXJ0aWVzLlByb3BlcnRpZXNFbnRyeVIKcHJvcGVydGllcxJdCgpkaW1lbnNpb25zGAIgAygLMj0uc2NoZWR1bGVyLlNjaGVkdWxlckNvbmZpZy5QbGF0Zm9ybVByb3BlcnRpZXMuRGltZW5zaW9uc0VudHJ5UgpkaW1lbnNpb25zGj0KD1Byb3BlcnRpZXNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIUCgV2YWx1ZRgCIAEoCVIFdmFsdWU6AjgBGj0KD0RpbWVuc2lvbnNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIUCgV2YWx1ZRgCIAEoCVIFdmFsdWU6AjgB');
-@$core.Deprecated('Use targetDescriptor instead')
-const Target$json = const {
-  '1': 'Target',
-  '2': const [
-    const {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'},
-    const {'1': 'dependencies', '3': 2, '4': 3, '5': 9, '10': 'dependencies'},
-    const {'1': 'bringup', '3': 3, '4': 1, '5': 8, '7': 'false', '10': 'bringup'},
-    const {'1': 'timeout', '3': 4, '4': 1, '5': 5, '7': '30', '10': 'timeout'},
-    const {'1': 'testbed', '3': 5, '4': 1, '5': 9, '7': 'linux-vm', '10': 'testbed'},
-    const {'1': 'properties', '3': 6, '4': 3, '5': 11, '6': '.scheduler.Target.PropertiesEntry', '10': 'properties'},
-    const {
-      '1': 'builder',
-      '3': 7,
-      '4': 1,
-      '5': 9,
-      '8': const {'3': true},
-      '10': 'builder',
-    },
-    const {
-      '1': 'scheduler',
-      '3': 8,
-      '4': 1,
-      '5': 14,
-      '6': '.scheduler.SchedulerSystem',
-      '7': 'cocoon',
-      '10': 'scheduler'
-    },
-    const {'1': 'presubmit', '3': 9, '4': 1, '5': 8, '7': 'true', '10': 'presubmit'},
-    const {'1': 'postsubmit', '3': 10, '4': 1, '5': 8, '7': 'true', '10': 'postsubmit'},
-    const {'1': 'run_if', '3': 11, '4': 3, '5': 9, '10': 'runIf'},
-    const {'1': 'enabled_branches', '3': 12, '4': 3, '5': 9, '10': 'enabledBranches'},
-    const {'1': 'recipe', '3': 13, '4': 1, '5': 9, '10': 'recipe'},
-    const {
-      '1': 'postsubmit_properties',
-      '3': 15,
-      '4': 3,
-      '5': 11,
-      '6': '.scheduler.Target.PostsubmitPropertiesEntry',
-      '10': 'postsubmitProperties'
-    },
-    const {'1': 'dimensions', '3': 16, '4': 3, '5': 11, '6': '.scheduler.Target.DimensionsEntry', '10': 'dimensions'},
-    const {'1': 'drone_dimensions', '3': 17, '4': 3, '5': 9, '10': 'droneDimensions'},
-    const {'1': 'run_if_not', '3': 18, '4': 3, '5': 9, '10': 'runIfNot'},
-  ],
-  '3': const [Target_PropertiesEntry$json, Target_PostsubmitPropertiesEntry$json, Target_DimensionsEntry$json],
-  '9': const [
-    const {'1': 14, '2': 15},
-  ],
-};
-
-@$core.Deprecated('Use targetDescriptor instead')
-const Target_PropertiesEntry$json = const {
-  '1': 'PropertiesEntry',
-  '2': const [
-    const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
-    const {'1': 'value', '3': 2, '4': 1, '5': 9, '10': 'value'},
-  ],
-  '7': const {'7': true},
-};
-
-@$core.Deprecated('Use targetDescriptor instead')
-const Target_PostsubmitPropertiesEntry$json = const {
-  '1': 'PostsubmitPropertiesEntry',
-  '2': const [
-    const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
-    const {'1': 'value', '3': 2, '4': 1, '5': 9, '10': 'value'},
-  ],
-  '7': const {'7': true},
-};
-
-@$core.Deprecated('Use targetDescriptor instead')
-const Target_DimensionsEntry$json = const {
-  '1': 'DimensionsEntry',
-  '2': const [
-    const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
-    const {'1': 'value', '3': 2, '4': 1, '5': 9, '10': 'value'},
-  ],
-  '7': const {'7': true},
-};
-
-/// Descriptor for `Target`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List targetDescriptor = $convert.base64Decode(
-    'CgZUYXJnZXQSEgoEbmFtZRgBIAEoCVIEbmFtZRIiCgxkZXBlbmRlbmNpZXMYAiADKAlSDGRlcGVuZGVuY2llcxIfCgdicmluZ3VwGAMgASgIOgVmYWxzZVIHYnJpbmd1cBIcCgd0aW1lb3V0GAQgASgFOgIzMFIHdGltZW91dBIiCgd0ZXN0YmVkGAUgASgJOghsaW51eC12bVIHdGVzdGJlZBJBCgpwcm9wZXJ0aWVzGAYgAygLMiEuc2NoZWR1bGVyLlRhcmdldC5Qcm9wZXJ0aWVzRW50cnlSCnByb3BlcnRpZXMSHAoHYnVpbGRlchgHIAEoCUICGAFSB2J1aWxkZXISQAoJc2NoZWR1bGVyGAggASgOMhouc2NoZWR1bGVyLlNjaGVkdWxlclN5c3RlbToGY29jb29uUglzY2hlZHVsZXISIgoJcHJlc3VibWl0GAkgASgIOgR0cnVlUglwcmVzdWJtaXQSJAoKcG9zdHN1Ym1pdBgKIAEoCDoEdHJ1ZVIKcG9zdHN1Ym1pdBIVCgZydW5faWYYCyADKAlSBXJ1bklmEikKEGVuYWJsZWRfYnJhbmNoZXMYDCADKAlSD2VuYWJsZWRCcmFuY2hlcxIWCgZyZWNpcGUYDSABKAlSBnJlY2lwZRJgChVwb3N0c3VibWl0X3Byb3BlcnRpZXMYDyADKAsyKy5zY2hlZHVsZXIuVGFyZ2V0LlBvc3RzdWJtaXRQcm9wZXJ0aWVzRW50cnlSFHBvc3RzdWJtaXRQcm9wZXJ0aWVzEkEKCmRpbWVuc2lvbnMYECADKAsyIS5zY2hlZHVsZXIuVGFyZ2V0LkRpbWVuc2lvbnNFbnRyeVIKZGltZW5zaW9ucxIpChBkcm9uZV9kaW1lbnNpb25zGBEgAygJUg9kcm9uZURpbWVuc2lvbnMSHAoKcnVuX2lmX25vdBgSIAMoCVIIcnVuSWZOb3QaPQoPUHJvcGVydGllc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgJUgV2YWx1ZToCOAEaRwoZUG9zdHN1Ym1pdFByb3BlcnRpZXNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIUCgV2YWx1ZRgCIAEoCVIFdmFsdWU6AjgBGj0KD0RpbWVuc2lvbnNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIUCgV2YWx1ZRgCIAEoCVIFdmFsdWU6AjgBSgQIDhAP');
diff --git a/app_dart/lib/src/model/proto/internal/scheduler.pbserver.dart b/app_dart/lib/src/model/proto/internal/scheduler.pbserver.dart
deleted file mode 100644
index a16fa83..0000000
--- a/app_dart/lib/src/model/proto/internal/scheduler.pbserver.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: lib/src/model/proto/internal/scheduler.proto
-//
-// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
-
-export 'scheduler.pb.dart';
diff --git a/app_dart/lib/src/model/proto/internal/scheduler.proto b/app_dart/lib/src/model/proto/internal/scheduler.proto
deleted file mode 100644
index a0df483..0000000
--- a/app_dart/lib/src/model/proto/internal/scheduler.proto
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package scheduler;
-
-// Model of .ci.yaml.
-// Next ID: 4
-message SchedulerConfig {
-    // Targets to run from this config.
-    repeated Target targets = 1;
-    // Git branches to run these targets against.
-    repeated string enabled_branches = 2;
-    // Universal platform args passed to LUCI builders.
-    // Keys are the platforms and values are the PlatformProperties (properties, dimensions etc.).
-    map<string, PlatformProperties> platform_properties = 3;
-    // Next ID: 3
-    message PlatformProperties {
-        // Generic key, value pairs to set platform-wide properties
-        map<string, string> properties = 1;
-        // Generic key, value pairs to set platform-wide dimensions
-        // Doc for dimension and properties: https://chromium.googlesource.com/infra/luci/luci-py/+/HEAD/appengine/swarming/doc/User-Guide.md
-        map<string, string> dimensions = 2;
-    }
-}
-
-// A unit of work for infrastructure to run.
-// Next ID: 17
-message Target {
-    // Unique, human readable identifier.
-    optional string name = 1;
-    // Names of other targets required to succeed before triggering this target.
-    repeated string dependencies = 2;
-    // Whether this target is stable and can be used to gate commits.
-    // Defaults to false which blocks builds and does not run in presubmit.
-    optional bool bringup = 3 [default = false];
-    // Number of minutes this target is allowed to run before being marked as failed.
-    optional int32 timeout = 4 [default = 30];
-    // Name of the testbed this target will run on.
-    // Defaults to a linux vm.
-    optional string testbed = 5 [default = 'linux-vm'];
-    // Properties to configure infrastructure tooling.
-    map<string, string> properties = 6;
-    // Name of the LUCI builder to trigger.
-    optional string builder = 7 [deprecated = true];
-    // Name of the scheduler to trigger this target.
-    // Defaults to being triggered by cocoon.
-    optional SchedulerSystem scheduler = 8 [default = cocoon];
-    // Whether target should run pre-submit. Defaults to true, will run in presubmit.
-    optional bool presubmit = 9 [default = true];
-    // Whether target should run post-submit. Defaults to true, will run in postsubmit.
-    optional bool postsubmit = 10 [default = true];
-    // List of paths that trigger this target in presubmit when there is a diff.
-    // If no paths are given, it will always run.
-    repeated string run_if = 11;
-    // Override of enabled_branches for this target (for release targets).
-    repeated string enabled_branches = 12;
-    // Name of the LUCI recipe to use for the builder.
-    optional string recipe = 13;
-    reserved 14; // tags
-    // Properties to configure infrastructure tooling for only postsubmit runs.
-    map<string, string> postsubmit_properties = 15;
-    // Dimensions to configure swarming dimensions of LUCI builds.
-    map<string, string> dimensions = 16;
-    // Dimensions used when this build runs within a drone.
-    repeated string drone_dimensions = 17;
-    // Runs the target if files are not in these paths.
-    repeated string run_if_not = 18;
-}
-
-// Schedulers supported in SchedulerConfig.
-// Next ID: 5
-enum SchedulerSystem {
-    // Cocoon will handle all actions for the target (initial trigger, retries).
-    cocoon = 1;
-    // LUCI triggers the build when mirrored to GoB. Cocoon triggers retries.
-    luci = 2;
-    // Google internally uses Flutter, and validates if tip-of-tree causes breakages.
-    google_internal = 3;
-    // Special Cocoon scheduler case to trigger targets intended for beta and stable releases.
-    release = 4;
-}
diff --git a/app_dart/lib/src/model/proto/protos.dart b/app_dart/lib/src/model/proto/protos.dart
deleted file mode 100644
index ae7cdee..0000000
--- a/app_dart/lib/src/model/proto/protos.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export 'internal/build_status_response.pb.dart';
-export 'internal/github_webhook.pb.dart';
-export 'internal/key.pb.dart';
-export 'internal/scheduler.pb.dart';
diff --git a/app_dart/lib/src/request_handlers/check_flaky_builders.dart b/app_dart/lib/src/request_handlers/check_flaky_builders.dart
deleted file mode 100644
index 41d64ba..0000000
--- a/app_dart/lib/src/request_handlers/check_flaky_builders.dart
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:cocoon_service/ci_yaml.dart';
-import 'package:collection/collection.dart';
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-import 'package:yaml/yaml.dart';
-
-import '../../protos.dart' as pb;
-import '../foundation/utils.dart';
-import '../request_handling/api_request_handler.dart';
-import '../request_handling/body.dart';
-import '../service/bigquery.dart';
-import '../service/config.dart';
-import '../service/github_service.dart';
-import 'flaky_handler_utils.dart';
-
-/// A handler to deflake builders if the builders are no longer flaky.
-///
-/// This handler gets flaky builders from ci.yaml in flutter/flutter and check
-/// the following conditions:
-/// 1. The builder is not in [ignoredBuilders].
-/// 2. The flaky issue of the builder is closed if there is one.
-/// 3. Does not have any existing pr against the target.
-/// 4. The builder has been passing for most recent [kRecordNumber] consecutive
-///    runs.
-/// 5. The builder is not marked with ignore_flakiness.
-///
-/// If all the conditions are true, this handler will file a pull request to
-/// make the builder unflaky.
-@immutable
-class CheckFlakyBuilders extends ApiRequestHandler<Body> {
-  const CheckFlakyBuilders({
-    required super.config,
-    required super.authenticationProvider,
-  });
-
-  static int kRecordNumber = 50;
-
-  static final RegExp _issueLinkRegex = RegExp(r'https://github.com/flutter/flutter/issues/(?<id>[0-9]+)');
-
-  /// Builders that are purposefully marked flaky and should be ignored by this
-  /// handler.
-  static const Set<String> ignoredBuilders = <String>{
-    'Mac_ios32 flutter_gallery__transition_perf_e2e_ios32',
-    'Mac_ios32 native_ui_tests_ios',
-  };
-
-  @override
-  Future<Body> get() async {
-    final RepositorySlug slug = Config.flutterSlug;
-    final GithubService gitHub = config.createGithubServiceWithToken(await config.githubOAuthToken);
-    final BigqueryService bigquery = await config.createBigQueryService();
-    final String ciContent = await gitHub.getFileContent(
-      slug,
-      kCiYamlPath,
-    );
-    final YamlMap? ci = loadYaml(ciContent) as YamlMap?;
-    final pb.SchedulerConfig unCheckedSchedulerConfig = pb.SchedulerConfig()..mergeFromProto3Json(ci);
-    final CiYaml ciYaml = CiYaml(
-      slug: slug,
-      branch: Config.defaultBranch(slug),
-      config: unCheckedSchedulerConfig,
-    );
-
-    final pb.SchedulerConfig schedulerConfig = ciYaml.config;
-    final List<pb.Target> targets = schedulerConfig.targets;
-
-    final List<_BuilderInfo> eligibleBuilders =
-        await _getEligibleFlakyBuilders(gitHub, slug, content: ciContent, ciYaml: ciYaml);
-    final String testOwnerContent = await gitHub.getFileContent(
-      slug,
-      kTestOwnerPath,
-    );
-
-    for (final _BuilderInfo info in eligibleBuilders) {
-      final BuilderType type = getTypeForBuilder(info.name, ciYaml);
-      final TestOwnership testOwnership = getTestOwnership(
-        targets.singleWhere((element) => element.name == info.name!),
-        type,
-        testOwnerContent,
-      );
-      final List<BuilderRecord> builderRecords =
-          await bigquery.listRecentBuildRecordsForBuilder(kBigQueryProjectId, builder: info.name, limit: kRecordNumber);
-      if (_shouldDeflake(builderRecords)) {
-        await _deflakyPullRequest(gitHub, slug, info: info, ciContent: ciContent, testOwnership: testOwnership);
-        // Manually add a 1s delay between consecutive GitHub requests to deal with secondary rate limit error.
-        // https://docs.github.com/en/rest/guides/best-practices-for-integrators#dealing-with-secondary-rate-limits
-        await Future.delayed(config.githubRequestDelay);
-      }
-    }
-    return Body.forJson(const <String, dynamic>{
-      'Status': 'success',
-    });
-  }
-
-  /// A builder should be deflaked if satisfying three conditions.
-  /// 1) There are enough data records.
-  /// 2) There is no flake
-  /// 3) There is no failure
-  bool _shouldDeflake(List<BuilderRecord> builderRecords) {
-    return builderRecords.length >= kRecordNumber &&
-        builderRecords.every((BuilderRecord record) => !record.isFlaky && !record.isFailed);
-  }
-
-  /// Gets the builders that match conditions:
-  /// 1. The builder's ignoreFlakiness is false.
-  /// 2. The builder is flaky
-  /// 3. The builder is not in [ignoredBuilders].
-  /// 4. The flaky issue of the builder is closed if there is one.
-  /// 5. Does not have any existing pr against the builder.
-  Future<List<_BuilderInfo>> _getEligibleFlakyBuilders(
-    GithubService gitHub,
-    RepositorySlug slug, {
-    required String content,
-    required CiYaml ciYaml,
-  }) async {
-    final YamlMap ci = loadYaml(content) as YamlMap;
-    final YamlList targets = ci[kCiYamlTargetsKey] as YamlList;
-    final List<YamlMap?> flakyTargets = targets
-        .where((dynamic target) => target[kCiYamlTargetIsFlakyKey] == true)
-        .map<YamlMap?>((dynamic target) => target as YamlMap?)
-        .toList();
-    final List<_BuilderInfo> result = <_BuilderInfo>[];
-    final List<String> lines = content.split('\n');
-    final Map<String?, PullRequest> nameToExistingPRs = await getExistingPRs(gitHub, slug);
-    for (final YamlMap? flakyTarget in flakyTargets) {
-      final String? builder = flakyTarget![kCiYamlTargetNameKey] as String?;
-      // If target specified ignore_flakiness, then skip.
-      if (getIgnoreFlakiness(builder, ciYaml)) {
-        continue;
-      }
-      if (ignoredBuilders.contains(builder)) {
-        continue;
-      }
-      // Skip the flaky target if the issue or pr for the flaky target is still
-      // open.
-      if (nameToExistingPRs.containsKey(builder)) {
-        continue;
-      }
-
-      //TODO (ricardoamador): Refactor this so we don't need to parse the entire yaml looking for commented issues, https://github.com/flutter/flutter/issues/113232
-      int builderLineNumber = lines.indexWhere((String line) => line.contains('name: $builder')) + 1;
-      while (builderLineNumber < lines.length && !lines[builderLineNumber].contains('name:')) {
-        if (lines[builderLineNumber].contains('$kCiYamlTargetIsFlakyKey:')) {
-          final RegExpMatch? match = _issueLinkRegex.firstMatch(lines[builderLineNumber]);
-          if (match == null) {
-            result.add(_BuilderInfo(name: builder));
-            break;
-          }
-          final Issue issue = await gitHub.getIssue(slug, issueNumber: int.parse(match.namedGroup('id')!))!;
-          if (issue.isClosed) {
-            result.add(_BuilderInfo(name: builder, existingIssue: issue));
-          }
-          break;
-        }
-        builderLineNumber += 1;
-      }
-    }
-    return result;
-  }
-
-  @visibleForTesting
-  static bool getIgnoreFlakiness(String? builderName, CiYaml ciYaml) {
-    final Target? target =
-        ciYaml.postsubmitTargets.singleWhereOrNull((Target target) => target.value.name == builderName);
-    return target == null ? false : target.getIgnoreFlakiness();
-  }
-
-  Future<void> _deflakyPullRequest(
-    GithubService gitHub,
-    RepositorySlug slug, {
-    required _BuilderInfo info,
-    required String ciContent,
-    required TestOwnership testOwnership,
-  }) async {
-    final String modifiedContent = _deflakeBuilderInContent(ciContent, info.name);
-    final GitReference masterRef = await gitHub.getReference(slug, kMasterRefs);
-    final DeflakePullRequestBuilder prBuilder = DeflakePullRequestBuilder(
-      name: info.name,
-      recordNumber: kRecordNumber,
-      ownership: testOwnership,
-      issue: info.existingIssue,
-    );
-    final PullRequest pullRequest = await gitHub.createPullRequest(
-      slug,
-      title: prBuilder.pullRequestTitle,
-      body: prBuilder.pullRequestBody,
-      commitMessage: prBuilder.pullRequestTitle,
-      baseRef: masterRef,
-      entries: <CreateGitTreeEntry>[
-        CreateGitTreeEntry(
-          kCiYamlPath,
-          kModifyMode,
-          kModifyType,
-          content: modifiedContent,
-        ),
-      ],
-    );
-    await gitHub.assignReviewer(slug, reviewer: prBuilder.pullRequestReviewer, pullRequestNumber: pullRequest.number);
-  }
-
-  /// Removes the `bringup: true` for the builder in the ci.yaml.
-  String _deflakeBuilderInContent(String content, String? builder) {
-    final List<String> lines = content.split('\n');
-    final int builderLineNumber = lines.indexWhere((String line) => line.contains('name: $builder'));
-    int nextLine = builderLineNumber + 1;
-    while (nextLine < lines.length && !lines[nextLine].contains('name:')) {
-      if (lines[nextLine].contains('$kCiYamlTargetIsFlakyKey:')) {
-        lines.removeAt(nextLine);
-        return lines.join('\n');
-      }
-      nextLine += 1;
-    }
-    throw 'Cannot find the flaky flag, is the test really marked flaky?';
-  }
-}
-
-/// The info of the builder's name and if there is any existing issue opened
-/// for the builder.
-class _BuilderInfo {
-  _BuilderInfo({this.name, this.existingIssue});
-  final String? name;
-  final Issue? existingIssue;
-}
diff --git a/app_dart/lib/src/request_handlers/create_branch.dart b/app_dart/lib/src/request_handlers/create_branch.dart
deleted file mode 100644
index 7d0d688..0000000
--- a/app_dart/lib/src/request_handlers/create_branch.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2020 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import '../request_handling/api_request_handler.dart';
-import '../request_handling/body.dart';
-import '../service/branch_service.dart';
-
-/// Creates the flutter/recipes branch to match a flutter/flutter branch.
-///
-/// This is used by Google Testing to create release infra whenever a good
-/// commit has been found, and is being considered as the branch point to
-/// be rolled into Google.
-class CreateBranch extends ApiRequestHandler<Body> {
-  const CreateBranch({
-    required this.branchService,
-    required super.config,
-    required super.authenticationProvider,
-  });
-
-  final BranchService branchService;
-
-  static const String branchParam = 'branch';
-  static const String engineShaParam = 'engine';
-
-  @override
-  Future<Body> get() async {
-    checkRequiredQueryParameters(<String>[branchParam, engineShaParam]);
-    final String branch = request!.uri.queryParameters[branchParam]!;
-    final String engineSha = request!.uri.queryParameters[engineShaParam]!;
-
-    await branchService.branchFlutterRecipes(branch, engineSha);
-
-    return Body.empty;
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/dart_internal_subscription.dart b/app_dart/lib/src/request_handlers/dart_internal_subscription.dart
deleted file mode 100644
index b778c5d..0000000
--- a/app_dart/lib/src/request_handlers/dart_internal_subscription.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2023 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-
-import 'package:cocoon_service/src/model/luci/buildbucket.dart';
-import 'package:meta/meta.dart';
-
-import '../../cocoon_service.dart';
-import '../model/appengine/task.dart';
-import '../request_handling/subscription_handler.dart';
-import '../service/datastore.dart';
-import '../service/logging.dart';
-
-/// TODO(drewroengoogle): Make this subscription generic so we can accept more
-/// than just dart-internal builds.
-///
-/// An endpoint for listening to build updates for dart-internal builds and
-/// saving the results to the datastore.
-///
-/// The PubSub subscription is set up here:
-/// https://console.cloud.google.com/cloudpubsub/subscription/detail/dart-internal-build-results-sub?project=flutter-dashboard
-@immutable
-class DartInternalSubscription extends SubscriptionHandler {
-  /// Creates an endpoint for listening for dart-internal build results.
-  /// The message should contain a single buildbucket id
-  const DartInternalSubscription({
-    required super.cache,
-    required super.config,
-    super.authProvider,
-    required this.buildBucketClient,
-    @visibleForTesting this.datastoreProvider = DatastoreService.defaultProvider,
-  }) : super(subscriptionName: 'dart-internal-build-results-sub');
-
-  final BuildBucketClient buildBucketClient;
-  final DatastoreServiceProvider datastoreProvider;
-
-  @override
-  Future<Body> post() async {
-    final DatastoreService datastore = datastoreProvider(config.db);
-
-    if (message.data == null) {
-      log.info('no data in message');
-      return Body.empty;
-    }
-
-    final dynamic buildData = json.decode(message.data!);
-    log.info('Build data json: $buildData');
-
-    if (buildData['build'] == null) {
-      log.info('no build information in message');
-      return Body.empty;
-    }
-
-    final String project = buildData['build']['builder']['project'];
-    final String bucket = buildData['build']['builder']['bucket'];
-    final String builder = buildData['build']['builder']['builder'];
-
-    // This should already be covered by the pubsub filter, but adding an additional check
-    // to ensure we don't process builds that aren't from dart-internal/flutter.
-    if (project != 'dart-internal' || bucket != 'flutter') {
-      log.info('Ignoring build not from dart-internal/flutter bucket');
-      return Body.empty;
-    }
-
-    // Only publish the parent release_builder builds to the datastore.
-    // TODO(drewroengoogle): Remove this regex in favor of supporting *all* dart-internal build results.
-    // Issue: https://github.com/flutter/flutter/issues/134674
-    final regex =
-        RegExp(r'(Linux|Mac|Windows)\s+(engine_release_builder|packaging_release_builder|flutter_release_builder)');
-    if (!regex.hasMatch(builder)) {
-      log.info('Ignoring builder that is not a release builder');
-      return Body.empty;
-    }
-
-    final String buildbucketId = buildData['build']['id'];
-    log.info('Creating build request object with build id $buildbucketId');
-    final GetBuildRequest request = GetBuildRequest(
-      id: buildbucketId,
-    );
-
-    log.info(
-      'Calling buildbucket api to get build data for build $buildbucketId',
-    );
-    final Build build = await buildBucketClient.getBuild(request);
-
-    log.info('Checking for existing task in datastore');
-    final Task? existingTask = await datastore.getTaskFromBuildbucketBuild(build);
-
-    late Task taskToInsert;
-    if (existingTask != null) {
-      log.info('Updating Task from existing Task');
-      existingTask.updateFromBuildbucketBuild(build);
-      taskToInsert = existingTask;
-    } else {
-      log.info('Creating Task from Buildbucket result');
-      taskToInsert = await Task.fromBuildbucketBuild(build, datastore);
-    }
-
-    log.info('Inserting Task into the datastore: ${taskToInsert.toString()}');
-    await datastore.insert(<Task>[taskToInsert]);
-
-    return Body.forJson(taskToInsert.toString());
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/file_flaky_issue_and_pr.dart b/app_dart/lib/src/request_handlers/file_flaky_issue_and_pr.dart
deleted file mode 100644
index 10ab0bc..0000000
--- a/app_dart/lib/src/request_handlers/file_flaky_issue_and_pr.dart
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:cocoon_service/ci_yaml.dart';
-import 'package:collection/collection.dart';
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-import 'package:yaml/yaml.dart';
-
-import '../../protos.dart' as pb;
-import '../foundation/utils.dart';
-import '../request_handling/api_request_handler.dart';
-import '../request_handling/body.dart';
-import '../service/bigquery.dart';
-import '../service/config.dart';
-import '../service/github_service.dart';
-import 'flaky_handler_utils.dart';
-
-/// A handler that queries build statistics from luci and file issues and pull
-/// requests for tests that have high flaky ratios.
-///
-/// The query parameter kThresholdKey is required for this handler to use it as
-/// the standard when compares the flaky ratios.
-@immutable
-class FileFlakyIssueAndPR extends ApiRequestHandler<Body> {
-  const FileFlakyIssueAndPR({
-    required super.config,
-    required super.authenticationProvider,
-  });
-
-  static const String kThresholdKey = 'threshold';
-
-  @override
-  Future<Body> get() async {
-    final RepositorySlug slug = Config.flutterSlug;
-    final GithubService gitHub = config.createGithubServiceWithToken(await config.githubOAuthToken);
-    final BigqueryService bigquery = await config.createBigQueryService();
-    final List<BuilderStatistic> builderStatisticList = await bigquery.listBuilderStatistic(kBigQueryProjectId);
-    final YamlMap? ci = loadYaml(await gitHub.getFileContent(slug, kCiYamlPath)) as YamlMap?;
-    final pb.SchedulerConfig unCheckedSchedulerConfig = pb.SchedulerConfig()..mergeFromProto3Json(ci);
-    final CiYaml ciYaml = CiYaml(
-      slug: slug,
-      branch: Config.defaultBranch(slug),
-      config: unCheckedSchedulerConfig,
-    );
-
-    final pb.SchedulerConfig schedulerConfig = ciYaml.config;
-    final List<pb.Target> targets = schedulerConfig.targets;
-
-    final String testOwnerContent = await gitHub.getFileContent(slug, kTestOwnerPath);
-    final Map<String?, Issue> nameToExistingIssue = await getExistingIssues(gitHub, slug);
-    final Map<String?, PullRequest> nameToExistingPR = await getExistingPRs(gitHub, slug);
-    int filedIssueAndPRCount = 0;
-    for (final BuilderStatistic statistic in builderStatisticList) {
-      // Skip if ignore_flakiness is specified.
-      if (getIgnoreFlakiness(statistic.name, ciYaml)) {
-        continue;
-      }
-      if (statistic.flakyRate < _threshold) {
-        continue;
-      }
-
-      final BuilderType type = getTypeForBuilder(statistic.name, ciYaml);
-      final bool issueAndPRFiled = await _fileIssueAndPR(
-        gitHub,
-        slug,
-        builderDetail: BuilderDetail(
-          statistic: statistic,
-          existingIssue: nameToExistingIssue[statistic.name],
-          existingPullRequest: nameToExistingPR[statistic.name],
-          isMarkedFlaky: _getIsMarkedFlaky(statistic.name, ci!),
-          type: type,
-          ownership: getTestOwnership(
-            targets.singleWhere((element) => element.name == statistic.name),
-            type,
-            testOwnerContent,
-          ),
-        ),
-      );
-      if (issueAndPRFiled) {
-        filedIssueAndPRCount++;
-      }
-      if (filedIssueAndPRCount == config.issueAndPRLimit) {
-        break;
-      }
-    }
-    return Body.forJson(<String, dynamic>{
-      'Status': 'success',
-      'NumberOfCreatedIssuesAndPRs': filedIssueAndPRCount,
-    });
-  }
-
-  double get _threshold => double.parse(request!.uri.queryParameters[kThresholdKey]!);
-
-  Future<bool> _fileIssueAndPR(
-    GithubService gitHub,
-    RepositorySlug slug, {
-    required BuilderDetail builderDetail,
-  }) async {
-    Issue? issue = builderDetail.existingIssue;
-    if (_shouldNotFileIssueAndPR(builderDetail, issue)) {
-      return false;
-    }
-    // Manually add a 1s delay between consecutive GitHub requests to deal with secondary rate limit error.
-    // https://docs.github.com/en/rest/guides/best-practices-for-integrators#dealing-with-secondary-rate-limits
-    await Future.delayed(config.githubRequestDelay);
-    issue = await fileFlakyIssue(builderDetail: builderDetail, gitHub: gitHub, slug: slug, threshold: _threshold);
-
-    if (builderDetail.type == BuilderType.shard ||
-        builderDetail.type == BuilderType.unknown ||
-        builderDetail.existingPullRequest != null) {
-      return true;
-    }
-    final String modifiedContent = _marksBuildFlakyInContent(
-      await gitHub.getFileContent(
-        slug,
-        kCiYamlPath,
-      ),
-      builderDetail.statistic.name,
-      issue.htmlUrl,
-    );
-    final GitReference masterRef = await gitHub.getReference(slug, kMasterRefs);
-    final PullRequestBuilder prBuilder =
-        PullRequestBuilder(statistic: builderDetail.statistic, ownership: builderDetail.ownership, issue: issue);
-    final PullRequest pullRequest = await gitHub.createPullRequest(
-      slug,
-      title: prBuilder.pullRequestTitle,
-      body: prBuilder.pullRequestBody,
-      commitMessage: prBuilder.pullRequestTitle,
-      baseRef: masterRef,
-      entries: <CreateGitTreeEntry>[
-        CreateGitTreeEntry(
-          kCiYamlPath,
-          kModifyMode,
-          kModifyType,
-          content: modifiedContent,
-        ),
-      ],
-    );
-    final String? label = getTeamLabelFromTeam(builderDetail.ownership.team);
-    await gitHub.assignReviewer(slug, reviewer: prBuilder.pullRequestReviewer, pullRequestNumber: pullRequest.number);
-    if (label != null) {
-      await gitHub.addIssueLabels(slug, pullRequest.number!, <String>[label]);
-    }
-    return true;
-  }
-
-  bool _shouldNotFileIssueAndPR(BuilderDetail builderDetail, Issue? issue) {
-    // Don't create a new issue or deflake PR using prod builds statuses if the builder has been marked as flaky.
-    // If the builder is `bringup: true`, but still hit flakes, a new bug will be filed in `/api/check_flaky_builders`
-    // based on staging builds statuses.
-    if (builderDetail.isMarkedFlaky) {
-      return true;
-    }
-
-    // Don't create a new issue or deflake PR if there is an open issue or a recent closed
-    // issue within kGracePeriodForClosedFlake days. It takes time for the flaky ratio to go
-    // down after the fix is merged.
-    if (issue != null &&
-        (issue.state != 'closed' ||
-            DateTime.now().difference(issue.closedAt!) <= const Duration(days: kGracePeriodForClosedFlake))) {
-      return true;
-    }
-
-    return false;
-  }
-
-  bool _getIsMarkedFlaky(String builderName, YamlMap ci) {
-    final YamlList targets = ci[kCiYamlTargetsKey] as YamlList;
-    final YamlMap? target = targets.firstWhere(
-      (dynamic element) => element[kCiYamlTargetNameKey] == builderName,
-      orElse: () => null,
-    ) as YamlMap?;
-    return target != null && target[kCiYamlTargetIsFlakyKey] == true;
-  }
-
-  @visibleForTesting
-  static bool getIgnoreFlakiness(String builderName, CiYaml ciYaml) {
-    final Target? target =
-        ciYaml.postsubmitTargets.singleWhereOrNull((Target target) => target.value.name == builderName);
-    return target == null ? false : target.getIgnoreFlakiness();
-  }
-
-  String _marksBuildFlakyInContent(String content, String builder, String issueUrl) {
-    final List<String> lines = content.split('\n');
-    final int builderLineNumber = lines.indexWhere((String line) => line.contains('name: $builder'));
-    // Takes care the case if is kCiYamlTargetIsFlakyKey is already defined to false
-    int nextLine = builderLineNumber + 1;
-    while (nextLine < lines.length && !lines[nextLine].contains('name:')) {
-      if (lines[nextLine].contains('$kCiYamlTargetIsFlakyKey:')) {
-        lines[nextLine] = lines[nextLine].replaceFirst('false', 'true # Flaky $issueUrl');
-        return lines.join('\n');
-      }
-      nextLine += 1;
-    }
-    lines.insert(builderLineNumber + 1, '    $kCiYamlTargetIsFlakyKey: true # Flaky $issueUrl');
-    return lines.join('\n');
-  }
-
-  Future<RepositorySlug> getSlugFor(GitHub client, String repository) async {
-    return RepositorySlug((await client.users.getCurrentUser()).login!, repository);
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/flaky_handler_utils.dart b/app_dart/lib/src/request_handlers/flaky_handler_utils.dart
deleted file mode 100644
index a5f31df..0000000
--- a/app_dart/lib/src/request_handlers/flaky_handler_utils.dart
+++ /dev/null
@@ -1,480 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:core';
-
-import 'package:cocoon_service/ci_yaml.dart';
-import 'package:cocoon_service/src/request_handlers/test_ownership.dart';
-import 'package:collection/collection.dart';
-import 'package:github/github.dart';
-
-import '../service/bigquery.dart';
-import '../service/github_service.dart';
-import '../../protos.dart' as pb;
-
-// String constants.
-const String kFlakeLabel = 'c: flake';
-const String kFrameworkLabel = 'team-framework';
-const String kToolLabel = 'team-tool';
-const String kEngineLabel = 'team-engine';
-const String kWebLabel = 'team-web';
-const String kInfraLabel = 'team-infra';
-const String kAndroidLabel = 'team-android';
-const String kIosLabel = 'team-ios';
-const String kReleaseLabel = 'team-release';
-const String kEcosystemLabel = 'team-ecosystem';
-const String kP0Label = 'P0';
-const String kP1Label = 'P1';
-const String kP2Label = 'P2';
-const String kP3Label = 'P3';
-
-const String kBigQueryProjectId = 'flutter-dashboard';
-const String kCiYamlTargetsKey = 'targets';
-const String kCiYamlTargetNameKey = 'name';
-const String kCiYamlTargetIgnoreFlakiness = 'ignore_flakiness';
-const String kCiYamlTargetIsFlakyKey = 'bringup';
-const String kCiYamlPropertiesKey = 'properties';
-const String kCiYamlTargetTagsKey = 'tags';
-const String kCiYamlTargetTagsShard = 'shard';
-const String kCiYamlTargetTagsFirebaselab = 'firebaselab';
-const String kCiYamlTargetTagsDevicelab = 'devicelab';
-const String kCiYamlTargetTagsFramework = 'framework';
-const String kCiYamlTargetTagsHostonly = 'hostonly';
-
-const String kMasterRefs = 'heads/master';
-const String kModifyMode = '100644'; // This is equivalent to mode: `-rw-r--r--`.
-const String kModifyType = 'blob';
-
-const int kSuccessBuildNumberLimit = 3;
-const int kFlayRatioBuildNumberList = 10;
-const double kDefaultFlakyRatioThreshold = 0.02;
-const int kGracePeriodForClosedFlake = 15; // days
-
-const String _commitPrefix = 'https://github.com/flutter/flutter/commit/';
-const String _buildDashboardPrefix = 'https://flutter-dashboard.appspot.com/#/build';
-const String _prodBuildPrefix = 'https://ci.chromium.org/ui/p/flutter/builders/prod/';
-const String _stagingBuildPrefix = 'https://ci.chromium.org/ui/p/flutter/builders/staging/';
-const String _flakeRecordPrefix =
-    'https://data.corp.google.com/sites/flutter_infra_metrics_datasite/flutter_check_test_flakiness_status_dashboard/?p=BUILDER_NAME:';
-
-/// A builder to build a new issue for a flake.
-class IssueBuilder {
-  IssueBuilder({
-    required this.statistic,
-    required this.ownership,
-    required this.threshold,
-    this.bringup = false,
-  });
-
-  final BuilderStatistic statistic;
-  final TestOwnership ownership;
-  final double threshold;
-  final bool bringup;
-
-  Bucket get buildBucket {
-    return bringup ? Bucket.staging : Bucket.prod;
-  }
-
-  String get issueTitle {
-    return '${statistic.name} is ${_formatRate(statistic.flakyRate)}% flaky';
-  }
-
-  String? get issueAssignee {
-    return ownership.owner;
-  }
-
-  /// Return `kSuccessBuildNumberLimit` successful builds if there are more. Otherwise return what's available.
-  int numberOfSuccessBuilds(int numberOfAvailableSuccessBuilds) {
-    return numberOfAvailableSuccessBuilds >= kSuccessBuildNumberLimit
-        ? kSuccessBuildNumberLimit
-        : numberOfAvailableSuccessBuilds;
-  }
-
-  String get issueBody {
-    return '''
-${_buildHiddenMetaTags(name: statistic.name)}
-${_issueSummary(statistic, threshold, bringup)}
-
-One recent flaky example for a same commit: ${_issueBuildLink(builder: statistic.name, build: statistic.flakyBuildOfRecentCommit, bucket: buildBucket)}
-Commit: $_commitPrefix${statistic.recentCommit}
-
-Flaky builds:
-${_issueBuildLinks(builder: statistic.name, builds: statistic.flakyBuilds!, bucket: buildBucket)}
-
-Recent test runs:
-${_issueBuilderLink(statistic.name)}
-
-Please follow https://github.com/flutter/flutter/wiki/Reducing-Test-Flakiness#fixing-flaky-tests to fix the flakiness and enable the test back after validating the fix (internal dashboard to validate: go/flutter_test_flakiness).
-''';
-  }
-
-  List<String> get issueLabels {
-    final List<String> labels = <String>[
-      kFlakeLabel,
-      kP0Label,
-    ];
-    final String? teamLabel = getTeamLabelFromTeam(ownership.team);
-    if (teamLabel != null && teamLabel.isNotEmpty == true) {
-      labels.add(teamLabel);
-    }
-    return labels;
-  }
-}
-
-/// A builder to build the update comment and labels for an existing open flaky
-/// issue.
-class IssueUpdateBuilder {
-  IssueUpdateBuilder({
-    required this.statistic,
-    required this.threshold,
-    required this.existingIssue,
-    required this.bucket,
-  });
-
-  final BuilderStatistic statistic;
-  final double threshold;
-  final Issue existingIssue;
-  final Bucket bucket;
-
-  bool get isBelow => statistic.flakyRate < threshold;
-
-  String get bucketString => bucket.toString().split('.').last;
-
-  List<String> get issueLabels {
-    final List<String> existingLabels = existingIssue.labels.map<String>((IssueLabel label) => label.name).toList();
-    // Update the priority.
-    if (!existingLabels.contains(kP0Label) && !isBelow) {
-      existingLabels.add(kP0Label);
-      existingLabels.remove(kP1Label);
-      existingLabels.remove(kP2Label);
-      existingLabels.remove(kP3Label);
-    }
-    return existingLabels;
-  }
-
-  String get issueUpdateComment {
-    String result =
-        '[$bucketString pool] flaky ratio for the past (up to) 100 commits between ${statistic.fromDate} and ${statistic.toDate} is ${_formatRate(statistic.flakyRate)}%. Flaky number: ${statistic.flakyNumber}; total number: ${statistic.totalNumber}.\n';
-    if (statistic.flakyRate > 0.0) {
-      result += '''
-One recent flaky example for a same commit: ${_issueBuildLink(builder: statistic.name, build: statistic.flakyBuildOfRecentCommit, bucket: bucket)}
-Commit: $_commitPrefix${statistic.recentCommit}
-Flaky builds:
-${_issueBuildLinks(builder: statistic.name, builds: statistic.flakyBuilds!, bucket: bucket)}
-
-Recent test runs:
-${_issueBuilderLink(statistic.name)}
-''';
-    }
-    return result;
-  }
-}
-
-/// A builder to build the pull request title and body for marking test flaky
-class PullRequestBuilder {
-  PullRequestBuilder({
-    required this.statistic,
-    required this.ownership,
-    required this.issue,
-  });
-
-  final BuilderStatistic statistic;
-  final TestOwnership ownership;
-  final Issue issue;
-
-  String get pullRequestTitle => 'Marks ${statistic.name} to be flaky';
-  String get pullRequestBody => '${_buildHiddenMetaTags(name: statistic.name)}Issue link: ${issue.htmlUrl}\n';
-  String? get pullRequestReviewer => ownership.owner;
-}
-
-/// A builder to build the pull request title and body for marking test unflaky
-class DeflakePullRequestBuilder {
-  DeflakePullRequestBuilder({
-    required this.name,
-    required this.recordNumber,
-    required this.ownership,
-    this.issue,
-  });
-
-  final String? name;
-  final Issue? issue;
-  final TestOwnership ownership;
-  final int recordNumber;
-
-  String get pullRequestTitle => 'Marks $name to be unflaky';
-  String get pullRequestBody {
-    String body = _buildHiddenMetaTags(name: name);
-    if (issue != null) {
-      body +=
-          'The issue ${issue!.htmlUrl} has been closed, and the test has been passing for [$recordNumber consecutive runs](${Uri.encodeFull('$_flakeRecordPrefix"$name"')}).\n';
-    } else {
-      body +=
-          'The test has been passing for [$recordNumber consecutive runs](${Uri.encodeFull('$_flakeRecordPrefix"$name"')}).\n';
-    }
-    body += 'This test can be marked as unflaky.\n';
-    return body;
-  }
-
-  String? get pullRequestReviewer => ownership.owner;
-}
-
-// TESTOWNER Regex
-
-const String kOwnerGroupName = 'owners';
-final RegExp devicelabTestOwners =
-    RegExp('## Linux Android DeviceLab tests\n(?<$kOwnerGroupName>.+)## Host only framework tests', dotAll: true);
-final RegExp frameworkHostOnlyTestOwners =
-    RegExp('## Host only framework tests\n(?<$kOwnerGroupName>.+)## Firebase tests', dotAll: true);
-final RegExp firebaselabTestOwners = RegExp('## Firebase tests\n(?<$kOwnerGroupName>.+)## Shards tests', dotAll: true);
-final RegExp shardTestOwners = RegExp('## Shards tests\n(?<$kOwnerGroupName>.+)', dotAll: true);
-
-// Utils methods
-
-/// Gets the existing flaky issues.
-///
-/// The state can be 'open', 'closed', or 'all'.
-Future<Map<String?, Issue>> getExistingIssues(GithubService gitHub, RepositorySlug slug, {String state = 'all'}) async {
-  final Map<String?, Issue> nameToExistingIssue = <String?, Issue>{};
-  for (final Issue issue in await gitHub.listIssues(slug, state: state, labels: <String>[kFlakeLabel])) {
-    if (issue.htmlUrl.contains('pull') == true) {
-      // For some reason, this github api may also return pull requests.
-      continue;
-    }
-    final Map<String, dynamic>? metaTags = retrieveMetaTagsFromContent(issue.body);
-    if (metaTags != null) {
-      final String? name = metaTags['name'] as String?;
-      if (!nameToExistingIssue.containsKey(name) || _isOtherIssueMoreImportant(nameToExistingIssue[name]!, issue)) {
-        nameToExistingIssue[name] = issue;
-      }
-    }
-  }
-  return nameToExistingIssue;
-}
-
-/// Gets the existing open pull requests that make tests flaky.
-Future<Map<String?, PullRequest>> getExistingPRs(GithubService gitHub, RepositorySlug slug) async {
-  final Map<String?, PullRequest> nameToExistingPRs = <String?, PullRequest>{};
-  for (final PullRequest pr in await gitHub.listPullRequests(slug, null)) {
-    try {
-      if (pr.body == null) {
-        continue;
-      }
-      final Map<String, dynamic>? metaTags = retrieveMetaTagsFromContent(pr.body!);
-      if (metaTags != null) {
-        nameToExistingPRs[metaTags['name'] as String] = pr;
-      }
-    } catch (e) {
-      throw 'Unable to parse body of ${pr.htmlUrl}\n$e';
-    }
-  }
-  return nameToExistingPRs;
-}
-
-/// File a GitHub flaky issue based on builder details in recent prod/staging runs.
-Future<Issue> fileFlakyIssue({
-  required BuilderDetail builderDetail,
-  required GithubService gitHub,
-  required RepositorySlug slug,
-  double threshold = kDefaultFlakyRatioThreshold,
-  bool bringup = false,
-}) async {
-  final IssueBuilder issueBuilder = IssueBuilder(
-    statistic: builderDetail.statistic,
-    ownership: builderDetail.ownership,
-    threshold: kDefaultFlakyRatioThreshold,
-    bringup: bringup,
-  );
-  return gitHub.createIssue(
-    slug,
-    title: issueBuilder.issueTitle,
-    body: issueBuilder.issueBody,
-    labels: issueBuilder.issueLabels,
-    assignee: issueBuilder.issueAssignee,
-  );
-}
-
-/// Looks up the owner of a builder in TESTOWNERS file.
-TestOwnership getTestOwnership(pb.Target target, BuilderType type, String testOwnersContent) {
-  final TestOwner testOwner = TestOwner(type);
-  return testOwner.getTestOwnership(target, testOwnersContent);
-}
-
-/// Gets the [BuilderType] of the builder by looking up the information in the
-/// ci.yaml.
-BuilderType getTypeForBuilder(String? targetName, CiYaml ciYaml, {bool unfilteredTargets = false}) {
-  final List<String>? tags = _getTags(targetName, ciYaml, unfilteredTargets: unfilteredTargets);
-  if (tags == null || tags.isEmpty) {
-    return BuilderType.unknown;
-  }
-
-  bool hasFrameworkTag = false;
-  bool hasHostOnlyTag = false;
-  // If tags contain 'shard', it must be a shard test.
-  // If tags contain 'devicelab', it must be a devicelab test.
-  // If tags contain 'firebaselab`, it must be a firebase tests.
-  // Otherwise, it is framework host only test if its tags contain both
-  // 'framework' and 'hostonly'.
-  for (String tag in tags) {
-    if (tag == kCiYamlTargetTagsFirebaselab) {
-      return BuilderType.firebaselab;
-    } else if (tag == kCiYamlTargetTagsShard) {
-      return BuilderType.shard;
-    } else if (tag == kCiYamlTargetTagsDevicelab) {
-      return BuilderType.devicelab;
-    } else if (tag == kCiYamlTargetTagsFramework) {
-      hasFrameworkTag = true;
-    } else if (tag == kCiYamlTargetTagsHostonly) {
-      hasHostOnlyTag = true;
-    }
-  }
-  return hasFrameworkTag && hasHostOnlyTag ? BuilderType.frameworkHostOnly : BuilderType.unknown;
-}
-
-List<String>? _getTags(String? targetName, CiYaml ciYaml, {bool unfilteredTargets = false}) {
-  final Set<Target> allUniqueTargets = {};
-  if (!unfilteredTargets) {
-    allUniqueTargets.addAll(ciYaml.presubmitTargets);
-    allUniqueTargets.addAll(ciYaml.postsubmitTargets);
-  } else {
-    allUniqueTargets.addAll(ciYaml.targets);
-  }
-
-  final Target? target = allUniqueTargets.firstWhereOrNull((element) => element.value.name == targetName);
-  return target?.tags;
-}
-
-bool _isOtherIssueMoreImportant(Issue original, Issue other) {
-  // Open issues are always more important than closed issues. If both issue
-  // are closed, the one that is most recently created is more important.
-  if (original.isOpen && other.isOpen) {
-    throw 'There should not be two open issues for the same test';
-  } else if (original.isOpen && other.isClosed) {
-    return false;
-  } else if (original.isClosed && other.isOpen) {
-    return true;
-  } else {
-    return other.createdAt!.isAfter(original.createdAt!);
-  }
-}
-
-String _buildHiddenMetaTags({String? name}) {
-  return '''<!-- meta-tags: To be used by the automation script only, DO NOT MODIFY.
-{
-  "name": "$name"
-}
--->
-''';
-}
-
-final RegExp _issueHiddenMetaTagsRegex =
-    RegExp(r'<!-- meta-tags: To be used by the automation script only, DO NOT MODIFY\.(?<meta>.+)-->', dotAll: true);
-
-/// Checks whether the github content contains meta tags and returns the meta
-/// tags if it does.
-///
-/// The script generated contents for issue bodies or pull request bodies
-/// contain the meta tags. Using this method is a reliable way to check whether
-/// a issue or pull request is generated by this script.
-Map<String, dynamic>? retrieveMetaTagsFromContent(String content) {
-  final RegExpMatch? match = _issueHiddenMetaTagsRegex.firstMatch(content);
-  if (match == null) {
-    return null;
-  }
-  return jsonDecode(match.namedGroup('meta')!) as Map<String, dynamic>?;
-}
-
-String _formatRate(double rate) => (rate * 100).toStringAsFixed(2);
-
-String _issueBuildLinks({String? builder, required List<String> builds, Bucket bucket = Bucket.prod}) {
-  return builds.map((String build) => _issueBuildLink(builder: builder, build: build, bucket: bucket)).join('\n');
-}
-
-String _issueSummary(BuilderStatistic statistic, double threshold, bool bringup) {
-  final String summary;
-  if (bringup) {
-    summary =
-        'The post-submit test builder `${statistic.name}`, which has been marked `bringup: true`, had ${statistic.flakyNumber} flakes over past ${statistic.totalNumber} commits.';
-  } else {
-    summary =
-        'The post-submit test builder `${statistic.name}` had a flaky ratio ${_formatRate(statistic.flakyRate)}% for the past (up to) 100 commits, which is above our ${_formatRate(threshold)}% threshold.';
-  }
-  return summary;
-}
-
-String _issueBuildLink({String? builder, String? build, Bucket bucket = Bucket.prod}) {
-  final String buildPrefix = bucket == Bucket.staging ? _stagingBuildPrefix : _prodBuildPrefix;
-  return Uri.encodeFull('$buildPrefix$builder/$build');
-}
-
-String _issueBuilderLink(String? builder) {
-  return Uri.encodeFull('$_buildDashboardPrefix?taskFilter=$builder');
-}
-
-String? getTeamLabelFromTeam(Team? team) {
-  return switch (team) {
-    Team.framework => kFrameworkLabel,
-    Team.engine => kEngineLabel,
-    Team.tool => kToolLabel,
-    Team.web => kWebLabel,
-    Team.infra => kInfraLabel,
-    Team.android => kAndroidLabel,
-    Team.ios => kIosLabel,
-    Team.release => kReleaseLabel,
-    Team.plugins => kEcosystemLabel,
-    Team.unknown || null => null,
-  };
-}
-
-enum BuilderType {
-  devicelab,
-  frameworkHostOnly,
-  shard,
-  firebaselab,
-  unknown,
-}
-
-enum Bucket {
-  prod,
-  staging,
-}
-
-enum Team {
-  framework,
-  engine,
-  tool,
-  web,
-  infra,
-  android,
-  ios,
-  release,
-  plugins,
-  unknown,
-}
-
-class TestOwnership {
-  TestOwnership(
-    this.owner,
-    this.team,
-  );
-  String? owner;
-  Team? team;
-}
-
-class BuilderDetail {
-  const BuilderDetail({
-    required this.statistic,
-    required this.existingIssue,
-    required this.existingPullRequest,
-    required this.isMarkedFlaky,
-    required this.ownership,
-    required this.type,
-  });
-  final BuilderStatistic statistic;
-  final Issue? existingIssue;
-  final PullRequest? existingPullRequest;
-  final TestOwnership ownership;
-  final bool isMarkedFlaky;
-  final BuilderType type;
-}
diff --git a/app_dart/lib/src/request_handlers/flush_cache.dart b/app_dart/lib/src/request_handlers/flush_cache.dart
deleted file mode 100644
index 824a0c7..0000000
--- a/app_dart/lib/src/request_handlers/flush_cache.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:meta/meta.dart';
-
-import '../request_handling/api_request_handler.dart';
-import '../request_handling/body.dart';
-import '../request_handling/exceptions.dart';
-import '../service/cache_service.dart';
-import '../service/config.dart';
-
-/// Trigger a cache flush on a config key and return empty response if successful.
-///
-/// If [cacheKeyParam] is not passed, throws [BadRequestException].
-/// If the cache does not have the given key, throws [NotFoundException].
-@immutable
-class FlushCache extends ApiRequestHandler<Body> {
-  const FlushCache({
-    required super.config,
-    required super.authenticationProvider,
-    required this.cache,
-  });
-
-  final CacheService cache;
-
-  /// Name of the query parameter passed to the endpoint.
-  ///
-  /// The value is expected to be an existing value from [CocoonConfig].
-  static const String cacheKeyParam = 'key';
-
-  @override
-  Future<Body> get() async {
-    checkRequiredQueryParameters(<String>[cacheKeyParam]);
-    final String cacheKey = request!.uri.queryParameters[cacheKeyParam]!;
-
-    // To validate cache flushes, validate that the key exists.
-    await cache.getOrCreate(
-      Config.configCacheName,
-      cacheKey,
-      createFn: () => throw NotFoundException('Failed to find cache key: $cacheKey'),
-    );
-
-    await cache.purge(Config.configCacheName, cacheKey);
-
-    return Body.empty;
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/get_build_status.dart b/app_dart/lib/src/request_handlers/get_build_status.dart
deleted file mode 100644
index e434842..0000000
--- a/app_dart/lib/src/request_handlers/get_build_status.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-
-import '../../protos.dart' show BuildStatusResponse, EnumBuildStatus;
-import '../request_handling/body.dart';
-import '../request_handling/request_handler.dart';
-import '../service/build_status_provider.dart';
-import '../service/datastore.dart';
-
-@immutable
-class GetBuildStatus extends RequestHandler<Body> {
-  const GetBuildStatus({
-    required super.config,
-    @visibleForTesting DatastoreServiceProvider? datastoreProvider,
-    @visibleForTesting BuildStatusServiceProvider? buildStatusProvider,
-  })  : datastoreProvider = datastoreProvider ?? DatastoreService.defaultProvider,
-        buildStatusProvider = buildStatusProvider ?? BuildStatusService.defaultProvider;
-  final DatastoreServiceProvider datastoreProvider;
-  final BuildStatusServiceProvider buildStatusProvider;
-
-  static const String kRepoParam = 'repo';
-
-  @override
-  Future<Body> get() async {
-    final DatastoreService datastore = datastoreProvider(config.db);
-    final BuildStatusService buildStatusService = buildStatusProvider(datastore);
-    final String repoName = request!.uri.queryParameters[kRepoParam] ?? 'flutter';
-    final RepositorySlug slug = RepositorySlug('flutter', repoName);
-    final BuildStatus status = (await buildStatusService.calculateCumulativeStatus(slug))!;
-    final BuildStatusResponse response = BuildStatusResponse()
-      ..buildStatus = status.succeeded ? EnumBuildStatus.success : EnumBuildStatus.failure
-      ..failingTasks.addAll(status.failedTasks);
-
-    return Body.forJson(response.writeToJsonMap());
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/get_green_commits.dart b/app_dart/lib/src/request_handlers/get_green_commits.dart
deleted file mode 100644
index 8a3adba..0000000
--- a/app_dart/lib/src/request_handlers/get_green_commits.dart
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2021 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:cocoon_service/src/model/appengine/commit.dart';
-import 'package:cocoon_service/src/model/appengine/stage.dart';
-import 'package:cocoon_service/src/model/appengine/task.dart';
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-
-import '../request_handling/body.dart';
-import '../request_handling/request_handler.dart';
-import '../service/build_status_provider.dart';
-import '../service/config.dart';
-import '../service/datastore.dart';
-
-/// Returns [List<String>] of the commit shas that had all passing tests.
-///
-/// A [CommitStatus] that have all passing tests is used to help the release tooling find commits Flutter infrastructure has validated.
-/// In order to qualify as a [CommitStatus] that have all passing tests, the rules are:
-/// 1. The [Commit] inside [CommitStatus] had all its tests run (at least those that are not in bringup)
-/// 2. all the blocking [Task] in [CommitStatus] should pass
-/// A [List<String>] of commit shas of the qualified [CommitStatus]s are returned, in the order of [Commit] timestamp, i.e.,
-/// A [Commit] with an earlier timestamp will apprear earlier in the result [List<String>], as compared to another [Commit]
-/// with a later timestamp.
-///
-/// Parameters:
-///   branch: defaults to the defaults branch for the repository.
-///   repo: default: 'flutter'. Name of the repository.
-///
-/// GET: /api/public/get-green-commits?repo=$repo
-
-@immutable
-class GetGreenCommits extends RequestHandler<Body> {
-  const GetGreenCommits({
-    required super.config,
-    @visibleForTesting this.datastoreProvider = DatastoreService.defaultProvider,
-    @visibleForTesting BuildStatusServiceProvider? buildStatusProvider,
-  }) : buildStatusProvider = buildStatusProvider ?? BuildStatusService.defaultProvider;
-
-  final DatastoreServiceProvider datastoreProvider;
-  final BuildStatusServiceProvider buildStatusProvider;
-
-  static const String kBranchParam = 'branch';
-  static const String kRepoParam = 'repo';
-
-  @override
-  Future<Body> get() async {
-    final String repoName = request!.uri.queryParameters[kRepoParam] ?? Config.flutterSlug.name;
-    final RepositorySlug slug = RepositorySlug('flutter', repoName);
-    final String branch = request!.uri.queryParameters[kBranchParam] ?? Config.defaultBranch(slug);
-    final DatastoreService datastore = datastoreProvider(config.db);
-    final BuildStatusService buildStatusService = buildStatusProvider(datastore);
-    final int commitNumber = config.commitNumber;
-
-    final List<String?> greenCommits = await buildStatusService
-        .retrieveCommitStatus(
-          limit: commitNumber,
-          branch: branch,
-          slug: slug,
-        )
-        .where((CommitStatus status) => everyNonFlakyTaskSucceed(status))
-        .map<String?>((CommitStatus status) => status.commit.sha)
-        .toList();
-
-    return Body.forJson(greenCommits);
-  }
-
-  bool everyNonFlakyTaskSucceed(CommitStatus status) {
-    return status.stages.every(
-      (Stage stage) => stage.tasks
-          .where((Task task) => !task.isFlaky!)
-          .every((Task nonFlakyTask) => nonFlakyTask.status == Task.statusSucceeded),
-    );
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/get_release_branches.dart b/app_dart/lib/src/request_handlers/get_release_branches.dart
deleted file mode 100644
index f698e2f..0000000
--- a/app_dart/lib/src/request_handlers/get_release_branches.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2020 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:cocoon_service/src/request_handling/request_handler.dart';
-import 'package:github/github.dart';
-
-import '../request_handling/body.dart';
-import '../service/branch_service.dart';
-import '../service/config.dart';
-import '../service/github_service.dart';
-
-/// Return a list of release branch information.
-///
-/// GET: /api/public/get-release-branches
-///
-/// Response: Status 200 OK
-///[
-///    {
-///        "branch":"flutter-2.13-candidate.0",
-///        "name":"stable"
-///    },
-///    {
-///        "branch":"flutter-3.2-candidate.5",
-///        "name":"beta"
-///    },
-///    {
-///        "branch":"flutter-3.4-candidate.5",
-///        "name":"dev"
-///    }
-///]
-
-class GetReleaseBranches extends RequestHandler<Body> {
-  GetReleaseBranches({required super.config, required this.branchService});
-
-  final BranchService branchService;
-
-  @override
-  Future<Body> get() async {
-    final GitHub github = await config.createGitHubClient(slug: Config.flutterSlug);
-    final GithubService githubService = GithubService(github);
-    final List<Map<String, String>> branchNames =
-        await branchService.getReleaseBranches(githubService: githubService, slug: Config.flutterSlug);
-    return Body.forJson(branchNames);
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/get_repos.dart b/app_dart/lib/src/request_handlers/get_repos.dart
deleted file mode 100644
index 0366ab1..0000000
--- a/app_dart/lib/src/request_handlers/get_repos.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2020 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-
-import '../request_handling/body.dart';
-import '../request_handling/request_handler.dart';
-import '../service/config.dart';
-
-/// Returns [Config.supportedRepos] as a list of repo names.
-@immutable
-class GetRepos extends RequestHandler<Body> {
-  const GetRepos({
-    required super.config,
-  });
-
-  @override
-  Future<Body> get() async {
-    final List<String> repos = config.supportedRepos.map((RepositorySlug slug) => slug.name).toList();
-    return Body.forJson(repos);
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/get_status.dart b/app_dart/lib/src/request_handlers/get_status.dart
deleted file mode 100644
index 55f812f..0000000
--- a/app_dart/lib/src/request_handlers/get_status.dart
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:gcloud/db.dart';
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-
-import '../model/appengine/commit.dart';
-import '../model/appengine/key_helper.dart';
-import '../request_handling/body.dart';
-import '../request_handling/exceptions.dart';
-import '../request_handling/request_handler.dart';
-import '../service/build_status_provider.dart';
-import '../service/config.dart';
-import '../service/datastore.dart';
-
-@immutable
-class GetStatus extends RequestHandler<Body> {
-  const GetStatus({
-    required super.config,
-    @visibleForTesting this.datastoreProvider = DatastoreService.defaultProvider,
-    @visibleForTesting this.buildStatusProvider = BuildStatusService.defaultProvider,
-  });
-
-  final DatastoreServiceProvider datastoreProvider;
-  final BuildStatusServiceProvider buildStatusProvider;
-
-  static const String kLastCommitKeyParam = 'lastCommitKey';
-  static const String kBranchParam = 'branch';
-  static const String kRepoParam = 'repo';
-
-  @override
-  Future<Body> get() async {
-    final String? encodedLastCommitKey = request!.uri.queryParameters[kLastCommitKeyParam];
-    final String repoName = request!.uri.queryParameters[kRepoParam] ?? Config.flutterSlug.name;
-    final RepositorySlug slug = RepositorySlug('flutter', repoName);
-    final String branch = request!.uri.queryParameters[kBranchParam] ?? Config.defaultBranch(slug);
-    final DatastoreService datastore = datastoreProvider(config.db);
-    final BuildStatusService buildStatusService = buildStatusProvider(datastore);
-    final KeyHelper keyHelper = config.keyHelper;
-    final int commitNumber = config.commitNumber;
-    final int lastCommitTimestamp = await _obtainTimestamp(encodedLastCommitKey, keyHelper, datastore);
-
-    final List<SerializableCommitStatus> statuses = await buildStatusService
-        .retrieveCommitStatus(
-          limit: commitNumber,
-          timestamp: lastCommitTimestamp,
-          branch: branch,
-          slug: slug,
-        )
-        .map<SerializableCommitStatus>(
-          (CommitStatus status) => SerializableCommitStatus(status, keyHelper.encode(status.commit.key)),
-        )
-        .toList();
-
-    return Body.forJson(<String, dynamic>{
-      'Statuses': statuses,
-    });
-  }
-
-  Future<int> _obtainTimestamp(String? encodedLastCommitKey, KeyHelper keyHelper, DatastoreService datastore) async {
-    /// [lastCommitTimestamp] is initially set as the current time, which allows query return
-    /// latest commit list. If [owerKeyParam] is not empty, [lastCommitTimestamp] will be set
-    /// as the timestamp of that [commit], and the query will return lastest commit
-    /// list whose timestamp is smaller than [lastCommitTimestamp].
-    int lastCommitTimestamp = DateTime.now().millisecondsSinceEpoch;
-
-    if (encodedLastCommitKey != null) {
-      final Key<String> ownerKey = keyHelper.decode(encodedLastCommitKey) as Key<String>;
-      final Commit commit = await datastore.db.lookupValue<Commit>(
-        ownerKey,
-        orElse: () => throw NotFoundException('Failed to find commit with key $ownerKey'),
-      );
-
-      lastCommitTimestamp = commit.timestamp!;
-    }
-    return lastCommitTimestamp;
-  }
-}
-
-/// The serialized representation of a [CommitStatus].
-// TODO(tvolkert): Directly serialize [CommitStatus] once frontends migrate to new format.
-class SerializableCommitStatus {
-  const SerializableCommitStatus(this.status, this.key);
-
-  final CommitStatus status;
-  final String key;
-
-  Map<String, dynamic> toJson() {
-    return <String, dynamic>{
-      'Checklist': <String, dynamic>{
-        'Key': key,
-        'Checklist': SerializableCommit(status.commit).facade,
-      },
-      'Stages': status.stages,
-    };
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/github/webhook_subscription.dart b/app_dart/lib/src/request_handlers/github/webhook_subscription.dart
deleted file mode 100644
index 05f7762..0000000
--- a/app_dart/lib/src/request_handlers/github/webhook_subscription.dart
+++ /dev/null
@@ -1,638 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-
-import 'package:cocoon_service/src/service/commit_service.dart';
-import 'package:github/github.dart';
-import 'package:github/hooks.dart';
-import 'package:meta/meta.dart';
-
-import '../../../protos.dart' as pb;
-import '../../model/gerrit/commit.dart';
-import '../../model/github/checks.dart' as cocoon_checks;
-import '../../request_handling/body.dart';
-import '../../request_handling/exceptions.dart';
-import '../../request_handling/subscription_handler.dart';
-import '../../service/config.dart';
-import '../../service/datastore.dart';
-import '../../service/gerrit_service.dart';
-import '../../service/github_checks_service.dart';
-import '../../service/logging.dart';
-import '../../service/scheduler.dart';
-
-// Filenames which are not actually tests.
-const List<String> kNotActuallyATest = <String>[
-  'packages/flutter/lib/src/gestures/hit_test.dart',
-];
-
-/// List of repos that require check for tests.
-Set<RepositorySlug> kNeedsTests = <RepositorySlug>{
-  Config.engineSlug,
-  Config.flutterSlug,
-  Config.packagesSlug,
-};
-
-final RegExp kEngineTestRegExp = RegExp(r'(tests?|benchmarks?)\.(dart|java|mm|m|cc|sh|py)$');
-
-// Extentions for files that use // for single line comments.
-// See [_allChangesAreCodeComments] for more.
-@visibleForTesting
-const Set<String> knownCommentCodeExtensions = <String>{
-  'cc',
-  'cpp',
-  'dart',
-  'gradle',
-  'groovy',
-  'java',
-  'kt',
-  'm',
-  'mm',
-  'swift',
-};
-
-/// Subscription for processing GitHub webhooks.
-///
-/// The PubSub subscription is set up here:
-/// https://console.cloud.google.com/cloudpubsub/subscription/detail/github-webhooks-sub?project=flutter-dashboard&tab=overview
-///
-/// This endpoint enables Cocoon to recover from outages.
-///
-/// This endpoint takes in a POST request with the GitHub event JSON.
-// TODO(chillers): There's potential now to split this into seprate subscriptions
-// for various activities (such as infra vs releases). This would mitigate
-// breakages across Cocoon.
-@immutable
-class GithubWebhookSubscription extends SubscriptionHandler {
-  /// Creates a subscription for processing GitHub webhooks.
-  const GithubWebhookSubscription({
-    required super.cache,
-    required super.config,
-    required this.scheduler,
-    required this.gerritService,
-    required this.commitService,
-    this.githubChecksService,
-    this.datastoreProvider = DatastoreService.defaultProvider,
-    super.authProvider,
-  }) : super(subscriptionName: 'github-webhooks-sub');
-
-  /// Cocoon scheduler to trigger tasks against changes from GitHub.
-  final Scheduler scheduler;
-
-  /// To verify whether a commit was mirrored to GoB.
-  final GerritService gerritService;
-
-  /// Used to handle push events and create commits based on those events.
-  final CommitService commitService;
-
-  /// To provide build status updates to GitHub pull requests.
-  final GithubChecksService? githubChecksService;
-
-  final DatastoreServiceProvider datastoreProvider;
-
-  @override
-  Future<Body> post() async {
-    if (message.data == null || message.data!.isEmpty) {
-      log.warning('GitHub webhook message was empty. No-oping');
-      return Body.empty;
-    }
-
-    final pb.GithubWebhookMessage webhook = pb.GithubWebhookMessage.fromJson(message.data!);
-
-    log.fine('Processing ${webhook.event}');
-    log.finest(webhook.payload);
-    switch (webhook.event) {
-      case 'pull_request':
-        await _handlePullRequest(webhook.payload);
-        break;
-      case 'check_run':
-        final Map<String, dynamic> event = jsonDecode(webhook.payload) as Map<String, dynamic>;
-        final cocoon_checks.CheckRunEvent checkRunEvent = cocoon_checks.CheckRunEvent.fromJson(event);
-        if (await scheduler.processCheckRun(checkRunEvent) == false) {
-          throw InternalServerError('Failed to process check_run event. checkRunEvent: $checkRunEvent');
-        }
-        break;
-      case 'push':
-        final Map<String, dynamic> event = jsonDecode(webhook.payload) as Map<String, dynamic>;
-        final String branch = event['ref'].split('/')[2]; // Eg: refs/heads/beta would return beta.
-        final String repository = event['repository']['name'];
-        // If the branch is beta/stable, then a commit wasn't created through a PR,
-        // meaning the commit needs to be added to the datastore here instead.
-        if (repository == 'flutter' && (branch == 'stable' || branch == 'beta')) {
-          await commitService.handlePushGithubRequest(event);
-        }
-        break;
-      case 'create':
-        final CreateEvent createEvent = CreateEvent.fromJson(json.decode(webhook.payload) as Map<String, dynamic>);
-        final RegExp candidateBranchRegex = RegExp(r'flutter-\d+\.\d+-candidate\.\d+');
-        // Create a commit object for candidate branches in the datastore so
-        // dart-internal builds that are triggered by the initial branch
-        // creation have an associated commit.
-        if (candidateBranchRegex.hasMatch(createEvent.ref!)) {
-          log.fine('Branch ${createEvent.ref} is a candidate branch, creating new commit in the datastore');
-          await commitService.handleCreateGithubRequest(createEvent);
-        }
-    }
-
-    return Body.empty;
-  }
-
-  /// Handles a GitHub webhook with the event type "pull_request".
-  ///
-  /// Regarding merged pull request events: the commit must be mirrored to GoB
-  /// before we can trigger postsubmit tasks. If the commit is not found, the
-  /// event will be failed so it can be retried. As of Jan 26, 2023, the
-  /// retention policy for Pub/Sub messages is 7 days. This event will be
-  /// retried with exponential backoff within that time period. The GoB mirror
-  /// should be caught up within that time frame via either the internal
-  /// mirroring service or [VacuumGithubCommits].
-  Future<void> _handlePullRequest(
-    String rawRequest,
-  ) async {
-    final PullRequestEvent? pullRequestEvent = await _getPullRequestEvent(rawRequest);
-    if (pullRequestEvent == null) {
-      throw const BadRequestException('Expected pull request event.');
-    }
-    final String? eventAction = pullRequestEvent.action;
-    final PullRequest pr = pullRequestEvent.pullRequest!;
-
-    // See the API reference:
-    // https://developer.github.com/v3/activity/events/types/#pullrequestevent
-    // which unfortunately is a bit light on explanations.
-    log.fine('Processing $eventAction for ${pr.htmlUrl}');
-    switch (eventAction) {
-      case 'closed':
-        // If it was closed without merging, cancel any outstanding tryjobs.
-        // We'll leave unfinished jobs if it was merged since we care about those
-        // results.
-        await scheduler.cancelPreSubmitTargets(
-          pullRequest: pr,
-          reason: (!pr.merged!) ? 'Pull request closed' : 'Pull request merged',
-        );
-
-        if (pr.merged!) {
-          log.fine('Pull request ${pr.number} was closed and merged.');
-          if (await _commitExistsInGob(pr)) {
-            log.fine('Merged commit was found on GoB mirror. Scheduling postsubmit tasks...');
-            return scheduler.addPullRequest(pr);
-          }
-          throw InternalServerError(
-            '${pr.mergeCommitSha!} was not found on GoB. Failing so this event can be retried...',
-          );
-        }
-        break;
-      case 'edited':
-        // Editing a PR should not trigger new jobs, but may update whether
-        // it has tests.
-        await _checkForTests(pullRequestEvent);
-        break;
-      case 'opened':
-      case 'reopened':
-        // These cases should trigger LUCI jobs. The closed event should happen
-        // before these which should cancel all in progress checks.
-        await _checkForTests(pullRequestEvent);
-        await _scheduleIfMergeable(pullRequestEvent);
-        await _tryReleaseApproval(pullRequestEvent);
-        break;
-      case 'labeled':
-        break;
-      case 'synchronize':
-        // This indicates the PR has new commits. We need to cancel old jobs
-        // and schedule new ones.
-        await _scheduleIfMergeable(pullRequestEvent);
-        break;
-      // Ignore the rest of the events.
-      case 'ready_for_review':
-      case 'unlabeled':
-      case 'assigned':
-      case 'locked':
-      case 'review_request_removed':
-      case 'review_requested':
-      case 'unassigned':
-      case 'unlocked':
-        break;
-    }
-  }
-
-  Future<bool> _commitExistsInGob(PullRequest pr) async {
-    final RepositorySlug slug = pr.base!.repo!.slug();
-    final String sha = pr.mergeCommitSha!;
-    final GerritCommit? gobCommit = await gerritService.findMirroredCommit(slug, sha);
-    return gobCommit != null;
-  }
-
-  /// This method assumes that jobs should be cancelled if they are already
-  /// runnning.
-  Future<void> _scheduleIfMergeable(
-    PullRequestEvent pullRequestEvent,
-  ) async {
-    final PullRequest pr = pullRequestEvent.pullRequest!;
-    final RepositorySlug slug = pullRequestEvent.repository!.slug();
-
-    log.info(
-      'Scheduling tasks if mergeable(${pr.mergeable}): owner=${slug.owner} repo=${slug.name} and pr=${pr.number}',
-    );
-
-    // The mergeable flag may be null. False indicates there's a merge conflict,
-    // null indicates unknown. Err on the side of allowing the job to run.
-    if (pr.mergeable == false) {
-      final RepositorySlug slug = pullRequestEvent.repository!.slug();
-      final GitHub gitHubClient = await config.createGitHubClient(pullRequest: pr);
-      final String body = config.mergeConflictPullRequestMessage;
-      if (!await _alreadyCommented(gitHubClient, pr, body)) {
-        await gitHubClient.issues.createComment(slug, pr.number!, body);
-      }
-      return;
-    }
-
-    await scheduler.triggerPresubmitTargets(pullRequest: pr);
-  }
-
-  /// Release tooling generates cherrypick pull requests that should be granted an approval.
-  Future<void> _tryReleaseApproval(
-    PullRequestEvent pullRequestEvent,
-  ) async {
-    final PullRequest pr = pullRequestEvent.pullRequest!;
-    final RepositorySlug slug = pullRequestEvent.repository!.slug();
-
-    final String defaultBranch = Config.defaultBranch(slug);
-    final String? branch = pr.base?.ref;
-    if (branch == null || branch.contains(defaultBranch)) {
-      // This isn't a release branch PR
-      return;
-    }
-
-    final List<String> releaseAccounts = await config.releaseAccounts;
-    if (releaseAccounts.contains(pr.user?.login) == false) {
-      // The author isn't in the list of release accounts, do nothing
-      return;
-    }
-
-    final GitHub gitHubClient = config.createGitHubClientWithToken(await config.githubOAuthToken);
-    final CreatePullRequestReview review = CreatePullRequestReview(slug.owner, slug.name, pr.number!, 'APPROVE');
-    await gitHubClient.pullRequests.createReview(slug, review);
-  }
-
-  Future<void> _checkForTests(PullRequestEvent pullRequestEvent) async {
-    final PullRequest pr = pullRequestEvent.pullRequest!;
-    final String? eventAction = pullRequestEvent.action;
-    final RepositorySlug slug = pr.base!.repo!.slug();
-    final bool isTipOfTree = pr.base!.ref == Config.defaultBranch(slug);
-    final GitHub gitHubClient = await config.createGitHubClient(pullRequest: pr);
-    await _validateRefs(gitHubClient, pr);
-    if (kNeedsTests.contains(slug) && isTipOfTree) {
-      switch (slug.name) {
-        case 'flutter':
-          return _applyFrameworkRepoLabels(gitHubClient, eventAction, pr);
-        case 'engine':
-          return _applyEngineRepoLabels(gitHubClient, eventAction, pr);
-        case 'packages':
-          return _applyPackageTestChecks(gitHubClient, eventAction, pr);
-      }
-    }
-  }
-
-  Future<void> _applyFrameworkRepoLabels(GitHub gitHubClient, String? eventAction, PullRequest pr) async {
-    if (pr.user!.login == 'engine-flutter-autoroll') {
-      return;
-    }
-
-    final RepositorySlug slug = pr.base!.repo!.slug();
-    log.info('Applying framework repo labels for: owner=${slug.owner} repo=${slug.name} and pr=${pr.number}');
-    final Stream<PullRequestFile> files = gitHubClient.pullRequests.listFiles(slug, pr.number!);
-
-    final Set<String> labels = <String>{};
-    bool hasTests = false;
-    bool needsTests = false;
-
-    await for (PullRequestFile file in files) {
-      final String filename = file.filename!;
-
-      if (_fileContainsAddedCode(file) &&
-          !_isTestExempt(filename) &&
-          !filename.startsWith('dev/bots/') &&
-          !filename.endsWith('.gitignore')) {
-        needsTests = !_allChangesAreCodeComments(file);
-      }
-
-      // Check to see if tests were submitted with this PR.
-      if (_isATest(filename)) {
-        hasTests = true;
-      }
-    }
-
-    if (pr.user!.login == 'fluttergithubbot') {
-      needsTests = false;
-      labels.addAll(<String>['c: tech-debt', 'c: flake']);
-    }
-
-    if (labels.isNotEmpty) {
-      await gitHubClient.issues.addLabelsToIssue(slug, pr.number!, labels.toList());
-    }
-
-    // We do not need to add test labels if this is an auto roller author.
-    if (config.rollerAccounts.contains(pr.user!.login)) {
-      return;
-    }
-
-    if (!hasTests && needsTests && !pr.draft! && !_isReleaseBranch(pr)) {
-      final String body = config.missingTestsPullRequestMessage;
-      if (!await _alreadyCommented(gitHubClient, pr, body)) {
-        await gitHubClient.issues.createComment(slug, pr.number!, body);
-      }
-    }
-  }
-
-  bool _isATest(String filename) {
-    if (kNotActuallyATest.any(filename.endsWith)) {
-      return false;
-    }
-    // Check for Objective-C tests which end in either "Tests.m" or "Test.m"
-    // in the "dev" directory.
-    final RegExp objectiveCTestRegex = RegExp(r'.*dev\/.*Test[s]?\.m$');
-    return filename.endsWith('_test.dart') ||
-        filename.endsWith('.expect') ||
-        filename.contains('test_fixes') ||
-        // Include updates to test utilities or test data
-        filename.contains('packages/flutter_tools/test/') ||
-        filename.startsWith('dev/bots/analyze.dart') ||
-        filename.startsWith('dev/bots/test.dart') ||
-        filename.startsWith('dev/devicelab/bin/tasks') ||
-        filename.startsWith('dev/devicelab/lib/tasks') ||
-        filename.startsWith('dev/benchmarks') ||
-        objectiveCTestRegex.hasMatch(filename);
-  }
-
-  /// Returns true if changes to [filename] are exempt from the testing
-  /// requirement, across repositories.
-  bool _isTestExempt(String filename) {
-    return filename.contains('.ci.yaml') ||
-        filename.contains('analysis_options.yaml') ||
-        filename.contains('AUTHORS') ||
-        filename.contains('CODEOWNERS') ||
-        filename.contains('TESTOWNERS') ||
-        filename.contains('pubspec.yaml') ||
-        // Exempt categories.
-        filename.contains('.github/') ||
-        filename.endsWith('.md') ||
-        // Exempt paths.
-        filename.startsWith('dev/devicelab/lib/versions/gallery.dart') ||
-        filename.startsWith('dev/integration_tests') ||
-        filename.startsWith('impeller/fixtures') ||
-        filename.startsWith('impeller/golden_tests') ||
-        filename.startsWith('impeller/playground') ||
-        filename.startsWith('shell/platform/embedder/tests') ||
-        filename.startsWith('shell/platform/embedder/fixtures');
-  }
-
-  Future<void> _applyEngineRepoLabels(GitHub gitHubClient, String? eventAction, PullRequest pr) async {
-    // Do not apply the test labels for the autoroller accounts.
-    if (pr.user!.login == 'skia-flutter-autoroll') {
-      return;
-    }
-
-    final RepositorySlug slug = pr.base!.repo!.slug();
-    final Stream<PullRequestFile> files = gitHubClient.pullRequests.listFiles(slug, pr.number!);
-    bool hasTests = false;
-    bool needsTests = false;
-
-    await for (PullRequestFile file in files) {
-      final String filename = file.filename!.toLowerCase();
-      if (_fileContainsAddedCode(file) && filename.endsWith('.dart') ||
-          filename.endsWith('.mm') ||
-          filename.endsWith('.m') ||
-          filename.endsWith('.java') ||
-          filename.endsWith('.cc')) {
-        needsTests = !_allChangesAreCodeComments(file);
-      }
-
-      if (kEngineTestRegExp.hasMatch(filename)) {
-        hasTests = true;
-      }
-    }
-
-    // We do not need to add test labels if this is an auto roller author.
-    if (config.rollerAccounts.contains(pr.user!.login)) {
-      return;
-    }
-
-    if (!hasTests && needsTests && !pr.draft! && !_isReleaseBranch(pr)) {
-      final String body = config.missingTestsPullRequestMessage;
-      if (!await _alreadyCommented(gitHubClient, pr, body)) {
-        await gitHubClient.issues.createComment(slug, pr.number!, body);
-      }
-    }
-  }
-
-  bool _fileContainsAddedCode(PullRequestFile file) {
-    // When null, do not assume 0 lines have been added.
-    final int linesAdded = file.additionsCount ?? 1;
-    final int linesDeleted = file.deletionsCount ?? 0;
-    final int linesTotal = file.changesCount ?? linesDeleted + linesAdded;
-    return linesAdded > 0 || linesDeleted != linesTotal;
-  }
-
-  // Runs automated test checks for both flutter/packages.
-  Future<void> _applyPackageTestChecks(GitHub gitHubClient, String? eventAction, PullRequest pr) async {
-    final RepositorySlug slug = pr.base!.repo!.slug();
-    final Stream<PullRequestFile> files = gitHubClient.pullRequests.listFiles(slug, pr.number!);
-    bool hasTests = false;
-    bool needsTests = false;
-
-    await for (PullRequestFile file in files) {
-      final String filename = file.filename!;
-
-      if (_fileContainsAddedCode(file) &&
-          !_isTestExempt(filename) &&
-          !filename.contains('.ci/') &&
-          // Custom package-specific test runners. These do not count as tests
-          // for the purposes of testing a change that otherwise needs tests,
-          // but since they are the driver for tests they don't need test
-          // coverage.
-          !filename.endsWith('tool/run_tests.dart') &&
-          !filename.endsWith('run_tests.sh')) {
-        needsTests = !_allChangesAreCodeComments(file);
-      }
-      // See https://github.com/flutter/flutter/wiki/Plugin-Tests for discussion
-      // of various plugin test types and locations.
-      if (filename.endsWith('_test.dart') ||
-          // Native iOS/macOS tests.
-          filename.contains('RunnerTests/') ||
-          filename.contains('RunnerUITests/') ||
-          // Native Android tests.
-          filename.contains('android/src/test/') ||
-          filename.contains('androidTest/') ||
-          // Native Linux tests.
-          filename.endsWith('_test.cc') ||
-          // Native Windows tests.
-          filename.endsWith('_test.cpp') ||
-          // Pigeon native tests.
-          filename.contains('/platform_tests/') ||
-          // Test files in package-specific test folders.
-          filename.contains('go_router/test_fixes/') ||
-          filename.contains('go_router_builder/test_inputs/')) {
-        hasTests = true;
-      }
-    }
-
-    // We do not need to add test labels if this is an auto roller author.
-    if (config.rollerAccounts.contains(pr.user!.login)) {
-      return;
-    }
-
-    if (!hasTests && needsTests && !pr.draft! && !_isReleaseBranch(pr)) {
-      final String body = config.missingTestsPullRequestMessage;
-      if (!await _alreadyCommented(gitHubClient, pr, body)) {
-        await gitHubClient.issues.createComment(slug, pr.number!, body);
-      }
-    }
-  }
-
-  /// Validate the base and head refs of the PR.
-  Future<void> _validateRefs(
-    GitHub gitHubClient,
-    PullRequest pr,
-  ) async {
-    final RepositorySlug slug = pr.base!.repo!.slug();
-    String body;
-    const List<String> releaseChannels = <String>[
-      'stable',
-      'beta',
-      'dev',
-    ];
-    // Close PRs that use a release branch as a source.
-    if (releaseChannels.contains(pr.head!.ref)) {
-      body = config.wrongHeadBranchPullRequestMessage(pr.head!.ref!);
-      if (!await _alreadyCommented(gitHubClient, pr, body)) {
-        await gitHubClient.pullRequests.edit(
-          slug,
-          pr.number!,
-          state: 'closed',
-        );
-        await gitHubClient.issues.createComment(slug, pr.number!, body);
-      }
-      return;
-    }
-    final String defaultBranchName = Config.defaultBranch(pr.base!.repo!.slug());
-    final String baseName = pr.base!.ref!;
-    if (baseName == defaultBranchName) {
-      return;
-    }
-    if (_isReleaseBranch(pr)) {
-      body = config.releaseBranchPullRequestMessage;
-      if (!await _alreadyCommented(gitHubClient, pr, body)) {
-        await gitHubClient.issues.createComment(slug, pr.number!, body);
-      }
-      return;
-    }
-
-    // For repos migrated to main, close PRs opened against master.
-    final bool isMaster = pr.base?.ref == 'master';
-    final bool isMigrated = defaultBranchName == 'main';
-    // PRs should never be open to "beta" or "stable."
-    final bool isReleaseChannelBranch = releaseChannels.contains(pr.base?.ref);
-    if ((isMaster && isMigrated) || isReleaseChannelBranch) {
-      body = _getWrongBaseComment(base: baseName, defaultBranch: defaultBranchName);
-      if (!await _alreadyCommented(gitHubClient, pr, body)) {
-        await gitHubClient.pullRequests.edit(
-          slug,
-          pr.number!,
-          base: Config.defaultBranch(slug),
-        );
-        await gitHubClient.issues.createComment(slug, pr.number!, body);
-      }
-    }
-  }
-
-  bool _isReleaseBranch(PullRequest pr) {
-    final String defaultBranchName = Config.defaultBranch(pr.base!.repo!.slug());
-    final String baseName = pr.base!.ref!;
-
-    if (baseName == defaultBranchName) {
-      return false;
-    }
-    // Check if branch name confroms to the format flutter-x.x-candidate.x,
-    // A pr with conforming branch name is likely to be intended
-    // for a release branch, whereas a pr with non conforming name is likely
-    // caused by user misoperations, in which case bot
-    // will suggest open pull request against default branch instead.
-    final RegExp candidateTest = RegExp(r'flutter-\d+\.\d+-candidate\.\d+');
-    if (candidateTest.hasMatch(baseName) && candidateTest.hasMatch(pr.head!.ref!)) {
-      return true;
-    }
-    return false;
-  }
-
-  Future<bool> _alreadyCommented(
-    GitHub gitHubClient,
-    PullRequest pr,
-    String message,
-  ) async {
-    final Stream<IssueComment> comments = gitHubClient.issues.listCommentsByIssue(pr.base!.repo!.slug(), pr.number!);
-    await for (IssueComment comment in comments) {
-      if (comment.body != null && comment.body!.contains(message)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  String _getWrongBaseComment({
-    required String base,
-    required String defaultBranch,
-  }) {
-    final String messageTemplate = config.wrongBaseBranchPullRequestMessage;
-    return messageTemplate.replaceAll('{{target_branch}}', base).replaceAll('{{default_branch}}', defaultBranch);
-  }
-
-  Future<PullRequestEvent?> _getPullRequestEvent(String request) async {
-    try {
-      return PullRequestEvent.fromJson(json.decode(request) as Map<String, dynamic>);
-    } on FormatException {
-      return null;
-    }
-  }
-
-  /// Returns true if the changes to [file] are all code comments.
-  ///
-  /// If that cannot be determined with confidence, returns false. False
-  /// negatives (e.g., for /* */-style multi-line comments) should be expected.
-  bool _allChangesAreCodeComments(PullRequestFile file) {
-    final int? linesAdded = file.additionsCount;
-    final int? linesDeleted = file.deletionsCount;
-    final String? patch = file.patch;
-    // If information is missing, err or the side of assuming it's a non-comment
-    // change.
-    if (linesAdded == null || linesDeleted == null || patch == null) {
-      return false;
-    }
-
-    final String filename = file.filename!;
-    final String? extension = filename.contains('.') ? filename.split('.').last.toLowerCase() : null;
-    if (extension == null || !knownCommentCodeExtensions.contains(extension)) {
-      return false;
-    }
-
-    // Only handles single-line comments; identifying multi-line comments
-    // would require the full file and non-trivial parsing. Also doesn't handle
-    // end-of-line comments (e.g., "int x = 0; // Info about x").
-    final RegExp commentRegex = RegExp(r'^[+-]\s*//');
-    final RegExp onlyWhitespaceRegex = RegExp(r'^[+-]\s*$');
-    for (String line in patch.split('\n')) {
-      if (!line.startsWith('+') && !line.startsWith('-')) {
-        continue;
-      }
-
-      if (onlyWhitespaceRegex.hasMatch(line)) {
-        // whitespace only changes don't require tests
-        continue;
-      }
-
-      if (!commentRegex.hasMatch(line)) {
-        return false;
-      }
-    }
-    return true;
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/github_rate_limit_status.dart b/app_dart/lib/src/request_handlers/github_rate_limit_status.dart
deleted file mode 100644
index d8cdc00..0000000
--- a/app_dart/lib/src/request_handlers/github_rate_limit_status.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:meta/meta.dart';
-
-import '../foundation/utils.dart';
-import '../request_handling/body.dart';
-import '../request_handling/request_handler.dart';
-import '../service/github_service.dart';
-import '../service/logging.dart';
-
-@immutable
-
-/// Endpoint to collect the current GitHub API quota usage of the flutter-dashboard app.
-///
-/// This endpoint pushes data to BigQuery for metric collection to analyze usage over time. There
-/// is a cron job set to run every minute, behind a [CacheRequestHandler] to ensure there exists
-/// at most one entry per repo per minute.
-///
-/// BigQuery entries contain the following fields:
-///   `timestamp`: [DateTime] of this entry.
-///   `limit`: Total API calls allowed on flutter-dashboard.
-///   `remaining`: Total number of API calls remaining before flutter-dashboard is blocked from sending further requests.
-///   `resets`: [DateTime] when [remaining] will reset back to [limit].
-class GithubRateLimitStatus extends RequestHandler<Body> {
-  const GithubRateLimitStatus({
-    required super.config,
-  });
-
-  @override
-  Future<Body> get() async {
-    final GithubService githubService = await config.createDefaultGitHubService();
-    final Map<String, dynamic> quotaUsage = (await githubService.getRateLimit()).toJson();
-    quotaUsage['timestamp'] = DateTime.now().toIso8601String();
-
-    final int remainingQuota = quotaUsage['remaining'] as int;
-    final int quotaLimit = quotaUsage['limit'] as int;
-    const double githubQuotaUsageSLO = 0.5;
-    if (remainingQuota < githubQuotaUsageSLO * quotaLimit) {
-      log.warning(
-        'Remaining GitHub quota is $remainingQuota, which is less than quota usage SLO ${githubQuotaUsageSLO * quotaLimit} (${githubQuotaUsageSLO * 100}% of the limit $quotaLimit)).',
-      );
-    }
-
-    /// Insert quota usage to BigQuery
-    const String githubQuotaTable = 'GithubQuotaUsage';
-    await insertBigquery(githubQuotaTable, quotaUsage, await config.createTabledataResourceApi());
-    return Body.forJson(quotaUsage);
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/github_webhook.dart b/app_dart/lib/src/request_handlers/github_webhook.dart
deleted file mode 100644
index 0d3e1d6..0000000
--- a/app_dart/lib/src/request_handlers/github_webhook.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'package:crypto/crypto.dart';
-import '../model/proto/protos.dart' as pb;
-import '../request_handling/body.dart';
-import '../request_handling/exceptions.dart';
-import '../request_handling/pubsub.dart';
-import '../request_handling/request_handler.dart';
-import '../service/logging.dart';
-
-/// The [RequestHandler] for processing GitHub webhooks and publishing valid events to PubSub.
-///
-/// Requests are only published as a [GithubWebhookMessage] iff they contain:
-///   1. Event type from the header `X-GitHub-Event`
-///   2. Event payload that was HMAC authenticated
-class GithubWebhook extends RequestHandler<Body> {
-  GithubWebhook({
-    required super.config,
-    required this.pubsub,
-    required this.secret,
-    required this.topic,
-  });
-
-  final PubSub pubsub;
-
-  /// PubSub topic to publish authenticated requests to.
-  final String topic;
-
-  /// Future that resolves to the GitHub apps webhook secret.
-  final Future<String> secret;
-
-  @override
-  Future<Body> post() async {
-    final String? event = request!.headers.value('X-GitHub-Event');
-
-    if (event == null || request!.headers.value('X-Hub-Signature') == null) {
-      throw const BadRequestException('Missing required headers.');
-    }
-    final List<int> requestBytes = await request!.expand((_) => _).toList();
-    final String? hmacSignature = request!.headers.value('X-Hub-Signature');
-    await _validateRequest(hmacSignature, requestBytes);
-
-    final String requestString = utf8.decode(requestBytes);
-
-    final pb.GithubWebhookMessage message = pb.GithubWebhookMessage.create()
-      ..event = event
-      ..payload = requestString;
-    log.fine(message);
-    await pubsub.publish(topic, message.writeToJsonMap());
-
-    return Body.empty;
-  }
-
-  /// Ensures the signature provided for the given payload matches what is expected.
-  ///
-  /// The expected key is the sha1 hash of the payload using the private key of the GitHub app.
-  Future<void> _validateRequest(
-    String? signature,
-    List<int> requestBody,
-  ) async {
-    final String rawKey = await secret;
-    final List<int> key = utf8.encode(rawKey);
-    final Hmac hmac = Hmac(sha1, key);
-    final Digest digest = hmac.convert(requestBody);
-    final String bodySignature = 'sha1=$digest';
-    if (bodySignature != signature) {
-      throw const Forbidden('X-Hub-Signature does not match expected value');
-    }
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/postsubmit_luci_subscription.dart b/app_dart/lib/src/request_handlers/postsubmit_luci_subscription.dart
deleted file mode 100644
index 1a70e80..0000000
--- a/app_dart/lib/src/request_handlers/postsubmit_luci_subscription.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:cocoon_service/ci_yaml.dart';
-import 'package:gcloud/db.dart';
-import 'package:meta/meta.dart';
-
-import '../model/appengine/commit.dart';
-import '../model/appengine/task.dart';
-import '../model/luci/push_message.dart';
-import '../request_handling/body.dart';
-import '../request_handling/exceptions.dart';
-import '../request_handling/subscription_handler.dart';
-import '../service/datastore.dart';
-import '../service/logging.dart';
-import '../service/github_checks_service.dart';
-import '../service/scheduler.dart';
-
-/// An endpoint for listening to build updates for postsubmit builds.
-///
-/// The PubSub subscription is set up here:
-/// https://cloud.google.com/cloudpubsub/subscription/detail/luci-postsubmit?project=flutter-dashboard&tab=overview
-///
-/// This endpoint is responsible for updating Datastore with the result of builds from LUCI.
-@immutable
-class PostsubmitLuciSubscription extends SubscriptionHandler {
-  /// Creates an endpoint for listening to LUCI status updates.
-  const PostsubmitLuciSubscription({
-    required super.cache,
-    required super.config,
-    super.authProvider,
-    @visibleForTesting this.datastoreProvider = DatastoreService.defaultProvider,
-    required this.scheduler,
-    required this.githubChecksService,
-  }) : super(subscriptionName: 'luci-postsubmit');
-
-  final DatastoreServiceProvider datastoreProvider;
-  final Scheduler scheduler;
-  final GithubChecksService githubChecksService;
-
-  @override
-  Future<Body> post() async {
-    final DatastoreService datastore = datastoreProvider(config.db);
-
-    final BuildPushMessage buildPushMessage = BuildPushMessage.fromPushMessage(message);
-    log.fine('userData=${buildPushMessage.userData}');
-    log.fine('Updating buildId=${buildPushMessage.build?.id} for result=${buildPushMessage.build?.result}');
-    if (buildPushMessage.userData.isEmpty) {
-      log.fine('User data is empty');
-      return Body.empty;
-    }
-
-    final String? rawTaskKey = buildPushMessage.userData['task_key'] as String?;
-    final String? rawCommitKey = buildPushMessage.userData['commit_key'] as String?;
-    if (rawCommitKey == null) {
-      throw const BadRequestException('userData does not contain commit_key');
-    }
-    final Build? build = buildPushMessage.build;
-    if (build == null) {
-      log.warning('Build is null');
-      return Body.empty;
-    }
-    final Key<String> commitKey = Key<String>(Key<dynamic>.emptyKey(Partition(null)), Commit, rawCommitKey);
-    Task? task;
-    if (rawTaskKey == null || rawTaskKey.isEmpty || rawTaskKey == 'null') {
-      log.fine('Pulling builder name from parameters_json...');
-      log.fine(build.buildParameters);
-      final String? taskName = build.buildParameters?['builder_name'] as String?;
-      if (taskName == null || taskName.isEmpty) {
-        throw const BadRequestException('task_key is null and parameters_json does not contain the builder name');
-      }
-      final List<Task> tasks = await datastore.queryRecentTasksByName(name: taskName).toList();
-      task = tasks.singleWhere((Task task) => task.parentKey?.id == commitKey.id);
-    } else {
-      log.fine('Looking up key...');
-      final int taskId = int.parse(rawTaskKey);
-      final Key<int> taskKey = Key<int>(commitKey, Task, taskId);
-      task = await datastore.lookupByValue<Task>(taskKey);
-    }
-    log.fine('Found $task');
-
-    if (_shouldUpdateTask(build, task)) {
-      final String oldTaskStatus = task.status;
-      task.updateFromBuild(build);
-      await datastore.insert(<Task>[task]);
-      log.fine('Updated datastore from $oldTaskStatus to ${task.status}');
-    } else {
-      log.fine('skip processing for build with status scheduled or task with status finished.');
-    }
-
-    final Commit commit = await datastore.lookupByValue<Commit>(commitKey);
-    final CiYaml ciYaml = await scheduler.getCiYaml(commit);
-    final List<Target> postsubmitTargets = ciYaml.postsubmitTargets;
-    if (!postsubmitTargets.any((element) => element.value.name == task!.name)) {
-      log.warning('Target ${task.name} has been deleted from TOT. Skip updating.');
-      return Body.empty;
-    }
-    final Target target = postsubmitTargets.singleWhere((Target target) => target.value.name == task!.name);
-    if (task.status == Task.statusFailed ||
-        task.status == Task.statusInfraFailure ||
-        task.status == Task.statusCancelled) {
-      log.fine('Trying to auto-retry...');
-      final bool retried = await scheduler.luciBuildService.checkRerunBuilder(
-        commit: commit,
-        target: target,
-        task: task,
-        datastore: datastore,
-      );
-      log.info('Retried: $retried');
-    }
-
-    // Only update GitHub checks if target is not bringup
-    if (target.value.bringup == false && config.postsubmitSupportedRepos.contains(target.slug)) {
-      log.info('Updating check status for ${target.getTestName}');
-      await githubChecksService.updateCheckStatus(
-        buildPushMessage,
-        scheduler.luciBuildService,
-        commit.slug,
-      );
-    }
-
-    return Body.empty;
-  }
-
-  // No need to update task in datastore if
-  // 1) the build is `scheduled`. Task is marked as `In Progress`
-  //    whenever scheduled, either from scheduler/backfiller/rerun. We need to update
-  //    task in datastore only for
-  //    a) `started`: update info like builder number.
-  //    b) `completed`: update info like status.
-  // 2) the task is already completed.
-  //    The task may have been marked as completed from test framework via update-task-status API.
-  bool _shouldUpdateTask(Build build, Task task) {
-    return build.status != Status.scheduled && !Task.finishedStatusValues.contains(task.status);
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/presubmit_luci_subscription.dart b/app_dart/lib/src/request_handlers/presubmit_luci_subscription.dart
deleted file mode 100644
index 63d4841..0000000
--- a/app_dart/lib/src/request_handlers/presubmit_luci_subscription.dart
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-
-import '../model/appengine/commit.dart';
-import '../model/ci_yaml/ci_yaml.dart';
-import '../model/ci_yaml/target.dart';
-import '../model/luci/push_message.dart';
-import '../request_handling/authentication.dart';
-import '../request_handling/body.dart';
-import '../request_handling/subscription_handler.dart';
-import '../service/buildbucket.dart';
-import '../service/config.dart';
-import '../service/github_checks_service.dart';
-import '../service/logging.dart';
-import '../service/luci_build_service.dart';
-import '../service/scheduler.dart';
-
-/// An endpoint for listening to LUCI status updates for scheduled builds.
-///
-/// [ScheduleBuildRequest.notify] property is set to tell LUCI to use this
-/// PubSub topic. LUCI then publishes updates about build status to that topic,
-/// which we listen to on the github-updater subscription. When new messages
-/// arrive, they are posted to this web service.
-///
-/// The PubSub subscription is set up here:
-/// https://console.cloud.google.com/cloudpubsub/subscription/detail/github-updater?project=flutter-dashboard
-///
-/// This endpoint is responsible for updating GitHub with the status of
-/// completed builds from LUCI.
-@immutable
-class PresubmitLuciSubscription extends SubscriptionHandler {
-  /// Creates an endpoint for listening to LUCI status updates.
-  const PresubmitLuciSubscription({
-    required super.cache,
-    required super.config,
-    required this.buildBucketClient,
-    required this.scheduler,
-    required this.luciBuildService,
-    required this.githubChecksService,
-    AuthenticationProvider? authProvider,
-  }) : super(subscriptionName: 'github-updater');
-
-  final BuildBucketClient buildBucketClient;
-  final LuciBuildService luciBuildService;
-  final GithubChecksService githubChecksService;
-  final Scheduler scheduler;
-
-  @override
-  Future<Body> post() async {
-    RepositorySlug slug;
-    final BuildPushMessage buildPushMessage = BuildPushMessage.fromPushMessage(message);
-    final Build build = buildPushMessage.build!;
-    final String builderName = build.tagsByName('builder').single;
-    log.fine('Available tags: ${build.tags.toString()}');
-    // Skip status update if we can not get the sha tag.
-    if (build.tagsByName('buildset').isEmpty) {
-      log.warning('Buildset tag not included, skipping Status Updates');
-      return Body.empty;
-    }
-    log.fine('Setting status: ${buildPushMessage.toJson()} for $builderName');
-    if (buildPushMessage.userData.containsKey('repo_owner') && buildPushMessage.userData.containsKey('repo_name')) {
-      // Message is coming from a github checks api enabled repo. We need to
-      // create the slug from the data in the message and send the check status
-      // update.
-      slug = RepositorySlug(
-        buildPushMessage.userData['repo_owner'] as String,
-        buildPushMessage.userData['repo_name'] as String,
-      );
-      bool rescheduled = false;
-      if (githubChecksService.taskFailed(buildPushMessage)) {
-        final int currentAttempt = githubChecksService.currentAttempt(buildPushMessage);
-        final int maxAttempt = await _getMaxAttempt(buildPushMessage, slug, builderName);
-        if (currentAttempt < maxAttempt) {
-          rescheduled = true;
-          log.fine('Rerun a failed task: $builderName');
-          await luciBuildService.rescheduleBuild(
-            builderName: builderName,
-            buildPushMessage: buildPushMessage,
-            rescheduleAttempt: currentAttempt + 1,
-          );
-        }
-      }
-      await githubChecksService.updateCheckStatus(
-        buildPushMessage,
-        luciBuildService,
-        slug,
-        rescheduled: rescheduled,
-      );
-    } else {
-      log.shout('This repo does not support checks API');
-    }
-    return Body.empty;
-  }
-
-  /// Gets target's allowed reschedule attempt.
-  ///
-  /// Each target can define their own allowed max number of reschedule attemp, and it
-  /// is defined as a property `presubmit_max_attempts`.
-  ///
-  /// If not property is defined, the target doesn't allow a reschedule after failures.
-  /// Typically the property will be used for targets that are likely flaky.
-  Future<int> _getMaxAttempt(
-    BuildPushMessage buildPushMessage,
-    RepositorySlug slug,
-    String builderName,
-  ) async {
-    final Commit commit = Commit(
-      branch: buildPushMessage.userData['commit_branch'] as String,
-      repository: slug.fullName,
-      sha: buildPushMessage.userData['commit_sha'] as String,
-    );
-    late CiYaml ciYaml;
-    if (commit.branch == Config.defaultBranch(commit.slug)) {
-      ciYaml = await scheduler.getCiYaml(commit, validate: true);
-    } else {
-      ciYaml = await scheduler.getCiYaml(commit);
-    }
-
-    // Do not block on the target not found.
-    if (!ciYaml.presubmitTargets.any((element) => element.value.name == builderName)) {
-      // do not reschedule
-      log.warning('Did not find builder with name: $builderName in ciYaml for ${commit.sha}');
-      final List<String> availableBuilderList = ciYaml.presubmitTargets.map((Target e) => e.value.name).toList();
-      log.warning('ciYaml presubmit targets found: $availableBuilderList');
-      return 1;
-    }
-
-    final Target target = ciYaml.presubmitTargets.where((element) => element.value.name == builderName).single;
-    final Map<String, Object> properties = target.getProperties();
-    if (!properties.containsKey('presubmit_max_attempts')) {
-      return 1;
-    }
-    return properties['presubmit_max_attempts'] as int;
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/push_build_status_to_github.dart b/app_dart/lib/src/request_handlers/push_build_status_to_github.dart
deleted file mode 100644
index 7c0de91..0000000
--- a/app_dart/lib/src/request_handlers/push_build_status_to_github.dart
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-
-import '../../cocoon_service.dart';
-import '../model/appengine/github_build_status_update.dart';
-import '../request_handling/api_request_handler.dart';
-import '../service/build_status_provider.dart';
-import '../service/datastore.dart';
-import '../service/logging.dart';
-
-@immutable
-class PushBuildStatusToGithub extends ApiRequestHandler<Body> {
-  const PushBuildStatusToGithub({
-    required super.config,
-    required super.authenticationProvider,
-    @visibleForTesting DatastoreServiceProvider? datastoreProvider,
-    @visibleForTesting BuildStatusServiceProvider? buildStatusServiceProvider,
-  })  : datastoreProvider = datastoreProvider ?? DatastoreService.defaultProvider,
-        buildStatusServiceProvider = buildStatusServiceProvider ?? BuildStatusService.defaultProvider;
-
-  final BuildStatusServiceProvider buildStatusServiceProvider;
-  final DatastoreServiceProvider datastoreProvider;
-  static const String fullNameRepoParam = 'repo';
-
-  @override
-  Future<Body> get() async {
-    if (authContext!.clientContext.isDevelopmentEnvironment) {
-      // Don't push GitHub status from the local dev server.
-      log.fine('GitHub statuses are not pushed from local dev environments');
-      return Body.empty;
-    }
-
-    final String repository = request!.uri.queryParameters[fullNameRepoParam] ?? 'flutter/flutter';
-    final RepositorySlug slug = RepositorySlug.full(repository);
-    final DatastoreService datastore = datastoreProvider(config.db);
-    final BuildStatusService buildStatusService = buildStatusServiceProvider(datastore);
-
-    final BuildStatus status = (await buildStatusService.calculateCumulativeStatus(slug))!;
-    await _insertBigquery(slug, status.githubStatus, Config.defaultBranch(slug), config);
-    await _updatePRs(slug, status.githubStatus, datastore);
-    log.fine('All the PRs for $repository have been updated with $status');
-
-    return Body.empty;
-  }
-
-  Future<void> _updatePRs(RepositorySlug slug, String status, DatastoreService datastore) async {
-    final GitHub github = await config.createGitHubClient(slug: slug);
-    final List<GithubBuildStatusUpdate> updates = <GithubBuildStatusUpdate>[];
-    await for (PullRequest pr in github.pullRequests.list(slug)) {
-      // Tree status is only put on PRs merging into ToT.
-      if (pr.base!.ref != Config.defaultBranch(slug)) {
-        log.fine('This PR is not staged to land on ${Config.defaultBranch(slug)}, skipping.');
-        continue;
-      }
-      final GithubBuildStatusUpdate update = await datastore.queryLastStatusUpdate(slug, pr);
-      if (update.status != status) {
-        log.fine('Updating status of ${slug.fullName}#${pr.number} from ${update.status} to $status');
-        final CreateStatus request = CreateStatus(status);
-        request.targetUrl = 'https://flutter-dashboard.appspot.com/#/build?repo=${slug.name}';
-        request.context = 'tree-status';
-        if (status != GithubBuildStatusUpdate.statusSuccess) {
-          request.description = config.flutterBuildDescription;
-        }
-        try {
-          await github.repositories.createStatus(slug, pr.head!.sha!, request);
-          update.status = status;
-          update.updates = (update.updates ?? 0) + 1;
-          update.updateTimeMillis = DateTime.now().millisecondsSinceEpoch;
-          updates.add(update);
-        } catch (error) {
-          log.severe('Failed to post status update to ${slug.fullName}#${pr.number}: $error');
-        }
-      }
-    }
-    await datastore.insert(updates);
-  }
-
-  Future<void> _insertBigquery(RepositorySlug slug, String status, String branch, Config config) async {
-    const String bigqueryTableName = 'BuildStatus';
-    final Map<String, dynamic> bigqueryData = <String, dynamic>{
-      'Timestamp': DateTime.now().millisecondsSinceEpoch,
-      'Status': status,
-      'Branch': branch,
-      'Repo': slug.name,
-    };
-    await insertBigquery(bigqueryTableName, bigqueryData, await config.createTabledataResourceApi());
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/push_gold_status_to_github.dart b/app_dart/lib/src/request_handlers/push_gold_status_to_github.dart
deleted file mode 100644
index d3fdcd9..0000000
--- a/app_dart/lib/src/request_handlers/push_gold_status_to_github.dart
+++ /dev/null
@@ -1,376 +0,0 @@
-// Copyright 2020 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:github/github.dart';
-import 'package:gql/language.dart' as lang;
-import 'package:graphql/client.dart';
-import 'package:http/http.dart' as http;
-import 'package:meta/meta.dart';
-
-import '../model/appengine/github_gold_status_update.dart';
-import '../request_handling/api_request_handler.dart';
-import '../request_handling/body.dart';
-import '../request_handling/exceptions.dart';
-import '../service/config.dart';
-import '../service/datastore.dart';
-import '../service/logging.dart';
-
-@immutable
-class PushGoldStatusToGithub extends ApiRequestHandler<Body> {
-  PushGoldStatusToGithub({
-    required super.config,
-    required super.authenticationProvider,
-    @visibleForTesting DatastoreServiceProvider? datastoreProvider,
-    http.Client? goldClient,
-    this.ingestionDelay = const Duration(seconds: 10),
-  })  : datastoreProvider = datastoreProvider ?? DatastoreService.defaultProvider,
-        goldClient = goldClient ?? http.Client();
-
-  final DatastoreServiceProvider datastoreProvider;
-  final http.Client goldClient;
-  final Duration ingestionDelay;
-
-  @override
-  Future<Body> get() async {
-    final DatastoreService datastore = datastoreProvider(config.db);
-
-    if (authContext!.clientContext.isDevelopmentEnvironment) {
-      // Don't push gold status from the local dev server.
-      return Body.empty;
-    }
-
-    await _sendStatusUpdates(datastore, Config.flutterSlug);
-    await _sendStatusUpdates(datastore, Config.engineSlug);
-
-    return Body.empty;
-  }
-
-  Future<void> _sendStatusUpdates(
-    DatastoreService datastore,
-    RepositorySlug slug,
-  ) async {
-    final GitHub gitHubClient = await config.createGitHubClient(slug: slug);
-    final List<GithubGoldStatusUpdate> statusUpdates = <GithubGoldStatusUpdate>[];
-    log.fine('Beginning Gold checks...');
-    await for (PullRequest pr in gitHubClient.pullRequests.list(slug)) {
-      assert(pr.number != null);
-      // Get last known Gold status from datastore.
-      final GithubGoldStatusUpdate lastUpdate = await datastore.queryLastGoldUpdate(slug, pr);
-      CreateStatus statusRequest;
-
-      log.fine('Last known Gold status for $slug#${pr.number} was with sha: '
-          '${lastUpdate.head}, status: ${lastUpdate.status}, description: ${lastUpdate.description}');
-
-      if (lastUpdate.status == GithubGoldStatusUpdate.statusCompleted && lastUpdate.head == pr.head!.sha) {
-        log.fine('Completed status already reported for this commit.');
-        // We have already seen this commit and it is completed or, this is not
-        // a change staged to land on master, which we should ignore.
-        continue;
-      }
-
-      final String defaultBranch = Config.defaultBranch(slug);
-      if (pr.base!.ref != defaultBranch) {
-        log.fine('This change is not staged to land on $defaultBranch, skipping.');
-        // This is potentially a release branch, or another change not landing
-        // on master, we don't need a Gold check.
-        continue;
-      }
-
-      if (pr.draft!) {
-        log.fine('This pull request is a draft.');
-        // We don't want to query Gold while a PR is in a draft state, and we
-        // don't want to needlessly hold a pending state either.
-        // If a PR has been marked `draft` after the fact, and there has not
-        // been a new commit, we cannot rescind a previously posted status, so
-        // if it is already pending, we should make the contributor aware of
-        // that fact.
-        if (lastUpdate.status == GithubGoldStatusUpdate.statusRunning &&
-            lastUpdate.head == pr.head!.sha &&
-            !await _alreadyCommented(gitHubClient, pr, slug, config.flutterGoldDraftChange)) {
-          await gitHubClient.issues
-              .createComment(slug, pr.number!, config.flutterGoldDraftChange + config.flutterGoldAlertConstant(slug));
-        }
-        continue;
-      }
-
-      log.fine('Querying builds for pull request #${pr.number} with sha: ${lastUpdate.head}...');
-      final GraphQLClient gitHubGraphQLClient = await config.createGitHubGraphQLClient();
-      final List<String> incompleteChecks = <String>[];
-      bool runsGoldenFileTests = false;
-      final Map<String, dynamic> data = (await _queryGraphQL(
-        gitHubGraphQLClient,
-        slug,
-        pr.number!,
-      ))!;
-      final Map<String, dynamic> prData = data['repository']['pullRequest'] as Map<String, dynamic>;
-      final Map<String, dynamic> commit = prData['commits']['nodes'].single['commit'] as Map<String, dynamic>;
-      List<Map<String, dynamic>>? checkRuns;
-      if (commit['checkSuites']['nodes'] != null && (commit['checkSuites']['nodes'] as List<dynamic>).isNotEmpty) {
-        checkRuns =
-            (commit['checkSuites']['nodes']?.first['checkRuns']['nodes'] as List<dynamic>).cast<Map<String, dynamic>>();
-      }
-      checkRuns = checkRuns ?? <Map<String, dynamic>>[];
-      log.fine('This PR has ${checkRuns.length} checks.');
-      for (Map<String, dynamic> checkRun in checkRuns) {
-        log.fine('Check run: $checkRun');
-        final String name = checkRun['name'].toLowerCase() as String;
-        // Framework shards run framework goldens
-        // Web shards run web version of framework goldens
-        // Misc shard runs API docs goldens
-        if (name.contains('framework') || name.contains('web engine') || name.contains('misc')) {
-          runsGoldenFileTests = true;
-        }
-        if (checkRun['conclusion'] == null || checkRun['conclusion'].toUpperCase() != 'SUCCESS') {
-          incompleteChecks.add(name);
-        }
-      }
-
-      if (runsGoldenFileTests) {
-        log.fine('This PR executes golden file tests.');
-        // Check when this PR was last updated. Gold does not keep results after
-        // >20 days. If a PR has gone stale, we should draw attention to it to be
-        // updated or closed.
-        final DateTime updatedAt = pr.updatedAt!.toUtc();
-        final DateTime twentyDaysAgo = DateTime.now().toUtc().subtract(const Duration(days: 20));
-        if (updatedAt.isBefore(twentyDaysAgo)) {
-          log.fine('Stale PR, no gold status to report.');
-          if (!await _alreadyCommented(gitHubClient, pr, slug, config.flutterGoldStalePR)) {
-            log.fine('Notifying for stale PR.');
-            await gitHubClient.issues
-                .createComment(slug, pr.number!, config.flutterGoldStalePR + config.flutterGoldAlertConstant(slug));
-          }
-          continue;
-        }
-
-        if (incompleteChecks.isNotEmpty) {
-          // If checks on an open PR are running or failing, the gold status
-          // should just be pending. Any draft PRs are skipped
-          // until marked ready for review.
-          log.fine('Waiting for checks to be completed.');
-          statusRequest =
-              _createStatus(GithubGoldStatusUpdate.statusRunning, config.flutterGoldPending, slug, pr.number!);
-        } else {
-          // We do not want to query Gold on a draft PR.
-          assert(!pr.draft!);
-          // Get Gold status.
-          final String goldStatus = await _getGoldStatus(slug, pr);
-          statusRequest = _createStatus(
-            goldStatus,
-            goldStatus == GithubGoldStatusUpdate.statusRunning ? config.flutterGoldChanges : config.flutterGoldSuccess,
-            slug,
-            pr.number!,
-          );
-          log.fine('New status for potential update: ${statusRequest.state}, ${statusRequest.description}');
-          if (goldStatus == GithubGoldStatusUpdate.statusRunning &&
-              !await _alreadyCommented(gitHubClient, pr, slug, config.flutterGoldCommentID(pr))) {
-            log.fine('Notifying for triage.');
-            await _commentAndApplyGoldLabels(gitHubClient, pr, slug);
-          }
-        }
-
-        // Push updates if there is a status change (detected by unique description)
-        // or this is a new commit.
-        if (lastUpdate.description != statusRequest.description || lastUpdate.head != pr.head!.sha) {
-          try {
-            log.fine('Pushing status to GitHub: ${statusRequest.state}, ${statusRequest.description}');
-            await gitHubClient.repositories.createStatus(slug, pr.head!.sha!, statusRequest);
-            lastUpdate.status = statusRequest.state!;
-            lastUpdate.head = pr.head!.sha;
-            lastUpdate.updates = (lastUpdate.updates ?? 0) + 1;
-            lastUpdate.description = statusRequest.description!;
-            statusUpdates.add(lastUpdate);
-          } catch (error) {
-            log.severe('Failed to post status update to ${slug.fullName}#${pr.number}: $error');
-          }
-        }
-      } else {
-        log.fine('This PR does not execute golden file tests.');
-      }
-    }
-    await datastore.insert(statusUpdates);
-    log.fine('Committed all updates for $slug');
-  }
-
-  /// Returns a GitHub Status for the given state and description.
-  CreateStatus _createStatus(String state, String description, RepositorySlug slug, int prNumber) {
-    final CreateStatus statusUpdate = CreateStatus(state)
-      ..targetUrl = _getTriageUrl(slug, prNumber)
-      ..context = 'flutter-gold'
-      ..description = description;
-    return statusUpdate;
-  }
-
-  /// Used to check for any tryjob results from Flutter Gold associated with a
-  /// pull request.
-  Future<String> _getGoldStatus(RepositorySlug slug, PullRequest pr) async {
-    // We wait for a few seconds in case tests _just_ finished and the tryjob
-    // has not finished ingesting the results.
-    await Future<void>.delayed(ingestionDelay);
-    final Uri requestForTryjobStatus =
-        Uri.parse('${_getGoldHost(slug)}/json/v1/changelist_summary/github/${pr.number}');
-    try {
-      log.fine('Querying Gold for image results...');
-      final http.Response response = await goldClient.get(requestForTryjobStatus);
-      if (response.statusCode != HttpStatus.ok) {
-        throw HttpException(response.body);
-      }
-
-      final dynamic jsonResponseTriage = json.decode(response.body);
-      if (jsonResponseTriage is! Map<String, dynamic>) {
-        throw const FormatException('Skia gold changelist summary does not match expected format.');
-      }
-      final List<dynamic> patchsets = jsonResponseTriage['patchsets'] as List<dynamic>;
-      int untriaged = 0;
-      for (int i = 0; i < patchsets.length; i++) {
-        final Map<String, dynamic> patchset = patchsets[i] as Map<String, dynamic>;
-        if (patchset['patchset_id'] == pr.head!.sha) {
-          untriaged = patchset['new_untriaged_images'] as int;
-          break;
-        }
-      }
-
-      if (untriaged == 0) {
-        log.fine('There are no unexpected image results for #${pr.number} at sha '
-            '${pr.head!.sha}.');
-
-        return GithubGoldStatusUpdate.statusCompleted;
-      } else {
-        log.fine('Tryjob for #${pr.number} at sha ${pr.head!.sha} generated new '
-            'images.');
-
-        return GithubGoldStatusUpdate.statusRunning;
-      }
-    } on FormatException catch (e) {
-      throw BadRequestException('Formatting error detected requesting '
-          'tryjob status for pr #${pr.number} from Flutter Gold.\n'
-          'response: $response\n'
-          'error: $e');
-    } catch (e) {
-      throw BadRequestException('Error detected requesting tryjob status for pr '
-          '#${pr.number} from Flutter Gold.\n'
-          'error: $e');
-    }
-  }
-
-  String _getTriageUrl(RepositorySlug slug, int number) {
-    return '${_getGoldHost(slug)}/cl/github/$number';
-  }
-
-  String _getGoldHost(RepositorySlug slug) {
-    if (slug == Config.flutterSlug) {
-      return 'https://flutter-gold.skia.org';
-    }
-
-    if (slug == Config.engineSlug) {
-      return 'https://flutter-engine-gold.skia.org';
-    }
-
-    throw Exception('Unknown slug: $slug');
-  }
-
-  /// Creates a comment on a given pull request identified to have golden file
-  /// changes and applies the `will affect goldens` label.
-  Future<void> _commentAndApplyGoldLabels(
-    GitHub gitHubClient,
-    PullRequest pr,
-    RepositorySlug slug,
-  ) async {
-    String body;
-    if (await _isFirstComment(gitHubClient, pr, slug)) {
-      body = config.flutterGoldInitialAlert(_getTriageUrl(slug, pr.number!));
-    } else {
-      body = config.flutterGoldFollowUpAlert(_getTriageUrl(slug, pr.number!));
-    }
-    body += config.flutterGoldAlertConstant(slug) + config.flutterGoldCommentID(pr);
-    await gitHubClient.issues.createComment(slug, pr.number!, body);
-    await gitHubClient.issues.addLabelsToIssue(slug, pr.number!, <String>[
-      'will affect goldens',
-    ]);
-  }
-
-  Future<bool> _alreadyCommented(
-    GitHub gitHubClient,
-    PullRequest pr,
-    RepositorySlug slug,
-    String message,
-  ) async {
-    final Stream<IssueComment> comments = gitHubClient.issues.listCommentsByIssue(slug, pr.number!);
-    await for (IssueComment comment in comments) {
-      if (comment.body!.contains(message)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  Future<bool> _isFirstComment(
-    GitHub gitHubClient,
-    PullRequest pr,
-    RepositorySlug slug,
-  ) async {
-    final Stream<IssueComment> comments = gitHubClient.issues.listCommentsByIssue(slug, pr.number!);
-    await for (IssueComment comment in comments) {
-      if (comment.body!.contains(config.flutterGoldInitialAlert(_getTriageUrl(slug, pr.number!)))) {
-        return false;
-      }
-    }
-    return true;
-  }
-}
-
-Future<Map<String, dynamic>?> _queryGraphQL(
-  GraphQLClient client,
-  RepositorySlug slug,
-  int prNumber,
-) async {
-  final QueryResult result = await client.query(
-    QueryOptions(
-      document: lang.parseString(pullRequestChecksQuery),
-      fetchPolicy: FetchPolicy.noCache,
-      variables: <String, dynamic>{
-        'sPullRequest': prNumber,
-        'sRepoOwner': slug.owner,
-        'sRepoName': slug.name,
-      },
-    ),
-  );
-
-  if (result.hasException) {
-    log.severe(result.exception.toString());
-    throw const BadRequestException('GraphQL query failed');
-  }
-  return result.data;
-}
-
-const String pullRequestChecksQuery = r'''
-query ChecksForPullRequest($sPullRequest: Int!, $sRepoOwner: String!, $sRepoName: String!) {
-  repository(owner: $sRepoOwner, name: $sRepoName) {
-    pullRequest(number: $sPullRequest) {
-      commits(last: 1) {
-        nodes {
-          commit {
-            # (appId: 64368) == flutter-dashboard. We only care about
-            # flutter-dashboard checks.
-
-            checkSuites(last: 1, filterBy: {appId: 64368}) {
-              nodes {
-                checkRuns(first: 100) {
-                  nodes {
-                    name
-                    status
-                    conclusion
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}''';
diff --git a/app_dart/lib/src/request_handlers/readiness_check.dart b/app_dart/lib/src/request_handlers/readiness_check.dart
deleted file mode 100644
index 6c8ecbe..0000000
--- a/app_dart/lib/src/request_handlers/readiness_check.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2021 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-import 'package:meta/meta.dart';
-import '../request_handling/body.dart';
-import '../request_handling/request_handler.dart';
-
-@immutable
-class ReadinessCheck extends RequestHandler<Body> {
-  const ReadinessCheck({required super.config});
-
-  @override
-  Future<Body> get() async {
-    return Body.empty;
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/reset_prod_task.dart b/app_dart/lib/src/request_handlers/reset_prod_task.dart
deleted file mode 100644
index 19e3162..0000000
--- a/app_dart/lib/src/request_handlers/reset_prod_task.dart
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2020 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:gcloud/db.dart';
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-
-import '../model/appengine/commit.dart';
-import '../model/appengine/key_helper.dart';
-import '../model/appengine/task.dart';
-import '../model/ci_yaml/ci_yaml.dart';
-import '../model/ci_yaml/target.dart';
-import '../model/google/token_info.dart';
-import '../request_handling/api_request_handler.dart';
-import '../request_handling/body.dart';
-import '../request_handling/exceptions.dart';
-import '../service/config.dart';
-import '../service/datastore.dart';
-import '../service/luci_build_service.dart';
-import '../service/scheduler.dart';
-
-/// Reruns a postsubmit LUCI build.
-///
-/// Expects either [taskKeyParam] or a set of params that give enough detail to lookup a task in datastore.
-@immutable
-class ResetProdTask extends ApiRequestHandler<Body> {
-  const ResetProdTask({
-    required super.config,
-    required super.authenticationProvider,
-    required this.luciBuildService,
-    required this.scheduler,
-    @visibleForTesting DatastoreServiceProvider? datastoreProvider,
-  }) : datastoreProvider = datastoreProvider ?? DatastoreService.defaultProvider;
-
-  final DatastoreServiceProvider datastoreProvider;
-  final LuciBuildService luciBuildService;
-  final Scheduler scheduler;
-
-  static const String branchParam = 'Branch';
-  static const String taskKeyParam = 'Key';
-  static const String ownerParam = 'Owner';
-  static const String repoParam = 'Repo';
-  static const String commitShaParam = 'Commit';
-
-  /// Name of the task to be retried.
-  ///
-  /// If "all" is given, all failed tasks will be retried. This enables
-  /// oncalls to quickly recover a commit without the tedium of the UI.
-  static const String taskParam = 'Task';
-
-  @override
-  Future<Body> post() async {
-    final DatastoreService datastore = datastoreProvider(config.db);
-    final String? encodedKey = requestData![taskKeyParam] as String?;
-    String? branch = requestData![branchParam] as String?;
-    final String owner = requestData![ownerParam] as String? ?? 'flutter';
-    final String? repo = requestData![repoParam] as String?;
-    final String? sha = requestData![commitShaParam] as String?;
-    final TokenInfo token = await tokenInfo(request!);
-    final String? taskName = requestData![taskParam] as String?;
-
-    RepositorySlug? slug;
-    if (encodedKey != null && encodedKey.isNotEmpty) {
-      // Check params required for dashboard.
-      checkRequiredParameters(<String>[taskKeyParam]);
-    } else {
-      // Checks params required when this API is called with curl.
-      checkRequiredParameters(<String>[commitShaParam, taskParam, repoParam]);
-      slug = RepositorySlug(owner, repo!);
-      branch ??= Config.defaultBranch(slug);
-    }
-
-    if (taskName == 'all') {
-      final Key<String> commitKey = Commit.createKey(
-        db: datastore.db,
-        slug: slug!,
-        gitBranch: branch!,
-        sha: sha!,
-      );
-      final tasks = await datastore.db.query<Task>(ancestorKey: commitKey).run().toList();
-      final List<Future<void>> futures = <Future<void>>[];
-      for (final Task task in tasks) {
-        if (!taskFailStatusSet.contains(task.status)) continue;
-        futures.add(
-          rerun(
-            datastore: datastore,
-            branch: branch,
-            sha: sha,
-            taskName: task.name,
-            slug: slug,
-            email: token.email!,
-          ),
-        );
-      }
-      await Future.wait(futures);
-    } else {
-      await rerun(
-        datastore: datastore,
-        encodedKey: encodedKey,
-        branch: branch,
-        sha: sha,
-        taskName: taskName,
-        slug: slug,
-        email: token.email!,
-        ignoreChecks: true,
-      );
-    }
-
-    return Body.empty;
-  }
-
-  Future<void> rerun({
-    required DatastoreService datastore,
-    String? encodedKey,
-    String? branch,
-    String? sha,
-    String? taskName,
-    RepositorySlug? slug,
-    required String email,
-    bool ignoreChecks = false,
-  }) async {
-    final Task task = await _getTaskFromNamedParams(
-      datastore: datastore,
-      encodedKey: encodedKey,
-      branch: branch,
-      name: taskName,
-      sha: sha,
-      slug: slug,
-    );
-    final Commit commit = await _getCommitFromTask(datastore, task);
-
-    final CiYaml ciYaml = await scheduler.getCiYaml(commit);
-    final Target target = ciYaml.postsubmitTargets.singleWhere((Target target) => target.value.name == task.name);
-
-    final Map<String, List<String>> tags = <String, List<String>>{
-      'triggered_by': <String>[email],
-      'trigger_type': <String>['manual'],
-    };
-    final bool isRerunning = await luciBuildService.checkRerunBuilder(
-      commit: commit,
-      task: task,
-      target: target,
-      datastore: datastore,
-      tags: tags,
-      ignoreChecks: ignoreChecks,
-    );
-
-    // For human retries from the dashboard, notify if a task failed to rerun.
-    if (ignoreChecks && isRerunning == false) {
-      throw InternalServerError('Failed to rerun $taskName');
-    }
-  }
-
-  /// Retrieve [Task] from [DatastoreService] from either an encoded key or commit + task name info.
-  ///
-  /// If [encodedKey] is passed, [KeyHelper] will decode it directly and return the associated entity.
-  ///
-  /// Otherwise, [name], [branch], [sha], and [slug] must be passed to find the [Task].
-  Future<Task> _getTaskFromNamedParams({
-    required DatastoreService datastore,
-    String? encodedKey,
-    String? branch,
-    String? name,
-    String? sha,
-    RepositorySlug? slug,
-  }) async {
-    if (encodedKey != null && encodedKey.isNotEmpty) {
-      final Key<int> key = config.keyHelper.decode(encodedKey) as Key<int>;
-      return datastore.lookupByValue<Task>(key);
-    }
-    final Key<String> commitKey = Commit.createKey(
-      db: datastore.db,
-      slug: slug!,
-      gitBranch: branch!,
-      sha: sha!,
-    );
-    return Task.fromDatastore(
-      datastore: datastore,
-      commitKey: commitKey,
-      name: name!,
-    );
-  }
-
-  /// Returns the [Commit] associated with [Task].
-  Future<Commit> _getCommitFromTask(DatastoreService datastore, Task task) async {
-    return (await datastore.lookupByKey<Commit>(<Key<dynamic>>[task.parentKey!])).single!;
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/reset_try_task.dart b/app_dart/lib/src/request_handlers/reset_try_task.dart
deleted file mode 100644
index 19829a5..0000000
--- a/app_dart/lib/src/request_handlers/reset_try_task.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2020 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-
-import '../../cocoon_service.dart';
-import '../request_handling/api_request_handler.dart';
-import '../request_handling/exceptions.dart';
-
-/// Runs all the applicable tasks for a given PR and commit hash. This will be
-/// used to unblock rollers when creating a new commit is not possible.
-@immutable
-class ResetTryTask extends ApiRequestHandler<Body> {
-  const ResetTryTask({
-    required super.config,
-    required super.authenticationProvider,
-    required this.scheduler,
-  });
-
-  final Scheduler scheduler;
-
-  static const String kOwnerParam = 'owner';
-  static const String kRepoParam = 'repo';
-  static const String kPullRequestNumberParam = 'pr';
-  static const String kBuilderParam = 'builders';
-
-  @override
-  Future<Body> get() async {
-    checkRequiredQueryParameters(<String>[kRepoParam, kPullRequestNumberParam]);
-    final String owner = request!.uri.queryParameters[kOwnerParam] ?? 'flutter';
-    final String repo = request!.uri.queryParameters[kRepoParam]!;
-    final String pr = request!.uri.queryParameters[kPullRequestNumberParam]!;
-    final String builders = request!.uri.queryParameters[kBuilderParam] ?? '';
-    final List<String> builderList = getBuilderList(builders);
-
-    final int? prNumber = int.tryParse(pr);
-    if (prNumber == null) {
-      throw const BadRequestException('$kPullRequestNumberParam must be a number');
-    }
-    final RepositorySlug slug = RepositorySlug(owner, repo);
-    final GitHub github = await config.createGitHubClient(slug: slug);
-    final PullRequest pullRequest = await github.pullRequests.get(slug, prNumber);
-    await scheduler.triggerPresubmitTargets(pullRequest: pullRequest, builderTriggerList: builderList);
-    return Body.empty;
-  }
-
-  /// Parses [builders] to a String list.
-  ///
-  /// The [builders] parameter is expecting comma joined string, e.g. 'builder1, builder2'.
-  /// Returns an empty list if no [builders] is specified.
-  List<String> getBuilderList(String builders) {
-    if (builders.isEmpty) {
-      return <String>[];
-    }
-    return builders.split(',').map((String builder) => builder.trim()).toList();
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/scheduler/batch_backfiller.dart b/app_dart/lib/src/request_handlers/scheduler/batch_backfiller.dart
deleted file mode 100644
index 0c80599..0000000
--- a/app_dart/lib/src/request_handlers/scheduler/batch_backfiller.dart
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:cocoon_service/src/foundation/utils.dart';
-import 'package:cocoon_service/src/model/appengine/task.dart';
-import 'package:cocoon_service/src/request_handling/body.dart';
-import 'package:cocoon_service/src/service/datastore.dart';
-import 'package:cocoon_service/src/service/scheduler/policy.dart';
-import 'package:gcloud/db.dart';
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-import 'package:retry/retry.dart';
-
-import '../../model/ci_yaml/ci_yaml.dart';
-import '../../model/ci_yaml/target.dart';
-import '../../request_handling/exceptions.dart';
-import '../../request_handling/request_handler.dart';
-import '../../service/config.dart';
-import '../../service/logging.dart';
-import '../../service/luci_build_service.dart';
-import '../../service/scheduler.dart';
-
-/// Cron request handler for scheduling targets when capacity becomes available.
-///
-/// Targets that have a [BatchPolicy] need to have backfilling enabled to ensure that ToT is always being tested.
-@immutable
-class BatchBackfiller extends RequestHandler {
-  /// Creates a subscription for sending BuildBucket requests.
-  const BatchBackfiller({
-    required super.config,
-    required this.scheduler,
-    @visibleForTesting this.datastoreProvider = DatastoreService.defaultProvider,
-  });
-
-  final DatastoreServiceProvider datastoreProvider;
-  final Scheduler scheduler;
-
-  @override
-  Future<Body> get() async {
-    final List<Future<void>> futures = <Future<void>>[];
-
-    for (RepositorySlug slug in config.supportedRepos) {
-      futures.add(backfillRepository(slug));
-    }
-
-    // Process all repos asynchronously
-    await Future.wait<void>(futures);
-
-    return Body.empty;
-  }
-
-  Future<void> backfillRepository(RepositorySlug slug) async {
-    final DatastoreService datastore = datastoreProvider(config.db);
-    final List<FullTask> tasks =
-        await (datastore.queryRecentTasks(slug: slug, commitLimit: config.backfillerCommitLimit)).toList();
-
-    // Construct Task columns to scan for backfilling
-    final Map<String, List<FullTask>> taskMap = <String, List<FullTask>>{};
-    for (FullTask fullTask in tasks) {
-      if (taskMap.containsKey(fullTask.task.name)) {
-        taskMap[fullTask.task.name]!.add(fullTask);
-      } else {
-        taskMap[fullTask.task.name!] = <FullTask>[fullTask];
-      }
-    }
-
-    // Check if should be scheduled (there is no yellow runs). Run the most recent gray.
-    List<Tuple<Target, FullTask, int>> backfill = <Tuple<Target, FullTask, int>>[];
-    for (List<FullTask> taskColumn in taskMap.values) {
-      final FullTask task = taskColumn.first;
-      final CiYaml ciYaml = await scheduler.getCiYaml(task.commit);
-      final List<Target> ciYamlTargets = ciYaml.backfillTargets;
-      // Skips scheduling if the task is not in TOT commit anymore.
-      final bool taskInToT = ciYamlTargets.map((Target target) => target.value.name).toList().contains(task.task.name);
-      if (!taskInToT) {
-        continue;
-      }
-      final Target target = ciYamlTargets.singleWhere((target) => target.value.name == task.task.name);
-      if (target.schedulerPolicy is! BatchPolicy) {
-        continue;
-      }
-      final FullTask? backfillTask = _backfillTask(target, taskColumn);
-      final int? priority = backfillPriority(taskColumn.map((e) => e.task).toList());
-      if (priority != null && backfillTask != null) {
-        backfill.add(Tuple<Target, FullTask, int>(target, backfillTask, priority));
-      }
-    }
-
-    // Get the number of targets to be backfilled in each cycle.
-    backfill = getFilteredBackfill(backfill);
-
-    log.fine('Backfilling ${backfill.length} builds');
-    log.fine(backfill.map<String>((Tuple<Target, FullTask, int> tuple) => tuple.first.value.name));
-
-    // Update tasks status as in progress to avoid duplicate scheduling.
-    final List<Task> backfillTasks = backfill.map((Tuple<Target, FullTask, int> tuple) => tuple.second.task).toList();
-    try {
-      await datastore.withTransaction<void>((Transaction transaction) async {
-        transaction.queueMutations(inserts: backfillTasks);
-        await transaction.commit();
-        log.fine(
-          'Updated ${backfillTasks.length} tasks: ${backfillTasks.map((e) => e.name).toList()} when backfilling.',
-        );
-      });
-      // Schedule all builds asynchronously.
-      // Schedule after db updates to avoid duplicate scheduling when db update fails.
-      await _scheduleWithRetries(backfill);
-    } catch (error) {
-      log.severe('Failed to update tasks when backfilling: $error');
-    }
-  }
-
-  /// Filters [config.backfillerTargetLimit] targets to backfill.
-  ///
-  /// High priority targets will be guranteed to get back filled first. If more targets
-  /// than [config.backfillerTargetLimit], pick the limited number of targets after a
-  /// shuffle. This is to make sure all targets are picked with the same chance.
-  List<Tuple<Target, FullTask, int>> getFilteredBackfill(List<Tuple<Target, FullTask, int>> backfill) {
-    if (backfill.length <= config.backfillerTargetLimit) {
-      return backfill;
-    }
-    final List<Tuple<Target, FullTask, int>> filteredBackfill = <Tuple<Target, FullTask, int>>[];
-    final List<Tuple<Target, FullTask, int>> highPriorityBackfill =
-        backfill.where((element) => element.third == LuciBuildService.kRerunPriority).toList();
-    final List<Tuple<Target, FullTask, int>> normalPriorityBackfill =
-        backfill.where((element) => element.third != LuciBuildService.kRerunPriority).toList();
-    if (highPriorityBackfill.length >= config.backfillerTargetLimit) {
-      highPriorityBackfill.shuffle();
-      filteredBackfill.addAll(highPriorityBackfill.sublist(0, config.backfillerTargetLimit));
-    } else {
-      filteredBackfill.addAll(highPriorityBackfill);
-      normalPriorityBackfill.shuffle();
-      filteredBackfill
-          .addAll(normalPriorityBackfill.sublist(0, config.backfillerTargetLimit - highPriorityBackfill.length));
-    }
-    return filteredBackfill;
-  }
-
-  /// Schedules tasks with retry when hitting pub/sub server errors.
-  Future<void> _scheduleWithRetries(List<Tuple<Target, FullTask, int>> backfill) async {
-    const RetryOptions retryOptions = Config.schedulerRetry;
-    try {
-      await retryOptions.retry(
-        () async {
-          final List<List<Tuple<Target, Task, int>>> tupleLists =
-              await Future.wait<List<Tuple<Target, Task, int>>>(backfillRequestList(backfill));
-          if (tupleLists.any((List<Tuple<Target, Task, int>> tupleList) => tupleList.isNotEmpty)) {
-            final int nonEmptyListLenght = tupleLists.where((element) => element.isNotEmpty).toList().length;
-            log.info('Backfill fails and retry backfilling $nonEmptyListLenght targets.');
-            backfill = _updateBackfill(backfill, tupleLists);
-            throw InternalServerError('Failed to backfill ${backfill.length} targets.');
-          }
-        },
-        retryIf: (Exception e) => e is InternalServerError,
-      );
-    } catch (error) {
-      log.severe('Failed to backfill ${backfill.length} targets due to error: $error');
-    }
-  }
-
-  /// Updates the [backfill] list with those that fail to get scheduled.
-  ///
-  /// [tupleLists] maintains the same tuple order as those in [backfill].
-  /// Each element from [backfill] is encapsulated as a list in [tupleLists] to prepare for
-  /// [scheduler.luciBuildService.schedulePostsubmitBuilds].
-  List<Tuple<Target, FullTask, int>> _updateBackfill(
-    List<Tuple<Target, FullTask, int>> backfill,
-    List<List<Tuple<Target, Task, int>>> tupleLists,
-  ) {
-    final List<Tuple<Target, FullTask, int>> updatedBackfill = <Tuple<Target, FullTask, int>>[];
-    for (int i = 0; i < tupleLists.length; i++) {
-      if (tupleLists[i].isNotEmpty) {
-        updatedBackfill.add(backfill[i]);
-      }
-    }
-    return updatedBackfill;
-  }
-
-  /// Creates a list of backfill requests.
-  List<Future<List<Tuple<Target, Task, int>>>> backfillRequestList(List<Tuple<Target, FullTask, int>> backfill) {
-    final List<Future<List<Tuple<Target, Task, int>>>> futures = <Future<List<Tuple<Target, Task, int>>>>[];
-    for (Tuple<Target, FullTask, int> tuple in backfill) {
-      // TODO(chillers): The backfill priority is always going to be low. If this is a ToT task, we should run it at the default priority.
-      final Tuple<Target, Task, int> toBeScheduled = Tuple(
-        tuple.first,
-        tuple.second.task,
-        tuple.third,
-      );
-      futures.add(
-        scheduler.luciBuildService.schedulePostsubmitBuilds(
-          commit: tuple.second.commit,
-          toBeScheduled: [toBeScheduled],
-        ),
-      );
-    }
-
-    return futures;
-  }
-
-  /// Returns priority for back filled targets.
-  ///
-  /// Skips scheduling newly created targets whose available entries are
-  /// less than `BatchPolicy.kBatchSize`.
-  ///
-  /// Uses a higher priority if there is an earlier failed build. Otherwise,
-  /// uses default `LuciBuildService.kBackfillPriority`
-  int? backfillPriority(List<Task> tasks) {
-    if (tasks.length < BatchPolicy.kBatchSize) {
-      return null;
-    }
-    if (shouldRerunPriority(tasks, BatchPolicy.kBatchSize)) {
-      return LuciBuildService.kRerunPriority;
-    }
-    return LuciBuildService.kBackfillPriority;
-  }
-
-  /// Returns the most recent [FullTask] to backfill.
-  ///
-  /// A [FullTask] is only returned iff:
-  ///   1. There are no running builds (yellow)
-  ///   2. There are tasks that haven't been run (gray)
-  ///
-  /// This is naive, and doesn't rely on knowing the actual Flutter infra capacity.
-  ///
-  /// Otherwise, returns null indicating nothing should be backfilled.
-  FullTask? _backfillTask(Target target, List<FullTask> tasks) {
-    final List<FullTask> relevantTasks = tasks.where((FullTask task) => task.task.name == target.value.name).toList();
-    if (relevantTasks.any((FullTask task) => task.task.status == Task.statusInProgress)) {
-      // Don't schedule more builds where there is already a running task
-      return null;
-    }
-
-    final List<FullTask> backfillTask =
-        relevantTasks.where((FullTask task) => task.task.status == Task.statusNew).toList();
-    if (backfillTask.isEmpty) {
-      return null;
-    }
-
-    // First item in the list is guranteed to be most recent.
-    // Mark task as in progress to ensure it isn't scheduled over
-    backfillTask.first.task.status = Task.statusInProgress;
-    return backfillTask.first;
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/scheduler/request_subscription.dart b/app_dart/lib/src/request_handlers/scheduler/request_subscription.dart
deleted file mode 100644
index 874d16d..0000000
--- a/app_dart/lib/src/request_handlers/scheduler/request_subscription.dart
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-
-import 'package:meta/meta.dart';
-import 'package:retry/retry.dart';
-
-import '../../../cocoon_service.dart';
-import '../../model/luci/buildbucket.dart';
-import '../../request_handling/exceptions.dart';
-import '../../request_handling/subscription_handler.dart';
-import '../../service/logging.dart';
-
-/// Subscription for making requests to BuildBucket.
-///
-/// The PubSub subscription is set up here:
-/// https://console.cloud.google.com/cloudpubsub/subscription/detail/scheduler-requests?project=flutter-dashboard
-///
-/// This endpoint allows Cocoon to defer BuildBucket requests off the main request loop. This is critical when new
-/// commits are pushed, and they can schedule 100+ builds at once.
-///
-/// This endpoint takes in a POST request with the JSON of a [BatchRequest]. In practice, the
-/// [BatchRequest] should contain a single request.
-@immutable
-class SchedulerRequestSubscription extends SubscriptionHandler {
-  /// Creates a subscription for sending BuildBucket requests.
-  const SchedulerRequestSubscription({
-    required super.cache,
-    required super.config,
-    required this.buildBucketClient,
-    super.authProvider,
-    this.retryOptions = Config.schedulerRetry,
-  }) : super(subscriptionName: 'scheduler-requests');
-
-  final BuildBucketClient buildBucketClient;
-
-  final RetryOptions retryOptions;
-
-  @override
-  Future<Body> post() async {
-    BatchRequest request;
-    try {
-      final String data = message.data!;
-      Map<String, dynamic> jsonData;
-      log.info('rawJson: $data');
-      try {
-        jsonData = jsonDecode(data) as Map<String, dynamic>;
-      } on FormatException {
-        jsonData = json.decode(String.fromCharCodes(base64.decode(data))) as Map<String, dynamic>;
-      }
-      request = BatchRequest.fromJson(jsonData);
-    } catch (e) {
-      log.severe('Failed to construct BatchRequest from message');
-      log.severe(e);
-      throw BadRequestException(e.toString());
-    }
-
-    /// Retry scheduling builds upto 3 times.
-    ///
-    /// Log error message when still failing after retry. Avoid endless rescheduling
-    /// by acking the pub/sub message without throwing an exception.
-    String? unScheduledBuilds;
-    try {
-      await retryOptions.retry(
-        () async {
-          final List<Request> requestsToRetry = await _sendBatchRequest(request);
-          request = BatchRequest(requests: requestsToRetry);
-          unScheduledBuilds = requestsToRetry.map((e) => e.scheduleBuild!.builderId.builder).toString();
-          if (requestsToRetry.isNotEmpty) {
-            throw InternalServerError('Failed to schedule builds: $unScheduledBuilds.');
-          }
-        },
-        retryIf: (Exception e) => e is InternalServerError,
-      );
-    } catch (e) {
-      log.warning('Failed to schedule builds: $unScheduledBuilds.');
-      return Body.forString('Failed to schedule builds: $unScheduledBuilds.');
-    }
-
-    return Body.empty;
-  }
-
-  /// Wrapper around [BuildbucketClient.batch] to ensure all requests are made.
-  ///
-  /// Returns [List<Request>] of requests that need to be retried.
-  Future<List<Request>> _sendBatchRequest(BatchRequest request) async {
-    final BatchResponse response = await buildBucketClient.batch(request);
-    log.fine('Made ${request.requests?.length} and received ${response.responses?.length}');
-    log.fine('Responses: ${response.responses}');
-
-    // By default, retry everything. Then remove requests with a verified response.
-    final List<Request> retry = request.requests ?? <Request>[];
-    response.responses?.forEach((Response subresponse) {
-      if (subresponse.scheduleBuild != null) {
-        retry
-            .removeWhere((Request request) => request.scheduleBuild?.builderId == subresponse.scheduleBuild!.builderId);
-      } else {
-        log.warning('Response does not have schedule build: $subresponse');
-      }
-      if (subresponse.error?.code != 0) {
-        log.fine('Non-zero grpc code: $subresponse');
-      }
-    });
-
-    return retry;
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/scheduler/vacuum_stale_tasks.dart b/app_dart/lib/src/request_handlers/scheduler/vacuum_stale_tasks.dart
deleted file mode 100644
index 852c526..0000000
--- a/app_dart/lib/src/request_handlers/scheduler/vacuum_stale_tasks.dart
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:cocoon_service/cocoon_service.dart';
-import 'package:github/github.dart' as gh;
-import 'package:meta/meta.dart';
-
-import '../../model/appengine/task.dart';
-import '../../service/datastore.dart';
-import '../../service/logging.dart';
-
-/// Vacuum stale tasks.
-///
-/// Occassionally, a build never gets processed by LUCI. To prevent tasks
-/// being stuck as "In Progress," this will return tasks to "New" if they have
-/// no updates after 3 hours.
-@immutable
-class VacuumStaleTasks extends RequestHandler<Body> {
-  const VacuumStaleTasks({
-    required super.config,
-    @visibleForTesting this.datastoreProvider = DatastoreService.defaultProvider,
-    @visibleForTesting this.nowValue,
-  });
-
-  final DatastoreServiceProvider datastoreProvider;
-
-  /// For testing, can be used to inject a deterministic time.
-  final DateTime? nowValue;
-
-  /// Tasks that are in progress for this duration will be reset.
-  static const Duration kTimeoutLimit = Duration(hours: 3);
-
-  @override
-  Future<Body> get() async {
-    final List<Future<void>> futures = <Future<void>>[];
-    for (gh.RepositorySlug slug in config.supportedRepos) {
-      futures.add(_vacuumRepository(slug));
-    }
-
-    await Future.wait(futures);
-
-    return Body.empty;
-  }
-
-  /// Scans [slug] for tasks that have reached the timeout limit, and sets
-  /// them back to the new state.
-  ///
-  /// The expectation is the [BatchBackfiller] will be able to reschedule these.
-  Future<void> _vacuumRepository(gh.RepositorySlug slug) async {
-    final DatastoreService datastore = datastoreProvider(config.db);
-
-    final List<FullTask> tasks = await datastore.queryRecentTasks(slug: slug).toList();
-    final Set<Task> tasksToBeReset = <Task>{};
-    for (FullTask fullTask in tasks) {
-      final Task task = fullTask.task;
-      if (task.status != Task.statusInProgress) {
-        continue;
-      }
-
-      if (task.createTimestamp == null) {
-        log.fine('Vacuuming $task due to createTimestamp being null');
-        tasksToBeReset.add(task);
-        continue;
-      }
-
-      final DateTime now = nowValue ?? DateTime.now();
-      final DateTime create = DateTime.fromMillisecondsSinceEpoch(task.createTimestamp!);
-      final Duration queueTime = now.difference(create);
-
-      if (queueTime > kTimeoutLimit) {
-        log.fine('Vacuuming $task due to staleness');
-        tasksToBeReset.add(task);
-        continue;
-      }
-    }
-
-    final Iterable<Task> inserts =
-        tasksToBeReset.map((Task task) => task..status = Task.statusNew).map((Task task) => task..createTimestamp = 0);
-    await datastore.insert(inserts.toList());
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/test_ownership.dart b/app_dart/lib/src/request_handlers/test_ownership.dart
deleted file mode 100644
index cdf3210..0000000
--- a/app_dart/lib/src/request_handlers/test_ownership.dart
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2023 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:cocoon_service/src/request_handlers/flaky_handler_utils.dart';
-import '../../protos.dart' as pb;
-
-abstract class TestOwner {
-  factory TestOwner(BuilderType builderType) {
-    switch (builderType) {
-      case BuilderType.devicelab:
-        return DeviceLabTestOwner();
-      case BuilderType.firebaselab:
-        return FirebaseLabTestOwner();
-      case BuilderType.frameworkHostOnly:
-        return FrameworkHostOnlyTestOwner();
-      case BuilderType.shard:
-        return ShardTestOwner();
-      default:
-        return UnknownTestOwner();
-    }
-  }
-
-  TestOwnership getTestOwnership(
-    pb.Target target,
-    String testOwnersContent,
-  );
-}
-
-Team teamFromString(String teamString) {
-  switch (teamString) {
-    case 'flutter/framework':
-      return Team.framework;
-    case 'flutter/engine':
-      return Team.engine;
-    case 'flutter/tool':
-      return Team.tool;
-    case 'flutter/web':
-      return Team.web;
-  }
-  return Team.unknown;
-}
-
-String getTestNameFromTargetName(String targetName) {
-  // The builder names is in the format '<platform> <test name>'.
-  final List<String> words = targetName.split(' ');
-  return words.length < 2 ? words[0] : words[1];
-}
-
-class DeviceLabTestOwner implements TestOwner {
-  DeviceLabTestOwner();
-
-  @override
-  TestOwnership getTestOwnership(
-    pb.Target target,
-    String testOwnersContent,
-  ) {
-    String? owner;
-    Team? team;
-    final String testName = target.properties['task_name']!;
-    // The format looks like this:
-    //   /dev/devicelab/bin/tasks/dart_plugin_registry_test.dart @stuartmorgan @flutter/plugin
-    final RegExpMatch? match = devicelabTestOwners.firstMatch(testOwnersContent);
-    if (match != null && match.namedGroup(kOwnerGroupName) != null) {
-      final List<String> lines = match
-          .namedGroup(kOwnerGroupName)!
-          .split('\n')
-          .where((String line) => line.isNotEmpty && !line.startsWith('#'))
-          .toList();
-
-      for (final String line in lines) {
-        final List<String> words = line.trim().split(' ');
-        // e.g. words = ['/xxx/xxx/xxx_test.dart', '@stuartmorgan' '@flutter/tool']
-        if (words[0].endsWith('$testName.dart')) {
-          owner = words[1].substring(1); // Strip out the lead '@'
-          team = words.length < 3 ? Team.unknown : teamFromString(words[2].substring(1)); // Strip out the lead '@'
-          break;
-        }
-      }
-    }
-
-    return TestOwnership(owner, team);
-  }
-}
-
-class ShardTestOwner implements TestOwner {
-  @override
-  TestOwnership getTestOwnership(
-    pb.Target target,
-    String testOwnersContent,
-  ) {
-    // The format looks like this:
-    //   # build_tests @zanderso @flutter/tool
-    final String testName = getTestNameFromTargetName(target.name);
-    String? owner;
-    Team? team;
-    final RegExpMatch? match = shardTestOwners.firstMatch(testOwnersContent);
-    if (match != null && match.namedGroup(kOwnerGroupName) != null) {
-      final List<String> lines =
-          match.namedGroup(kOwnerGroupName)!.split('\n').where((String line) => line.contains('@')).toList();
-
-      for (final String line in lines) {
-        final List<String> words = line.trim().split(' ');
-        // e.g. words = ['#', 'build_test', '@zanderso' '@flutter/tool']
-        if (testName.contains(words[1])) {
-          owner = words[2].substring(1); // Strip out the lead '@'
-          team = words.length < 4 ? Team.unknown : teamFromString(words[3].substring(1)); // Strip out the lead '@'
-          break;
-        }
-      }
-    }
-
-    return TestOwnership(owner, team);
-  }
-}
-
-class FrameworkHostOnlyTestOwner implements TestOwner {
-  @override
-  TestOwnership getTestOwnership(
-    pb.Target target,
-    String testOwnersContent,
-  ) {
-    final String testName = getTestNameFromTargetName(target.name);
-    String? owner;
-    Team? team;
-    // The format looks like this:
-    //   # Linux analyze
-    //   /dev/bots/analyze.dart @HansMuller @flutter/framework
-    final RegExpMatch? match = frameworkHostOnlyTestOwners.firstMatch(testOwnersContent);
-    if (match != null && match.namedGroup(kOwnerGroupName) != null) {
-      final List<String> lines =
-          match.namedGroup(kOwnerGroupName)!.split('\n').where((String line) => line.isNotEmpty).toList();
-      int index = 0;
-      while (index < lines.length) {
-        if (lines[index].startsWith('#')) {
-          // Multiple tests can share same test file and ownership.
-          // e.g.
-          //   # Linux docs_test
-          //   # Linux docs_public
-          //   /dev/bots/docs.sh @HansMuller @flutter/framework
-          bool isTestDefined = false;
-          while (lines[index].startsWith('#') && index + 1 < lines.length) {
-            final List<String> commentWords = lines[index].trim().split(' ');
-            if (testName.contains(commentWords[2])) {
-              isTestDefined = true;
-            }
-            index += 1;
-          }
-          if (isTestDefined) {
-            final List<String> ownerWords = lines[index].trim().split(' ');
-            // e.g. ownerWords = ['/xxx/xxx/xxx_test.dart', '@HansMuller' '@flutter/framework']
-            owner = ownerWords[1].substring(1); // Strip out the lead '@'
-            team = ownerWords.length < 3
-                ? Team.unknown
-                : teamFromString(ownerWords[2].substring(1)); // Strip out the lead '@'
-            break;
-          }
-        }
-        index += 1;
-      }
-    }
-
-    return TestOwnership(owner, team);
-  }
-}
-
-class FirebaseLabTestOwner implements TestOwner {
-  @override
-  TestOwnership getTestOwnership(
-    pb.Target target,
-    String testOwnersContent,
-  ) {
-    final String testName = getTestNameFromTargetName(target.name);
-    String? owner;
-    Team? team;
-
-    // The format looks like this for builder `Linux firebase_abstrac_method_smoke_test`:
-    //   /dev/integration_tests/abstrac_method_smoke_test @blasten @flutter/android
-    final RegExpMatch? match = firebaselabTestOwners.firstMatch(testOwnersContent);
-    if (match != null && match.namedGroup(kOwnerGroupName) != null) {
-      final List<String> lines = match
-          .namedGroup(kOwnerGroupName)!
-          .split('\n')
-          .where((String line) => line.isNotEmpty && !line.startsWith('#'))
-          .toList();
-
-      for (final String line in lines) {
-        final List<String> words = line.trim().split(' ');
-        final List<String> dirs = words[0].split('/').toList();
-        if (testName.contains(dirs.last)) {
-          owner = words[1].substring(1); // Strip out the lead '@'
-          team = words.length < 3 ? Team.unknown : teamFromString(words[2].substring(1)); // Strip out the lead '@'
-          break;
-        }
-      }
-    }
-
-    return TestOwnership(owner, team);
-  }
-}
-
-class UnknownTestOwner implements TestOwner {
-  @override
-  TestOwnership getTestOwnership(
-    pb.Target target,
-    String testOwnersContent,
-  ) {
-    return TestOwnership(null, Team.unknown);
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/update_existing_flaky_issues.dart b/app_dart/lib/src/request_handlers/update_existing_flaky_issues.dart
deleted file mode 100644
index d1f2b58..0000000
--- a/app_dart/lib/src/request_handlers/update_existing_flaky_issues.dart
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:cocoon_service/ci_yaml.dart';
-import 'package:github/github.dart';
-import 'package:meta/meta.dart';
-import 'package:yaml/yaml.dart';
-
-import '../../protos.dart' as pb;
-import '../foundation/utils.dart';
-import '../request_handling/api_request_handler.dart';
-import '../request_handling/body.dart';
-import '../service/bigquery.dart';
-import '../service/config.dart';
-import '../service/github_service.dart';
-import 'flaky_handler_utils.dart';
-
-/// This handler updates existing open flaky issues with the latest build
-/// statistics.
-///
-/// The query parameter kThresholdKey is required in order for the handler to
-/// properly adjusts the priority labels.
-@immutable
-class UpdateExistingFlakyIssue extends ApiRequestHandler<Body> {
-  const UpdateExistingFlakyIssue({
-    required super.config,
-    required super.authenticationProvider,
-    @visibleForTesting this.ciYaml,
-  });
-
-  static const String kThresholdKey = 'threshold';
-  static const int kFreshPeriodForOpenFlake = 7; // days
-
-  final CiYaml? ciYaml;
-
-  @override
-  Future<Body> get() async {
-    final RepositorySlug slug = Config.flutterSlug;
-    final GithubService gitHub = config.createGithubServiceWithToken(await config.githubOAuthToken);
-    final BigqueryService bigquery = await config.createBigQueryService();
-
-    CiYaml? localCiYaml = ciYaml;
-    if (localCiYaml == null) {
-      final YamlMap? ci = loadYaml(
-        await gitHub.getFileContent(
-          slug,
-          kCiYamlPath,
-        ),
-      ) as YamlMap?;
-      final pb.SchedulerConfig unCheckedSchedulerConfig = pb.SchedulerConfig()..mergeFromProto3Json(ci);
-      localCiYaml = CiYaml(
-        slug: slug,
-        branch: Config.defaultBranch(slug),
-        config: unCheckedSchedulerConfig,
-      );
-    }
-
-    final List<BuilderStatistic> prodBuilderStatisticList =
-        await bigquery.listBuilderStatistic(kBigQueryProjectId, bucket: 'prod');
-    final List<BuilderStatistic> stagingBuilderStatisticList =
-        await bigquery.listBuilderStatistic(kBigQueryProjectId, bucket: 'staging');
-    final Map<String?, Issue> nameToExistingIssue = await getExistingIssues(gitHub, slug, state: 'open');
-    await _updateExistingFlakyIssue(
-      gitHub,
-      slug,
-      localCiYaml,
-      prodBuilderStatisticList: prodBuilderStatisticList,
-      stagingBuilderStatisticList: stagingBuilderStatisticList,
-      nameToExistingIssue: nameToExistingIssue,
-    );
-    return Body.forJson(const <String, dynamic>{
-      'Status': 'success',
-    });
-  }
-
-  double get _threshold => double.parse(request!.uri.queryParameters[kThresholdKey]!);
-
-  /// Adds an update comment and adjusts the labels of the existing issue based
-  /// on the latest statistics.
-  ///
-  /// This method skips issues that are created within kFreshPeriodForOpenFlake
-  /// days.
-  Future<void> _addCommentToExistingIssue(
-    GithubService gitHub,
-    RepositorySlug slug, {
-    required Bucket bucket,
-    required BuilderStatistic statistic,
-    required Issue existingIssue,
-    required CiYaml ciYaml,
-  }) async {
-    if (DateTime.now().difference(existingIssue.createdAt!) < const Duration(days: kFreshPeriodForOpenFlake)) {
-      return;
-    }
-    final IssueUpdateBuilder updateBuilder =
-        IssueUpdateBuilder(statistic: statistic, threshold: _threshold, existingIssue: existingIssue, bucket: bucket);
-    await gitHub.createComment(slug, issueNumber: existingIssue.number, body: updateBuilder.issueUpdateComment);
-    await gitHub.replaceLabelsForIssue(slug, issueNumber: existingIssue.number, labels: updateBuilder.issueLabels);
-    if (existingIssue.assignee == null && !updateBuilder.isBelow) {
-      final String testOwnerContent = await gitHub.getFileContent(
-        slug,
-        kTestOwnerPath,
-      );
-
-      final pb.SchedulerConfig schedulerConfig = ciYaml.config;
-      final List<pb.Target> targets = schedulerConfig.targets;
-
-      final String? testOwner = getTestOwnership(
-        targets.singleWhere((element) => element.name == statistic.name),
-        getTypeForBuilder(statistic.name, ciYaml),
-        testOwnerContent,
-      ).owner;
-      if (testOwner != null) {
-        await gitHub.assignIssue(slug, issueNumber: existingIssue.number, assignee: testOwner);
-      }
-    }
-  }
-
-  /// Updates existing flaky issues based on corrresponding builder stats.
-  Future<void> _updateExistingFlakyIssue(
-    GithubService gitHub,
-    RepositorySlug slug,
-    CiYaml ciYaml, {
-    required List<BuilderStatistic> prodBuilderStatisticList,
-    required List<BuilderStatistic> stagingBuilderStatisticList,
-    required Map<String?, Issue> nameToExistingIssue,
-  }) async {
-    final Map<String, bool> builderFlakyMap = <String, bool>{};
-    final Map<String, bool> ignoreFlakyMap = <String, bool>{};
-    for (Target target in ciYaml.postsubmitTargets) {
-      builderFlakyMap[target.value.name] = target.value.bringup;
-      if (target.getIgnoreFlakiness()) {
-        ignoreFlakyMap[target.value.name] = true;
-      }
-    }
-    // Update an existing flaky bug with only prod stats if the builder is with `bringup: false`, such as a shard builder.
-    //
-    // Update an existing flaky bug with both prod and staging stats if the builder is with `bringup: true`. When a builder
-    // is newly identified as flaky, there is a gap between the builder is marked as `bringup: true` and the flaky bug is filed.
-    // For this case, there will be builds still running in `prod` pool, and we need to append `prod` stats as well.
-    for (final BuilderStatistic statistic in prodBuilderStatisticList) {
-      // ignore: iterable_contains_unrelated_type
-      if (nameToExistingIssue.containsKey(statistic.name) &&
-          builderFlakyMap.containsKey(statistic.name) &&
-          // ignore: iterable_contains_unrelated_type
-          !ignoreFlakyMap.containsKey(statistic.name)) {
-        await _addCommentToExistingIssue(
-          gitHub,
-          slug,
-          bucket: Bucket.prod,
-          statistic: statistic,
-          existingIssue: nameToExistingIssue[statistic.name]!,
-          ciYaml: ciYaml,
-        );
-      }
-    }
-    // For all staging builder stats, updates any existing flaky bug.
-    for (final BuilderStatistic statistic in stagingBuilderStatisticList) {
-      if (nameToExistingIssue.containsKey(statistic.name) &&
-          builderFlakyMap[statistic.name] == true &&
-          // ignore: iterable_contains_unrelated_type
-          !ignoreFlakyMap.containsKey(statistic.name)) {
-        await _addCommentToExistingIssue(
-          gitHub,
-          slug,
-          bucket: Bucket.staging,
-          statistic: statistic,
-          existingIssue: nameToExistingIssue[statistic.name]!,
-          ciYaml: ciYaml,
-        );
-      }
-    }
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/update_task_status.dart b/app_dart/lib/src/request_handlers/update_task_status.dart
deleted file mode 100644
index e4e6ed4..0000000
--- a/app_dart/lib/src/request_handlers/update_task_status.dart
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:gcloud/db.dart';
-import 'package:meta/meta.dart';
-
-import '../model/appengine/commit.dart';
-import '../model/appengine/task.dart';
-import '../request_handling/api_request_handler.dart';
-import '../request_handling/body.dart';
-import '../request_handling/exceptions.dart';
-import '../service/datastore.dart';
-import '../service/logging.dart';
-
-/// Endpoint for task runners to update Cocoon with test run information.
-///
-/// This handler requires (1) task identifier and (2) task status information.
-///
-/// 1. Tasks are identified by:
-///  [gitBranchParam], [gitShaParam], [builderNameParam]
-///
-/// 2. Task status information
-///  A. Required: [newStatusParam], either [Task.statusSucceeded] or [Task.statusFailed].
-///  B. Optional: [resultsParam] and [scoreKeysParam] which hold performance benchmark data.
-@immutable
-class UpdateTaskStatus extends ApiRequestHandler<UpdateTaskStatusResponse> {
-  const UpdateTaskStatus({
-    required super.config,
-    required super.authenticationProvider,
-    @visibleForTesting this.datastoreProvider = DatastoreService.defaultProvider,
-  });
-
-  final DatastoreServiceProvider datastoreProvider;
-
-  static const String gitBranchParam = 'CommitBranch';
-  static const String gitShaParam = 'CommitSha';
-  static const String newStatusParam = 'NewStatus';
-  static const String builderNameParam = 'BuilderName';
-  static const String testFlayParam = 'TestFlaky';
-
-  @override
-  Future<UpdateTaskStatusResponse> post() async {
-    checkRequiredParameters(<String>[newStatusParam, gitBranchParam, gitShaParam, builderNameParam]);
-
-    final DatastoreService datastore = datastoreProvider(config.db);
-    final String newStatus = requestData![newStatusParam] as String;
-    final bool isTestFlaky = (requestData![testFlayParam] as bool?) ?? false;
-
-    if (newStatus != Task.statusSucceeded && newStatus != Task.statusFailed) {
-      throw const BadRequestException('NewStatus can be one of "Succeeded", "Failed"');
-    }
-
-    final Task task = await _getTaskFromNamedParams(datastore);
-
-    task.status = newStatus;
-    task.endTimestamp = DateTime.now().millisecondsSinceEpoch;
-    task.isTestFlaky = isTestFlaky;
-
-    await datastore.insert(<Task>[task]);
-    return UpdateTaskStatusResponse(task);
-  }
-
-  /// Retrieve [Task] from [DatastoreService] when given [gitShaParam], [gitBranchParam], and [builderNameParam].
-  ///
-  /// This is used when the DeviceLab test runner is uploading results to Cocoon for runs on LUCI.
-  /// LUCI does not know the [Key] assigned to task when scheduling the build, but Cocoon can
-  /// lookup the task based on these key values.
-  ///
-  /// To lookup the value, we construct the ancestor key, which corresponds to the [Commit].
-  /// Then we query the tasks with that ancestor key and search for the one that matches the builder name.
-  Future<Task> _getTaskFromNamedParams(DatastoreService datastore) async {
-    final Key<String> commitKey = await _constructCommitKey(datastore);
-
-    final String? builderName = requestData![builderNameParam] as String?;
-    final Query<Task> query = datastore.db.query<Task>(ancestorKey: commitKey);
-    final List<Task> initialTasks = await query.run().toList();
-    log.fine('Found ${initialTasks.length} tasks for commit');
-    final List<Task> tasks = <Task>[];
-    log.fine('Searching for task with builderName=$builderName');
-    for (Task task in initialTasks) {
-      if (task.builderName == builderName || task.name == builderName) {
-        tasks.add(task);
-      }
-    }
-
-    if (tasks.length != 1) {
-      log.severe('Found ${tasks.length} entries for builder $builderName');
-      throw InternalServerError('Expected to find 1 task for $builderName, but found ${tasks.length}');
-    }
-
-    return tasks.first;
-  }
-
-  /// Construct the Datastore key for [Commit] that is the ancestor to this [Task].
-  ///
-  /// Throws [BadRequestException] if the given git branch does not exist in [CocoonConfig].
-  Future<Key<String>> _constructCommitKey(DatastoreService datastore) async {
-    final String gitBranch = (requestData![gitBranchParam] as String).trim();
-    final String gitSha = (requestData![gitShaParam] as String).trim();
-
-    final String id = 'flutter/flutter/$gitBranch/$gitSha';
-    final Key<String> commitKey = datastore.db.emptyKey.append<String>(Commit, id: id);
-    log.fine('Constructed commit key=$id');
-    // Return the official key from Datastore for task lookups.
-    final Commit commit = await config.db.lookupValue<Commit>(commitKey);
-    return commit.key;
-  }
-}
-
-@immutable
-class UpdateTaskStatusResponse extends JsonBody {
-  const UpdateTaskStatusResponse(this.task);
-
-  final Task task;
-
-  @override
-  Map<String, dynamic> toJson() {
-    return <String, dynamic>{
-      'Name': task.name,
-      'Status': task.status,
-    };
-  }
-}
diff --git a/app_dart/lib/src/request_handlers/vacuum_github_commits.dart b/app_dart/lib/src/request_handlers/vacuum_github_commits.dart
deleted file mode 100644
index 2f70d0c..0000000
--- a/app_dart/lib/src/request_handlers/vacuum_github_commits.dart
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:gcloud/db.dart';
-import 'package:github/github.dart' as gh;
-import 'package:meta/meta.dart';
-import 'package:truncate/truncate.dart';
-
-import '../model/appengine/commit.dart';
-import '../request_handling/api_request_handler.dart';
-import '../request_handling/body.dart';
-import '../service/config.dart';
-import '../service/datastore.dart';
-import '../service/github_service.dart';
-import '../service/logging.dart';
-import '../service/scheduler.dart';
-
-/// Query GitHub for commits from the past day and ensure they exist in datastore.
-@immutable
-class VacuumGithubCommits extends ApiRequestHandler<Body> {
-  const VacuumGithubCommits({
-    required super.config,
-    required super.authenticationProvider,
-    required this.scheduler,
-    @visibleForTesting this.datastoreProvider = DatastoreService.defaultProvider,
-  });
-
-  final DatastoreServiceProvider datastoreProvider;
-
-  final Scheduler scheduler;
-
-  static const String branchParam = 'branch';
-
-  @override
-  Future<Body> get() async {
-    final DatastoreService datastore = datastoreProvider(config.db);
-
-    for (gh.RepositorySlug slug in config.supportedRepos) {
-      final String branch = request!.uri.queryParameters[branchParam] ?? Config.defaultBranch(slug);
-      await _vacuumRepository(slug, datastore: datastore, branch: branch);
-    }
-
-    return Body.empty;
-  }
-
-  Future<void> _vacuumRepository(
-    gh.RepositorySlug slug, {
-    DatastoreService? datastore,
-    required String branch,
-  }) async {
-    final GithubService githubService = await config.createGithubService(slug);
-    final List<Commit> commits = await _vacuumBranch(
-      slug,
-      branch,
-      datastore: datastore,
-      githubService: githubService,
-    );
-    await scheduler.addCommits(commits);
-  }
-
-  Future<List<Commit>> _vacuumBranch(
-    gh.RepositorySlug slug,
-    String branch, {
-    DatastoreService? datastore,
-    required GithubService githubService,
-  }) async {
-    List<gh.RepositoryCommit> commits = <gh.RepositoryCommit>[];
-    // Sliding window of times to add commits from.
-    final DateTime queryAfter = DateTime.now().subtract(const Duration(days: 1));
-    final DateTime queryBefore = DateTime.now().subtract(const Duration(minutes: 3));
-    try {
-      log.fine('Listing commit for slug: $slug branch: $branch and msSinceEpoch: ${queryAfter.millisecondsSinceEpoch}');
-      commits = await githubService.listBranchedCommits(slug, branch, queryAfter.millisecondsSinceEpoch);
-      log.fine('Retrieved ${commits.length} commits from GitHub');
-      // Do not try to add recent commits as they may already be processed
-      // by cocoon, which can cause race conditions.
-      commits = commits
-          .where(
-            (gh.RepositoryCommit commit) =>
-                commit.commit!.committer!.date!.millisecondsSinceEpoch < queryBefore.millisecondsSinceEpoch,
-          )
-          .toList();
-    } on gh.GitHubError catch (error) {
-      log.severe('$error');
-    }
-
-    return _toDatastoreCommit(slug, commits, datastore, branch);
-  }
-
-  /// Convert [gh.RepositoryCommit] to Cocoon's [Commit] format.
-  Future<List<Commit>> _toDatastoreCommit(
-    gh.RepositorySlug slug,
-    List<gh.RepositoryCommit> commits,
-    DatastoreService? datastore,
-    String branch,
-  ) async {
-    final List<Commit> recentCommits = <Commit>[];
-    for (gh.RepositoryCommit commit in commits) {
-      final String id = '${slug.fullName}/$branch/${commit.sha}';
-      final Key<String> key = datastore!.db.emptyKey.append<String>(Commit, id: id);
-      recentCommits.add(
-        Commit(
-          key: key,
-          timestamp: commit.commit!.committer!.date!.millisecondsSinceEpoch,
-          repository: slug.fullName,
-          sha: commit.sha!,
-          author: commit.author!.login!,
-          authorAvatarUrl: commit.author!.avatarUrl!,
-          // The field has a size of 1500 we need to ensure the commit message
-          // is at most 1500 chars long.
-          message: truncate(commit.commit!.message!, 1490, omission: '...'),
-          branch: branch,
-        ),
-      );
-    }
-    return recentCommits;
-  }
-}
diff --git a/app_dart/lib/src/request_handlin