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.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | nothing itself; its verbs read and write one case directory. |
| Writes | nothing itself; each verb's help names what it writes |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 a verb ran and returned 0 · 2 no verb given, or the verb refused |
| Machine output | human-only-by-design — group dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
Examples
Open a case directory with its hash-chained journal.
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:00ZIntake a local advisory into the case.
sbomflow case intake case-1 advisories/osv.json --actor psirt-lead --received-at 2026-06-21T09:00:00Z --reporter-class researcherShow the case: state, assignee, assessments and chain verification.
sbomflow case show case-1See also: sbomflow case open, sbomflow case show, sbomflow help goal post-market.
sbomflow case accept-risk#
Record a time-boxed human risk acceptance.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one case directory. |
| Writes | psirt-case.json (the case record, with an event appended to its hash-chained journal) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 a refused acceptance: no evidence, no expiry, or an unknown case |
| Machine output | artifact-suffices — appends the named human's bounded risk decision to the hash-chained case journal |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
--reason | REASON | none | any | yes | Substantive human rationale for accepting the risk. |
--expires-at | EXPIRES_AT | none | any | yes | ISO timestamp the acceptance runs out; an acceptance is time-boxed and never open-ended. |
--actor | ACTOR | none | any | yes | Named human recording this event; every case event is attributed. |
--evidence | EVIDENCE | none | any | yes | Evidence reference (repeatable); at least one is required. |
--renews | RENEWS | none | any | no | Prior acceptance event hash. |
--as-of | AS_OF | none | any | no | Timestamp to record (default: now, UTC). |
Examples
Record a time-boxed risk acceptance, with its rationale and evidence.
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:00ZSee 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.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one or more case directories holding a recorded final advisory, and csaf.publisher from sbomflow.yaml in the working directory. |
| Writes | a local directory laid out as CSAF 2.0 section 7.1 describes, with a receipt; never signed, hosted, uploaded or published |
--output names | a directory |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 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 output | artifact-suffices — writes a local directory and a receipt listing every file and its digest |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir [case_dir ...] | case_dir [case_dir ...] | none | any | yes | Case directories whose final advisories enter the tree. |
--output | OUTPUT | none | any | yes | Where 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.
sbomflow case advisory-tree case-1 --output csaf-treeSee also: sbomflow case export-advisory, sbomflow case show.
sbomflow case assign#
Assign the case to a named actor.
Assign the case to a named actor, recorded as a journal event. An unassigned
case cannot advance past triage.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one case directory. |
| Writes | psirt-case.json (the case record, with an event appended to its hash-chained journal) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 an unknown case |
| Machine output | artifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
--assignee | ASSIGNEE | none | any | yes | Named actor the case is assigned to. |
--actor | ACTOR | none | any | yes | Named human recording the assignment. |
--as-of | AS_OF | none | any | no | Timestamp to record (default: now, UTC). |
Examples
Assign the case to a named team.
sbomflow case assign case-1 --assignee firmware-team --actor psirt-lead --as-of 2026-06-21T09:00:00ZSee also: sbomflow case transition, sbomflow case show.
sbomflow case communicate#
Draft, approve, or record an externally-sent communication.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one case directory; nothing is ever sent. |
| Writes | an entry in the case's local communication journal |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 a refused draft, approval or record |
| Machine output | artifact-suffices — drafts, approves, or records delivery in the local communication journal; it never sends |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
--draft | (flag) | false | — | no | Create a new draft communication; nothing is sent. |
--approve | COMM_ID | none | any | no | Mark an existing draft approved for sending. |
--mark-sent | COMM_ID | none | any | no | Record that a human sent this communication elsewhere. SBOMFlow never sends anything. |
--kind | KIND | none | customer_notice, advisory, disclosure_note | no | What kind of communication this is (with --draft). One of: customer_notice, advisory, disclosure_note. |
--audience | AUDIENCE | none | any | no | Who the communication is addressed to (with --draft). |
--subject | SUBJECT | none | any | no | Subject line to record (with --draft). |
--body | BODY | none | any | no | Body text to record (with --draft). |
--external-ref | EXTERNAL_REF | none | any | no | Reference to where the communication actually went (ticket, message id) when marking it sent. |
--actor | ACTOR | none | any | yes | Named human recording this event; every case event is attributed. |
--as-of | AS_OF | none | any | no | Timestamp to record (default: now, UTC). |
Examples
Draft a customer notice; nothing is sent.
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:00ZApprove that draft for sending.
sbomflow case communicate case-1 --approve comm-73678b01f5ee9612 --actor psirt-lead --as-of 2026-06-21T09:00:00ZRecord that a human sent it elsewhere, and where.
sbomflow case communicate case-1 --mark-sent comm-73678b01f5ee9612 --external-ref TICKET-42 --actor psirt-lead --as-of 2026-06-21T09:00:00ZSee 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').
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one case directory, a local OSV-format snapshot and the releases an evidence store holds. |
| Writes | psirt-case.json (the case record, with an event appended to its hash-chained journal) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 an unreadable snapshot, store or case |
| Machine output | artifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
--store | STORE | none | any | yes | Evidence store directory. |
--advisories | ADVISORIES | none | any | yes | Local OSV-format snapshot (list, {'vulns': []}, or JSONL). |
--product | PRODUCT | none | any | no | Limit to one product (store name/id). |
--variant | VARIANT | none | any | no | Limit to one exact declared release variant (no cohort inference). |
--as-of | AS_OF | none | any | no | Timestamp to record (default: now, UTC). |
Examples
Correlate local advisories against the stored releases into exposure candidates.
sbomflow case correlate case-1 --store .sbomflow-store --advisories osv-snapshot.json --as-of 2026-06-21T09:00:00ZSee also: sbomflow case triage, sbomflow case show, sbomflow store query.
sbomflow case disclose#
Record a disclosure timeline event; sends nothing.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one case directory; nothing is sent, published or filed. |
| Writes | psirt-case.json (the case record, with an event appended to its hash-chained journal) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 a refused event |
| Machine output | artifact-suffices — records a human disclosure-timeline event without publishing anything |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
--event | STAGE | none | report_received, acknowledged, coordination_started, embargo_agreed, published | yes | Which disclosure-timeline stage is being recorded. One of: report_received, acknowledged, coordination_started, embargo_agreed, published. |
--party | PARTY | none | any | yes | The other party in this stage (reporter, coordinator, the reporting recipient). |
--communication-id | COMMUNICATION_ID | none | any | no | Communication this stage refers to, from case communicate. |
--note | NOTE | none | any | no | Free-text note recorded with the stage. |
--not-occurred | (flag) | false | — | no | Record that this stage did NOT happen (requires --reason). Without it an unrecorded stage stays 'not recorded'. |
--reason | REASON | none | any | no | Human's reason, required with --not-occurred. |
--actor | ACTOR | none | any | yes | Named human recording this event; every case event is attributed. |
--as-of | AS_OF | none | any | no | Timestamp to record (default: now, UTC). |
Examples
Record that a researcher's report was received.
sbomflow case disclose case-1 --event report_received --party researcher --actor psirt-lead --as-of 2026-06-21T09:00:00ZRecord that a stage did not happen, and why.
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:00ZSee 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.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one 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. |
| Writes | an 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 |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 an unknown release or unreadable input |
| Machine output | artifact-suffices — writes an unsigned, unsubmitted advisory draft |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
--store | STORE | none | any | yes | Evidence store holding the release the advisory describes. |
--release | RELEASE | none | any | yes | Release id the exported DRAFT is about. |
--advisories | ADVISORIES | none | any | yes | Local OSV-format advisory snapshot to draw the advisory text from (offline). |
--as-of | AS_OF | none | any | no | Timestamp to record (default: now, UTC). |
--profile | PROFILE | csaf_vex | csaf_vex, csaf_security_advisory | no | CSAF 2.0 profile of the document: csaf_vex (default; today's draft, byte-identical) or csaf_security_advisory. |
--document-status | {draft,interim,final} | draft | draft, interim, final | no | CSAF 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. |
--reviewer | REVIEWER | none | any | no | Named human recording an interim or final status (required with them; refused with draft). |
--note | NOTE | none | any | no | The reviewer's own note for an interim or final status (required with them; refused with draft). |
--tlp | {WHITE,GREEN,AMBER,RED} | none | WHITE, GREEN, AMBER, RED | no | TLP 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.
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:00ZRecord a named reviewer's final status for a TLP:WHITE security advisory naming the publisher from sbomflow.yaml.
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:00ZSee also: sbomflow case show, sbomflow case disclose, sbomflow analyze.
sbomflow case intake#
Intake a local advisory/report file with provenance + dedupe.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one case directory and a local advisory or report file (CSAF 2.0/2.1, CVE JSON 5, OSV or native). |
| Writes | psirt-case.json (the case record, with an event appended to its hash-chained journal) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 a missing or unrecognised report |
| Machine output | artifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
report_file | report_file | none | any | yes | Local CSAF 2.0/2.1, CVE JSON 5.x, OSV or native report JSON. |
--actor | ACTOR | none | any | yes | Named human performing the intake. |
--received-at | RECEIVED_AT | none | any | no | Received timestamp (default: now, UTC). |
--reporter-class | REPORTER_CLASS | none | any | no | researcher|customer|feed|internal|coordinator|unknown. |
--confidentiality | CONFIDENTIALITY | none | any | no | private|coordinated|public (default private). |
Examples
Intake a local OSV advisory, stating who reported it.
sbomflow case intake case-1 advisories/osv.json --actor psirt-lead --received-at 2026-06-21T09:00:00Z --reporter-class researcherIntake a CVE JSON 5 record under coordinated disclosure.
sbomflow case intake case-1 advisories/cve-record-5.json --actor psirt-lead --confidentiality coordinatedSee also: sbomflow case correlate, sbomflow case open, sbomflow help goal post-market.
sbomflow case open#
Open a new case directory + hash-chained journal.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | nothing but the directory named, which must not exist yet. |
| Writes | psirt-case.json (a new case record and its hash-chained journal) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 the case directory already exists |
| Machine output | artifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory to create. |
--case-id | CASE_ID | none | any | yes | Stable case id. |
--actor | ACTOR | none | any | yes | Named human opening the case. |
--title | TITLE | none | any | no | Short case title. |
--as-of | AS_OF | none | any | no | Timestamp to record (default: now, UTC). |
Examples
Open a case directory with its hash-chained journal.
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:00ZRefuse a case directory that already exists. Exits 2.
sbomflow case open case-1 --case-id PSIRT-2026-001 --actor psirt-leadSee also: sbomflow case intake, sbomflow case show, sbomflow help goal post-market.
sbomflow case propose-propagation#
Write family propagation proposals; applies to no product.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one case directory and a product-family definition file. |
| Writes | propagation-proposals.json in the case directory; it applies to no product; stdout (with --json, the same document) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 a missing family file or case |
| Machine output | has-json — emits a versioned proposal document with applied: false |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
--family | FAMILY | none | any | yes | Product-family definition file the proposals are written against. |
--json | (flag) | false | — | no | Print machine-readable JSON. |
Examples
Propose the family's other products for review.
sbomflow case propose-propagation case-1 --family family.jsonThe proposals as JSON.
sbomflow case propose-propagation case-1 --family family.json --jsonSee also: sbomflow case correlate, sbomflow case triage, sbomflow portfolio.
sbomflow case remediate#
Record remediation and verify finding removal in a frozen release.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one case directory and the frozen fixing release in an evidence store. |
| Writes | psirt-case.json (a remediation event, with the frozen-pack verification result) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 an unknown release, or evidence the command needs is absent |
| Machine output | artifact-suffices — appends a remediation observation and its frozen-pack verification result |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
--store | STORE | none | any | yes | Evidence store holding the frozen release the fix is verified against. |
--release | RELEASE | none | any | yes | Fixing release id. |
--finding-key | FINDING_KEY | none | any | yes | Finding key that must be absent from the fixing release for the remediation to verify. |
--summary | SUMMARY | none | any | yes | What was changed, in the recorder's own words. |
--actor | ACTOR | none | any | yes | Named human recording this event; every case event is attributed. |
--evidence | EVIDENCE | none | any | yes | Evidence reference (repeatable); at least one is required. |
--supersedes | SUPERSEDES | none | any | no | Prior remediation event hash. |
--as-of | AS_OF | none | any | no | Timestamp to record (default: now, UTC). |
Examples
Record a remediation and verify the finding is absent from the fixing release.
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:00ZSee 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.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one resolved or closed case directory. |
| Writes | psirt-case.json (the case record, with an event appended to its hash-chained journal) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 the case is not resolved or closed, or the input is refused |
| Machine output | artifact-suffices — appends the attributed advisory-reopen decision and transition to the hash-chained journal; no case is reopened automatically |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Resolved or closed case directory. |
--delta | {kev_added,range_widened,epss_spike} | none | kev_added, range_widened, epss_spike | yes | What changed about the advisory that justifies reopening a resolved case. |
--reason | REASON | none | any | yes | Substantive human rationale. |
--evidence | EVIDENCE | none | any | no | Evidence reference (repeatable). |
--actor | ACTOR | none | any | yes | Named human authorising the reopen. |
--as-of | AS_OF | none | any | no | Timestamp to record (default: now, UTC). |
Examples
Reopen a resolved case after the advisory was added to KEV.
sbomflow case reopen case-1 --delta kev_added --reason 'Added to KEV after release.' --actor psirt-lead --as-of 2026-06-21T09:00:00ZRefuse to reopen a case that was never resolved. Exits 2.
sbomflow case reopen case-1 --delta kev_added --reason 'Added to KEV.' --actor psirt-leadSee also: sbomflow case transition, sbomflow case correlate, sbomflow case show.
sbomflow case show#
Show the case: state, assignee, assessments, chain verification.
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one case directory and, optionally, a custody set its evidence references name. |
| Writes | stdout (the case state, assessments and chain verification; --json prints JSON) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 an unknown case directory · 4 the case journal's hash chain no longer verifies |
| Machine output | has-json — read/status surface; one versioned JSON document on stdout |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
--json | (flag) | false | — | no | Print machine-readable JSON. |
--custody-set | DIR | none | any | no | Custody 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.
sbomflow case show case-1The same as JSON.
sbomflow case show case-1 --jsonResolve its preserved-artifact evidence references against a custody set (a release run's evidence directory is accepted too).
sbomflow case show case-1 --custody-set custody-setSee also: sbomflow case triage, sbomflow case transition, sbomflow custody show.
sbomflow case transition#
Move the case state machine (guards enforced).
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one case directory; each transition's guards are enforced. |
| Writes | psirt-case.json (the case record, with an event appended to its hash-chained journal) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 a guarded transition refused |
| Machine output | artifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
--to | STATE | none | intake, triaging, assessed, remediating, resolved, closed | yes | Target state. One of: intake, triaging, assessed, remediating, resolved, closed. |
--actor | ACTOR | none | any | yes | Named human recording the transition. |
--note | NOTE | none | any | no | Optional note. |
--removal-override-reason | REASON | none | any | no | Substantive actor-attributed reason to override an unverified-removal closure block. Recorded in the journal; never implied. |
--as-of | AS_OF | none | any | no | Timestamp to record (default: now, UTC). |
Examples
Move an assigned case into triage.
sbomflow case transition case-1 --to triaging --actor psirt-lead --as-of 2026-06-21T09:00:00ZRefuse to close a case that was never worked. Exits 2.
sbomflow case transition case-1 --to closed --actor psirt-leadSee 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).
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.| Fact | Value |
|---|---|
| Group | post-market — Post-market cases (experimental) |
| Stability | experimental |
| Regime | any |
| Reads | one case directory in triage and the assessment named. |
| Writes | psirt-case.json (the case record, with an event appended to its hash-chained journal) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 a refused outcome, such as not_affected with no CISA justification |
| Machine output | artifact-suffices — appends JSON case records to a hash-chained journal; case show with --json is the read side |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
case_dir | case_dir | none | any | yes | Case directory. |
--assessment | ASSESSMENT | none | any | yes | Assessment id (see case show). |
--outcome | {affected,not_affected,needs_info} | none | affected, not_affected, needs_info | yes | The human determination. |
--actor | ACTOR | none | any | yes | Named human deciding. |
--evidence | EVIDENCE | none | any | no | Evidence reference (repeatable). |
--justification | JUSTIFICATION | none | any | no | CISA justification (required for not_affected). |
--statement | STATEMENT | none | any | no | Reviewer statement recorded on the assessment. |
--as-of | AS_OF | none | any | no | Timestamp to record (default: now, UTC). |
Examples
Record a human determination that the release is not affected, with its justification.
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:00ZRecord that it is affected.
sbomflow case triage case-1 --assessment assess-e02ce5f1b18637f1 --outcome affected --actor psirt-lead --evidence advisory-match --as-of 2026-06-21T09:00:00ZRefuse not_affected with no CISA justification. Exits 2.
sbomflow case triage case-1 --assessment assess-e02ce5f1b18637f1 --outcome not_affected --actor psirt-leadSee also: sbomflow case correlate, sbomflow case remediate, sbomflow review.