veripublica CLI convention

Version 0.4.1. The command-line contract every veripublica tool follows. The key words MUST, MUST NOT, SHOULD, and MAY are to be interpreted as described in RFC 2119 and RFC 8174 when, and only when, they appear in all capitals.

The goal: a user or a script that knows one veripublica tool already knows how to drive the next — same flags, same output naming, same exit codes — and one tool can consume another’s output without special-casing.

Two principles run through every rule below:


1. Invocation

<tool> [OPTIONS]
<tool> <subcommand> [OPTIONS]

2. Input

3. Options

3.1 Reserved options

These names have the same meaning in every tool. A tool implements the ones that apply to it (see §8) and MUST NOT repurpose them. Reserved names bind exact spellings, not prefixes: --image-format does not collide with --format. The one-line descriptions below are canonical — help text SHOULD reproduce them verbatim (see §7).

Option Meaning
-i, --input <PATH> The input. The only input form; positional paths are not accepted.
-o, --output <PATH> Where to write the output. See §4 for the default and the safety rules.
-f, --force Permit replacing existing output files. Never lifts the output-equals-input refusal.
--format <FORMAT> Report format. human (the default) is always supported; json is reserved for FORMATS.md.
--dry-run Report what would happen; change nothing on disk.
-y, --yes Assume “yes” for every prompt; run non-interactively. Not permission to overwrite files — that is -f.
-q, --quiet Suppress non-essential output. Errors still go to stderr.
-v, --verbose Emit more detail. Boolean: there are no verbosity levels.
-V, --version Print <tool> <semver> to stdout and exit 0.
-h, --help Print help to stdout and exit 0. See §7.
-- Not used. A tool MAY accept and ignore it; it MUST NOT give it any other meaning.

The <semver> printed by -V MAY carry SemVer build metadata pinning the exact source: +<short-hash>, with .dirty appended when the working tree had uncommitted changes at build time — epubveri 0.4.4+ca06641. Build metadata is part of a valid SemVer string and is ignored for precedence, so the reserved shape is unchanged for every consumer. When the hash is unavailable (notably a crates.io tarball build, which has no .git) the tool MUST fall back silently to the plain version: a published release is pinned by its tag; the hash pins the builds between tags. One string, everywhere: the CLI’s -V, a wasm crate’s version(), and a demo page’s footer print the same value from the same source.

3.2 The short-flag set is closed

Short flags are drawn only from the reserved set above. Every other option is long-form only (--quality, --profile, --goal, …).

3.3 Accepted syntaxes

Every tool, hand-rolled or library-parsed, accepts the same spellings:

3.4 Repetition

Given more than once Behaviour
A boolean flag (-v -v, -qq) Same as once. MUST NOT be an error.
Opposing booleans (-q … -v) The last one on the command line wins.
A single-valued option (--format x --format y) Usage error, exit 2 — two answers to one question; the tool does not guess.
A multi-valued option (a verifier’s -i) Accumulates.

Implementation note: clap’s default boolean errors on repetition; declare repeatable booleans with ArgAction::Count and read them as > 0.

3.5 Unrecognized tokens and values

3.6 --format

3.7 --dry-run

4. Output and file safety

For any tool that writes files:

5. Streams, prompts, and color

Streams.

Prompts.

Color.

6. Exit codes

Code Meaning
0 Success. For a verifier: every input processed; no error- or fatal-severity findings. For a transformer: the operation completed and its goal was met.
1 Completed, but problems remain. For a verifier: every input processed; at least one error- or fatal-severity finding remains. For a transformer: the goal was not met — declined fixes, or defects the tool cannot fix, remain.
2 The tool could not run, or could not process at least one input: usage errors, unreadable input, the §4 refusals, an unanswerable prompt (§5), an I/O failure.

7. Help

8. Conformance

A tool conforms to veripublica conventions vX when both hold:

  1. it satisfies every rule above that applies to it; and
  2. any reserved name it implements carries the meaning defined here.

There are no conformance levels. “Applies to it” is decided by this table:

Rules Required when
-h, -V, --format (§3.6), accepted syntaxes (§3.3), repetition (§3.4), unrecognized-token handling (§3.5), streams (§5), exit codes (§6), help (§7) Always
-i and the no-positional rule (§2) The tool takes a user-supplied input
-o, output naming and file safety (§4), -f The tool writes files
-y and the prompt rules (§5) The tool prompts
--format json (FORMATS.md), --dry-run, -q, -v, --color Never — but when implemented, with the defined meaning

A verifier needs no -o and no --dry-run; a tool with no prompts needs no -y. That is why there are no levels: “full conformance” would name a target no tool should even want to reach.

The claim — “conforms to veripublica conventions v0.4” — names the convention’s stability key (see §9), and a tag with that prefix (e.g. v0.4.0) MUST exist: a claim against main, or against an untagged version, points at a moving document and asserts nothing.

9. Versioning

10. Prior art — and departures

No RFC governs command-line syntax. RFC 2119 and RFC 8174, cited in the preamble, define the requirement keywords and nothing else in this document. The rules above descend from two non-RFC sources, and from one de facto convention:

Where this convention departs from those sources, it departs deliberately; each departure was argued in the linked issue:

The recurring justification: POSIX and GNU serve hundreds of independent programs, where uniformity can only ever be advisory. These are a handful of tools in one pipeline with one owner, where explicitness and loud failure are worth more than matching a reflex.