[VF] updates includes addressing Ukraine labels

Closes twitter/the-algorithm#1489
Closes twitter/the-algorithm#1524
Closes twitter/the-algorithm#1659
Closes twitter/the-algorithm#1520
This commit is contained in:
twitter-team 2023-04-04 16:27:41 -04:00
parent bb095608b7
commit 3f6974687f
14 changed files with 105 additions and 106 deletions

View file

@ -494,6 +494,9 @@ visibility_library_enable_trends_representative_tweet_safety_level:
visibility_library_enable_trusted_friends_user_list_safety_level:
default_availability: 10000
visibility_library_enable_twitter_delegate_user_list_safety_level:
default_availability: 10000
visibility_library_enable_tweet_detail_safety_level:
default_availability: 10000
@ -758,7 +761,7 @@ visibility_library_enable_short_circuiting_from_blender_visibility_library:
visibility_library_enable_short_circuiting_from_search_visibility_library:
default_availability: 0
visibility_library_enable_nsfw_text_topics_drop_rule:
visibility_library_enable_nsfw_text_high_precision_drop_rule:
default_availability: 10000
visibility_library_enable_spammy_tweet_rule_verdict_logging:

View file

@ -535,6 +535,9 @@ private[visibility] object DeciderKey extends DeciderKeyEnum {
val EnableTrustedFriendsUserListSafetyLevel: Value = Value(
"visibility_library_enable_trusted_friends_user_list_safety_level"
)
val EnableTwitterDelegateUserListSafetyLevel: Value = Value(
"visibility_library_enable_twitter_delegate_user_list_safety_level"
)
val EnableTweetDetailSafetyLevel: Value = Value(
"visibility_library_enable_tweet_detail_safety_level"
)
@ -869,8 +872,8 @@ private[visibility] object DeciderKey extends DeciderKeyEnum {
"visibility_library_enable_short_circuiting_from_search_visibility_library"
)
val EnableNsfwTextTopicsDropRule: Value = Value(
"visibility_library_enable_nsfw_text_topics_drop_rule"
val EnableNsfwTextHighPrecisionDropRule: Value = Value(
"visibility_library_enable_nsfw_text_high_precision_drop_rule"
)
val EnableSpammyTweetRuleVerdictLogging: Value = Value(

View file

@ -198,6 +198,7 @@ private[visibility] object VisibilityDeciders {
TopicRecommendations -> DeciderKey.EnableTopicRecommendationsSafetyLevel,
TrendsRepresentativeTweet -> DeciderKey.EnableTrendsRepresentativeTweetSafetyLevel,
TrustedFriendsUserList -> DeciderKey.EnableTrustedFriendsUserListSafetyLevel,
TwitterDelegateUserList -> DeciderKey.EnableTwitterDelegateUserListSafetyLevel,
TweetDetail -> DeciderKey.EnableTweetDetailSafetyLevel,
TweetDetailNonToo -> DeciderKey.EnableTweetDetailNonTooSafetyLevel,
TweetEngagers -> DeciderKey.EnableTweetEngagersSafetyLevel,
@ -287,7 +288,7 @@ private[visibility] object VisibilityDeciders {
RuleParams.EnableDropAllTrustedFriendsTweetsRuleParam -> DeciderKey.EnableDropAllTrustedFriendsTweetsRule,
RuleParams.EnableDropTrustedFriendsTweetContentRuleParam -> DeciderKey.EnableDropTrustedFriendsTweetContentRule,
RuleParams.EnableDropAllCollabInvitationTweetsRuleParam -> DeciderKey.EnableDropCollabInvitationTweetsRule,
RuleParams.EnableNsfwTextTopicsDropRuleParam -> DeciderKey.EnableNsfwTextTopicsDropRule,
RuleParams.EnableNsfwTextHighPrecisionDropRuleParam -> DeciderKey.EnableNsfwTextHighPrecisionDropRule,
RuleParams.EnableLikelyIvsUserLabelDropRule -> DeciderKey.EnableLikelyIvsUserLabelDropRule,
RuleParams.EnableCardUriRootDomainCardDenylistRule -> DeciderKey.EnableCardUriRootDomainDenylistRule,
RuleParams.EnableCommunityNonMemberPollCardRule -> DeciderKey.EnableCommunityNonMemberPollCardRule,

View file

@ -85,7 +85,7 @@ private[visibility] object RuleParams {
object EnableDropAllCollabInvitationTweetsRuleParam extends RuleParam(false)
object EnableNsfwTextTopicsDropRuleParam extends RuleParam(false)
object EnableNsfwTextHighPrecisionDropRuleParam extends RuleParam(false)
object EnableLikelyIvsUserLabelDropRule extends RuleParam(false)

View file

@ -186,6 +186,7 @@ private[visibility] object SafetyLevelParams {
object EnableTopicRecommendationsSafetyLevelParam extends SafetyLevelParam(false)
object EnableTrendsRepresentativeTweetSafetyLevelParam extends SafetyLevelParam(false)
object EnableTrustedFriendsUserListSafetyLevelParam extends SafetyLevelParam(false)
object EnableTwitterDelegateUserListSafetyLevelParam extends SafetyLevelParam(false)
object EnableTweetDetailSafetyLevelParam extends SafetyLevelParam(false)
object EnableTweetDetailNonTooSafetyLevelParam extends SafetyLevelParam(false)
object EnableTweetDetailWithInjectionsHydrationSafetyLevelParam extends SafetyLevelParam(false)

View file

@ -143,7 +143,7 @@ class VisibilityRuleEngine private[VisibilityRuleEngine] (
builder.withRuleResult(rule, RuleResult(builder.verdict, ShortCircuited))
} else {
if (rule.fallbackActionBuilder.nonEmpty) {
if (failedFeatureDependencies.nonEmpty && rule.fallbackActionBuilder.nonEmpty) {
metricsRecorder.recordRuleFallbackAction(rule.name)
}

View file

@ -194,6 +194,7 @@ object SafetyLevel {
ThriftSafetyLevel.TopicsLandingPageTopicRecommendations -> TopicsLandingPageTopicRecommendations,
ThriftSafetyLevel.TrendsRepresentativeTweet -> TrendsRepresentativeTweet,
ThriftSafetyLevel.TrustedFriendsUserList -> TrustedFriendsUserList,
ThriftSafetyLevel.TwitterDelegateUserList -> TwitterDelegateUserList,
ThriftSafetyLevel.GryphonDecksAndColumns -> GryphonDecksAndColumns,
ThriftSafetyLevel.TweetDetail -> TweetDetail,
ThriftSafetyLevel.TweetDetailNonToo -> TweetDetailNonToo,
@ -772,6 +773,9 @@ object SafetyLevel {
case object TrustedFriendsUserList extends SafetyLevel {
override val enabledParam: SafetyLevelParam = EnableTrustedFriendsUserListSafetyLevelParam
}
case object TwitterDelegateUserList extends SafetyLevel {
override val enabledParam: SafetyLevelParam = EnableTwitterDelegateUserListSafetyLevelParam
}
case object TweetDetail extends SafetyLevel {
override val enabledParam: SafetyLevelParam = EnableTweetDetailSafetyLevelParam
}

View file

@ -379,13 +379,6 @@ object SafetyLevelGroup {
)
}
case object ProfileMixer extends SafetyLevelGroup {
override val levels: Set[SafetyLevel] = Set(
ProfileMixerMedia,
ProfileMixerFavorites,
)
}
case object Reactions extends SafetyLevelGroup {
override val levels: Set[SafetyLevel] = Set(
SignalsReactions,
@ -516,6 +509,10 @@ object SafetyLevelGroup {
SafetyLevel.TimelineProfile,
TimelineProfileAll,
TimelineProfileSpaces,
TimelineMedia,
ProfileMixerMedia,
TimelineFavorites,
ProfileMixerFavorites
)
}

View file

@ -36,8 +36,8 @@ object SpaceSafetyLabelType extends SafetyLabelType {
s.SpaceSafetyLabelType.HatefulHighRecall -> HatefulHighRecall,
s.SpaceSafetyLabelType.ViolenceHighRecall -> ViolenceHighRecall,
s.SpaceSafetyLabelType.HighToxicityModelScore -> HighToxicityModelScore,
s.SpaceSafetyLabelType.UkraineCrisisTopic -> UkraineCrisisTopic,
s.SpaceSafetyLabelType.DoNotPublicPublish -> DoNotPublicPublish,
s.SpaceSafetyLabelType.DeprecatedSpaceSafetyLabel14 -> Deprecated,
s.SpaceSafetyLabelType.DeprecatedSpaceSafetyLabel15 -> Deprecated,
s.SpaceSafetyLabelType.Reserved16 -> Deprecated,
s.SpaceSafetyLabelType.Reserved17 -> Deprecated,
s.SpaceSafetyLabelType.Reserved18 -> Deprecated,
@ -69,10 +69,6 @@ object SpaceSafetyLabelType extends SafetyLabelType {
case object ViolenceHighRecall extends SpaceSafetyLabelType
case object HighToxicityModelScore extends SpaceSafetyLabelType
case object UkraineCrisisTopic extends SpaceSafetyLabelType
case object DoNotPublicPublish extends SpaceSafetyLabelType
case object Deprecated extends SpaceSafetyLabelType
case object Unknown extends SpaceSafetyLabelType

View file

@ -3,6 +3,7 @@ package com.twitter.visibility.rules
import com.twitter.spam.rtf.thriftscala.SafetyResultReason
import com.twitter.util.Memoize
import com.twitter.visibility.common.actions.AppealableReason
import com.twitter.visibility.common.actions.AvoidReason.MightNotBeSuitableForAds
import com.twitter.visibility.common.actions.LimitedEngagementReason
import com.twitter.visibility.common.actions.SoftInterventionDisplayType
import com.twitter.visibility.common.actions.SoftInterventionReason
@ -440,36 +441,6 @@ object FreedomOfSpeechNotReachActions {
}
}
case class ConversationSectionAbusiveQualityAction(
violationLevel: ViolationLevel = DefaultViolationLevel)
extends FreedomOfSpeechNotReachActionBuilder[ConversationSectionAbusiveQuality.type] {
override def actionType: Class[_] = ConversationSectionAbusiveQuality.getClass
override val actionSeverity = 5
private def toRuleResult: Reason => RuleResult = Memoize { r =>
RuleResult(ConversationSectionAbusiveQuality, Evaluated)
}
def build(evaluationContext: EvaluationContext, featureMap: Map[Feature[_], _]): RuleResult = {
val appealableReason =
FreedomOfSpeechNotReach.extractTweetSafetyLabel(featureMap).map(_.labelType) match {
case Some(label) =>
FreedomOfSpeechNotReach.eligibleTweetSafetyLabelTypesToAppealableReason(
label,
violationLevel)
case _ =>
AppealableReason.Unspecified(violationLevel.level)
}
toRuleResult(Reason.fromAppealableReason(appealableReason))
}
override def withViolationLevel(violationLevel: ViolationLevel) = {
copy(violationLevel = violationLevel)
}
}
case class SoftInterventionAvoidAction(violationLevel: ViolationLevel = DefaultViolationLevel)
extends FreedomOfSpeechNotReachActionBuilder[TweetInterstitial] {
@ -662,6 +633,9 @@ object FreedomOfSpeechNotReachRules {
override def enabled: Seq[RuleParam[Boolean]] =
Seq(EnableFosnrRuleParam, FosnrRulesEnabledParam)
override val fallbackActionBuilder: Option[ActionBuilder[_ <: Action]] = Some(
new ConstantActionBuilder(Avoid(Some(MightNotBeSuitableForAds))))
}
case class ViewerIsNonFollowerNonAuthorAndTweetHasViolationOfLevel(
@ -678,6 +652,9 @@ object FreedomOfSpeechNotReachRules {
override def enabled: Seq[RuleParam[Boolean]] =
Seq(EnableFosnrRuleParam, FosnrRulesEnabledParam)
override val fallbackActionBuilder: Option[ActionBuilder[_ <: Action]] = Some(
new ConstantActionBuilder(Avoid(Some(MightNotBeSuitableForAds))))
}
case class ViewerIsNonAuthorAndTweetHasViolationOfLevel(
@ -692,6 +669,9 @@ object FreedomOfSpeechNotReachRules {
override def enabled: Seq[RuleParam[Boolean]] =
Seq(EnableFosnrRuleParam, FosnrRulesEnabledParam)
override val fallbackActionBuilder: Option[ActionBuilder[_ <: Action]] = Some(
new ConstantActionBuilder(Avoid(Some(MightNotBeSuitableForAds))))
}
case object TweetHasViolationOfAnyLevelFallbackDropRule

View file

@ -188,6 +188,7 @@ object RuleBase {
TopicRecommendations -> TopicRecommendationsPolicy,
TrendsRepresentativeTweet -> TrendsRepresentativeTweetPolicy,
TrustedFriendsUserList -> TrustedFriendsUserListPolicy,
TwitterDelegateUserList -> TwitterDelegateUserListPolicy,
TweetDetail -> TweetDetailPolicy,
TweetDetailNonToo -> TweetDetailNonTooPolicy,
TweetDetailWithInjectionsHydration -> TweetDetailWithInjectionsHydrationPolicy,

View file

@ -144,6 +144,9 @@ object NsfwCardImageAvoidAllUsersTweetLabelRule
action = Avoid(Some(AvoidReason.ContainsNsfwMedia)),
) {
override def enabled: Seq[RuleParam[Boolean]] = Seq(EnableAvoidNsfwRulesParam)
override val fallbackActionBuilder: Option[ActionBuilder[_ <: Action]] = Some(
new ConstantActionBuilder(Avoid(Some(MightNotBeSuitableForAds))))
}
object NsfwCardImageAvoidAdPlacementAllUsersTweetLabelRule
@ -247,6 +250,9 @@ object GoreAndViolenceHighPrecisionAvoidAllUsersTweetLabelRule
TweetSafetyLabelType.GoreAndViolenceHighPrecision
) {
override def enabled: Seq[RuleParam[Boolean]] = Seq(EnableAvoidNsfwRulesParam)
override val fallbackActionBuilder: Option[ActionBuilder[_ <: Action]] = Some(
new ConstantActionBuilder(Avoid(Some(MightNotBeSuitableForAds))))
}
object GoreAndViolenceHighPrecisionAllUsersTweetLabelRule
@ -266,6 +272,9 @@ object NsfwReportedHeuristicsAvoidAllUsersTweetLabelRule
TweetSafetyLabelType.NsfwReportedHeuristics
) {
override def enabled: Seq[RuleParam[Boolean]] = Seq(EnableAvoidNsfwRulesParam)
override val fallbackActionBuilder: Option[ActionBuilder[_ <: Action]] = Some(
new ConstantActionBuilder(Avoid(Some(MightNotBeSuitableForAds))))
}
object NsfwReportedHeuristicsAvoidAdPlacementAllUsersTweetLabelRule
@ -274,6 +283,9 @@ object NsfwReportedHeuristicsAvoidAdPlacementAllUsersTweetLabelRule
TweetSafetyLabelType.NsfwReportedHeuristics
) {
override def enabled: Seq[RuleParam[Boolean]] = Seq(EnableAvoidNsfwRulesParam)
override val fallbackActionBuilder: Option[ActionBuilder[_ <: Action]] = Some(
new ConstantActionBuilder(Avoid(Some(MightNotBeSuitableForAds))))
}
object NsfwReportedHeuristicsAllUsersTweetLabelRule
@ -294,6 +306,9 @@ object GoreAndViolenceReportedHeuristicsAvoidAllUsersTweetLabelRule
TweetSafetyLabelType.GoreAndViolenceReportedHeuristics
) {
override def enabled: Seq[RuleParam[Boolean]] = Seq(EnableAvoidNsfwRulesParam)
override val fallbackActionBuilder: Option[ActionBuilder[_ <: Action]] = Some(
new ConstantActionBuilder(Avoid(Some(MightNotBeSuitableForAds))))
}
object GoreAndViolenceReportedHeuristicsAvoidAdPlacementAllUsersTweetLabelRule
@ -302,6 +317,9 @@ object GoreAndViolenceReportedHeuristicsAvoidAdPlacementAllUsersTweetLabelRule
TweetSafetyLabelType.GoreAndViolenceReportedHeuristics
) {
override def enabled: Seq[RuleParam[Boolean]] = Seq(EnableAvoidNsfwRulesParam)
override val fallbackActionBuilder: Option[ActionBuilder[_ <: Action]] = Some(
new ConstantActionBuilder(Avoid(Some(MightNotBeSuitableForAds))))
}
object GoreAndViolenceHighPrecisionAllUsersTweetLabelDropRule
@ -791,7 +809,7 @@ object SkipTweetDetailLimitedEngagementTweetLabelRule
object DynamicProductAdDropTweetLabelRule
extends TweetHasLabelRule(Drop(Unspecified), TweetSafetyLabelType.DynamicProductAd)
object NsfwTextTweetLabelTopicsDropRule
object NsfwTextHighPrecisionTweetLabelDropRule
extends RuleWithConstantAction(
Drop(Reason.Nsfw),
And(
@ -803,7 +821,7 @@ object NsfwTextTweetLabelTopicsDropRule
)
)
with DoesLogVerdict {
override def enabled: Seq[RuleParam[Boolean]] = Seq(EnableNsfwTextTopicsDropRuleParam)
override def enabled: Seq[RuleParam[Boolean]] = Seq(EnableNsfwTextHighPrecisionDropRuleParam)
override def actionSourceBuilder: Option[RuleActionSourceBuilder] = Some(
TweetSafetyLabelSourceBuilder(TweetSafetyLabelType.NsfwTextHighPrecision))
}
@ -832,7 +850,10 @@ object DoNotAmplifyTweetLabelAvoidRule
extends TweetHasLabelRule(
Avoid(),
TweetSafetyLabelType.DoNotAmplify
)
) {
override val fallbackActionBuilder: Option[ActionBuilder[_ <: Action]] = Some(
new ConstantActionBuilder(Avoid(Some(MightNotBeSuitableForAds))))
}
object NsfaHighPrecisionTweetLabelAvoidRule
extends TweetHasLabelRule(

View file

@ -776,7 +776,10 @@ case object MagicRecsPolicy
tweetRules = MagicRecsPolicyOverrides.union(
RecommendationsPolicy.tweetRules.filterNot(_ == SafetyCrisisLevel3DropRule),
NotificationsIbisPolicy.tweetRules,
Seq(NsfaHighRecallTweetLabelRule, NsfwHighRecallTweetLabelRule),
Seq(
NsfaHighRecallTweetLabelRule,
NsfwHighRecallTweetLabelRule,
NsfwTextHighPrecisionTweetLabelDropRule),
Seq(
AuthorBlocksViewerDropRule,
ViewerBlocksAuthorRule,
@ -1171,7 +1174,7 @@ case object ReturningUserExperiencePolicy
NsfwHighRecallTweetLabelRule,
NsfwVideoTweetLabelDropRule,
NsfwTextTweetLabelDropRule,
NsfwTextTweetLabelTopicsDropRule,
NsfwTextHighPrecisionTweetLabelDropRule,
SpamHighRecallTweetLabelDropRule,
DuplicateContentTweetLabelDropRule,
GoreAndViolenceTweetLabelRule,
@ -1785,6 +1788,14 @@ case object TimelineListsPolicy
NsfwReportedHeuristicsAllUsersTweetLabelRule,
GoreAndViolenceReportedHeuristicsAllUsersTweetLabelRule,
NsfwCardImageAllUsersTweetLabelRule,
NsfwHighPrecisionTweetLabelAvoidRule,
NsfwHighRecallTweetLabelAvoidRule,
GoreAndViolenceHighPrecisionAvoidAllUsersTweetLabelRule,
NsfwReportedHeuristicsAvoidAllUsersTweetLabelRule,
GoreAndViolenceReportedHeuristicsAvoidAllUsersTweetLabelRule,
NsfwCardImageAvoidAllUsersTweetLabelRule,
DoNotAmplifyTweetLabelAvoidRule,
NsfaHighPrecisionTweetLabelAvoidRule,
) ++ LimitedEngagementBaseRules.tweetRules
)
@ -2132,7 +2143,13 @@ case object TimelineHomePolicy
userRules = Seq(
ViewerMutesAuthorRule,
ViewerBlocksAuthorRule,
DeciderableAuthorBlocksViewerDropRule
DeciderableAuthorBlocksViewerDropRule,
ProtectedAuthorDropRule,
SuspendedAuthorRule,
DeactivatedAuthorRule,
ErasedAuthorRule,
OffboardedAuthorRule,
DropTakendownUserRule
),
policyRuleParams = SensitiveMediaSettingsTimelineHomeBaseRules.policyRuleParams
)
@ -2171,7 +2188,13 @@ case object BaseTimelineHomePolicy
userRules = Seq(
ViewerMutesAuthorRule,
ViewerBlocksAuthorRule,
DeciderableAuthorBlocksViewerDropRule
DeciderableAuthorBlocksViewerDropRule,
ProtectedAuthorDropRule,
SuspendedAuthorRule,
DeactivatedAuthorRule,
ErasedAuthorRule,
OffboardedAuthorRule,
DropTakendownUserRule
)
)
@ -2255,7 +2278,13 @@ case object TimelineHomeLatestPolicy
userRules = Seq(
ViewerMutesAuthorRule,
ViewerBlocksAuthorRule,
DeciderableAuthorBlocksViewerDropRule
DeciderableAuthorBlocksViewerDropRule,
ProtectedAuthorDropRule,
SuspendedAuthorRule,
DeactivatedAuthorRule,
ErasedAuthorRule,
OffboardedAuthorRule,
DropTakendownUserRule
),
policyRuleParams = SensitiveMediaSettingsTimelineHomeBaseRules.policyRuleParams
)
@ -3283,7 +3312,7 @@ case object TopicRecommendationsPolicy
tweetRules =
Seq(
NsfwHighRecallTweetLabelRule,
NsfwTextTweetLabelTopicsDropRule
NsfwTextHighPrecisionTweetLabelDropRule
)
++ RecommendationsPolicy.tweetRules,
userRules = RecommendationsPolicy.userRules
@ -3536,6 +3565,17 @@ case object TrustedFriendsUserListPolicy
)
)
case object TwitterDelegateUserListPolicy
extends VisibilityPolicy(
userRules = Seq(
ViewerBlocksAuthorRule,
ViewerIsAuthorDropRule,
DeactivatedAuthorRule,
AuthorBlocksViewerDropRule
),
tweetRules = Seq(DropAllRule)
)
case object QuickPromoteTweetEligibilityPolicy
extends VisibilityPolicy(
tweetRules = TweetDetailPolicy.tweetRules,

View file

@ -100,30 +100,6 @@ object TweetRuleGenerator {
FreedomOfSpeechNotReachActions.SoftInterventionAvoidLimitedEngagementsAction(
limitedActionStrings = Some(level3LimitedActions))
)
.addSafetyLevelRule(
SafetyLevel.TimelineMedia,
FreedomOfSpeechNotReachActions
.SoftInterventionAvoidLimitedEngagementsAction(limitedActionStrings =
Some(level3LimitedActions))
)
.addSafetyLevelRule(
SafetyLevel.ProfileMixerMedia,
FreedomOfSpeechNotReachActions
.SoftInterventionAvoidLimitedEngagementsAction(limitedActionStrings =
Some(level3LimitedActions))
)
.addSafetyLevelRule(
SafetyLevel.TimelineFavorites,
FreedomOfSpeechNotReachActions
.SoftInterventionAvoidLimitedEngagementsAction(limitedActionStrings =
Some(level3LimitedActions))
)
.addSafetyLevelRule(
SafetyLevel.ProfileMixerFavorites,
FreedomOfSpeechNotReachActions
.SoftInterventionAvoidLimitedEngagementsAction(limitedActionStrings =
Some(level3LimitedActions))
)
.build,
UserType.Author -> TweetVisibilityPolicy
.builder()
@ -159,30 +135,6 @@ object TweetRuleGenerator {
.InterstitialLimitedEngagementsAvoidAction(limitedActionStrings =
Some(level3LimitedActions))
)
.addSafetyLevelRule(
SafetyLevel.TimelineMedia,
FreedomOfSpeechNotReachActions
.InterstitialLimitedEngagementsAvoidAction(limitedActionStrings =
Some(level3LimitedActions))
)
.addSafetyLevelRule(
SafetyLevel.ProfileMixerMedia,
FreedomOfSpeechNotReachActions
.InterstitialLimitedEngagementsAvoidAction(limitedActionStrings =
Some(level3LimitedActions))
)
.addSafetyLevelRule(
SafetyLevel.TimelineFavorites,
FreedomOfSpeechNotReachActions
.InterstitialLimitedEngagementsAvoidAction(limitedActionStrings =
Some(level3LimitedActions))
)
.addSafetyLevelRule(
SafetyLevel.ProfileMixerFavorites,
FreedomOfSpeechNotReachActions
.InterstitialLimitedEngagementsAvoidAction(limitedActionStrings =
Some(level3LimitedActions))
)
.build,
),
)