KaizoCoreKaizoCore docs

The scoring engine

Seven layers, 44+ rules, and the exact math that turns them into a 0–100 score.

Layers and weights

Every rule belongs to exactly one layer. Each layer's highest-scoring fired rule (not a sum of all fired rules in that layer) contributes its weighted share to the final score:

LayerWeightWhat it covers
behavior25%Mouse dynamics, keystroke timing, uncanny-valley detection
device20%User-Agent analysis, known-bot TLS fingerprints (JA3/JA4)
environment15%JS engine tampering, iframe/worker context mismatches
journey15%Page-view sequence, dwell time, journey confidence
network10%IP type (datacenter/VPN/Tor/CGNAT), impossible travel
entity10%Cross-request velocity, bad-actor registry matches
session5%Cookie binding mismatches, token replay abuse

These sum to 100%. Weight distribution is a deliberate statement about where trust should come from: behavior + device + environment = 60% of the total, because a real human doing something a script can't cheaply fake is worth more than any single static signal.

Why max-per-layer, not sum-per-layer

If layer scoring summed every fired rule instead of taking the max, a single behavioral anomaly could double- or triple-count across multiple rules that all key off the same underlying signal, artificially inflating a score that's really evidence of one thing, not three. Taking the layer maximum means adding more rules to a layer never mechanically raises scores for sessions that were already going to fire the strongest one.

Deterministic vs. probabilistic rules

Rules are split into two categories that get treated differently downstream by ML fusion:

  • Deterministic rules are identity facts: a User-Agent string either matches a known automation signature or it doesn't; a TLS fingerprint either matches a known bad client or it doesn't; a JS engine's Function.prototype.toString either has been patched or it hasn't. These are exactly as reliable regardless of how much behavioral data exists for the session, so they pass through fusion at full value, ungated by data completeness.
  • Everything else (mouse/keyboard dynamics, journey confidence, cookie binding checks) genuinely needs an adequate sample size to be trustworthy — a session with almost no behavioral data shouldn't get to claim high confidence on a thin behavioral read. These stay gated by a completeness score.

The completeness gate ("the Golden Rule," enforced mathematically)

completeness =
    0.40 if HasMouseData
  + 0.20 if DeterminismRatio > 0
  + 0.20 if HasEnvironmentData
  + 0.20 if IPType is known

If completeness falls under a hard threshold (0.40), the final score is capped — regardless of how high the raw probabilistic component would otherwise be — at a ceiling below the SOFT_CHALLENGE band. A session KaizoCore doesn't have enough evidence about can never be confidently escalated on a guess. This is the same principle as Why KaizoCore's "absence is never suspicious," made literal in the score formula rather than left as a design intention.

The fusion formula

deterministic_component = deterministic_score   (full weight, never gated)
probabilistic_component = (probabilistic_score × 0.85)
                         + (ml_bot_prob × 100 × 0.10)
                         + (if_anomaly_dev × 100 × 0.05)

final_score = deterministic_component + (probabilistic_component × completeness)

The 0.85 / 0.10 / 0.05 split is a deliberate Stage A rollout weighting — rules dominant, ML models contributing a real but conservative share while their track record builds on live traffic. See ML fusion for what Stage B/C promotion would look like and what has to be true before that happens.

Escalation on top of the score

After the fused score maps to a decision band (see Decision scores), three more mechanisms can push a decision up — never down:

  1. Per-action thresholds — you can configure tighter or looser block/challenge thresholds per event type (login vs. checkout vs. payment often warrant different tolerances).
  2. Policy overrides — see The policy engine.
  3. The late GHOST override — high-confidence uncanny-valley behavioral timing detected after scoring forces a hard BLOCK, bypassing the numeric threshold entirely for the highest-confidence robotic cases.

Rule reference

The full, current list of every registered rule — ID, layer, base score, and whether it's deterministic — is in Rules reference. That list is generated from the same rule registry the engine actually runs, so it never drifts out of sync with production behavior.

On this page