On this page

Detector score cache

The cache is Skryba's local SQLite record of detector probabilities. It prevents a repeated score for identical text from billing the same detector endpoint and revision again.

Location

--cache wins over SKRYBA_CACHE; the default is ~/.cache/skryba/detector-scores.sqlite3. Parent directories are created automatically. SQLite uses WAL mode.

Schema

CREATE TABLE scores (
  detector TEXT NOT NULL,
  text_hash TEXT NOT NULL,
  probability REAL NOT NULL,
  created_at INTEGER NOT NULL DEFAULT (unixepoch()),
  PRIMARY KEY (detector, text_hash)
);

text_hash is lowercase hexadecimal SHA-256 over the exact UTF-8 input. Whitespace changes therefore create a different entry.

The detector key is a cache namespace, not only the short provider name:

<name>:<revision>:<endpoint>

Changing provider revision or endpoint cannot reuse the old response accidentally.

Lifecycle

  1. Open the database and create scores if absent.
  2. Before an HTTP request, look up (cache_namespace, sha256(text)).
  3. A hit returns the probability with cached: true and skips rate limiting and HTTP.
  4. A miss is requested, parsed, normalized, and upserted with a fresh created_at; the result says cached: false.

There is no expiration or automatic pruning. Removing the database, its WAL, and shared-memory files discards all cached scores; do this only when deliberately accepting re-billing.

Invariants and failures

  • Cache writes occur only after a successful provider response and valid probability extraction.
  • A failed or malformed response is never cached.
  • The process mutex serializes SQLite access.
  • Open failures begin opening detector cache <path>.
  • Directory failures begin creating detector cache directory <path>.
  • A poisoned mutex is detector cache lock poisoned.

The scoring walkthrough captures the same score first with cached: false, then with cached: true.

Maintained as part of the website-owned Skryba documentation corpus.