Repository: knative/serving
Pull request #10128 (2020-11-17 16:53:19)

Tidy up probe tests
Since I had these open anyway.

- drop unneeded t.Log
- remove switch for scheme that was never used (the scheme is always http since we use httptest.NewServer)
- move `httptest.NewServer` calls into helper and use `t.Cleanup` to tidy up defers since it's the same in every test
- move url/port parsing in to helper in readiness/probe_test since it's used in every test

/assign @vagababov @markusthoemmes 

knative-prow-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative/serving/pull/10128#" title="Author self-approved">julz</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative%2Fserving).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[pkg/queue/OWNERS](https://github.com/knative/serving/blob/master/pkg/queue/OWNERS)~~ [julz]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
codecov[bot]: # [Codecov](https://codecov.io/gh/knative/serving/pull/10128?src=pr&el=h1) Report
> Merging [#10128](https://codecov.io/gh/knative/serving/pull/10128?src=pr&el=desc) (a550d2b) into [master](https://codecov.io/gh/knative/serving/commit/32eabd48fc03d1f16ae2508d7b50cc9e9ebb8280?el=desc) (32eabd4) will **increase** coverage by `0.02%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/knative/serving/pull/10128/graphs/tree.svg?width=650&height=150&src=pr&token=MPpDfAj4Ui)](https://codecov.io/gh/knative/serving/pull/10128?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #10128      +/-   ##
==========================================
+ Coverage   87.98%   88.00%   +0.02%     
==========================================
  Files         185      185              
  Lines        8729     8729              
==========================================
+ Hits         7680     7682       +2     
+ Misses        799      797       -2     
  Partials      250      250              
```


| [Impacted Files](https://codecov.io/gh/knative/serving/pull/10128?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/activator/net/revision\_backends.go](https://codecov.io/gh/knative/serving/pull/10128/diff?src=pr&el=tree#diff-cGtnL2FjdGl2YXRvci9uZXQvcmV2aXNpb25fYmFja2VuZHMuZ28=) | `91.40% <0.00%> (+0.90%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/knative/serving/pull/10128?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/knative/serving/pull/10128?src=pr&el=footer). Last update [32eabd4...a550d2b](https://codecov.io/gh/knative/serving/pull/10128?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/config/core/configmaps/gc.yaml b/config/core/configmaps/gc.yaml
index eae65af91..cf1cd004d 100644
--- a/config/core/configmaps/gc.yaml
+++ b/config/core/configmaps/gc.yaml
@@ -20,7 +20,7 @@ metadata:
   labels:
     serving.knative.dev/release: devel
   annotations:
-    knative.dev/example-checksum: "4b89cfa0"
+    knative.dev/example-checksum: "e6149382"
 data:
   _example: |
     ################################
@@ -38,31 +38,11 @@ data:
     # this example block and unindented to be in the data block
     # to actually change the configuration.
 
-    # Delay after revision creation before considering it for GC
-    stale-revision-create-delay: "48h"
-
-    # Duration since a route has pointed at the revision before it
-    # should be GC'd.
-    # This minus lastpinned-debounce must be longer than the controller
-    # resync period (10 hours).
-    stale-revision-timeout: "15h"
-
-    # Minimum number of generations of non-active revisions to keep before
-    # considering them for GC.
-    stale-revision-minimum-generations: "20"
-
-    # To avoid constant updates, we allow an existing annotation to be stale by this
-    # amount before we update the timestamp.
-    stale-revision-lastpinned-debounce: "5h"
-
 
     # ---------------------------------------
-    # V2 Garbage Collector Settings
+    # Garbage Collector Settings
     # ---------------------------------------
     #
-    # These settings are enabled via the "responsive-revision-gc" feature flag.
-    # ALPHA NOTE: This feature is still experimental and under active development.
-    #
     # Active
     #   * Revisions which are referenced by a Route are considered active.
     #   * Individual revisions may be marked with the annotation
diff --git a/pkg/apis/config/features.go b/pkg/apis/config/features.go
index ce43c1fb5..a3b762c34 100644
--- a/pkg/apis/config/features.go
+++ b/pkg/apis/config/features.go
@@ -49,7 +49,6 @@ func defaultFeaturesConfig() *Features {
 		PodSpecRuntimeClassName: Disabled,
 		PodSpecSecurityContext:  Disabled,
 		PodSpecTolerations:      Disabled,
-		ResponsiveRevisionGC:    Enabled,
 		TagHeaderBasedRouting:   Disabled,
 	}
 }
@@ -67,7 +66,6 @@ func NewFeaturesConfigFromMap(data map[string]string) (*Features, error) {
 		asFlag("kubernetes.podspec-runtimeclassname", &nc.PodSpecRuntimeClassName),
 		asFlag("kubernetes.podspec-securitycontext", &nc.PodSpecSecurityContext),
 		asFlag("kubernetes.podspec-tolerations", &nc.PodSpecTolerations),
-		asFlag("responsive-revision-gc", &nc.ResponsiveRevisionGC),
 		asFlag("tag-header-based-routing", &nc.TagHeaderBasedRouting)); err != nil {
 		return nil, err
 	}
@@ -89,7 +87,6 @@ type Features struct {
 	PodSpecRuntimeClassName Flag
 	PodSpecSecurityContext  Flag
 	PodSpecTolerations      Flag
-	ResponsiveRevisionGC    Flag
 	TagHeaderBasedRouting   Flag
 }
 
diff --git a/pkg/apis/serving/v1/revision_helpers.go b/pkg/apis/serving/v1/revision_helpers.go
index 303376026..275b59079 100644
--- a/pkg/apis/serving/v1/revision_helpers.go
+++ b/pkg/apis/serving/v1/revision_helpers.go
@@ -17,8 +17,6 @@ limitations under the License.
 package v1
 
 import (
-	"fmt"
-	"strconv"
 	"time"
 
 	corev1 "k8s.io/api/core/v1"
@@ -91,16 +89,8 @@ type (
 	}
 
 	// +k8s:deepcopy-gen=false
-
-	// LastPinnedParseError is the error returned when the lastPinned annotation
-	// could not be parsed.
-	LastPinnedParseError AnnotationParseError
 )
 
-func (e LastPinnedParseError) Error() string {
-	return fmt.Sprintf("%v lastPinned value: %q", e.Type, e.Value)
-}
-
 // GetContainer returns a pointer to the relevant corev1.Container field.
 // It is never nil and should be exactly the specified container if len(containers) == 1 or
 // if there are multiple containers it returns the container which has Ports
@@ -163,8 +153,7 @@ func (r *Revision) GetRoutingStateModified() time.Time {
 
 // IsReachable returns whether or not the revision can be reached by a route.
 func (r *Revision) IsReachable() bool {
-	return r.Labels[serving.RouteLabelKey] != "" ||
-		RoutingState(r.Labels[serving.RoutingStateLabelKey]) == RoutingStateActive
+	return RoutingState(r.Labels[serving.RoutingStateLabelKey]) == RoutingStateActive
 }
 
 // GetProtocol returns the app level network protocol.
@@ -183,44 +172,6 @@ func (r *Revision) GetProtocol() (p net.ProtocolType) {
 	return
 }
 
-// SetLastPinned sets the revision's last pinned annotations
-// to be the specified time.
-func (r *Revision) SetLastPinned(t time.Time) {
-	if r.Annotations == nil {
-		r.Annotations = make(map[string]string, 1)
-	}
-
-	r.Annotations[serving.RevisionLastPinnedAnnotationKey] = RevisionLastPinnedString(t)
-}
-
-// GetLastPinned returns the time the revision was last pinned.
-func (r *Revision) GetLastPinned() (time.Time, error) {
-	if r.Annotations == nil {
-		return time.Time{}, LastPinnedParseError{
-			Type: AnnotationParseErrorTypeMissing,
-		}
-	}
-
-	str, ok := r.Annotations[serving.RevisionLastPinnedAnnotationKey]
-	if !ok {
-		// If a revision is past the create delay without an annotation it is stale.
-		return time.Time{}, LastPinnedParseError{
-			Type: AnnotationParseErrorTypeMissing,
-		}
-	}
-
-	secs, err := strconv.ParseInt(str, 10, 64)
-	if err != nil {
-		return time.Time{}, LastPinnedParseError{
-			Type:  AnnotationParseErrorTypeInvalid,
-			Value: str,
-			Err:   err,
-		}
-	}
-
-	return time.Unix(secs, 0), nil
-}
-
 // IsActivationRequired returns true if activation is required.
 func (rs *RevisionStatus) IsActivationRequired() bool {
 	if c := revisionCondSet.Manage(rs).GetCondition(RevisionConditionActive); c != nil {
@@ -228,8 +179,3 @@ func (rs *RevisionStatus) IsActivationRequired() bool {
 	}
 	return false
 }
-
-// RevisionLastPinnedString returns a string representation of the specified time.
-func RevisionLastPinnedString(t time.Time) string {
-	return fmt.Sprint(t.Unix())
-}
diff --git a/pkg/gc/config.go b/pkg/gc/config.go
index 97fe2b9ae..4218e6fc6 100644
--- a/pkg/gc/config.go
+++ b/pkg/gc/config.go
@@ -25,8 +25,6 @@ import (
 
 	corev1 "k8s.io/api/core/v1"
 	cm "knative.dev/pkg/configmap"
-	"knative.dev/pkg/controller"
-	"knative.dev/pkg/logging"
 )
 
 const (
@@ -42,16 +40,6 @@ const (
 
 // Config defines the tunable parameters for Garbage Collection.
 type Config struct {
-	// Delay duration after a revision create before considering it for GC
-	StaleRevisionCreateDelay time.Duration
-	// Timeout since a revision lastPinned before it should be GC'd
-	// This must be longer than the controller resync period
-	StaleRevisionTimeout time.Duration
-	// Minimum number of generations of revisions to keep before considering for GC.
-	StaleRevisionMinimumGenerations int64
-	// Minimum staleness duration before updating lastPinned
-	StaleRevisionLastpinnedDebounce time.Duration
-
 	// Duration from creation when a Revision should be considered active
 	// and exempt from GC. Note that GCMaxStaleRevision may override this if set.
 	// Set Disabled (-1) to disable/ignore duration and always consider active.
@@ -70,13 +58,6 @@ type Config struct {
 
 func defaultConfig() *Config {
 	return &Config{
-		// V1 GC Settings
-		StaleRevisionCreateDelay:        48 * time.Hour,
-		StaleRevisionTimeout:            15 * time.Hour,
-		StaleRevisionLastpinnedDebounce: 5 * time.Hour,
-		StaleRevisionMinimumGenerations: 20,
-
-		// V2 GC Settings
 		RetainSinceCreateTime:     48 * time.Hour,
 		RetainSinceLastActiveTime: 15 * time.Hour,
 		MinNonActiveRevisions:     20,
@@ -86,19 +67,11 @@ func defaultConfig() *Config {
 
 // NewConfigFromConfigMapFunc creates a Config from the supplied ConfigMap func.
 func NewConfigFromConfigMapFunc(ctx context.Context) func(configMap *corev1.ConfigMap) (*Config, error) {
-	logger := logging.FromContext(ctx)
-	minRevisionTimeout := controller.GetResyncPeriod(ctx)
 	return func(configMap *corev1.ConfigMap) (*Config, error) {
 		c := defaultConfig()
 
 		var retainCreate, retainActive, max string
 		if err := cm.Parse(configMap.Data,
-			cm.AsDuration("stale-revision-create-delay", &c.StaleRevisionCreateDelay),
-			cm.AsDuration("stale-revision-timeout", &c.StaleRevisionTimeout),
-			cm.AsDuration("stale-revision-lastpinned-debounce", &c.StaleRevisionLastpinnedDebounce),
-			cm.AsInt64("stale-revision-minimum-generations", &c.StaleRevisionMinimumGenerations),
-
-			// v2 settings
 			cm.AsString("retain-since-create-time", &retainCreate),
 			cm.AsString("retain-since-last-active-time", &retainActive),
 			cm.AsInt64("min-non-active-revisions", &c.MinNonActiveRevisions),
@@ -107,17 +80,6 @@ func NewConfigFromConfigMapFunc(ctx context.Context) func(configMap *corev1.Conf
 			return nil, fmt.Errorf("failed to parse data: %w", err)
 		}
 
-		if c.StaleRevisionMinimumGenerations < 0 {
-			return nil, fmt.Errorf(
-				"stale-revision-minimum-generations must be non-negative, was: %d",
-				c.StaleRevisionMinimumGenerations)
-		}
-		if c.StaleRevisionTimeout-c.StaleRevisionLastpinnedDebounce < minRevisionTimeout {
-			logger.Warnf("Got revision timeout of %v, minimum supported value is %v",
-				c.StaleRevisionTimeout, minRevisionTimeout+c.StaleRevisionLastpinnedDebounce)
-			c.StaleRevisionTimeout = minRevisionTimeout + c.StaleRevisionLastpinnedDebounce
-		}
-
 		// validate V2 settings
 		if err := parseDisabledOrDuration(retainCreate, &c.RetainSinceCreateTime); err != nil {
 			return nil, fmt.Errorf("failed to parse retain-since-create-time: %w", err)
@@ -126,13 +88,13 @@ func NewConfigFromConfigMapFunc(ctx context.Context) func(configMap *corev1.Conf
 			return nil, fmt.Errorf("failed to parse retain-since-last-active-time: %w", err)
 		}
 		if err := parseDisabledOrInt64(max, &c.MaxNonActiveRevisions); err != nil {
-			return nil, fmt.Errorf("failed to parse max-stale-revisions: %w", err)
+			return nil, fmt.Errorf("failed to parse max-non-active-revisions: %w", err)
 		}
 		if c.MinNonActiveRevisions < 0 {
 			return nil, fmt.Errorf("min-non-active-revisions must be non-negative, was: %d", c.MinNonActiveRevisions)
 		}
 		if c.MaxNonActiveRevisions >= 0 && c.MinNonActiveRevisions > c.MaxNonActiveRevisions {
-			return nil, fmt.Errorf("min-non-active-revisions(%d) must be <= max-stale-revisions(%d)", c.MinNonActiveRevisions, c.MaxNonActiveRevisions)
+			return nil, fmt.Errorf("min-non-active-revisions(%d) must be <= max-non-active-revisions(%d)", c.MinNonActiveRevisions, c.MaxNonActiveRevisions)
 		}
 		return c, nil
 	}
diff --git a/pkg/reconciler/configuration/resources/revision.go b/pkg/reconciler/configuration/resources/revision.go
index a8919958e..9fb516dcd 100644
--- a/pkg/reconciler/configuration/resources/revision.go
+++ b/pkg/reconciler/configuration/resources/revision.go
@@ -23,10 +23,8 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/clock"
 	"knative.dev/pkg/kmeta"
-	cfgmap "knative.dev/serving/pkg/apis/config"
 	"knative.dev/serving/pkg/apis/serving"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
-	"knative.dev/serving/pkg/reconciler/configuration/config"
 )
 
 // MakeRevision creates a revision object from configuration.
@@ -44,9 +42,7 @@ func MakeRevision(ctx context.Context, configuration *v1.Configuration, clock cl
 	}
 
 	// Pending tells the labeler that we have not processed this revision.
-	if config.FromContextOrDefaults(ctx).Features.ResponsiveRevisionGC != cfgmap.Disabled {
-		rev.SetRoutingState(v1.RoutingStatePending, clock)
-	}
+	rev.SetRoutingState(v1.RoutingStatePending, clock)
 
 	updateRevisionLabels(rev, configuration)
 	updateRevisionAnnotations(rev, configuration)
diff --git a/pkg/reconciler/gc/config/store.go b/pkg/reconciler/gc/config/store.go
index cac21568f..83d6604c5 100644
--- a/pkg/reconciler/gc/config/store.go
+++ b/pkg/reconciler/gc/config/store.go
@@ -30,7 +30,6 @@ type cfgKey struct{}
 // Config is the configuration for GC.
 type Config struct {
 	RevisionGC *gc.Config
-	Features   *apiconfig.Features
 }
 
 // FromContext fetches the config from the context.
@@ -57,7 +56,6 @@ func (s *Store) ToContext(ctx context.Context) context.Context {
 func (s *Store) Load() *Config {
 	return &Config{
 		RevisionGC: s.UntypedLoad(gc.ConfigName).(*gc.Config).DeepCopy(),
-		Features:   s.UntypedLoad(apiconfig.FeaturesConfigName).(*apiconfig.Features).DeepCopy(),
 	}
 }
 
diff --git a/pkg/reconciler/gc/reconciler.go b/pkg/reconciler/gc/reconciler.go
index 5f5abc3ec..478c6a3c0 100644
--- a/pkg/reconciler/gc/reconciler.go
+++ b/pkg/reconciler/gc/reconciler.go
@@ -20,13 +20,10 @@ import (
 	"context"
 
 	pkgreconciler "knative.dev/pkg/reconciler"
-	cfgmap "knative.dev/serving/pkg/apis/config"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
 	clientset "knative.dev/serving/pkg/client/clientset/versioned"
 	configreconciler "knative.dev/serving/pkg/client/injection/reconciler/serving/v1/configuration"
 	listers "knative.dev/serving/pkg/client/listers/serving/v1"
-	configns "knative.dev/serving/pkg/reconciler/gc/config"
-	gcv1 "knative.dev/serving/pkg/reconciler/gc/v1"
 	gcv2 "knative.dev/serving/pkg/reconciler/gc/v2"
 )
 
@@ -43,12 +40,5 @@ var _ configreconciler.Interface = (*reconciler)(nil)
 
 // ReconcileKind implements Interface.ReconcileKind.
 func (c *reconciler) ReconcileKind(ctx context.Context, config *v1.Configuration) pkgreconciler.Event {
-	switch configns.FromContext(ctx).Features.ResponsiveRevisionGC {
-
-	case cfgmap.Disabled: // v1 logic
-		return gcv1.Collect(ctx, c.client, c.revisionLister, config)
-
-	default: // v2 logic
-		return gcv2.Collect(ctx, c.client, c.revisionLister, config)
-	}
+	return gcv2.Collect(ctx, c.client, c.revisionLister, config)
 }
diff --git a/pkg/reconciler/gc/v1/gc.go b/pkg/reconciler/gc/v1/gc.go
deleted file mode 100644
index 875a9c8f8..000000000
--- a/pkg/reconciler/gc/v1/gc.go
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-Copyright 2020 The Knative Authors
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1
-
-import (
-	"context"
-	"errors"
-	"sort"
-	"time"
-
-	"go.uber.org/zap"
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/labels"
-	"knative.dev/pkg/logging"
-	pkgreconciler "knative.dev/pkg/reconciler"
-	"knative.dev/serving/pkg/apis/serving"
-	v1 "knative.dev/serving/pkg/apis/serving/v1"
-	clientset "knative.dev/serving/pkg/client/clientset/versioned"
-	listers "knative.dev/serving/pkg/client/listers/serving/v1"
-	configns "knative.dev/serving/pkg/reconciler/gc/config"
-)
-
-// Collect deletes stale revisions if they are sufficiently old
-func Collect(
-	ctx context.Context,
-	client clientset.Interface,
-	revisionLister listers.RevisionLister,
-	config *v1.Configuration) pkgreconciler.Event {
-	cfg := configns.FromContext(ctx).RevisionGC
-	logger := logging.FromContext(ctx)
-
-	selector := labels.SelectorFromSet(labels.Set{serving.ConfigurationLabelKey: config.Name})
-	revs, err := revisionLister.Revisions(config.Namespace).List(selector)
-	if err != nil {
-		return err
-	}
-
-	gcSkipOffset := cfg.StaleRevisionMinimumGenerations
-
-	if gcSkipOffset >= int64(len(revs)) {
-		return nil
-	}
-
-	// Sort by creation timestamp descending
-	sort.Slice(revs, func(i, j int) bool {
-		return revs[j].CreationTimestamp.Before(&revs[i].CreationTimestamp)
-	})
-
-	for _, rev := range revs[gcSkipOffset:] {
-		if isRevisionStale(ctx, rev, config) {
-			err := client.ServingV1().Revisions(rev.Namespace).Delete(ctx, rev.Name, metav1.DeleteOptions{})
-			if err != nil {
-				logger.With(zap.Error(err)).Errorf("Failed to delete stale revision %q", rev.Name)
-				continue
-			}
-		}
-	}
-	return nil
-}
-
-func isRevisionStale(ctx context.Context, rev *v1.Revision, config *v1.Configuration) bool {
-	if config.Status.LatestReadyRevisionName == rev.Name {
-		return false
-	}
-
-	cfg := configns.FromContext(ctx).RevisionGC
-	logger := logging.FromContext(ctx)
-
-	curTime := time.Now()
-	if rev.ObjectMeta.CreationTimestamp.Add(cfg.StaleRevisionCreateDelay).After(curTime) {
-		// Revision was created sooner than staleRevisionCreateDelay. Ignore it.
-		return false
-	}
-
-	lastPin, err := rev.GetLastPinned()
-	if err != nil {
-		var errLastPinned v1.LastPinnedParseError
-		if errors.As(err, &errLastPinned) && errLastPinned.Type != v1.AnnotationParseErrorTypeMissing {
-			logger.Errorw("Failed to determine revision last pinned", zap.Error(err))
-		} else {
-			// Revision was never pinned and its RevisionConditionReady is not true after staleRevisionCreateDelay.
-			// It usually happens when ksvc was deployed with wrong configuration.
-			rc := rev.Status.GetCondition(v1.RevisionConditionReady)
-			if rc == nil || rc.Status != corev1.ConditionTrue {
-				return true
-			}
-		}
-		return false
-	}
-
-	ret := lastPin.Add(cfg.StaleRevisionTimeout).Before(curTime)
-	if ret {
-		logger.Infof("Detected stale revision %v with creation time %v and lastPinned time %v.", rev.ObjectMeta.Name, rev.ObjectMeta.CreationTimestamp, lastPin)
-	}
-	return ret
-}
diff --git a/pkg/reconciler/gc/v2/gc.go b/pkg/reconciler/gc/v2/gc.go
index b27416bb0..bece2e05c 100644
--- a/pkg/reconciler/gc/v2/gc.go
+++ b/pkg/reconciler/gc/v2/gc.go
@@ -159,14 +159,11 @@ func isRevisionStale(cfg *gc.Config, rev *v1.Revision, logger *zap.SugaredLogger
 }
 
 // revisionLastActiveTime returns if present:
-// routingStateModified, then lastPinnedTime, then the created time.
+// routingStateModified, then the created time.
 // This is used for sort-ordering by most recently active.
 func revisionLastActiveTime(rev *v1.Revision) time.Time {
 	if t := rev.GetRoutingStateModified(); !t.IsZero() {
 		return t
 	}
-	if t, err := rev.GetLastPinned(); err == nil {
-		return t
-	}
 	return rev.ObjectMeta.GetCreationTimestamp().Time
 }
diff --git a/pkg/reconciler/labeler/controller.go b/pkg/reconciler/labeler/controller.go
index 85bd9aecb..d30dd0193 100644
--- a/pkg/reconciler/labeler/controller.go
+++ b/pkg/reconciler/labeler/controller.go
@@ -30,7 +30,6 @@ import (
 	routereconciler "knative.dev/serving/pkg/client/injection/reconciler/serving/v1/route"
 	servingreconciler "knative.dev/serving/pkg/reconciler"
 	"knative.dev/serving/pkg/reconciler/configuration/config"
-	labelerv1 "knative.dev/serving/pkg/reconciler/labeler/v1"
 	labelerv2 "knative.dev/serving/pkg/reconciler/labeler/v2"
 
 	"knative.dev/pkg/configmap"
@@ -99,11 +98,7 @@ func newControllerWithClock(
 	))
 
 	client := servingclient.Get(ctx)
-
-	c.caccV1 = labelerv1.NewConfigurationAccessor(client, tracker, configInformer.Lister())
 	c.caccV2 = labelerv2.NewConfigurationAccessor(client, tracker, configInformer.Lister(), configInformer.Informer().GetIndexer(), clock)
-
-	c.raccV1 = labelerv1.NewRevisionAccessor(client, tracker, revisionInformer.Lister())
 	c.raccV2 = labelerv2.NewRevisionAccessor(client, tracker, revisionInformer.Lister(), revisionInformer.Informer().GetIndexer(), clock)
 
 	return impl
diff --git a/pkg/reconciler/labeler/labeler.go b/pkg/reconciler/labeler/labeler.go
index 3b23ff2b0..f6299eca5 100644
--- a/pkg/reconciler/labeler/labeler.go
+++ b/pkg/reconciler/labeler/labeler.go
@@ -20,19 +20,13 @@ import (
 	"context"
 
 	pkgreconciler "knative.dev/pkg/reconciler"
-	cfgmap "knative.dev/serving/pkg/apis/config"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
 	routereconciler "knative.dev/serving/pkg/client/injection/reconciler/serving/v1/route"
-	"knative.dev/serving/pkg/reconciler/configuration/config"
-	labelerv1 "knative.dev/serving/pkg/reconciler/labeler/v1"
 	labelerv2 "knative.dev/serving/pkg/reconciler/labeler/v2"
 )
 
 // Reconciler implements controller.Reconciler for Route resources.
 type Reconciler struct {
-	caccV1 *labelerv1.Configuration
-	raccV1 *labelerv1.Revision
-
 	caccV2 *labelerv2.Configuration
 	raccV2 *labelerv2.Revision
 }
@@ -44,52 +38,17 @@ var _ routereconciler.Finalizer = (*Reconciler)(nil)
 // FinalizeKind removes all Route reference metadata from its traffic targets.
 // This does not modify or observe spec for the Route itself.
 func (rec *Reconciler) FinalizeKind(ctx context.Context, r *v1.Route) pkgreconciler.Event {
-	newGC := config.FromContextOrDefaults(ctx).Features.ResponsiveRevisionGC
-
-	// v1 logic
-	if newGC == cfgmap.Disabled || newGC == cfgmap.Allowed {
-		if err := labelerv1.ClearLabels(ctx, r.Namespace, r.Name, rec.caccV1, rec.raccV1); err != nil {
-			return err
-		}
+	if err := labelerv2.ClearRoutingMeta(ctx, r, rec.caccV2, rec.raccV2); err != nil {
+		return err
 	}
-
-	// v2 logic
-	if newGC == cfgmap.Allowed || newGC == cfgmap.Enabled {
-		if err := labelerv2.ClearRoutingMeta(ctx, r, rec.caccV2, rec.raccV2); err != nil {
-			return err
-		}
-	}
-
 	return nil
 }
 
 // ReconcileKind syncs the Route reference metadata to its traffic targets.
 // This does not modify or observe spec for the Route itself.
 func (rec *Reconciler) ReconcileKind(ctx context.Context, r *v1.Route) pkgreconciler.Event {
-	switch config.FromContextOrDefaults(ctx).Features.ResponsiveRevisionGC {
-	case cfgmap.Disabled:
-		if err := labelerv1.SyncLabels(ctx, r, rec.caccV1, rec.raccV1); err != nil {
-			return err
-		}
-		// Clear the new label for downgrade
-		if err := labelerv2.ClearRoutingMeta(ctx, r, rec.caccV2, rec.raccV2); err != nil {
-			return err
-		}
-	case cfgmap.Allowed: // Both labelers on, down/upgrade don't lose data.
-		if err := labelerv1.SyncLabels(ctx, r, rec.caccV1, rec.raccV1); err != nil {
-			return err
-		}
-		if err := labelerv2.SyncRoutingMeta(ctx, r, rec.caccV2, rec.raccV2); err != nil {
-			return err
-		}
-	case cfgmap.Enabled:
-		if err := labelerv2.SyncRoutingMeta(ctx, r, rec.caccV2, rec.raccV2); err != nil {
-			return err
-		}
-		// Clear the old label for upgrade
-		if err := labelerv1.ClearLabels(ctx, r.Namespace, r.Name, rec.caccV1, rec.raccV1); err != nil {
-			return err
-		}
+	if err := labelerv2.SyncRoutingMeta(ctx, r, rec.caccV2, rec.raccV2); err != nil {
+		return err
 	}
 
 	return nil
diff --git a/pkg/reconciler/labeler/v1/accessors.go b/pkg/reconciler/labeler/v1/accessors.go
deleted file mode 100644
index 0ac7658c5..000000000
--- a/pkg/reconciler/labeler/v1/accessors.go
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
-Copyright 2020 The Knative Authors
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1
-
-import (
-	"context"
-
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/labels"
-	"k8s.io/apimachinery/pkg/types"
-	"knative.dev/pkg/kmeta"
-
-	"knative.dev/pkg/tracker"
-	"knative.dev/serving/pkg/apis/serving"
-	clientset "knative.dev/serving/pkg/client/clientset/versioned"
-	listers "knative.dev/serving/pkg/client/listers/serving/v1"
-)
-
-// Accessor defines an abstraction for manipulating labeled entity
-// (Configuration, Revision) with shared logic.
-type Accessor interface {
-	get(ctx context.Context, ns, name string) (kmeta.Accessor, error)
-	list(ctx context.Context, ns, name string) ([]kmeta.Accessor, error)
-	patch(ctx context.Context, ns, name string, pt types.PatchType, p []byte) error
-}
-
-// Revision is an implementation of Accessor for Revisions.
-type Revision struct {
-	client         clientset.Interface
-	tracker        tracker.Interface
-	revisionLister listers.RevisionLister
-}
-
-// Revision implements Accessor
-var _ Accessor = (*Revision)(nil)
-
-// NewRevisionAccessor is a factory function to make a new revision accessor.
-func NewRevisionAccessor(
-	client clientset.Interface,
-	tracker tracker.Interface,
-	lister listers.RevisionLister) *Revision {
-	return &Revision{
-		client:         client,
-		tracker:        tracker,
-		revisionLister: lister,
-	}
-}
-
-// get implements Accessor
-func (r *Revision) get(_ context.Context, ns, name string) (kmeta.Accessor, error) {
-	return r.revisionLister.Revisions(ns).Get(name)
-}
-
-// list implements Accessor
-func (r *Revision) list(_ context.Context, ns, name string) ([]kmeta.Accessor, error) {
-	rl, err := r.revisionLister.Revisions(ns).List(labels.SelectorFromSet(labels.Set{
-		serving.RouteLabelKey: name,
-	}))
-	if err != nil {
-		return nil, err
-	}
-	// Need a copy to change types in Go
-	kl := make([]kmeta.Accessor, len(rl))
-	for i, r := range rl {
-		kl[i] = r
-	}
-	return kl, err
-}
-
-// patch implements Accessor
-func (r *Revision) patch(ctx context.Context, ns, name string, pt types.PatchType, p []byte) error {
-	_, err := r.client.ServingV1().Revisions(ns).Patch(ctx, name, pt, p, metav1.PatchOptions{})
-	return err
-}
-
-// Configuration is an implementation of Accessor for Configurations.
-type Configuration struct {
-	client              clientset.Interface
-	tracker             tracker.Interface
-	configurationLister listers.ConfigurationLister
-}
-
-// Configuration implements Accessor
-var _ Accessor = (*Configuration)(nil)
-
-// NewConfigurationAccessor is a factory function to make a new configuration Accessor.
-func NewConfigurationAccessor(
-	client clientset.Interface,
-	tracker tracker.Interface,
-	lister listers.ConfigurationLister) *Configuration {
-	return &Configuration{
-		client:              client,
-		tracker:             tracker,
-		configurationLister: lister,
-	}
-}
-
-// get implements Accessor
-func (c *Configuration) get(_ context.Context, ns, name string) (kmeta.Accessor, error) {
-	return c.configurationLister.Configurations(ns).Get(name)
-}
-
-// list implements Accessor
-func (c *Configuration) list(_ context.Context, ns, name string) ([]kmeta.Accessor, error) {
-	cl, err := c.configurationLister.Configurations(ns).List(labels.SelectorFromSet(labels.Set{
-		serving.RouteLabelKey: name,
-	}))
-	if err != nil {
-		return nil, err
-	}
-	// Need a copy to change types in Go
-	kl := make([]kmeta.Accessor, len(cl))
-	for i, c := range cl {
-		kl[i] = c
-	}
-	return kl, err
-}
-
-// patch implements Accessor
-func (c *Configuration) patch(ctx context.Context, ns, name string, pt types.PatchType, p []byte) error {
-	_, err := c.client.ServingV1().Configurations(ns).Patch(ctx, name, pt, p, metav1.PatchOptions{})
-	return err
-}
diff --git a/pkg/reconciler/labeler/v1/labels.go b/pkg/reconciler/labeler/v1/labels.go
deleted file mode 100644
index fe6fef962..000000000
--- a/pkg/reconciler/labeler/v1/labels.go
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
-Copyright 2018 The Knative Authors
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1
-
-import (
-	"context"
-	"encoding/json"
-	"fmt"
-
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/apimachinery/pkg/util/sets"
-	"knative.dev/pkg/kmeta"
-	"knative.dev/pkg/tracker"
-
-	"knative.dev/serving/pkg/apis/serving"
-	v1 "knative.dev/serving/pkg/apis/serving/v1"
-)
-
-// SyncLabels makes sure that the revisions and configurations referenced from
-// a Route are labeled with route labels.
-func SyncLabels(ctx context.Context, r *v1.Route, cacc *Configuration, racc *Revision) error {
-	revisions := sets.NewString()
-	configs := sets.NewString()
-
-	// Walk the Route's .status.traffic and .spec.traffic and build a list
-	// of revisions and configurations to label
-	for _, tt := range append(r.Status.Traffic, r.Spec.Traffic...) {
-		revName := tt.RevisionName
-		configName := tt.ConfigurationName
-
-		if revName != "" {
-			if err := racc.tracker.TrackReference(ref(r.Namespace, revName, "Revision"), r); err != nil {
-				return err
-			}
-
-			rev, err := racc.get(ctx, r.Namespace, revName)
-			if err != nil {
-				// The revision might not exist (yet). The informers will notify if it gets created.
-				continue
-			}
-
-			revisions.Insert(revName)
-
-			// If the owner reference is a configuration, treat it like a configuration target
-			if owner := metav1.GetControllerOf(rev); owner != nil && owner.Kind == "Configuration" {
-				configName = owner.Name
-			}
-		}
-
-		if configName != "" {
-			if err := cacc.tracker.TrackReference(ref(r.Namespace, configName, "Configuration"), r); err != nil {
-				return err
-			}
-
-			config, err := cacc.configurationLister.Configurations(r.Namespace).Get(configName)
-			if err != nil {
-				// The config might not exist (yet). The informers will notify if it gets created.
-				continue
-			}
-
-			configs.Insert(configName)
-
-			// If the target is for the latest revision, add the latest created revision to the list
-			// so that there is a smooth transition when the new revision becomes ready.
-			if config.Status.LatestCreatedRevisionName != "" && tt.LatestRevision != nil && *tt.LatestRevision {
-				revisions.Insert(config.Status.LatestCreatedRevisionName)
-			}
-		}
-	}
-
-	// Clear old labels only after the route is fully resolved
-	if r.IsReady() || r.IsFailed() {
-		if err := deleteLabelForNotListed(ctx, r.Namespace, r.Name, racc, revisions); err != nil {
-			return err
-		}
-		if err := deleteLabelForNotListed(ctx, r.Namespace, r.Name, cacc, configs); err != nil {
-			return err
-		}
-	}
-
-	if err := setLabelForListed(ctx, r, racc, revisions); err != nil {
-		return err
-	}
-	return setLabelForListed(ctx, r, cacc, configs)
-}
-
-// ClearLabels removes any labels for a named route from given accessors.
-func ClearLabels(ctx context.Context, ns, name string, accs ...Accessor) error {
-	for _, acc := range accs {
-		if err := deleteLabelForNotListed(ctx, ns, name, acc, nil /*none listed*/); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-// setLabelForListed uses the accessor to attach the label for this route to every element
-// listed within "names" in the same namespace.
-func setLabelForListed(ctx context.Context, route *v1.Route, acc Accessor, names sets.String) error {
-	for name := range names {
-		elt, err := acc.get(ctx, route.Namespace, name)
-		if err != nil {
-			return err
-		}
-		routeName, ok := elt.GetLabels()[serving.RouteLabelKey]
-		if ok {
-			if routeName != route.Name {
-				return fmt.Errorf("%s %q is already in use by %q, and cannot be used by %q",
-					elt.GroupVersionKind(), elt.GetName(), routeName, route.Name)
-			}
-		} else {
-			if err := setRouteLabel(ctx, acc, elt, &route.Name); err != nil {
-				return fmt.Errorf("failed to add route label to %s %q: %w",
-					elt.GroupVersionKind(), elt.GetName(), err)
-			}
-		}
-	}
-
-	return nil
-}
-
-// deleteLabelForNotListed uses the accessor to delete the label from any listable entity that is
-// not named within our list.  Unlike setLabelForListed, this function takes ns/name instead of a
-// Route so that it can clean things up when a Route ceases to exist.
-func deleteLabelForNotListed(ctx context.Context, ns, name string, acc Accessor, names sets.String) error {
-	oldList, err := acc.list(ctx, ns, name)
-	if err != nil {
-		return err
-	}
-
-	// Delete label for newly removed traffic targets.
-	for _, elt := range oldList {
-		if names.Has(elt.GetName()) {
-			continue
-		}
-
-		if err := setRouteLabel(ctx, acc, elt, nil); err != nil {
-			return fmt.Errorf("failed to remove route label to %s %q: %w",
-				elt.GroupVersionKind(), elt.GetName(), err)
-		}
-	}
-
-	return nil
-}
-
-// setRouteLabel toggles the route label on the specified element through the provided accessor.
-// a nil route name will cause the route label to be deleted, and a non-nil route will cause
-// that route name to be attached to the element.
-func setRouteLabel(ctx context.Context, acc Accessor, elt kmeta.Accessor, routeName *string) error {
-	mergePatch := map[string]interface{}{
-		"metadata": map[string]interface{}{
-			"labels": map[string]interface{}{
-				serving.RouteLabelKey: routeName,
-			},
-		},
-	}
-
-	patch, err := json.Marshal(mergePatch)
-	if err != nil {
-		return err
-	}
-
-	return acc.patch(ctx, elt.GetNamespace(), elt.GetName(), types.MergePatchType, patch)
-}
-
-func ref(namespace, name, kind string) tracker.Reference {
-	apiVersion, kind := v1.SchemeGroupVersion.WithKind(kind).ToAPIVersionAndKind()
-	return tracker.Reference{
-		APIVersion: apiVersion,
-		Kind:       kind,
-		Name:       name,
-		Namespace:  namespace,
-	}
-}
diff --git a/pkg/reconciler/route/reconcile_resources.go b/pkg/reconciler/route/reconcile_resources.go
index 109e38baa..4e232ad20 100644
--- a/pkg/reconciler/route/reconcile_resources.go
+++ b/pkg/reconciler/route/reconcile_resources.go
@@ -19,27 +19,21 @@ package route
 import (
 	"context"
 	"encoding/json"
-	"errors"
 	"fmt"
 
-	"github.com/davecgh/go-spew/spew"
 	"go.uber.org/zap"
 	"golang.org/x/sync/errgroup"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/equality"
 	apierrs "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/sets"
 
 	"knative.dev/networking/pkg/apis/networking"
 	netv1alpha1 "knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/pkg/apis/duck"
 	"knative.dev/pkg/controller"
-	"knative.dev/pkg/kmeta"
 	"knative.dev/pkg/logging"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
-	"knative.dev/serving/pkg/reconciler/route/config"
 	"knative.dev/serving/pkg/reconciler/route/resources"
 	"knative.dev/serving/pkg/reconciler/route/resources/names"
 	"knative.dev/serving/pkg/reconciler/route/traffic"
@@ -53,19 +47,12 @@ func (c *Reconciler) reconcileIngress(
 ) (*netv1alpha1.Ingress, error) {
 	recorder := controller.GetEventRecorder(ctx)
 
-	desired, err := resources.MakeIngress(ctx, r, tc, tls, ingressClass, acmeChallenges...)
-	if err != nil {
-		return nil, err
-	}
-	// Get the current rollout state as described by the traffic.
-	curRO := tc.BuildRollout()
-
 	ingress, err := c.ingressLister.Ingresses(r.Namespace).Get(names.Ingress(r))
 	if apierrs.IsNotFound(err) {
-		// If there is no exisiting Ingress, then current rollout is _the_ rollout.
-		desired.Annotations = kmeta.UnionMaps(desired.Annotations, map[string]string{
-			networking.RolloutAnnotationKey: serializeRollout(ctx, curRO),
-		})
+		desired, err := resources.MakeIngress(ctx, r, tc, tls, ingressClass, acmeChallenges...)
+		if err != nil {
+			return nil, err
+		}
 		ingress, err = c.netclient.NetworkingV1alpha1().Ingresses(desired.Namespace).Create(ctx, desired, metav1.CreateOptions{})
 		if err != nil {
 			recorder.Eventf(r, corev1.EventTypeWarning, "CreationFailed", "Failed to create Ingress: %v", err)
@@ -78,11 +65,23 @@ func (c *Reconciler) reconcileIngress(
 		return nil, err
 	} else {
 		// Ingress exists. We need to compute the rollout spec diff.
-		prevRO := deserializeRollout(ctx, ingress.Annotations[networking.RolloutAnnotationKey])
+		// Get the current rollout state as described by the traffic.
+		curRO := tc.BuildRollout()
+
+		// Get the previous rollout state from the annotation.
+		// If it's corrupt, inexistent, or otherwise incorrect,
+		// the prevRO will be just nil rollout.
+		prevRO := deserializeRollout(ctx,
+			ingress.Annotations[networking.RolloutAnnotationKey])
+
+		// And recompute the rollout state.
 		effectiveRO := curRO.Step(prevRO)
-		// Update the annotation.
-		desired.Annotations[networking.RolloutAnnotationKey] = serializeRollout(ctx, effectiveRO)
-		// TODO(vagababov): apply the Rollout to the ingress spec here.
+		desired, err := resources.MakeIngressWithRollout(ctx, r, tc, effectiveRO,
+			tls, ingressClass, acmeChallenges...)
+		if err != nil {
+			return nil, err
+		}
+
 		if !equality.Semantic.DeepEqual(ingress.Spec, desired.Spec) ||
 			!equality.Semantic.DeepEqual(ingress.Annotations, desired.Annotations) ||
 			!equality.Semantic.DeepEqual(ingress.Labels, desired.Labels) {
@@ -210,67 +209,6 @@ func (c *Reconciler) updatePlaceholderServices(ctx context.Context, route *v1.Ro
 	return eg.Wait()
 }
 
-// Update the lastPinned annotation on revisions we target so they don't get GC'd.
-func (c *Reconciler) reconcileTargetRevisions(ctx context.Context, t *traffic.Config, route *v1.Route) error {
-	gcConfig := config.FromContext(ctx).GC
-	logger := logging.FromContext(ctx)
-	lpDebounce := gcConfig.StaleRevisionLastpinnedDebounce
-
-	eg, egCtx := errgroup.WithContext(ctx)
-	for _, target := range t.Targets {
-		for _, rt := range target {
-			tt := rt.TrafficTarget
-			eg.Go(func() error {
-				rev, err := c.revisionLister.Revisions(route.Namespace).Get(tt.RevisionName)
-				if apierrs.IsNotFound(err) {
-					logger.Infof("Unable to update lastPinned for missing revision %q", tt.RevisionName)
-					return nil
-				} else if err != nil {
-					return err
-				}
-
-				newRev := rev.DeepCopy()
-
-				lastPin, err := newRev.GetLastPinned()
-				if err != nil {
-					// Missing is an expected error case for a not yet pinned revision.
-					var errLastPinned v1.LastPinnedParseError
-					if errors.As(err, &errLastPinned) && errLastPinned.Type != v1.AnnotationParseErrorTypeMissing {
-						return err
-					}
-				} else if lastPin.Add(lpDebounce).After(c.clock.Now()) {
-					// Enforce a delay before performing an update on lastPinned to avoid excess churn.
-					return nil
-				}
-
-				newRev.SetLastPinned(c.clock.Now())
-
-				patch, err := duck.CreateMergePatch(rev, newRev)
-				if err != nil {
-					return err
-				}
-
-				if _, err := c.client.ServingV1().Revisions(route.Namespace).Patch(egCtx, rev.Name, types.MergePatchType, patch, metav1.PatchOptions{}); err != nil {
-					return fmt.Errorf("failed to set revision annotation: %w", err)
-				}
-				return nil
-			})
-		}
-	}
-	return eg.Wait()
-}
-
-func serializeRollout(ctx context.Context, r *traffic.Rollout) string {
-	sr, err := json.Marshal(r)
-	if err != nil {
-		// This must never happen in the normal course of things.
-		logging.FromContext(ctx).Warnw("Error serializing Rollout: "+spew.Sprint(r),
-			zap.Error(err))
-		return ""
-	}
-	return string(sr)
-}
-
 func deserializeRollout(ctx context.Context, ro string) *traffic.Rollout {
 	if ro == "" {
 		return nil
diff --git a/pkg/reconciler/route/resources/ingress.go b/pkg/reconciler/route/resources/ingress.go
index 129d66e9e..cae5804c7 100644
--- a/pkg/reconciler/route/resources/ingress.go
+++ b/pkg/reconciler/route/resources/ingress.go
@@ -18,8 +18,11 @@ package resources
 
 import (
 	"context"
+	"encoding/json"
 	"sort"
 
+	"github.com/davecgh/go-spew/spew"
+	"go.uber.org/zap"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/intstr"
@@ -30,6 +33,7 @@ import (
 	netv1alpha1 "knative.dev/networking/pkg/apis/networking/v1alpha1"
 	ingress "knative.dev/networking/pkg/ingress"
 	"knative.dev/pkg/kmeta"
+	"knative.dev/pkg/logging"
 	"knative.dev/serving/pkg/activator"
 	apicfg "knative.dev/serving/pkg/apis/config"
 	"knative.dev/serving/pkg/apis/serving"
@@ -59,6 +63,23 @@ func MakeIngress(
 	tls []netv1alpha1.IngressTLS,
 	ingressClass string,
 	acmeChallenges ...netv1alpha1.HTTP01Challenge,
+) (*netv1alpha1.Ingress, error) {
+	return MakeIngressWithRollout(
+		// If no rollout is specified, we just build the default one.
+		ctx, r, tc, tc.BuildRollout(), tls, ingressClass, acmeChallenges...)
+}
+
+// MakeIngressWithRollout builds a KIngress object from the given parameters.
+// When building the ingress the builder will take into the account
+// the desired rollout state to split the traffic.
+func MakeIngressWithRollout(
+	ctx context.Context,
+	r *servingv1.Route,
+	tc *traffic.Config,
+	ro *traffic.Rollout,
+	tls []netv1alpha1.IngressTLS,
+	ingressClass string,
+	acmeChallenges ...netv1alpha1.HTTP01Challenge,
 ) (*netv1alpha1.Ingress, error) {
 	spec, err := makeIngressSpec(ctx, r, tls, tc, acmeChallenges...)
 	if err != nil {
@@ -74,6 +95,7 @@ func MakeIngress(
 			}),
 			Annotations: kmeta.FilterMap(kmeta.UnionMaps(map[string]string{
 				networking.IngressClassAnnotationKey: ingressClass,
+				networking.RolloutAnnotationKey:      serializeRollout(ctx, ro),
 			}, r.GetAnnotations()), func(key string) bool {
 				return key == corev1.LastAppliedConfigAnnotation
 			}),
@@ -83,6 +105,17 @@ func MakeIngress(
 	}, nil
 }
 
+func serializeRollout(ctx context.Context, r *traffic.Rollout) string {
+	sr, err := json.Marshal(r)
+	if err != nil {
+		// This must never happen in the normal course of things.
+		logging.FromContext(ctx).Warnw("Error serializing Rollout: "+spew.Sprint(r),
+			zap.Error(err))
+		return ""
+	}
+	return string(sr)
+}
+
 // makeIngressSpec builds a new IngressSpec from inputs.
 func makeIngressSpec(
 	ctx context.Context,
diff --git a/pkg/reconciler/route/route.go b/pkg/reconciler/route/route.go
index c149d4833..b25a2aa84 100644
--- a/pkg/reconciler/route/route.go
+++ b/pkg/reconciler/route/route.go
@@ -41,7 +41,6 @@ import (
 	pkgreconciler "knative.dev/pkg/reconciler"
 	"knative.dev/pkg/system"
 	"knative.dev/pkg/tracker"
-	cfgmap "knative.dev/serving/pkg/apis/config"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
 	clientset "knative.dev/serving/pkg/client/clientset/versioned"
 	routereconciler "knative.dev/serving/pkg/client/injection/reconciler/serving/v1/route"
@@ -127,14 +126,6 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, r *v1.Route) pkgreconcil
 		return err
 	}
 
-	if config.FromContextOrDefaults(ctx).Features.ResponsiveRevisionGC != cfgmap.Enabled {
-		// In all cases we will add annotations to the referred targets.  This is so that when they become
-		// routable we can know (through a listener) and attempt traffic configuration again.
-		if err := c.reconcileTargetRevisions(ctx, traffic, r); err != nil {
-			return err
-		}
-	}
-
 	r.Status.Address = &duckv1.Addressable{
 		URL: &apis.URL{
 			Scheme: "http",
diff --git a/pkg/reconciler/service/resources/configuration.go b/pkg/reconciler/service/resources/configuration.go
index 7ec5d1811..6e5920765 100644
--- a/pkg/reconciler/service/resources/configuration.go
+++ b/pkg/reconciler/service/resources/configuration.go
@@ -23,7 +23,6 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"knative.dev/pkg/kmeta"
-	cfgmap "knative.dev/serving/pkg/apis/config"
 	"knative.dev/serving/pkg/apis/serving"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
 	labelerv2 "knative.dev/serving/pkg/reconciler/labeler/v2"
@@ -32,28 +31,22 @@ import (
 
 // MakeConfiguration creates a Configuration from a Service object.
 func MakeConfiguration(service *v1.Service) (*v1.Configuration, error) {
-	return MakeConfigurationFromExisting(service, &v1.Configuration{}, cfgmap.Enabled)
+	return MakeConfigurationFromExisting(service, &v1.Configuration{})
 }
 
 // MakeConfigurationFromExisting creates a Configuration from a Service object given an existing Configuration.
-func MakeConfigurationFromExisting(service *v1.Service, existing *v1.Configuration, gc cfgmap.Flag) (*v1.Configuration, error) {
+func MakeConfigurationFromExisting(service *v1.Service, existing *v1.Configuration) (*v1.Configuration, error) {
 	labels := map[string]string{serving.ServiceLabelKey: service.Name}
 	anns := kmeta.FilterMap(service.GetAnnotations(), func(key string) bool {
 		return key == corev1.LastAppliedConfigAnnotation
 	})
 
 	routeName := names.Route(service)
-	if gc != cfgmap.Enabled {
-		labels[serving.RouteLabelKey] = routeName
-	}
-
-	if gc != cfgmap.Disabled {
-		set := labelerv2.GetListAnnValue(existing.Annotations, serving.RoutesAnnotationKey)
-		if !set.Has(routeName) {
-			set.Insert(routeName)
-		}
-		anns[serving.RoutesAnnotationKey] = strings.Join(set.UnsortedList(), ",")
+	set := labelerv2.GetListAnnValue(existing.Annotations, serving.RoutesAnnotationKey)
+	if !set.Has(routeName) {
+		set.Insert(routeName)
 	}
+	anns[serving.RoutesAnnotationKey] = strings.Join(set.UnsortedList(), ",")
 
 	return &v1.Configuration{
 		ObjectMeta: metav1.ObjectMeta{
diff --git a/pkg/reconciler/service/service.go b/pkg/reconciler/service/service.go
index f21d57dd7..ca360ce91 100644
--- a/pkg/reconciler/service/service.go
+++ b/pkg/reconciler/service/service.go
@@ -34,7 +34,6 @@ import (
 	"knative.dev/pkg/kmp"
 	"knative.dev/pkg/logging"
 	pkgreconciler "knative.dev/pkg/reconciler"
-	cfgmap "knative.dev/serving/pkg/apis/config"
 	"knative.dev/serving/pkg/apis/serving"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
 	listers "knative.dev/serving/pkg/client/listers/serving/v1"
@@ -185,8 +184,7 @@ func (c *Reconciler) checkRoutesNotReady(config *v1.Configuration, logger *zap.S
 }
 
 func (c *Reconciler) createConfiguration(ctx context.Context, service *v1.Service) (*v1.Configuration, error) {
-	gc := cfgmap.FromContextOrDefaults(ctx).Features.ResponsiveRevisionGC
-	cfg, err := resources.MakeConfigurationFromExisting(service, &v1.Configuration{}, gc)
+	cfg, err := resources.MakeConfiguration(service)
 	if err != nil {
 		return nil, err
 	}
@@ -214,8 +212,7 @@ func (c *Reconciler) reconcileConfiguration(ctx context.Context, service *v1.Ser
 	// We are setting the up-to-date default values here so an update won't be triggered if the only
 	// diff is the new default values.
 	existing.SetDefaults(ctx)
-	gc := cfgmap.FromContextOrDefaults(ctx).Features.ResponsiveRevisionGC
-	desiredConfig, err := resources.MakeConfigurationFromExisting(service, existing, gc)
+	desiredConfig, err := resources.MakeConfigurationFromExisting(service, existing)
 	if err != nil {
 		return nil, err
 	}


Test patch:
diff --git a/pkg/apis/config/features_test.go b/pkg/apis/config/features_test.go
index f0e5629ef..0ec3bf592 100644
--- a/pkg/apis/config/features_test.go
+++ b/pkg/apis/config/features_test.go
@@ -66,7 +66,6 @@ func TestFeaturesConfiguration(t *testing.T) {
 			PodSpecRuntimeClassName: Enabled,
 			PodSpecSecurityContext:  Enabled,
 			PodSpecTolerations:      Enabled,
-			ResponsiveRevisionGC:    Enabled,
 			TagHeaderBasedRouting:   Enabled,
 		}),
 		data: map[string]string{
@@ -242,24 +241,6 @@ func TestFeaturesConfiguration(t *testing.T) {
 		data: map[string]string{
 			"kubernetes.podspec-tolerations": "Disabled",
 		},
-	}, {
-		name:    "responsive-revision-gc Allowed",
-		wantErr: false,
-		wantFeatures: defaultWith(&Features{
-			ResponsiveRevisionGC: Allowed,
-		}),
-		data: map[string]string{
-			"responsive-revision-gc": "Allowed",
-		},
-	}, {
-		name:    "responsive-revision-gc Enabled",
-		wantErr: false,
-		wantFeatures: defaultWith(&Features{
-			ResponsiveRevisionGC: Enabled,
-		}),
-		data: map[string]string{
-			"responsive-revision-gc": "Enabled",
-		},
 	}, {
 		name:    "security context Allowed",
 		wantErr: false,
diff --git a/pkg/apis/serving/v1/revision_helpers_test.go b/pkg/apis/serving/v1/revision_helpers_test.go
index a45b7f556..aeb5b699b 100644
--- a/pkg/apis/serving/v1/revision_helpers_test.go
+++ b/pkg/apis/serving/v1/revision_helpers_test.go
@@ -106,92 +106,18 @@ func TestIsActivationRequired(t *testing.T) {
 	}
 }
 
-func TestRevisionGetLastPinned(t *testing.T) {
-	cases := []struct {
-		name              string
-		annotations       map[string]string
-		expectTime        time.Time
-		setLastPinnedTime time.Time
-		expectErr         error
-	}{{
-		name: "Nil annotations",
-		expectErr: LastPinnedParseError{
-			Type: AnnotationParseErrorTypeMissing,
-		},
-	}, {
-		name:        "Empty map annotations",
-		annotations: map[string]string{},
-		expectErr: LastPinnedParseError{
-			Type: AnnotationParseErrorTypeMissing,
-		},
-	}, {
-		name:              "Empty map annotations - with set time",
-		annotations:       map[string]string{},
-		setLastPinnedTime: time.Unix(1000, 0),
-		expectTime:        time.Unix(1000, 0),
-	}, {
-		name:        "Invalid time",
-		annotations: map[string]string{serving.RevisionLastPinnedAnnotationKey: "abcd"},
-		expectErr: LastPinnedParseError{
-			Type:  AnnotationParseErrorTypeInvalid,
-			Value: "abcd",
-		},
-	}, {
-		name:        "Valid time",
-		annotations: map[string]string{serving.RevisionLastPinnedAnnotationKey: "10000"},
-		expectTime:  time.Unix(10000, 0),
-	}, {
-		name:              "Valid time empty annotations",
-		setLastPinnedTime: time.Unix(1000, 0),
-		expectTime:        time.Unix(1000, 0),
-	}}
-
-	for _, tc := range cases {
-		t.Run(tc.name, func(t *testing.T) {
-			rev := Revision{
-				ObjectMeta: metav1.ObjectMeta{
-					Annotations: tc.annotations,
-				},
-			}
-
-			if tc.setLastPinnedTime != (time.Time{}) {
-				rev.SetLastPinned(tc.setLastPinnedTime)
-			}
-
-			pt, err := rev.GetLastPinned()
-			failErr := func() {
-				t.Fatalf("Expected error %v got %v", tc.expectErr, err)
-			}
-
-			if tc.expectErr == nil {
-				if err != nil {
-					failErr()
-				}
-			} else {
-				if tc.expectErr.Error() != err.Error() {
-					failErr()
-				}
-			}
-
-			if tc.expectTime != pt {
-				t.Fatalf("Expected pin time %v got %v", tc.expectTime, pt)
-			}
-		})
-	}
-}
-
 func TestRevisionIsReachable(t *testing.T) {
 	tests := []struct {
 		name   string
 		labels map[string]string
 		want   bool
 	}{{
-		name:   "has route annotation",
-		labels: map[string]string{serving.RouteLabelKey: "the-route"},
+		name:   "has serving state label",
+		labels: map[string]string{serving.RoutingStateLabelKey: "active"},
 		want:   true,
 	}, {
 		name:   "empty route annotation",
-		labels: map[string]string{serving.RouteLabelKey: ""},
+		labels: map[string]string{serving.RoutingStateLabelKey: ""},
 		want:   false,
 	}, {
 		name:   "no route annotation",
diff --git a/pkg/gc/config_test.go b/pkg/gc/config_test.go
index e686b8e85..a4fc035e4 100644
--- a/pkg/gc/config_test.go
+++ b/pkg/gc/config_test.go
@@ -47,42 +47,16 @@ func TestOurConfig(t *testing.T) {
 	}, {
 		name: "with value overrides",
 		want: &Config{
-			StaleRevisionCreateDelay:        15 * time.Hour,
-			StaleRevisionTimeout:            14 * time.Hour,
-			StaleRevisionMinimumGenerations: 10,
-			StaleRevisionLastpinnedDebounce: 2*time.Hour + 30*time.Minute + 44*time.Second,
-			RetainSinceCreateTime:           17 * time.Hour,
-			RetainSinceLastActiveTime:       16 * time.Hour,
-			MinNonActiveRevisions:           5,
-			MaxNonActiveRevisions:           500,
+			RetainSinceCreateTime:     17 * time.Hour,
+			RetainSinceLastActiveTime: 16 * time.Hour,
+			MinNonActiveRevisions:     5,
+			MaxNonActiveRevisions:     500,
 		},
 		data: map[string]string{
-			"stale-revision-create-delay":        "15h",
-			"stale-revision-timeout":             "14h",
-			"stale-revision-minimum-generations": "10",
-			"stale-revision-lastpinned-debounce": "2h30m44s",
-			"retain-since-create-time":           "17h",
-			"retain-since-last-active-time":      "16h",
-			"min-non-active-revisions":           "5",
-			"max-non-active-revisions":           "500",
-		},
-	}, {
-		name: "invalid duration",
-		fail: true,
-		data: map[string]string{
-			"stale-revision-create-delay": "invalid",
-		},
-	}, {
-		name: "invalid negative minimum generation",
-		fail: true,
-		data: map[string]string{
-			"stale-revision-minimum-generations": "-1",
-		},
-	}, {
-		name: "invalid minimum generation",
-		fail: true,
-		data: map[string]string{
-			"stale-revision-minimum-generations": "invalid",
+			"retain-since-create-time":      "17h",
+			"retain-since-last-active-time": "16h",
+			"min-non-active-revisions":      "5",
+			"max-non-active-revisions":      "500",
 		},
 	}, {
 		name: "Invalid negative min stale",
@@ -157,23 +131,6 @@ func TestOurConfig(t *testing.T) {
 		data: map[string]string{
 			"max-non-active-revisions": disabled,
 		},
-	}, {
-		name: "below minimum timeout",
-		fail: false,
-		want: &Config{
-			StaleRevisionCreateDelay:        15 * time.Hour,
-			StaleRevisionTimeout:            15 * time.Hour,
-			StaleRevisionMinimumGenerations: 20,
-			StaleRevisionLastpinnedDebounce: 5 * time.Hour,
-			RetainSinceCreateTime:           48 * time.Hour,
-			RetainSinceLastActiveTime:       15 * time.Hour,
-			MinNonActiveRevisions:           20,
-			MaxNonActiveRevisions:           1000,
-		},
-		data: map[string]string{
-			"stale-revision-create-delay": "15h",
-			"stale-revision-timeout":      "1h",
-		},
 	}} {
 		t.Run(tt.name, func(t *testing.T) {
 			got, err := NewConfigFromConfigMapFunc(logtesting.TestContextWithLogger(t))(
diff --git a/pkg/gc/zz_generated.deepcopy_test.go b/pkg/gc/zz_generated.deepcopy_test.go
index 70f09a94e..a94eb9270 100644
--- a/pkg/gc/zz_generated.deepcopy_test.go
+++ b/pkg/gc/zz_generated.deepcopy_test.go
@@ -25,10 +25,10 @@ import (
 
 func TestDeepCopy(t *testing.T) {
 	src := Config{
-		StaleRevisionCreateDelay:        5 * time.Minute,
-		StaleRevisionTimeout:            5 * time.Minute,
-		StaleRevisionMinimumGenerations: 1,
-		StaleRevisionLastpinnedDebounce: 1 * time.Minute,
+		RetainSinceCreateTime:     5 * time.Minute,
+		RetainSinceLastActiveTime: 5 * time.Minute,
+		MinNonActiveRevisions:     1,
+		MaxNonActiveRevisions:     5,
 	}
 
 	if diff := cmp.Diff(src, *src.DeepCopy()); diff != "" {
@@ -39,10 +39,10 @@ func TestDeepCopy(t *testing.T) {
 func TestDeepCopyInto(t *testing.T) {
 	var dest Config
 	src := Config{
-		StaleRevisionCreateDelay:        5 * time.Minute,
-		StaleRevisionTimeout:            5 * time.Minute,
-		StaleRevisionMinimumGenerations: 1,
-		StaleRevisionLastpinnedDebounce: 1 * time.Minute,
+		RetainSinceCreateTime:     5 * time.Minute,
+		RetainSinceLastActiveTime: 5 * time.Minute,
+		MinNonActiveRevisions:     1,
+		MaxNonActiveRevisions:     5,
 	}
 
 	src.DeepCopyInto(&dest)
diff --git a/pkg/queue/health/probe_test.go b/pkg/queue/health/probe_test.go
index d28348c71..0a88027b7 100644
--- a/pkg/queue/health/probe_test.go
+++ b/pkg/queue/health/probe_test.go
@@ -31,10 +31,9 @@ import (
 )
 
 func TestTCPProbe(t *testing.T) {
-	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	server := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer server.Close()
+	})
 	config := TCPProbeConfigOptions{
 		Address:       server.Listener.Addr().String(),
 		SocketTimeout: time.Second,
@@ -60,7 +59,7 @@ func TestHTTPProbeSuccess(t *testing.T) {
 	}
 	var gotPath string
 	expectedPath := "/health"
-	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	server := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		for headerKey, headerValue := range r.Header {
 			// Filtering for expectedHeader.TestKey to avoid other HTTP probe headers
 			if expectedHeader.Name == headerKey {
@@ -74,15 +73,15 @@ func TestHTTPProbeSuccess(t *testing.T) {
 
 		gotPath = r.URL.Path
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer server.Close()
-	httpGetAction := newHTTPGetAction(t, server.URL)
-	httpGetAction.Path = expectedPath
-	httpGetAction.HTTPHeaders = []corev1.HTTPHeader{expectedHeader}
+	})
+
+	action := newHTTPGetAction(t, server.URL)
+	action.Path = expectedPath
+	action.HTTPHeaders = []corev1.HTTPHeader{expectedHeader}
 
 	config := HTTPProbeConfigOptions{
 		Timeout:       time.Second,
-		HTTPGetAction: httpGetAction,
+		HTTPGetAction: action,
 	}
 	// Connecting to the server should work
 	if err := HTTPProbe(config); err != nil {
@@ -104,16 +103,16 @@ func TestHTTPProbeSuccess(t *testing.T) {
 	}
 }
 
-func TestHTTPsSchemeProbeSuccess(t *testing.T) {
-	server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+func TestHTTPSchemeProbeSuccess(t *testing.T) {
+	server := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer server.Close()
+	})
 
 	config := HTTPProbeConfigOptions{
 		Timeout:       time.Second,
 		HTTPGetAction: newHTTPGetAction(t, server.URL),
 	}
+
 	// Connecting to the server should work
 	if err := HTTPProbe(config); err != nil {
 		t.Error("Expected probe to succeed but failed with error", err)
@@ -127,11 +126,10 @@ func TestHTTPsSchemeProbeSuccess(t *testing.T) {
 }
 
 func TestHTTPProbeTimeoutFailure(t *testing.T) {
-	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	server := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		time.Sleep(2 * time.Second)
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer server.Close()
+	})
 
 	config := HTTPProbeConfigOptions{
 		Timeout:       time.Second,
@@ -143,10 +141,9 @@ func TestHTTPProbeTimeoutFailure(t *testing.T) {
 }
 
 func TestHTTPProbeResponseStatusCodeFailure(t *testing.T) {
-	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	server := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusServiceUnavailable)
-	}))
-	defer server.Close()
+	})
 
 	config := HTTPProbeConfigOptions{
 		Timeout:       time.Second,
@@ -201,26 +198,28 @@ func TestIsHTTPProbeShuttingDown(t *testing.T) {
 	}
 }
 
+func newTestServer(t *testing.T, handler http.HandlerFunc) *httptest.Server {
+	t.Helper()
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		handler(w, r)
+	}))
+	t.Cleanup(server.Close)
+
+	return server
+}
+
 func newHTTPGetAction(t *testing.T, serverURL string) *corev1.HTTPGetAction {
-	urlParsed, err := url.Parse(serverURL)
+	t.Helper()
+
+	u, err := url.Parse(serverURL)
 	if err != nil {
 		t.Fatalf("Error parsing URL")
 	}
-	port := intstr.FromString(urlParsed.Port())
-
-	var uriScheme corev1.URIScheme
-	switch urlParsed.Scheme {
-	case "http":
-		uriScheme = corev1.URISchemeHTTP
-	case "https":
-		uriScheme = corev1.URISchemeHTTPS
-	default:
-		t.Fatal("Unsupported scheme", urlParsed.Scheme)
-	}
 
 	return &corev1.HTTPGetAction{
-		Host:   urlParsed.Hostname(),
-		Port:   port,
-		Scheme: uriScheme,
+		Host: u.Hostname(),
+		Port: intstr.FromString(u.Port()),
+		// We only ever use httptest.NewServer which is http.
+		Scheme: corev1.URISchemeHTTP,
 	}
 }
diff --git a/pkg/queue/readiness/probe_test.go b/pkg/queue/readiness/probe_test.go
index 6a94eedbe..f9718c49b 100644
--- a/pkg/queue/readiness/probe_test.go
+++ b/pkg/queue/readiness/probe_test.go
@@ -135,17 +135,9 @@ func TestExecHandler(t *testing.T) {
 }
 
 func TestTCPSuccess(t *testing.T) {
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	tsURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer ts.Close()
-
-	tsURL, err := url.Parse(ts.URL)
-	if err != nil {
-		t.Fatalf("Failed to parse URL %s: %v", ts.URL, err)
-	}
-
-	t.Log("Port", tsURL.Port())
+	})
 
 	pb := NewProbe(&corev1.Probe{
 		PeriodSeconds:    1,
@@ -186,15 +178,9 @@ func TestHTTPFailureToConnect(t *testing.T) {
 }
 
 func TestHTTPBadResponse(t *testing.T) {
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	tsURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusBadRequest)
-	}))
-	defer ts.Close()
-
-	tsURL, err := url.Parse(ts.URL)
-	if err != nil {
-		t.Fatalf("Failed to parse URL %s: %v", ts.URL, err)
-	}
+	})
 
 	pb := NewProbe(&corev1.Probe{
 		PeriodSeconds:    1,
@@ -216,15 +202,9 @@ func TestHTTPBadResponse(t *testing.T) {
 }
 
 func TestHTTPSuccess(t *testing.T) {
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	tsURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer ts.Close()
-
-	tsURL, err := url.Parse(ts.URL)
-	if err != nil {
-		t.Fatalf("Failed to parse URL %s: %v", ts.URL, err)
-	}
+	})
 
 	pb := NewProbe(&corev1.Probe{
 		PeriodSeconds:    1,
@@ -247,18 +227,12 @@ func TestHTTPSuccess(t *testing.T) {
 
 func TestHTTPManyParallel(t *testing.T) {
 	var count atomic.Int32
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	tsURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		if count.Inc() == 1 {
 			// Add a small amount of work to allow the requests below to collapse into one.
 			time.Sleep(200 * time.Millisecond)
 		}
-	}))
-	defer ts.Close()
-
-	tsURL, err := url.Parse(ts.URL)
-	if err != nil {
-		t.Fatalf("Failed to parse URL %s: %v", ts.URL, err)
-	}
+	})
 
 	pb := NewProbe(&corev1.Probe{
 		PeriodSeconds:    1,
@@ -297,16 +271,10 @@ func TestHTTPManyParallel(t *testing.T) {
 }
 
 func TestHTTPTimeout(t *testing.T) {
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	tsURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		time.Sleep(3 * time.Second)
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer ts.Close()
-
-	tsURL, err := url.Parse(ts.URL)
-	if err != nil {
-		t.Fatalf("Failed to parse URL %s: %v", ts.URL, err)
-	}
+	})
 
 	pb := NewProbe(&corev1.Probe{
 		PeriodSeconds:    1,
@@ -328,16 +296,10 @@ func TestHTTPTimeout(t *testing.T) {
 }
 
 func TestHTTPSuccessWithDelay(t *testing.T) {
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	tsURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		time.Sleep(200 * time.Millisecond)
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer ts.Close()
-
-	tsURL, err := url.Parse(ts.URL)
-	if err != nil {
-		t.Fatalf("Failed to parse URL %s: %v", ts.URL, err)
-	}
+	})
 
 	pb := NewProbe(&corev1.Probe{
 		PeriodSeconds:    1,
@@ -360,20 +322,14 @@ func TestHTTPSuccessWithDelay(t *testing.T) {
 
 func TestKnHTTPSuccessWithRetry(t *testing.T) {
 	var count atomic.Int32
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	tsURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		// Fail the very first request.
 		if count.Inc() == 1 {
 			w.WriteHeader(http.StatusBadRequest)
 			return
 		}
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer ts.Close()
-
-	tsURL, err := url.Parse(ts.URL)
-	if err != nil {
-		t.Fatalf("Failed to parse URL %s: %v", ts.URL, err)
-	}
+	})
 
 	pb := NewProbe(&corev1.Probe{
 		PeriodSeconds:    0,
@@ -398,16 +354,10 @@ func TestKnHTTPSuccessWithThreshold(t *testing.T) {
 	var threshold int32 = 3
 
 	var count atomic.Int32
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	tsURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		count.Inc()
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer ts.Close()
-
-	tsURL, err := url.Parse(ts.URL)
-	if err != nil {
-		t.Fatalf("Failed to parse URL %s: %v", ts.URL, err)
-	}
+	})
 
 	pb := NewProbe(&corev1.Probe{
 		PeriodSeconds:    0,
@@ -437,20 +387,14 @@ func TestKnHTTPSuccessWithThresholdAndFailure(t *testing.T) {
 	var requestFailure int32 = 2
 
 	var count atomic.Int32
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	tsURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		if count.Inc() == requestFailure {
 			w.WriteHeader(http.StatusBadRequest)
 			return
 		}
 
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer ts.Close()
-
-	tsURL, err := url.Parse(ts.URL)
-	if err != nil {
-		t.Fatalf("Failed to parse URL %s: %v", ts.URL, err)
-	}
+	})
 
 	pb := NewProbe(&corev1.Probe{
 		PeriodSeconds:    0,
@@ -480,16 +424,10 @@ func TestKnHTTPSuccessWithThresholdAndFailure(t *testing.T) {
 }
 
 func TestKnHTTPTimeoutFailure(t *testing.T) {
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	tsURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
 		time.Sleep(time.Second)
 		w.WriteHeader(http.StatusOK)
-	}))
-	defer ts.Close()
-
-	tsURL, err := url.Parse(ts.URL)
-	if err != nil {
-		t.Fatalf("Failed to parse URL %s: %v", ts.URL, err)
-	}
+	})
 
 	pb := NewProbe(&corev1.Probe{
 		PeriodSeconds:    0,
@@ -552,6 +490,7 @@ func TestKnUnimplementedProbe(t *testing.T) {
 		t.Error("Got probe success. Wanted failure.")
 	}
 }
+
 func TestKnTCPProbeFailure(t *testing.T) {
 	pb := NewProbe(&corev1.Probe{
 		PeriodSeconds:    0,
@@ -667,3 +606,17 @@ func TestKnTCPProbeSuccessThresholdIncludesFailure(t *testing.T) {
 		t.Errorf("Count = %d, want: %d", got, successThreshold)
 	}
 }
+
+func newTestServer(t *testing.T, h http.HandlerFunc) *url.URL {
+	t.Helper()
+
+	s := httptest.NewServer(h)
+	t.Cleanup(s.Close)
+
+	u, err := url.Parse(s.URL)
+	if err != nil {
+		t.Fatalf("Failed to parse URL %s: %v", s.URL, err)
+	}
+
+	return u
+}
diff --git a/pkg/reconciler/configuration/configuration_test.go b/pkg/reconciler/configuration/configuration_test.go
index 3e167626f..675fa7941 100644
--- a/pkg/reconciler/configuration/configuration_test.go
+++ b/pkg/reconciler/configuration/configuration_test.go
@@ -37,7 +37,6 @@ import (
 	"knative.dev/pkg/controller"
 	"knative.dev/pkg/logging"
 	"knative.dev/pkg/ptr"
-	cfgmap "knative.dev/serving/pkg/apis/config"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
 	servingclient "knative.dev/serving/pkg/client/injection/client/fake"
 	configreconciler "knative.dev/serving/pkg/client/injection/reconciler/serving/v1/configuration"
@@ -69,18 +68,6 @@ func TestReconcile(t *testing.T) {
 	test(t)
 }
 
-func TestReconcileNewGCEnabled(t *testing.T) {
-	testClock = clock.NewFakeClock(time.Now())
-
-	c := &config.Config{
-		Features: &cfgmap.Features{
-			ResponsiveRevisionGC: cfgmap.Enabled,
-		},
-	}
-	testCtx = config.ToContext(context.Background(), c)
-	test(t)
-}
-
 func test(t *testing.T) {
 	retryAttempted := false
 	now := testClock.Now()
diff --git a/pkg/reconciler/configuration/resources/revision_test.go b/pkg/reconciler/configuration/resources/revision_test.go
index 2a365c531..aa1ab1179 100644
--- a/pkg/reconciler/configuration/resources/revision_test.go
+++ b/pkg/reconciler/configuration/resources/revision_test.go
@@ -27,10 +27,8 @@ import (
 	"k8s.io/apimachinery/pkg/util/clock"
 
 	"knative.dev/pkg/ptr"
-	cfgmap "knative.dev/serving/pkg/apis/config"
 	"knative.dev/serving/pkg/apis/serving"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
-	"knative.dev/serving/pkg/reconciler/configuration/config"
 )
 
 var fakeCurTime = time.Unix(1e9, 0)
@@ -121,9 +119,11 @@ func TestMakeRevisions(t *testing.T) {
 		},
 		want: &v1.Revision{
 			ObjectMeta: metav1.ObjectMeta{
-				Namespace:   "with",
-				Name:        "labels-00100",
-				Annotations: map[string]string{},
+				Namespace: "with",
+				Name:      "labels-00100",
+				Annotations: map[string]string{
+					serving.RoutingStateModifiedAnnotationKey: v1.RoutingStateModifiedString(clock),
+				},
 				OwnerReferences: []metav1.OwnerReference{{
 					APIVersion:         v1.SchemeGroupVersion.String(),
 					Kind:               "Configuration",
@@ -135,6 +135,7 @@ func TestMakeRevisions(t *testing.T) {
 					serving.ConfigurationLabelKey:           "labels",
 					serving.ConfigurationGenerationLabelKey: "100",
 					serving.ServiceLabelKey:                 "",
+					serving.RoutingStateLabelKey:            "pending",
 					"foo":                                   "bar",
 					"baz":                                   "blah",
 				},
@@ -188,10 +189,12 @@ func TestMakeRevisions(t *testing.T) {
 					serving.ConfigurationLabelKey:           "annotations",
 					serving.ConfigurationGenerationLabelKey: "100",
 					serving.ServiceLabelKey:                 "",
+					serving.RoutingStateLabelKey:            "pending",
 				},
 				Annotations: map[string]string{
 					"foo": "bar",
 					"baz": "blah",
+					serving.RoutingStateModifiedAnnotationKey: v1.RoutingStateModifiedString(clock),
 				},
 			},
 			Spec: v1.RevisionSpec{
@@ -297,6 +300,7 @@ func TestMakeRevisions(t *testing.T) {
 					"serving.knative.dev/creator": "someone",
 					"foo":                         "bar",
 					"baz":                         "blah",
+					serving.RoutingStateModifiedAnnotationKey: v1.RoutingStateModifiedString(clock),
 				},
 				OwnerReferences: []metav1.OwnerReference{{
 					APIVersion:         v1.SchemeGroupVersion.String(),
@@ -309,6 +313,7 @@ func TestMakeRevisions(t *testing.T) {
 					serving.ConfigurationLabelKey:           "config",
 					serving.ConfigurationGenerationLabelKey: "10",
 					serving.ServiceLabelKey:                 "",
+					serving.RoutingStateLabelKey:            "pending",
 				},
 			},
 			Spec: v1.RevisionSpec{
@@ -323,29 +328,10 @@ func TestMakeRevisions(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			ctx := context.Background()
-			ctx = enableResponsiveGC(ctx, test.responsiveGC)
-
-			got := MakeRevision(ctx, test.configuration, clock)
+			got := MakeRevision(context.Background(), test.configuration, clock)
 			if diff := cmp.Diff(test.want, got); diff != "" {
 				t.Error("MakeRevision (-want, +got) =", diff)
 			}
 		})
 	}
 }
-
-func enableResponsiveGC(ctx context.Context, enabled bool) context.Context {
-	flag := cfgmap.Disabled
-	if enabled {
-		flag = cfgmap.Enabled
-	}
-
-	defaultDefaults, _ := cfgmap.NewDefaultsConfigFromMap(map[string]string{})
-	c := &config.Config{
-		Features: &cfgmap.Features{
-			ResponsiveRevisionGC: flag,
-		},
-		Defaults: defaultDefaults,
-	}
-	return config.ToContext(ctx, c)
-}
diff --git a/pkg/reconciler/gc/config/store_test.go b/pkg/reconciler/gc/config/store_test.go
index 6b1f3051f..6ef71c76e 100644
--- a/pkg/reconciler/gc/config/store_test.go
+++ b/pkg/reconciler/gc/config/store_test.go
@@ -23,7 +23,6 @@ import (
 	"github.com/google/go-cmp/cmp"
 
 	logtesting "knative.dev/pkg/logging/testing"
-	apiconfig "knative.dev/serving/pkg/apis/config"
 	"knative.dev/serving/pkg/gc"
 
 	. "knative.dev/pkg/configmap/testing"
@@ -47,11 +46,4 @@ func TestStoreLoadWithContext(t *testing.T) {
 			t.Error("Unexpected controller config (-want, +got):", diff)
 		}
 	})
-
-	t.Run("features", func(t *testing.T) {
-		expected, _ := apiconfig.NewFeaturesConfigFromConfigMap(featuresConfig)
-		if diff := cmp.Diff(expected, config.Features); diff != "" {
-			t.Error("Unexpected controller config (-want, +got):", diff)
-		}
-	})
 }
diff --git a/pkg/reconciler/gc/reconciler_test.go b/pkg/reconciler/gc/reconciler_test.go
index 39317262c..dd237d9c5 100644
--- a/pkg/reconciler/gc/reconciler_test.go
+++ b/pkg/reconciler/gc/reconciler_test.go
@@ -32,7 +32,6 @@ import (
 	"knative.dev/pkg/logging"
 	"knative.dev/pkg/ptr"
 	pkgrec "knative.dev/pkg/reconciler"
-	apiconfig "knative.dev/serving/pkg/apis/config"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
 	servingclient "knative.dev/serving/pkg/client/injection/client/fake"
 	configreconciler "knative.dev/serving/pkg/client/injection/reconciler/serving/v1/configuration"
@@ -59,7 +58,6 @@ var revisionSpec = v1.RevisionSpec{
 
 func TestGCReconcile(t *testing.T) {
 	now := time.Now()
-	tenMinutesAgo := now.Add(-10 * time.Minute)
 
 	old := now.Add(-11 * time.Minute)
 	older := now.Add(-12 * time.Minute)
@@ -69,90 +67,11 @@ func TestGCReconcile(t *testing.T) {
 		ConfigStore: &testConfigStore{
 			config: &config.Config{
 				RevisionGC: &gc.Config{
-					// v1 settings
-					StaleRevisionCreateDelay:        5 * time.Minute,
-					StaleRevisionTimeout:            5 * time.Minute,
-					StaleRevisionMinimumGenerations: 2,
-
-					// v2 settings
 					RetainSinceCreateTime:     5 * time.Minute,
 					RetainSinceLastActiveTime: 5 * time.Minute,
 					MinNonActiveRevisions:     1,
 					MaxNonActiveRevisions:     gc.Disabled,
 				},
-				Features: &apiconfig.Features{
-					ResponsiveRevisionGC: apiconfig.Disabled,
-				},
-			},
-		}}
-
-	table := TableTest{{
-		Name: "delete oldest, keep two V1",
-		Objects: []runtime.Object{
-			cfg("keep-two", "foo", 5556,
-				WithLatestCreated("5556"),
-				WithLatestReady("5556"),
-				WithConfigObservedGen),
-			rev("keep-two", "foo", 5554, MarkRevisionReady,
-				WithRevName("5554"),
-				WithCreationTimestamp(oldest),
-				WithLastPinned(tenMinutesAgo)),
-			rev("keep-two", "foo", 5555, MarkRevisionReady,
-				WithRevName("5555"),
-				WithCreationTimestamp(older),
-				WithLastPinned(tenMinutesAgo)),
-			rev("keep-two", "foo", 5556, MarkRevisionReady,
-				WithRevName("5556"),
-				WithCreationTimestamp(old),
-				WithLastPinned(tenMinutesAgo)),
-		},
-		WantDeletes: []clientgotesting.DeleteActionImpl{{
-			ActionImpl: clientgotesting.ActionImpl{
-				Namespace: "foo",
-				Verb:      "delete",
-				Resource:  v1.SchemeGroupVersion.WithResource("revisions"),
-			},
-			Name: "5554",
-		}},
-		Key: "foo/keep-two",
-	}}
-
-	table.Test(t, MakeFactory(func(ctx context.Context, listers *Listers, cmw configmap.Watcher) controller.Reconciler {
-		r := &reconciler{
-			client:         servingclient.Get(ctx),
-			revisionLister: listers.GetRevisionLister(),
-		}
-		return configreconciler.NewReconciler(ctx, logging.FromContext(ctx),
-			servingclient.Get(ctx), listers.GetConfigurationLister(),
-			controller.GetEventRecorder(ctx), r, controllerOpts)
-	}))
-}
-
-func TestGCReconcileV2(t *testing.T) {
-	now := time.Now()
-
-	old := now.Add(-11 * time.Minute)
-	older := now.Add(-12 * time.Minute)
-	oldest := now.Add(-13 * time.Minute)
-
-	controllerOpts := controller.Options{
-		ConfigStore: &testConfigStore{
-			config: &config.Config{
-				RevisionGC: &gc.Config{
-					// v1 settings
-					StaleRevisionCreateDelay:        5 * time.Minute,
-					StaleRevisionTimeout:            5 * time.Minute,
-					StaleRevisionMinimumGenerations: 2,
-
-					// v2 settings
-					RetainSinceCreateTime:     5 * time.Minute,
-					RetainSinceLastActiveTime: 5 * time.Minute,
-					MinNonActiveRevisions:     1,
-					MaxNonActiveRevisions:     gc.Disabled,
-				},
-				Features: &apiconfig.Features{
-					ResponsiveRevisionGC: apiconfig.Enabled,
-				},
 			},
 		}}
 
diff --git a/pkg/reconciler/gc/v1/gc_test.go b/pkg/reconciler/gc/v1/gc_test.go
deleted file mode 100644
index daad61dac..000000000
--- a/pkg/reconciler/gc/v1/gc_test.go
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
-Copyright 2020 The Knative Authors
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1
-
-import (
-	"context"
-	"fmt"
-	"testing"
-	"time"
-
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/util/clock"
-	clientgotesting "k8s.io/client-go/testing"
-	duckv1 "knative.dev/pkg/apis/duck/v1"
-	"knative.dev/pkg/ptr"
-	pkgrec "knative.dev/pkg/reconciler"
-	v1 "knative.dev/serving/pkg/apis/serving/v1"
-	fakeservingclient "knative.dev/serving/pkg/client/injection/client/fake"
-	fakerevisioninformer "knative.dev/serving/pkg/client/injection/informers/serving/v1/revision/fake"
-	gcconfig "knative.dev/serving/pkg/gc"
-	"knative.dev/serving/pkg/reconciler/configuration/resources"
-	"knative.dev/serving/pkg/reconciler/gc/config"
-
-	_ "knative.dev/serving/pkg/client/injection/informers/serving/v1/configuration/fake"
-
-	. "knative.dev/pkg/reconciler/testing"
-	. "knative.dev/serving/pkg/testing/v1"
-)
-
-var revisionSpec = v1.RevisionSpec{
-	PodSpec: corev1.PodSpec{
-		Containers: []corev1.Container{{
-			Image: "busybox",
-		}},
-	},
-	TimeoutSeconds: ptr.Int64(60),
-}
-
-func TestCollect(t *testing.T) {
-	now := time.Now()
-	tenMinutesAgo := now.Add(-10 * time.Minute)
-
-	old := now.Add(-11 * time.Minute)
-	older := now.Add(-12 * time.Minute)
-	oldest := now.Add(-13 * time.Minute)
-
-	cfgMap := &config.Config{
-		RevisionGC: &gcconfig.Config{
-			StaleRevisionCreateDelay:        5 * time.Minute,
-			StaleRevisionTimeout:            5 * time.Minute,
-			StaleRevisionMinimumGenerations: 2,
-		},
-	}
-	ctx, _ := SetupFakeContext(t)
-	ctx = config.ToContext(ctx, cfgMap)
-
-	table := []struct {
-		name        string
-		cfg         *v1.Configuration
-		revs        []*v1.Revision
-		wantDeletes []clientgotesting.DeleteActionImpl
-	}{{
-		name: "delete oldest, keep two",
-		cfg: cfg("keep-two", "foo", 5556,
-			WithLatestCreated("5556"),
-			WithLatestReady("5556"),
-			WithConfigObservedGen),
-		revs: []*v1.Revision{
-			rev(ctx, "keep-two", "foo", 5554, MarkRevisionReady,
-				WithRevName("5554"),
-				WithCreationTimestamp(oldest),
-				WithLastPinned(tenMinutesAgo)),
-			rev(ctx, "keep-two", "foo", 5555, MarkRevisionReady,
-				WithRevName("5555"),
-				WithCreationTimestamp(older),
-				WithLastPinned(tenMinutesAgo)),
-			rev(ctx, "keep-two", "foo", 5556, MarkRevisionReady,
-				WithRevName("5556"),
-				WithCreationTimestamp(old),
-				WithLastPinned(tenMinutesAgo)),
-		},
-		wantDeletes: []clientgotesting.DeleteActionImpl{{
-			ActionImpl: clientgotesting.ActionImpl{
-				Namespace: "foo",
-				Verb:      "delete",
-				Resource:  v1.SchemeGroupVersion.WithResource("revisions"),
-			},
-			Name: "5554",
-		}},
-	}, {
-		name: "keep oldest when no lastPinned",
-		cfg: cfg("keep-no-last-pinned", "foo", 5556,
-			WithLatestCreated("5556"),
-			WithLatestReady("5556"),
-			WithConfigObservedGen),
-		revs: []*v1.Revision{
-			// No lastPinned so we will keep this.
-			rev(ctx, "keep-no-last-pinned", "foo", 5554, MarkRevisionReady,
-				WithRevName("5554"),
-				WithCreationTimestamp(oldest)),
-			rev(ctx, "keep-no-last-pinned", "foo", 5555, MarkRevisionReady,
-				WithRevName("5555"),
-				WithCreationTimestamp(older),
-				WithLastPinned(tenMinutesAgo)),
-			rev(ctx, "keep-no-last-pinned", "foo", 5556, MarkRevisionReady,
-				WithRevName("5556"),
-				WithCreationTimestamp(old),
-				WithLastPinned(tenMinutesAgo)),
-		},
-	}, {
-		name: "keep recent lastPinned",
-		cfg: cfg("keep-recent-last-pinned", "foo", 5556,
-			WithLatestCreated("5556"),
-			WithLatestReady("5556"),
-			WithConfigObservedGen),
-		revs: []*v1.Revision{
-			rev(ctx, "keep-recent-last-pinned", "foo", 5554, MarkRevisionReady,
-				WithRevName("5554"),
-				WithCreationTimestamp(oldest),
-				// This is an indication that things are still routing here.
-				WithLastPinned(now)),
-			rev(ctx, "keep-recent-last-pinned", "foo", 5555, MarkRevisionReady,
-				WithRevName("5555"),
-				WithCreationTimestamp(older),
-				WithLastPinned(tenMinutesAgo)),
-			rev(ctx, "keep-recent-last-pinned", "foo", 5556, MarkRevisionReady,
-				WithRevName("5556"),
-				WithCreationTimestamp(old),
-				WithLastPinned(tenMinutesAgo)),
-		},
-	}, {
-		name: "keep LatestReadyRevision",
-		cfg: cfg("keep-two", "foo", 5556,
-			WithLatestReady("5554"),
-			// This comes after 'WithLatestReady' so the
-			// Configuration's 'Ready' Status is 'Unknown'
-			WithLatestCreated("5556"),
-			WithConfigObservedGen),
-		revs: []*v1.Revision{
-			// Create a revision where the LatestReady is 5554, but LatestCreated is 5556.
-			// We should keep LatestReady even if it is old.
-			rev(ctx, "keep-two", "foo", 5554, MarkRevisionReady,
-				WithRevName("5554"),
-				WithCreationTimestamp(oldest),
-				WithLastPinned(tenMinutesAgo)),
-			rev(ctx, "keep-two", "foo", 5555, // Not Ready
-				WithRevName("5555"),
-				WithCreationTimestamp(older),
-				WithLastPinned(tenMinutesAgo)),
-			rev(ctx, "keep-two", "foo", 5556, // Not Ready
-				WithRevName("5556"),
-				WithCreationTimestamp(old),
-				WithLastPinned(tenMinutesAgo)),
-		},
-	}, {
-		name: "keep stale revision because of minimum generations",
-		cfg: cfg("keep-all", "foo", 5554,
-			// Don't set the latest ready revision here
-			// since those by default are always retained
-			WithLatestCreated("keep-all"),
-			WithConfigObservedGen),
-		revs: []*v1.Revision{
-			rev(ctx, "keep-all", "foo", 5554,
-				WithRevName("keep-all"),
-				WithCreationTimestamp(oldest),
-				WithLastPinned(tenMinutesAgo)),
-		},
-	}}
-
-	for _, test := range table {
-		t.Run(test.name, func(t *testing.T) {
-			ctx, _ = SetupFakeContext(t)
-			ctx = config.ToContext(ctx, cfgMap)
-			client := fakeservingclient.Get(ctx)
-
-			ri := fakerevisioninformer.Get(ctx)
-			for _, rev := range test.revs {
-				ri.Informer().GetIndexer().Add(rev)
-			}
-
-			recorderList := ActionRecorderList{client}
-
-			Collect(ctx, client, ri.Lister(), test.cfg)
-
-			actions, err := recorderList.ActionsByVerb()
-			if err != nil {
-				t.Errorf("Error capturing actions by verb: %q", err)
-			}
-
-			for i, want := range test.wantDeletes {
-				if i >= len(actions.Deletes) {
-					t.Errorf("Missing delete: %#v", want)
-					continue
-				}
-				got := actions.Deletes[i]
-				if got.GetName() != want.GetName() {
-					t.Errorf("Unexpected delete[%d]: %#v", i, got)
-				}
-			}
-			if got, want := len(actions.Deletes), len(test.wantDeletes); got > want {
-				for _, extra := range actions.Deletes[want:] {
-					t.Errorf("Extra delete: %s/%s", extra.GetNamespace(), extra.GetName())
-				}
-			}
-		})
-	}
-}
-
-func TestIsRevisionStale(t *testing.T) {
-	curTime := time.Now()
-	staleTime := curTime.Add(-10 * time.Minute)
-
-	tests := []struct {
-		name      string
-		rev       *v1.Revision
-		latestRev string
-		want      bool
-	}{{
-		name: "fresh revision that was never pinned",
-		rev: &v1.Revision{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:              "myrev",
-				CreationTimestamp: metav1.NewTime(curTime),
-			},
-		},
-		want: false,
-	}, {
-		name: "stale revision that was never pinned w/ Ready status",
-		rev: &v1.Revision{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:              "myrev",
-				CreationTimestamp: metav1.NewTime(staleTime),
-			},
-			Status: v1.RevisionStatus{
-				Status: duckv1.Status{
-					Conditions: duckv1.Conditions{{
-						Type:   v1.RevisionConditionReady,
-						Status: "True",
-					}},
-				},
-			},
-		},
-		want: false,
-	}, {
-		name: "stale revision that was never pinned w/o Ready status",
-		rev: &v1.Revision{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:              "myrev",
-				CreationTimestamp: metav1.NewTime(staleTime),
-			},
-			Status: v1.RevisionStatus{
-				Status: duckv1.Status{
-					Conditions: duckv1.Conditions{{
-						Type:   v1.RevisionConditionReady,
-						Status: "Unknown",
-					}},
-				},
-			},
-		},
-		want: true,
-	}, {
-		name: "stale revision that was previously pinned",
-		rev: &v1.Revision{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:              "myrev",
-				CreationTimestamp: metav1.NewTime(staleTime),
-				Annotations: map[string]string{
-					"serving.knative.dev/lastPinned": fmt.Sprint(staleTime.Unix()),
-				},
-			},
-		},
-		want: true,
-	}, {
-		name: "fresh revision that was previously pinned",
-		rev: &v1.Revision{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:              "myrev",
-				CreationTimestamp: metav1.NewTime(staleTime),
-				Annotations: map[string]string{
-					"serving.knative.dev/lastPinned": fmt.Sprint(curTime.Unix()),
-				},
-			},
-		},
-		want: false,
-	}, {
-		name: "stale latest ready revision",
-		rev: &v1.Revision{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:              "myrev",
-				CreationTimestamp: metav1.NewTime(staleTime),
-				Annotations: map[string]string{
-					"serving.knative.dev/lastPinned": fmt.Sprint(staleTime.Unix()),
-				},
-			},
-		},
-		latestRev: "myrev",
-		want:      false,
-	}}
-
-	cfgStore := testConfigStore{
-		config: &config.Config{
-			RevisionGC: &gcconfig.Config{
-				StaleRevisionCreateDelay:        5 * time.Minute,
-				StaleRevisionTimeout:            5 * time.Minute,
-				StaleRevisionMinimumGenerations: 2,
-			},
-		},
-	}
-	ctx := cfgStore.ToContext(context.Background())
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			cfg := &v1.Configuration{
-				Status: v1.ConfigurationStatus{
-					ConfigurationStatusFields: v1.ConfigurationStatusFields{
-						LatestReadyRevisionName: test.latestRev,
-					},
-				},
-			}
-
-			got := isRevisionStale(ctx, test.rev, cfg)
-
-			if got != test.want {
-				t.Errorf("IsRevisionStale = %v want: %v", got, test.want)
-			}
-		})
-	}
-}
-
-func cfg(name, namespace string, generation int64, co ...ConfigOption) *v1.Configuration {
-	c := &v1.Configuration{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:       name,
-			Namespace:  namespace,
-			Generation: generation,
-		},
-		Spec: v1.ConfigurationSpec{
-			Template: v1.RevisionTemplateSpec{
-				Spec: *revisionSpec.DeepCopy(),
-			},
-		},
-	}
-	for _, opt := range co {
-		opt(c)
-	}
-	c.SetDefaults(context.Background())
-	return c
-}
-
-func rev(ctx context.Context, name, namespace string, generation int64, ro ...RevisionOption) *v1.Revision {
-	config := cfg(name, namespace, generation)
-	rev := resources.MakeRevision(ctx, config, clock.RealClock{})
-	rev.SetDefaults(context.Background())
-
-	for _, opt := range ro {
-		opt(rev)
-	}
-	return rev
-}
-
-type testConfigStore struct {
-	config *config.Config
-}
-
-func (t *testConfigStore) ToContext(ctx context.Context) context.Context {
-	return config.ToContext(ctx, t.config)
-}
-
-var _ pkgrec.ConfigStore = (*testConfigStore)(nil)
diff --git a/pkg/reconciler/gc/v2/gc_test.go b/pkg/reconciler/gc/v2/gc_test.go
index 1126bac35..6c7eea2b1 100644
--- a/pkg/reconciler/gc/v2/gc_test.go
+++ b/pkg/reconciler/gc/v2/gc_test.go
@@ -18,7 +18,6 @@ package v2
 
 import (
 	"context"
-	"fmt"
 	"testing"
 	"time"
 
@@ -490,30 +489,6 @@ func TestIsRevisionStale(t *testing.T) {
 			},
 		},
 		want: false,
-	}, {
-		name: "stale pinned time",
-		rev: &v1.Revision{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:              "myrev",
-				CreationTimestamp: metav1.NewTime(staleTime),
-				Annotations: map[string]string{
-					"serving.knative.dev/lastPinned": fmt.Sprint(staleTime.Unix()),
-				},
-			},
-		},
-		want: true,
-	}, {
-		name: "fresh pinned time",
-		rev: &v1.Revision{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:              "myrev",
-				CreationTimestamp: metav1.NewTime(staleTime),
-				Annotations: map[string]string{
-					"serving.knative.dev/lastPinned": fmt.Sprint(curTime.Unix()),
-				},
-			},
-		},
-		want: false,
 	}, {
 		name: "stale revisionStateModified",
 		rev: &v1.Revision{
diff --git a/pkg/reconciler/labeler/labeler_both_test.go b/pkg/reconciler/labeler/labeler_both_test.go
deleted file mode 100644
index 4cd6242a7..000000000
--- a/pkg/reconciler/labeler/labeler_both_test.go
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-Copyright 2020 The Knative Authors
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package labeler
-
-import (
-	"context"
-	"testing"
-
-	// Inject the fake informers that this controller needs.
-	servingclient "knative.dev/serving/pkg/client/injection/client/fake"
-	_ "knative.dev/serving/pkg/client/injection/informers/serving/v1/configuration/fake"
-	_ "knative.dev/serving/pkg/client/injection/informers/serving/v1/revision/fake"
-	_ "knative.dev/serving/pkg/client/injection/informers/serving/v1/route/fake"
-
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/util/clock"
-	clientgotesting "k8s.io/client-go/testing"
-	routereconciler "knative.dev/serving/pkg/client/injection/reconciler/serving/v1/route"
-
-	"knative.dev/pkg/configmap"
-	"knative.dev/pkg/controller"
-	"knative.dev/pkg/logging"
-	cfgmap "knative.dev/serving/pkg/apis/config"
-	v1 "knative.dev/serving/pkg/apis/serving/v1"
-
-	. "knative.dev/pkg/reconciler/testing"
-	labelerv1 "knative.dev/serving/pkg/reconciler/labeler/v1"
-	labelerv2 "knative.dev/serving/pkg/reconciler/labeler/v2"
-	. "knative.dev/serving/pkg/reconciler/testing/v1"
-	. "knative.dev/serving/pkg/testing/v1"
-)
-
-func TestV2ReconcileAllowed(t *testing.T) {
-	now := metav1.Now()
-	fakeTime := now.Time
-
-	table := TableTest{{
-		Name: "change configurations",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Allowed),
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "config-change", "new-config", WithRouteFinalizer),
-
-			rev("default", "old-config",
-				WithRevisionLabel("serving.knative.dev/route", "config-change"),
-				WithRevisionAnn("serving.knative.dev/routes", "config-change"),
-				WithRoutingState(v1.RoutingStateActive)),
-
-			simpleConfig("default", "new-config"),
-			rev("default", "new-config"),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			// v1 sync
-			patchRemoveLabel("default", rev("default", "old-config").Name,
-				"serving.knative.dev/route"),
-			patchAddLabel("default", rev("default", "new-config").Name, "serving.knative.dev/route", "config-change"),
-			patchAddLabel("default", "new-config", "serving.knative.dev/route", "config-change"),
-
-			// v2 sync
-			patchRemoveRouteAndServingStateLabel("default", rev("default", "old-config").Name, now.Time),
-			patchAddRouteAndServingStateLabel(
-				"default", rev("default", "new-config").Name, "config-change", now.Time),
-			patchAddRouteAnn("default", "new-config", "config-change"),
-		},
-		Key: "default/config-change",
-	}, {
-		Name: "failure while removing a rev annotation should return an error",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Allowed),
-		// Induce a failure during patching
-		WantErr: true,
-		WithReactors: []clientgotesting.ReactionFunc{
-			InduceFailure("patch", "revisions"),
-		},
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "add-label-failure", "new-config", WithRouteFinalizer),
-			simpleConfig("default", "new-config",
-				WithConfigLabel("serving.knative.dev/route", "add-label-failure")),
-			rev("default", "new-config"),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchAddLabel("default", rev("default", "new-config").Name,
-				"serving.knative.dev/route", "add-label-failure"),
-		},
-		WantEvents: []string{
-			Eventf(corev1.EventTypeWarning, "InternalError",
-				`failed to add route label to /, Kind= "new-config-dbnfd": inducing failure for patch revisions`),
-		},
-		Key: "default/add-label-failure",
-	}}
-
-	table.Test(t, MakeFactory(func(ctx context.Context, listers *Listers, cmw configmap.Watcher) controller.Reconciler {
-		clock := clock.NewFakeClock(fakeTime)
-		client := servingclient.Get(ctx)
-		cLister := listers.GetConfigurationLister()
-		cIndexer := listers.IndexerFor(&v1.Configuration{})
-		rLister := listers.GetRevisionLister()
-		rIndexer := listers.IndexerFor(&v1.Revision{})
-		r := &Reconciler{
-			caccV1: labelerv1.NewConfigurationAccessor(client, &NullTracker{}, cLister),
-			caccV2: labelerv2.NewConfigurationAccessor(client, &NullTracker{}, cLister, cIndexer, clock),
-			raccV1: labelerv1.NewRevisionAccessor(client, &NullTracker{}, rLister),
-			raccV2: labelerv2.NewRevisionAccessor(client, &NullTracker{}, rLister, rIndexer, clock),
-		}
-
-		return routereconciler.NewReconciler(ctx, logging.FromContext(ctx), servingclient.Get(ctx),
-			listers.GetRouteLister(), controller.GetEventRecorder(ctx), r)
-	}))
-}
diff --git a/pkg/reconciler/labeler/labelerv1_test.go b/pkg/reconciler/labeler/labelerv1_test.go
deleted file mode 100644
index ad0337a7a..000000000
--- a/pkg/reconciler/labeler/labelerv1_test.go
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
-Copyright 2020 The Knative Authors
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package labeler
-
-import (
-	"context"
-	"fmt"
-	"testing"
-
-	// Inject the fake informers that this controller needs.
-	servingclient "knative.dev/serving/pkg/client/injection/client/fake"
-	_ "knative.dev/serving/pkg/client/injection/informers/serving/v1/configuration/fake"
-	_ "knative.dev/serving/pkg/client/injection/informers/serving/v1/revision/fake"
-	_ "knative.dev/serving/pkg/client/injection/informers/serving/v1/route/fake"
-
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/util/clock"
-	clientgotesting "k8s.io/client-go/testing"
-	routereconciler "knative.dev/serving/pkg/client/injection/reconciler/serving/v1/route"
-
-	"knative.dev/pkg/configmap"
-	"knative.dev/pkg/controller"
-	"knative.dev/pkg/logging"
-	cfgmap "knative.dev/serving/pkg/apis/config"
-	v1 "knative.dev/serving/pkg/apis/serving/v1"
-
-	. "knative.dev/pkg/reconciler/testing"
-	labelerv1 "knative.dev/serving/pkg/reconciler/labeler/v1"
-	labelerv2 "knative.dev/serving/pkg/reconciler/labeler/v2"
-	. "knative.dev/serving/pkg/reconciler/testing/v1"
-	. "knative.dev/serving/pkg/testing/v1"
-)
-
-func TestV1Reconcile(t *testing.T) {
-	now := metav1.Now()
-	fakeTime := now.Time
-
-	table := TableTest{{
-		Name: "bad workqueue key",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		// Make sure Reconcile handles bad keys.
-		Key: "too/many/parts",
-	}, {
-		Name: "key not found",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		// Make sure Reconcile handles good keys that don't exist.
-		Key: "foo/not-found",
-	}, {
-		Name: "label runLatest configuration",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "first-reconcile", "the-config"),
-			simpleConfig("default", "the-config"),
-			rev("default", "the-config"),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchAddFinalizerAction("default", "first-reconcile"),
-			patchAddLabel("default", rev("default", "the-config").Name,
-				"serving.knative.dev/route", "first-reconcile"),
-			patchAddLabel("default", "the-config", "serving.knative.dev/route", "first-reconcile"),
-		},
-		WantEvents: []string{
-			Eventf(corev1.EventTypeNormal, "FinalizerUpdate", "Updated %q finalizers", "first-reconcile"),
-		},
-		Key: "default/first-reconcile",
-	}, {
-		Name: "label pinned revision",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		Objects: []runtime.Object{
-			pinnedRoute("default", "pinned-revision", "the-revision"),
-			simpleConfig("default", "the-config"),
-			rev("default", "the-config"),
-			rev("default", "the-config", WithRevName("the-revision")),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchAddFinalizerAction("default", "pinned-revision"),
-			patchAddLabel("default", "the-revision",
-				"serving.knative.dev/route", "pinned-revision"),
-			patchAddLabel("default", "the-config",
-				"serving.knative.dev/route", "pinned-revision"),
-		},
-		WantEvents: []string{
-			Eventf(corev1.EventTypeNormal, "FinalizerUpdate", "Updated %q finalizers", "pinned-revision"),
-		},
-		Key: "default/pinned-revision",
-	}, {
-		Name: "steady state",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "steady-state", "the-config", WithRouteFinalizer),
-			simpleConfig("default", "the-config",
-				WithConfigLabel("serving.knative.dev/route", "steady-state")),
-			rev("default", "the-config",
-				WithRevisionLabel("serving.knative.dev/route", "steady-state")),
-		},
-		Key: "default/steady-state",
-	}, {
-		Name: "no ready revision",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "no-ready-revision", "the-config", WithStatusTraffic()),
-			simpleConfig("default", "the-config", WithLatestReady("")),
-			rev("default", "the-config"),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchAddFinalizerAction("default", "no-ready-revision"),
-			patchAddLabel("default", rev("default", "the-config").Name,
-				"serving.knative.dev/route", "no-ready-revision"),
-			patchAddLabel("default", "the-config",
-				"serving.knative.dev/route", "no-ready-revision"),
-		},
-		WantEvents: []string{
-			Eventf(corev1.EventTypeNormal, "FinalizerUpdate", "Updated %q finalizers", "no-ready-revision"),
-		},
-		Key: "default/no-ready-revision",
-	}, {
-		Name: "transitioning route",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "transitioning-route", "old", WithRouteFinalizer,
-				WithSpecTraffic(configTraffic("new"))),
-			simpleConfig("default", "old",
-				WithConfigLabel("serving.knative.dev/route", "transitioning-route")),
-			rev("default", "old",
-				WithRevisionLabel("serving.knative.dev/route", "transitioning-route")),
-			simpleConfig("default", "new"),
-			rev("default", "new"),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchAddLabel("default", rev("default", "new").Name,
-				"serving.knative.dev/route", "transitioning-route"),
-			patchAddLabel("default", "new",
-				"serving.knative.dev/route", "transitioning-route"),
-		},
-		Key: "default/transitioning-route",
-	}, {
-		Name: "failure adding label (revision)",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		// Induce a failure during patching
-		WantErr: true,
-		WithReactors: []clientgotesting.ReactionFunc{
-			InduceFailure("patch", "revisions"),
-		},
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "add-label-failure", "the-config", WithRouteFinalizer),
-			simpleConfig("default", "the-config"),
-			rev("default", "the-config"),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchAddLabel("default", rev("default", "the-config").Name,
-				"serving.knative.dev/route", "add-label-failure"),
-		},
-		WantEvents: []string{
-			Eventf(corev1.EventTypeWarning, "InternalError",
-				`failed to add route label to /, Kind= "the-config-dbnfd": inducing failure for patch revisions`),
-		},
-		Key: "default/add-label-failure",
-	}, {
-		Name: "failure adding label (configuration)",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		// Induce a failure during patching
-		WantErr: true,
-		WithReactors: []clientgotesting.ReactionFunc{
-			InduceFailure("patch", "configurations"),
-		},
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "add-label-failure", "the-config", WithRouteFinalizer),
-			simpleConfig("default", "the-config"),
-			rev("default", "the-config",
-				WithRevisionLabel("serving.knative.dev/route", "add-label-failure")),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchAddLabel("default", "the-config", "serving.knative.dev/route", "add-label-failure"),
-		},
-		WantEvents: []string{
-			Eventf(corev1.EventTypeWarning, "InternalError",
-				`failed to add route label to /, Kind= "the-config": inducing failure for patch configurations`),
-		},
-		Key: "default/add-label-failure",
-	}, {
-		Name:    "label config with incorrect label",
-		Ctx:     setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		WantErr: true,
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "the-route", "the-config", WithRouteFinalizer),
-			simpleConfig("default", "the-config",
-				WithConfigLabel("serving.knative.dev/route", "another-route")),
-			rev("default", "the-config",
-				WithRevisionLabel("serving.knative.dev/route", "another-route")),
-		},
-		WantEvents: []string{
-			Eventf(corev1.EventTypeWarning, "InternalError",
-				`/, Kind= "the-config-dbnfd" is already in use by "another-route", and cannot be used by "the-route"`),
-		},
-		Key: "default/the-route",
-	}, {
-		Name: "change configurations",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "config-change", "new-config", WithRouteFinalizer),
-			simpleConfig("default", "old-config",
-				WithConfigLabel("serving.knative.dev/route", "config-change")),
-			rev("default", "old-config",
-				WithRevisionLabel("serving.knative.dev/route", "config-change")),
-			simpleConfig("default", "new-config"),
-			rev("default", "new-config"),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchRemoveLabel("default", rev("default", "old-config").Name,
-				"serving.knative.dev/route"),
-			patchRemoveLabel("default", "old-config", "serving.knative.dev/route"),
-			patchAddLabel("default", rev("default", "new-config").Name,
-				"serving.knative.dev/route", "config-change"),
-			patchAddLabel("default", "new-config", "serving.knative.dev/route", "config-change"),
-		},
-		Key: "default/config-change",
-	}, {
-		Name: "update configuration",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "config-update", "the-config", WithRouteFinalizer),
-			simpleConfig("default", "the-config",
-				WithLatestCreated("the-config-ecoge"),
-				WithConfigLabel("serving.knative.dev/route", "config-update")),
-			rev("default", "the-config",
-				WithRevisionLabel("serving.knative.dev/route", "config-update")),
-			rev("default", "the-config",
-				WithRevName("the-config-ecoge")),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchAddLabel("default", "the-config-ecoge",
-				"serving.knative.dev/route", "config-update"),
-		},
-		Key: "default/config-update",
-	}, {
-		Name: "delete route",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "delete-route", "the-config", WithRouteFinalizer, WithRouteDeletionTimestamp(&now)),
-			simpleConfig("default", "the-config",
-				WithConfigLabel("serving.knative.dev/route", "delete-route")),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchRemoveLabel("default", "the-config", "serving.knative.dev/route"),
-			patchRemoveFinalizerAction("default", "delete-route"),
-		},
-		WantEvents: []string{
-			Eventf(corev1.EventTypeNormal, "FinalizerUpdate", `Updated "delete-route" finalizers`),
-		},
-		Key: "default/delete-route",
-	}, {
-		Name:    "delete route failure",
-		Ctx:     setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		WantErr: true,
-		WithReactors: []clientgotesting.ReactionFunc{
-			InduceFailure("patch", "configurations"),
-		},
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "delete-route", "the-config", WithRouteFinalizer, WithRouteDeletionTimestamp(&now)),
-			simpleConfig("default", "the-config",
-				WithConfigLabel("serving.knative.dev/route", "delete-route")),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchRemoveLabel("default", "the-config", "serving.knative.dev/route"),
-		},
-		WantEvents: []string{
-			Eventf(corev1.EventTypeWarning, "InternalError",
-				`failed to remove route label to /, Kind= "the-config": inducing failure for patch configurations`),
-		},
-		Key: "default/delete-route",
-	}, {
-		Name: "failure while removing a cfg annotation should return an error",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		// Induce a failure during patching
-		WantErr: true,
-		WithReactors: []clientgotesting.ReactionFunc{
-			InduceFailure("patch", "configurations"),
-		},
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "delete-label-failure", "new-config", WithRouteFinalizer),
-			simpleConfig("default", "old-config",
-				WithConfigLabel("serving.knative.dev/route", "delete-label-failure")),
-			simpleConfig("default", "new-config",
-				WithConfigLabel("serving.knative.dev/route", "delete-label-failure")),
-			rev("default", "new-config",
-				WithRevisionLabel("serving.knative.dev/route", "delete-label-failure")),
-			rev("default", "old-config"),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchRemoveLabel("default", "old-config", "serving.knative.dev/route"),
-		},
-		WantEvents: []string{
-			Eventf(corev1.EventTypeWarning, "InternalError",
-				`failed to remove route label to /, Kind= "old-config": inducing failure for patch configurations`),
-		},
-		Key: "default/delete-label-failure",
-	}, {
-		Name: "failure while removing a rev annotation should return an error",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		// Induce a failure during patching
-		WantErr: true,
-		WithReactors: []clientgotesting.ReactionFunc{
-			InduceFailure("patch", "revisions"),
-		},
-		Objects: []runtime.Object{
-			simpleRunLatest("default", "delete-label-failure", "new-config", WithRouteFinalizer),
-			simpleConfig("default", "old-config",
-				WithConfigLabel("serving.knative.dev/route", "delete-label-failure")),
-			simpleConfig("default", "new-config",
-				WithConfigLabel("serving.knative.dev/route", "delete-label-failure")),
-			rev("default", "new-config",
-				WithRevisionLabel("serving.knative.dev/route", "delete-label-failure")),
-			rev("default", "old-config",
-				WithRevisionLabel("serving.knative.dev/route", "delete-label-failure")),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchRemoveLabel("default", rev("default", "old-config").Name,
-				"serving.knative.dev/route"),
-		},
-		WantEvents: []string{
-			Eventf(corev1.EventTypeWarning, "InternalError",
-				`failed to remove route label to /, Kind= "old-config-dbnfd": inducing failure for patch revisions`),
-		},
-		Key: "default/delete-label-failure",
-	}}
-
-	table.Test(t, MakeFactory(func(ctx context.Context, listers *Listers, cmw configmap.Watcher) controller.Reconciler {
-		ctx = setResponsiveGCFeature(ctx, cfgmap.Disabled)
-		clock := clock.NewFakeClock(fakeTime)
-		client := servingclient.Get(ctx)
-		cLister := listers.GetConfigurationLister()
-		cIndexer := listers.IndexerFor(&v1.Configuration{})
-		rLister := listers.GetRevisionLister()
-		rIndexer := listers.IndexerFor(&v1.Revision{})
-		r := &Reconciler{
-			caccV1: labelerv1.NewConfigurationAccessor(client, &NullTracker{}, cLister),
-			caccV2: labelerv2.NewConfigurationAccessor(client, &NullTracker{}, cLister, cIndexer, clock),
-			raccV1: labelerv1.NewRevisionAccessor(client, &NullTracker{}, rLister),
-			raccV2: labelerv2.NewRevisionAccessor(client, &NullTracker{}, rLister, rIndexer, clock),
-		}
-
-		return routereconciler.NewReconciler(ctx, logging.FromContext(ctx), servingclient.Get(ctx),
-			listers.GetRouteLister(), controller.GetEventRecorder(ctx), r)
-	}))
-}
-
-func patchRemoveLabel(namespace, name, key string) clientgotesting.PatchActionImpl {
-	return clientgotesting.PatchActionImpl{
-		Name:       name,
-		ActionImpl: clientgotesting.ActionImpl{Namespace: namespace},
-		Patch:      []byte(fmt.Sprintf(`{"metadata":{"labels":{%q:null}}}`, key)),
-	}
-}
-
-func patchAddLabel(namespace, name, key, value string) clientgotesting.PatchActionImpl {
-	return clientgotesting.PatchActionImpl{
-		Name:       name,
-		ActionImpl: clientgotesting.ActionImpl{Namespace: namespace},
-		Patch:      []byte(fmt.Sprintf(`{"metadata":{"labels":{%q:%q}}}`, key, value)),
-	}
-}
diff --git a/pkg/reconciler/labeler/labelerv2_test.go b/pkg/reconciler/labeler/labelerv2_test.go
index fceea3bd9..796afa0fa 100644
--- a/pkg/reconciler/labeler/labelerv2_test.go
+++ b/pkg/reconciler/labeler/labelerv2_test.go
@@ -46,8 +46,6 @@ import (
 	autoscalercfg "knative.dev/serving/pkg/autoscaler/config"
 
 	. "knative.dev/pkg/reconciler/testing"
-	"knative.dev/serving/pkg/reconciler/configuration/config"
-	labelerv1 "knative.dev/serving/pkg/reconciler/labeler/v1"
 	labelerv2 "knative.dev/serving/pkg/reconciler/labeler/v2"
 	. "knative.dev/serving/pkg/reconciler/testing/v1"
 	. "knative.dev/serving/pkg/testing/v1"
@@ -59,17 +57,14 @@ func TestV2Reconcile(t *testing.T) {
 
 	table := TableTest{{
 		Name: "bad workqueue key",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		// Make sure Reconcile handles bad keys.
 		Key: "too/many/parts",
 	}, {
 		Name: "key not found",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		// Make sure Reconcile handles good keys that don't exist.
 		Key: "foo/not-found",
 	}, {
 		Name: "label runLatest configuration",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		Objects: []runtime.Object{
 			simpleRunLatest("default", "first-reconcile", "the-config"),
 			simpleConfig("default", "the-config"),
@@ -87,7 +82,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/first-reconcile",
 	}, {
 		Name: "label pinned revision",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		Objects: []runtime.Object{
 			pinnedRoute("default", "pinned-revision", "the-revision"),
 			simpleConfig("default", "the-config"),
@@ -107,7 +101,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/pinned-revision",
 	}, {
 		Name: "steady state",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		Objects: []runtime.Object{
 			simpleRunLatest("default", "steady-state", "the-config", WithRouteFinalizer),
 			simpleConfig("default", "the-config",
@@ -120,7 +113,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/steady-state",
 	}, {
 		Name: "no ready revision",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		Objects: []runtime.Object{
 			simpleRunLatest("default", "no-ready-revision", "the-config", WithStatusTraffic()),
 			simpleConfig("default", "the-config", WithLatestReady("")),
@@ -139,7 +131,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/no-ready-revision",
 	}, {
 		Name: "transitioning route",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		Objects: []runtime.Object{
 			simpleRunLatest("default", "transitioning-route", "old", WithRouteFinalizer,
 				WithSpecTraffic(configTraffic("new"))),
@@ -160,7 +151,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/transitioning-route",
 	}, {
 		Name: "failure adding annotation (revision)",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		// Induce a failure during patching
 		WantErr: true,
 		WithReactors: []clientgotesting.ReactionFunc{
@@ -182,7 +172,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/add-label-failure",
 	}, {
 		Name: "failure adding annotation (configuration)",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		// Induce a failure during patching
 		WantErr: true,
 		WithReactors: []clientgotesting.ReactionFunc{
@@ -206,7 +195,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/add-label-failure",
 	}, {
 		Name: "delete route existing ann",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		Objects: []runtime.Object{
 			simpleRunLatest("default", "delete-route", "the-config", WithRouteFinalizer, WithRouteDeletionTimestamp(&now)),
 			simpleConfig("default", "the-config",
@@ -222,7 +210,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/delete-route",
 	}, {
 		Name: "change configurations",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		Objects: []runtime.Object{
 			simpleRunLatest("default", "config-change", "new-config", WithRouteFinalizer),
 			simpleConfig("default", "old-config",
@@ -243,7 +230,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/config-change",
 	}, {
 		Name: "update configuration",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		Objects: []runtime.Object{
 			simpleRunLatest("default", "config-update", "the-config", WithRouteFinalizer),
 			simpleConfig("default", "the-config",
@@ -262,7 +248,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/config-update",
 	}, {
 		Name: "delete route",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		Objects: []runtime.Object{
 			simpleRunLatest("default", "delete-route", "the-config", WithRouteFinalizer, WithRouteDeletionTimestamp(&now)),
 			simpleConfig("default", "the-config",
@@ -278,7 +263,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/delete-route",
 	}, {
 		Name:    "delete route failure",
-		Ctx:     setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		WantErr: true,
 		WithReactors: []clientgotesting.ReactionFunc{
 			InduceFailure("patch", "configurations"),
@@ -298,7 +282,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/delete-route",
 	}, {
 		Name: "failure while removing a cfg annotation should return an error",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		// Induce a failure during patching
 		WantErr: true,
 		WithReactors: []clientgotesting.ReactionFunc{
@@ -326,7 +309,6 @@ func TestV2Reconcile(t *testing.T) {
 		Key: "default/delete-label-failure",
 	}, {
 		Name: "failure while removing a rev annotation should return an error",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
 		// Induce a failure during patching
 		WantErr: true,
 		WithReactors: []clientgotesting.ReactionFunc{
@@ -362,9 +344,7 @@ func TestV2Reconcile(t *testing.T) {
 		rLister := listers.GetRevisionLister()
 		rIndexer := listers.IndexerFor(&v1.Revision{})
 		r := &Reconciler{
-			caccV1: labelerv1.NewConfigurationAccessor(client, &NullTracker{}, cLister),
 			caccV2: labelerv2.NewConfigurationAccessor(client, &NullTracker{}, cLister, cIndexer, clock),
-			raccV1: labelerv1.NewRevisionAccessor(client, &NullTracker{}, rLister),
 			raccV2: labelerv2.NewRevisionAccessor(client, &NullTracker{}, rLister, rIndexer, clock),
 		}
 
@@ -534,9 +514,3 @@ func TestNew(t *testing.T) {
 		t.Fatal("Expected NewController to return a non-nil value")
 	}
 }
-
-func setResponsiveGCFeature(ctx context.Context, flag cfgmap.Flag) context.Context {
-	c := config.FromContextOrDefaults(ctx)
-	c.Features.ResponsiveRevisionGC = flag
-	return config.ToContext(ctx, c)
-}
diff --git a/pkg/reconciler/revision/resources/imagecache_test.go b/pkg/reconciler/revision/resources/imagecache_test.go
index dc0345f4e..a1155a972 100644
--- a/pkg/reconciler/revision/resources/imagecache_test.go
+++ b/pkg/reconciler/revision/resources/imagecache_test.go
@@ -43,8 +43,7 @@ func TestMakeImageCache(t *testing.T) {
 				Namespace: "foo",
 				Name:      "bar",
 				Annotations: map[string]string{
-					"a":                                     "b",
-					serving.RevisionLastPinnedAnnotationKey: "c",
+					"a": "b",
 				},
 				UID: "1234",
 			},
@@ -98,8 +97,7 @@ func TestMakeImageCache(t *testing.T) {
 				Namespace: "foo",
 				Name:      "bar",
 				Annotations: map[string]string{
-					"a":                                     "b",
-					serving.RevisionLastPinnedAnnotationKey: "c",
+					"a": "b",
 				},
 				UID: "1234",
 			},
@@ -161,8 +159,7 @@ func TestMakeImageCache(t *testing.T) {
 				Namespace: "foo",
 				Name:      "bar",
 				Annotations: map[string]string{
-					"a":                                     "b",
-					serving.RevisionLastPinnedAnnotationKey: "c",
+					"a": "b",
 				},
 				UID: "1234",
 			},
diff --git a/pkg/reconciler/revision/resources/pa_test.go b/pkg/reconciler/revision/resources/pa_test.go
index 88ec41f03..a1290ebb1 100644
--- a/pkg/reconciler/revision/resources/pa_test.go
+++ b/pkg/reconciler/revision/resources/pa_test.go
@@ -44,11 +44,10 @@ func TestMakePA(t *testing.T) {
 					Name:      "bar",
 					UID:       "1234",
 					Labels: map[string]string{
-						serving.RouteLabelKey: "some-route",
+						serving.RoutingStateLabelKey: "active",
 					},
 					Annotations: map[string]string{
-						"a":                                     "b",
-						serving.RevisionLastPinnedAnnotationKey: "timeless",
+						"a": "b",
 					},
 				},
 				Spec: v1.RevisionSpec{
@@ -260,7 +259,7 @@ func TestMakePA(t *testing.T) {
 					Name:      "robin",
 					UID:       "4321",
 					Labels: map[string]string{
-						serving.RouteLabelKey: "asdf",
+						serving.RoutingStateLabelKey: "active",
 					},
 				},
 				Spec: v1.RevisionSpec{
diff --git a/pkg/reconciler/revision/table_test.go b/pkg/reconciler/revision/table_test.go
index b7d821d89..5f11ff0db 100644
--- a/pkg/reconciler/revision/table_test.go
+++ b/pkg/reconciler/revision/table_test.go
@@ -38,7 +38,6 @@ import (
 	tracingconfig "knative.dev/pkg/tracing/config"
 	asv1a1 "knative.dev/serving/pkg/apis/autoscaling/v1alpha1"
 	defaultconfig "knative.dev/serving/pkg/apis/config"
-	"knative.dev/serving/pkg/apis/serving"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
 	"knative.dev/serving/pkg/autoscaler/config/autoscalerconfig"
 	servingclient "knative.dev/serving/pkg/client/injection/client"
@@ -387,7 +386,7 @@ func TestReconcile(t *testing.T) {
 		Objects: []runtime.Object{
 			Revision("foo", "fix-mutated-pa",
 				WithK8sServiceName("ill-follow-the-sun"), WithLogURL, MarkRevisionReady,
-				WithRevisionLabel(serving.RouteLabelKey, "foo")),
+				WithRoutingState(v1.RoutingStateActive)),
 			pa("foo", "fix-mutated-pa", WithProtocolType(networking.ProtocolH2C),
 				WithTraffic, WithPASKSReady, WithScaleTargetInitialized, WithReachabilityReachable,
 				WithPAStatusService("fix-mutated-pa")),
@@ -400,7 +399,7 @@ func TestReconcile(t *testing.T) {
 				// When our reconciliation has to change the service
 				// we should see the following mutations to status.
 				WithK8sServiceName("fix-mutated-pa"),
-				WithRevisionLabel(serving.RouteLabelKey, "foo"), WithLogURL, MarkRevisionReady,
+				WithRoutingState(v1.RoutingStateActive), WithLogURL, MarkRevisionReady,
 				withDefaultContainerStatuses()),
 		}},
 		WantUpdates: []clientgotesting.UpdateActionImpl{{
diff --git a/pkg/reconciler/route/config/store_test.go b/pkg/reconciler/route/config/store_test.go
index 9de536ff2..c9b7b89d3 100644
--- a/pkg/reconciler/route/config/store_test.go
+++ b/pkg/reconciler/route/config/store_test.go
@@ -19,7 +19,6 @@ package config
 import (
 	"context"
 	"testing"
-	"time"
 
 	"github.com/google/go-cmp/cmp"
 	network "knative.dev/networking/pkg"
@@ -62,19 +61,6 @@ func TestStoreLoadWithContext(t *testing.T) {
 			t.Error("Unexpected controller config (-want, +got):", diff)
 		}
 	})
-
-	t.Run("gc invalid timeout", func(t *testing.T) {
-		gcConfig.Data["stale-revision-timeout"] = "1h"
-		expected, err := gc.NewConfigFromConfigMapFunc(ctx)(gcConfig)
-
-		if err != nil {
-			t.Error("Got error parsing gc config with invalid timeout:", err)
-		}
-
-		if expected.StaleRevisionTimeout != 15*time.Hour {
-			t.Errorf("Expected revision timeout of %v, got %v", 15*time.Hour, expected.StaleRevisionTimeout)
-		}
-	})
 }
 
 func TestStoreLoadWithContextOrDefaults(t *testing.T) {
diff --git a/pkg/reconciler/route/domains/domains_test.go b/pkg/reconciler/route/domains/domains_test.go
index 363fc0dcb..6cbcb39e7 100644
--- a/pkg/reconciler/route/domains/domains_test.go
+++ b/pkg/reconciler/route/domains/domains_test.go
@@ -19,7 +19,6 @@ package domains
 import (
 	"context"
 	"testing"
-	"time"
 
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
@@ -30,7 +29,6 @@ import (
 	network "knative.dev/networking/pkg"
 	"knative.dev/serving/pkg/apis/serving"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
-	"knative.dev/serving/pkg/gc"
 	"knative.dev/serving/pkg/reconciler/route/config"
 )
 
@@ -48,9 +46,6 @@ func testConfig() *config.Config {
 			DefaultIngressClass: "ingress-class-foo",
 			DomainTemplate:      network.DefaultDomainTemplate,
 		},
-		GC: &gc.Config{
-			StaleRevisionLastpinnedDebounce: 1 * time.Minute,
-		},
 	}
 }
 
diff --git a/pkg/reconciler/route/reconcile_resources_test.go b/pkg/reconciler/route/reconcile_resources_test.go
index e0f3426bf..b227c0722 100644
--- a/pkg/reconciler/route/reconcile_resources_test.go
+++ b/pkg/reconciler/route/reconcile_resources_test.go
@@ -18,9 +18,7 @@ package route
 
 import (
 	"context"
-	"errors"
 	"testing"
-	"time"
 
 	"github.com/google/go-cmp/cmp"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -29,11 +27,9 @@ import (
 	netv1alpha1 "knative.dev/networking/pkg/apis/networking/v1alpha1"
 	fakeingressinformer "knative.dev/networking/pkg/client/injection/informers/networking/v1alpha1/ingress/fake"
 	"knative.dev/pkg/ptr"
-	"knative.dev/serving/pkg/apis/serving"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
 	fakeservingclient "knative.dev/serving/pkg/client/injection/client/fake"
 	fakerevisioninformer "knative.dev/serving/pkg/client/injection/informers/serving/v1/revision/fake"
-	"knative.dev/serving/pkg/gc"
 	"knative.dev/serving/pkg/reconciler/route/config"
 	"knative.dev/serving/pkg/reconciler/route/traffic"
 
@@ -90,85 +86,14 @@ func TestReconcileIngressUpdate(t *testing.T) {
 	}
 }
 
-func TestReconcileTargetValidRevision(t *testing.T) {
-	var reconciler *Reconciler
-	ctx, _, _, _, cancel := newTestSetup(t, func(r *Reconciler) {
-		reconciler = r
-	})
-	defer cancel()
-
-	r := Route("test-ns", "test-route", WithRouteLabel(map[string]string{"route": "test-route"}))
-	rev := newTestRevision(r.Namespace, "revision")
-	tc := traffic.Config{Targets: map[string]traffic.RevisionTargets{
-		traffic.DefaultTarget: {{
-			TrafficTarget: v1.TrafficTarget{
-				RevisionName: "revision",
-				Percent:      ptr.Int64(100),
-			},
-		}}}}
-
-	ctx = config.ToContext(ctx, &config.Config{
-		GC: &gc.Config{
-			StaleRevisionLastpinnedDebounce: time.Minute,
-		},
-	})
-
-	fakeservingclient.Get(ctx).ServingV1().Revisions(r.Namespace).Create(ctx, rev, metav1.CreateOptions{})
-	fakerevisioninformer.Get(ctx).Informer().GetIndexer().Add(rev)
-
-	// Get timestamp before reconciling, so that we can compare this to the last pinned timestamp
-	// after reconciliation
-	beforeTimestamp, err := getLastPinnedTimestamp(t, rev)
-	if err != nil {
-		t.Fatal("Error getting last pinned:", err)
-	}
-
-	if err = reconciler.reconcileTargetRevisions(updateContext(ctx), &tc, r); err != nil {
-		t.Fatal("Error reconciling target revisions:", err)
-	}
-
-	// Verify last pinned annotation is updated correctly
-	newRev, err := fakeservingclient.Get(ctx).ServingV1().Revisions(r.Namespace).Get(ctx, rev.Name, metav1.GetOptions{})
-	if err != nil {
-		t.Fatal("Error getting revision:", err)
-	}
-	afterTimestamp, err := getLastPinnedTimestamp(t, newRev)
-	if err != nil {
-		t.Fatal("Error getting last pinned timestamps:", err)
-	}
-	if beforeTimestamp == afterTimestamp {
-		t.Fatal("The last pinned timestamp is not updated")
-	}
-}
-
 func TestReconcileRevisionTargetDoesNotExist(t *testing.T) {
-	var reconciler *Reconciler
-	ctx, _, _, _, cancel := newTestSetup(t, func(r *Reconciler) {
-		reconciler = r
-	})
+	ctx, _, _, _, cancel := newTestSetup(t)
 	defer cancel()
 
 	r := Route("test-ns", "test-route", WithRouteLabel(map[string]string{"route": "test-route"}))
 	rev := newTestRevision(r.Namespace, "revision")
-	tcInvalidRev := traffic.Config{Targets: map[string]traffic.RevisionTargets{
-		traffic.DefaultTarget: {{
-			TrafficTarget: v1.TrafficTarget{
-				RevisionName: "invalid-revision",
-				Percent:      ptr.Int64(100),
-			},
-		}}}}
-	ctx = config.ToContext(ctx, &config.Config{
-		GC: &gc.Config{
-			StaleRevisionLastpinnedDebounce: time.Minute,
-		},
-	})
 	fakeservingclient.Get(ctx).ServingV1().Revisions(r.Namespace).Create(ctx, rev, metav1.CreateOptions{})
 	fakerevisioninformer.Get(ctx).Informer().GetIndexer().Add(rev)
-
-	// Try reconciling target revisions for a revision that does not exist. No err should be returned
-	if err := reconciler.reconcileTargetRevisions(ctx, &tcInvalidRev, r); err != nil {
-		t.Fatal("Error reconciling target revisions:", err)
-	}
 }
 
 func newTestRevision(namespace, name string) *v1.Revision {
@@ -176,22 +101,11 @@ func newTestRevision(namespace, name string) *v1.Revision {
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      name,
 			Namespace: namespace,
-			Annotations: map[string]string{
-				serving.RevisionLastPinnedAnnotationKey: v1.RevisionLastPinnedString(time.Now().Add(-1 * time.Hour)),
-			},
 		},
 		Spec: v1.RevisionSpec{},
 	}
 }
 
-func getLastPinnedTimestamp(t *testing.T, rev *v1.Revision) (string, error) {
-	lastPinnedTime, ok := rev.Annotations[serving.RevisionLastPinnedAnnotationKey]
-	if !ok {
-		return "", errors.New("last pinned annotation not found")
-	}
-	return lastPinnedTime, nil
-}
-
 func testIngressParams(t *testing.T, r *v1.Route, trafficOpts ...func(tc *traffic.Config)) (*traffic.Config,
 	[]netv1alpha1.IngressTLS) {
 	tc := &traffic.Config{Targets: map[string]traffic.RevisionTargets{
diff --git a/pkg/reconciler/route/resources/ingress_test.go b/pkg/reconciler/route/resources/ingress_test.go
index c3e5753d5..ac1339e87 100644
--- a/pkg/reconciler/route/resources/ingress_test.go
+++ b/pkg/reconciler/route/resources/ingress_test.go
@@ -48,6 +48,8 @@ import (
 const (
 	ns = "test-ns"
 
+	emptyRollout = "{}"
+
 	testRouteName       = "test-route"
 	testAnnotationValue = "test-annotation-value"
 	testIngressClass    = "test-ingress"
@@ -78,6 +80,7 @@ func TestMakeIngressCorrectMetadata(t *testing.T) {
 		Annotations: map[string]string{
 			// Make sure to get passdownIngressClass instead of ingressClass
 			networking.IngressClassAnnotationKey: passdownIngressClass,
+			networking.RolloutAnnotationKey:      emptyRollout,
 			"test-annotation":                    "bar",
 		},
 		OwnerReferences: []metav1.OwnerReference{*kmeta.NewControllerRef(r)},
@@ -99,6 +102,15 @@ func TestMakeIngressWithRollout(t *testing.T) {
 	)
 	cfg := &traffic.Config{
 		Targets: map[string]traffic.RevisionTargets{
+			"tagged": {{
+				TrafficTarget: v1.TrafficTarget{
+					ConfigurationName: "thor",
+					LatestRevision:    ptr.Bool(true),
+					Percent:           ptr.Int64(100),
+					RevisionName:      "thor-02020",
+				},
+				ServiceName: "hammer",
+			}},
 			traffic.DefaultTarget: {{
 				TrafficTarget: v1.TrafficTarget{
 					ConfigurationName: "valhalla",
@@ -129,6 +141,7 @@ func TestMakeIngressWithRollout(t *testing.T) {
 		Annotations: map[string]string{
 			// Make sure to get passdownIngressClass instead of ingressClass
 			networking.IngressClassAnnotationKey: passdownIngressClass,
+			networking.RolloutAnnotationKey:      `{"configurations":[{"configurationName":"valhalla","percent":100,"revisions":[{"revisionName":"valhalla-01982","percent":100}]},{"configurationName":"thor","tag":"tagged","percent":100,"revisions":[{"revisionName":"thor-02020","percent":100}]}]}`,
 			"test-annotation":                    "bar",
 		},
 		OwnerReferences: []metav1.OwnerReference{*kmeta.NewControllerRef(r)},
@@ -919,6 +932,7 @@ func TestMakeIngressWithTLS(t *testing.T) {
 			Namespace: ns,
 			Annotations: map[string]string{
 				networking.IngressClassAnnotationKey: ingressClass,
+				networking.RolloutAnnotationKey:      emptyRollout,
 			},
 			Labels: map[string]string{
 				serving.RouteLabelKey:          "test-route",
diff --git a/pkg/reconciler/route/resources/service_test.go b/pkg/reconciler/route/resources/service_test.go
index 688e3a672..770a04624 100644
--- a/pkg/reconciler/route/resources/service_test.go
+++ b/pkg/reconciler/route/resources/service_test.go
@@ -19,7 +19,6 @@ package resources
 import (
 	"context"
 	"testing"
-	"time"
 
 	"github.com/google/go-cmp/cmp"
 
@@ -37,7 +36,6 @@ import (
 	apiConfig "knative.dev/serving/pkg/apis/config"
 	"knative.dev/serving/pkg/apis/serving"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
-	"knative.dev/serving/pkg/gc"
 	"knative.dev/serving/pkg/reconciler/route/config"
 	"knative.dev/serving/pkg/reconciler/route/traffic"
 
@@ -380,9 +378,6 @@ func testConfig() *config.Config {
 			DomainTemplate:      network.DefaultDomainTemplate,
 			TagTemplate:         network.DefaultTagTemplate,
 		},
-		GC: &gc.Config{
-			StaleRevisionLastpinnedDebounce: 1 * time.Minute,
-		},
 		Features: &apiConfig.Features{
 			MultiContainer:        apiConfig.Disabled,
 			PodSpecAffinity:       apiConfig.Disabled,
@@ -390,7 +385,6 @@ func testConfig() *config.Config {
 			PodSpecDryRun:         apiConfig.Enabled,
 			PodSpecNodeSelector:   apiConfig.Disabled,
 			PodSpecTolerations:    apiConfig.Disabled,
-			ResponsiveRevisionGC:  apiConfig.Disabled,
 			TagHeaderBasedRouting: apiConfig.Disabled,
 		},
 	}
diff --git a/pkg/reconciler/route/table_test.go b/pkg/reconciler/route/table_test.go
index 054439d1e..0afc597e1 100644
--- a/pkg/reconciler/route/table_test.go
+++ b/pkg/reconciler/route/table_test.go
@@ -18,6 +18,7 @@ package route
 
 import (
 	"context"
+	"encoding/json"
 	"fmt"
 	"testing"
 	"time"
@@ -47,7 +48,6 @@ import (
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
 	servingclient "knative.dev/serving/pkg/client/injection/client/fake"
 	routereconciler "knative.dev/serving/pkg/client/injection/reconciler/serving/v1/route"
-	"knative.dev/serving/pkg/gc"
 	kaccessor "knative.dev/serving/pkg/reconciler/accessor"
 	"knative.dev/serving/pkg/reconciler/route/config"
 	"knative.dev/serving/pkg/reconciler/route/resources"
@@ -1722,112 +1722,6 @@ func TestReconcile(t *testing.T) {
 	}))
 }
 
-func TestReconcileResponsiveGC(t *testing.T) {
-	table := TableTest{{
-		Name: "Update stale lastPinned",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Disabled),
-		Objects: []runtime.Object{
-			Route("default", "stale-lastpinned", WithConfigTarget("config"),
-				WithURL, WithAddress, WithRouteConditionsAutoTLSDisabled,
-				MarkTrafficAssigned, MarkIngressReady, WithRouteFinalizer,
-				WithRouteGeneration(1), WithRouteObservedGeneration,
-				WithStatusTraffic(
-					v1.TrafficTarget{
-						RevisionName:   "config-00001",
-						Percent:        ptr.Int64(100),
-						LatestRevision: ptr.Bool(true),
-					})),
-			cfg("default", "config",
-				WithConfigGeneration(1), WithLatestCreated("config-00001"), WithLatestReady("config-00001"),
-				// The Route controller attaches our label to this Configuration.
-				WithConfigLabel("serving.knative.dev/route", "stale-lastpinned"),
-			),
-			rev("default", "config", 1, MarkRevisionReady,
-				WithRevName("config-00001"),
-				WithLastPinned(fakeCurTime.Add(-10*time.Minute))),
-			simpleReadyIngress(
-				Route("default", "stale-lastpinned", WithConfigTarget("config"), WithURL),
-				&traffic.Config{
-					Targets: map[string]traffic.RevisionTargets{
-						traffic.DefaultTarget: {{
-							TrafficTarget: v1.TrafficTarget{
-								RevisionName:      "config-00001",
-								ConfigurationName: "config",
-								LatestRevision:    ptr.Bool(true),
-								Percent:           ptr.Int64(100),
-							},
-						}},
-					},
-				},
-			),
-			simpleK8sService(Route("default", "stale-lastpinned", WithConfigTarget("config"))),
-		},
-		WantPatches: []clientgotesting.PatchActionImpl{
-			patchLastPinned("default", "config-00001"),
-		},
-		Key: "default/stale-lastpinned",
-	}, {
-		Name: "lastPinned update disabled",
-		Ctx:  setResponsiveGCFeature(context.Background(), cfgmap.Enabled),
-		Objects: []runtime.Object{
-			Route("default", "stale-lastpinned", WithConfigTarget("config"),
-				WithURL, WithAddress, WithRouteConditionsAutoTLSDisabled,
-				MarkTrafficAssigned, MarkIngressReady, WithRouteFinalizer,
-				WithRouteGeneration(1), WithRouteObservedGeneration,
-				WithStatusTraffic(
-					v1.TrafficTarget{
-						RevisionName:   "config-00001",
-						Percent:        ptr.Int64(100),
-						LatestRevision: ptr.Bool(true),
-					})),
-			cfg("default", "config",
-				WithConfigGeneration(1), WithLatestCreated("config-00001"), WithLatestReady("config-00001"),
-				// The Route controller attaches our label to this Configuration.
-				WithConfigLabel("serving.knative.dev/route", "stale-lastpinned"),
-			),
-			rev("default", "config", 1, MarkRevisionReady,
-				WithRevName("config-00001")),
-			simpleReadyIngress(
-				Route("default", "stale-lastpinned", WithConfigTarget("config"), WithURL),
-				&traffic.Config{
-					Targets: map[string]traffic.RevisionTargets{
-						traffic.DefaultTarget: {{
-							TrafficTarget: v1.TrafficTarget{
-								ConfigurationName: "config",
-								LatestRevision:    ptr.Bool(true),
-								// Use the Revision name from the config.
-								RevisionName: "config-00001",
-								Percent:      ptr.Int64(100),
-							},
-						}},
-					},
-				},
-			),
-			simpleK8sService(Route("default", "stale-lastpinned", WithConfigTarget("config"))),
-		},
-		// WantPatches: Expecting no patch for when disabled.
-		Key: "default/stale-lastpinned",
-	}}
-
-	table.Test(t, MakeFactory(func(ctx context.Context, listers *Listers, cmw configmap.Watcher) controller.Reconciler {
-		r := &Reconciler{
-			kubeclient:          kubeclient.Get(ctx),
-			client:              servingclient.Get(ctx),
-			netclient:           networkingclient.Get(ctx),
-			configurationLister: listers.GetConfigurationLister(),
-			revisionLister:      listers.GetRevisionLister(),
-			serviceLister:       listers.GetK8sServiceLister(),
-			ingressLister:       listers.GetIngressLister(),
-			tracker:             ctx.Value(TrackerKey).(tracker.Interface),
-			clock:               FakeClock{Time: fakeCurTime},
-		}
-
-		return routereconciler.NewReconciler(ctx, logging.FromContext(ctx), servingclient.Get(ctx),
-			listers.GetRouteLister(), controller.GetEventRecorder(ctx), r,
-			controller.Options{ConfigStore: &testConfigStore{config: reconcilerTestConfig(false)}})
-	}))
-}
-
 func TestReconcileEnableAutoTLS(t *testing.T) {
 	table := TableTest{{
 		Name: "check that existing wildcard cert is used when creating a Route",
@@ -2561,13 +2455,7 @@ func ingressWithClass(r *v1.Route, tc *traffic.Config, class string, io ...Ingre
 }
 
 func baseIngressWithClass(r *v1.Route, tc *traffic.Config, class string, io ...IngressOption) *netv1alpha1.Ingress {
-	ingress, _ := resources.MakeIngress(getContext(), r, tc, nil, class)
-
-	// By default attach current rollout.
-	ro := tc.BuildRollout()
-	ingress.Annotations = kmeta.UnionMaps(ingress.Annotations, map[string]string{
-		networking.RolloutAnnotationKey: serializeRollout(context.Background(), ro),
-	})
+	ingress, _ := resources.MakeIngress(getContext(), r, tc, nil /*tls*/, class)
 
 	for _, opt := range io {
 		opt(ingress)
@@ -2583,12 +2471,6 @@ func ingressWithTLS(r *v1.Route, tc *traffic.Config, tls []netv1alpha1.IngressTL
 func baseIngressWithTLS(r *v1.Route, tc *traffic.Config, tls []netv1alpha1.IngressTLS, challenges []netv1alpha1.HTTP01Challenge, io ...IngressOption) *netv1alpha1.Ingress {
 	ingress, _ := resources.MakeIngress(getContext(), r, tc, tls, TestIngressClass, challenges...)
 
-	// By default attach current rollout.
-	ro := tc.BuildRollout()
-	ingress.Annotations = kmeta.UnionMaps(ingress.Annotations, map[string]string{
-		networking.RolloutAnnotationKey: serializeRollout(context.Background(), ro),
-	})
-
 	for _, opt := range io {
 		opt(ingress)
 	}
@@ -2636,24 +2518,10 @@ func mutateIngress(ci *netv1alpha1.Ingress) *netv1alpha1.Ingress {
 	return ci
 }
 
-func patchLastPinned(namespace, name string) clientgotesting.PatchActionImpl {
-	action := clientgotesting.PatchActionImpl{}
-	action.Name = name
-	action.Namespace = namespace
-	lastPinStr := v1.RevisionLastPinnedString(fakeCurTime)
-	patch := fmt.Sprintf(`{"metadata":{"annotations":{"serving.knative.dev/lastPinned":%q}}}`, lastPinStr)
-	action.Patch = []byte(patch)
-	return action
-}
-
 func rev(namespace, name string, generation int64, ro ...RevisionOption) *v1.Revision {
 	r := &v1.Revision{
 		ObjectMeta: metav1.ObjectMeta{
 			Namespace: namespace,
-			Annotations: map[string]string{
-				"serving.knative.dev/lastPinned": v1.RevisionLastPinnedString(
-					fakeCurTime.Add(-1 * time.Second)),
-			},
 			OwnerReferences: []metav1.OwnerReference{{
 				APIVersion:         v1.SchemeGroupVersion.String(),
 				Kind:               "Configuration",
@@ -2697,9 +2565,6 @@ func reconcilerTestConfig(enableAutoTLS bool) *config.Config {
 			TagTemplate:             network.DefaultTagTemplate,
 			HTTPProtocol:            network.HTTPEnabled,
 		},
-		GC: &gc.Config{
-			StaleRevisionLastpinnedDebounce: 1 * time.Minute,
-		},
 		Features: &cfgmap.Features{
 			MultiContainer:        cfgmap.Disabled,
 			PodSpecAffinity:       cfgmap.Disabled,
@@ -2707,7 +2572,6 @@ func reconcilerTestConfig(enableAutoTLS bool) *config.Config {
 			PodSpecDryRun:         cfgmap.Enabled,
 			PodSpecNodeSelector:   cfgmap.Disabled,
 			PodSpecTolerations:    cfgmap.Disabled,
-			ResponsiveRevisionGC:  cfgmap.Disabled,
 			TagHeaderBasedRouting: cfgmap.Disabled,
 		},
 	}
@@ -2739,12 +2603,6 @@ func url(s string) *apis.URL {
 	return url
 }
 
-func setResponsiveGCFeature(ctx context.Context, flag cfgmap.Flag) context.Context {
-	c := cfgmap.FromContextOrDefaults(ctx)
-	c.Features.ResponsiveRevisionGC = flag
-	return cfgmap.ToContext(ctx, c)
-}
-
 func simpleRollout(cfg string, revs []traffic.RevisionRollout) IngressOption {
 	return func(i *netv1alpha1.Ingress) {
 		r := &traffic.Rollout{
@@ -2754,7 +2612,9 @@ func simpleRollout(cfg string, revs []traffic.RevisionRollout) IngressOption {
 				Revisions:         revs,
 			}},
 		}
-		ro := serializeRollout(context.Background(), r)
-		i.Annotations[networking.RolloutAnnotationKey] = ro
+		i.Annotations[networking.RolloutAnnotationKey] = func() string {
+			d, _ := json.Marshal(r)
+			return string(d)
+		}()
 	}
 }
diff --git a/pkg/reconciler/route/traffic/traffic_test.go b/pkg/reconciler/route/traffic/traffic_test.go
index 6f610d74c..828e7122b 100644
--- a/pkg/reconciler/route/traffic/traffic_test.go
+++ b/pkg/reconciler/route/traffic/traffic_test.go
@@ -22,7 +22,6 @@ import (
 	"fmt"
 	"os"
 	"testing"
-	"time"
 
 	"github.com/davecgh/go-spew/spew"
 	"github.com/google/go-cmp/cmp"
@@ -38,7 +37,6 @@ import (
 	fakeclientset "knative.dev/serving/pkg/client/clientset/versioned/fake"
 	informers "knative.dev/serving/pkg/client/informers/externalversions"
 	listers "knative.dev/serving/pkg/client/listers/serving/v1"
-	"knative.dev/serving/pkg/gc"
 	"knative.dev/serving/pkg/reconciler/route/config"
 	"knative.dev/serving/pkg/reconciler/route/domains"
 	. "knative.dev/serving/pkg/testing/v1"
@@ -1511,8 +1509,5 @@ func testNetworkConfig() *config.Config {
 			DomainTemplate:      network.DefaultDomainTemplate,
 			TagTemplate:         network.DefaultTagTemplate,
 		},
-		GC: &gc.Config{
-			StaleRevisionLastpinnedDebounce: 1 * time.Minute,
-		},
 	}
 }
diff --git a/pkg/reconciler/service/resources/configuration_test.go b/pkg/reconciler/service/resources/configuration_test.go
index 44fd87f15..34f955d43 100644
--- a/pkg/reconciler/service/resources/configuration_test.go
+++ b/pkg/reconciler/service/resources/configuration_test.go
@@ -21,10 +21,7 @@ import (
 
 	corev1 "k8s.io/api/core/v1"
 
-	cfgmap "knative.dev/serving/pkg/apis/config"
 	"knative.dev/serving/pkg/apis/serving"
-	v1 "knative.dev/serving/pkg/apis/serving/v1"
-	"knative.dev/serving/pkg/reconciler/service/resources/names"
 )
 
 func TestConfigurationSpec(t *testing.T) {
@@ -49,31 +46,6 @@ func TestConfigurationSpec(t *testing.T) {
 	}
 }
 
-func TestConfigurationSpecGCAllowed(t *testing.T) {
-	s := createService()
-	c, _ := MakeConfigurationFromExisting(s, &v1.Configuration{}, cfgmap.Allowed)
-	if got, want := c.Name, testServiceName; got != want {
-		t.Errorf("expected %q for service name got %q", want, got)
-	}
-	if got, want := c.Namespace, testServiceNamespace; got != want {
-		t.Errorf("expected %q for service namespace got %q", want, got)
-	}
-	if got, want := c.Spec.GetTemplate().Spec.GetContainer().Name, testContainerName; got != want {
-		t.Errorf("expected %q for container name got %q", want, got)
-	}
-	expectOwnerReferencesSetCorrectly(t, c.OwnerReferences)
-
-	if got, want := len(c.Labels), 2; got != want {
-		t.Errorf("expected %d labels got %d", want, got)
-	}
-	if got, want := c.Labels[serving.ServiceLabelKey], testServiceName; got != want {
-		t.Errorf("expected %q labels got %q", want, got)
-	}
-	if got, want := c.Annotations[serving.RoutesAnnotationKey], names.Route(s); got != want {
-		t.Errorf("expected %q route annotation got %q", want, got)
-	}
-}
-
 func TestConfigurationHasNoKubectlAnnotation(t *testing.T) {
 	s := createServiceWithKubectlAnnotation()
 	c, err := MakeConfiguration(s)
diff --git a/pkg/testing/v1/revision.go b/pkg/testing/v1/revision.go
index 7bd4f1248..409370408 100644
--- a/pkg/testing/v1/revision.go
+++ b/pkg/testing/v1/revision.go
@@ -87,13 +87,6 @@ func WithCreationTimestamp(t time.Time) RevisionOption {
 	}
 }
 
-// WithLastPinned updates the "last pinned" annotation to the provided timestamp.
-func WithLastPinned(t time.Time) RevisionOption {
-	return func(rev *v1.Revision) {
-		rev.SetLastPinned(t)
-	}
-}
-
 // WithRevisionPreserveAnnotation updates the annotation with preserve key.
 func WithRevisionPreserveAnnotation() RevisionOption {
 	return func(rev *v1.Revision) {
diff --git a/test/e2e-auto-tls-tests.sh b/test/e2e-auto-tls-tests.sh
index 824999b97..1997deb73 100755
--- a/test/e2e-auto-tls-tests.sh
+++ b/test/e2e-auto-tls-tests.sh
@@ -166,7 +166,7 @@ initialize "$@" --skip-istio-addon --min-nodes=4 --max-nodes=4
 
 header "Enabling high-availability"
 
-scale_controlplane controller autoscaler-hpa webhook
+scale_controlplane "${HA_COMPONENTS[@]}"
 
 # Wait for a new leader Controller to prevent race conditions during service reconciliation
 wait_for_leader_controller || failed=1
diff --git a/test/v1/revision.go b/test/v1/revision.go
index ea409f06a..8ebbdaa3e 100644
--- a/test/v1/revision.go
+++ b/test/v1/revision.go
@@ -80,14 +80,7 @@ func IsRevisionReady(r *v1.Revision) (bool, error) {
 // IsRevisionRoutingActive will check if the revision is actively routing to a route.
 func IsRevisionRoutingActive(r *v1.Revision) (bool, error) {
 	routingState := r.Labels[serving.RoutingStateLabelKey]
-	if v1.RoutingState(routingState) == v1.RoutingStateActive {
-		return true, nil
-	}
-
-	// TODO(whaught): remove this fallback as we remove the lastPinned annotation
-	// Fallback to lastPinned - this is needed for downgrade tests where the annotation still exists.
-	_, pinned := r.Annotations[serving.RevisionLastPinnedAnnotationKey]
-	return pinned, nil
+	return v1.RoutingState(routingState) == v1.RoutingStateActive, nil
 }
 
 // IsRevisionAtExpectedGeneration returns a function that will check if the annotations
diff --git a/third_party/cert-manager-latest/net-certmanager.yaml b/third_party/cert-manager-latest/net-certmanager.yaml
index 43bb920b1..66516ffac 100644
--- a/third_party/cert-manager-latest/net-certmanager.yaml
+++ b/third_party/cert-manager-latest/net-certmanager.yaml
@@ -18,7 +18,7 @@ metadata:
   # These are the permissions needed by the `cert-manager` `Certificate` implementation.
   name: knative-serving-certmanager
   labels:
-    serving.knative.dev/release: "v20201110-859a9fd"
+    serving.knative.dev/release: "v20201117-065c199"
     serving.knative.dev/controller: "true"
     networking.knative.dev/certificate-provider: cert-manager
 rules:
@@ -49,7 +49,7 @@ kind: ValidatingWebhookConfiguration
 metadata:
   name: config.webhook.net-certmanager.networking.internal.knative.dev
   labels:
-    serving.knative.dev/release: "v20201110-859a9fd"
+    serving.knative.dev/release: "v20201117-065c199"
 webhooks:
   - admissionReviewVersions:
       - v1beta1
@@ -86,7 +86,7 @@ metadata:
   name: net-certmanager-webhook-certs
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201110-859a9fd"
+    serving.knative.dev/release: "v20201117-065c199"
 
 ---
 # Copyright 2020 The Knative Authors
@@ -109,7 +109,7 @@ metadata:
   name: config-certmanager
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201110-859a9fd"
+    serving.knative.dev/release: "v20201117-065c199"
     networking.knative.dev/certificate-provider: cert-manager
 data:
   _example: |
@@ -156,7 +156,7 @@ metadata:
   name: networking-certmanager
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201110-859a9fd"
+    serving.knative.dev/release: "v20201117-065c199"
     networking.knative.dev/certificate-provider: cert-manager
 spec:
   selector:
@@ -168,14 +168,14 @@ spec:
         cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
       labels:
         app: networking-certmanager
-        serving.knative.dev/release: "v20201110-859a9fd"
+        serving.knative.dev/release: "v20201117-065c199"
     spec:
       serviceAccountName: controller
       containers:
         - name: networking-certmanager
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/controller@sha256:385ddbf5b1799b16cf6f0a1aed0b7f26fd2aabe017fb7f83a9632168bc9f7ed1
+          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/controller@sha256:ef1ebde73534b3f75886180887566f8b3d03855e8402e0e70bc519ebae9f8d5e
           resources:
             requests:
               cpu: 30m
@@ -213,7 +213,7 @@ kind: Service
 metadata:
   labels:
     app: networking-certmanager
-    serving.knative.dev/release: "v20201110-859a9fd"
+    serving.knative.dev/release: "v20201117-065c199"
     networking.knative.dev/certificate-provider: cert-manager
   name: networking-certmanager
   namespace: knative-serving
@@ -250,7 +250,7 @@ metadata:
   name: net-certmanager-webhook
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201110-859a9fd"
+    serving.knative.dev/release: "v20201117-065c199"
 spec:
   selector:
     matchLabels:
@@ -263,14 +263,14 @@ spec:
       labels:
         app: net-certmanager-webhook
         role: net-certmanager-webhook
-        serving.knative.dev/release: "v20201110-859a9fd"
+        serving.knative.dev/release: "v20201117-065c199"
     spec:
       serviceAccountName: controller
       containers:
         - name: webhook
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/webhook@sha256:e6843cdc1adb80952c88946abad7e1eedca64cab7d6787adb7f82ad02bb72a7f
+          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/webhook@sha256:8d3716b5034e8222061d4818ff88246b34e6eaf52dfb188a9a2f7cee4629792a
           resources:
             requests:
               cpu: 20m
@@ -329,7 +329,7 @@ metadata:
   namespace: knative-serving
   labels:
     role: net-certmanager-webhook
-    serving.knative.dev/release: "v20201110-859a9fd"
+    serving.knative.dev/release: "v20201117-065c199"
 spec:
   ports:
     # Define metrics and profiling for them to be accessible within service meshes.
diff --git a/third_party/contour-latest/contour.yaml b/third_party/contour-latest/contour.yaml
index 62e0a8f5a..7e094a6c8 100644
--- a/third_party/contour-latest/contour.yaml
+++ b/third_party/contour-latest/contour.yaml
@@ -1482,7 +1482,7 @@ spec:
     spec:
       containers:
         - name: contour
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:77ac49282a903f7f3979531f8cd75bf9aa7d0ccbc4585dcc4e461cb732be77f5
           imagePullPolicy: Always
           command:
             - contour
@@ -1709,7 +1709,7 @@ spec:
             - --contour-key-file=/certs/tls.key
             - --config-path=/config/contour.yaml
           command: ["contour"]
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:77ac49282a903f7f3979531f8cd75bf9aa7d0ccbc4585dcc4e461cb732be77f5
           imagePullPolicy: IfNotPresent
           name: contour
           ports:
@@ -1795,7 +1795,7 @@ spec:
           args:
             - envoy
             - shutdown-manager
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:77ac49282a903f7f3979531f8cd75bf9aa7d0ccbc4585dcc4e461cb732be77f5
           imagePullPolicy: IfNotPresent
           lifecycle:
             preStop:
@@ -1871,7 +1871,7 @@ spec:
             - --envoy-key-file=/certs/tls.key
           command:
             - contour
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:77ac49282a903f7f3979531f8cd75bf9aa7d0ccbc4585dcc4e461cb732be77f5
           imagePullPolicy: IfNotPresent
           name: envoy-initconfig
           volumeMounts:
@@ -3381,7 +3381,7 @@ spec:
     spec:
       containers:
         - name: contour
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:77ac49282a903f7f3979531f8cd75bf9aa7d0ccbc4585dcc4e461cb732be77f5
           imagePullPolicy: Always
           command:
             - contour
@@ -3608,7 +3608,7 @@ spec:
             - --contour-key-file=/certs/tls.key
             - --config-path=/config/contour.yaml
           command: ["contour"]
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:77ac49282a903f7f3979531f8cd75bf9aa7d0ccbc4585dcc4e461cb732be77f5
           imagePullPolicy: IfNotPresent
           name: contour
           ports:
@@ -3694,7 +3694,7 @@ spec:
           args:
             - envoy
             - shutdown-manager
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:77ac49282a903f7f3979531f8cd75bf9aa7d0ccbc4585dcc4e461cb732be77f5
           imagePullPolicy: IfNotPresent
           lifecycle:
             preStop:
@@ -3770,7 +3770,7 @@ spec:
             - --envoy-key-file=/certs/tls.key
           command:
             - contour
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:77ac49282a903f7f3979531f8cd75bf9aa7d0ccbc4585dcc4e461cb732be77f5
           imagePullPolicy: IfNotPresent
           name: envoy-initconfig
           volumeMounts:
diff --git a/third_party/contour-latest/net-contour.yaml b/third_party/contour-latest/net-contour.yaml
index 4c8ff5388..c4d0f2fb2 100644
--- a/third_party/contour-latest/net-contour.yaml
+++ b/third_party/contour-latest/net-contour.yaml
@@ -34,7 +34,7 @@ metadata:
   namespace: knative-serving
   labels:
     networking.knative.dev/ingress-provider: contour
-    serving.knative.dev/release: "v20201114-2ae0c66f"
+    serving.knative.dev/release: "v20201117-0db0cb4c"
 data:
   _example: |
     ################################
@@ -105,7 +105,7 @@ spec:
         - name: controller
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-contour/cmd/controller@sha256:6a1866086c4ee0570306239ece6d0a95504042b50c081f39516247063f3e341a
+          image: gcr.io/knative-nightly/knative.dev/net-contour/cmd/controller@sha256:7624c3e445ba06ad75c4d427779d41e2bf82cdc8404bf3aefdaa4a58db3a5ab4
           resources:
             requests:
               cpu: 40m
diff --git a/third_party/istio-latest/net-istio.yaml b/third_party/istio-latest/net-istio.yaml
index fe5004350..341ce03d6 100644
--- a/third_party/istio-latest/net-istio.yaml
+++ b/third_party/istio-latest/net-istio.yaml
@@ -1,4 +1,4 @@
-# Generated when HEAD was cbc1a3d4e2ab6826fc042e3dad501c24d26dc327
+# Generated when HEAD was 7d1ed7ad8c91d140ebf046b099bba37c1f5cc412
 #
 # Copyright 2019 The Knative Authors
 #
@@ -20,7 +20,7 @@ metadata:
   # These are the permissions needed by the Istio Ingress implementation.
   name: knative-serving-istio
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     serving.knative.dev/controller: "true"
     networking.knative.dev/ingress-provider: istio
 rules:
@@ -50,7 +50,7 @@ metadata:
   name: knative-ingress-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -87,7 +87,7 @@ metadata:
   name: cluster-local-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -106,7 +106,7 @@ metadata:
   name: knative-local-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -125,7 +125,7 @@ metadata:
   name: knative-local-gateway
   namespace: istio-system
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 spec:
   type: ClusterIP
@@ -145,7 +145,7 @@ metadata:
   name: "webhook"
   namespace: "knative-serving"
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -160,7 +160,7 @@ metadata:
   name: "istio-webhook"
   namespace: "knative-serving"
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -189,7 +189,7 @@ kind: MutatingWebhookConfiguration
 metadata:
   name: webhook.istio.networking.internal.knative.dev
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 webhooks:
   - admissionReviewVersions:
@@ -225,7 +225,7 @@ kind: ValidatingWebhookConfiguration
 metadata:
   name: config.webhook.istio.networking.internal.knative.dev
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 webhooks:
   - admissionReviewVersions:
@@ -263,7 +263,7 @@ metadata:
   name: istio-webhook-certs
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 
 ---
@@ -287,7 +287,7 @@ metadata:
   name: config-istio
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 data:
   _example: |
@@ -357,7 +357,7 @@ metadata:
   name: networking-istio
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -373,14 +373,14 @@ spec:
         sidecar.istio.io/inject: "false"
       labels:
         app: networking-istio
-        serving.knative.dev/release: "v20201111-cbc1a3d4"
+        serving.knative.dev/release: "v20201117-7d1ed7ad"
     spec:
       serviceAccountName: controller
       containers:
         - name: networking-istio
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/controller@sha256:604660e3e300ae8e4ebb92724cefea9eb14d997b664ec9cf76be2efc5c86bf20
+          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/controller@sha256:9773631ff1474a6373e4e1b27b4e238893b77bfb76b70b81c4ae9f96e5b59588
           resources:
             requests:
               cpu: 30m
@@ -437,7 +437,7 @@ metadata:
   name: istio-webhook
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -451,14 +451,14 @@ spec:
       labels:
         app: istio-webhook
         role: istio-webhook
-        serving.knative.dev/release: "v20201111-cbc1a3d4"
+        serving.knative.dev/release: "v20201117-7d1ed7ad"
     spec:
       serviceAccountName: controller
       containers:
         - name: webhook
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/webhook@sha256:17bc9958b175fb5d58995d35614bae730fbe84bdc48b7adacdad2f556c78d9d6
+          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/webhook@sha256:03889833812b7843d903313b0fba545962f2b938254daaad495cd1d38c61a9f1
           resources:
             requests:
               cpu: 20m
@@ -512,7 +512,7 @@ metadata:
   namespace: knative-serving
   labels:
     role: istio-webhook
-    serving.knative.dev/release: "v20201111-cbc1a3d4"
+    serving.knative.dev/release: "v20201117-7d1ed7ad"
     networking.knative.dev/ingress-provider: istio
 spec:
   ports: