explain --json command returns a structured trace of command analysis. This page defines the JSON shape for scripts and other tools. It also explains what a trace can reveal before you share it.
See CLI commands for flags and exit behavior. See Troubleshooting for help with an unexpected block.
ExplainResult
The top-level object returned byexplain --json.
The result builds
effectiveLevel, selectedPreset, effectiveCapabilities, and destructiveCommandRuleOverrides once and includes them in every return path. They are present even when you explain an empty command. safetyPresetScope joins them on the same path, but only when a project .cc-safety-net/policy.json was read.
Human output renders the preset in the CONFIG section as , where the scope is user policy, project policy, or built-in default. Without a project policy file the line is with no parenthetical.
effectiveCapabilities
effectiveCapabilities is a record keyed by fail_closed, paranoid_rm, and paranoid_interpreters. Each value contains:
See Modes for what each capability changes.
ruleActivation
ruleActivation is present only when the relevant rule declares an activation capability. The relevant rule is either the matched rule or a mode-gated candidate. A mode-gated candidate is a rule that would match if its required level or capability were active.
Human output renders this as one line: .
ExplainTrace
The trace is passive: recording it never changes a decision, and ordinary guard evaluation never builds one. It exists only for
explain.
Bounds. The recorder keeps at most 512 events, 2,048 characters per text value, 128 items per list, 128 properties per object, and 16 levels of nesting. It discards events beyond the cap and deep-freezes each recorded value. ExplainTrace exposes only steps and segments.
TraceStep variants
Use type to select the variant before you read its other fields.
Human output renders
temp-root-relaxation as a numbered Temp-root relaxation step showing Git cwd: and Result: Allowed git discard in a temp-root repository. See Temp-root relaxation for the conditions behind it, and Working-directory tracking for what makes a cd record a cwd-change step.
recurse reasons
recurse.reason has one of eight values: shell-wrapper, interpreter, busybox, shell-eval, shell-trap, shell-stdin, shell-heredoc, or heredoc-file.
heredoc-file is recorded when a command runs a script file whose content the analysis already knows. The content is a quoted heredoc body written to that path earlier in the same command through cat > or tee. The analyzer then treats the stored body as the script. See Heredoc analysis.
transparent-wrapper steps
transparent-wrapper is a segment-scoped step recorded when the analyzer looks through a command registered with rule wrapper add. It emits one step for the primary child and one for each alternative. Each step carries:
The step is recorded immediately before recursing into those tokens, so it always precedes the analysis of the wrapped command. Human output renders it as a numbered
Transparent wrapper step showing Wrapper: and Tokens:.
Manage wrappers with the rule wrapper add, rule wrapper remove, and rule wrapper list commands. See rule wrapper.
Trace order
A typical trace flows fromparse → per-segment env-strip / leading-tokens-stripped → detection (shell-wrapper / interpreter / busybox / transparent-wrapper) → rule-check or custom-rules-check → a decision. Recursion appears as recurse steps with increasing depth, except busybox dispatch, which records a recurse step but does not consume recursion depth, so a chain of busybox wrappers repeats the same depth value. When you only need the verdict, read result (plus reason, segment, and ruleId) at the top level instead of walking the trace.
Three protections short-circuit before the evaluator runs: policy-file protection, Git-metadata protection, and secret protection. When one of those blocks a command, the trace contains a single synthetic rule-check step and no parse step, with ruleId set to policy-protection, git-metadata-protection, or the id of the matched secret rule. Tooling that assumes every trace opens with a parse step needs to handle this case.
Before you share a trace
For example, explaining a command that contains a--token=… assignment redacts the token, but a path like /srv/acme-prod/customer-dump.sql in the same command is returned in full, along with any hostname, IP address, or account name in the command text.
You can include explain output in a vulnerability report. Redaction is a best-effort control, not a guarantee. A redaction bypass is a reportable vulnerability. Review the complete output before you paste it.
Related pages
- CLI commands documents
explainflags, examples, and exit behavior. - Audit log lists the redaction patterns and applies the same bound to logged records.
- Analysis engine defines the behavior behind each trace step.
- Troubleshooting explains how to use
explainfor an unexpected block.