From fb7ddbba700e1dd8f092de72fe87efd12a18c2f1 Mon Sep 17 00:00:00 2001 From: FoxxMD Date: Mon, 7 Mar 2022 13:02:17 -0500 Subject: [PATCH] docs: Add overview for runs and flow control #73 --- docs/README.md | 2 +- docs/examples/README.md | 1 + docs/examples/advancedConcepts/README.md | 6 +- docs/examples/advancedConcepts/flowControl.md | 236 ++++++++++++++++++ .../advancedConcepts/flowControl.yaml | 96 +++++++ 5 files changed, 338 insertions(+), 3 deletions(-) create mode 100644 docs/examples/advancedConcepts/flowControl.md create mode 100644 docs/examples/advancedConcepts/flowControl.yaml diff --git a/docs/README.md b/docs/README.md index 201666d..d4f3d0a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -90,7 +90,7 @@ An example of Runs: * A group of Checks that look for missing flairs on a user or a new submission and flair accordingly * A group of Checks that detect spam or self-promotion and then remove those activities -Both group of Checks are independent of each other (don't have any patterns or actions in common) +Both group of Checks are independent of each other (don't have any patterns or actions in common). Learn more about using [Runs and **Flow Control** to control how CM behaves.](/docs/examples/advancedConcepts/flowControl.md) ### Checks diff --git a/docs/examples/README.md b/docs/examples/README.md index 3567cab..920a49b 100644 --- a/docs/examples/README.md +++ b/docs/examples/README.md @@ -21,6 +21,7 @@ This directory contains example of valid, ready-to-go configurations for Context * [Author and post flairs](/docs/examples/onlyfansFlair) * [Toolbox User Notes](/docs/examples/userNotes) * [Advanced Concepts](/docs/examples/advancedConcepts) + * [Flow Control](/docs/examples/advancedConcepts/flowControl.md) * [Rule Sets](/docs/examples/advancedConcepts/ruleSets.json5) * [Name Rules](/docs/examples/advancedConcepts/ruleNameReuse.json5) * [Check Ordering](/docs/examples/advancedConcepts) diff --git a/docs/examples/advancedConcepts/README.md b/docs/examples/advancedConcepts/README.md index 675f7ef..3695309 100644 --- a/docs/examples/advancedConcepts/README.md +++ b/docs/examples/advancedConcepts/README.md @@ -2,11 +2,13 @@ See **Rule Name Reuse Examples [YAML](/docs/examples/advancedConcepts/ruleNameReuse.yaml) | [JSON](/docs/examples/advancedConcepts/ruleNameReuse.json5)** -### Check Order +### Check Order and Flow Control Checks are run in the order they appear in your configuration, therefore you should place your highest requirement/severe action checks at the top and lowest requirement/moderate actions at the bottom. -This is so that if an Activity warrants a more serious reaction that Check is triggered first rather than having a lower requirement check with less severe actions triggered and causing all subsequent Checks to be skipped. +This is so that if an Activity warrants a more serious reaction that Check is triggered first rather than having a lower requirement check with less severe actions triggered and causing all subsequent Checks to be skipped. + +This behavior can also be controlled modified using [Flow Control](/docs/examples/advancedConcepts/flowControl.md) * Attribution >50% AND Repeat Activity 8x AND Recent Activity in 2 subs => remove submission + ban * Attribution >20% AND Repeat Activity 4x AND Recent Activity in 5 subs => remove submission + flair user restricted diff --git a/docs/examples/advancedConcepts/flowControl.md b/docs/examples/advancedConcepts/flowControl.md new file mode 100644 index 0000000..97cc812 --- /dev/null +++ b/docs/examples/advancedConcepts/flowControl.md @@ -0,0 +1,236 @@ +Context Mod's behavior after a **Check** has been processed can be configured by a user. This allows a subreddit to control exactly what Runs/Checks will be processed based on the outcome (triggered or not) of a Check. + +# Table of Contents + +- [Post-Check Properties](#post-check-properties) + * [State](#state) + * [Behavior](#behavior) + + [Next](#next) + + [Next Run](#next-run) + + [Stop](#stop) + + [Goto](#goto) + - [Goto Syntax](#goto-syntax) +- [Default Behaviors](#default-behaviors) + * [Defining Default Behaviors](#defining-default-behaviors) +- [Examples](#examples) + +# Post-Check Properties + +## State + +When a Check is finished processing it can be in one of two states: + +* **Triggered** -- The **Rules** defined in the Check were **triggered** which caused the **Actions** for the Check to be run +* **Failure** -- The **Rules** defined in the check were **not triggered**, based on the conditions that were set (either from the [Check condition](/docs/README.md#Checks) or [Rule Sets](/docs/examples/advancedConcepts/README.md#Rule-Sets)), and no **Actions** were run + +The behavior CM follows is based on which state it is in. The behavior can be specified **by one or both** of these **state properties** on the Check configuration: + +* `postTrigger` -- Specifies what behavior to take when the check is **triggered** +* `postFail` -- Specifies what behavior to take when the check is **not triggered** + +## Behavior + +There are **four** behaviors CM can take. Both/either **state properties** can be defined with **any behavior.** + +### Next + +The **Next** behavior tells CM to continue to whatever comes *after the Check that was just processed.* This could be another Check or, if this is the last Check in a Run. + +NOTE: `next` is the **default behavior** for the `postFail` state + +Example + +```yaml +- name: MyCheck + # ... + postFail: next # CM will start processing AnotherCheck + +- name: AnotherCheck + # ... +``` + +### Next Run + +The **Next Run** behavior tells CM to **skip all remaining Checks in the current Run and start processing the next Run in order.** + +NOTE: `nextRun` is the **default behavior** for the `postTrigger` state + +Example + +```yaml +runs: + - name: MyFirstRun + checks: + - name: MyCheck + # ... + postTrigger: nextRun # CM will SKIP mySecondCheck and instead start processing MySecondRun + - name: MySecondCheck + # ... + + - name: MySecondRun + checks: + - name: FooCheck + # ... +``` + +### Stop + +The **Stop** behavior tells CM to **stop processing the Activity entirely.** This means all remaining Checks and Runs will not be processed. + +Example + +```yaml +runs: + - name: MyFirstRun + checks: + - name: MyCheck + # ... + postTrigger: stop # CM will NOT process MySecondCheck OR MySecondRun. The activity is "done" being processed at this point + - name: MySecondCheck + # ... + + - name: MySecondRun + checks: + - name: FooCheck + # ... +``` + +### Goto + +The **Goto** behavior is an **advanced** behavior that allows you to specify that CM should "jump to" a specific place in your configuration, regardless of order/location, and continue processing the Activity from there. It can be used to do things like: + +* create a loop/iteration to have CM re-process the Activity on an earlier executed part of your configuration because a later part modified the Activity (flaired, etc...) +* use a Check as a simplified *switch statement* + +**Goto should be use with care.** If you do not fully understand how this mechanism works you should avoid using it as **most** behaviors can be accomplished using the other behaviors. + +As an additional protection **goto depth is limited to 1 by default** which means if a `goto` would be executed more than once during an Activity's lifecycle CM will automatically stop processing that Activity. The `maxGotoDepth` can be raised by the [**Bot Operator**](/docs/gettingStartedOperator.md) per subreddit. + +#### Goto Syntax + +Location to "jump to" can be specified as: + +* **Run** -- `goto:myRunName` +* **Check inside a different Run** -- `goto:myRunName.aCheckInsideTheRun` +* **Check inside the current Run** -- `goto:.myCheck` + +Example + +```yaml +runs: + - name: MyFirstRun + checks: + - name: FirstCheck + # ... + - name: MyCheck + # ... + postTrigger: 'goto:MyThirdRun' # jump to the run MyThirdRun + postFail: 'goto:MySecondRun.BuzzCheck' # jump to the Check BuzzCheck inside the Run MySecondRun + + - name: MySecondRun + checks: + - name: FooCheck + # ... + - name: BuzzCheck + # ... + + - name: MyThirdRun + checks: + - name: BarCheck + # ... +``` + +# Default Behaviors + +It is **not required** to define post-Check behavior. CM uses sane defaults to mimic the behavior of automoderator as well as what is "intuitive" when reading a configuration -- that logic flows from top-to-bottom in the order it was defined. For each Check like this: + +```yaml +- name: MyCheck + kind: comment + rules: + # ... + actions: + # ... +``` + +`postTrigger` and `postFail` have default behaviors (mentioned in the sections above) that make the Check end up working like this: + +```yaml +- name: MyCheck + kind: comment + rules: + # ... + actions: + # ... + postTrigger: nextRun # check is triggered and actions were performed, skip remaining checks and go to the next Run + postFail: next # check is not triggered and no actions performed, continue to the next check in this Run +``` + +**So if you are fine with all Checks running in order until one triggered there is no need to define post-Check behaviors at all.** + +## Defining Default Behaviors + +Defining `postTrigger` and/or `postFail` on a **Run** will set the default behavior for any **Checks** in the Run that **do not have an explicit behavior set.** + +```yaml +runs: + - name: MyFirstRun + postTrigger: stop # all Checks without postTrigger defined will have 'stop' as their behavior + checks: + - name: FooCheck # postTrigger is 'stop' since it is not defined + # ... + - name: BarCheck + # ... + postTrigger: next # overrides default behavior +``` + +# Examples + +One **Run** with **default behavior** (no post-Check behavior explicitly defined) + +
+ +```mermaid +flowchart TB + subgraph spam ["(Run) Spam"] + b1["(Check) self-promotion"] -- "postFail: next" -->b2 + b2["(Check) repeat spam"] -- "postFail: next" --> b3 + b3["(Check) Good user"] + end + b1 -- "postTrigger: nextRun" --> finish + b2 -- "postTrigger: nextRun" --> finish + b3 -- "postFail: next" --> finish + b3 -- "postTrigger: nextRun" --> finish + finish[Processing Finished] +``` + +
+ +Two **Runs** with **default behavior** (no post-Check behavior explicitly defined) + +
+ +```mermaid +flowchart TB + subgraph flair ["(Run) Flairing"] + a1["(Check) Flair Submission based on history"]-- "postFail: next" -->a2 + a2["(Check) Flair Submission based on user profile"] -- "postFail: next" --> a3 + a3["(Check) Flair Submission based on self text"] + end + a1 -- "postTrigger: nextRun" --> b1 + a2 -- "postTrigger: nextRun" --> b1 + a3 -- "postFail: next" --> b1 + a3 -- "postTrigger: nextRun" --> b1 + subgraph spam ["(Run) Spam"] + b1["(Check) self-promotion"] -- "postFail: next" -->b2 + b2["(Check) repeat spam"] -- "postFail: next" --> b3 + b3["(Check) Good user"] + end + b1 -- "postTrigger: nextRun" --> finish + b2 -- "postTrigger: nextRun" --> finish + b3 -- "postFail: next" --> finish + b3 -- "postTrigger: nextRun" --> finish + finish[Processing Finished] +``` + +
diff --git a/docs/examples/advancedConcepts/flowControl.yaml b/docs/examples/advancedConcepts/flowControl.yaml new file mode 100644 index 0000000..15371ea --- /dev/null +++ b/docs/examples/advancedConcepts/flowControl.yaml @@ -0,0 +1,96 @@ +runs: + - name: flairAndCategory + + # Runs inherit the same filters as checks/rules/actions + # If these filters fail the Run is skipped and CM processes the next run in order + # authorIs: + # itemIs: + + # Set the default behavior for check trigger/fail + # postTrigger: + # postFail: + + # Defaults can also be set for check authorIs/itemIs + # same as at operator/subreddit level - any defined here will override "higher" defaults + # filterCriteriaDefaults: + + checks: + - name: goodUserFlair + description: flair user if they have decent history in sub + kind: submission + authorIs: + exclude: + - flairText: 'Good User' + rules: + - kind: recentActivity + thresholds: + - threshold: '> 5' + karma: '> 10' + subreddits: + - mySubreddit + actions: + - kind: userflair + text: 'Good User' + # post-behavior after a check has run. Either the check is TRIGGERED or FAIL + # there are 4 possible behaviors for each post-behavior type: + # + # 'next' => Continue to next check in order + # 'nextRun' => Exit the current Run (skip all remaining Checks) and go to the next Run in order + # 'stop' => Exit the current Run and finish activity processing immediately (skip all remaining Runs) + # 'goto:run[.check]' => Specify a run[.check] to jump to. This can be anywhere in your config. CM will continue to process in order from the specified point. + # + # GOTO syntax -- + # 'goto:normalFilters' => go to run "normalFilters" + # 'goto:normalFilters.myCheck' => go to run "normalFilters" and start at check "myCheck" + # 'goto:.goodUserFlair' => go to check 'goodUserFlair' IN THE SAME RUN currently processing + # + + # this means if the check triggers then continue to 'good submission flair' + postTrigger: next # default is 'nextRun' + # postFail: # default is 'next' + + - name: good submission flair + description: flair submission if from good user + kind: submission + authorIs: + include: + - flairText: 'Good User' + actions: + - kind: flair + text: 'Trusted Source' + - kind: approve + # this means if the check is triggered then stop processing the activity entirely + postTrigger: stop + + - name: Determine Suspect + checks: + - name: is suspect + kind: submission + rules: + - kind: recentActivity + thresholds: + - subreddits: + - over_18: true + actions: + # do some actions + + # if check is triggered then go to run 'suspectFilters' + postTrigger: 'goto:suspectFilters' + # if check is not triggered then go to run 'normalFilters' + postFail: 'goto:normalFilters' + + - name: suspectFilters + postTrigger: stop + authorIs: + exclude: + - flairText: 'Good User' + checks: + # some checks for users that are suspicious + + + - name: normalFilters + authorIs: + exclude: + - flairText: 'Good User' + checks: + # some checks for general activities