Skip to content

[pull] main from forem:main - #405

Merged
pull[bot] merged 4 commits into
amishakov:mainfrom
forem:main
Sep 29, 2026
Merged

pull[bot] merged 4 commits into
amishakov:mainfrom
forem:main

Conversation

@pull

@pull pull Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

jonmarkgo and others added 4 commits September 29, 2026 11:23
…23902)

* Spam-block content that Gemini refuses as PROHIBITED_CONTENT

When Gemini blocks a prompt (or a candidate) with PROHIBITED_CONTENT it returns no
answer, and every spam check treated that as an error and fell back to "not spam". The
most severe content was the content getting through, and LabelCleanupWorker re-ran it
every 30 minutes.

Ai::Base now raises Ai::Base::ProhibitedContentError for that response. The labelers and
spam checks let it through, and Spam::Handler treats it as a clear violation: the mascot
vomits the article, comment or profile and the author gets the spam role. Articles are
also labeled clear_and_obvious_harmful so the cleanup worker stops retrying them.

Claude-Session: https://claude.ai/code/session_01FLx46puMiJkQWtNe7kTRJU

* Only sanction prompt-level blocks, and re-check blocked comments on their own

- Ai::Base raises ProhibitedContentError only for promptFeedback.blockReason. A candidate's
  finishReason is about Gemini's own output, not the user's input.
- CommentCheck's prompt includes the parent post, which may belong to someone else. When
  that prompt is blocked, re-ask about the comment alone; the author is only spam-blocked
  if the comment by itself is blocked.

Claude-Session: https://claude.ai/code/session_01FLx46puMiJkQWtNe7kTRJU
… posts (#23904)

The repeat-offender rule marked any low-trust author with 3+ clear-violation flags in
the last month. Authors of self-promotional but useful technical posts collect a few
clear-spam labels among many well-rated posts, and were being marked as spam too.
Now the flagged posts must also be at least 75% of the author's published posts in
that month.

Claude-Session: https://claude.ai/code/session_01FLx46puMiJkQWtNe7kTRJU
#23903)

* Refresh article notifications only when their data changes, in batches

Notifications::UpdateWorker was the top source of Sidekiq statement timeouts on DEV
(~500 a day, plus ~50 deadlocks). Article#update_notifications ran after almost every
article update, including the last_comment_at touch on each new comment, and rewrote
json_data on every follower's Published notification in a single UPDATE.

- Only refresh when a field the notification shows changes (title, path, tags,
  published_at, reading_time, author or organization).
- Update in id-ordered batches of 1,000 so each statement stays under the timeout and
  concurrent refreshes lock rows in the same order.

Claude-Session: https://claude.ai/code/session_01FLx46puMiJkQWtNe7kTRJU

* Refresh article notifications when crossposted_at changes

readable_publish_date in the notification payload comes from
displayable_published_at, which prefers crossposted_at over published_at.
Also move NOTIFICATION_DATA_ATTRIBUTES up with the other constants
(Layout/ClassStructure).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Ben Halpern <bendhalpern@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Make linked domain spam score threshold admin-configurable

Replaces the hard-coded -2000 net score threshold in
Spam::Handler.article_linked_domain_spam? with a
Settings::RateLimit.linked_domain_spam_score_threshold setting (default
2000, so behavior is unchanged). Adds a form on the admin Linked Domains
page to set it, with explanations of roughly how many spam posts the
number corresponds to and the effective threshold by author score.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Strictly parse admin domain spam threshold; fix explanation grammar

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@pull pull Bot locked and limited conversation to collaborators Sep 29, 2026
@pull pull Bot added the ⤵️ pull label Sep 29, 2026
@pull
pull Bot merged commit b0762aa into amishakov:main Sep 29, 2026
2 of 4 checks passed

This branch had an error being deployed

1 failed deployment
production — b0762aa4 Deployed Sep 29, 2026 by pull[bot] via deploy (production) #381
staging — b0762aa4 Deployed Sep 29, 2026 by pull[bot] via deploy (staging) #381
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants