On this page

Quick start

From clone to a scored and rewritten text. Every command below was run against the built binary; the captured output is real. Commands that need credentials show the exact refusal you get without them, so you know the setup is working before you spend a detector call.

1. Build

Rust 1.85+, edition 2024. TLS is rustls and SQLite is bundled — no system dependencies.

git clone https://github.com/wisent-ai/skryba
cd skryba
cargo build --release
    Finished `release` profile [optimized] target(s) in 0.41s

The binary is target/release/skryba. cargo install --path . puts it on ~/.cargo/bin (which the desktop app also searches).

2. Prove the binary answers

skryba --help
Detector-directed text rewriting with a native Rust GRPO policy

Usage: skryba [OPTIONS] <COMMAND>

Commands:
  score       Measure detector AI probabilities
  corpus      Verify a curated corpus against its declared words and checksums
  rewrite     Generate candidates and select the least detectable rewrite
  rentahuman  Commission and monitor human rewrites through RentAHuman
  benchmark   Evaluate rewrite quality on a curated corpus or on README and docs passages
  train       Optimize the native rewrite-strategy policy with GRPO
  help        Print this message or the help of the given subcommand(s)

3. Run something that needs nothing

corpus verifies a curated corpus file offline — no credentials, no network:

skryba corpus corpus.json
{
  "corpus": "corpus.json",
  "samples": [
    { "id": "docs-sample-1", "whitespace_words": 19 },
    { "id": "docs-sample-2", "whitespace_words": 23 }
  ],
  "verified_samples": 2
}

(The corpus file format is documented in train and benchmark; tests/fixtures/humanization_samples.json in this repository is a real one.)

4. Configure credentials

Skryba refuses precisely when a credential is missing. Without any detector key:

echo "Some text." | skryba score
Error: no detector credentials found; configure GPTZERO_API_KEY, WINSTON_API_KEY, ORIGINALITY_API_KEY, or SAPLING_API_KEY

Export at least one detector key, and BRAMA_TOKEN for anything that generates or judges text:

export SAPLING_API_KEY=…      # any of the four detector keys
export BRAMA_TOKEN=…          # required for rewrite, train, benchmark

The full variable table is configuration. The detector ensemble is inferred from which keys are set; --detectors gptzero,sapling selects explicitly.

5. Score

echo "Additionally, the study found that participants who received the intervention reported higher satisfaction." | skryba score

Real output (captured against a local Sapling-shaped endpoint; with a real key the number is the detector's verdict, the shape is identical):

{
  "ai_probability": 0.7835,
  "detectors": [
    {
      "ai_probability": 0.7835,
      "cached": false,
      "detector": "sapling"
    }
  ]
}

Run the same text again and "cached": true — the score came from the local SQLite cache and cost nothing.

6. Rewrite

skryba rewrite draft.txt --report report.json

Prints the rewritten text to stdout and writes every per-chunk, per-candidate score to report.json. A real end-to-end run — including what the JSON looks like — is captured in the offline rewrite walkthrough. INPUT is a file path or - for stdin (the default) on score, rewrite, and rentahuman create alike.

7. Where next

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