Skip to main content

Output formats and exit codes

One line: one --format flag and one exit-code contract across the whole CLI, so every check drops into CI the same way.

The --format flag

Eight finding-producing commands share the flag: verify, warden, inspect, audit, foresee, skillscan, memcheck, and drift.

FormatWhat you get
textA human-readable table (the default)
jsonA flat JSON array of findings
sarifSARIF 2.1.0 for CI code-scanning (GitHub, etc.)

lock and trustdb write files rather than findings, and cardcheck prints its verdict report as text; none of the three takes --format.

The pre-0.2.0 --json flag on verify and warden is kept as a deprecated alias for one release; it prints a stderr warning and maps to --format json.

JSON

$ vulkro-live verify --format json lodahs
[
{
"ecosystem": "npm",
"name": "lodahs",
"verdict": "MALICIOUS",
"reason": "flagged malicious by OSV (MAL-2025-25502): Malicious code in lodahs (npm)",
"latest_version": "0.0.1-security",
"created": "2019-11-25T16:49:21.220Z",
"malicious_ids": [
"MAL-2025-25502"
]
}
]

SARIF and the rule-id namespace

SARIF output validates against 2.1.0 and uploads directly to GitHub code scanning. Rule ids are namespaced vulkro-live/<command>/<slug>, for example vulkro-live/verify/malicious or vulkro-live/drift/description-changed, so they never collide with the paid engine's vulkro/... ids in the same code-scanning view.

$ vulkro-live verify --format sarif lodahs
{
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
"version": "2.1.0",
"runs": [
{
"tool": {
"driver": {
"name": "vulkro-live",
"informationUri": "https://vulkro.com",
"rules": [
{
"id": "vulkro-live/verify/malicious",
"shortDescription": { "text": "malicious" }
}
]
}
},
"results": [
{
"level": "error",
"ruleId": "vulkro-live/verify/malicious",
"message": {
"text": "lodahs (npm): flagged malicious by OSV (MAL-2025-25502): Malicious code in lodahs (npm)"
}
}
]
}
]
}

(Trimmed for width; the real output also carries logical locations and the tool version.)

Exit codes

Every command follows the same contract:

CodeMeaning
0Success, nothing flagged
1The check completed and something was flagged
2Error: bad arguments, IO failure, no lock file yet (drift)

Per-command specifics, all stated in each command's --help:

  • verify: 1 when any package is not OK.
  • warden: 1 only when a HIGH or MEDIUM finding is present.
  • inspect, skillscan, cardcheck: 1 for REVIEW or AVOID.
  • foresee: 1 when a predicted name is already registered as a trap.
  • audit: 1 for a flagged server, instruction finding, network hook, config secret, or dangerous setting.
  • memcheck: 1 when a poisoned memory is found.
  • drift: 1 when the manifest moved since the lock.
  • lock and trustdb: 0 or 2 only; they have no findings.

A CI recipe

- name: Agent-surface gate
run: |
vulkro-live verify --manifest package.json --format sarif > verify.sarif
vulkro-live audit --format sarif > audit.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: verify.sarif

Because flagged findings exit 1, the step fails the build without any output parsing.