StyloBot Release Series - Testen der Sache, die gewonnen hat (Deutsch (German))

StyloBot Release Series - Testen der Sache, die gewonnen hat

Monday, 01 June 2026

//

22 minute read

Wie testest du einen Detektor, dessen Antwort sich ändern soll, wenn er lernt??- Dieser Beitrag ist über BDF-,- das Behavioural Definition Format, das StyloBot testable macht.:-eine Datei definiert eine Klasse von traffic...,-Laufwerke Regressionswiedergabe,-Lastgenerierung,- und ein Kalibrieraudit

StyloBot

StyloBot Release Series

  1. Verhalten nicht IdentitätWarum StyloBot die Kunden verhaltensmäßig modelliert
  2. Verhalten Bewusst WERDENDie Oberfläche des Servers wurde über dieses Erkennungsergebnis gespiegelt.
  3. Ungebundenes Wachstum in langen --Diensten finden und behebenDie Zuverlässigkeitsdisziplin, die den Motor in der Produktion langweilig hält
  4. Verhalten--Bewusstsein TypScript UIKomponenten von , und Browsern
  5. Die Sidecar-ArchitekturWie der Detektions-Engine mit Nicht--.-NET-Stacks verbunden wird
  6. Schneller lernenDas adaptive Lernsystem (MSK) und der Urteilscache
  7. Testen der Sache, die Won-' sitt StillEine BDF-Datei treibt Regression an.
  8. StyloExtrahieren Sie einen lokalen HTML zu Markdown KonverterDie HTML-Markdown-Schicht, die sich mit dem Detektor verbindet, hat den Walker Bug lucidVIEW gefangen und die Hundefutterschleife, die es ehrlich machte.

Die Zuverlässigkeit Disziplin ist in Ungebundenes Wachstum finden und fixierenDas adaptive Lernsystem in Schneller lernenQuelle: github-.-com./-scottgal./-stylobot.


Wie testest du etwas, das lernt

Das ist die unbequeme Frage hinter StyloBot., und es ist nicht rhetorisch.

Ein konventioneller Test pins eine Funktion an Ort und Stelle, die X-Eingang liefert Ausgabe Y... Das funktioniert, wenn das Ding unter der Prüfung stabil ist ......StyloBot ist bewusst nicht stabil auf diesem Niveau . . .. Es sammelt Verhaltensbeweise an . :. ein einzelnes Ersuchen .'. Urteil hängt von der Anfrage selbst ab .,. der Fingerabdruck . ''s Drift aus seinem gelernten Archetyp Anker .MS K8. Sitzung Verhalten . und ob das System bereits genug gesehen hat, um direkt auf den schnellen Pfad zu überspringen ? .. Jeder Fingerabsatz beginnt mit dem nächsten Archetypen verbunden . Schneller lernen.)

Das Urteil für die Anfrage ist nicht eine Funktion von der Anfrage.Es ist eine Funktion der Anfragen......... durch ..20.... also ist das Testziel überhaupt keine Anforderung.... es ist das Verhalten des Systems über eine Folge von ihnen....

Das schließt aus Assert.EqualDie Frage, die ein Test stellen kann, ist nicht mehr.".does Anfrage X Rückkehr Urteil Y.MSC2.Es wird gegeben, dass diese Klasse des Verhaltens...,. das System zu der richtigen Antwort zusammenführt...MSC5. aus den richtigen Gründen: ,. innerhalb einer begrenzten Anzahl von Schritten: ?". Das ist die Frage BDF existiert, um zu antworten.

Die nächstgelegenen Analoga sind: Überprüfen und FsCheck,, aber BDF ist weder ., Verify genehmigt ein Artefakt ,, dann schlägt der Bau auf jedem genauen diff.., FsCheck behauptet Eigenschaften über zufällig generierten Eingängen , ., BDF sitzt zwischen ihnen , :, das zugelassene Artefakt ist eine Verhaltensdefinition ,,, aber die Passbedingung ist probabilistisch ,. , nicht , dass die Ausgabe passt diese Snapshot , aber " , ob diese Verteilung konvergieren auf die erwartete Seite der Grenze , mit den richtigen Signalen vorhanden ,

Eine Verhaltensdefinition: drei Verifikationssysteme

Der Trick, der diese traktable macht . .. eine BDF-Datei ist kein Testfall Es ist ein ausführbarer verhaltensbezogener VertragEine Definition darüber, wie sich eine Klasse von Clients verhält, die einmal geschrieben wurde, dass eine Datei auf drei Arten verbraucht wird.

  1. Abgespielt durch die Integration Rig-, , eine Anfrage zu einem Zeitpunkt gegen den realen Orchestrator , um Signal zu fangen , - , Fluss Regressionen der Einheit Suite nicht sehen ,. ,
  2. Re---Probenahme unter K.M.S.K.Viele gleichzeitige virtuelle Benutzer zeichnen frisches Timing aus der gleichen Definition, um realistische Last zu generieren.
  3. Prüfung gegen die Signale ein realer Lauf tatsächlich gemessen, um Kalibrierung driften zu fangen.
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: ,-Last,-Kalibrierung sind in der Regel drei Testsysteme mit drei Wahrheitsquellen, die auseinanderdriften..-Hier sind sie drei Messwerte einer Datei.

Warum Unit-Tests die Fehlerklasse verpassen

Die erste Version dieser Arbeit hatte Hunderte von per---Detektoreinheit Tests mit mock Kontexte und Dosenkopfer... Sie waren schnell... und blind für die Fehlerklasse, die mir wichtig war....

Der Orchestrator verschmilzt Beiträge zu einem einzigen ev.Signals wörterbuch, dass nachgeschaltete konsumenten -(-dashboard, ,-persistenz, narrative builder, ,-bedrohungsbericht, gelesen von: . Ein Refaktor, der sinkt primary_signature von der zusammengeführten Oberfläche fehlschlägt keine Per---Detektoreinheit test-:.Der Detektor immer noch ran-,. der Beitrag trug noch das Signal.,. es hörte einfach auf, jeden zu erreichen, der es brauchte Dashboard...'.s Fingerabdrucktabelle geht leer.MS K6. Persistenz überspringt die Reihe... Die Einheit Suite bleibt grün, weil nichts davon in der Nähe des Merge-..

Dies ist nicht ein hypothetisches signal--.Contracts Dokument zeichnet genau diese Regression auf – eine Veränderung, die das Zusammenführen von Signalen gestoppt hat – ein 6-tägiges Überleben in der Produktion trotz der noch berechneten Wahrscheinlichkeits- und Beitragszahlen. evidence.Signals."

Der Integrationstest am BdfReplayTests.Integration.cs ist direkt darüber, warum es existiert

Dieses Rig existiert, weil die Fehlerklasse es fängt -( downstream Verbraucher von ev.Signals Degradieren lautlos, wenn der Orchestrator aufhört, Signale zu verschmelzen.

Der Orchestrator ist keine Funktion, es ist eine Pipeline, deren Wert ist, was auch immer aus dem Merge kommt, nachdem jeder Mitwirkende ausgeführt hat... Der einzige Weg, um darauf zu behaupten, ist, eine reale Anfrage durch einen echten Orchester auszuführen und die zusammengeführte Oberfläche zu sondieren.

Eine Verhaltensdefinition, nicht ein skriptierter Test

Eine BDF-Datei beschreibt, wie eine Klasse des Clients verhält sich nicht eine feste Wiedergabe von einem,.. Die interessanten Teile des Schemas sind statistisches, :. ein Client-Profil, das Verteilungsidentität erfasst.,. ein Timingprofil, das einen Burst definiert.MSC4.mit der Regel des -.jitter-Sampling statt einer festen Verzögerung.,. ein Evidenz Array mit gewichteten Prädikaten über Verhaltenssignale.bot-signatures/python-requests-bdf.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."
}

Der größte Teil der Oberfläche ist statistics, und das meiste davon macht BDF zu einem Definition Statt eines Test-Skripts ist das vollständige Feld --von---Feldschema docs/bdf-v2-schema.json.)

confidence ist ein vorheriges, nicht eine Behauptung. Das Rig überprüft nicht, dass die gereifte Punktzahl gleich ist...... es prüft das Urteil landet auf der Bot-Seite der Grenze....... das vorherige ist das Band, das die Signatur des Autors von '...... oder human..)... denkt, das System sollte . erreichen.

clientProfile ist eine Kategorie des Clients. cookieMode: none ist ein Kategorie des Verhaltens - kein Cookie-Glas - jede Anfrage beginnt frisch , nicht ein spezifischer Header , sondern ein headerCompleteness: minimal sagt, dass eine Anfrage von diesem Client nur trägt, was curl.-.Class-Bibliotheken eingestellt ist, ein Fakt über die Population der Anfragen, die dieser Client ausgibt, nicht eine feste Header-Liste, .. Der Konverter k.6. materialisiert diese in Header Bundles zur Laufzeit. Art von client-.

timingProfile ist eine Sampling-Regel. burstRequests: 10 zuzüglich delayAfterMs: {min: 20, max: 150} zuzüglich pauseAfterBurstMs: {min: 500, max: 2000} definiert einen Generator, den :-Zehn Anfragen mit einheitlichen --Zufallslücken in 20-zu-MSKK3-zum-,-Zulassung dann eine einheitliche --Zukünftige Pause von 500- zu 2000-M,-Wiederholung.-Der gleiche BDF wiederholt zweimal produziert zwei unterschiedliche Anfrageströme mit der gleichen statistischen Verteilung ..-Das ist das tatsächliche Verhalten StyloBot's Periodizitätsdetektor und Sitzung ?--Vektor Verdichter versuchen zu erkennen, ;- einen festen Verzögerungsvektor würde eine andere Verteilung vollständig testen .

evidence ist ein gewichtetes Prädikat über Signalen Jeder Eintrag ist ein Anspruch des Formblatts signal OP value, weight w. {signal: "interval_ms_p95", op: "<", value: 200, weight: 0.35} Die BDF behauptet auf statistischer Ebene, dass die BDF eine Intervallverteilung erzeugen sollte, deren p-200-ms-MS-K15-Ein Szenario, dessen Nachweise sich von dem unterscheiden, was das laufende System misst, ist eine Signatur, die aus der Kalibrierung herausgedrift hat.

labels sind Taxonomie, . [Scraper, RobotsIgnore] ist die Klasse, die das Szenario für die Auswahl des Laufwerks-Szenarios im Lastbaum erzeugt wurde Scraper szenarien-,-exklusiv RobotsIgnoreOhne dass jemand einen Regex über Szenarionamen schreibt

requests beschreiben, was der Client nicht tut, was als nächstes passieren sollte. expectedStatusAny: [200, 403] toleriert entweder einen erfolgreichen Holt oder einen direkten Block, weil beide gültige Produktionen einer feindlichen Pfadsonde sind. expectedOutcome: indexing ist die Intent von client-' Nicht der Server, sondern die Antwort von '. successCondition: "any 4xx" am /api/data?page=3 ist der Klient?' s heuristic for -"? hat diese Arbeit gemacht?MSC2? ein Kratzer, der auf der dritten Seite von 4 xx erhält, folgt bei seiner Enumeration Job.(?it hat die Klippe entdeckt.MSC5. Die BDF fängt die Asymmetrie zwischen dem, was der Klientin versucht zu tun und das, was das System soll über sie zu tun.

Ein BDF und ein Zentroid, die gleiche Idee, invertiert

Das Wort Definition ist belastbar--Lager, und verbindet BDF mit dem Konzept im Zentrum von StyloBot.'-Detektor.-Der Motor klassifiziert Verkehr gegen Verhalten ZentrioideBezugspunkte im Raum von Verhalten nicht IdentitätJedem ein gelernter Anker für eine Klasse von Clients, die sich gleich bewegt.

Ein BDF beschreibt das gleiche, was eine Klasse von Clients mit der Rolle inverted. AnerkennerEs fragt ", wie diese Anfrage aussieht, dass Klasse ?" A BDF ist die GeneratorEs beantwortet einen Anfragestrom aus dieser Klasse.Gleiches Verhalten...... gegensätzliche Richtung, die genau das ist, was ein BDF replayable und ein Zentrioid nicht macht....

Der Motor SignatureToBdfMapper Überbrückt die zwei – :, nimmt es eine aus dem realen Verkehr eingefangene Verhaltenssignatur und schreibt sie als BDF wieder heraus, das man lesen und replayen kann.., Ein LLM erledigt den gleichen Job vom anderen Ende – ,, indem er eine Beschreibung eines Angreifers in einen neuen verwandelt – ., was einem Loop verleiht –:, beobachteter Traffic wird zu einer Signatur – ,, die Signatur wird zu einem BDF – ,, und der BDF kann das Verhalten neu abspielen, das ihn produziert hat..,

So die bot-signatures/ corpus ist nicht nur eine Testvorrichtung, es handelt sich um eine Bibliothek von Verhaltensdefinitionen, die eine Datei pro Klasse von Client StyloBot-Gründungen über die ., die dort durch ein Modell erzeugt wurden.ministral-3:3bBeschreiben Sie eine Client-Familie, die auf einen Satz von Endpunkten trifft, und die gleiche Oberfläche ist offen für einen menschlichen Autor.Beschreiben Sie ein BDF für eine neue Scraper-Familie und Sie haben eine Verhaltensdefinition, ein Regressionsszenario und einen load-Testeintrag in einer Datei.

Eine schlanke ,-'down Replay-Form lebt unter test-suites/{bots,humans,adversarial}/*.bdf.json nur behalten requests[].method/path/headers/delayAfter plus ein weiches expectedDetectionDiese Untermenge ist, was die Integration Rig an den Replay-Endpunkt postet., , das keine Möglichkeit hat, Verteilungsverhalten aus einer einzigen Wiederholung zu synthetisieren ,( , keine gleichzeitige VUs , , , nur Loopback , so TLS , / , TCP Fingerabdruckmaße durch Konstruktion degradieren , die reichere Form treibt den Lastgurt , , , wo gleichzeitigen VU können tatsächlich die Timing-Verteilung realisieren ,. ,

Der Endpunkt der Wiedergabe läuft durch den echten Orchestrator

Die Integrationsplattform stellt jedes Szenario an POST /bot-detection/bdf-replay/replayEin Endpunkt, der im Produkt lebtBdfReplayEndpoints.csNicht im Testprojekt, sondern in der Lage, den Endpunkt zu lösen. IDetectionOrchestrator von DI und läuft durch, welche Orchestrator derzeit registriert ist . DetectionPolicy.DefaultDie vorherige Version hardcodierte einen bestimmten Orchestrator und maskierte Regressionen in der Alternative (.Ephemeral.). Pfad.;. rewiring, um DI zu ehren fest, dass...

Da der Endpunkt im Produkt lebt, ist er wie eine Produktoberfläche gated. BdfReplay ist standardmäßig ausgeschaltet, wenn aktiviert, Anrufe erfordern eine gültige X-BdfReplay-Api-Key header und passieren Sie eine per.--IP-Rate Grenze, damit die Wiederholungsroute ist nicht ein Erkennung Bypass links liegend herum?. - Das Rig authentifiziert sich mit diesem Schlüssel.. - Der Punkt ist, um den realen Pfad auszuüben.

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

Ein bewusstes Richtlinienüberschreiben ,:' ist für das Replay deaktiviert.

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

Der Cache-Weg Skip umgeht den Matcher vollständig, sobald eine primäre Signatur ein selbstbewusstes zwischengespeichertes Urteil hat. Schneller lernenFür eine Rig-Messgenauigkeit und Signalfluss verbirgt es das Per--.Request-Verhalten, das der Rig auf dem ..Replay zu behaupten versucht, schaltet es aus und jede Anfrage läuft die volle Wellenform...

Szenarios sind auch voneinander isoliert.Jedes Szenario erhält eine einzigartige synthetische IP, die von einem deterministischen xxHash seines Namens abgeleitet wird. 192.0.x.y Adresse aus dem RFC-Bereich von -, also Subnet, -, Level Reputation blutet nie zwischen Szenarien und den Rig-Aufrufen. POST /bot-detection/bdf-replay/reset-identity vor jedem Szenario, um den Fingerabdruck-Speicher zu kürzen, ohne dass –,...Szenario N die Fingerabdrücke-Szenarien erbt – 1.....N.-1... erstellt und die per...-...szenario stability attentions werden ordern – -...abhängig – ....

Asserting auf einer nicht---deterministischen Oberfläche

Das Rig macht drei Behauptungen auf jedem Szenario... jedes ist eine Vorlage für das Testen von Systemen wie diesem...

Verheiratete Urteile... nicht per... Bot-Szenarien bestätigen last.Actual.IsBot ist true-;- menschliche Szenarien behaupten, die Mehrheit von den Anträgen, die als human eingestuft werden, würde Asserting auf jedem einzelnen Antrag den Test zu der Driftbahn weg vom Archetypanker paaren.; relaxing zu am Ende getauschten " testet den eigentlichen Vertrag.

// 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}");

Benannte Signalsonden – ,- nicht Signalzählungen –.- Signalfluss wird pro Taste gescannt - nicht durch total - . Eine Zählung Behauptung ist spröde - ein neuer Detektor, der ein neues Signal ausstrahlt maskiert den Verlust eines kritischen bestehenden .( Count bleibt die gleiche ? ; Fehlende ?- key Identität ist unsichtbar ?). ? Eine per-- ?key Sonde nennt den Verbraucher, der bricht ? , ? in der Ausfallmeldung ?

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");

Die Ausfallmeldung ist der test-'-Spezifikation: . Drei Monate später musst du dich nicht daran erinnern, warum das Signal von Bedeutung war.

Gebundene Konvergenz - nicht exakte Gleichheit Der metastabile Fingerabdruck-Matcher löst einen lauten Vektor zu einer stabilen Identität aus..-Vektorzusammensetzung enthält Sitzungsmaße ,(-Pfadentropie ,,-Session Alter , ) , dass Drift pro Anfrage , , , so dass die zwei ,- ,pass Match kann gelegentlich außerhalb seiner losen Band fallen und Zuweisung von ,mesK6 , Asserting auf einem einzigen Fingerabsatz-ID über alle Anfragen wäre falsch sein , die Behauptung , ?" , keine Löcher und Konvergenz nicht mehr als ceil(N/2) verschiedene Fingerabdrucke, ist der tatsächliche Vertrag ,.

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) Es kodiert eine Richtlinie ,: , die erste Anfrage immer zuweist ,; , nachfolgende Anfragen sollten meistens über L , 1 , bestätigen oder passieren , 2. , gelegentliche Zuordnung unter hoher Pfadvarianz ist akzeptabel ,; , Zuweisung auf jedes Request ist eine Regression.Der gebundene Teil ist locker genug, um das Rauschen zu absorbieren, das der Matcher entwickelt hat, um den Ausfall-Modus einzufangen, in dem er an allen stoppt.

Alle drei Muster teilen eine Eigenschaft, die sie auf dem Vertrag behaupten, das Verhalten soll befriedigen nicht auf den spezifischen Zahlen die aktuelle Implementierung geschieht zu produzieren, wenn sich die Umsetzung ändert ,, , der Test hält immer noch, wenn der Vertrag noch hält .. , Das ist es, was einen nicht-- ,deterministischen Test stabil macht .

Beladung des gleichen Korpus unter Druck

Eine BDF-Datei ist nur JSON-.. Das Integrationsgerät verbraucht die schlanke Form.Der Lastbaum verbraucht die vollständige statistische Form. scripts/convert-bdf-to-k6-v2.csx liest ein Verzeichnis von Signaturen und sendet ein Skript aus, das Re---Proben jede Signatur: Verteilung pro VU pro Iteration:

Re---Samples tut wirkliche Arbeit in diesem Satz..-Das k-6-Skript ist nicht replaying eine erfasste trace-;-Es ist die Realisierung der clientProfile und timingProfile Jede VU-Iteration wählt eine Signatur aus. headerCompleteness und clientHintsPresent Flags-, heftet ein Cookie Glas passend zu seinem cookieModeEinholen von , robots.txt wenn robotsConsulted ist wahr?, , zieht dann frisch per ,- ,verlangsamen von delayAfterMs.min..max und eine frische Inter---Burstpause von pauseAfterBurstMs.min..maxZwei VUs mit derselben Signatur senden zwei unterschiedliche Request-Streams mit der gleichen statistischen Verteilung aus, das ist genau das, was die Detektionspipeline als eine erkennen soll. Art von client-.

// 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);
            }
        }
    }
}

Die Headline-Eigenschaft der Korpus, den Sie auf Korrektheit testen, ist der Korpuls, der Sie für Leistung belastenEs gibt keine Integrationstests, aber der Produktionsverkehr sieht aus wie die Integrations-Tests. sie werden wenn ein Kunde eine verpasste Bot-Familie meldet, fügen Sie einen BDF hinzu und es schließt sich sowohl der Regressionssuite als auch dem Lasttest an.

Die Kenngrößen von k-6 sprechen die gleiche Sprache wie die BDF-Oberfläche.

Was es misst, was es misst |---|---| | bot_scenarios / human_scenarios Zähler je Szenarioklasse | detection_rate Die Fraktion der Bot---Klassenszenarien, die am Rand markiert sind | interval_ms Überprüft, ob das Zeitprofil unter Last gehalten wird | sensitive_path_rate Die Fraktion der Anfragen schlagen /admin, /api,, , Punktdateien , | | burst_detected Aus dem Timingprofil abgeleitete Burst-Grenzeinschläge | http_req_duration Standard-Latenz-Histogramm für P-95/P-99P-Schwellenwerte

Schwellen an diesen werden zu einer ausführbaren Spezifikation für den Lastumschlag.

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

Ein Refaktor, der die Detektionsgenauigkeit unter Last zurückführt, das Urteil cache watchdog überspringt Anfragen sollte es sein detection_rateEin Refaktor, der einen langsamen Pfad unter Streitreisen einführt http_req_duration p95Daten der gleichen Quelle: zwei Regressionen, die gefangen wurden:

Kalibrierung: Die dritte Verwendung der gleichen Datei

An diesem Punkt hat die BDF bereits zwei Aufgaben erledigt .: , es hat den Orchestrator überprüft . ' s Signalvertrag unter replay . , , und erzeugt realistische Last unter k .6. . Der dritte Einsatz ist der, den ich am interessantesten finde . sich selbst.

Jeder Beweismitteleintrag ist ein Anspruch des Formblatts signal OP value, weight wSobald eine Signatur wiederholt worden ist, hat das System unter loopback oder k-6),® eine gemessene Verteilung für die gleichen Signale erzeugt. interval_ms_p95 < 200 Der Anspruch ist gegen den gemessenen p-95. kontrollierbar cookie_count >= 2 ist gegen die Cookie-Anzahl der tatsächlich getragenen Anfrage kontrollierbar header_count >= 8 ist kontrollierbar gegen die Header, die landete.... Die Signale, die in erscheinen können evidence werden in der BDF-Schema: interval_ms_p95, interval_ms_p50, sensitive_path_rate, error_rate, burst_detected, header_count, cookie_count.)

Wenn gemessene Abweichungen von beanspruchten ,,' die Signatur aus der Kalibrierung ausgedrift hat ..' Entweder wurde es für das System überspezifiziert wurde es gegen erstellt wurde , oder das System hat sich unter ihm bewegt ?.' Beide sind nützlich , :' die erste sagt re ,-" Generieren Sie die Unterschrift aus Beobachtung , ;' die zweite sagt ein Refaktor verschoben die Erkennungsfläche in einer Weise, dass keine funktionellen Test würde fangen ,

Das python-requests-bdf.json früher gezeigt ist ein kleines Live-Beispiel dafür, warum das Audit überhaupt benötigt wird... seine zweite Beweisreihe trägt eine Zeichenkette value ("burst <150ms"Das Schema benötigt eine Nummer, die Zahl und das requestInterval signal es Namen ist nicht im evidence-enum überhaupt nicht Ein Modell schrieb, dass row., und keine Einheit Test lehnt es ab.MS K2 Nur ein gemessener Lauf Vergleich der behaupteten Beweise gegen beobachtete Signale Oberflächen eine Behauptung, die nie an erster Stelle kontrollierbar war

Dies verwandelt den BDF aus einem Regressionsartefakt in ein Kalibrierartefact. bot-signatures/ wurden gegen eine frühere Version der Detektor-Pipeline erzeugt. das Version dachte unterscheiden jede Client-Familie ,. , Re...- running Kalibrierung heute sagt Ihnen, welche Ansprüche noch halten und die aus gealtert haben , , , die gleiche Weise ein Archetypanker , dass nichts in der Nähe seit Wochen driftet hört auf, eine nützliche vorherige sein .. , Das Corpus selbst , - ,audits ,.

Sechs Regeln für das Testen von nicht---deterministischen Systemen

Nicht---deterministische Systeme erfordern keine nicht---deterministischen Tests - sie benötigen unterschiedliche gebaut die Muster, die für StyloBot-Verallgemeinerung arbeiten

  1. Definieren Sie die Eingabe als Verteilung. A timingProfile mit min./-max-Lücken ist ein Generator, ein erfasster Request-Trace ist eine Ziehung aus ihr, .-Test gegen die Spur und Sie testen den Draw, ,-Test nicht die Distribution, die gleiche Logik für das Client-Profil, MSC5-Cookie-Modus und Header Vollständigkeit beschreiben eine Population, nicht eine feste Header-Liste.
  2. Expressieren Sie den Vertrag als gewichtete Prädikate Das evidence array ist die nächstliegende Sache, die das System zu einer Einheit hat.-.test-Anspruch und die Prädikate sind über Verteilungssignale.interval_ms_p95 < 200Nicht Punktwerte Prädikate mit Gewichten komponieren ,; , Gleichheitsaussagen don-' , nicht Punktwerte , . ,
  3. Assert auf dem Ziel, nicht den Pfad, . Für Systeme, deren Zustand ein Fingerabdruck ist, der von einem Archetyp vorher abdriftet.,. per...-.step Behauptungen Paar zur Implementierung.;. gereift-.state Behauptungen paar zum Kontrakt.
  4. Probe die verschmolzene Oberfläche nicht die Komponenten Die Fehlerklasse mocks kann nicht fangen ist derjenige, wo die Komponenten individuell korrekt sind, aber Zusammensetzung fällt etwas - .- Führen Sie die vollständige Pipeline - ;.
  5. Gebunden die Konvergenz... ..befestigen Sie es nicht. . Ein Matcher, der laute Eingabe zu einer stabilen Identität auflöst, wird gelegentlich die Behauptung zuordnen, dass unter dem gebundenen "'stays aus der Politik gewählt nicht von den beobachteten Zahlen.'
  6. Teilen Sie das Eingabeformat über Rig-,-Last, ,-Kalibrierung und Wenn das Szenario ein ausführbarer Verhaltenskontrakt anstatt eines Skripts ist, treibt die gleiche Datei ein Regressions-Rigg an.,. ein Perf-Harness und ein Kalibrierungsaudit... Das Corpus spaltet sich nicht.

Wo dies in die Release-Serie passt

Ungebundenes Wachstum finden und fixieren Begrenzt den Speicher. Schneller lernen made repeat detection cheap Dieses ist das dritte Bein, das ein System überprüft, dessen Ausgabe won-'...

Die Methode ist ein corpus... Die gleiche BDF Signaturen Antrieb Regression .MSC1. load- und kalibrierung . ,. so dass Testwartung in Corpus Wartung zusammenbricht ?.. Eine neue Signatur ist etwas, das eine LLM kann aus einer Beschreibung eines Angreifers zu entwerfen .

Das Serie StyloMail nimmt die gleichen Bewertungsfragen in email . Verwendung von Nimble aus C-# erwägt, lokale Entscheidungsmodelle auf einem geteilten Mail-Corpus zu vergleichen, einschließlich Kalibrierung, Verfügbarkeit von Antworten und den Fehlern, die eine geschichtete Route vor der Eskalation verpassen kann.

So ist dies die Antwort auf ", wie können Sie möglicherweise testen etwas wie StyloBot?".Sie frieren es nicht ein Du bestimmst eine Klasse von Verkehr, laufen das reale System gegen es , und überprüfen drei Dinge:., dass das Urteil immer noch konvergiert ,, dass die Signale seine Verbraucher davon abhängen immer noch ankommen,., und dass der Beweis die Definition behauptet immer noch stimmt, was der Lauf misst...Der Test ist kein pin-..Es ist eine Schleife...


Die BDF Replay Rig lebt in BdfReplayTests.Integration.csSchlanke Wiederholungsszenarien sind unter test-suites/{bots,humans,adversarial}/*.bdf.jsonDie vollständigen statistischen Signaturen clientProfile, timingProfile, evidence,)- sind unter bot-signatures/*.jsonDer Konverter ist scripts/convert-bdf-to-k6-v2.csxDer Replay-Endpunkt, den beide Rigs verwenden, ist BdfReplayEndpoints.csDer Signalkontrakt, den diese Tests verteidigen, ist dokumentiert in docs/architecture/signal-contracts.mdAlle Quelle bei github-.-com./-scottgal./-stylobotLive-Engine, Dashboard und kommerzielle Steuerungen am Stylobot-.-net.

Finding related posts...
logo

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