6For a first scan, follow the6For a first scan, follow the
7[CLI quickstart](https://learn.chatgpt.com/docs/security/cli).7[CLI quickstart](https://learn.chatgpt.com/docs/security/cli).
8 8
9The `@openai/codex-security` package is public. Scans using OpenAI inference9Scans use your local permissions and don't pause for approval. Some
10 require Codex Security access. Scans use your local permissions and don't10 cybersecurity requests and protected findings require
11 pause for approval. Before you start, review [Local scan11 [Trusted Access for Cyber](https://chatgpt.com/cyber)
12 permissions](#local-scan-permissions).12 . See [Local scan permissions](#local-scan-permissions).
13 13
14Run the CLI with `npx @openai/codex-security`. For older installations, check14Run the CLI with `npx @openai/codex-security`. The installed package also
15`--version` and command-specific `--help`. The installed package also provides15provides the `cs` alias.
16the `cs` alias.
17 16
18## Command overview17## Command overview
19 18
133 [--post-scan-prompt-file FILE]132 [--post-scan-prompt-file FILE]
134 [--mode {standard,deep}] [--workers N]133 [--mode {standard,deep}] [--workers N]
135 [--subagents N] [--stop-after-no-new N]134 [--subagents N] [--stop-after-no-new N]
136 [--max-discovery-runs N] [--max-time-hours HOURS]135 [--max-discovery-runs N] [--max-time MINUTES]
137 [--model MODEL]136 [--model MODEL]
138 [--effort EFFORT]137 [--effort EFFORT]
139 [--output-dir DIR]138 [--output-dir DIR]
140 [--archive-existing]139 [--archive-existing]
141 [--plugin-path PATH] [--python PATH]140 [--plugin-path PATH] [--python PATH]
142 [--codex KEY=VALUE] [--fail-on-severity LEVEL]141 [--codex KEY=VALUE] [--fail-on-severity LEVEL]
143 [--patch] [--patch-severity {critical,high,medium,low}]142 [--validate] [--patch] [--patch-severity {critical,high,medium,low}]
144 [--create-pr]143 [--create-pr]
145 [--max-cost USD] [--show-cost] [--dry-run] [--mock]144 [--max-cost USD] [--show-cost] [--dry-run] [--mock]
146 [--workflow-id ID] [--safety-identifier ID]145 [--workflow-id ID] [--safety-identifier ID]
207hashed identifier with API-key authentication. Use 1–64 characters without NUL206hashed identifier with API-key authentication. Use 1–64 characters without NUL
208or personal data such as email addresses.207or personal data such as email addresses.
209 208
210The bundled runtime doesn't yet support this option. It requires a compatible209To forward the identifier, use `CODEX_CLI_PATH` to select a Codex build that
211Codex build selected with `CODEX_CLI_PATH` and a plugin that forwards the210supports this option and a plugin that passes it to workers. The bundled Codex
212identifier to workers. The SDK validates the identifier format, not runtime211runtime doesn't support it.
213or plugin compatibility; older versions may omit it.
214 212
215### Use OpenRouter or Fireworks213### Use OpenRouter or Fireworks
216 214
293scan to check access. For AWS authentication or access-denied errors, check291scan to check access. For AWS authentication or access-denied errors, check
294your credentials, region, and model permissions.292your credentials, region, and model permissions.
295 293
296#### Bedrock release status294#### Bedrock cost estimates
297 295
298Starting in 0.2.0, `@openai/codex-security` supports cost estimates and `--max-cost` for296The CLI supports cost estimates and `--max-cost` for the Daybreak Blue and
299the Daybreak Blue and Daybreak Red model IDs above. Estimates use AWS Standard297Daybreak Red model IDs above. Estimates use AWS Standard
300commercial in-region prices, including the AWS fee. The cost limit uses298commercial in-region prices, including the AWS fee. The cost limit uses
301`estimatedUsd`, the short-context baseline. Requests already in progress can299`estimatedUsd`, the short-context baseline. Requests already in progress can
302put this estimate above the limit. Long-context pricing can raise the reported300put this estimate above the limit. Long-context pricing can raise the reported
303`estimatedUsdRange` above it. This limit is not a billing cap.301`estimatedUsdRange` above it. This limit is not a billing cap.
304 302
305Check your installed package and bundled Codex versions:
306
307```bash
308npx @openai/codex-security --version
309npx @openai/codex-security info --json
310```
311
312Use `npx @openai/codex-security scan --help` to check the options available
313in your installed version.
314
315### Select the scan target303### Select the scan target
316 304
317Choose one target type for each scan.305Choose one target type for each scan.
364 352
365### Configure deep scans353### Configure deep scans
366 354
367Use these options with `--mode deep` to control worker concurrency and runtime:355Use these options with `--mode deep` to control discovery:
368 356
369| Argument | Description |357| Argument | Description |
370| ------------------------ | -------------------------------------------------------------------------------------- |358| ------------------------ | ----------------------------------------------------------------------------------------------------- |
371| `--workers N` | Limit on concurrent independent standard-scan workers. Defaults to `4`. |359| `--workers N` | Limit on concurrent independent standard-scan workers. Defaults to `4`. |
372| `--subagents N` | Subagents available to each worker. Defaults to `3`. |360| `--subagents N` | Subagents available to each worker. Defaults to `3`. Use `0` to disable them. |
373| `--stop-after-no-new N` | Stop after `N` consecutive completed worker scans find no new issues. Defaults to `4`. |361| `--stop-after-no-new N` | Stop after `N` consecutive completed worker scans find no new issues. Defaults to `4`. |
374| `--max-discovery-runs N` | Limit on total independent standard-scan runs. Defaults to `40`. |362| `--max-discovery-runs N` | Limit on total independent standard-scan runs. Defaults to `40`. |
375| `--max-time-hours HOURS` | Worker execution time limit in hours. Defaults to `96`; accepts fractions. |363| `--max-time MINUTES` | Discovery time limit. Accepts positive fractional minutes. The default and maximum are 5,760 minutes. |
376 364
377`--subagents` accepts zero or a positive integer. `--max-time-hours` accepts a365For example, use two workers, allow up to ten runs, and stop discovery after 90 minutes:
378positive number no greater than `96`. The remaining options require a positive
379integer. These options aren't available for standard scans.
380
381For example, use two workers, allow up to ten runs, and stop worker execution
382after 1.5 hours:
383 366
384```bash367```bash
385npx @openai/codex-security scan . \368npx @openai/codex-security scan . \
388 --subagents 0 \371 --subagents 0 \
389 --stop-after-no-new 3 \372 --stop-after-no-new 3 \
390 --max-discovery-runs 10 \373 --max-discovery-runs 10 \
391 --max-time-hours 1.5374 --max-time 90
392```375```
393 376
394When the time limit expires, the scan stops unfinished workers, keeps completed377When the time limit expires, the scan stops unfinished workers and combines
395scan results, and aggregates them into the final report. Reaching a configured378completed findings in its report. For a standard scan, `--max-time` sets an
396limit with a valid finalized report isn't an execution failure. Review its379advisory investigation time. Reporting can finish later. Custom validation
397follow-up work and coverage notes; see [Exit codes and signals](#exit-codes-and-signals).380and post-scan instructions run outside that allowance.
398 381
399Set persistent defaults in `~/.codex/codex-security/config.toml`, or in382To reuse these limits, save them in a
400`$CODEX_HOME/codex-security/config.toml` when you set `CODEX_HOME`:383[project configuration file](#load-project-configuration):
401 384
402```toml385```yaml
403[deep_scan]386scan:
404workers = 2387 mode: deep
405subagents = 0388 max_time_minutes: 90
406stop_after_no_new = 3389 deep:
407max_discovery_runs = 10390 workers: 2
408max_time_hours = 1.5391 subagents_per_worker: 0
392 stop_after_no_new: 3
393 max_discovery_runs: 10
409```394```
410 395
411Command-line options override these defaults. `scan --workers` controls396Command-line options override the project configuration. Use
412independent standard-scan workers within one deep scan; `bulk-scan --workers`397`scan.deep.stop_after_consecutive_errors` to change how many consecutive worker
413controls concurrent repository scans. Set `stop_after_consecutive_errors` in398errors stop discovery. The default is `3`. For `bulk-scan`, `--workers`
414the legacy TOML file or `scan.deep.stop_after_consecutive_errors` in a project399controls concurrent repository scans.
415file; its default is `3`.
416 400
417### Add security context401### Add security context
418 402
451The follow-up doesn't run after cancellation or when the scan reaches its cost435The follow-up doesn't run after cancellation or when the scan reaches its cost
452limit. When it runs, the follow-up is outside scan cost tracking and `--max-cost`.436limit. When it runs, the follow-up is outside scan cost tracking and `--max-cost`.
453 437
454Use `--validation-prompt-file FILE` to replace final validation with your own438### Validate findings in your environment
455workflow in Standard and diff scans. Source review still runs. Include setup,439
456authorized targets, required evidence, and cleanup. Deep scans reject custom440Use `--validation-prompt-file FILE` to replace the final validation step with
457validation; scans with no candidates skip it.441your own test procedure. Codex reviews the source first and skips validation if
442it finds no candidates. Keep the prompt and test script in a directory you
443control outside the checkout:
444
445```bash
446npx @openai/codex-security scan . \
447 --validation-prompt-file /path/to/security-tests/validation.md
448```
449
450For example, if your local test server is running, put these instructions in
451`validation.md`:
452
453```text
454Run /path/to/security-tests/validate.sh against http://localhost:3000.
455Report which findings reproduce and include the relevant test output.
456```
457
458Use this flag with standard repository, path, diff, or working-tree scans. For
459standard component scans, set `scan.validation_file` in the
460[project configuration](#load-project-configuration). Deep scans reject custom validation.
461
462Add `--validate` to a new scan command for a separate source-only assessment
463of each reported finding. If the scan reports findings, the CLI writes the
464assessments to a report in the scan directory. They don't change the findings
465or severity-policy decision. You can't combine `--validate` with `--dry-run`,
466`--mock`, or a scan cost limit set on the command line or in the project
467configuration.
458 468
459### Set output and policy options469### Set output and policy options
460 470
476| `--dry-run` | Check the repository, target, knowledge base, output directory, and Codex configuration without starting a scan. |486| `--dry-run` | Check the repository, target, knowledge base, output directory, and Codex configuration without starting a scan. |
477| `--headless` | Show plain-text progress instead of the interactive scan dashboard. |487| `--headless` | Show plain-text progress instead of the interactive scan dashboard. |
478| `--verbose` | Print additional lifecycle, authentication, progress, and cost diagnostics to stderr. |488| `--verbose` | Print additional lifecycle, authentication, progress, and cost diagnostics to stderr. |
479| `--json` | Print manifest, findings, coverage, paths, and turn metadata as one JSON document. |489| `--json` | Print the manifest, findings, review exclusions, paths, and turn metadata as one JSON document. |
480| `--format FORMAT` | Print the complete scan result as `toon`, `json`, `yaml`, or `jsonl`. |490| `--format FORMAT` | Print the complete scan result as `toon`, `json`, `yaml`, or `jsonl`. |
481| `--full-output` | Print the complete result using the default structured output format. |491| `--full-output` | Print the complete result using the default structured output format. |
482 492
563Add `--dry-run --verbose` to your scan command to inspect the resolved model573Add `--dry-run --verbose` to your scan command to inspect the resolved model
564and effort before starting a scan.574and effort before starting a scan.
565 575
566To select a different model and reasoning effort without writing TOML, choose a576To choose a model and reasoning effort, select a [Codex model](https://learn.chatgpt.com/docs/models)
567model your credentials can access. If you use ChatGPT sign-in, check [GPT-6.1577available to your account:
568Sol availability](https://learn.chatgpt.com/docs/models#gpt-6.1-sol) before using these examples:
569 578
570```bash579```bash
571npx @openai/codex-security scan . --model gpt-6.1-sol --effort medium580npx @openai/codex-security scan . --model gpt-6.1-sol --effort medium
707 716
708## `codex-security scan-components`717## `codex-security scan-components`
709 718
710Run a separate scan for each component of one repository:719Use `scan-components` to scan services or packages in one repository separately.
720Each run, including a plan-only run, needs a new or empty output directory
721outside the enclosing Git worktree. Set it with `--output-dir` or with
722`output.directory` in the project configuration.
723
724For example, scan two services in parallel:
711 725
712```bash726```bash
713npx @openai/codex-security scan-components . \727npx @openai/codex-security scan-components . \
714 --component apps/api --component apps/web \728 --component apps/api --component apps/web \
715 --workers 4 --output-dir /path/outside/repository/components729 --output-dir /path/outside/repository/manual-components
716```730```
717 731
718Unlike `scan --path`, this command produces a scan per component, then combines732Unlike `scan --path`, this command produces a scan per component, then combines
719and matches the findings. Use `--components-file FILE` for a saved plan. To733and matches the findings. By default, four component scans can run at once.
720propose a split for review before scanning:734Set `--workers N` to change that limit. `--max-cost USD` limits each component
735scan. It excludes automatic planning and cross-component matching.
736
737To have Codex propose a split, save a plan for review before scanning:
721 738
722```bash739```bash
723npx @openai/codex-security scan-components . --auto --plan-only \740npx @openai/codex-security scan-components . --auto --plan-only \
724 --output-dir /path/outside/repository/component-plan741 --output-dir /path/outside/repository/component-plan
725```742```
726 743
727Component scans require `--output-dir` or `output.directory` in the project744Review the component names and paths in `components.json`, then run the saved
728configuration, including plan-only runs. Failed scans or matching failures745plan in a new output directory:
729return `2`; severity-policy violations return `1`. See the [component scan guide](https://github.com/openai/codex-security/blob/main/sdk/typescript/docs/cli.md#scan-project-components) for plan syntax and retries.746
747```bash
748npx @openai/codex-security scan-components . \
749 --components-file /path/outside/repository/component-plan/components.json \
750 --output-dir /path/outside/repository/components
751```
752
753Open `report.md` in the output directory to review the combined findings. If
754a component fails, use the saved retry plan to rerun only the failed components:
755
756```bash
757npx @openai/codex-security scan-components . \
758 --components-file /path/outside/repository/components/retry-components.json \
759 --output-dir /path/outside/repository/retry-results
760```
761
762The retry report covers only the retried components. Keep the original report
763to review findings from components that completed on the first run.
764
765Failed scans or matching failures return `2`. Severity-policy violations return `1`. See the [component scan guide](https://github.com/openai/codex-security/blob/main/sdk/typescript/docs/cli.md#scan-project-components) for plan syntax and retries.
730 766
731## `codex-security bulk-scan`767## `codex-security bulk-scan`
732 768
753Run `npx @openai/codex-security bulk-scan` without arguments to select789Run `npx @openai/codex-security bulk-scan` without arguments to select
754repositories interactively. This flow requires a GitHub CLI sign-in.790repositories interactively. This flow requires a GitHub CLI sign-in.
755 791
756To choose a model and reasoning effort during interactive discovery, use a model792For interactive discovery, select a [Codex model](https://learn.chatgpt.com/docs/models) available
757your credentials can access. See [GPT-6.1 Sol availability with ChatGPT793to your account:
758sign-in](https://learn.chatgpt.com/docs/models#gpt-6.1-sol):
759 794
760```bash795```bash
761npx @openai/codex-security bulk-scan --model gpt-6.1-sol --effort medium796npx @openai/codex-security bulk-scan --model gpt-6.1-sol --effort medium
939## `codex-security export`974## `codex-security export`
940 975
941Export saved findings or a threat model without starting Codex or loading976Export saved findings or a threat model without starting Codex or loading
942credentials. You can export findings as CSV, JSON, or SARIF only from a977credentials. You can export findings as CSV, JSON, SARIF, or a ServiceNow AVIT
943completed, sealed scan. Threat models use Markdown.978CSV only from a completed, sealed scan. Threat models use Markdown.
944 979
945```text980```text
946usage: codex-security export [scan_dir | --scan SCAN_ID]981usage: codex-security export [scan_dir | --scan SCAN_ID]
947 [--artifact {findings,threat-model}]982 [--artifact {findings,threat-model}]
948 [--export-format {csv,json,sarif,md}]983 [--export-format {csv,json,sarif,md,servicenow-avit}]
984 [--avit-template FILE]
949 [--output FILE|-] [--source-root PATH]985 [--output FILE|-] [--source-root PATH]
950 [--python PATH]986 [--python PATH]
951```987```
956these selectors.992these selectors.
957 993
958| Argument | Description |994| Argument | Description |
959| ------------------------------------- | ------------------------------------------------------------------------------------------- |995| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
960| `--artifact {findings,threat-model}` | Select the saved artifact. The default is `findings`. |996| `--artifact {findings,threat-model}` | Select the saved artifact. The default is `findings`. |
961| `--scan SCAN_ID` | Select a saved scan by ID or unique prefix of at least eight characters. |997| `--scan SCAN_ID` | Select a saved scan by ID, unique prefix of at least eight characters, or `latest`. |
962| `--export-format {csv,json,sarif,md}` | Select the format. Findings default to `sarif`; threat models support only `md`. |998| `--export-format FORMAT` | Select `csv`, `json`, `sarif`, `md`, or `servicenow-avit`. Findings default to `sarif`; threat models support only `md`. |
999| `--avit-template FILE` | Supply the CSV template that `servicenow-avit` requires. Only this format accepts it. |
963| `--output FILE\|-` | Write the selected format to a file or stdout. Defaults to a file in the current directory. |1000| `--output FILE\|-` | Write the selected format to a file or stdout. Defaults to a file in the current directory. |
964| `--source-root PATH` | Add source-line fingerprints to SARIF using a repository checkout. |1001| `--source-root PATH` | Add source-line fingerprints to SARIF using a repository checkout. |
965| `--python PATH` | Select the Python interpreter for the bundled exporter. |1002| `--python PATH` | Select the Python interpreter for the bundled exporter. |
969not include local workbench triage state.1006not include local workbench triage state.
970 1007
971Without `--output`, the CLI writes SARIF to `results.sarif`, JSON to1008Without `--output`, the CLI writes SARIF to `results.sarif`, JSON to
972`findings.json`, CSV to `findings.csv`, and Markdown to `threatmodel.md` in the1009`findings.json`, CSV to `findings.csv`, ServiceNow AVIT CSV to
973current working directory.1010`servicenow-avit.csv`, and Markdown to `threatmodel.md` in the current working
1011directory.
974Exports can contain source excerpts and vulnerability details. Pass `--output`1012Exports can contain source excerpts and vulnerability details. Pass `--output`
975with a private path outside the checkout. When running outside the repository,1013with a private path outside the checkout. When running outside the repository,
976also specify a result directory or `--scan`.1014also specify a result directory or `--scan`.
1011 --output /path/outside/repository/exports/findings.csv1049 --output /path/outside/repository/exports/findings.csv
1012```1050```
1013 1051
1052### Export findings for ServiceNow
1053
1054ServiceNow requires the **Ethical Hacker** role (`sn_vul.app_pen_tester`).
1055Open **All** > **Manual AVIT Ingestion** > **Upload File UI** and download the
1056CSV template. Keep the original headers and exactly one data row.
1057Use the exact ServiceNow application name. Fill in the purpose, sensitive data
1058types, compliance programs, technology stack, application team, and URLs to test.
1059Set **Requested by**, **Assigned to**, and **Assignment group**. Leave the
1060finding fields blank. Save the template as `app.csv` in a private directory
1061outside the scanned repository. Reuse it for scans of the same application.
1062
1063From the scanned repository, export the latest findings with that template.
1064Keep the output in the private directory as well:
1065
1066```bash
1067npx @openai/codex-security export --scan latest \
1068 --export-format servicenow-avit \
1069 --avit-template /path/outside/repository/exports/app.csv \
1070 --output /path/outside/repository/exports/findings-avit.csv
1071```
1072
1073The CLI writes one row per finding and fills **Steps to reproduce** from the
1074recorded attack path when available. Review those steps and fill in any blanks
1075in the exported CSV. Return to **Upload File UI**, select **Import File**,
1076upload the CSV, and select **Submit**. Each upload creates a new penetration
1077test form for the application.
1078See the [ServiceNow upload instructions](https://www.servicenow.com/docs/r/security-management/application-vulnerability-response/ingest-vulnerabilities-manually-avr.html).
1079
1014### Export a saved threat model1080### Export a saved threat model
1015 1081
1016Starting in version 0.2.0, scans save their threat models for reuse without1082Export the latest completed scan's saved threat model to stdout without making
1017another model call. Export the latest completed scan's model to stdout:1083another model call:
1018 1084
1019```bash1085```bash
1020npx @openai/codex-security export --artifact threat-model --output -1086npx @openai/codex-security export --artifact threat-model --output -
1223 1289
1224### Patch findings after a scan1290### Patch findings after a scan
1225 1291
1226Use `scan --patch` to fix findings after a complete scan. This requires1292Use `scan --patch` to fix findings after a completed scan. The default severity
1227`@openai/codex-security` 0.1.15 or later. The default severity threshold is1293threshold is `low`. This command selects high and critical findings:
1228`low`. This command selects high and critical findings:
1229 1294
1230```bash1295```bash
1231npx @openai/codex-security scan . --patch --patch-severity high --json1296npx @openai/codex-security scan . --patch --patch-severity high --json
1332`--format`, or `--full-output` to send structured scan results to stdout.1397`--format`, or `--full-output` to send structured scan results to stdout.
1333 1398
1334Interactive terminals show a live dashboard with the current scan phase,1399Interactive terminals show a live dashboard with the current scan phase,
1335reviewed files, activity, token usage, and estimated cost. CI and redirected1400file inventory, activity, token usage, and estimated cost. CI and redirected
1336output use plain-text progress. Add `--headless` to use plain-text progress in1401output use plain-text progress. Add `--headless` to use plain-text progress in
1337an interactive terminal:1402an interactive terminal:
1338 1403
1362### Completion summary1427### Completion summary
1363 1428
1364A completed scan writes its open repository finding count, severity breakdown,1429A completed scan writes its open repository finding count, severity breakdown,
1365elapsed time, report path, and result directory to stderr. It includes token1430elapsed time, report path, and result directory to stderr. It also reports token
1366usage when available and estimated cost when you set `--show-cost` or1431usage when available and estimated cost when you set `--show-cost` or
1367`--max-cost`:1432`--max-cost`. For example:
1368 1433
1369```text1434```text
1370 REPORT /path/to/scan/report.md1435 REPORT /path/to/scan/report.md
1371 1436
1372 FINDINGS 4 (3 confirmed this scan; 1 previously found; 1 critical, 2 high, 1 informational)1437 FINDINGS 4 (3 confirmed this scan; 1 previously found; 1 critical, 2 high, 1 informational)
1438 SCOPE repository: .
1373 ELAPSED 1s1439 ELAPSED 1s
1374 TOKENS 1,250 input, 200 cached, 30 output
1375 RESULTS /path/to/scan1440 RESULTS /path/to/scan
1376```1441```
1377 1442
1381 1446
1382### JSON output1447### JSON output
1383 1448
1384`scan --json` writes one complete JSON document to stdout. Its top-level shape1449`scan --json` writes one JSON document to stdout. Use `manifest.scan` for
1385is:1450status and scope and `findings` for the current scan's findings. When available,
1386 1451`repositoryFindings` includes those findings and earlier open findings.
1387```text1452`review.excludedPaths` lists path patterns the scan recorded as excluded from
1388manifest1453review. `scanDir`, `reportPath`, and `artifactsDir` point to the saved results.
1389repositoryFindings
1390findings
1391coverage
1392threatModel
1393threatModelPath
1394scanDir
1395threadId
1396reportPath
1397artifactsDir
1398sarifPath
1399cost
1400turn
1401 id
1402 status
1403 durationMs
1404 finalResponse
1405 usage
1406```
1407 1454
1408`threatModel` contains the saved model as structured data or Markdown.1455`threatModel` contains the saved model as structured data or Markdown.
1409`threatModelPath` points to its saved document. Either can be `null`; the model1456`threatModelPath` points to its saved document. Either can be `null`; the model
1440<scan-directory>/1487<scan-directory>/
1441├── scan-manifest.json1488├── scan-manifest.json
1442├── findings.json1489├── findings.json
1443├── coverage.json
1444├── report.md1490├── report.md
1445├── threatmodel.md # when available1491├── threatmodel.md # when available
1446├── artifacts/1492├── artifacts/
1454| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------- |1500| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
1455| `scan-manifest.json` | Scan identity, status, target, scope, producer, and sealed artifact records. |1501| `scan-manifest.json` | Scan identity, status, target, scope, producer, and sealed artifact records. |
1456| `findings.json` | Finding identifiers, severity, confidence, taxonomy, locations, evidence, validation, data flow, reachability, and remediation. |1502| `findings.json` | Finding identifiers, severity, confidence, taxonomy, locations, evidence, validation, data flow, reachability, and remediation. |
1457| `coverage.json` | Recorded review scope, exclusions, deferred work, and open questions. |
1458| `report.md` | Readable scan report. |1503| `report.md` | Readable scan report. |
1459| `threatmodel.md` | Saved threat model, when available. |1504| `threatmodel.md` | Saved threat model, when available. |
1460| `artifacts/` | Supporting scan artifacts. |1505| `artifacts/` | Supporting scan artifacts. |
1462 1507
1463### Completion and review coverage1508### Completion and review coverage
1464 1509
1465A completed scan means the requested workflow finished normally. It doesn't prove that1510Read `scan.status` in `scan-manifest.json` to check whether the scan
1466every file or attack path was reviewed. Read `coverage.json`, `report.md`, and1511completed. Read `scan.scope` for the configured scope and
1467the recorded scope in `scan-manifest.json` for exclusions, deferred work, and1512`scan.review.excludedPaths` for exclusions the scan recorded during review.
1468open questions. Retained input inventories describe scan inputs but don't prove1513Scan comparisons also use those exclusions. A completed scan can still leave
1469that every listed file was reviewed.1514some files in scope unreviewed.
1470
1471Current reports omit `coverage.completeness`. Older reports may contain
1472`complete`, `partial`, or `unknown`; those legacy values no longer determine
1473the command's status or exit code. Use `manifest.scan.status` and the
1474[exit code](#exit-codes-and-signals) to distinguish execution failures from
1475findings-policy violations.
1476 1515
1477For unresolved work, inspect the available evidence with `scans show SCAN_ID`1516For unresolved work, inspect the available evidence with `scans show SCAN_ID`
1478and `scans logs SCAN_ID`. An eligible interrupted Deep Scan can continue with1517and `scans logs SCAN_ID`. An eligible interrupted Deep Scan can continue with