Delete identical comment campaigns across linked channel posts (#81) #37
No reviewers
Labels
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
backmeupplz/jev_antispam_bot!37
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/81-repeat-campaign"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Agentboard #81 (https://agentboard.icefish-betta.ts.net/#81). Implements Nikita's option B ("yeah do B").
What
A bot-side repeat-campaign rule. When the same actor posts an identical comment (NFKC + lowercase + whitespace-collapsed, 40+ chars) under 3+ distinct linked channel posts within 10 minutes, every qualifying copy is deleted, including earlier copies the model kept. Later copies in the same window are deleted as they arrive.
Copies are tracked in a dedicated per-chat, per-actor
CampaignLedger(10-minute TTL, 20 copies). It is independent of the classifier's kept-message history, so copies already deleted by the model, the cache or the rule still count towards the posts. A copy edited into an ineligible message is forgotten. A copy whose delete was attempted is never retried within the window.history.clearand the 10-message history cap don't hide copies, and a classifier failure doesn't skip the rule.A "post" is only a same-chat
is_automatic_forwardreply whosesender_chatis a channel. Replies to another member's message (for example their own job request), non-linked channel chatter, and messages that are not replies never count and are never deleted by this rule.Known gap (deliberate, conservative): a copy that replies to any other comment is exempt, because the bot can't tell a member's request from a random comment. A spammer replying to random comments under each post evades this rule; the model still judges each copy.
In scope by decision: one actor pasting any identical 40+ char text under 3 posts within 10 minutes is deleted whatever its content, whether an offer, a job search or a warning (Nikita accepted this for "looking for work"). Several different members echoing the same warning are untouched.
Only identical qualifying copies are deleted. Interleaved messages from the same actor and other actors' histories are left alone.
When the model deletes a copy itself, the rule also deletes the earlier kept copies that its weak links (~0.72 < 0.75) would have missed.
The Laya model, checkpoint, prompt, classifier input/context serialization and the 0.80 gate are all unchanged. No forced score. The classifier input and its kept-message history are untouched; the ledger is separate state.
Content-free
repeat_campaign_detectedlog andruleonspam_deleted. Audit snapshots exist for every deleted copy. Stats source staysjev.Cache:
CACHE_POLICY_REVISIONis a digest ofbot.tsand friends, so it changes automatically.campaign.tswas added to the digest list.Why the model can't do this
See the #81 findings: identical prior copies lower Laya's score, because its training history only ever held kept messages (survivorship bias). Retraining is forbidden by decision.
Tests
src/campaign.test.ts: normalization, post detection, ledger threshold/selection, deleted-copy counting, edits, TTL expiry and bound.src/bot.test.ts: real grammY routing with channel-post reply entities. Covers the incident (model keep 0.79/0.61/0.54 → deletes 1,2,3, and a 4th copy deleted on arrival), the model-delete widening, a model-deleted first copy still counting, classifier failure, 11 messages of chatter between copies, members echoing a warning/report (kept), the same actor mass-posting a warning (deleted), an edited-away copy (forgotten), a failed delete (not retried), two posts / same post / edits / other actor (not triggered, other history kept), requested-offer replies to members, interleaved messages, short chatter, non-linked channel, distinct controls, and audit per copy.src/campaign.live.test.ts(gatedRUN_LIVE_LAYA=1 JEV_URL=…): before/after on the approved ckpt-v2 (laya-jev-ckpt-v2-examples-856e52e3, checkpoint sha d899eecd…) at 0.80, through the real handler. SYNTHETIC reconstruction:bun run check: 486 pass, 0 fail.