Reference · v0.44.0
Output
From the pinned CLI source. Read upstream.
Current format policy: Portable .tine files default to v5 (since 0.42). --for-legacy writes v4. The .tine/ repository format is v3. tine evidence export writes v4.
Errors, --json and exit codes (0.36)
Every leaf subcommand accepts --json. Commands with their own JSON payload
keep it unchanged; fleet up (with or without --dry-run) and
replay --dry-run/--inspect now emit one JSON object instead of ignoring the
flag. Any other command wraps its human output:
{"command": "fsck", "exit_code": 0, "output": "..."}
The v3 plumbing verbs (fsck, object, migrate-v3, fetch, push) always
print bare JSON; --json on them is a no-op. output.format = json turns on
only a command's own JSON, never the wrapper.
Errors go to stderr. Under --json, stdout carries only JSON: a failing command
that wrote no JSON of its own emits one error object (a usage error included)
and anything human it printed moves to stderr:
{"error": {"code": "not_found", "exit_code": 3, "message": "..."}}
| Exit | code | Meaning |
|---|---|---|
| 0 | — | ok |
| 1 | error | any other failure |
| 2 | usage | bad flags or arguments, or a refused flag combination |
| 3 | not_found | a run, ref or object that does not exist |
| 4 | verification_failed | a signature, digest or verdict did not hold |
| 5 | budget_exhausted | a budget or limit stopped the work |
| 6 | trust_required | needs a trust decision, or is unsupported here (verify --hermetic) |
Existing exit statuses keep their meaning; commands move to the specific codes
as they are revised, so a script should treat any non-zero status as failure
and read error.code for the reason.
New in 0.36: serve --oidc-issuer URL --oidc-audience AUD verifies OIDC bearer
tokens instead of the static token (--oidc-jwks-uri URL pins the key set,
otherwise it comes from the issuer's discovery document; every URL must be
https:// and none is ever taken from a token; --oidc-tenant-claim and
--oidc-roles-claim name the claims). The static token must now hold at least
32 bytes; serve --allow-weak-tokens starts with a shorter one while it is
rotated. After 5 consecutive failed authentications a client gets 429 with
Retry-After for a delay that doubles per failure (up to 5 minutes), and a 500
answers only {"error":"internal","request_id":...}, logging the exception.
New in 0.44: serve --quota-rate PER_SECOND [--quota-burst N] gives every
(tenant, subject) a token bucket; an upload or ref update over quota gets 429
with Retry-After. At most --quota-max-keys buckets (10,000) are held, the
least recently used evicted first. Clients retry a 429 at most 3 times,
honouring Retry-After up to 30 seconds and within the request deadline; a
0.34 client reports remote returned HTTP 429 and stops. serve --vsa-dir DIR
writes an in-toto SLSA Verification Summary Attestation
(https://slsa.dev/verification_summary/v1) for every admitted push to
DIR/<tenant>/<sha256>.json.
Default output format
tine config set output.format json # every command with --json now emits JSON
tine config get output.format # prints json; exit 1 when unset
tine config unset output.format
OPENTINE_OUTPUT=text tine show RUN # the env var wins over the file
tine show RUN --text # human output for this call only
output.format is text or json, stored only in the user's
$XDG_CONFIG_HOME/opentine/settings.json (written 0600; a repository cannot set
it). Precedence: an explicit --json or --text on the command, then
OPENTINE_OUTPUT, then the file, then text. Every command that has --json also
has --text; giving both is an error. Commands whose --json is only the
0.36 wrapper ignore the setting and never read the file. A value other than text/json in the env var
or the file, or a malformed file, stops the command with a one-line error (exit
- instead of guessing.
tine config set|get|unsetare the user settings;tine config KEY [VALUE]still edits the repository's porcelain keys. With no setting, every command's output is unchanged.