On this page

Spawn contract

The spawn contract is the complete boundary between Skryba Desktop and the installed skryba executable.

Executable resolution

On the first run, SkrybaCLI searches directories in this order:

  1. every current PATH entry;
  2. ~/.cargo/bin;
  3. ~/.local/bin;
  4. ~/.stado/bin;
  5. /opt/homebrew/bin;
  6. /usr/local/bin.

The first executable file named skryba is cached. Before reuse, the app checks that the cached path is still executable; otherwise it searches again.

Failure is Skryba is not installed. Install the CLI with cargo install --path . in the Skryba repository, or use the product installer, and make the executable discoverable in one of these directories.

Process inputs

  • executable URL: resolved path;
  • arguments: exactly SkrybaCommandDraft.arguments;
  • environment: launch environment plus missing keys from ~/.config/skryba/env;
  • stdin: pasted text for Score and Rewrite, the JSON pair for writing-style keep, and nothing for the writing-style and catalog forms, which carry paths, names and instructions in argv;
  • stdout and stderr: separate pipes. Both are pipes, never a terminal, so a CLI run that spawns ster — Train adapter, or a rewrite written by your own model — has its child's streaming output buffered into the stderr pipe and delivered only at exit.

An absent environment file adds nothing. Any other failure reading it refuses the run before process launch, naming the path and filesystem cause; it does not run the CLI without the file's credentials.

Rewrite always includes --style <NAME> and --language <NAME>, defaulting to preserve for both; the names come from the catalog listing the app ran, never from a list inside the app. These are separate from --policy, --generator, and --adapter. Besides the workflow the person runs, the app spawns skryba style list and skryba language list when the window opens and after every catalog change.

The model initially derives a display command from skryba plus argv. After execution starts it replaces that with executable.lastPathComponent plus the same argv. Text sent through stdin is not embedded in the displayed command.

Completion

Input delivery, both output drains and process-exit observation run concurrently. The app observes operations in completion order: an output-read failure is not hidden behind an unfinished input write. It returns an outcome only after input delivery, both output drains and the child process have finished. The outcome retains command line, Int32 termination status, stdout decoded as UTF-8, and stderr decoded as UTF-8. There is no polling interval or elapsed-time cutoff.

A failed read is a transport failure, not empty output. The run's error names standard output or standard error and the underlying cause. Input delivery retains write and close failures, including both when both fail. A transport failure requests termination of this invocation and joins its remaining I/O and exit work; partial output is not decoded as a successful workflow. The same error reaches the workflow failure panel, catalog diagnostic, draft operation or Keep mine status through the existing run boundary.

  • Nonzero status: stderr becomes the failure without paraphrase; empty stderr becomes skryba exited with status <status>. This includes a source-fallback refusal naming the requested profile and failed checks, and every catalog refusal.
  • Zero status: Score, Rewrite, Writing style, and Styles & languages decode stdout JSON.

Compatibility contract

Desktop depends on the CLI command names, argv flags, and serialized field names mirrored in SkrybaResults.swift. Rewrite requires profile.style, profile.language, and style_matched and language_matched in quality evaluations; profile.style_instruction and profile.language_instruction are read when present. The catalog report requires action, kind, and store, and entries with name, instruction, created_at, and updated_at. The app displays the returned profile, not just the form's current selection. Update the CLI and app together: an older CLI has no skryba style, and an incomplete result is not decoded with invented passing defaults.

Additional fields are tolerated by Swift decoding. Writing-style training's adapter and ster_command remain optional. A second JSON document on stdout is not additive and does break the view: the CLI keeps the spawned Ster process's output on stderr so stdout stays one document. Renaming or removing required fields, changing their types, or changing successful stdout away from one JSON document breaks the view. The CLI remains the only place allowed to interpret detector, quality, policy, style, or language behavior.

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