# StyloBot-julkaisusarja: testaus siitä, mikä onnistui

*Miten testataan paljastaja, jonka vastauksen odotetaan muuttuvan oppiessaan?? Tämä artikkeli koskee BDF:tä, Behavioural Definition Formatia, joka tekee StyloBotin testikelpoiseksi?*

[<img src="/articleimages/stylobot-logo.svg" alt="StyloBot" width="120" />](https://www.stylobot.net)

> **StyloBot -sarja**
> 
> 1. [**Käytänne, Ei identiteettiä**](/blog/stylobot-fingerprint): miksi StyloBot mallistaa asiakkaita käytännöllisesti
> 2. [**Behaviour-Aware ASP.NET UI**](/blog/behaviour-aware-ux): palvelijaM SK1 luovutti pintansa kyseisen havaitsemistuloksen yli
> 3. [**Pitkällä aikavälillä tapahtuvan -käynnissä olevan .NET-palvelujen rajaton kasvun löytäminen ja korjaaminen**](/blog/stylobot-release-reliability):, luotettavuuden kurinalaisuus, joka pitää moottorin tuskallisena tuotannossa
> 4. [**Behaviour-Aware TypeScript UI**](/blog/typescript-sdk): ExpressM SK1 Fastify, ja hakukonekomponentit
> 5. [**Sidecar-arkkitehtuuri**](/blog/sidecar-architecture): miten havaitsemismoottori liitetään muihin kuin -.NET-palkkiin
> 6. [**Oppiminen nopeuttamaan**](/blog/stylobot-release-learning): mukautuva oppimisjärjestelmä, , neljä,- tasotasoinen muisti ja , tuomiovarasto
> 7. **Todistuksen testaaminen, joka ei jää rauhaan**: tarkastusta koskevat säännökset : yksi BDF-tietokanta hallinnoi regressiaa M SK2 lastausta, , ja kalibrointia
> 8. [**StyloExtract - paikallisen oppimisen HTML:n Markdown-muuttaja**](/blog/stylobot-release-styloextract): HTMLM SK1Markdown-laaja, joka on päällekkäinen tunnistajan kanssa , walkinger bug lucidVIEW caught, ja dogfood loop, joka teki siitä rehellisen

<!--category-- ASP.NET, StyloBot, Bot Detection, Testing, Architecture -->
<datetime class="hidden">2026-06-01T10:30</datetime>

Luotettavuuden kurinalaisuus on [Rajattoman kasvun löytäminen ja korjaaminen](/blog/stylobot-release-reliability); mukautumiskoulutusjärjestelmä [Oppiminen nopeuttamaan](/blog/stylobot-release-learning); lähde osoitteessa [github.com/scottgalM SK2stylobot](https://github.com/scottgal/stylobot).

[TOC]

---


## Miten testataan jotakin, joka oppii?

Tämä on StyloBotin aiheuttama epämiellyttävä kysymys, eikä se ole retorinen.

Tavallinen testauspisto pitää tehtävän paikallaan: input X palauttaa output Y. Se toimii silloin, kun testattavana oleva asia on vakaaM SK2 StyloBot ei ole tarkoituksellisesti vakaa kyseisellä tasolla . Se kerää käytännöllisiä todisteitaMSC4 yksi ainoa pyyntöMST5 päätös riippuu itse pyynnöstäMst6 sormenjäljestäMSt7 sen opitusta arkkityypin ankkurista tapahtuvasta ajostaM st8 istunnon käytöstäM St9 ja siitä, onko järjestelmä jo nähnyt tarpeeksi, jotta se voisi siirtyä suoraan nopeaan suuntaanM ST10 Jokainen sormenjälki alkaa pistonneella lähimmän arkkityyppiin M T11 edeltäjänsä jäljeen jäljelleM S T12 kun uusia havaintoja aloitetaan, se liikkuuM TS13 ja liikkuvuus on itse signaaliMTS14 Metatabelinen sormenjälkeen sovittelija ratkaisee meluisen vektorin vakaalle identiteettiin kahden toimenpiteen välityksellä. [Oppiminen nopeuttamaan](/blog/stylobot-release-learning).)

Pyynnön tuomio 20, sen jälkeen, ei ole pyynnön toimenpide 20. Se on toimenpite pyyntöjen toimenpiteiden SSK3 kautta 20. Näin ollen testaustarkoitus ei ole lainkaan pyyntöM SK5 Kyse on järjestelmän käyttäytymisestä niiden järjestyksessä

Se ei salli `Assert.Equal`. Kysymys, jonka testi voi esittää, ei ole enää "pyy X:n palauttamispäätökseen YM SK2 Siitä tulee SSK3, kun otetaan huomioon tämä tyyppinen menettelytapa, onko järjestelmä lähentynyt oikeaan vastaukseenMSC5 oikeista syistä

Lähimmät .NET-analogeet ovat [Tarkistetaan](https://github.com/VerifyTests/Verify) ja [Fs-tarkastus](https://github.com/fscheck/FsCheck), mutta BDF ei ole kummankaan osapuolen kanssaM SK1 Verify hyväksyy artifactin, ja epäonnistuu rakentamisessa millään täsmällisellä diff-arvolla . FsCheck vahvistaa ominaisuuksia sattumanvaraisesti tuotuihin tuloksiin nähdenMSC4 BDF sijoittuu niiden välilleMST5 hyväksytty artifact on käytännöllinen määritelmäMSV6 mutta passiehto on todennäköinenM SV7 Ei MSCV8onko output vastannut tätä snapshotia?MSV9 mutta SMSV10?onko tämä jakelu lähentynyt rajan odotettavaan puoleen?M SV11 oikeat signaalit ovat mukana?M Sv12

## Yksi käytännöllinen määritelmä, kolme tarkastusjärjestelmää

Sääntö, joka tekee BDF-asiakirjasta helppotajuisen: ei ole testitapaus. Se on *toimeenpanokelpoinen käyttäytymissopimus*, määritelmä siitä, miten luokka käyttäytyy clientin kanssa

1. **Toistetaan** yhdentymisjärjestelmän kautta, todellisen orkestraatorin vastainen pyyntö kerrallaan, signaalin saaminenM SK2virtaregressionit, joita yksiköiden ryhmä ei voi nähdä .
2. **Re-sampled** alapuolella [k6](https://k6.io/), monet samanaikaiset virtuaaliset käyttäjät laativat tuoreen ajankohdan samasta määritelmästä , realistisen kuormituksen aikaansaamiseksi
3. **Tarkasteltu** todellisiin signaaleihin nähden todelliset mittaukset, kalibrointivirran kiinnittämiseksiM SK1

```mermaid
flowchart TD
    classDef def fill:none,stroke:#3b82f6,stroke-width:2px
    classDef rig fill:none,stroke:#a855f7,stroke-width:2px
    classDef out fill:none,stroke:#22c55e,stroke-width:2px

    BDF["BDF behavioural definition<br/>clientProfile · timingProfile<br/>requests · evidence · labels"]:::def

    Replay["Integration replay<br/>slim form · real orchestrator<br/>cache disabled · identity reset"]:::rig
    K6["k6 load harness<br/>full form · re-sampled per VU<br/>burst + jitter"]:::rig
    Calibration["Calibration audit<br/>claimed evidence<br/>vs measured signals"]:::rig

    Signals["Signal-flow regressions caught<br/>merged ev.Signals reaches<br/>dashboard · persistence · threat report"]:::out
    Metrics["Load envelope verified<br/>latency · detection_rate<br/>burst_detected"]:::out
    Drift["Calibration drift surfaced<br/>stale claims · aged signatures<br/>moved detection surface"]:::out

    BDF --> Replay --> Signals
    BDF --> K6 --> Metrics
    BDF --> Calibration --> Drift
```

Regression, loadM SK1 ja kalibrointi ovat yleensä kolme testausjärjestelmää, joissa on kolme todellisuuden lähdettä, jotka vaihtelevat toisistaan.

## Miksi yksiköiden testit jäävät epäonnistumisluokkaan

Tämän työn ensimmäisessä versiossa oli satoja kutakin ”-”-detektoryksikköä testaavia kokeita, joissa käytettiin mallikokeuksia ja pakkausmerkintöjä.

Esittelijä yhdistää puheenvuorot yhdeksi ainoaksi `ev.Signals` sanasto, joka kuluttajien downstreamin osalta (dashboard `primary_signature` sulautuneesta pinta-alasta ei tule minkäänlaista virhettä.- detector unit test : detector still ran , contribution still carried the signal , it just stopped reaching anyone who needed it . dashboard ' fingerprint table goes blank . Persistence skips the row

Tämä ei ole hypoteettinen [signal-sopimusasiakirja](https://github.com/scottgal/stylobot/blob/main/docs/architecture/signal-contracts.md) kirjaa täsmälleen tämän taantumisen: muutoksen, joka lopetti yhdistelmäsignaalien yhdistämisen M SK1 selviytyi kuusi päivää tuotannossa huolimatta 1957 ydintestien läpikäymisestä" koska SSK4yksiköiden testit vahvistettiin todennäköisyydellä ja osuuden laskennalla `evidence.Signals`."

Integraatiotesti [`BdfReplayTests.Integration.cs`](https://github.com/scottgal/stylobot/blob/main/src/Mostlylucid.BotDetection.Orchestration.Tests/Integration/BdfReplayTests.Integration.cs) on suora syy siihen, miksi se on olemassa:

> Järjestelmä on olemassa sen vuoksi, että (onnettomuusluokkaan kuuluvat `ev.Signals` hidastuu hiljaisesti, kun orkesteri lopettaa yhdistävän signaalin) ei epäonnistu millään yksiköllä tehtävässä testissä

Järjestelmä ei ole toiminto; se on putki, jonka arvo on mitä tahansa, joka tulee sulautumasta sen jälkeen kun kaikki osallistujat ovat suorittaneetM SK1 ainoa tapa vahvistaa tämä on suorittaa todellinen pyyntö todellisen järjestelmän kautta ja tutkia sulautuneen pinta-alan. sulautumisen mokkiminen voittaa testin .

## BDF: käytännöllinen määritelmä , ei käännetty testi

BDF (Behavioural Definition FormatM SK1-tietokanta kuvaa, miten *luokka* ohjelmien mielenkiintoiset osat ovat tilastolliset: ohjelmia koskeva profiili, joka sisältää jakeluidentiteetinM SK3 aikatauluprofiili, jossa määritellään purkaminen - käyttämällä M SK5 nopeutettujen viivästysten sijasta nopeutettuja sampling-sääntöjä, käytännöllisiä signaaleja koskevien painotettujen lähtökohtien näyttötaulukkoMSC7 ja luottamuksen ennakkotapaus[`bot-signatures/python-requests-bdf.json`](https://github.com/scottgal/stylobot/blob/main/bot-signatures/python-requests-bdf.json)):

```json
{
  "scenarioName": "python-requests-bdf",
  "scenario": "A bot/scraper using python-requests/2.31.0 with specific behavior patterns.",
  "confidence": 0.85,

  "clientProfile": {
    "userAgent": "python-requests/2.31.0",
    "cookieMode": "none",
    "headerCompleteness": "minimal",
    "clientHintsPresent": false,
    "robotsConsulted": false
  },

  "timingProfile": {
    "burstRequests": 10,
    "delayAfterMs":      { "min":   20, "max":   150 },
    "pauseAfterBurstMs": { "min":  500, "max":  2000 }
  },

  "requests": [
    { "method": "GET",  "path": "/",                "expectedStatusAny": [200,301,302], "expectedOutcome": "indexing", "successCondition": "any 2xx" },
    { "method": "HEAD", "path": "/admin",           "expectedStatusAny": [200,403],     "expectedOutcome": "indexing", "successCondition": "any 2xx" },
    { "method": "GET",  "path": "/api/data?page=1", "expectedStatusAny": [200,403],     "expectedOutcome": "indexing", "successCondition": "any 2xx" },
    { "method": "GET",  "path": "/api/data?page=2", "expectedStatusAny": [200,403],     "expectedOutcome": "indexing", "successCondition": "any 2xx" },
    { "method": "GET",  "path": "/api/data?page=3", "expectedStatusAny": [403,404],     "expectedOutcome": "indexing", "successCondition": "any 4xx" }
  ],

  "labels": ["Scraper", "RobotsIgnore"],

  "evidence": [
    { "signal": "interval_ms_p95", "op": "<", "value": 200,           "weight": 0.35 },
    { "signal": "requestInterval", "op": "<", "value": "burst <150ms", "weight": 0.70 }
  ],

  "patterns":  { "requestInterval": "burst <150ms" },
  "reasoning": "The bot/scraper uses python-requests/2.31.0 to access various endpoints, including the root path and admin pages, while also enumerating API paths and testing different HTTP methods."
}
```

Suurin osa pinta-alasta on tilastollista, ja suurin osa siitä tekee BDF:stä *määritelmä* pitemmälle kuin test-skripti. [`docs/bdf-v2-schema.json`](https://github.com/scottgal/stylobot/blob/main/docs/bdf-v2-schema.json).)

**`confidence` on aikaisempi, ei väiteM SK1** 0.85 sanoo " tämä pitäisi laskeutua korkealle-luottamusbot, kun järjestelmä on terveellistäM SK3 Rigi ei tarkista kypsä tulos on samaa kuin 0.85; se tarkistaa tuomion laskeutuu bot-puolelle rajastaMSC5 Enemmistö on vyöhyke allekirjoituksenaMST6 kirjoittaja \MST7\LLM tai ihminen\)\ uskoo, että järjestelmän pitäisi saavuttaa \mST9\ Drift täällä on kalibrointi tarina \ MST10\ ei yksittäinen \ mST11\ testaushäiriö \ .\

**`clientProfile` on asiakasluokka.** `cookieMode: none` on *Luettelo* käyttäytyminen (ei koekunttiaM SK1 jokainen pyyntö alkaa tuoreena ), ei erityistä otsikkoa M SK3 `headerCompleteness: minimal` sanoo, että "pyynnön esittäjällä on vain se curl, jonka luokkakirjastot ovat määrittäneet ",todellisuus pyynnöistä, joita tämä pyyntöjen esittelijä antaaM SK3 ei kiinteää otsikoluetteloa *luonteeltaan* tilanteesta.

**`timingProfile` on näytteenottosääntö.** `burstRequests: 10` lisäys `delayAfterMs: {min: 20, max: 150}` lisäys `pauseAfterBurstMs: {min: 500, max: 2000}` määrittelee generaattorin: kymmenen pyyntöä yhdenmukaisina - sattumanvaraiset puutteet M SK2 to SSK3ms\, ja sen jälkeen yhdenmukainen- sattumallinen pausi |500 to [2000ms], toistaaMSC9 sama BDF, joka toistetaan kahdesti, tuottaa kaksi eri pyyntövirtaa saman tilastollisen jakautumisen kanssa.

**`evidence` on painotettu lähtökohta yli signaaleja.** Jokainen merkintö on vaatimus lomakkeesta `signal OP value, weight w`. `{signal: "interval_ms_p95", op: "<", value: 200, weight: 0.35}` BDF väittää tilastotasolla, että : ei ole "pyynnön \7 palannut botin \ =todellisena \ МSK11\ mutta SSK12kuluttajan luoman väestön olisi tuotava intervaltijakauma, jonka pM SK13 jää alle | 200ms". | Scenario, jonka todisteet poikkeavat siitä, mitä käynnissä oleva järjestelmä mittaa, on allekirjoitus, joka on vetäytynyt kalibroinnin ulkopuolelle.

**`labels` ovat taxonomia.** `[Scraper, RobotsIgnore]` on luokitus, jonka skenaario generoitiin . Labelin ajosuunnitelman valinnassa vain (run-laadun hallinnassa `Scraper` skenaariot, poistaa `RobotsIgnore`) ilman, että kukaan kirjoittaa regexiä skenaariojen nimiä kohtaan

**`requests` kuvataan, mitä klientti tekee, ei sitä, minkä pitäisi tapahtua seuraavaksiM SK1** `expectedStatusAny: [200, 403]` sallii joko onnistuneen fetchin tai suoran blockin,, koska molemmat ovat päteviä tuotantoja vihollisen radan tutkimuksessa. `expectedOutcome: indexing` on *client'in tarkoitus* (enumerate API-sivutM SK1 ei palvelijaa 'vastaus. `successCondition: "any 4xx"` liikkeellä `/api/data?page=3` on otettava huomioon, että järjestelmässä ei ole mitään epäsymmetristä sen välillä, mitä klientti yrittää tehdä ja mitä järjestelmän pitäisi tehdä siitä.

### BDF:n ja centroidin sama ajatus:, , käännettynä

Sana *määritelmä* on kuormitusta-kantaaM SK1 ja se yhdistää BDF:n StyloBotin keskipisteessä olevaan suunnitelmaan'detektoriinMSC3. Motori luokittelee liikenteen käyttäytymiseen **centroidit**: viitearvon kohdassa, joka on [Käytänne, Ei identiteettiä](/blog/stylobot-fingerprint), kukin oppinut ankkuri yhtäläisesti liikkuvan asiakkaiden ryhmälle

BDF:ssä kuvataan samaa asiaa (clientin luokitus ), jossa rooli on käännettyM SK2 centroidi on **tunnustaja**: se pyytää "ko tämä pyyntö näyttää siltä, että luokka **Generatorti**: se vastaa " tuottaa pyynnön virtaa kyseisestä luokastaM SK2 Sama toimintatapa, vastasuuntainen suuntaMSC4 joka on juuri se, mikä tekee BDF:sta uudelleenlaadittavan ja keskinäisen ei-

Moottori's [`SignatureToBdfMapper`](https://github.com/scottgal/stylobot/blob/main/src/Mostlylucid.BotDetection/Behavioral/SignatureToBdfMapper.cs) bridges the two: se ottaa todellisesta liikenteestä kerätyn käyttäytymistä koskevan allekirjoituksen ja kirjoittaa sen takaisin takaisin BDF:ksi, jonka voi lukea ja joka voidaan kääntää uudelleen

Joten [`bot-signatures/`](https://github.com/scottgal/stylobot/tree/main/bot-signatures) corpus ei ole vain testausväline; se on käytännöllisten määritelmien kirjasto, yksi asiakirja kutakin luokkaa kohden StyloBot syyt siitä . siellä syntyneet allekirjoitukset olivat mallia M SK3`ministral-3:3b`, kutakin luetteloa vartenM SK1s README) annetut ohjeet, jotka kuvailevat Client-perhettä, joka joutuu kohtaamaan joukon loppukohtiaMSC3 ja sama pinta on avoin ihmisen laatijalle . kirjoittakaa BDF:tä uudelle scraper-perheelle, ja teillä on käyttäytymisen määritelmäMST5 regressi-esitys~MST6~ ja kuormitus~-~test-tulos yhdessä asiakirjassa.

A slimmed-down-replay -muoto elää [`test-suites/{bots,humans,adversarial}/*.bdf.json`](https://github.com/scottgal/stylobot/tree/main/test-suites) vain `requests[].method/path/headers/delayAfter` + pehmeä `expectedDetection`. Tämä alakokonaisuus on se, mitä integrointilaitoksessa sijoitetaan uudelleensovittamisen loppupisteeseen , jolla ei ole mahdollisuutta synteesoida jakautumiskäyttäytymistä yhdestä uudelleensoittamisesta.

## Jälleensovittamisen loppukohta kulkee reaaliorkestraatorin kautta

Integrointilaitoksessa asetetaan kaikki skenaariot `POST /bot-detection/bdf-replay/replay`, loppukohta, joka on mukana tuotteessa[`BdfReplayEndpoints.cs`](https://github.com/scottgal/stylobot/blob/main/src/Mostlylucid.BotDetection/Endpoints/BdfReplayEndpoints.cs)), ei testaushankkeessa . Sijoittaminen on kuormitustaM SK2kantaa: loppupiste ratkaisee `IDetectionOrchestrator` DI:stä ja kulkee sen kautta, kuka on tällä hetkellä rekisteröity, `DetectionPolicy.Default`. Edellisessä versiossa vahvistettiin erityinen orkesteri ja peiteltyjä regressiivejä vaihtoehtoisessa (Väliaikainen)lähestymistapaM SK3 uudelleenliittäminen DI:n kunniaksi vahvisti, että

Koska loppupiste elää tuotteessa, se on suljettu kuin tuotteiden pinta. `BdfReplay` on poikkeuksellisesti suljettu; kun se on aktivoitu, puhelut edellyttävät voimassa olevaa `X-BdfReplay-Api-Key` header and pass a per-IP rate limit, so the replay route is not a detection bypass left lying aroundM SK2 The rig authenticates with that key . The point is to exercise the real pathMSC4

```mermaid
flowchart LR
    classDef test fill:none,stroke:#3b82f6,stroke-width:2px
    classDef proc fill:none,stroke:#a855f7,stroke-width:2px
    classDef out fill:none,stroke:#22c55e,stroke-width:2px

    Test["BDF replay rig<br/>authenticated with API key"]:::test --> Endpoint["Product replay endpoint<br/>identity reset · cache disabled"]:::proc
    Endpoint --> Orch["Current DI-registered<br/>orchestrator"]:::proc
    Orch --> Signals["Merged ev.Signals"]:::proc
    Signals --> Assert["Contract assertions<br/>verdict · signal probes<br/>convergence bound"]:::out
```

Eräs tahallinen politiikka sallii uudelleensovittamisen, kun sallitaan: allekirjoituksen verdict cache per-

```csharp
var replayPolicy = Policies.DetectionPolicy.Default with
{
    SignatureCache = Policies.DetectionPolicy.Default.SignatureCache with { Enabled = false }
};
```

Cache's Skip-tie ohittaa täysin sovittelijan, kun ensisijaisella allekirjoituksella on luottamuksellinen varattu tuomio [Oppiminen nopeuttamaan](/blog/stylobot-release-learning)); pyynnöstä, jolla mitataan havaitsemisselvityksen täsmällisyyttä ja signaalivirtaa, se peittää pyynnön käyttäytymisen, jonka pyynnössä yritetään vahvistaa.

Scenariot on myös eristetty toisistaan. Jokainen skenaario saa ainutlaatuisen synteettisen IP:n, joka on peräisin deterministisesta xxHash-nimestä M SK1a `192.0.x.y` address from the RFC 5737 TEST -NET range), so subnetM SK3 reputation never bleeds between scenariosMSC4 And the rig calls `POST /bot-detection/bdf-replay/reset-identity` ennen kuin kukin skenaario lyhentää sormenjälkivarastoa; ilman sitäM SK1 skenaaria N perii created fingerprints scenarios |1.. |N | -1 | ja peritään - |scenarion vakautta koskevat toteamukset orderingiksi

## Toteutuminen muulla kuin -deterministisella pinnalla

Järjestelmä esittää kolme väitettä kussakin skenaariossa. Jokainen on malli tällaisten testijärjestelmien testaamiseenM SK1

**Tuomittu tuomio, ei perinpohjainenM SK1pyynnön tuomio .** Bot-skenaariot väittävät `last.Actual.IsBot` on totta; inhimilliset skenaariot vahvistavat *enemmistö* todetaan, että jokaisella yksittäisellä pyynnöllä testaus yhdistettäisiin ajoreittiin, joka on kaukana arkkityypin ankkurista.

```csharp
// Some heuristics legitimately escalate on outlier rates; assert majority human, not all.
var humanCount = response.Results.Count(r => r.Actual is { IsBot: false });
var botCount = response.Results.Count - humanCount;
Assert.True(humanCount >= botCount,
    $"{response.ScenarioName}: {botCount}/{response.Results.Count} requests classified as bot, " +
    $"expected majority human. Last verdict: {last.Actual!.RiskBand} prob={last.Actual.BotProbability:F2}");
```

**Named signal probes, ei signaalien lukumäärääM SK1** Signaalivirrat tutkitaan kutakin avainta kohden, ei kokonaisuudessaan . Lukulause on brittillinen: uusi tunnistus, joka antaa uuden signaalin, peittää olemassa olevan kriittisen numeron menetyksen M SK3 luku pysyy samanlaisenaMSC4 puuttuuMST5 avaimen identiteetti on näkymätöntäMSV6 kutakaan avainta kohti koskevassa kyselyssä mainitaan kuluttaja, joka rikkoo häiriöviestissään

```csharp
Assert.True(probes.TryGetValue(SignalKeys.PrimarySignature, out var hasSig) && hasSig,
    $"{scenarioName}: {SignalKeys.PrimarySignature} missing from ev.Signals — " +
    "RequestPersistenceService skips persistence, dashboard fingerprint table goes blank");
```

Ongelmaviesti on testi's spec. Kolme kuukautta myöhemmin teidän ei tarvitse muistaa, miksi signaali oli tärkeä ; väite kertoo teille

**Rajoitettu lähentyminen, ei täsmällistä tasa-arvoaM SK1** Metastatiivinen sormenjälkien sovittelija ratkaisee meluisen vektorin vakaalle identiteetille. Vektorin koostumukseen sisältyy istunnon mittasuhteet (path entropyM SK2 istuntoikä) joka ajoittuu pyynnöstä toiseenMNK4 niin että kaksiMSC5pass-yhteyttä voidaan toisinaan pudottaa vapaan vyöhykkeen ulkopuolelle ja kohdentaa toisiinsa. `ceil(N/2)` erottomat sormenjäljet" on todellinen sopimus

```csharp
var distinctFps = withFingerprints
    .Select(r => r.Actual!.IdentityFingerprintId!)
    .Distinct(StringComparer.OrdinalIgnoreCase)
    .Count();
var allowed = Math.Max(1, (int)Math.Ceiling(response.Results.Count / 2.0));
Assert.True(distinctFps <= allowed,
    $"{scenarioName}: {distinctFps} distinct fingerprints across {response.Results.Count} requests " +
    $"(allowed {allowed}). The matcher isn't converging — every request is allocating new, suggesting " +
    "vector composition is unstable or LooseThreshold is unreachable.");
```

`ceil(N/2)` ei ole ihmettä. Se kodifioi politiikkaaM SK1 ensimmäinen pyyntö jakaa aina ; seuraavat pyynnöt olisi vastattava pääasiassa L:n välityksellä *joka kerta* vaatimus on regressiivinen. Raja on riittävän löyhä, jotta se absorboi melua, jonka sovittelija on suunniteltu absorboimaanM SK1 riittävän tiukka, jotta sen katkaisemaan epäonnistumismuodon, jossa se lopettaa lähentymisen kokonaan

Kaikilla kolmella mallilla on yhteinen omaisuus: ne väittävät sopimuksessa, että käyttäytymisen on tarkoitus tyydyttää–, ei tietyillä numeroilla, joita nykyinen täytäntöönpano tuottaa–M SK2 Kun täytäntöönpano muuttuu –, testi pysyy ennallaan, jos sopimus säilyy ennnallaan–. Tämän vuoksi ei-deterministinen testi pysyä vakaana–MSC6

## Load: sama korpus paineessa

BDF-tietokanta on vain JSON. Integraatiolaitoksessa kuluu pienimuotoinen muotoM SK1 Load harnessissa kuluu koko tilastollinen muoto : [`scripts/convert-bdf-to-k6-v2.csx`](https://github.com/scottgal/stylobot/blob/main/scripts/convert-bdf-to-k6-v2.csx) lukee allekirjoitusten luettelon ja lähettää k6-skriptin, joka *re-esimerkit* kukin allekirjoitus's jakelu VU:ta kohti iteraatiota kohtiM SK1

Re-esimerkit tekevät todellista työtä kyseisessä lauseessa `clientProfile` ja `timingProfile` jokaisessa VU-iteraatiossa valitaan allekirjoitus, rakentaa otsikot sen `headerCompleteness` ja `clientHintsPresent` lippuja, liittää cookie jarin, joka vastaa sen `cookieMode`, fetches `robots.txt` jos `robotsConsulted` on totta,, sen jälkeen vetää tuoreita perM SK1pyynnön viivästyksiä `delayAfterMs.min..max` ja uusi välihuomautuksen pausi `pauseAfterBurstMs.min..max`. Kaksi samaa allekirjoitusta käyttävää VU:ta antaa kaksi erilaista pyynnönvirtaa, joilla on sama tilastollinen jakelu. *luonteeltaan* tilanteesta.

```javascript
// Main test function - each VU picks random scenario and replays with burst/jitter.
// Multiple VUs running concurrently provide natural request interleaving.
export default function() {
    const sig = signatures[Math.floor(Math.random() * signatures.length)];
    // ... robots.txt, cookie jar, header bundle built from sig.clientProfile ...

    for (let i = 0; i < sig.requests.length; i++) {
        const req = sig.requests[i];
        const url = `${TARGET_URL}${req.path}`;
        const headers = buildHeaders(req.headers || {}, sig.clientProfile);
        const res = http.request(req.method, url, null, params);

        if (sig.timingProfile) {
            if (requestCount < sig.timingProfile.burstRequests) {
                sleep(randomBetween(
                    sig.timingProfile.delayAfterMs.min / 1000,
                    sig.timingProfile.delayAfterMs.max / 1000));
            } else {
                sleep(randomBetween(
                    sig.timingProfile.pauseAfterBurstMs.min / 1000,
                    sig.timingProfile.pauseAfterBurstMs.max / 1000));
                requestCount = 0;
                burstRate.add(1);
            }
        }
    }
}
```

Pääotsakkeen omaisuus: **Korpus, jota testaatte asianmukaisuuden puolesta, on korpus, jonka painotatte suorituskyvyn puolesta.**. Integraatiotestit eivät passoi, mutta tuotantoliikenne ei näytä yhdentymistesteiltä. *ovat* liikennegeneraattori. Kun asiakas ilmoittaa puutteellisesta bot-perheestä, lisäätte yhden BDF:n ja se liittyy sekä regressipakettiin että taakkatestiin.

k6 metrikot puhuvat samaa kieltä kuin BDF-pinnat

| kM SK1 metrinen | Mitkä se mittaa
|---|---|
| `bot_scenarios` / `human_scenarios` | Kertomukset skenaarioluokkaa kohden
| `detection_rate` | Pohjoinen osa bot-luokkaa koskevista skenaarioista
| `interval_ms` |InterM SK1pyynnön aukkosuuntaus ; tarkastaa aikatauluprofiilin, joka pysyy paineen alla
| `sensitive_path_rate` | Hakettujen pyyntöjen osuus `/admin`, `/api`, pisteitä koskevat asiakirjat |
| `burst_detected` | Burst raja-iskut, jotka johtuvat aikatauluprofiilista
| `http_req_duration` | P:n standardi latenttihistogramma 95/pM SK2 kynnysarvojen osalta

Näiden kynnysarvoista tulee täytäntöönpanokelpoinen määritelmä lastauspaketille:

```javascript
thresholds: {
    http_req_duration: ['p(95)<1000'],
    http_req_failed: ['rate<0.1'],
    'detection_rate': ['rate>0.3'],
},
```

Toistotekijä, joka vähentää havaitsemisselvityksen täsmällisyyttä kuormituksen nojalla (päätökseen jäävän verkon vartijan välttämättömät pyynnöt `detection_rate`. Reaktio, joka ottaa käyttöön hitaan tien ristiriitojen aikana `http_req_duration p95`. Samat lähteetiedot

## Kalibraatio: saman tiedoston kolmas käyttö

Tässä vaiheessa BDF on jo tehnyt kahta tehtävää: se on tarkistanut soittajan' signaalisopimuksen uudelleensovittamisen yhteydessäM SK2 ja tuottanut realistisen taakan k 6. Kolmas käyttötarkoitus on mielestäni kaikkein mielenkiintoisinMSC4, koska tässä BDF tarkastetaan vastaan *itse*.

Jokainen todisteiden merkintö on vaatimus lomakkeesta `signal OP value, weight w`. Kun allekirjoitus on käännetty uudelleen, ( loopbackin tai kM SK2 nojalla järjestelmä on tuottanut mitatun jakautumisen samoille signaaleille `interval_ms_p95 < 200` vaatimus voidaan tarkistaa mitattuna p95. `cookie_count >= 2` voidaan tarkistaa todellisuudessa toimitetun pyynnön Cookie-lisämäärän perusteella. `header_count >= 8` on tarkistettava alkaneiden otsakkeiden kanssa. M SK1Signaalit, jotka voivat ilmetä `evidence` on lueteltu [BDF v2 -järjestelmä](https://github.com/scottgal/stylobot/blob/main/docs/bdf-v2-schema.json): `interval_ms_p95`, `interval_ms_p50`, `sensitive_path_rate`, `error_rate`, `burst_detected`, `header_count`, `cookie_count`.)

Kun mittaus poikkeaa väitetystä,, allekirjoitus on vetäytynyt kalibroinnin ulkopuolelle . joko se on määritelty liikaa järjestelmälle, jota varten se on laadittu, tai järjestelmä on siirretty sen alapuolelle–. Molemmat ovat hyödyllisiäM SK4 ensimmäinen sanoo uudelleen-, että se tuottaa allekirjoituksen havainnollistamisen perusteella–;, toinen sanoo, että toisfactori siirtää havaitsemispinnan tavalla, jolla mitään toiminnallista testiä ei saisi kiinnittää–M SK7

Euroopan unionin `python-requests-bdf.json` esitetty aiemmin on pieni suora esimerkki siitä, miksi tarkastusta tarvitaan lainkaan. Sen toinen todiste rivi sisältää stringin `value` (`"burst <150ms"`), jossa järjestelmä edellyttää numeroa `requestInterval` merkki, jonka nimi ei sisälly todisteisiin enumissa lainkaan. Mudelma kirjoitti, että riviM SK1 eikä yksikäinen testi torju sitä . Ainoastaan todettujen todisteiden ja havaittujen todistusten vertaileminen mitattuna on todistus, jota ei koskaan voitu tarkistaa ensiksikään

Tämä muuttaa BDF:n regressiivisestä artifactista kalibrointi artifactiksi. `bot-signatures/` LLM:n, -:n ja ;:n alkuperäistä versiota koskevat todisteiden väitteet sisältävät *että* version thought distinguished each client family. ReM SK1käynnissä oleva kalibrointi kertoo teille, mitkä vaatimukset ovat edelleen voimassa ja mitkä ovat vanhentuneet , samoin kuin archetypinen ankkuri, jossa mikään ei ole kulkenut lähemmäs viikkoja, ei enää ole hyödyllinen aikaisempi. Korpuso itseMSC4tarkastukset

## Kuusi sääntöä muiden kuin -:n määritelmäjärjestelmien testaamiseksi

Ei-terministiset järjestelmät eivät edellytä ei-terministisia testejä, ne edellyttävät eri tavalla *rakennettu* ones. StyloBotin mukaiset mallit yleistävät

1. **määritellään tuloksia jakaukseksi, ei jäljeksiM SK1** A `timingProfile` minin kanssa/max-vaje on generatori; pyynnön jäljestä otettu pyynti on yksi vetäytyminen siitä . testataan jäljen vastaisesti ja te testaatte vetäytymisenM SK3 ei jakeluaMSC4 Sama logiikka client profilen osalta | ( | Cookie-modus ja header-täydellisyys kuvaavat väestöä |, | ei kiinteää headerlistiä |
2. **Ilmaistakaa sopimus painotettuina lähtökohtina.** Euroopan unionin `evidence` järjestelmään lähempänä oleva järjestelmä on yksikön-test assertionM SK1, ja lähtökohdat ovat yli jakelusignaaleja (`interval_ms_p95 < 200`), ei kohtaarvojaM SK1 Vääritelmät painoineen koostuvat
3. **Vahvistetaan kohdealueelle, ei tietä.** Järjestelmien osalta, joiden asema on arkkityypistä peräisin oleva sormenjälki.
4. **Tutkitaan sulautunutta pinta-alaa, ei osiaM SK1** Ongelmaluokkaa koskevat mallit, jotka eivät pysty saamaan kiinni, ovat ne, joissa osat ovat yksittäisesti oikeita mutta niiden koostumus heikentää jotakin.
5. **Suljetaan lähentyminen, ei korjata sitäM SK1** Määräaja, joka ratkaisee meluisen tulon vakaalle identiteetille, jakaa ajoittain. Väite on M SK1 pysyy rajojen alapuolella",, joka valittiin politiikasta
6. **Yrittäkää jakaa input-formattia rigin kautta, lastaus, ja kalibrointiM SK2** Kun skenaario on täytäntöönpanokelpoinen käyttäytymissopimus sen sijaan, että se olisi skriptti, sama asiakirja hallinnoi regressiivistä koneistoaM SK1 perf-harnessia , ja kalibrointitarkastusta. Korpus ei jakaudu

## Missä tämä sopii release-sarjaan

[Rajattoman kasvun löytäminen ja korjaaminen](/blog/stylobot-release-reliability) rajattu muisti; [Oppiminen nopeuttamaan](/blog/stylobot-release-learning) Tämä on kolmas vaihe, jossa tarkistetaan järjestelmää, jonka tulos on parempi.

Menetelmä on yksi komissio. Samat BDF-signaalit johtavat regressioon , kuormitukseen M SK2 ja kalibrointiin , joten testitarkastukset kaatuvat komissiota koskevaan maintenance-järjestelmään. Uusi allekirjoitus on jotain, mitä LLM voi auttaa laatimaan hyökkääjän kuvauksesta

Näin ollen tämä on vastaus tähän kysymykseen: "millä tavoin voidaan mahdollisesti testata StyloBotin kaltaista asiaa?

---


*BDF:n uudelleensovittamista koskeva rig lives at [`BdfReplayTests.Integration.cs`](https://github.com/scottgal/stylobot/blob/main/src/Mostlylucid.BotDetection.Orchestration.Tests/Integration/BdfReplayTests.Integration.cs). Lyhyt uudelleensovittamisen skenaariot ovat [`test-suites/{bots,humans,adversarial}/*.bdf.json`](https://github.com/scottgal/stylobot/tree/main/test-suites); koko tilastollinen allekirjoitus `clientProfile`, `timingProfile`, `evidence`) ovat [`bot-signatures/*.json`](https://github.com/scottgal/stylobot/tree/main/bot-signatures). kM SK1 muuntaja on [`scripts/convert-bdf-to-k6-v2.csx`](https://github.com/scottgal/stylobot/blob/main/scripts/convert-bdf-to-k6-v2.csx). Replay loppupiste, jota molemmat moottorit käyttävät on [`BdfReplayEndpoints.cs`](https://github.com/scottgal/stylobot/blob/main/src/Mostlylucid.BotDetection/Endpoints/BdfReplayEndpoints.cs). Näiden testien suojaamista koskeva signaalisopimus on dokumentoitu [`docs/architecture/signal-contracts.md`](https://github.com/scottgal/stylobot/blob/main/docs/architecture/signal-contracts.md). Kaikki lähteet osoitteessa [github.com/scottgalM SK2stylobot](https://github.com/scottgal/stylobot). Elävä moottoriM SK1 Dashboard , ja kaupalliset valvontalaitteet [stylobot.net](https://www.stylobot.net).*