Machine output coverage

Which commands speak --json, which print machine output by default without a flag, which produce machine-readable artifacts on disk instead, and which are for a person at a terminal. Every command path carries one verdict, recorded once in the bundled command catalog and read from there by this page, sbomflow help machine-output, the last line of every command's own help and sbomflow commands --json. The offline test suite holds each verdict to evidence, so this page cannot silently rot when a command is added or gains a flag.

If you are scripting against SBOMFlow, start with the CLI overview's integration contract; this page is the per-command census behind it.

The machine interface, in order of authority#

  1. Artifacts on disk are the API. SBOMFlow's product is deterministic, versioned JSON files. A command that writes artifacts already has a machine interface — usually a richer one than any terminal flag could carry. sbomflow schema list names the families; sbomflow schema show <family> documents the fields offline.
  2. --json where operators read terminals. Read/status commands emit one pure, versioned JSON document on stdout, under the contract below.
  3. Machine output by default where the document is the product. The build-evidence, update-evidence, ingest and verification commands print their JSON document on stdout when no --output is given; --output FILE writes the same document to a file instead. Those documents name their contract under a schema key, the name the same bytes carry as a file.
  4. Exit codes are a machine contract of their own. Every command's exit code follows the published exit-code reference, and errors carry stable [E0xx] codes in both text and JSON.

A universal "result envelope" wrapping every command's stdout is deliberately not provided: artifacts on disk are the primary machine interface, and re-wrapping every command's output for symmetry would break existing consumers without serving a named need.

The --json contract#

Every command path that takes --json keeps four promises. They are checked by running every such path: once with the shortest invocation that reaches the command and points at nothing, and again over real invocations against a freshly built pack, store, custody set, case, index and vulnerability snapshot.

  1. Exactly one document. Under --json, stdout holds one JSON document and nothing else. Progress, notes, receipts and warnings go to stderr, so sbomflow … --json | jq never breaks on a stray line. A command that records something (approve --role, review --accept, regime-profile init) prints its human receipt on stderr and puts its document on stdout: the approval status, the refreshed review queue, the profile as written.
  2. Versioned. The document carries schema_version. Three documents are JSON arrays — index query, store list and store query — and there the contract name rides on each element rather than in a wrapper: wrapping the array would break every consumer already parsing it, for a key those consumers do not read. upgrade plan, gate simulate, store verify-gates and store verify-replay shipped their version under a schema key first; each now carries schema_version as well, with the same value, and the original key is unchanged.
  3. The same exit code with and without --json. Three declared exceptions, each because --json changes what the invocation does rather than how it is shown: - quickstart --json prints the pre-write disclosure and exits without writing or auditing anything, so the refusal that guards the write when no target is named and no terminal can confirm the scope (exit 2) is never reached; - ingest-codex-security --json and ingest-preserved-artifact --json are write-free, so combining --json with a write destination (--output, or --output-dir) is refused with [E019] and exit 2 rather than leaving the destination silently unwritten.
  4. A failure still answers on stdout. When a command that took --json fails after it has started, stdout carries one versioned sbomflow-cli-error-v1 document: the [E0xx] code, the title, the detail, the repair, the docs link, the exit code the process actually returned and the retry and state-change semantics. A command that already emits its own document on the failure path (validate --json prints its validate-report and then fails) keeps exactly that document — stdout never carries two. The stderr text is unchanged. What this does not cover: a usage error the argument parser rejects before any command runs (an unknown option, a missing required option, an invalid choice) prints the usage and a coded line on stderr, nothing on stdout, and exits 2, with or without --json.

Where to look a verdict up#

  • sbomflow help machine-output lists every verdict with its count, every path that takes --json, every path that prints machine output without a flag, and this contract in four sentences.
  • sbomflow help <command> (or sbomflow <command> --help) ends with a Machine output: line: that command's verdict and the reason for it.
  • sbomflow commands --json carries the same verdict on every command as a machine_output object (verdict, why, and served_by when a sibling command serves the data), alongside each command's options and network class. It is the command catalog. sbomflow help --json is a different document: the network-policy registry, one row per command with its network class and egress gates. Neither replaces the other.

The census#

In this build the CLI grammar has 174 command paths (95 top-level commands + 79 nested verbs), re-derived from the parser on every generation, never carried forward from a previous release. Of these, 70 take --json, 26 print machine output by default without a flag, 52 produce artifacts on disk as their machine interface, and 26 are human-only by design.

VerdictCountMeaning
has-json70Takes --json; one versioned JSON document on stdout.
machine-native26Machine output is already the default: JSON with no flag, or a CI-native format.
artifact-suffices52The command's product is deterministic files on disk (or an identical sibling surface already speaks --json); a terminal flag would duplicate the real interface.
human-only-by-design26Prose, interactive or dispatch surfaces for a person at a terminal; a machine consumer has no job here (18 of the 26 are bare group names that print usage).
add0A real machine-consumer job unserved by any surface. The audit found three; all three now ship the flag.

Every verdict is checked against evidence, not against its help text: has-json against the real parser, machine-native against an executed run of the command whose stdout parses as one JSON document, artifact-suffices against what the command declares it writes (and never against a command whose --output defaults to stdout), and human-only-by-design against the parser, which knows which paths only dispatch to their nested verbs.

The audited matrix#

CommandMachine outputVerdictWhy
analyzeartifacts on diskartifact-sufficeswrites the full evidence artifact set (SBOM, findings, gate, and under the cra regime the gaps and CRA report…); the files are the API
annotatestdout, no flagmachine-nativeits output IS a machine format: native CI annotations selected with --format (github, gitlab)
approve--jsonhas-jsonshows the approval status, or records one approval action and then shows it; the status is one versioned JSON document on stdout and a recording action's receipt goes to stderr
audit--jsonhas-jsonread/status surface; one versioned JSON document on stdout
auditor-packartifacts on diskartifact-sufficeswrites auditor-pack.zip, a self-contained read-only package
backfill--jsonhas-jsonread/status surface; one versioned JSON document on stdout
batch-run--jsonhas-jsonone versioned batch summary on stdout; each job's own output is captured so the document stays parseable, and every row carries that job's warning count (with the line count it was taken out of) plus its declared network posture
build-applicability-evidenceartifacts on diskartifact-sufficeswrites the build-applicability document at --output; that file is the machine surface, and analyze reads it through build_applicability in sbomflow.yaml
bundleartifacts on diskartifact-sufficeswrites evidence-bundle.json / .zip, the portable reviewer handoff
caseusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
case accept-riskartifacts on diskartifact-sufficesappends the named human's bounded risk decision to the hash-chained case journal
case advisory-treeartifacts on diskartifact-sufficeswrites a local directory and a receipt listing every file and its digest
case assignartifacts on diskartifact-sufficesappends JSON case records to a hash-chained journal; case show with --json is the read side
case communicateartifacts on diskartifact-sufficesdrafts, approves, or records delivery in the local communication journal; it never sends
case correlateartifacts on diskartifact-sufficesappends JSON case records to a hash-chained journal; case show with --json is the read side
case discloseartifacts on diskartifact-sufficesrecords a human disclosure-timeline event without publishing anything
case export-advisoryartifacts on diskartifact-sufficeswrites an unsigned, unsubmitted advisory draft
case intakeartifacts on diskartifact-sufficesappends JSON case records to a hash-chained journal; case show with --json is the read side
case openartifacts on diskartifact-sufficesappends JSON case records to a hash-chained journal; case show with --json is the read side
case propose-propagation--jsonhas-jsonemits a versioned proposal document with applied: false
case remediateartifacts on diskartifact-sufficesappends a remediation observation and its frozen-pack verification result
case reopenartifacts on diskartifact-sufficesappends the attributed advisory-reopen decision and transition to the hash-chained journal; no case is reopened automatically
case show--jsonhas-jsonread/status surface; one versioned JSON document on stdout
case transitionartifacts on diskartifact-sufficesappends JSON case records to a hash-chained journal; case show with --json is the read side
case triageartifacts on diskartifact-sufficesappends JSON case records to a hash-chained journal; case show with --json is the read side
cmake-evidencestdout, no flagmachine-nativeprints its CMake File API build-evidence document as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
commands--jsonhas-jsonread/status surface; one versioned JSON document on stdout (the command catalog resolved against the parser)
compare-releasesartifacts on diskartifact-sufficeswrites release-drift.json
component-supportusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
component-support fetchartifacts on diskartifact-sufficessaves each product document unchanged and component-support-fetch.json beside them in --output; those files are the machine surface
configusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
config show--jsonhas-jsonread/status surface; one versioned JSON document on stdout
cosign-verifystdout, no flagmachine-nativeprints its verification observations as JSON on stdout by default, no flag needed; --output writes the same document to a file instead; with cosign absent it still prints the document, recording available: false
custodyusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
custody add--jsonhas-jsonone sbomflow-custody-operation-v1 document: the outcome and the set's row for the artifact; with --intake-manifest, row is null and intake carries each entry's outcome
custody compare--jsonhas-jsonone sbomflow-custody-comparison-v1 document: what two sides record differently, or comparable: false with the reason nothing was compared
custody export--jsonhas-jsonone sbomflow-custody-export-v1 manifest: every exported member with its sha256 and size (the generated custody-export-index.md among them), the seal, the audit chain head and count, readable_index, and originals_carried: false
custody hold--jsonhas-jsonone sbomflow-custody-hold-v1 document: the hold as the set now records it and the audit event that binds it
custody init--jsonhas-jsonone sbomflow-custody-operation-v1 document for the new set
custody list--jsonhas-jsonprints the set index, sbomflow-custody-set-v1, verbatim
custody release-hold--jsonhas-jsonone sbomflow-custody-hold-v1 document: the lifted hold as the set now records it and the audit event that binds it
custody review--jsonhas-jsonone sbomflow-custody-review-result-v1 document: the key, status, reviewer, operation id and whether a keyed retry converged
custody show--jsonhas-jsonone sbomflow-custody-show-v1 document: the row with its decision, its records, and the set's decision file state
custody verify--jsonhas-jsonone sbomflow-custody-verify-v1 report; exit 4 on any integrity problem
dashboardartifacts on diskartifact-sufficesrenders a static human dashboard from release-index.json, which is already the machine surface
decisionsusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
decisions quarantine--jsonhas-jsonmoves an unreadable decision journal under quarantine as an AUDITED event — the copy, its digest and the parse failure are appended before the original is unlinked, so an un-audited quarantine is unreachable; one versioned JSON document on stdout
decisions recover--jsonhas-jsonread/status surface; one versioned JSON document on stdout
decisions transactions--jsonhas-jsonread/status surface; one versioned JSON document on stdout
decisions verify-transactions--jsonhas-jsonread/status surface; one versioned JSON document on stdout
diffoscope-comparestdout, no flagmachine-nativeprints its diffoscope comparison observations as JSON on stdout by default, no flag needed; --output writes the same document to a file instead; with diffoscope absent it still prints the document, recording available: false
doctor--jsonhas-jsonone versioned JSON document on stdout
elf-evidencestdout, no flagmachine-nativeprints its ELF inventory evidence as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
emit-user-infoartifacts on diskartifact-sufficeswrites the UNSIGNED CRA Annex II user-information draft files
esp-idf-evidencestdout, no flagmachine-nativeprints its ESP-IDF build-evidence document as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
examples--jsonhas-jsonread/status surface; one versioned JSON document on stdout
explaintext for humanshuman-only-by-designrenders a prose explanation composed from artifacts that are already machine-readable on disk
export-cleartifacts on diskartifact-sufficeswrites the lifecycle-event document at --output and cle-export-receipt.json beside it; those files are the machine surface
export-reqifartifacts on diskartifact-sufficeswrites the ReqIF document at --output and reqif-export-receipt.json beside it; those files are the machine surface
firmware-extractstdout, no flagmachine-nativeprints the bounded extraction inventory as JSON on stdout by default, no flag needed; --output writes the same document to a file instead; with the extractor absent it still prints the document, recording that extraction was skipped
gateusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
gate simulate--jsonhas-jsonread/status surface; one versioned JSON document on stdout
help--jsonhas-jsonread/status surface; one versioned JSON document on stdout
indexusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
index query--jsonhas-jsonread/status surface; one versioned JSON document on stdout
index rebuildartifacts on diskartifact-sufficeswrites the derived SQLite index — itself a machine-queryable artifact (index query speaks --json)
index validate--jsonhas-jsonstructured errors/notes on stdout; the exit code is unchanged, so switching on --json cannot change the verdict
index-releasesartifacts on diskartifact-sufficeswrites release-index.json, the machine-readable cross-release index. A product entry also carries product_line when its releases declared one distinct from the product name; absent means no line was declared, never that grouping failed
ingest-build-cve-reportartifacts on diskartifact-sufficeswrites build-cve-report-ingest.json into --output; that file is the machine surface
ingest-codex-security--jsonhas-jsonimports a sealed local Codex Security scan as external AI-assisted observations; one versioned JSON document on stdout, every record needs_review
ingest-cyclonedx-vdrartifacts on diskartifact-sufficeswrites cyclonedx-vdr-ingest.json into --output; that file is the machine surface
ingest-grypestdout, no flagmachine-nativeprints the sourced Grype observations as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
ingest-preserved-artifact--jsonhas-jsonpreserves one operator-selected artifact by identity and records what a human asserted about it; one versioned JSON document on stdout, never parsed, never a gate
ingest-sarifstdout, no flagmachine-nativeprints the sourced SARIF observations as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
ingest-trivystdout, no flagmachine-nativeprints the sourced Trivy observations as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
initartifacts on diskartifact-sufficesscaffolds sbomflow.yaml and inert review templates; the scaffolded files are the product
licenseusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
license inspect--jsonhas-jsonread/status surface; one versioned JSON document on stdout
license install--jsonhas-jsonverifies a delivered entitlement offline, then files it at the per-user discovery path; one versioned, non-secret JSON result on stdout (never the customer id, signature or entitlement id)
license status--jsonhas-jsonread/status surface; one versioned JSON document on stdout
license verify--jsonhas-jsonread/status surface; one versioned JSON document on stdout
linker-map-evidencestdout, no flagmachine-nativeprints its linker-map evidence as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
mcuboot-evidencestdout, no flagmachine-nativeprints its MCUboot image-header evidence as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
mcuboot-verifystdout, no flagmachine-nativeprints its verification observations as JSON on stdout by default, no flag needed; --output writes the same document to a file instead; the exit code carries the verdict
mender-evidencestdout, no flagmachine-nativeprints its Mender artifact evidence as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
migrate-in--jsonhas-jsonone versioned migration manifest; every row carries claim_origin and unimported files are listed with reasons
next-actions--jsonhas-jsonone versioned next-actions document on stdout; aggregation only, never a decision
notifyartifacts on diskartifact-sufficeswrites the notification plan artifact; delivery is a separate explicit step
oci-evidencestdout, no flagmachine-nativeprints its OCI image-layout evidence as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
passportusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
passport issueartifacts on diskartifact-sufficeswrites the signed passport files; passport verify (with --json) is the read side
passport verify--jsonhas-jsonread/status surface; one versioned JSON document on stdout
policyusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
policy diff--jsonhas-jsonread/status surface; one versioned JSON document on stdout
policy show--jsonhas-jsonread/status surface; one versioned JSON document on stdout
portfolioartifacts on diskartifact-sufficeswrites the cross-product portfolio index plus its dashboard. When the config declares products:[], the index also carries config_grouping: the operator's own group names joined to the product_ids their directories resolved to. Presentation only — it never changes identity, and a group whose outputs span two product identities is reported as spanning two rather than merged
prov-mapstdout, no flagmachine-nativeprints the PROV mapping of a traceability file as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
provenance-checkstdout, no flagmachine-nativeprints its provenance-check observations, expectation verdicts included, as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
quickstart--jsonhas-jsonone versioned JSON document on stdout (sbomflow-quickstart-preflight-v1, or sbomflow-quickstart-ci-preflight-v1 under --ci — two shapes, so two names). The RUN's machine interface is still the artifact set it writes; --json serves the pre-write disclosure instead — the same document the terminal form renders, so a caller reading JSON and a caller reading the terminal cannot reach different conclusions about the scan root, the bounded and labelled file count, or which of the five states the output directory is in. It emits that document and exits without writing, auditing or consenting
rauc-evidencestdout, no flagmachine-nativeprints its RAUC bundle evidence as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
recheckartifacts on diskartifact-sufficeswrites the recheck report artifact comparing shipped evidence to newer local advisory data
regime-profile--jsonhas-jsonlocal profile authoring kit; under --json every action prints one document (the profile it wrote, the validation, the inspection or the export manifest), and every action writes only profile files, never evidence
regime-view--jsonhas-jsonread-only view of an existing verified pack through a versioned profile; one versioned JSON document on stdout
release-chainusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
release-chain verify--jsonhas-jsonread/status surface; one versioned JSON document on stdout
reportusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
report freshness--jsonhas-jsonread/status surface; one versioned JSON document on stdout
reproducible-comparestdout, no flagmachine-nativeprints the digest comparison of the two build trees as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
review--jsonhas-jsonshows the review queue, or records one decision and then shows the refreshed queue; one versioned JSON document on stdout, and a recording action's receipt goes to stderr
review-mergeartifacts on diskartifact-sufficeswrites the merged reviewer decision file plus a conflict report
review-viewartifacts on diskartifact-sufficeswrites reviewer.html, a human console composed from artifacts that are already machine-readable
sbom-setusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
sbom-set compare--jsonhas-jsonone sbomflow-sbom-concordance-v1 document with --json (stdout) or --output (file): the subject binding, every input's custody record and, when the binding holds, the nine dimensions
schemausage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
schema list--jsonhas-jsonone versioned JSON document; exposing the flag revived a branch the parser could never reach
schema show--jsonhas-jsonread/status surface; one versioned JSON document on stdout
setuptext for humanshuman-only-by-designinteractive, TTY-gated onboarding; refuses CI and redirected IO by design
sign-bundleartifacts on diskartifact-sufficeswrites detached signature envelope files (formats: sbomflow, in-toto)
standards-view--jsonhas-jsonread/status surface; one versioned JSON document on stdout
storeusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
store addartifacts on diskartifact-sufficesrecords the release into the store (JSON records + index); store list / store show with --json are the read side
store empty-trash--jsonhas-jsonread/status surface; one versioned JSON document on stdout
store exploitation-deltaartifacts on diskartifact-sufficeswrites the delta document to --output; that file is the machine surface
store export--jsonhas-jsonone versioned completeness manifest, also written to the export directory; reconciles against the store index. store_index_state records how much of that index was read, and complete can only be true when it is read
store hold--jsonhas-jsonread/status surface; one versioned JSON document on stdout
store list--jsonhas-jsonread/status surface; one versioned JSON document on stdout
store query--jsonhas-jsonread/status surface; one versioned JSON document on stdout
store register-rename--jsonhas-jsonread/status surface; one versioned JSON document on stdout
store reindex--jsonhas-jsonrebuilds the deterministic index from canonical store-owned packs and reports every skipped input; prior_index_state says how much of the replaced index was read, and a prior index that will not parse is refused rather than rebuilt over
store reissueartifacts on diskartifact-sufficeswrites a new release plus portable-reissue-receipt.json; human summary on stdout
store reissue-plan--jsonhas-jsonread-only diagnosis of a refused export; one versioned JSON document on stdout
store release-hold--jsonhas-jsonread/status surface; one versioned JSON document on stdout
store retain--jsonhas-jsonread/status surface; one versioned JSON document on stdout
store show--jsonhas-jsonread/status surface; one versioned JSON document on stdout
store timeline--jsonhas-jsonread/status surface; one versioned JSON document on stdout
store verify--jsonhas-jsonread/status surface; one versioned JSON document on stdout
store verify-gates--jsonhas-jsonread/status surface; one versioned JSON document on stdout
store verify-replay--jsonhas-jsonreplays a stored release's recorded vulnerability inputs and reports whether each resolved to its exact recorded bytes; a recorded input it cannot find is reported as unavailable, never reproduced from whatever is current
supplier-packageusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
supplier-package emitartifacts on diskartifact-sufficeswrites intake.json, the shared SBOMs, emitted-from.json and (with --include-vex) vex.json into --to; those files are the machine surface
support-bundleartifacts on diskartifact-sufficeswrites the redaction-audited diagnostics zip; its contents are structured JSON
swupdate-evidencestdout, no flagmachine-nativeprints its SWUpdate artifact evidence as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
syft-scanstdout, no flagmachine-nativeprints the ingested Syft result as JSON on stdout by default, no flag needed; --output writes the same document to a file instead; with Syft absent it still prints the document, recording available: false
sync-dependencytrackartifacts on diskartifact-sufficesdry-run by default: writes the machine-readable sync plan artifact; delivery is a separate explicit step
sync-issuesartifacts on diskartifact-sufficesdry-run by default: writes the machine-readable sync plan artifact; delivery is a separate explicit step
sync-jiraartifacts on diskartifact-sufficesdry-run by default: writes the machine-readable sync plan artifact; delivery is a separate explicit step
sync-servicenowartifacts on diskartifact-sufficesdry-run by default: writes the machine-readable sync plan artifact; delivery is a separate explicit step
twister-evidencestdout, no flagmachine-nativeprints its Twister test-result evidence as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
update-manifest-evidencestdout, no flagmachine-nativeprints its TUF/SUIT update-manifest evidence as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
upgradeusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
upgrade inspecttext for humanshuman-only-by-designpre-migration eyeball of artifact families/versions; the machine decision surface is upgrade plan with --json
upgrade migrate-copyartifacts on diskartifact-sufficeswrites migrated copies plus upgrade-manifest.json to a new directory, never in place
upgrade plan--jsonhas-jsonread/status surface; one versioned JSON document on stdout
upgrade validateartifacts on diskartifact-sufficesthe identical validation ships as top-level validate, which speaks --json with the same exit contract; served by validate
uptane-evidencestdout, no flagmachine-nativeprints its Uptane metadata evidence as JSON on stdout by default, no flag needed; --output writes the same document to a file instead
validate--jsonhas-jsonread/status surface; one versioned JSON document on stdout
validate-annexii-modeltext for humanshuman-only-by-designpackaged-model self-check; the machine contract is the exit code (0 pass, non-zero fail)
validate-article14-modeltext for humanshuman-only-by-designpackaged-model self-check; the machine contract is the exit code (0 pass, non-zero fail)
validate-configartifacts on diskartifact-sufficesthe same config validation surfaces machine-readably in doctor --json (config block: errors and warnings); served by doctor
validate-graphtext for humanshuman-only-by-designpackaged-model self-check; the machine contract is the exit code (0 pass, non-zero fail)
validate-ssvc-modeltext for humanshuman-only-by-designpackaged-model self-check; the machine contract is the exit code (0 pass, non-zero fail)
validate-techdoc-modeltext for humanshuman-only-by-designpackaged-model self-check; the machine contract is the exit code (0 pass, non-zero fail)
verify-bundle--jsonhas-jsonverification detail, per-layer under --layered; parity with passport verify --json. Version skew stays context, changing no status and no exit code
verify-package-artifactsartifacts on diskartifact-sufficeswrites digest-verification observations JSON
vulndbusage onlyhuman-only-by-designgroup dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs
vulndb change-impact--jsonhas-jsonexplains which stored releases a source-set change touches, reusing the release comparison already on disk; --store is required so the command can only emit the shape the schema registry declares
vulndb inspectstdout, no flagmachine-nativeprints its report as JSON on stdout with no flag needed
vulndb pinartifacts on diskartifact-sufficesrecords the active-snapshot pin; vulndb inspect is the JSON read side
vulndb reindexartifacts on diskartifact-sufficesrebuilds the derived index from complete snapshot manifests after index loss or corruption
vulndb retentionartifacts on diskartifact-sufficeswrites a deterministic needed-snapshots binding and conservative retention plan; deletion requires explicit --apply
vulndb sources--jsonhas-jsonread/status surface; lists the registered sources and what each one has ACTIVE locally
vulndb updateartifacts on diskartifact-sufficesrecords a pinned, hashed snapshot plus its manifest (the one explicit network step)
vulndb verify--jsonhas-jsonread/status surface; one versioned JSON document on stdout
zephyr-evidencestdout, no flagmachine-nativeprints its Zephyr build-evidence document as JSON on stdout by default, no flag needed; --output writes the same document to a file instead

The three audited gaps — CLOSED#

Only three of the 123 non-dispatch paths audited in that pass were verdicted a real gap, all of them read-only verifiers or listings whose sibling commands already speak --json. All three now ship the flag, additively:

  • schema list — the machine-readable listing already existed internally, behind a flag the parser never declared, so the branch could not be reached. Declaring --json exposes the document and revives that dead branch.
  • index validate — integrity notes and errors are now a structured document. The exit code is unchanged, so a caller that switches on --json cannot get a different verdict from the one the text reported.
  • verify-bundle — verification detail, per-layer under --layered, at parity with passport verify --json. Version skew stays context: it appears in the document but changes no layer status and no exit code.

Human text, exit codes, and artifacts are byte-identical to before on every one of the three.

verify-bundle --layered: what a zero exit proves#

Every layered document carries exit_code_scope, and the human output prints the same sentence, because a consumer reading only one of the two must not have to find that boundary in prose somewhere else. Exit 0 proves that no layer failed and that every layer named by --require-layers reached a trusted status. It does not prove the bundle is trusted (read verdict / trusted_use), that an unrequired layer verified, that the evidence inside the bundle is correct, or anything at all about conformity.

--require-layers content,envelope,semantics,authority adds an expectation block — required, met, unmet, and a per-layer row carrying the observed status alongside the accepted_statuses that would have satisfied the requirement — and exits 7 when a well-formed report does not meet it. The full layer report is still emitted: an expectation narrows what the exit code means, never what the run reports. Without the flag the block is absent and every exit code is exactly what it was; a genuine verification failure stays 3 and outranks 7; an unknown layer name is refused as an input error (2) before verification runs, because a stricter check that silently did not happen is worse than no check. Nothing else on this page is a commitment to add flags; the remaining non---json rows are deliberate.

Doctor facts added by the same audit#

The same audit reviewed two outstanding doctor requests, and both shipped alongside it as facts-only additions — doctor reports local facts, fabricates nothing, and never decides:

  • offline docs availability — whether sbomflow help error and sbomflow help exit render from this install, with their code counts, and which web docs URLs error messages will print (recorded, never fetched).
  • path length — the absolute target path's length in characters and bytes next to the filesystem's own reported PATH_MAX / NAME_MAX limits, or an honest "not reported" where the platform has no answer.

See Troubleshooting for what doctor reports and why each row is context, never a verdict.