On this page

Writing style workflow

The original writing-style form adds authored files, exports examples and trains an adapter through local Ster. Those commands need no model-provider credential. The separate Your voice panel registers automatic sources, offers writing and rewrite assignments, and shows prospective model comparisons. Generating new assignments or evaluating an adapter uses the selected Brama decision route or a declared direct chat service. A passage count or detector probability is not a personal-voice score.

Form

A segmented picker selects the subcommand: Add writing, Sources, Remove a source, Train adapter, Export for Ster, Status. keep is deliberately absent from it: a preference is recorded from a finished rewrite by the button under that result, not by filling another form.

No number starts filled in: each is a field you type, and the app names the first empty one the subcommand needs before it runs anything.

Subcommand Control UI value CLI argument
Add writing sources editor, one path per line non-empty positional SOURCES
Add writing fewest words per passage typed, required --min-words
Add writing most words per passage typed, required --max-words
Sources none — —
Remove a source the file or directory as it was named when adding non-empty positional SOURCE
Remove a source "Remove its passages; this cannot be undone" toggle off --yes when on
Train adapter objective SFT examples or DPO pairs, default SFT --method sft|dpo
Train adapter checkpoint empty --model
Train adapter adapter destination empty --output
Train adapter revision (optional) empty, omitted when blank --revision
Train adapter device cpu, metal, or cuda, default cpu --device
Train adapter precision f32, f16, or bf16, default f32 --precision
Train adapter LoRA rank typed, required --rank
Train adapter LoRA alpha typed, required --alpha
Train adapter epochs typed, required --epochs
Train adapter learning rate typed, required --learning-rate, as typed
Train adapter accumulation (rows per optimizer step) typed, required --accumulation
Train adapter token limit per row typed, required --max-sequence
Train adapter rows per pass typed, required --batch-size
Train adapter seed typed, required --seed
Train adapter beta (pull toward the base model) typed; required for DPO, hidden for SFT --beta
Train adapter lead words used as the prompt typed; required for SFT, hidden for DPO --lead-words
Train adapter rows used (empty = all) typed; omitted when empty --limit
Export for Ster shape SFT examples or DPO pairs, default SFT --format sft|dpo
Export for Ster destination file empty --output
Export for Ster name writing-style --name
Export for Ster lead words used as the prompt typed; required for SFT, hidden for DPO --lead-words
Export for Ster rows used (empty = all) typed; omitted when empty --limit
Status none — —

The objective, the name, the lead words and the rows used are one piece of state shared by Train adapter and Export for Ster; the name is changed in the export form. The train form shows no --export control, so the file Ster reads always lands beside the adapter.

Blank lines and surrounding whitespace are dropped from the sources editor, so one path per line is the whole rule. Run is blocked with the app's own sentences:

  • Name at least one file or directory of your own writing.
  • Name the file or directory whose passages to remove.
  • Name the checkpoint to train on.
  • Say where the adapter should be written.
  • Give the export a destination file.
  • State the <setting>. for the first empty number the subcommand needs, for example State the fewest words per passage., State the LoRA rank. or State the lead words.

Status and Sources have nothing to validate and always run. Remove a source with the toggle off runs too: the CLI then names the passages and words it would remove and removes nothing, and that refusal is what the window shows, so the counts are read before the toggle is turned on.

Exact invocation shape

skryba writing-style add --min-words N --max-words N PATH [PATH...]
skryba writing-style train --method sft --model CHECKPOINT --device cpu --precision f32 --output PATH --rank N --alpha A --epochs N --learning-rate F --accumulation N --max-sequence N --batch-size N --seed N --name writing-style [--beta B] [--lead-words N] [--revision REV] [--limit N]
skryba writing-style export --format sft --output PATH --name writing-style [--lead-words N] [--limit N]
skryba writing-style status
skryba writing-style sources
skryba writing-style remove PATH [--yes]

Every number is sent exactly as typed. --lead-words is sent for SFT, and --revision and --limit only when they carry a value, which is why they trail the fixed block rather than sitting beside --model.

These forms carry paths in argv and send nothing on stdin. Detector options are not added: this workflow has no detector.

Successful result

Stdout must decode as the one report shape every writing-style subcommand shares:

action
store
passages
passage_words
preferences
added
skipped
removed         passages a Remove a source run took back; zero otherwise
sources         Sources only: every source with its passages and words
output          absent unless the command wrote a file
written         absent unless the command wrote a file
adapter         train only: the safetensors Ster wrote
ster_command    train only: the exact `ster` command the CLI ran

The Writing-style store panel shows the store path, passages and their word total, preference pairs, what this run added, skipped or removed, every source with its counts after a Sources run, and — after an export — the destination and the record count. The app computes none of those numbers.

A train run renders in the same panel with two additions and one relabelling. output and written are the export Ster read, so the count row reads Ster read records above the export path instead of Written; then the adapter path Ster wrote, under Adapter Ster wrote:, with a Copy adapter path button; then the ster command the run reported, verbatim, so it can be repeated in a terminal. Both fields are optional in the decoder: a CLI without train still decodes, and every other subcommand omits them.

There is nothing to watch while it runs. The app pipes stdout and stderr and drains them to the end, and the CLI sends Ster's progress to its own stderr, so the preflight and per-step loss arrive only when the process exits, behind Skryba is running / This may take several minutes. A training run is minutes to hours, and the window shows nothing until it finishes.

Keep mine, on a finished rewrite

A completed Rewrite result carries a Keep mine editor seeded with the CLI's own rewritten text. Change it into your own words and the pair — the model's text against yours — is recorded by a second, separate invocation:

skryba writing-style keep

with {"kept": …, "machine": …, "strategy": …} on stdin. The two texts travel as one JSON object rather than in argv, which is the same rule Score and Rewrite follow: the command line the app displays stays a command, not a copy of somebody's prose.

The status line under the button is the CLI's own word, verbatim on failure and one sentence on success:

  • Recorded. The writing-style store holds <n> preference pairs.
  • Already recorded. The writing-style store holds <n> preference pairs.

A rewrite nobody changed is refused by the CLI — the kept text is identical to the machine text; that is a rewrite nobody changed, not a preference — and that refusal is what the line shows. Recording a preference never replaces the rewrite result it was read from.

Failure

A nonzero exit shows CLI stderr verbatim, so every refusal on the CLI writing-style page appears here unaltered — a missing directory, a store that holds nothing to export, a --lead-words no passage survives, a missing ster binary, or Ster's own message plus the ster command that carried it. A zero exit with malformed JSON throws the platform decoding error; a train run against a CLI old enough to print Ster's own report object on stdout is one such case, and it fails with The data couldn’t be read because it isn’t in the correct format. — the adapter is written even then, at the destination the form named. Install a CLI that keeps Ster's output on stderr. Use runbook to separate form, spawn, CLI, and decoding failures.

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