In PV0, we do not propagate the necessary information to secondaries for them to advance their commit point. We still, however, keep around a list of stable optime candidates that we add to every time we update our lastApplied optime. Normally, we can purge timestamps from this list that are earlier than the stable timestamp (which is the latest timestamp in this list earlier than the commit point), since we don't need them any more. If the commit point never moves on secondaries, though, this list will never get purged, and it will grow without bound.
To avoid keeping around an unbounded amount of storage engine history in PV0, we already manually advance the storage engine's stable timestamp to whatever the lastApplied timestamp is. We should do something similar for the stable optime candidate list. For PV0 secondaries it should likely be sufficient to keep no stable optime candidates in this list. When we become a primary, we can then start adding optimes to this list, and purging them appropriately since we advance the commit point as a primary. Upon protocol version upgrade from PV0 => PV1, we will start without any stable optime candidates. We can then start adding optime candidates when we start applying writes in PV1, and set a new stable timestamp as soon as we learn of a commit point later than one of our candidates.
This only applies to 3.6, which is where we first added the "stable optime candidate" list. Protocol version 0 is banned in versions >= 4.0 as of