Reading enforcement_user.yaml at c65aa17, the base cluster_spam enforcement rules appear to be unreachable: a broad skip rule is ordered above the specific action rules that share its predicate, and the engine is first-match-wins.
The engine is first-match-wins
decide_with returns on the first rule whose when evaluates true:
https://github.com/xai-org/x-algorithm/blob/c65aa17/abuse-enforcement-service/service-lib/src/rules.rs#L256-L277
Value::Bool(true) => return Ok(outcome_to_decision(&rule.outcome)),
Value::Bool(false) => continue,
So a broad rule placed above narrower rules that share its predicate shadows them.
The ordering
https://github.com/xai-org/x-algorithm/blob/c65aa17/abuse-enforcement-service/service-lib/rules/enforcement_user.yaml#L179-L202
- id: hold_cluster_spam
when: 'score.model_version.startsWith("cluster_spam")' # broad, SKIP
then: { kind: skip, reason: cluster_spam_held }
- id: act_cluster_spam_suspend
when: '...startsWith("cluster_spam") && "cluster_spam_suspend" in score.labels'
then: { kind: act_suspend_user, perm: false, policy: PlatformManipulation }
- id: act_cluster_spam_bounce
when: '...startsWith("cluster_spam") && "cluster_spam_bounce" in score.labels'
then: { kind: act_arkose }
- id: act_cluster_spam_label
when: '...startsWith("cluster_spam") && "cluster_spam_label_shr" in score.labels'
then: { kind: act_add_labels_v2, labels: ["SpamHighRecall"], ... }
hold_cluster_spam matches every model version starting with cluster_spam and returns skip. It sits above the three act_cluster_spam_* rules, which share the same startsWith("cluster_spam") prefix. For any base cluster_spam model version, hold_cluster_spam matches first and the three action rules below are never reached. An account the model flags with cluster_spam_suspend (or _bounce, or _label_shr) is held rather than actioned.
Confirming it is genuinely unreachable, not just suspicious
Walking a base cluster_spam decision from the top of the file:
- The
inauthentic_detection_v45_* rules require startsWith("inauthentic_detection_v45"), no match.
- The
cluster_spam_extended_* action rules (above hold_cluster_spam) require startsWith("cluster_spam_extended"); a base cluster_spam version does not match.
- The label-only rules near the top match on
score.labels unrelated to cluster spam, so a normal cluster_spam decision does not hit them.
- Execution therefore reaches
hold_cluster_spam, matches, and returns skip. Lines for suspend/bounce/label never execute.
Note the contrast: the cluster_spam_extended family is ordered correctly, its action rules precede any hold. Only the base cluster_spam family is shadowed, which suggests this is an ordering mistake rather than an intended hold-all.
Suggested fix
Move hold_cluster_spam below the three act_cluster_spam_* rules, so it acts as the catch-all for cluster_spam decisions that carry no actionable label, mirroring how the cluster_spam_extended rules are already arranged.
Caveat
The file header reads # mirrored from GrowthBook dynamic config; last sync 2026-08-12, and the file contains acknowledged mock values (for example high_follower_count >= 12.34, commented as a mock). So this YAML may be a sanitised mirror, and the ordering here might be an artefact of that rather than a reflection of production. I cannot tell from the repository whether the live GrowthBook config carries the same order. If it does, base cluster_spam enforcement (suspend, bounce, label) is disabled. Worth confirming against the production config, and either way the published rules read as a shadowing bug.
Reading
enforcement_user.yamlatc65aa17, the basecluster_spamenforcement rules appear to be unreachable: a broadskiprule is ordered above the specific action rules that share its predicate, and the engine is first-match-wins.The engine is first-match-wins
decide_withreturns on the first rule whosewhenevaluates true:https://github.com/xai-org/x-algorithm/blob/c65aa17/abuse-enforcement-service/service-lib/src/rules.rs#L256-L277
So a broad rule placed above narrower rules that share its predicate shadows them.
The ordering
https://github.com/xai-org/x-algorithm/blob/c65aa17/abuse-enforcement-service/service-lib/rules/enforcement_user.yaml#L179-L202
hold_cluster_spammatches every model version starting withcluster_spamand returnsskip. It sits above the threeact_cluster_spam_*rules, which share the samestartsWith("cluster_spam")prefix. For any basecluster_spammodel version,hold_cluster_spammatches first and the three action rules below are never reached. An account the model flags withcluster_spam_suspend(or_bounce, or_label_shr) is held rather than actioned.Confirming it is genuinely unreachable, not just suspicious
Walking a base
cluster_spamdecision from the top of the file:inauthentic_detection_v45_*rules requirestartsWith("inauthentic_detection_v45"), no match.cluster_spam_extended_*action rules (abovehold_cluster_spam) requirestartsWith("cluster_spam_extended"); a basecluster_spamversion does not match.score.labelsunrelated to cluster spam, so a normal cluster_spam decision does not hit them.hold_cluster_spam, matches, and returnsskip. Lines for suspend/bounce/label never execute.Note the contrast: the
cluster_spam_extendedfamily is ordered correctly, its action rules precede any hold. Only the basecluster_spamfamily is shadowed, which suggests this is an ordering mistake rather than an intended hold-all.Suggested fix
Move
hold_cluster_spambelow the threeact_cluster_spam_*rules, so it acts as the catch-all for cluster_spam decisions that carry no actionable label, mirroring how thecluster_spam_extendedrules are already arranged.Caveat
The file header reads
# mirrored from GrowthBook dynamic config; last sync 2026-08-12, and the file contains acknowledged mock values (for examplehigh_follower_count >= 12.34, commented as a mock). So this YAML may be a sanitised mirror, and the ordering here might be an artefact of that rather than a reflection of production. I cannot tell from the repository whether the live GrowthBook config carries the same order. If it does, basecluster_spamenforcement (suspend, bounce, label) is disabled. Worth confirming against the production config, and either way the published rules read as a shadowing bug.