Post-market cases (experimental)

Track a case and draft its documents; nothing is filed. This page documents every command in the post-market group, in the order sbomflow help post-market lists them. Each command's section is generated from the command itself — its summary, description and options from the parser, and its reads, writes, exit codes, examples and see-also from the command catalog — so it says exactly what sbomflow <command> --help says. Every example below is executed offline by the test suite, and every non-zero exit code is either produced by an executed probe or carries a recorded reason why no offline probe can produce it.

See the CLI overview for how the thirteen groups fit together and the command reference for every command's options in one place.

Overview#

sbomflow case tracks one post-market vulnerability case and drafts its documents. It never decides that a product is affected and never files or submits anything. sbomflow help goal post-market walks the steps.

Who this is for: PSIRT engineers and disclosure coordinators.

sbomflow case#

Post-market PSIRT case workflow (experimental): track a case and draft its documents.

text
Work one post-market case in a local directory with a hash-chained
journal: open it, intake a local advisory, correlate it against the
evidence store into exposure CANDIDATES, record named human triage,
remediation, risk acceptance, communications and disclosure stages, and
export an unsigned advisory draft. Offline; drafts and records only:
never an 'affected' verdict, never a filing, and nothing is ever sent.
Name a verb, or the group prints its usage and exits 2.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsnothing itself; its verbs read and write one case directory.
Writesnothing itself; each verb's help names what it writes
Networkoffline — This command has no network-capable path.
Exit codes0 a verb ran and returned 0 · 2 no verb given, or the verb refused
Machine outputhuman-only-by-design — group dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit

Examples

Open a case directory with its hash-chained journal.

sh
sbomflow case open case-1 --case-id PSIRT-2026-001 --actor psirt-lead --title 'Advisory against the demo gateway' --as-of 2026-06-21T09:00:00Z

Intake a local advisory into the case.

sh
sbomflow case intake case-1 advisories/osv.json --actor psirt-lead --received-at 2026-06-21T09:00:00Z --reporter-class researcher

Show the case: state, assignee, assessments and chain verification.

sh
sbomflow case show case-1

See also: sbomflow case open, sbomflow case show, sbomflow help goal post-market.

sbomflow case accept-risk#

Record a time-boxed human risk acceptance.

text
Record a named human's time-boxed risk acceptance, with a substantive reason
and at least one evidence reference. An acceptance always expires; it is never
open-ended.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory.
Writespsirt-case.json (the case record, with an event appended to its hash-chained journal)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 a refused acceptance: no evidence, no expiry, or an unknown case
Machine outputartifact-suffices — appends the named human's bounded risk decision to the hash-chained case journal

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
--reasonREASONnoneanyyesSubstantive human rationale for accepting the risk.
--expires-atEXPIRES_ATnoneanyyesISO timestamp the acceptance runs out; an acceptance is time-boxed and never open-ended.
--actorACTORnoneanyyesNamed human recording this event; every case event is attributed.
--evidenceEVIDENCEnoneanyyesEvidence reference (repeatable); at least one is required.
--renewsRENEWSnoneanynoPrior acceptance event hash.
--as-ofAS_OFnoneanynoTimestamp to record (default: now, UTC).

Examples

Record a time-boxed risk acceptance, with its rationale and evidence.

sh
sbomflow case accept-risk case-1 --reason 'Exposure needs local access; fix ships in 2.5.' --expires-at 2999-12-31T23:59:59Z --actor psirt-lead --evidence threat-model.md --as-of 2026-06-21T09:00:00Z

See also: sbomflow case remediate, sbomflow case show, sbomflow review.

sbomflow case advisory-tree#

Write a local CSAF 2.0 section 7.1 directory of final advisories; never publish.

text
Write a directory laid out as CSAF 2.0 section 7.1 describes (provider
metadata, white/<yyyy>/ documents with .sha256 and .sha512 files, index.txt,
changes.csv and a ROLIE feed) from each case's final advisory. A document
enters only when its case journal records final for exactly its sha256, it is
TLP:WHITE and it names the csaf.publisher stated in sbomflow.yaml; any refused
case writes nothing. Generated locally for the manufacturer to review and
publish: SBOMFlow does not publish, host, sign or upload.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone or more case directories holding a recorded final advisory, and csaf.publisher from sbomflow.yaml in the working directory.
Writesa local directory laid out as CSAF 2.0 section 7.1 describes, with a receipt; never signed, hosted, uploaded or published
--output namesa directory
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 no stated publisher, or a case whose advisory is not recorded final for its exact bytes, not TLP:WHITE or names another publisher; nothing is written
Machine outputartifact-suffices — writes a local directory and a receipt listing every file and its digest

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dir [case_dir ...]case_dir [case_dir ...]noneanyyesCase directories whose final advisories enter the tree.
--outputOUTPUTnoneanyyesWhere to write the tree: absent, empty, or a tree SBOMFlow wrote before (replaced whole); anything else is left untouched and refused (directory).

Examples

Write a local directory laid out as CSAF 2.0 section 7.1 describes from the case's final TLP:WHITE advisory.

sh
sbomflow case advisory-tree case-1 --output csaf-tree

See also: sbomflow case export-advisory, sbomflow case show.

sbomflow case assign#

Assign the case to a named actor.

text
Assign the case to a named actor, recorded as a journal event. An unassigned
case cannot advance past triage.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory.
Writespsirt-case.json (the case record, with an event appended to its hash-chained journal)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 an unknown case
Machine outputartifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
--assigneeASSIGNEEnoneanyyesNamed actor the case is assigned to.
--actorACTORnoneanyyesNamed human recording the assignment.
--as-ofAS_OFnoneanynoTimestamp to record (default: now, UTC).

Examples

Assign the case to a named team.

sh
sbomflow case assign case-1 --assignee firmware-team --actor psirt-lead --as-of 2026-06-21T09:00:00Z

See also: sbomflow case transition, sbomflow case show.

sbomflow case communicate#

Draft, approve, or record an externally-sent communication.

text
Keep the case's communications in a local journal: draft one, approve a draft,
or record that a human sent it elsewhere, with where it went. SBOMFlow never
sends anything.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory; nothing is ever sent.
Writesan entry in the case's local communication journal
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 a refused draft, approval or record
Machine outputartifact-suffices — drafts, approves, or records delivery in the local communication journal; it never sends

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
--draft(flag)false—noCreate a new draft communication; nothing is sent.
--approveCOMM_IDnoneanynoMark an existing draft approved for sending.
--mark-sentCOMM_IDnoneanynoRecord that a human sent this communication elsewhere. SBOMFlow never sends anything.
--kindKINDnonecustomer_notice, advisory, disclosure_notenoWhat kind of communication this is (with --draft). One of: customer_notice, advisory, disclosure_note.
--audienceAUDIENCEnoneanynoWho the communication is addressed to (with --draft).
--subjectSUBJECTnoneanynoSubject line to record (with --draft).
--bodyBODYnoneanynoBody text to record (with --draft).
--external-refEXTERNAL_REFnoneanynoReference to where the communication actually went (ticket, message id) when marking it sent.
--actorACTORnoneanyyesNamed human recording this event; every case event is attributed.
--as-ofAS_OFnoneanynoTimestamp to record (default: now, UTC).

Examples

Draft a customer notice; nothing is sent.

sh
sbomflow case communicate case-1 --draft --kind customer_notice --audience customers --subject 'Gateway advisory' --body 'An update is available.' --actor psirt-lead --as-of 2026-06-21T09:00:00Z

Approve that draft for sending.

sh
sbomflow case communicate case-1 --approve comm-73678b01f5ee9612 --actor psirt-lead --as-of 2026-06-21T09:00:00Z

Record that a human sent it elsewhere, and where.

sh
sbomflow case communicate case-1 --mark-sent comm-73678b01f5ee9612 --external-ref TICKET-42 --actor psirt-lead --as-of 2026-06-21T09:00:00Z

See also: sbomflow case disclose, sbomflow case show, sbomflow help goal post-market.

sbomflow case correlate#

Correlate local advisory records against the store into exposure CANDIDATES (never 'affected').

text
Correlate a local OSV-format snapshot against the releases an evidence store
holds, and record each match as an exposure CANDIDATE, per release, variant
and channel. A candidate is never an 'affected' verdict; a named human triages
it.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory, a local OSV-format snapshot and the releases an evidence store holds.
Writespsirt-case.json (the case record, with an event appended to its hash-chained journal)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 an unreadable snapshot, store or case
Machine outputartifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
--storeSTOREnoneanyyesEvidence store directory.
--advisoriesADVISORIESnoneanyyesLocal OSV-format snapshot (list, {'vulns': []}, or JSONL).
--productPRODUCTnoneanynoLimit to one product (store name/id).
--variantVARIANTnoneanynoLimit to one exact declared release variant (no cohort inference).
--as-ofAS_OFnoneanynoTimestamp to record (default: now, UTC).

Examples

Correlate local advisories against the stored releases into exposure candidates.

sh
sbomflow case correlate case-1 --store .sbomflow-store --advisories osv-snapshot.json --as-of 2026-06-21T09:00:00Z

See also: sbomflow case triage, sbomflow case show, sbomflow store query.

sbomflow case disclose#

Record a disclosure timeline event; sends nothing.

text
Record one coordinated-disclosure stage (report received, acknowledged,
coordination started, embargo agreed, published), or record that a stage did
not happen and why. No deadline is computed and nothing is sent, published or
filed.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory; nothing is sent, published or filed.
Writespsirt-case.json (the case record, with an event appended to its hash-chained journal)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 a refused event
Machine outputartifact-suffices — records a human disclosure-timeline event without publishing anything

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
--eventSTAGEnonereport_received, acknowledged, coordination_started, embargo_agreed, publishedyesWhich disclosure-timeline stage is being recorded. One of: report_received, acknowledged, coordination_started, embargo_agreed, published.
--partyPARTYnoneanyyesThe other party in this stage (reporter, coordinator, the reporting recipient).
--communication-idCOMMUNICATION_IDnoneanynoCommunication this stage refers to, from case communicate.
--noteNOTEnoneanynoFree-text note recorded with the stage.
--not-occurred(flag)false—noRecord that this stage did NOT happen (requires --reason). Without it an unrecorded stage stays 'not recorded'.
--reasonREASONnoneanynoHuman's reason, required with --not-occurred.
--actorACTORnoneanyyesNamed human recording this event; every case event is attributed.
--as-ofAS_OFnoneanynoTimestamp to record (default: now, UTC).

Examples

Record that a researcher's report was received.

sh
sbomflow case disclose case-1 --event report_received --party researcher --actor psirt-lead --as-of 2026-06-21T09:00:00Z

Record that a stage did not happen, and why.

sh
sbomflow case disclose case-1 --event embargo_agreed --party coordinator --not-occurred --reason 'No coordinator involved.' --actor psirt-lead --as-of 2026-06-21T09:00:00Z

See also: sbomflow case communicate, sbomflow case show, sbomflow validate-article14-model.

sbomflow case export-advisory#

Export an unsigned CSAF advisory (a DRAFT by default); never publish.

text
Export an unsigned CSAF 2.0 advisory about one stored release, drawing the
advisory text from a local snapshot, for human review. By default it is the
CSAF VEX DRAFT case-advisory.DRAFT.json. --profile csaf_security_advisory
writes the security-advisory profile; --document-status interim or final
records a named reviewer's status for the exact bytes written and needs
--reviewer, --note, --tlp and csaf.publisher in sbomflow.yaml. It is generated
locally for the manufacturer to review and publish: never signed, submitted,
hosted, uploaded or published.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory, a release in an evidence store, a local advisory snapshot and, for a non-default document, csaf.publisher from sbomflow.yaml in the working directory.
Writesan unsigned CSAF advisory into the case directory (case-advisory.DRAFT.json by default, case-advisory.<status>.json for a recorded interim or final); never submitted or published
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 an unknown release or unreadable input
Machine outputartifact-suffices — writes an unsigned, unsubmitted advisory draft

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
--storeSTOREnoneanyyesEvidence store holding the release the advisory describes.
--releaseRELEASEnoneanyyesRelease id the exported DRAFT is about.
--advisoriesADVISORIESnoneanyyesLocal OSV-format advisory snapshot to draw the advisory text from (offline).
--as-ofAS_OFnoneanynoTimestamp to record (default: now, UTC).
--profilePROFILEcsaf_vexcsaf_vex, csaf_security_advisorynoCSAF 2.0 profile of the document: csaf_vex (default; today's draft, byte-identical) or csaf_security_advisory.
--document-status{draft,interim,final}draftdraft, interim, finalnoCSAF tracking status. draft (default) is written as case-advisory.DRAFT.json and records nothing; interim or final is written as case-advisory.<status>.json and appends an advisory_status_recorded journal event naming the reviewer, the note and the document's sha256.
--reviewerREVIEWERnoneanynoNamed human recording an interim or final status (required with them; refused with draft).
--noteNOTEnoneanynoThe reviewer's own note for an interim or final status (required with them; refused with draft).
--tlp{WHITE,GREEN,AMBER,RED}noneWHITE, GREEN, AMBER, REDnoTLP label a person chose for the document (CSAF 2.0 section 3.2.1.5.2); required for interim and final and never defaulted. Only a TLP:WHITE final document can enter case advisory-tree.

Examples

Export an unsigned CSAF VEX draft about one stored release.

sh
sbomflow case export-advisory case-1 --store .sbomflow-store --release example-gateway-2.4.1 --advisories osv-snapshot.json --as-of 2026-06-21T09:00:00Z

Record a named reviewer's final status for a TLP:WHITE security advisory naming the publisher from sbomflow.yaml.

sh
sbomflow case export-advisory case-1 --store .sbomflow-store --release example-gateway-2.4.1 --advisories osv-snapshot.json --profile csaf_security_advisory --document-status final --reviewer psirt-lead --note 'Reviewed against the 2.4.2 release notes.' --tlp WHITE --as-of 2026-06-21T09:00:00Z

See also: sbomflow case show, sbomflow case disclose, sbomflow analyze.

sbomflow case intake#

Intake a local advisory/report file with provenance + dedupe.

text
Intake one local advisory or report file (CSAF 2.0 or 2.1, CVE JSON 5, OSV or
a native report) into the case, recording its provenance, who received it and
when, and de-duplicating it against what the case already holds.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory and a local advisory or report file (CSAF 2.0/2.1, CVE JSON 5, OSV or native).
Writespsirt-case.json (the case record, with an event appended to its hash-chained journal)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 a missing or unrecognised report
Machine outputartifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
report_filereport_filenoneanyyesLocal CSAF 2.0/2.1, CVE JSON 5.x, OSV or native report JSON.
--actorACTORnoneanyyesNamed human performing the intake.
--received-atRECEIVED_ATnoneanynoReceived timestamp (default: now, UTC).
--reporter-classREPORTER_CLASSnoneanynoresearcher|customer|feed|internal|coordinator|unknown.
--confidentialityCONFIDENTIALITYnoneanynoprivate|coordinated|public (default private).

Examples

Intake a local OSV advisory, stating who reported it.

sh
sbomflow case intake case-1 advisories/osv.json --actor psirt-lead --received-at 2026-06-21T09:00:00Z --reporter-class researcher

Intake a CVE JSON 5 record under coordinated disclosure.

sh
sbomflow case intake case-1 advisories/cve-record-5.json --actor psirt-lead --confidentiality coordinated

See also: sbomflow case correlate, sbomflow case open, sbomflow help goal post-market.

sbomflow case open#

Open a new case directory + hash-chained journal.

text
Create a new case directory with its hash-chained journal and first event,
naming the stable case id and the human who opened it. A directory that
already exists is refused.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsnothing but the directory named, which must not exist yet.
Writespsirt-case.json (a new case record and its hash-chained journal)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 the case directory already exists
Machine outputartifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory to create.
--case-idCASE_IDnoneanyyesStable case id.
--actorACTORnoneanyyesNamed human opening the case.
--titleTITLEnoneanynoShort case title.
--as-ofAS_OFnoneanynoTimestamp to record (default: now, UTC).

Examples

Open a case directory with its hash-chained journal.

sh
sbomflow case open case-1 --case-id PSIRT-2026-001 --actor psirt-lead --title 'Advisory against the demo gateway' --as-of 2026-06-21T09:00:00Z

Refuse a case directory that already exists. Exits 2.

sh
sbomflow case open case-1 --case-id PSIRT-2026-001 --actor psirt-lead

See also: sbomflow case intake, sbomflow case show, sbomflow help goal post-market.

sbomflow case propose-propagation#

Write family propagation proposals; applies to no product.

text
Write propagation proposals for the other products of a product family: each
is a proposal for review and applies to no product until a named human records
a decision for it.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory and a product-family definition file.
Writespropagation-proposals.json in the case directory; it applies to no product; stdout (with --json, the same document)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 a missing family file or case
Machine outputhas-json — emits a versioned proposal document with applied: false

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
--familyFAMILYnoneanyyesProduct-family definition file the proposals are written against.
--json(flag)false—noPrint machine-readable JSON.

Examples

Propose the family's other products for review.

sh
sbomflow case propose-propagation case-1 --family family.json

The proposals as JSON.

sh
sbomflow case propose-propagation case-1 --family family.json --json

See also: sbomflow case correlate, sbomflow case triage, sbomflow portfolio.

sbomflow case remediate#

Record remediation and verify finding removal in a frozen release.

text
Record a remediation and verify it against a frozen fixing release in the
evidence store: the named finding must be absent from that release's pack. The
verification result is recorded beside the remediation.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory and the frozen fixing release in an evidence store.
Writespsirt-case.json (a remediation event, with the frozen-pack verification result)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 an unknown release, or evidence the command needs is absent
Machine outputartifact-suffices — appends a remediation observation and its frozen-pack verification result

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
--storeSTOREnoneanyyesEvidence store holding the frozen release the fix is verified against.
--releaseRELEASEnoneanyyesFixing release id.
--finding-keyFINDING_KEYnoneanyyesFinding key that must be absent from the fixing release for the remediation to verify.
--summarySUMMARYnoneanyyesWhat was changed, in the recorder's own words.
--actorACTORnoneanyyesNamed human recording this event; every case event is attributed.
--evidenceEVIDENCEnoneanyyesEvidence reference (repeatable); at least one is required.
--supersedesSUPERSEDESnoneanynoPrior remediation event hash.
--as-ofAS_OFnoneanynoTimestamp to record (default: now, UTC).

Examples

Record a remediation and verify the finding is absent from the fixing release.

sh
sbomflow case remediate case-1 --store .sbomflow-store --release example-gateway-2.4.1 --finding-key x --summary 'Upgraded requests.' --actor psirt-lead --evidence change-1234 --as-of 2026-06-21T09:00:00Z

See also: sbomflow case transition, sbomflow case accept-risk, sbomflow store timeline.

sbomflow case reopen#

Human-only reopen after a material advisory delta; returns the case to triaging.

text
Reopen a resolved or closed case after a material advisory delta (added to
KEV, a widened range, an EPSS spike), returning it to triaging. Human-only: no
case is ever reopened automatically.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone resolved or closed case directory.
Writespsirt-case.json (the case record, with an event appended to its hash-chained journal)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 the case is not resolved or closed, or the input is refused
Machine outputartifact-suffices — appends the attributed advisory-reopen decision and transition to the hash-chained journal; no case is reopened automatically

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesResolved or closed case directory.
--delta{kev_added,range_widened,epss_spike}nonekev_added, range_widened, epss_spikeyesWhat changed about the advisory that justifies reopening a resolved case.
--reasonREASONnoneanyyesSubstantive human rationale.
--evidenceEVIDENCEnoneanynoEvidence reference (repeatable).
--actorACTORnoneanyyesNamed human authorising the reopen.
--as-ofAS_OFnoneanynoTimestamp to record (default: now, UTC).

Examples

Reopen a resolved case after the advisory was added to KEV.

sh
sbomflow case reopen case-1 --delta kev_added --reason 'Added to KEV after release.' --actor psirt-lead --as-of 2026-06-21T09:00:00Z

Refuse to reopen a case that was never resolved. Exits 2.

sh
sbomflow case reopen case-1 --delta kev_added --reason 'Added to KEV.' --actor psirt-lead

See also: sbomflow case transition, sbomflow case correlate, sbomflow case show.

sbomflow case show#

Show the case: state, assignee, assessments, chain verification.

text
Show the case: its state, assignee, assessments, exposure by variant and
channel, recorded events and whether its hash-chained journal still verifies.
A journal whose chain no longer verifies exits 4. Read-only.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory and, optionally, a custody set its evidence references name.
Writesstdout (the case state, assessments and chain verification; --json prints JSON)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 an unknown case directory · 4 the case journal's hash chain no longer verifies
Machine outputhas-json — read/status surface; one versioned JSON document on stdout

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
--json(flag)false—noPrint machine-readable JSON.
--custody-setDIRnoneanynoCustody set, or a release run's evidence directory (its preserved-artifacts.json), to resolve the case's preserved-artifact evidence references against: present (review status; the original's state), absent, or set_unusable. Read-only; no original is opened or hashed.

Examples

Show the case: state, assignee, assessments and chain verification.

sh
sbomflow case show case-1

The same as JSON.

sh
sbomflow case show case-1 --json

Resolve its preserved-artifact evidence references against a custody set (a release run's evidence directory is accepted too).

sh
sbomflow case show case-1 --custody-set custody-set

See also: sbomflow case triage, sbomflow case transition, sbomflow custody show.

sbomflow case transition#

Move the case state machine (guards enforced).

text
Move the case through its state machine: intake, triaging, assessed,
remediating, resolved, closed. Each transition's guards are enforced (an
assignee, a triage outcome, a verified remediation) and a refused transition
exits 2.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory; each transition's guards are enforced.
Writespsirt-case.json (the case record, with an event appended to its hash-chained journal)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 a guarded transition refused
Machine outputartifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
--toSTATEnoneintake, triaging, assessed, remediating, resolved, closedyesTarget state. One of: intake, triaging, assessed, remediating, resolved, closed.
--actorACTORnoneanyyesNamed human recording the transition.
--noteNOTEnoneanynoOptional note.
--removal-override-reasonREASONnoneanynoSubstantive actor-attributed reason to override an unverified-removal closure block. Recorded in the journal; never implied.
--as-ofAS_OFnoneanynoTimestamp to record (default: now, UTC).

Examples

Move an assigned case into triage.

sh
sbomflow case transition case-1 --to triaging --actor psirt-lead --as-of 2026-06-21T09:00:00Z

Refuse to close a case that was never worked. Exits 2.

sh
sbomflow case transition case-1 --to closed --actor psirt-lead

See also: sbomflow case triage, sbomflow case reopen, sbomflow case show.

sbomflow case triage#

Record a human triage outcome for one exposure assessment (evidence-backed, VEX-justified).

text
Record a named human's determination for one exposure assessment: affected,
not_affected (with a CISA justification) or needs_info, with the evidence it
rests on. The case must be in triage.
FactValue
Grouppost-market — Post-market cases (experimental)
Stabilityexperimental
Regimeany
Readsone case directory in triage and the assessment named.
Writespsirt-case.json (the case record, with an event appended to its hash-chained journal)
Networkoffline — This command has no network-capable path.
Exit codes0 ok · 2 a refused outcome, such as not_affected with no CISA justification
Machine outputartifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side

Options

OptionValueDefaultAllowedRequiredHelp
-h, --help(flag)none—noshow this help message and exit
case_dircase_dirnoneanyyesCase directory.
--assessmentASSESSMENTnoneanyyesAssessment id (see case show).
--outcome{affected,not_affected,needs_info}noneaffected, not_affected, needs_infoyesThe human determination.
--actorACTORnoneanyyesNamed human deciding.
--evidenceEVIDENCEnoneanynoEvidence reference (repeatable).
--justificationJUSTIFICATIONnoneanynoCISA justification (required for not_affected).
--statementSTATEMENTnoneanynoReviewer statement recorded on the assessment.
--as-ofAS_OFnoneanynoTimestamp to record (default: now, UTC).

Examples

Record a human determination that the release is not affected, with its justification.

sh
sbomflow case triage case-1 --assessment assess-e02ce5f1b18637f1 --outcome not_affected --justification vulnerable_code_not_in_execute_path --actor psirt-lead --evidence reachability.json --as-of 2026-06-21T09:00:00Z

Record that it is affected.

sh
sbomflow case triage case-1 --assessment assess-e02ce5f1b18637f1 --outcome affected --actor psirt-lead --evidence advisory-match --as-of 2026-06-21T09:00:00Z

Refuse not_affected with no CISA justification. Exits 2.

sh
sbomflow case triage case-1 --assessment assess-e02ce5f1b18637f1 --outcome not_affected --actor psirt-lead

See also: sbomflow case correlate, sbomflow case remediate, sbomflow review.