Skip to main content

JSON Output (--json)

Machine-readable structured diagnostics for tooling integration.

JSON output provides a structured format for verification results, designed for CI/CD pipelines, IDE integrations, and programmatic processing. The output follows a versioned schema (currently version 2) that includes detailed source locations, code snippets, fix hints, and optional counterexamples. Use it with --verify; plain --check --json is not the structured diagnostics path.

When to Use

Use JSON output (--json) when:

  • Building CI/CD pipelines that parse verification results
  • Integrating Sector9 with IDEs or editors
  • Writing tools that process verification failures programmatically
  • Generating reports or dashboards from verification runs

Use other formats for:

  • Human-readable (default) - Interactive terminal debugging
  • --toon - LLM-assisted debugging, AI tools

Basic Usage

Enable JSON output with the --json flag:

sector9 --package core ./core/src --verify --json file.sr9

The JSON is printed to stdout. Redirect to a file for processing:

sector9 --package core ./core/src --verify --json file.sr9 > results.json

Success Output

When verification succeeds, the output contains an empty failures array:

{
"schema_version": "2",
"status": "VALID",
"failures": [],
"warnings": [],
"silicon": {
"exitCode": 0,
"stdout": "Silicon finished verification successfully in ?s.\n",
"stderr": ""
}
}

The status field is "VALID" and the command exits with code 0.

Failure Output

When verification fails, the output includes detailed failure entries:

{
"schema_version": "2",
"status": "INVALID",
"failures": [
{
"failure_id": "d017ca6529e6b16a1b529fbc00c46f8c",
"failure_kind": "verification",
"obligation_kind": "postcondition",
"msg": "Postcondition of increment might not hold.",
"message": "Postcondition of increment might not hold.",
"obligation": "Postcondition might not hold",
"method": "increment",
"label": null,
"motoko_span": {
"file": "counter.sr9",
"line": 8,
"col": 4,
"endLine": 8,
"endCol": 28
},
"viper_span": {
"file": "counter.vpr",
"line": 146,
"col": 19,
"endLine": 146,
"endCol": 35
},
"motoko_snippet": " ensures result == x + 1;",
"viper_snippet": " 145 | ensures $Res == x + 1\n> 146 | {...}",
"fix_hints": [
"Strengthen the implementation or weaken the ensures."
],
"counterexample": null,
"models": []
}
],
"warnings": [],
"silicon": {
"exitCode": 1,
"stdout": "Silicon found 1 error in ?s.\n",
"stderr": ""
}
}

The status field is "INVALID" and the command exits with code 1.

Schema Structure

Top-Level Fields

FieldTypeDescription
schema_versionstringAlways "2" for current Sector9 versions
statusstring"VALID", "INVALID", or "ERROR"
failuresarrayList of verification failure objects
warningsarrayList of warning objects
siliconobjectRaw verifier backend output
errorstring?Error message if diagnostics parsing failed

For frontend translation errors, status is "ERROR" and the silicon object may be absent because Silicon was never invoked. If the Viper backend itself cannot be located, the command exits before JSON verifier diagnostics are produced.

Failure Object Fields

Each failure contains these fields:

FieldTypeDescription
failure_idstringStable MD5 hash for correlating failures across runs
failure_kindstring"verification" or "translation"
obligation_kindstringType: "assert", "postcondition", "precondition", "invariant", etc.
msgstringFull error message
messagestringSame as msg (for compatibility)
obligationstringShort obligation description
methodstring?Function or method name, or null
labelstring?Named assertion label, or null
motoko_spanobject?Source location in the .sr9 file
viper_spanobject?Location in generated Viper code, or null for frontend translation errors
motoko_snippetstring?Source code excerpt from original file
viper_snippetstring?Generated Viper code excerpt
fix_hintsarrayList of suggested fixes
counterexampleobject?Counterexample models (when --counterexample used)
modelsarrayFlattened list of all model bindings
contract_snippetstring?Contract context extracted from the generated Viper failure
source_excerptstring?Best available source or Viper excerpt
footprint_missingobject?Missing reads/modifies clauses
siliconFailureobject?Raw mapped Silicon failure metadata for verification failures

Span Object Fields

Both motoko_span and viper_span use this structure:

FieldTypeDescription
filestringFile path
lineintStart line (1-based)
colintStart column (1-based)
endLineintEnd line
endColintEnd column

The motoko_span may be null if the failure cannot be mapped back to the original source.

Warning Object Fields

FieldTypeDescription
msgstringWarning message
messagestringSame as msg
codestringWarning code (e.g., "M0155")
categorystringWarning category
spanobjectSource location

Obligation Types

The obligation_kind field indicates what verification obligation failed:

ValueMeaning
postconditionensures clause could not be proven
preconditionrequires clause not satisfied at call site
assertassert statement could not be proven
loop invariantLoop invariant not maintained
invariantActor invariant not preserved
insufficient permissionMissing reads or modifies
division by zeroDivisor not proven non-zero

Fix Hints

The fix_hints array contains actionable suggestions:

ObligationTypical Hints
postcondition"Strengthen the implementation or weaken the ensures."
precondition"Guard the call or strengthen the callee requires."
assert"Add proof steps or strengthen preconditions to establish the assertion."
loop invariant"Strengthen the loop invariant or add missing assertions."
insufficient permission"Add missing reads/modifies or ensure permissions are in scope."
division by zero"Add a requires guard (e.g., d != 0) before division/modulo."

Footprint Analysis

When a permission error occurs, footprint_missing identifies the missing clauses:

{
"footprint_missing": {
"reads": ["balance", "owner"],
"modifies": ["balance"]
},
"fix_hints": [
"Add `reads balance, owner;`",
"Add `modifies balance;`"
]
}

Counterexamples

Use --counterexample (or --models) to include concrete failing values:

sector9 --package core ./core/src --verify --json --counterexample file.sr9

The counterexample appears in the failure object:

{
"counterexample": {
"models": [
{
"label": "return",
"bindings": [
{
"name": "x",
"value": "0",
"kind": "local",
"scope": "local"
},
{
"name": "result",
"value": "-1",
"kind": "local",
"scope": "local"
}
]
}
]
}
}

Binding Fields

FieldTypeDescription
namestringVariable or field name
valuestringConcrete value from SMT solver
kindstring"field", "local", or "internal"
scopestringScope context
labelstring?Model label (e.g., "entry", "return")

By default, internal bindings (names starting with $) are filtered out unless they appear in the failure message. Use --show-internal with --counterexample to include them.

Translation Errors

For compilation or type errors (not verification failures), the structure differs:

{
"schema_version": "2",
"status": "ERROR",
"failures": [
{
"failure_kind": "translation",
"obligation_kind": "diagnostic",
"code": "M0057",
"msg": "unbound variable x",
"motoko_span": {
"file": "example.sr9",
"line": 1,
"col": 49,
"endLine": 1,
"endCol": 50
},
"viper_span": null,
"motoko_snippet": "> 1 | persistent actor { public func f() : async Nat { x } }",
"viper_snippet": null,
"source_excerpt": "> 1 | persistent actor { public func f() : async Nat { x } }",
"counterexample": null,
"models": []
}
],
"warnings": []
}

Silicon Backend Output

The silicon object contains raw backend output:

{
"silicon": {
"exitCode": 1,
"stdout": "Silicon 1.1-SNAPSHOT\nSilicon found 1 error in ?s.\n",
"stderr": ""
}
}

Timing information is sanitized (replaced with ?s) to ensure reproducible output across runs.

Flag Interactions

The --json flag interacts with other flags:

FlagEffect
--toonMutually exclusive - last one wins
--no-jsonExplicitly disables JSON output
--counterexampleAdds counterexample models (does not change format)
--modelsAlias for --counterexample
--verify-timeout-msWorks with JSON; timeout status reflected in output

For human-oriented debugging, see Human-Readable Output. For compact agent input, see TOON Format.

CI/CD Integration

For continuous integration, combine timeout and JSON output:

sector9 --package core ./core/src --verify --json --verify-timeout-ms 300000 my_actor.sr9

Parse the JSON output to integrate with test reporters:

#!/bin/bash
OUTPUT=$(sector9 --package core ./core/src --verify --json file.sr9)
STATUS=$(echo "$OUTPUT" | jq -r '.status')

if [ "$STATUS" = "VALID" ]; then
echo "Verification passed"
exit 0
else
echo "Verification failed"
echo "$OUTPUT" | jq '.failures[].msg'
exit 1
fi

Parsing with jq

Extract specific information using jq:

# Get status
sector9 --package core ./core/src --verify --json file.sr9 | jq -r '.status'

# List all failure messages
sector9 --package core ./core/src --verify --json file.sr9 | jq -r '.failures[].msg'

# Get file locations of failures
sector9 --package core ./core/src --verify --json file.sr9 | jq '.failures[] | "\(.motoko_span.file):\(.motoko_span.line)"'

# Count failures
sector9 --package core ./core/src --verify --json file.sr9 | jq '.failures | length'

# Get fix hints
sector9 --package core ./core/src --verify --json file.sr9 | jq -r '.failures[].fix_hints[]'

Comparing Formats

AspectHumanJSONTOON
Target audienceDevelopersToolsLLMs
ColorsYes (TTY)NoNo
Structured dataNoYesYes
Easy to parseNoYesYes
Schema versionedNoYesYes
DefaultYesNoNo
Flag neededNone--json--toon

Examples

Successful Verification

$ sector9 --package core ./core/src --verify --json counter.sr9 | jq '.status'
"VALID"

Failed Postcondition with Counterexample

$ sector9 --package core ./core/src --verify --json --counterexample buggy.sr9 | jq '.failures[0]'
{
"failure_id": "abc123...",
"failure_kind": "verification",
"obligation_kind": "postcondition",
"msg": "Postcondition of withdraw might not hold.",
"method": "withdraw",
"motoko_span": {
"file": "buggy.sr9",
"line": 12,
"col": 4
},
"fix_hints": [
"Strengthen the implementation or weaken the ensures."
],
"counterexample": {
"models": [
{
"label": "return",
"bindings": [
{"name": "amount", "value": "100", "kind": "local"},
{"name": "balance", "value": "50", "kind": "field"}
]
}
]
}
}

Multiple Warnings

$ sector9 --package core ./core/src --verify --json file.sr9 | jq '.warnings[] | "\(.code): \(.msg)"'
"M0145: pattern does not cover value false"
"M0237: The compare argument can be inferred"

Summary

  • Use --json to enable machine-readable JSON output
  • Schema version 2 provides stable, versioned structure
  • Includes detailed source locations, snippets, and fix hints
  • Add --counterexample to include concrete failing values
  • Exit codes match verification status (0 = valid, 1 = invalid)
  • Parse with jq or any JSON library for tooling integration
  • Backend setup errors such as a missing viperserver.jar are emitted before structured verifier JSON.