this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

:saprkles: Auto escalate accounts for high follow/like churn (#740)

authored by

bnewbold and committed by
GitHub
cca47579 7d0ca5d0

+86 -6
+8
automod/engine/context.go
··· 311 311 c.effects.TakedownRecord() 312 312 } 313 313 314 + func (c *RecordContext) EscalateRecord() { 315 + c.effects.EscalateRecord() 316 + } 317 + 318 + func (c *RecordContext) AcknowledgeRecord() { 319 + c.effects.AcknowledgeRecord() 320 + } 321 + 314 322 func (c *RecordContext) TakedownBlob(cid string) { 315 323 c.effects.TakedownBlob(cid) 316 324 }
+14
automod/engine/effects.go
··· 50 50 RecordReports []ModReport 51 51 // Same as "AccountTakedown", but at record-level 52 52 RecordTakedown bool 53 + // Same as "AccountEscalate", but at record-level 54 + RecordEscalate bool 55 + // Same as "AccountAcknowledge", but at record-level 56 + RecordAcknowledge bool 53 57 // Set of Blob CIDs to takedown (eg, purge from CDN) when doing a record takedown 54 58 BlobTakedowns []string 55 59 // If "true", indicates that a rule indicates that the action causing the event should be blocked or prevented ··· 202 206 // Enqueues the record to be taken down at the end of rule processing. 203 207 func (e *Effects) TakedownRecord() { 204 208 e.RecordTakedown = true 209 + } 210 + 211 + // Enqueues the record to be "escalated" for mod review at the end of rule processing. 212 + func (e *Effects) EscalateRecord() { 213 + e.RecordEscalate = true 214 + } 215 + 216 + // Enqueues the record to be "escalated" for mod review at the end of rule processing. 217 + func (e *Effects) AcknowledgeRecord() { 218 + e.RecordAcknowledge = true 205 219 } 206 220 207 221 // Enqueues the blob CID to be taken down (aka, CDN purge) as part of any record takedown
+62 -6
automod/engine/persist.go
··· 203 203 } 204 204 205 205 if newEscalation { 206 - c.Logger.Warn("account-escalate") 206 + c.Logger.Info("account-escalate") 207 207 actionNewEscalationCount.WithLabelValues("account").Inc() 208 208 comment := "[automod]: auto account-escalation" 209 209 _, err := toolsozone.ModerationEmitEvent(ctx, xrpcc, &toolsozone.ModerationEmitEvent_Input{ ··· 225 225 } 226 226 227 227 if newAcknowledge { 228 - c.Logger.Warn("account-acknowledge") 228 + c.Logger.Info("account-acknowledge") 229 229 actionNewAcknowledgeCount.WithLabelValues("account").Inc() 230 230 comment := "[automod]: auto account-acknowledge" 231 231 _, err := toolsozone.ModerationEmitEvent(ctx, xrpcc, &toolsozone.ModerationEmitEvent_Input{ ··· 266 266 atURI := c.RecordOp.ATURI().String() 267 267 newLabels := dedupeStrings(c.effects.RecordLabels) 268 268 newTags := dedupeStrings(c.effects.RecordTags) 269 - if (len(newLabels) > 0 || len(newTags) > 0) && eng.OzoneClient != nil { 269 + newEscalation := c.effects.RecordEscalate 270 + newAcknowledge := c.effects.RecordAcknowledge 271 + 272 + if (newEscalation || newAcknowledge || len(newLabels) > 0 || len(newTags) > 0) && eng.OzoneClient != nil { 270 273 // fetch existing record labels, tags, etc 271 274 rv, err := toolsozone.ModerationGetRecord(ctx, eng.OzoneClient, c.RecordOp.CID.String(), c.RecordOp.ATURI().String()) 272 275 if err != nil { ··· 286 289 negLabels = dedupeStrings(negLabels) 287 290 newLabels = dedupeLabelActions(newLabels, existingLabels, negLabels) 288 291 existingTags := []string{} 289 - if rv.Moderation != nil && rv.Moderation.SubjectStatus != nil && rv.Moderation.SubjectStatus.Tags != nil { 292 + hasSubjectStatus := rv.Moderation != nil && rv.Moderation.SubjectStatus != nil 293 + if hasSubjectStatus && rv.Moderation.SubjectStatus.Tags != nil { 290 294 existingTags = rv.Moderation.SubjectStatus.Tags 291 295 } 292 296 newTags = dedupeTagActions(newTags, existingTags) 297 + newEscalation = newEscalation && hasSubjectStatus && *rv.Moderation.SubjectStatus.ReviewState != "tools.ozone.moderation.defs#reviewEscalate" 298 + newAcknowledge = newAcknowledge && hasSubjectStatus && *rv.Moderation.SubjectStatus.ReviewState != "tools.ozone.moderation.defs#reviewNone" && *rv.Moderation.SubjectStatus.ReviewState != "tools.ozone.moderation.defs#reviewClosed" 293 299 } 294 300 } 295 301 ··· 316 322 if err != nil { 317 323 return fmt.Errorf("failed to circuit break takedowns: %w", err) 318 324 } 325 + newEscalation, err = eng.circuitBreakModAction(ctx, newEscalation) 326 + if err != nil { 327 + return fmt.Errorf("circuit-breaking escalation: %w", err) 328 + } 329 + newAcknowledge, err = eng.circuitBreakModAction(ctx, newAcknowledge) 330 + if err != nil { 331 + return fmt.Errorf("circuit-breaking acknowledge: %w", err) 332 + } 319 333 320 - if newTakedown || len(newLabels) > 0 || len(newTags) > 0 || len(newFlags) > 0 || len(newReports) > 0 { 334 + if newEscalation || newAcknowledge || newTakedown || len(newLabels) > 0 || len(newTags) > 0 || len(newFlags) > 0 || len(newReports) > 0 { 321 335 if eng.Notifier != nil { 322 336 for _, srv := range dedupeStrings(c.effects.NotifyServices) { 323 337 if err := eng.Notifier.SendRecord(ctx, srv, c); err != nil { ··· 337 351 } 338 352 339 353 // exit early 340 - if !newTakedown && len(newLabels) == 0 && len(newTags) == 0 && len(newReports) == 0 { 354 + if !newAcknowledge && !newEscalation && !newTakedown && len(newLabels) == 0 && len(newTags) == 0 && len(newReports) == 0 { 341 355 return nil 342 356 } 343 357 ··· 433 447 if err != nil { 434 448 c.Logger.Error("failed to execute record takedown", "err", err) 435 449 } 450 + 451 + // we don't want to escalate if there is a takedown 452 + newEscalation = false 436 453 } 437 454 455 + if newEscalation { 456 + c.Logger.Warn("record-escalation") 457 + actionNewEscalationCount.WithLabelValues("record").Inc() 458 + comment := "[automod]: automated record-escalation" 459 + _, err := toolsozone.ModerationEmitEvent(ctx, xrpcc, &toolsozone.ModerationEmitEvent_Input{ 460 + CreatedBy: xrpcc.Auth.Did, 461 + Event: &toolsozone.ModerationEmitEvent_Input_Event{ 462 + ModerationDefs_ModEventEscalate: &toolsozone.ModerationDefs_ModEventEscalate{ 463 + Comment: &comment, 464 + }, 465 + }, 466 + Subject: &toolsozone.ModerationEmitEvent_Input_Subject{ 467 + RepoStrongRef: &strongRef, 468 + }, 469 + }) 470 + if err != nil { 471 + c.Logger.Error("failed to execute record escalation", "err", err) 472 + } 473 + } 474 + 475 + if newAcknowledge { 476 + c.Logger.Warn("record-acknowledge") 477 + actionNewAcknowledgeCount.WithLabelValues("record").Inc() 478 + comment := "[automod]: automated record-acknowledge" 479 + _, err := toolsozone.ModerationEmitEvent(ctx, xrpcc, &toolsozone.ModerationEmitEvent_Input{ 480 + CreatedBy: xrpcc.Auth.Did, 481 + Event: &toolsozone.ModerationEmitEvent_Input_Event{ 482 + ModerationDefs_ModEventAcknowledge: &toolsozone.ModerationDefs_ModEventAcknowledge{ 483 + Comment: &comment, 484 + }, 485 + }, 486 + Subject: &toolsozone.ModerationEmitEvent_Input_Subject{ 487 + RepoStrongRef: &strongRef, 488 + }, 489 + }) 490 + if err != nil { 491 + c.Logger.Error("failed to execute record acknowledge", "err", err) 492 + } 493 + } 438 494 return nil 439 495 }
+2
automod/rules/interaction.go
··· 26 26 c.Logger.Info("high-like-churn", "created-today", created, "deleted-today", deleted) 27 27 c.AddAccountFlag("high-like-churn") 28 28 c.ReportAccount(automod.ReportReasonSpam, fmt.Sprintf("interaction churn: %d likes, %d unlikes today (so far)", created, deleted)) 29 + // c.EscalateAccount() 29 30 c.Notify("slack") 30 31 return nil 31 32 } ··· 38 39 c.Logger.Info("high-follow-churn", "created-today", created, "deleted-today", deleted) 39 40 c.AddAccountFlag("high-follow-churn") 40 41 c.ReportAccount(automod.ReportReasonSpam, fmt.Sprintf("interaction churn: %d follows, %d unfollows today (so far)", created, deleted)) 42 + // c.EscalateAccount() 41 43 c.Notify("slack") 42 44 return nil 43 45 }