Back to "StyloBot-utsläppsserien: Att bli snabbare"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

ASP.NET Bot Detection Machine Learning Performance StyloBot

StyloBot-utsläppsserien: Att bli snabbare

Wednesday, 13 May 2026

Uppåt- -den här är för nördarna.- -.. Det är en djup vetenskaplig dykning in i StyloBots adaptiv-lärningssystem. (. EWMA-uppdateringar. Mostlylucid.BotDetection och ledtrådar till den likvärdiga maskinen.-.Lernering konstruerar så att ML-reader har en ingångspunkt... Om du vill ha hissen på hissen,,. läsa de tidigare utsläppsposterna.M SK3. Om ni vill veta hur fyras minne, -, omvandlar upprepade trafiker till subprocesser och under tiden återhämtar sig från felaktiga positiva signaler.

DRAFT

Detta är ett arbetsprojekt i StyloBot-utsläppsserien.

StyloBot-utsläppsserien

  1. Behavior, Inte Identitet - varför StyloBot modellerar klienter beteendemässigt
  2. Behavior-Är medveten ASP.NET UI - servern - skickade ut ytan över det upptäcktsresultatet
  3. Att hitta och lösa gränslös tillväxt i långtids-, -- och / eller körande- -.-nätverk - den tillförlitlighetsdisciplin som gör motorn tråkig i produktionen
  4. Behavior-Akvis typscript-UI - Express , Fastify, och webbladerkomponenter
  5. Sidecar-arkitekturen - hur detektoren kopplas till icke--.NET-skivor
  6. Att lära sig bli snabbare - adaptiv inlärningssystem, ,, fyra, M SK2, övningsminnet, ,, och bedömningsキャッシュen
  7. Att testa det som inte stannar kvar - kontrolldisciplinen : en BDF-fielddriver regression M SK2 belastning , och kalibrering
  8. StyloExtract - en lokal lärande HTML omvandlare till Markdown - HTML, →, Markdown-lagret som paras med detektorn, ,, walkersbug lucidVIEW som fångade, M SK3, och den hundföda-loopan som gjorde det ärligt

Behavioralmodellen finns i Behavior, Inte Identitet; tillförlitlighetsdisciplinen i Att hitta och fixa gränslös tillväxt; källa på github.com/scottgalM SK2stylobot.


Varför stör StyloBot med det här

StyloBots hela jobb är att berätta för människor från robotar, ,, och det sättet den gör det på den mest grundläggande nivån är genom att bygga en bild av hur en genomsnittlig bot ser ut och hur en medelmänsklig människa ser ut.., inga fixera regler.,, ingen regex över användaren.M SK4, agentsträngar. Accuracy förbättras först; latens förbättras som ett resultat (Klasteringsidan av detta är täckt av Behavior, Inte Identitet; det här laget handlar om vad som händer med centrärerna när man har dem

Den mekanismen är också vad som gör StyloBot till att användas på dumt olika ställen.:, en personlig blogg på 50, begäran, /, minuten, ,, en marknadsföringssida som exploderar när produkten lanseras.,, ett SPA där större delen av trafiken är API-sändningar.

En upptäckare som kör hela pipelinen på varje utmaning är noggrann men oekonomisk. En upptäcker som blindt kastar ut bedömningar är snabb men brittisk . StyloBot sätter sig mellan de två M SK2 kaschen är det vanligaste fallet

För kontext mot de mer bekanta namnen i detta utrymme:

Platsering Typiskt per - anställningskostnader Vad du får tillbaka
Cloudflare Bot Management Rand ( Deras CDN ) МSK4 Sub - Millisekund vid kanten Block / Utmaningen Sk8 tillåt innan din ursprung ser det
CHEQ ♫ ♫ / ♫ DataDome ♫ {\displaystyle ♫{ ♫ Server ♫} - ♫ Side API callout ♫
StyloBot Iprocessen eller lokala gRPC-bilar ~10-50 μs uppvärmda via Skip, 400-900 μs för en fullfast -path pipeline runBotProbability, Confidence, RiskBand, ThreatScore) direkt i din handledare

Kanterprodukter är jättebra på "block före ursprunget "; vad de inte kan göra är att ge din applikation en procent per request, och låta din kassasida bestämma vad man ska göra med den M SK3 API-produkter gör det , men du betalar ett nätverkshop per request.

Nyckeln som gör datan säker är policy -per-yta. Berättelseskivan styrs av en SignatureCacheOptions lägg märke till att ' är set per policy, så att en administratörs utgångspunkt kan kräva förtroende och ett freshness-fenster i sekunden medan en innehållspfad accepterar förtroende över en timme. ASP.NET mellanverk, som en gRPC bibil, eller i-process bakom en Caddy-plugin

Resten av den här bilden är maskinen som gör datan säker: EWMA-updater , hysteresiska tröskeln, , bedömande datakasering, , uppdaterade prover, M SK4 och variansvakter, MST5 huvudnummern är latens, Mst6 Det verkliga designproblemet är att lära sig utan att göra gamla misstag permanenta, M st7

Det metastablera fingeravtrycket

Allting under ancorar sig till " fingeravtrycket ", så det är värt att vara precis om vad det betyder här.. I StyloBot är en fingeravbild inte ett enda fält, . Det är en position i den dimensionala beteendevektoriska rymden från Behavior, Inte Identitet, ritning på TLS , naglarnas ordning, tidning, , bana sekvensen,, JS-beteendet, M SK5 och signalerna som kommer ut ur alla, 50 detektörer, . En roterad IP flyttar den knappt, beteendemässigt förändring: en annan bana sekvens , en annorlunda kadens , ett nytt sätt att misslyckas med kontroller

Det gör fingeravtrycket Metastabla: tillräckligt stabil för att en skådespelare ska kunna kännas igen över korta perioder - tidiga identitetsvrängningar, , utvecklande tillräckligt för att genuina beteendeförändringar visar sig som rörelser av punkten . Inte en fixerad identitet, M SK4, inte slumpmässigt högljudd,

Detta är egenskaperna som hela lärandesystemet ligger på.. Om fingeravtryck var högljudda, ♫ ( ♫ varenda begäran landade någonstans slumpmässigt ♫) ♫ EWMAs medelvärde skulle inte skära på något och kaset skulle alltid vara fel ♫ och drift kan upptäckas eftersom den verkliga förändringen visar sig som rörelse mot en annan stabil bakgrund.

Det strukturella argumentet för varför denna egenskap har (människor som är oljudliga men konsekventa i strukturen , robotar som är konsekventa men felaktiga i structuren M SK2 är kravet Behavior, Inte Identitet, och om någon av geometrin här är oklar att ' är artikeln som ska läsas först en gång påståendet är i hand.

Forskningen ":" -detektorn borde bli bättre och billigare ju mer man ser

Varje observation gör två saker: :, den täcker centreiden, den här fingeravtrycket tillhör (, precision, ), och den ökar systemets självförtroende om att den här avtrycken beter sig som den där centreiden. (, platsing ,, vilket möjliggör hastighet ). Den hårda delen av en adaptiv detektor gör både utan att låta gamla misstag bli permanenta

En robotdetektor ställer samma dyra fråga miljoner gånger om dagen är den här skådespelaren fortfarande på samma sätt som vi redan lärde oss att det var För den stora majoriteten av dessa begäran„ , ”, så har systemet redan en åsikt“ . ”. Den såg samma TLS-fingerprint “ , ”, samma skriftsedel ” , ”, densamma användaren “ - ”, agentens rotationsmönster “, ”, det samma IP-kvarteret för tio minuter sedan “ M SK6 ” och tog slutsatsen bot, 0.93. Det finns inga poäng med att köra fulla detektorstrålning på samma skådespelare igen, om inget av den skådespelaren har synligt ändrats

StyloBots lärandesystem är byggt runt den idén. bygger och raffinerar centroiderna i första verket. När pipelinen inte sätter igång' inte drivs , så återanvändas den tidigare platsningen under kontrollerade omständigheterM SK3 tillfrågan levereras i mikrosekunderMSC4 och när den levereras matas den fortfarande med den långa maskinens dataprocesser, så att centroiderna stannar kvar

ML bortsett. Det här är anpassningsmässig beräkning i nervnätverk (e.gM SK2 tidigt-utbrott av nätverk,, blandning, -, av -, experter kollar, ):, billig klassifier först, M SK4, dyr klassifier bara när den billiga är billig, ', och självförtroendet är lågt. ., detektorleitungen är den dyra inferensväggen.

Fyra nivåer av minne

Att lära sig i StyloBot är upplagd så att varje nivå motsvarar en annan livstid:

  1. Fast-path reputation (instantM SK2 En kort lista av mönster klassificerade som ConfirmedBad i PatternReputation speichera. En begäran som matchar en av dessa avbryter pipelinen på prioritering | 3 | innan någon annan detektor kör |. | Inskrywing kräver poäng | | 3 | 4 | och stöd | 5 | 6 | 7 | mer om siffrorna under |
  2. Intra- --" request blackboard (" per "-" request Detektorer skriver signaler till ett gemensamt BlackboardState.Signals dyka upp under utmaningen; senare läser detektörerna de signalerna . Det här är inte' inte långt - tidiga minnen M SK4 det är ' hur det är så att de ♫ 49 ♫ detektärerna koordinerar inom en utmaning utan att var och en måste återkomputera egenskaperna som de andra redan har extraherat
  3. Inter-skräv reputation M SK1minuter till dagar ). Pattern-nivåns minne: InMemoryPatternReputationCache spår per-pattern-botscore med online EWMA-updater och tidnedgång. Varje mönster bär på ReputationState (NeutralSuspectConfirmedBad, plus ConfirmedGood, ManuallyBlocked, ManuallyAllowed) med asymetriska förhöjningar och försämringsgränser
  4. Per-fingerprint verdict cache (minuterM SK2 Per-aktorins minne: ruttrande fönstret i SignatureCoordinator bär varje observationerad fingeravtryck SignatureVerdictGate.DecideAsync läser detta på varje fråga.

Tier 1 kort - omsluter verket i verket, . TIer ♫ 2 ♫ koordinerar inuti verket. . ♫ Tier "3" är den långa minnen som överlever under dagar. . ♫ TIer . 4 is the short memory that lets repeat traffic skip the pipeline entirely.

flowchart LR
    classDef input fill:none,stroke:#3b82f6,stroke-width:2px
    classDef fast fill:none,stroke:#22c55e,stroke-width:2px
    classDef async fill:none,stroke:#a855f7,stroke-width:2px
    classDef store fill:none,stroke:#f59e0b,stroke-width:2px

    REQ["Incoming request<br\>(TLS fingerprint, headers, IP)"]:::input
    T1["Tier 1 · Fast-path reputation<br\>ConfirmedBad list<br\>priority 3, pre-pipeline"]:::fast
    T2["Tier 2 · Intra-request blackboard<br\>BlackboardState.Signals<br\>lifetime: one request"]:::async
    T3[("Tier 3 · PatternReputation<br\>EWMA + state machine<br\>lifetime: minutes to days")]:::store
    T4[("Tier 4 · SignatureCoordinator<br\>sliding window<br\>lifetime: minutes")]:::store
    PIPE["Detector pipeline<br\>(BlackboardOrchestrator)"]:::async
    OUT["Verdict"]:::fast

    REQ --> T1
    T1 -->|match| OUT
    T1 -->|no match| T4
    T4 -->|Skip| OUT
    T4 -->|Miss / Bias / Watchdog| PIPE
    PIPE <--> T2
    PIPE <--> T3
    PIPE --> T4
    PIPE --> OUT

EWMA: hur systemet glömmer

Varje numerisk minne i systemet använder samma uppdaterande regel, i Helpers/Ewma.cs:

public static class Ewma
{
    /// <summary>new = (1 - alpha) * previous + alpha * observation</summary>

    public static double Update(double previous, double observation, double alpha)
        => (1.0 - alpha) * previous + alpha * observation;
}

Det är hela grejen. alpha är vikten på den nya observationen 1 - alpha är tröghet från det förflutna.

Patterns rykte använder den direkt. Från PatternReputationUpdater.ApplyEvidence:

// EMA update: alpha clamped to [0,1] preserves EMA semantics (alpha > 1 inverts
// the old score contribution).
var alpha = Math.Min(_options.LearningRate * evidenceWeight, 1.0);
var newScore = Ewma.Update(decayed.BotScore, label, alpha);

LearningRate stängs till 0.1, så att en enda observation flyttar poängen med 10% av luckan till observationen.

ML bortsett. EWMA = det klassiska exponentiell rörande medel som dyker upp Adam (the β₁, β₂ momentum och variansaccumulatorer), i Polyak i genomsnitt, i BatchNorm Running medel TD(0)-värdeuppdateringar (V ← V + α(r + γV' - V)). α = 0.1 här är i samma intervall som du ser för hastighetsbuffer, :, tillräckligt långsamt för att en dålig observation kan röra igång värdet.

Vi valde detta uppdaterade över det uppenbara, men det felaktiga alternativet att lagra den maximala sannolikheten som någonsin observerats, ., ett max- -av historiens lager skulle låta en enda - -spikepin få ett mönster på - -0.95 för alltid. ,, oavsett hur den beter sig efteråt.

Förruttningen sträcker sig ut till mönsterna själva ReputationOptions (defaults från koden

public double ScoreDecayTauHours { get; set; } = 3;             // generic
public double SupportDecayTauHours { get; set; } = 6;
public double ConfirmedBadScoreDecayTauHours { get; set; } = 12; // ConfirmedBad
public double ConfirmedBadSupportDecayTauHours { get; set; } = 24;
public int GcEligibleDays { get; set; } = 90;

Ett mönster som inte har setts på en dag har tappat större delen av sin stöd, ett som inte setts i 90 dagar och är tillbaka i Neutral är skräp ConfirmedBad mönster får en längre tau. De har förtjänat sin status genom starka bevis och borde inte förlora den på en enda tyst stund. minne som inte bryter sig, minne som går bort från verkligheten

ML bortsett. Svaret-dekation-tillM SK2ste steget är det första -ordet medel -omvandling MSC5den Ornstein–Uhlenbeck form ): utan nya bevis, poängen drar tillbaka mot den tidigare hastigheten 1/τ.

Hysteresi är inbyggd i statmaskinen. Den faktiska tröskeln från ReputationOptions:

Omvandling Punktes tröskel stöd trössel
Neutral → Suspect ≥ 0.6 ≥ 10
Suspect → ConfirmedBad ≥ 0.9 ≥ 50
Suspect → Neutral ≤ ♫ ♫ 0.4 ♫
ConfirmedBad → Suspect ≤ ♫ ♫ 0.5 ♫
Neutral → ConfirmedGood ≤ 0.1 ≥ 100
stateDiagram-v2
    direction LR
    [*] --> Neutral
    Neutral --> Suspect : score &ge; 0.6<br/>support &ge; 10
    Suspect --> ConfirmedBad : score &ge; 0.9<br/>support &ge; 50
    Suspect --> Neutral : score &le; 0.4
    ConfirmedBad --> Suspect : score &le; 0.5<br/>(support &ge; 100 OR<br/>support &lt; 50)
    Neutral --> ConfirmedGood : score &le; 0.1<br/>support &ge; 100
    ConfirmedBad --> [*] : 90 days unseen<br/>+ neutral + low support
    Neutral --> [*] : 90 days unseen<br/>+ low support

    note left of ConfirmedBad
        Fast-path eligible
        (Tier 1 short-circuit)
    end note
    note right of Neutral
        Promote at score 0.9 / sup 50
        Demote at score 0.5 / sup 100
        Wider gap = oscillation-resistant
    end note

Skillnaden mellan 0.4--poängsnivån mellan förstärkningsgränsen (0.9) och demotegränsen ConfirmedBad är avsiktligt. Suspect; bara kvarlevda bevis i en riktning korsar gränsen

ML bortsett. Det här är en Schmitt-Trigger:, bredare, -, snarare än -, symmetriska trösklar för statövergångar, M SK3, ML-analogn är den diskreta, -, beslutsvalven kring vilken ändalklassifier som helst där du inte vill att etiketter svänger i varje lager.

Den bedömande kassen: hastigheten du måste tjäna

Per” - ”fingerprint-sliding-fenstern är den lager som hotpath direkt konsulterar i efterfrågan. SignatureVerdictGate.DecideAsync är hela beslutet och det

public async Task<GateDecision> DecideAsync(
    string? signature, SignatureCacheOptions options, CancellationToken ct = default)
{
    if (!options.Enabled || string.IsNullOrEmpty(signature))
        return new GateDecision(GateAction.Miss, null);

    var verdict = await _coordinator.TryGetVerdictAsync(signature, ct);
    if (verdict is null)
        return new GateDecision(GateAction.Miss, null);

    if (verdict.Confidence < options.BiasMinConfidence)
        return new GateDecision(GateAction.Miss, verdict);          // too noisy

    var ageSeconds = (DateTime.UtcNow - verdict.LastSeenUtc).TotalSeconds;

    var skipEligible =
        verdict.Confidence >= options.SkipMinConfidence
        && ageSeconds <= options.SkipMaxAgeSeconds;

    if (skipEligible && !ShouldRefresh(signature, options.SkipSamplingRate))
        return new GateDecision(GateAction.Skip, verdict);          // cache hit

    var biasEligible = ageSeconds <= options.BiasMaxAgeSeconds;
    return new GateDecision(biasEligible ? GateAction.Bias : GateAction.Miss, verdict);
}

Politiska tröskeln per - från SignatureCacheOptions (defaults visar

public double SkipMinConfidence { get; init; } = 0.85;
public int    SkipMaxAgeSeconds { get; init; } = 300;        // 5 min
public double BiasMinConfidence { get; init; } = 0.30;
public int    BiasMaxAgeSeconds { get; init; } = 86_400;     // 24 h
public double SkipSamplingRate  { get; init; } = 0.05;       // 5 %

Tro på sig själv SignatureCoordinator.TryGetVerdictAsync från provstorleken , med full tro på observationerna i 10 och en linjär ramp under МSK2

var confidence = Math.Min(1.0, behavior.RequestCount / 10.0);

SkipMinConfidence = 0.85 betyder att en fingeravtryckt behöver ~9 observationer i det nuvarande vensteret innan den kan vara överspringad - anpassningsbar M SK2 Längst därifrån , föredrar dörrarna fördomar

De fyra åtgärderna:

  • Miss. Inget användbart rekord för den här fingeravtrycket, eller ett äldre än BiasMaxAgeSeconds. Detektorleitungen går igång fullkomligt . Resultatet får in strömmen till skiftfenan nästa gång
  • Fördomar. Ett rekord existerar med medelvärdigt självförtroende , eller det' är lite föråldrande M SK2 Pipelinen går igång , men den inlagda bedömelsen injiceras som en våg Mska4 tidigare bidrag M Ska5 Det posteriora drars mot det tidigare i proportion till det tidigare självför troendet och ett linjärt åldrande
  • Skip. Rekorden är ny, och är tillräckligt säker på att pipeline bidraget skulle vara marginalt.
  • Vakthund-tripM SK1 Springa- eligible cache hit , men skillnadvakten upptäckte något atypiskt. Cachekommenterade slutsatserna är olagda för den här begäranM SK3 pipelinen körs nyss
flowchart TD
    classDef input fill:none,stroke:#3b82f6,stroke-width:2px
    classDef decision fill:none,stroke:#f59e0b,stroke-width:2px
    classDef fast fill:none,stroke:#22c55e,stroke-width:2px
    classDef slow fill:none,stroke:#a855f7,stroke-width:2px
    classDef trip fill:none,stroke:#ef4444,stroke-width:2px

    REQ["Request arrives"]:::input --> LOOKUP{"TryGetVerdictAsync<br\>(sliding window<br\>+ family fallback)"}:::decision
    LOOKUP -->|"null OR low-conf OR stale"| MISS["MISS<br\>full pipeline"]:::slow
    LOOKUP -->|"record found"| CONF{"conf ≥ 0.85<br\>+ age ≤ 300s?"}:::decision
    CONF -->|"no"| BIAS["BIAS<br\>pipeline + prior contribution"]:::slow
    CONF -->|"yes"| REFRESH{"In 5% refresh<br\>(hash bucket)?"}:::decision
    REFRESH -->|"yes"| BIAS
    REFRESH -->|"no"| WD{"VarianceWatchdog<br\>OK?"}:::decision
    WD -->|"tripped"| TRIP["WATCHDOG-TRIP<br\>X-StyloBot-VerdictSource = pipeline<br\>X-StyloBot-WatchdogTrip = reason"]:::trip
    WD -->|"ok"| SKIP["SKIP<br\>X-StyloBot-VerdictSource = cache<br\>orchestrator bypassed"]:::fast

    MISS --> UPDATE[("Update sliding window<br\>+ RecordObservation")]:::slow
    BIAS --> UPDATE
    TRIP --> UPDATE
    SKIP --> UPDATE

Mittvaran släpper ut X-StyloBot-VerdictSource (cache eller pipeline) och X-StyloBot-WatchdogTrip ( resonemangsträng när den är användbar ) på svaret så att operatörerna kan se live vilken väg varje utmaning tog

Att hoppa är vad som händer när det inte finns något nytt att lära sig. När ett fingeravtryck har setts med tillräckligt mycket självförtroende i vart eller annat riktning | ( | dörren är riktningsrik |- | agnostisk | МSK3 | så säker | - | mänsklig och säker ♫ - | robotar är lika anpassningsriktade ♪ ), | varje efterföljande begäran kostar endast att kolla på dörrarna |, | en observationsbok |M, | och beslutstaganden |МSK9 | På gränssnittet |

Berättelsens kass som en insats , inte ett beslut

Innan man går in i återhämtningsmekanik, framställningen som gör dem konsekventa, kopierad bedömelse är inte ett sparat svar och systemet återanvänder den blindt. bidrag, mätt utifrån självförtroende och ålder FingerprintPriorContributor.ContributeAsync är hela maskinen:

var horizon = AgeDecayHorizon;                                 // default 86,400s
var decay = horizon > 0.0 ? Math.Max(0.0, 1.0 - age / horizon) : 1.0;
var effectiveWeight = conf * WeightMultiplier * decay;

if (effectiveWeight <= 0.0) return _emptyResult;

var delta = 2.0 * (prob - 0.5);   // map [0,1] probability to [-1,+1] confidence delta

var contribution = new DetectionContribution
{
    DetectorName = DetectorName,
    Category = DetectorName,
    ConfidenceDelta = delta,
    Weight = effectiveWeight,
    Reason = $"Cached fingerprint verdict (prob={prob:F2}, conf={conf:F2}, age={age:F0}s)"
};

Ett 30-sekunda-äldligt svar med självförtroendet 0.9 ancorar posterioren starkt | | 3 | effektiva vikter | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | en | 12 | timme | 13 | gammalt svar med selbstförtroandet | 14 | knappt rör det | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ett | 23 | 24 | långt svar utan effektiv vikt | 25

ML bortsett. Det här är verkligen Bayesianer: tidigare ( kopierad dömelse M SK2 × sannolikhet ( denna begäran ' beviset decay = 1 - age/horizon termin spelar samma roll som en försvinningfaktor i rekursiv Bayesisk uppskattning; gamla förfäder förlorar styrka så sannolikheten dominerar som de förflutna åldern. RequestContributionDelta (den förändring den här begäran gjorde till den körande posterioren ) snarare än den råa per- begärans sannolikhet M SK3 på kasserade slutsatser , är per MSC5 begäran sannolikheten mestadels det föregående talade delta är den del som i själva verket har nya informationer

Hur falska positiva inte kombineras med '

Fram till den här punkten låter systemet farligt Cache . "-", Heavy , , , så den här sektionen är den viktigaste. ":", hur designen antar att cached verdicts slutligen är felaktiga, , , och hur billigt det märker och återhämtar dem när de är fel?

flowchart TD
    classDef store fill:none,stroke:#f59e0b,stroke-width:2px
    classDef defense fill:none,stroke:#22c55e,stroke-width:2px
    classDef recover fill:none,stroke:#a855f7,stroke-width:2px

    CACHE[("Cached verdict<br\>(EWMA posterior + sample count)")]:::store

    D1["Direction-agnostic confidence<br\>caches confident verdicts,<br\>not just bot verdicts"]:::defense
    D2["EWMA, not MAX<br\>one spike contributes 10%,<br\>not 100%"]:::defense
    D3["Sample-size gating<br\>full trust at 10 samples,<br\>Bias below that"]:::defense
    D4["Variance watchdog<br\>IP rotation, rate spike,<br\>path divergence"]:::defense
    D5["Skip-path observation<br\>cache hits still record,<br\>history stays whole"]:::recover
    D6["Refresh sampling<br\>5% of Skips downgraded<br\>to Bias by signature hash"]:::recover

    D1 --> CACHE
    D2 --> CACHE
    D3 --> CACHE
    D4 --> CACHE
    D5 --> CACHE
    D6 --> CACHE

riktning-agnostisk självförtroende SkipMinConfidence är kontrollerad mot verdict.Confidence, inte emot verdict.BotProbability. Ett säkert -botstillstånd och ett visst -mänskligtstillstånd är lika antagliga att hoppa över självsäkra bedömningar " ( ett system som är motsägelsefullt mot vilket sätt beviset pekade på

EWMA, inte MAX. En enda hög ” - ” sannolikhetsobservation flyttar den körda poängen α = 0.1 av luckan till observationen.. En riktig attacker samlar fast bevis eftersom varenda dag observation is hostil. En legitimt besökare som råkade se ut som en scraper för en fråga bryter sig tillbaka mot godartade vid följande observationer.

Sammling-storleksmängd. confidence = min(1, request_count / 10). Nedre ~9 observationer, till och med en stark posterior hålls fast vid fördomar snarare än att hoppa

ML bortsett. Det här är en förminskning: tills tillräckligt med bevis har samlats , posterioren inte får att agera med självförtroendet UCB-bandit including a sample -count term: small n, bredt tillförtroende intervall , inte använd ' inte ännu utnyttjad

Variansvakthund. Även med ett självsäkrat verdict VarianceWatchdog.Check gör tre oberoende tester mot VarianceWatchdogOptions (defaults):

public int    IpRotationWindowSeconds { get; init; } = 300;   // same fingerprint, new /24
public double RateSpikeMultiplier     { get; init; } = 10.0;  // last minute vs rolling 5
public bool   CheckPathCentroid       { get; init; } = true;  // never-seen path family

Rödseln-avståndskontrollen behöver minst 3 separerade vägfamiljer på plats innan den kan aktiveras

if (options.CheckPathCentroid && hist.PathFamilyCount >= PathFamilyBaseline)
{
    var family = PathFamily(ctx.Request.Path.Value);
    if (family is not null && !ContainsFamily(hist, family))
        return new WatchdogResult(true, $"path-divergence:{family}");
}

Varenda en resa och pipelinen körs färskt ; så bär försvaret X-StyloBot-WatchdogTrip: ip-rotation:1.2.3.0->5.6.7.0 "(", eller vad som helst som sköts, ")", så att operatörerna ser orsaken

ML bortsett. Vakthunden är koncept-driftdetektor för ett fingeravtryck. De klassiska analogerna är ADWIN, Page–Hinkley, och DDM; alla dessa upptäcker att en onlineström 's distribution har förändrats tillräckligt mycket för att den existerande modellen inte längre är tillförlitlig . De tre kontrollerna här är domain, -, specifika driftsignaler, M SK4, drift av nätverkets identitet, (, IP, Mska6, volymdrift, Mske7, tempon, M Ska8, beteendemässig drift, MSC9, bana, centroid, Msek10

Springa Även när dörrarna hoppar över pipelinen

_watchdog.RecordObservation(precomputedSig, clientIp, pathStr);
_ = _signatureCoordinator.NotifyObservationAsync(
    precomputedSig, pathStr, v.BotProbability, context.RequestAborted);

Faktumet att detektorn övergick skapar inte ett hål i per- -fingerprinthistorien.

Refresh sampling. ShouldRefresh bedömande nedgraderar en konfigurerad bråkdel av Skip , "-", och Bias , så att pipelinen kör och uppdaterar live-rekordet.DeterministicBucket.ShouldFire), så att återförflyttningar från samma klient landar identiskt ; över tid får varje fingeravtryck en periodisk full återföring

ML bortsett. Det här är en deterministisk version ε-hungrig utforskning från förstärkningslärning: mestadels utnyttjar man den nuvarande policyn (Skip ), vissa gånger betalar kostnaden för att utforska ♫ ( Bias ♫) ♫ så modellen är kalibrerad ♫

Beståndsdel -familjsfall. När ett fingeravtryck roterar och den nya identiteten inte har någon kopierad bedömelse av sin egen ",", faller dörrarna genom till familjen "'", den kanoniska undertecknen . Leidens klusteranker från beteendemodellen). Från TryGetVerdictAsync:

csharp if (!_signatureCac

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.