Skip to content
Annex S · Preview · Not yet installable Proposed Illustrative API

Setwork

Setwork names the fittings; Cuprum runs the pipes. It is a proposed offline compiler that turns command descriptions into typed Python functions, each returning an exact Cuprum SafeCmd.

Design draft v0.1, last revised 18 July 2026 · no code, package, or public repository yet

Plate 08 Copper inspects a fitting from a crate sorted by kind. Setwork is about naming the fittings; the tags are blank because the corpus is not written yet.

01 — The boundary

Describe, generate, run

Three owners, and generation is not execution. Setwork produces argv; Cuprum decides whether and how it runs.

Fig. 01

Who describes a command, who generates it, and who runs it?

Proposed
  1. 1 · Source description completion specs + overlays Versioned command metadata, imported statically, corrected by curated overlays for a named target profile.
    passes evidence-bearing IR to the next stage
  2. 2 · Generated adapter def echo(*text, n=False) -> SafeCmd An ordinary typed function that serializes values into an exact argv. It runs nothing.
    passes SafeCmd to the next stage
  3. 3 · Cuprum runtime policy, run, pipelines, results Allowlists, scopes, execution, observation, cancellation, and results, exactly as for any SafeCmd.
  • Build time The compiler never executes imported completion code under its default policy, and a command with unresolved facts is not published.
  • Run time The generated package imports no compiler, Node.js, or Fig code, and never inspects PATH.
Setwork names the fittings. Cuprum runs the pipes. Source: Setwork technical design, draft v0.1 (18 July 2026), Figure 1

Why a compiler

Cuprum’s tar builder validates its values and constructs a canonical tuple of tokens by hand. That works, but every supported command needs new handwritten API, validation, serialization, documentation, and tests. Meanwhile completion projects such as Fig, Carapace, and OpenCLI already describe the structure of many popular command lines.

Setwork proposes to close that gap: import what those sources can prove, correct it with curated overlays, and generate typed functions a checker can hold to account.

Why not trust completion data as is

Completion asks what token might sensibly come next. Invocation asks which typed values form a valid command, and exactly how they become argv. A completion spec may suggest numbers without proving the program accepts an integer, or which separator it wants, or which version introduced the option.

So every field in Setwork’s intermediate representation carries its evidence — authoritative, curated, imported, inferred, or unresolved — and unresolved fields block publication.

02 — Illustrative API

What a generated adapter looks like

A handwritten stand-in from the design documents, not generated output and not a package you can install.

generated_api_example.py (excerpt) Illustrative
def echo(
    *text: TextOperand,
    n: bool = False,
    enable_escapes: bool = False,
    disable_escapes: bool = False,
) -> SafeCmd:
    """Write operands with the selected GNU ``echo`` profile."""

    if enable_escapes and disable_escapes:
        raise ValueError("enable_escapes and disable_escapes conflict")

    operands = tuple(_stringify(value, role="echo operand") for value in text)
    if operands and _looks_like_echo_option(operands[0]):
        msg = (
            f"ambiguous first echo operand {operands[0]!r}; the selected profile "
            "has no verified option terminator for this position"
        )
        raise ValueError(msg)

    argv: list[str] = []
    if n:
        argv.append("-n")
    if enable_escapes:
        argv.append("-e")
    if disable_escapes:
        argv.append("-E")
    argv.extend(operands)
    return _BUILD_ECHO(*argv)
use_adapters.py Illustrative
import functools

from generated_api_example import BlockSize, Conversion, dd, echo

backup = dd(
    input_path="disk.img",
    output_path="backup.img",
    block_size=BlockSize("4M"),
    conversions=(Conversion.NOERROR, Conversion.SYNC),
)
print(backup.argv_with_program)

quiet = functools.partial(echo, n=True)
print(quiet("hello", "pipes").argv_with_program)

try:
    echo("-n")
except ValueError as exc:
    print(f"ValueError: {exc}")
Run 2026-10-19 against Cuprum 0.2.0b2
Exact argvstdout
('dd', 'if=disk.img', 'of=backup.img', 'bs=4M', 'conv=noerror,sync')
('echo', '-n', 'hello', 'pipes')
ValueError: ambiguous first echo operand '-n'; the selected profile has no verified option terminator for this position

Reading it

dd takes assignment operands, so its parameters become if=, of=, bs=, and conv= tokens rather than flags. echo is wrapped with functools.partial and keeps a checkable signature. And an operand the GNU profile could read as an option is refused before anything runs, because this profile has no verified way to terminate options.

Source lock
Each source repository, immutable revision, selected files, checksums, and adapter version
Licence
Licence evidence for every imported source, carried into the generated package
Overlays
The curated overlay set applied on top of imported facts
Evidence
Per field: authoritative, curated, imported, inferred, or unresolved
Reproducible
Two builds from the same lock produce byte-identical source and provenance

03 — Grammar

Not every command is flat

Commands fall into grammar classes, and each class changes what a trustworthy serializer needs.

Command grammar classes · from the Setwork terms of reference
Grammar class Examples Consequence for Setwork
Flat option algebra echo, many core utilitiesA generated function can usually model the full command.
Assignment operands ddNamed values serialize as tokens such as bs=4M, not POSIX flags.
Command family git, dockerRunnable leaves map to functions in a module.
Mode-sensitive command tar, opensslIncompatible modes become separate functions.
Embedded language find, sedA command-specific syntax tree is required.
Delegated execution find -exec, sh -cAuthorization must cover programs nested inside arguments. Excluded for now.

Dialect is part of the contract. GNU, BSD, BusyBox, and vendor variants are separate target profiles, never folded into a fictional universal command, and Setwork does not guess one from the machine it runs on.

04 — Exclusions

What Setwork will not do

05 — Open questions

Decisions still to make

  1. Which target profile ships first? GNU/Linux, macOS/BSD, BusyBox, or a narrower pinned toolchain decides the semantics, fixtures, and package naming.
  2. Which commands form the first corpus? The proposal is echo, dd, selected git leaves, tar create and extract, and a non-delegating find subset.
  3. May derived Fig material be redistributed? The examined revision’s licence files disagree, so this needs a written interpretation first.
  4. How should Cuprum authorize delegated execution? A joint Setwork and Cuprum decision; it blocks -exec-style features, not a safe first subset.
  5. One package, per-profile extras, or generate-it-yourself? The choice sets release cadence, licence obligations, and compatibility promises.
  6. Can the name be held? setwork was unclaimed on PyPI when this page was checked on 2026-09-23, but nothing reserves it yet, and a trademark search comes before anything is published.