Source-code analysis diagrams
STIG diagrams are generated from analyzer JSON files. They are views over analyzer results, not independent analysis runs.
Ownership
STIG defines diagram semantics and rendering. The consumer project owns the analysis configuration and must decide which generated diagrams are relevant evidence for a review.
Analyzer JSON To Vista
Each analyzer JSON file is loaded into one independent Vista graph model. The next analyzer JSON creates a new Vista. STIG does not merge all analyzer JSON files into one global graph. Use Check and align analysis evidence to compare every sink through the LLVM, analyzer, and report stages and to assess activity-local knownGaps.
For one sink ASIL, STIG produces at most two analyzer JSON files: one data-and-control-flow artifact and one cascading-failure artifact. Each contains every configured sink in that ASIL scope plus one shared ICFG. One-sink diagrams are projections of the same aggregate artifact; STIG does not launch or store a dedicated analyzer result for each sink.
Inside one native invocation, IDE-XTaint runs over deterministic source and sink batches. Positive physical-sink results retain isolated evidence components with their solver/source/sink provenance. Kotlin selects components for a one-sink view or takes their provenance-preserving union for an all-sinks view; it does not merge separate analyzer JSON files into a global safety result.
Before a Vista is built, STIG validates the analyzer JSON. For schema v7 this includes exact source/sink Cartesian coverage, OR aggregation of PhASAR verdicts, run-global canonical facts and (instruction, fact) states, ordered payloads, RLE successor lists, delta-coded positional topology shapes, sparse labelled-template overrides, component ownership/provenance, source roots, sink terminals, compaction counters, and ICFG entry-point reachability. Optional Z3 paths are metadata; they are validated for internal consistency but do not change the structural data-flow verdict. A failure here is a toolchain consistency problem, not a diagram rendering preference. Maintainer details are documented in Analyzer output validation.
After Vista transformation, STIG also validates the generated diagram/report artifacts at the output layer. The diagram generator reports enabled cells that cannot render, empty analyzer outputs, missing source lines, missing source browse URLs, and element-ASIL propagation mismatches as postconditions. The appendix task then checks that Markdown references to flattened SVG, Cytoscape, Sigma, source-browser, and pruning sidecar assets resolve, and it renders an explicit "no nodes" note instead of embedding a blank diagram. Those output checks catch publication and rendering defects; they do not replace the analyzer JSON semantic validator.
Edge Sources
Data-flow and control-flow diagrams intentionally use different analyzer edge sources:
Data-flow diagrams use the component-selected topology under
dataFlowEvidence; archived v5/v6 artifacts usesinks[].dataFlowDAG.Control-flow and ICFG diagrams use analyzer ICFG edges from
controlFlowGraph.edges.
The diagram transform filters by edge kind before rendering. A data-flow diagram does not use ICFG edges, and a control-flow diagram does not use data-flow DAG edges.
Analysis Scope
Data and control-flow analysis shows source-to-sink flow for sources at the analyzed safety sink's ASIL or higher. Lower-ASIL sources are excluded from this view because they are treated as faulty interference, not as normal evidence for the sink. For example, QM sources do not contribute to the data/control-flow complexity shown for an ASIL B sink. If such a source is upgraded to ASIL B, it becomes part of the data/control-flow analysis scope and the reported complexity can grow.
Cascading-failure analysis is the complementary view. It intentionally asks whether lower-ASIL sources, such as QM inputs, can taint a safety-related sink. In that section, source-to-sink data flow is unexpected interference and is reported as a cascading-fault problem.
Data-flow DAG semantics
The schema-v7 analyzer evidence is one run-global immutable store. Facts, exact stable instruction/fact states, and ordered source-to-sink payloads are interned across all physical sinks and solver executions. Exact outgoing position lists are stored once as consecutive-index runs. A delta-coded positional shape stores adjacency, roots, terminals, and one base payload layout; each labelled template stores only sparse payload differences from that base. Each positive component references one template and retains its own solver, sink, leak-fact, and exact source-call-to-generated-state provenance. Equal shapes or complete templates may be shared, but equal individual payloads, vertices, or edges from different component templates are never unioned. Archived schema-v6 results keep equivalent fact-aware structures per sink, while schema-v5 results use flattened segments[] and edges[].
For a one-sink view, STIG copies only the global tables reachable from that sink's components, remaps all indices, and rebases a retained template when the original shape base belongs to another sink. Expansion before and after projection is exact; this storage optimization cannot add or remove a data-flow path.
The maintainer-facing contract and correction plan are documented in Data-flow DAG semantics.
The shared controlFlowGraph.nodes[] array is the module-scoped instruction catalog. V6/v7 payload order is semantic, but the fact is part of every state: collapsing (instruction, fact) to printed IR text or an instruction-only arrow loses evidence. V5 segments[].instructionIds[] remains membership metadata and does not prove adjacent IR-to-IR edges.
Important consequences:
one IR instruction can occur in many states under different canonical facts;
two components can share an interned payload without sharing a graph vertex or edge;
data-flow diagrams use component-local edges for
pathFeasibility = no-check,feasible-only, andboth;Z3 feasibility is expensive, disabled by default, and remains optional path metadata. It must not select, prune, or synthesize data-flow diagram edges;
data-flow diagrams expose
summarizedanddetailed_per_segmentviews. A detailed IR view may expose state membership, but it must not replace fact-aware states with invented instruction-only propagation edges.
Facts and segments are different concepts. A fact identifies the tainted value/access path; a state combines that fact with one stable instruction; a payload orders states; and a segment instance places one payload in one solver-produced component. Display labels and local PhASAR ESG IDs are not identities across solver executions.
ASIL Visual Semantics
Data-flow diagrams distinguish endpoint classification from propagated taint:
fill color is the nominal ASIL of a diagram-scoped source or sink endpoint. Internal IR instructions and segments without a selected endpoint use a neutral fill;
border color is the weakest ASIL propagated to that IR instruction or segment through the data-flow DAG. The border uses the darker stroke color of that ASIL family, so propagated QM is green, ASIL B is amber, ASIL C is orange, and ASIL D is red;
thick border marks a cascading-failure boundary, where a lower propagated ASIL reaches a higher nominal sink ASIL.
For example, an ASIL B sink reached by QM data is rendered with ASIL B fill, QM border, and a thick border. Tooltips show both values explicitly as nominal ASIL and propagated ASIL. The same rule is used for segment diagrams: a segment gets nominal fill only when it contains a source/sink selected for that generated diagram, and its border shows the weakest propagated ASIL among its members. Unrelated endpoint-looking calls inside the same segment do not color or mark a one-sink diagram.
The source/sink status tables use the same palette as compact ASIL chips. A non-tainted endpoint chip uses its nominal ASIL for both fill and border. In cascading-failure tables, a tainted sink chip keeps the sink's nominal ASIL fill and uses the propagated lower-ASIL border, so an ASIL B sink tainted by QM data appears as an ASIL B chip with a QM-green border.
Z3 Path Feasibility
Z3 feasibility is a data-flow path refinement. It checks whether the branch conditions along a reconstructed data-flow path are satisfiable, so it uses control-flow constraints to decide whether a structurally reported data-flow path is executable by some runtime input.
Schema-v7 Z3 paths are associated with one solver execution and use ordered sinks[].feasibleFacts[].paths[].instructionIds[], from a configured source instruction to the selected physical sink. Archived schema v5 uses ordered segmentIds[]. Z3 does not select or prune component edges, does not cancel PhASAR's structural verdict, and does not authorize dropping facts from v7 states.
Endpoint Pruning And Summaries
Data-flow diagrams are source-to-sink evidence diagrams by default. STIG keeps only paths from configured source endpoints to the configured sink endpoints covered by the diagram, and prunes branches that never reach those sinks.
For component-backed data-flow results, STIG first selects the components belonging to the requested physical/logical sink projection. Within each component it keeps segments reachable from a selected source root that can reach the sink terminal. It never adds an edge between components, even when their immutable payloads are equal. The pruned segment/sink list is emitted as machine-readable sidecar data next to Cytoscape/Sigma graphs and rendered in the report.
A root segment has one or more exact source-generation boundaries. Several physical calls of the same configured source may enter the same (instruction, fact) state, in which case PhASAR reconstructs one shared root and STIG retains every distinct incoming source-call boundary. These boundaries are references to the shared root state; STIG does not duplicate the root or discard all but one source call.
Control-flow and ICFG diagrams still use endpoint-to-endpoint contraction over the analyzer ICFG, because those diagrams answer an execution-order question rather than a taint-evidence question.
Summarized diagrams contract non-endpoint chains:
data-flow summaries contract source-to-sink reachability over isolated analyzer components;
control-flow and ICFG summaries contract analyzer
CONTROL_FLOWICFG paths;for any source
Sand sinkK, the data-flow summary emitsS -> Kwhen a segment containingScan reach a segment containingK;when one source has paths to several sinks, each relation is rendered, even if the paths share a prefix.
For example:
is summarized for data-flow as:
This pruning is controlled by the P7 task input pruneDataFlowToSourceSinkPaths, which defaults to true.
Reached, Unreached, And Called Sinks
The report distinguishes taint reachability from call reachability:
a sink can be tainted/reached: at least one covering solver reports it reached;
sink.leakedis the OR of those PhASAR verdicts and has at least one matching evidence component when graph emission is enabled;a sink can be unreached but called: the ICFG contains a configured sink call, but no configured source segment reaches it in data flow;
a sink can be unreached and not called: the analyzer emits a negative configured-sink verdict with no ICFG node, no facts, states, payloads, components, or feasible paths.
Both negative cases are valid analyzer output. The critical error is a contradiction, for example sink.leaked = true without component evidence, a component rooted outside its solver's source batch, a Z3 feasible path outside its solver/source/sink scope, or a positive leak whose configured endpoints are missing from the control-flow graph.
Source Browser Assets
The optional Monaco source pane uses a shared activity-level source browser rather than one repeated source bundle per diagram. Configure its complete lifecycle with one enum:
The modes are:
Mode | Local HTML | Pages publication |
|---|---|---|
| No source-browser content. This is the factory default. | No source-browser content. |
| Generated and usable. | Omitted. |
| Generated and usable. | Included when every source-browser asset satisfies the configured publication limit. |
For each activity, stigGenerateDiagramAppendix writes one <activity>--source-browser-manifest.json and one deterministic gzip <activity>--source-browser-source--<name>--<hash>.txt.gz shard per unique selected source file. The manifest contains file metadata and hashes, not another copy of diagram topology. Node-to-source mappings already belong to the SVG, Cytoscape, or Sigma payload being viewed. The browser fetches and decompresses a source shard only when that file is opened. This removes the former per-diagram source-index repetition that could turn a small activity into hundreds of MiB or more of redundant report data.
The source files follow the same include, exclude, generated-source, and element-directory selection recorded by function_metrics.json. GENERATE marks the manifest and all its shards as local-only in the generated HTML inventory; stigPublishHtml omits those exact files and removes the source-browser query parameter from published viewer links. Use GENERATE_AND_PUBLISH only when the selected source may be hosted on the configured Pages site.
Published Artifact Size Limit
diagramOutputs.maxArtifactSizeMiB limits each diagram publication copy and each source-browser asset requested for Pages publication independently. It does not limit native analysis.json or P7 analysis output: STIG always generates and retains the complete SVG, raw Cytoscape .cyjson, Sigma, and pruning artifacts under the task's build/stig/stigAnalysisP7GenerateDiagrams/diagrams directory so metrics, postconditions, and local inspection see the full result. The setting cascades from project defaults through the element's group to the element itself. For example, a group-wide hosted-Pages limit is:
An element may override the inherited value with its own diagramOutputs block. The value is expressed in MiB (1 MiB = 1,048,576 bytes); leaving it unset keeps artifact sizes unlimited.
For Cytoscape, stigGenerateDiagramAppendix writes a lossless .cyjson.gz report copy under its declared docsOutputDir output. That gzip file, rather than the raw P7 .cyjson, is copied into hosted Pages, linked from the generated Markdown, and measured against maxArtifactSizeMiB. The viewer decompresses it in the browser before JSON parsing. Source-browser shards are also measured as stored gzip files. SVG, Sigma, pruning, and the small source-browser manifest are measured in their stored formats.
When a configured SVG, compressed Cytoscape, Sigma, or pruning publication asset exceeds the limit, STIG omits that one copy from the report and emits a HIGH problem containing its exact path, stored byte size, MiB size, and configured limit. The original P7 artifact remains in build/. STIG does not enable or synthesize another format; an independently enabled smaller format, such as the summarized SVG, remains available. Generated-reference postconditions treat this explicit publication omission as intentional, so hosted Pages contains neither the oversized file nor a broken link to it.
Source-browser content has a stricter completeness rule. In GENERATE_AND_PUBLISH, if any manifest or compressed source shard exceeds the limit, STIG emits the same exact-size HIGH problem but retains the complete browser in local HTML and marks the activity's whole source-browser group local-only. It never publishes a manifest whose source shards are missing. GENERATE is already local-only, so a Pages publication limit does not delete or truncate its local source.
The consumer build must still provide enough Gradle heap and local disk for the complete analyzer model and generated artifact. Configure that heap through the consumer's org.gradle.jvmargs in gradle.properties; the publication limit is not a generation-time memory or disk limit and never authorizes partial safety evidence. Gzip reduces Pages storage and transfer size, but the browser still needs memory for the decompressed JSON and Cytoscape's parsed graph.
Which Diagram To Use
Use the summarized all-sinks diagram for an overview. It remains enabled when enableDetailedDiagramsForAllSinks = false; that setting disables only detailed all-sinks cells. Use one-sink diagrams for investigation and review; they are exact projections from the same aggregate analyzer JSON.
Use detailed-per-segment diagrams to inspect component-local evidence and its component/solver provenance. Use detailed IR views for code context and exact state membership, not for representative instruction-only arrows. Use summarized diagrams for contracted source-to-sink data-flow relations or contracted control-flow relations, depending on diagram type.
Viewer Interaction
Standalone SVG, Cytoscape, and Sigma viewers show diagram metadata as compact chips: analysis kind, flow kind, grouping, and viewer format. The remaining title text is the sink or diagram name.
SVG viewers keep ordinary mouse-wheel input for page scrolling when they are embedded in the generated HTML report. Use Ctrl/Meta-wheel over the SVG to zoom the diagram itself.
In detailed per-IR Cytoscape data-flow views, double-clicking an instruction focuses the instruction, the analyzer segments that contain it, and the incoming/outgoing neighboring segment context. The viewer draws temporary dotted membership links from the instruction to its segment nodes so the relationship is visible. The solid data-flow evidence is still the segment-to-segment DAG edge set; the temporary membership links are navigation aid, not analyzer data-flow edges.
When a source browser is enabled, selecting an instruction or segment opens its selected source file and line. Monaco loads that file's gzip shard lazily; opening one line does not download or parse every source file in the activity.