On this page

CLI reference — global options, score, rewrite, corpus

The binary is skryba (src/main.rs). Structured command results print JSON by default. Add --text for path: value lines from the same result. rewrite prints the rewritten text unless --json is set; its explicit JSON output and report file are unaffected by --text. Operational errors are printed by anyhow as Error: <message> (with Caused by: chains) on stderr, exit status 1. Invalid arguments exit 2. Success is exit 0. Training and benchmark are on their own page.

Command tree

Every public command has its own reference page:

Global options

Global options come before the subcommand (skryba --detectors sapling score). Each env: variable is read by clap, so the flag always wins over the environment.

Flag Env Default Meaning
--text — off render structured results as readable path: value lines instead of JSON; does not change rewrite output
--brama-url <URL> BRAMA_URL https://brama.wisent.com Brama base URL; /v1/chat/completions is appended
--model <MODEL> SKRYBA_MODEL claude-code-subscription generator model name passed to Brama
--judge-model <MODEL> SKRYBA_JUDGE_MODEL generator model quality-judge model; defaults to --model
--minimum-quality <F> — none; required by rewrite, benchmark and train quality gate; see quality judge. Missing: --minimum-quality is required: the quality score a rewrite must reach is the caller's to state
--detectors <NAMES> — inferred from keys comma-separated subset of gptzero, winston, originality, sapling
--detector-interval-ms <N> — none; requests are not paced pause between two requests to one detector

The drafts, the writing-style rows, the catalog and the detector score cache are tables of the fleet database; there is no flag naming a file for them. SKRYBA_DATABASE_SCHEMA names the schema they live in (default skryba).

For example, skryba --text database check prints the same observed table counts as skryba database check. Nested objects use dotted paths; array entries use bracketed indices. Strings are printed without JSON quotes; nulls and empty collections are shown as -. Text output is for reading, not for parsing back into a result: use the default JSON for automation.

Detector selection: with --detectors, names are lowercased and must all be known; an unknown name is unknown detector "<name>"; available detectors: gptzero, originality, sapling, winston, and every named detector's key must be set (GPTZERO_API_KEY is required for gptzero). Without --detectors, the ensemble is every detector whose key is a non-empty environment variable; none set is no detector credentials found; configure GPTZERO_API_KEY, WINSTON_API_KEY, ORIGINALITY_API_KEY, or SAPLING_API_KEY.

Input convention

score and rewrite take optional [INPUT]: a file path or - for stdin. With no input they read stdin. Each also accepts --draft <ID> to read exact text retained by skryba draft import; INPUT and --draft conflict. ~ in paths is expanded against HOME. Reading a missing file fails with reading <path>.

skryba score [INPUT]

Measure detector AI probabilities. Builds the detector ensemble, scores the text once with every detector concurrently (each detector obeys its own rate limit and cache), and prints:

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

ai_probability is the unweighted mean of the per-detector probabilities. cached: true means the number came from the score cache in the fleet database and no request was sent. Needs at least one detector key; does not need Brama credentials. Empty or whitespace-only input is refused per detector: <name> cannot score empty text.

skryba rewrite [OPTIONS] [INPUT]

The full pipeline: chunk → generate candidates, through Brama or locally through ster generate → score with detectors and the quality judge → select per chunk (rewrite). Needs BRAMA_TOKEN_ROLE=ROLE#FIELD and at least one detector key on either route: the judge is Brama's whichever generator writes the candidates. See configuration for endpoint, model, credential resolution and optional paired agent identity.

Flag Default Meaning
--output <PATH> — write the rewritten text (plus trailing newline) to a file instead of stdout
--report <PATH> — write the complete RewriteResult JSON to a file
--json off print the complete RewriteResult JSON to stdout
--policy <PATH> built-in uniform policy load a trained policy JSON; missing/invalid file is an error, not a fallback
--style <NAME> preserve required style, by name, from skryba style list; applies to every candidate
--language <NAME> preserve output language, by name, from skryba language list; a named language translates when needed
--candidates <N> required candidates generated per chunk; 0 is refused (candidate count must be positive)
--max-words-per-chunk <N> required chunk budget; 0 is refused
--temperature <F> required generator sampling temperature; a nonfinite or negative value is refused (temperature must be a finite number of at least 0); Skryba keeps no ceiling, the generator route owns any upper bound
--seed <N> required seeds strategy sampling — the same seed, policy, and candidate count sample the same strategies
--generator <brama|local> required brama posts one chat completion per candidate; local spawns one ster generate per candidate with the person's own adapter attached
--local-model <MODEL> — checkpoint Ster maps; required with --generator local
--local-revision <REV> Ster's own, main immutable Hugging Face revision for that checkpoint
--adapter <PATH> none LoRA adapter to attach, as written by skryba writing-style train; without it the local route generates from the base checkpoint
--local-device <DEVICE> cpu Ster device: cpu, metal, or cuda
--local-precision <PRECISION> f32 Ster precision: f32, f16, or bf16
--local-chat-template <MODE> auto auto asks through the checkpoint's own chat template when it publishes one; off asks as raw text
--local-max-new-tokens <N> required with --generator local generation budget per candidate, passed to ster generate; Ster assumes none, and 0 is refused

The required style and language take precedence over a sampled policy instruction or a personal adapter's learned voice. They do not train an adapter or select one editing strategy. Both names are resolved in the catalog before any model or detector credential is read; the instruction each name stands for is listed by skryba style list and skryba language list.

Output modes combine: --output suppresses the text on stdout; --json prints the JSON to stdout regardless; --report writes the same JSON to a file. With none of the three, stdout is the rewritten text alone.

The RewriteResult JSON (--json/--report):

text                       final text: selected chunk texts joined by blank lines
profile
  style                    the style name the run resolved
  style_instruction        that style's instruction, as the generator and judge received it
  language                 the language name the run resolved
  language_instruction     that language's instruction, as the generator and judge received it
chunks[]                   one per chunk
  source                   the original chunk
  selected                 the winning CandidateScore
  candidates[]             every generated CandidateScore
  used_source_fallback     true when no candidate passed and the source matched the profile
CandidateScore:
  strategy_index           index into the policy's strategies; null for the source fallback
  strategy                 strategy name, or "source-fallback"
  text                     candidate text
  ai_probability           ensemble mean for this candidate
  quality_score            weakest judged dimension (see quality judge)
  quality_passed           quality thresholds, no critical error, and both profile checks
  quality                  six dimensions, critical_error, style_matched, language_matched, issues, rationale
  detectors[]              per-detector {detector, ai_probability, cached}

If every candidate fails, the original chunk is eligible only when the judge confirms both profile checks. Otherwise the command exits 1, names the chunk and requested profile, and leaves final output and report files unwritten. A source fallback can still have quality_passed: false; it is not a claim that the original passed every numeric threshold. The earlier offline walkthrough used stand-ins and is not proof of style or translation quality.

skryba style and skryba language

List, show, add, change and remove the styles and output languages rewrite can require. No model credential is read. Full commands, output and refusals: catalog.

skryba corpus <PATH> --seed N [--samples N]

Verify a curated corpus file offline: every sample's declared whitespace_words and input_sha256 must match its input text. Prints the verified sample list:

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

--samples (default: all) truncates after a deterministic shuffle keyed by --seed (required) — the same order benchmark --corpus uses, so corpus previews exactly which samples a benchmark would take. Any mismatch is a refusal naming the sample, e.g. curated sample docs-sample-1 declares 5 words and carries 19. The file format is defined in train and benchmark.

skryba writing-style <add|keep|pairs|unkeep|samples|harvest|export|train|status|profile|sources|remove>

The other half of the product: hold the prose the person writing actually wrote, collect more of it by itself, have them rewrite samples, and train an adapter on it. add ingests their files; harvest collects their writing from folders, Messages, Notes and Transcript Lake, on a Stado schedule if asked; samples plan works out how many rewritten pairs each kind and length of their writing still needs and samples generate has the Brama model write them; keep records one pair they resolved, a rewrite or a sample; pairs and unkeep list and take back kept pairs; profile measures their sentence, word and paragraph lengths; export writes --format sft or --format dpo; train writes the same file and runs ster tune sft — or ster tune dpo under --method dpo — over it; status reports the counts, sources lists where the passages came from, and remove <SOURCE> --yes takes back everything one source contributed. All of them print the same JSON report. Only samples generate calls Brama. train is the one that holds the machine: it spawns the local ster binary for as long as the gradient takes.

Full flags, required values, and refusals: skryba writing-style. What the rows keep and why: writing-style store. Which product owns the weights: training boundary.

skryba rule <list|show|add|edit|remove|check>

Writing rules every rewrite is counted against: words per sentence, letters per word, sentences and words per paragraph, list lines, headings and phrases. No model credential is read; a candidate that breaks a rule is not selected. Full commands, output and refusals: skryba rule; what each metric counts: writing rules.

skryba lyrics <form <list|show|add|edit|remove>|check|compose>

Lyrics written to a counted form: a stanza's rhyme scheme, syllables per line, how many syllables of sound a rhyme shares, endings that carry no rhyme, and internal rhymes. check counts by Polish pronunciation and reads no model credential; compose writes through the selected model route and returns only lyrics every count passes. Full commands, output and refusals: skryba lyrics; how the counting works: lyric form.

skryba database <check|drop-schema>

check resolves, connects and reports the schema's tables and row counts, naming the step that failed; drop-schema --schema NAME removes a schema a journey or a test created. Full description: database.

Exit status

0 on success; 1 on an operational error, with the message on stderr, including a style or language the catalog does not hold; 2 when clap rejects arguments, a required flag missing included.

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