Skip to content

Appeals for automated NSFW labels have no published effect path — users are told to appeal, then wait for TTL or silence Labels (if you can set them) visibility-filtering adult-content under-the-hood #16108

Description

@taiseisouma0723-dot

Summary
X’s public help text tells users to appeal if an automated adult-content label is wrong. The published algorithm shows how those labels are applied, aggregated onto accounts, and used to drop out-of-network recommendations. It does not show a path where a user appeal actually clears the label, blocks re-application, or stops account-level rollup.
In practice, many users file the in-product appeal or contact support and then see one of two outcomes:

  1. no visible review state and no response
  2. the label expires on its own (often ~7 days) and is re-applied when the next posts hit the same classifiers
    That is a product spec gap, not just a support staffing issue. The official remedy and the published enforcement pipeline do not connect.
    Current published behavior
    What users are told
    Adult Content Policy: if X made a mistake, submit an appeal.
    Post UI: appeal / request review on a labeled post.
    August 2026 transparency work (Under the Hood + this repo) explains that a label exists and what it does to visibility. It does not provide a control to remove it.
    What the repo actually implements
    • Post labels such as NSFW_HIGH_RECALL and NSFW_HIGH_PRECISION are produced by automated classifiers (grox/, media models, pnsfwmedia/). Thresholds and prompts are not published.
    • Account labels are derived from recent post labels. ApplyNsfwUserLabel.df applies an account-level action after more than two same-type labeled posts in one day.
    • ApplyNsfwUserLabelOrCreateReport.df sets account labels with a default expiry of 7 days (sometimes 3). After expiry, the same rule can fire again.
    • A NsfwUserLabelRemoved marker only changes auto-apply into an internal report for 90 days. Users cannot set this marker. Support DMs have no published guarantee that they set it.
    • Gold/Gray verified and some high-PageRank accounts are reported instead of auto-labeled, at most once per week. Premium subscription is not a published skip condition.
    • visibility-filtering drops all posts from non-follower recommendations when the author carries NsfwHighRecall / NsfwHighPrecision / related account labels — including posts that have no post-level NSFW label (see also Issue Follow me on Twitter #79).
    There is no published consumer of “appeal granted” that:
    • removes the post label
    • subtracts that post from the daily/period rollup
    • writes NsfwUserLabelRemoved
    • prevents the same media hash from being labeled again on re-upload
    • exposes review state in Under the Hood (pending / upheld / overturned)
    Why this is a spec problem
    The official loop is:
    auto label → user appeals as instructed → human review → correction
    The implemented loop is:
    auto label → visibility penalty (often with no interstitial on HIGH_RECALL) → appeal with no status → TTL expiry and/or re-detect → account rollup
    If appeal is the documented fix for false positives, but the only reliable “fix” is waiting for expiry while new posts refill the counter, then the documented fix is not part of the system. Users cannot comply their way out. High-recall false positives are expected by design; an appeal path that does not bind the label store makes that design un-auditable.
    This is already a large, repeated complaint on the platform, especially for illustration, cosplay, game screenshots, and other non-explicit media that still trips HIGH_RECALL.
    Proposed spec (minimal, compatible with current architecture)
    Do not ask for public model weights or a self-serve instant un-label for confirmed adult content. Ask for the appeal to be a first-class event in the same pipeline that applies labels.
  3. Appeal is a stored state, not a mailbox.
For each appealed post label: pending | upheld | overturned, with timestamps, visible in Under the Hood and on the post.
  4. Overturn writes through.
On overturned:
    • clear the post label
    • exclude that post ID from ApplyNsfwUserLabel / safety-label-user-agg counts
    • if the account label was derived only from now-overturned posts, clear it and set NsfwUserLabelRemoved
  5. Pending must not keep digging the hole.
While pending, do not let that post increment the “more than 2 in a day” HLL toward a new account label.
  6. SLA or honest copy.
Either publish a review window, or stop telling users that appeal is the remedy. “Wait for the 7-day TTL” should not be the silent backend of a documented appeal.
  7. Re-application after overturn.
If the same media is posted again, require a new classifier score above the high-precision bar, or a human queue, before HIGH_RECALL can be re-attached. Blind re-apply after a successful appeal is the loop.
  8. Separate post eligibility from author history for clean posts.
Same request as Follow me on Twitter #79: an overturned or unlabeled post must be able to enter OON recommendations even if an older author label is still decaying.
    Out of scope
    • Weakening age-gating for actually labeled adult media
    • User-set permanent immunity from adult-content policy
    • Publishing classifier prompts
    The request is only: if the product tells people to appeal mistakes, the published system must treat a granted appeal as an input, not as an optional support ticket that the label pipeline never reads.
    Acceptance checks
    • Under the Hood shows appeal state per labeled post, not only monthly aggregates
    • An overturned post does not count toward account-level NSFW rollup
    • After overturn, the author label does not persist solely because of that post
    • Docs (help center + underTheHoodLabels.strato) describe the same lifecycle as the code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions