STIG Help

Generate and publish reports

stigGenerateHtml creates an aggregated Dokka HTML site for the consumer project. The site combines model documentation, generated analysis evidence, source-code analysis results, diagrams, and build provenance.

Run stigImportModel explicitly when Context interfaces or other imported viewpoints need refreshing, then check and report in a separate invocation. Imported Kotlin specifications are ordinary consumer sources. Enabled harness generation is a cacheable report prerequisite: changes to C++, dependent headers, topics, annotations, or configuration regenerate the C++ harness under build/ for P5. Use the central STIG workflows guide for initialization and configuration workflows.

The report is a review artifact. It is not meant to replace the repository's developer notes or project-specific setup documentation.

Use ordinary Markdown headings and tables for document history, notes, and sequential sections. To make a section collapsible, mark its heading with {.stig-box .note}; add .open to start expanded. Marked blockquotes provide bounded or deeply nested boxes, including the dedicated DFA types. The same source renders as styled, collapsible boxes in Dokka and MkDocs. See authored report boxes for the syntax and nesting rules. Convert MkDocs ???/!!! admonitions to these annotations when authoring for both formats. Dokka does not parse MkDocs === tab blocks.

Use ordinary Markdown links relative to the file containing them, for example [Analysis](../analysis/ComponentAnalysis.md) and ![Context diagram](../images/context.svg). Keep these paths suitable for editor previews. STIG's Dokka plugin resolves them from the original source file and maps the destination to its generated page. Documents with the same # Package header contribute to one package page; linked standalone documents without a # Module or # Package header receive separate pages.

The aggregate root page follows the same rules. In docs/dokka-root.md, link to a module's source document, for example [Work products](../items/example/src/main/kotlin/module.md). The report preserves the label and links to that module's index.html; keep the source-relative Markdown path in the authored file.

A directory link such as [Analysis](../analysis/) works when the Markdown files directly in that directory identify one module or package. Otherwise, link to a specific file. File links may include explicit section anchors, such as [Details](../analysis/ComponentAnalysis.md#details) with <a id="details"></a> in the target document. Qualified Dokka symbol references remain available for model declarations.

Referenced images are tracked as Gradle inputs. SVGs retain their module and source path under images/authored/<owner-module>/<source-relative-path>, so two modules can use the same filename. PNGs, including PNGs embedded inside authored SVGs, are stored once per distinct file content in images/authored/_shared/. Published SVGs reference those shared files; the browser reassembles self-contained SVGs for inline images, viewers, and viewer downloads. Authored source images are unchanged. Partial Dokka modules carry canonical links and do not copy those assets. Embedded images from another module are included in standalone previews too. A hyperlink resolves to its target; it does not copy another module's output tree. A standalone module report also includes the authored documentation pages reached through links to other modules; those pages contain the referenced Markdown, while the aggregate report links to the full module and package pages. Kotlin references in those imported pages retain their labels in a standalone preview because the other module's declarations are outside that preview. The owning module and aggregate reports resolve those references to their declarations.

HTML tasks generate their intermediate Markdown in Dokka format. The markdownFormat setting applies to direct stigGenerateMarkdown exports; choosing MkDocs there does not change the HTML pipeline's format.

Ask $stig:project

Use $stig:project to generate the complete HTML report for this project, explain any failed gate at its producing layer, and give me the final local URL. Do not publish or change model/configuration source unless I explicitly ask.

Choose the workflow

Run these commands from a consumer project that applies STIG, such as stig-project; do not run them from the STIG tool-source build. The explicit root task path (:stigGenerateHtml) always means the complete aggregated report.

1. Work Locally With IntelliJ IDEA

IDEA already provides a local web server. STIG logs its localhost:63342 report link, so no separate STIG server is needed. IDEA must be running for that link to work.

Generate The Current Report Once

Build the current checkout, validate the report, open the logged IDEA link, and refresh the browser when needed.

Direct Gradle:

./gradlew :stigGenerateHtml

Bazel launcher:

bazel run @model_repository//models/stig-project:stig -- :stigGenerateHtml

Edit And Rebuild Continuously

Gradle builds once, watches the pipeline's declared inputs, and rebuilds after changes made in IDEA. Refresh the browser after a successful rebuild. Stop watching with Ctrl+C.

Direct Gradle:

./gradlew :stigGenerateHtml --continuous

Bazel launcher:

bazel run @model_repository//models/stig-project:stig -- :stigGenerateHtml --continuous

--continuous (short: -t) is Gradle's standard watch/rebuild option. It is not a STIG option and does not reload the browser automatically.

2. Work Locally Without IntelliJ IDEA

Add --serve when IDEA's web server is unavailable. STIG starts or reuses a background JDK server and verifies that it serves the generated index.html before stigGenerateHtml finishes.

Generate And Serve Once

This is a one-time build. The server remains available, but source changes do not rebuild the report.

Direct Gradle:

./gradlew :stigGenerateHtml --serve

Bazel launcher:

bazel run @model_repository//models/stig-project:stig -- :stigGenerateHtml --serve

Edit, Rebuild, And Serve Continuously

This command builds once and then keeps Gradle watching for changes. The background server immediately exposes each successful rebuild; refresh the browser to display it. Stop rebuilding with Ctrl+C.

Direct Gradle:

./gradlew :stigGenerateHtml --serve --continuous

Bazel launcher:

bazel run @model_repository//models/stig-project:stig -- :stigGenerateHtml --serve --continuous

The server deliberately remains available with the last successful report after Ctrl+C. Stop it explicitly when it is no longer needed:

Direct Gradle:

./gradlew :stigStopHtmlServer

Bazel launcher:

bazel run @model_repository//models/stig-project:stig -- :stigStopHtmlServer

3. Preview And Publish From A Workstation Or CI

Before publishing from a workstation, the one-time --serve command provides a local preview of the exact generated report. It is normally unnecessary in CI because the CI job does not need a local web server.

Direct Gradle:

./gradlew :stigGenerateHtml --serve

Bazel launcher:

bazel run @model_repository//models/stig-project:stig -- :stigGenerateHtml --serve

Publish the complete report with the root-only task. It generates and validates the report before committing and pushing the configured GitHub/GitLab Pages subtree; a separate stigGenerateHtml invocation is not required.

Direct Gradle:

./gradlew :stigPublishHtml

Bazel launcher:

bazel run @model_repository//models/stig-project:stig -- :stigPublishHtml

The consumer project's stigProject { publish { ... } } block selects the remote, Pages branch, owned subtree, and published base URL.

HTML generation and publication allow uncommitted source changes by default, including generated Graphify files. Source-repository cleanliness is an opt-in task input, requireCleanSourceRepositories, whose convention is false. To require clean configured Git worktrees both before generation and immediately before publication, configure both checks in the root build.gradle.kts:

import com.stigway.gradle.tasks.docs.StigGenerateHtmlPipelineStartTask import com.stigway.gradle.tasks.docs.StigPublishHtmlTask tasks.withType<StigGenerateHtmlPipelineStartTask>().configureEach { requireCleanSourceRepositories.set(true) } tasks.withType<StigPublishHtmlTask>().configureEach { requireCleanSourceRepositories.set(true) }

The strict check includes staged, unstaged, and non-ignored untracked files in each configured Git worktree. A branch being ahead of its remote does not make the worktree dirty. Pipeline timing remains enabled in either mode.

Report Versions And URLs

Consumer report publication uses Gradle's project.version by default, normally set in the consumer's gradle.properties:

version=1.2.3-SNAPSHOT

This value identifies the report in Dokka and controls its publication behavior. The separate stigVersion property selects the STIG plugin version when the consumer has no local STIG checkout.

A snapshot version ends in the exact, case-sensitive suffix -SNAPSHOT, such as 1.2.3-SNAPSHOT. A valid identifier without that suffix, such as 1.2.3 or report-2026.06, is a release. A differently cased suffix such as -snapshot is rejected.

Each stigPublishHtml publication removes previously published snapshots. Publishing a snapshot leaves one current snapshot; publishing a release leaves none. All published releases are preserved by default, with no numerical retention limit for consumer reports. Republishing an existing release identifier is rejected by default. Deliberate replacement and pruning require the explicit publication options described in the Gradle task API.

The paths below are relative to the configured publish.pagesSubdir. For example, with pagesSubdir = "my-project/report", / means /my-project/report/ on the Pages site.

Path within the report subtree

Content

/

The current report, whether it is a snapshot or a release.

/versions/<current-version>/

The current version's entry point, which redirects to /.

/versions/<older-release>/

The preserved HTML report for an earlier release.

The report root is the current-report URL. Publication removes the former /latest/ compatibility redirect; update bookmarks to the report root.

For example, after publishing 1.2.3 and then 1.2.4-SNAPSHOT, / serves the snapshot and /versions/1.2.3/ serves the preserved release. Publishing 1.2.4 next makes that release current at /, keeps 1.2.3 under versions/, and removes the previous snapshot.

The maximumRetainedDocumentationReleases setting in STIG's own source build applies separately to its Writerside/Dokka documentation website; consumer report publication does not apply that limit.

Fresh Output Inventory And Size Diagnostics

Every root or module-specific stigGenerateHtml replaces its selected Dokka output directory before rendering, then validates the site and writes an exact SHA-256 inventory under build/stig/html-output-manifest/. It does not leave an old unreferenced file in the new report merely because that file existed in an earlier build. At the end of generation, the task logs the generated file count and total size, followed by every file at least 10 MiB, sorted largest first and reported in MiB.

stigPublishHtml validates that generated inventory again immediately before publication. It copies only the exact inventory entries marked publishable; it does not use an open-ended directory wildcard. Local-only source-browser assets are therefore excluded even if they exist in the local HTML tree. The task reports the total file count and size of the prepared published subtree and lists its files at least 10 MiB in largest-first order.

Source-browser generation and publication are controlled by diagramOutputs.sourceBrowser. See Source-code analysis diagrams for the NONE, GENERATE, and GENERATE_AND_PUBLISH modes and the lazy gzip shard format.

Pages Subtree And History

Publication deletes and recreates only the configured pagesSubdir inside a detached Pages worktree. Paths outside that subtree are taken from the verified current Pages tip and preserved. The resulting complete Pages tree is written as one parentless commit and the remote branch is replaced with an exact force-with-lease, so prior report commits and their large blobs are no longer reachable from the branch. A concurrent change inside the owned subtree fails instead of being overwritten; a concurrent change outside it is incorporated into the new complete tree.

This bounds the reachable history to one commit without assuming that STIG owns other publishers' directories. Retained report releases remain as directories in that commit's tree; the one-commit policy does not limit their count. Remote storage is reclaimed only when the GitHub/GitLab server garbage-collects unreachable objects; a client-side force push cannot promise when that physical cleanup occurs.

Select The Complete Report, A Filtered Aggregate, Or One Module

The workflow commands above use :stigGenerateHtml, which generates the complete project report. To omit one or more STIG modules from a single aggregate invocation, repeat the root task's typed --exclude option with an absolute Gradle project path:

./gradlew :stigGenerateHtml \ --exclude :activities:fusion_activity \ --exclude :activities:other_activity

--exclude accepts one path per occurrence; braces and comma-separated values are not part of its syntax. Each selected module is removed from the aggregate Dokka module set, root complexity overview, generated-asset inputs, and STIG report pipeline dependencies. The option accepts any subproject that applies the STIG plugin, including activities, components, and clusters. A retained module's ordinary Gradle project dependency can still compile an excluded module, but does not restore that module's report pages or STIG report pipeline.

The publication task exposes the same typed option and forwards the selected modules into its dependent aggregate generation:

./gradlew :stigPublishHtml --exclude :activities:fusion_activity

The option belongs to the root aggregate. Use the explicit :stigGenerateHtml path in scripts; a module-scoped stigGenerateHtml preview rejects --exclude. The unqualified root-directory spelling also works, but Gradle still selects and then skips the redundant per-module lifecycle wrappers.

To generate only one module as a standalone preview, replace the root task path with that module's exact project path:

Direct Gradle:

./gradlew :activities:example_activity:stigGenerateHtml

Bazel launcher:

bazel run @model_repository//models/stig-project:stig -- \ :activities:example_activity:stigGenerateHtml

The local preview options apply to a module task, for example:

Direct Gradle:

./gradlew :activities:example_activity:stigGenerateHtml --serve --continuous ./gradlew :activities:example_activity:stigStopHtmlServer

Bazel launcher:

bazel run @model_repository//models/stig-project:stig -- \ :activities:example_activity:stigGenerateHtml --serve --continuous bazel run @model_repository//models/stig-project:stig -- \ :activities:example_activity:stigStopHtmlServer

The activity preview is written under the activity's build/dokka/module-preview/. The aggregate report is written to the consumer root's build/dokka/html/; it is generated from per-module Dokka inputs rather than by copying standalone activity previews.

A root :stigGenerateHtml or :stigPublishHtml prepares the selected compiled model once. Model checks, generated Markdown, and Dokka model pages consume that preparation; individual Dokka workers do not reload the executable model. Dokka still processes each module's Kotlin documentation and renders its pages separately. Unchanged preparation is reused through Gradle's normal input and output checks.

A module preview prepares only that module and its required model context. Gradle may compile transitive project dependencies: if A depends on B and B depends on C, C must compile successfully before A can be loaded. This does not make B or C subjects of A's model checks. Module checks retain their connected context and explicit includes; the explicit root :stigCheckModel evaluates the whole project with one complete model.

A standalone preview keeps references to other modules as text, including their names and ASIL badges. Links within the selected module remain clickable. Generate the aggregate report for navigation between modules; a preview does not require another module's generated HTML or link outside its own report directory.

Preview Server Details

By default, the managed JDK server binds only to 127.0.0.1 and asks the operating system for a free port. A repeated invocation reuses a compatible server. Use --serve-port=<port> to override the configured port for one invocation; it implies --serve. Port 0 remains the recommended collision-free default. An explicitly occupied port fails rather than silently serving on another port.

Runtime state and the server log stay under the selected project's build/stig/html-preview-server/. The matching clean task stops the server before deleting the project's build directory. If the server is stopped while a continuous --serve build is still watching, the next successful rebuild starts it again.

The preview server is configured independently from Pages publishing:

stigProject { generateHtml { enableModelListings = false sourceLinks { view = true edit = false idea = true } jwebserver { enabled = true bindAddress = "127.0.0.1" port = 0 } } }

These are also the defaults when generateHtml {} is omitted. enableModelListings controls only the optional Markdown copies of Kotlin viewpoint sources; regenerating with it disabled also removes previously generated listings. The structured runtime model tree remains in Dokka. sourceLinks controls the icon-only source actions on executable-model boxes and attribute rows. Set the preview server's enabled = false to keep only the file and IDEA preview hints.

Report Root

The report root is titled Project <name> and links to the included elements and their generated viewpoints. Consumer projects can describe the report's scope and link to its main entry points in docs/dokka-root.md. Keep the first line as # Module <name> for Dokka's include parser; the generated page displays the project title. Detailed onboarding belongs in the repository README.

Analysis statistics appears only when an included element has control-flow, data-and-control-flow or cascading-fault analysis enabled. Enabled elements remain listed when results are missing, incomplete or failed. Project Complexity Overview appears only when an included component or activity has complexity metrics enabled and a generated summary is available. Disabled elements' retained summaries do not appear, and an empty overview has no project quick link.

The sidebar lists CREATE viewpoints beneath each element. Model libraries appear when they declare model entities; ticket registries without model content do not appear. When a library has multiple packages in one viewpoint, one viewpoint entry groups the distinct package links.

Filed Issues

The project and element landing pages show summaries and prominent links in their Issues section. Open Filed issues in external tracking systems to review the complete ticket table on external-issues.html. Counts appear beside the table, independently of headings and navigation labels. Priority icons use the same sprites and colors as model-check findings. Filed issues do not add another CREATE viewpoint in the sidebar.

The separate page has searchable choice filters for Kotlin module, Viewpoint, Status, Priority, and Assignee, plus text filters for the other columns. A ticket referencing several modules or viewpoints matches each of them. Choices update when current Jira fields load or refresh, while selected filters remain active.

To show a single link from the landing page to the Issues summary page, configure the root task in build.gradle.kts:

import com.stigway.gradle.tasks.docs.StigGenerateHtmlTask tasks.named<StigGenerateHtmlTask>("stigGenerateHtml") { inlineIssues.set(false) }

Module tasks inherit this setting unless explicitly overridden. The default is inlineIssues = true.

Model Check Results

The project landing page and its Issues page link to Model-check findings and Filed issues in external tracking systems. Interactive filters are available on the separate table pages. A finding is a result reported by a model check; a filed issue is an external ticket tracking work on that finding. The paginated model-check table on model-check-findings.html includes automatic findings from every module included in the report. It loads the display JSON separately and retains every finding, source link, reviewed-object link, correction, and severity sprite. Each positive summary count opens the corresponding rows in the findings viewer, retaining its module, viewpoint, rule, severity, and filed-issue filters. Download this table as JSON exports the currently filtered findings in their displayed sort order, as readable row objects. The project landing page also groups the shared rule summaries by viewpoint. Modules omitted with --exclude are omitted from these aggregates too. With inlineIssues = false, the landing page links to the Issues summary page instead of displaying the two summaries.

Both table pages fill the available width and allow column resizing. Their filters are stored in the URL: open a filtered link to restore its selections, change the filters, then use Copy filtered link or copy the address bar to share the new selection. Several choices in one column match any selected value; different columns must all match. Clear filters removes every active filter, including filters supplied by the incoming link. Reset filters to link restores the incoming selection. The link retains the report data and section anchor; it shares filter criteria, so refreshed Jira fields can change the matching tickets. Changing filters updates the current browser history entry without reloading the page.

Ordinary checks and HTML generation report automatic findings. Manual review requests are opt-in through stigCheckModel --checks all or --checks manual; see check selection. SARIF and JSON results retain the originating module, producer task, CREATE viewpoint, and reviewed object's identity.

Severity summaries start with All severities: N total / M without filed issue, then show the same pair for each severity. Per-rule tables use Rule, Findings, and Findings without filed issue. Both count cells show the total and its severity breakdown. Zero is always 0, without a link. Rules that have not run show an execution label and an em dash instead of a misleading zero. The findings viewer's Filed issue column shows matching tickets, with the reviewed object's ID on hover.

The ? Contributor unknown button precedes a finding when it stays on the receiving object because the faulty child contributor cannot be identified. Activate it to read the explanation. Ordinary missing content in a known local container, such as an Analysis omitting an interface point, does not carry this badge. The badge changes neither the finding's severity nor which object's tickets can cover it.

Only issues declared on the exact reviewed object can cover its finding. A ticket covers either its specified rule classes or, when the list is omitted, all rules on that object. Multiple tickets contribute their union. Containers, parents, siblings, propagation targets, and referenced definitions or measures never supply inherited coverage. Findings without an existing reviewed object cannot borrow an owner's ticket. Multiple matching tickets count a finding once; the same ticket can be explicitly declared on several objects. Model IDs include the qualified Kotlin declaration path; short names may repeat in different scopes. If distinct Kotlin objects resolve to the same full model ID, their findings show ambiguous model ID, without a model-object link or ticket coverage. Correct the identity binding before attaching tickets to those findings. Jira ticket numbers do not participate in model identity resolution.

These counts measure declared tracking coverage, regardless of Jira status. Ticket links never reduce problem severity, remove findings, or change the failAt threshold. The model retains the authored links, and regenerating the reports recomputes the counts without editing generated JSON or duplicating Jira's action workflow.

Each module's Model Checking Summary links to check results on its Context, Requirements, Design, Analysis, and Tests viewpoint pages. Rule tables, severity counts, and filtered findings links live on those pages; the module page contains only the overview. Its flat column headers list Rules - total, Rules - by result, Findings - total, Findings - per severity, and Findings - without filed issue, in that order. Findings count reported violations. Only the viewpoint column has a text filter; numeric totals remain sortable.

The viewpoint summary has three columns: Rule, Results, and Without filed issue. It lists executable checks with Passed, a linked violation count, Not selected, Not run, or Incomplete. A rule passes only when its selected scopes were evaluated and no violations were reported; unselected or uninvoked rules never become passes. Project summaries merge the selected modules' rule inventories, including scope selection and execution counts. Semantic rules remain in the rule inventory and opt-in manual-review workflow.

Rule IDs in the summary and findings table link directly to the matching section of the generated Highway model rules. The anchor is the existing Kotlin-defined rule ID, unchanged. SARIF rule help and IDEA inspection descriptions use the same documentation links. Each reference shows the rule's possible finding-severity badges, linked ID, and human-readable name inline. These badges describe the rule's possible outputs; the Severity column describes the individual finding. Model ASIL remains a separate classification. The generated catalog includes the actual Kotlin check implementation, including the concrete configuration and shared implementation for inherited checks. Semantic check code selects evidence for review; it does not decide whether the semantic requirement has passed or failed.

Released and snapshot STIG builds link to the public rule reference at https://docs.stigway.com/model-rules.html#ruleId. This reference follows the documentation published at the site root. Unsupported build-version labels retain the rule ID as text.

The priority line always reports Critical, High, Moderate, and Low, including zero counts. Pending-review and unresolved-assessment counts are not part of this automatic-check summary.

Project and module viewpoint summaries share the same header layout. Each positive total or severity count opens the separate findings page for the viewpoint. A rule's finding count opens that page with its rule and viewpoint filters already selected, matching exact identifiers. All viewpoints in a module share one display JSON file. N findings match filters counts all matching findings across pagination pages. The status also shows the findings in the report and, when modules are selected, the findings in those modules before applying other filters. Reset filters to link restores the filters from the original URL; Reset filters clears them when the URL has none. Every report table has a native page-size selector with 20, 50, 100, 200, 500, and 1,000 rows (default 50). Its columns are Kotlin module, Viewpoint, ASIL, Source, Reviewed object, Message, Correction, Severity, Rule, Filed issue, and Element. Every issue table has column filters in the header, including Kotlin module and Viewpoint, at every scope.

In model-check findings, Kotlin module, Viewpoint, ASIL, Reviewed object, Severity, Rule, Filed issue, and Element offer searchable choices from the loaded findings. Choose several values to match any of them; different columns combine to narrow the results. Selected choices appear as removable chips. Typing in a header applies case-insensitive text matching and accepts * patterns, including pecu*. The choices menu's search narrows its list; Use text or pattern adds that search as a filter choice. Source, Message, and Correction retain text filters, including multiword names and literal </& characters.

The module list includes exact paths and descendant branches. Select :clusters:pecusw together with :components:pecu:* to include that cluster module and every descendant module under :components:pecu. A :* branch excludes the parent module itself and similarly named branches such as :components:pecu2. Overlapping selections count each finding once. Element identifies the owning model element independently of the Gradle module that was checked; it is not an additional module hierarchy.

Each choice shows its finding count under all other column filters, excluding its own column's filter. Alternatives remain available at zero matches. Natural order uses severity/ASIL strength and alphabetical order with numeric sorting for other fields. Most matches orders choices by descending count with alphabetical tie-breaking. The order stays stable while selecting values in an open menu. ASIL choices reuse the report badges, retaining decomposition notation; viewpoint choices reuse the navigation icons. ASIL is the reviewed object's classification, using effective ASIL for interface points. Not specified means that classification is unavailable, not QM. Regenerate model-check evidence and reports to populate ASIL in previously generated findings.

Reviewed object, immediately before Message, shows [Kotlin reference] human name and links to that object's anchor in the Dokka model tree. Hovering shows the fully qualified ID. Correction contains the problem-specific remediation, or the rule's default guidance. Source opens the repository file at its recorded line and revision. The IntelliJ IDEA sprite beside the source link opens the same line in IDEA when the configured source actions provide a link. These actions are separate from navigation within the HTML report. Severity prefixes the severity text with the same colored sprite used in the viewpoint's priority summary. Message and Correction start at 560 px and 520 px respectively; the table scrolls horizontally instead of squeezing the columns into the screen. Each column header's menu offers Hide this column and Show all columns. Finding records are loaded from JSON rather than embedded in HTML, and the former 200-record display limit does not apply.

Rule messages identify objects consistently as [fully.qualified.Kotlin.reference]; human names are separate display data. Rule names, Kotlin identifiers, and human names retain their original capitalization when displayed in messages or report fields. JSON stores plain text, structured URLs, and icon metadata. Literal quoted name values can still appear when a rule checks the contents of a name or description. No Markdown support is required in the findings table or IDEA to distinguish an object's reference from its multiword name.

The complete diagnostic StigProblemRecord export stays on the build machine. The report shows its actual repository-relative path in code font and an IntelliJ IDEA action when source-action configuration resolves it. Generated diagnostic files use the local IDEA action without a Git file link. These records retain result kinds, subjects, owning elements, source locations, remediation and evidence, including manual-review records when requested. entityId identifies the reviewed object; subjectId can identify a separate obligation anchored to it. Neither field is a duplicate-row key.

stigGenerateMarkdown writes one --model-check-results.json (local diagnostics) and one --model-check-table.json (display data) per module under build/docs/. Filenames include the configured package prefix and module name. Generation prints clickable file paths with their purpose and publication scope, including the compressed table filename used by the HTML report. A standalone stigCheckModel prints its canonical local results and rule-inventory paths. At the project root, both stigCheckModel and :stigCheckModel run one complete model check without also selecting the individual module checks. The root summary identifies the consolidated results and lists the diagnostic JSON, display JSON, and published HTML table destinations. Those report destinations are explicitly marked as not refreshed by the check; run report generation to create or refresh them. When project-wide findings are disabled, the summary states that those exports are disabled. Check and report tasks also run stigPrintVersion once per build, showing the loaded STIG version, selected source and project version.

Root model checks and shared report preparation load and wire the compiled model once. They prepare source inventories and module scopes before checking modules in parallel. The default worker budget is the available logical CPU count minus one, with a minimum of one; Gradle's --max-workers can lower that budget. Rules remain sequential within each module, and findings and diagnostic messages are merged in module order. Report page rendering follows the completed checks sequentially. The session remains open until every worker has finished, including after failure or interruption. Progress events report model loading, source and scope preparation, checking wall time, and aggregation separately. Summed evaluation and serialization times add the workers' elapsed times and can exceed checking wall time.

Check sections still attach to their source viewpoint packages. The default project-wide aggregate adds build/stig/model-check/project--model-check-table.json and its local diagnostic export. To omit only the project-wide findings and rule summaries:

stigProject { generateHtml { enableProjectWideFindings = false } }

The table's Correction column contains one short human-readable paragraph, including finding-specific values where applicable, such as the required ASIL. It is generated from the explicit remediation summary or the rule's short correction; detailed remediation is never used as the table payload. Full repair instructions and diagnostic evidence remain in the local results JSON identified by the report's repository-relative path.

Repeated table values use lossless column dictionaries whenever these are smaller than ordinary rows. Detailed incoming-link corrections contain target-specific instructions; their complete candidate inventories are computed once per owner and written once to model_check_remediation.json beside the task's problems.jsonl. Diagnostic records identify the inventory by repository-relative file path and ID. This avoids repeating the whole Design/Analysis inventory in every correction. IDEA can display that same inventory with the correction.

After this reduction, generation writes a .json.gz table and logs its row count, raw JSON bytes, and gzip bytes. Dokka publishes only the compressed table in images/, alongside model-check-findings.html. The browser decompresses it without requiring Pages server configuration, and the review UI reuses the same data. Raw tables, diagnostic exports, remediation inventories, and complete-project SARIF remain local. Both aggregate reports and standalone module previews use the same table reader, count, filtering, pagination, and export controls.

Display tables and SARIF retain a 95 MiB (99,614,720-byte) per-file safeguard. If dictionary storage still cannot fit a table, long Correction text is shortened before Message text with an explicit marker directing readers to local evidence. All rows, short text, identities, priorities, and links remain intact; generation fails if protected data still exceeds the limit. Local diagnostic exports and task-owned JSONL are not subject to this display limit.

Compact model documentation

Shared model libraries retain ordinary Dokka declarations and canonical model anchors. Their default compact model section lists each definition, its scalar attributes, and incoming references once, without the foldable boxes or review controls used by full trees. Consumers retain their normal CREATE trees and link to the library; reference popups fetch the compact definition on demand. A library has no architectural viewpoint summary or CREATE quick links.

Configure the library's build file, for example:

import com.stigway.gradle.dsl.ModelDocumentationMode stig { modelDocumentation { mode = ModelDocumentationMode.COMPACT maxTextLength = 240 } }

IDENTIFIERS lists IDs and names with incoming references. FULL retains complete CREATE trees and remains the default for element modules. maxTextLength bounds each displayed descriptive value, counting the ellipsis within the limit; zero omits those values and null leaves them complete. IDs and names remain intact. These settings affect model rendering and reference metadata; Kotlin sources, model values, and report evidence remain complete. Use the generated file sizes to select a mode and text limit appropriate for the publishing host.

Executable Model Trees

Each root model object or top-level value owns one Dokka page containing its complete foldable runtime-model tree. The declaration-to-page extension creates that page before Dokka resolves navigation and search links. The root's implementation class and its contained model declarations resolve to this page and its tree anchors; separate Kotlin API tables are not emitted for those declarations. Package pages provide the entry links.

Full model pages start with the tree controls and root model box. The root box supplies the page's level-one heading; contained boxes follow the model depth. There are no separate declaration or source-file headings above the tree.

Every model-box heading and each source-resolvable attribute use the same provider-branded View in GitHub/GitLab, optional Edit in GitHub/GitLab, and Open in IntelliJ IDEA icon actions. Every model box also has a semantic icon, complete attribute table, and stable anchor.

Model relations have distinct forward and reverse roles, such as allocatedTo/allocatingRequirements and derivedFrom/derivesTo. Display labels split these camel-case names into lower-case words: allocated to/allocating requirements. Reverse links are computed from the authored forward references; users do not populate them separately.

The StigModelRelations.Relation enum owns a typed Kotlin property reference, source and target classifiers, and both display role names. Every direction has a unique role name and label. Repeated stored property names are qualified for display: Design.element becomes design element, and Analysis.element becomes analysis element. Kotlin properties, source actions, review identities, and consumer models retain their existing names. The registry's proposedNames records candidates for a future metamodel rename and stigUpdate migration; these proposals do not affect current rendering or serialization.

Following a model relation briefly highlights the destination. When its corresponding reverse reference is present, an outline and ↩ Back to previous item cue identify the originating item for four seconds. Following a reverse reference identifies its forward counterpart in the same way. The cue adds no focus change or extra scrolling and does not animate; the destination flash respects reduced-motion preferences.

The reverse of usedIn appears as uses on the referenced Context interface point and on each analysis of that exact point. It lists the interface-point analyses containing those authored references; showing the same incoming references on an analysis does not create another authored relation or assign ownership of a shared definition. Dokka's aggregate report prepares all selected documented modules before computing these links, including modules referenced only in the incoming direction. A standalone module preview includes incoming references available in its required model context and shows them as labels when their source pages are outside the preview; it does not load unrelated modules to discover their incoming references. The aggregate report links to those pages. Compact library definitions retain incoming links in both COMPACT and IDENTIFIERS modes.

The first two displayed model levels open initially; deeper boxes start closed. Separate Expand all and Collapse all actions are available, with both enabled for a partially open tree. An action is disabled when the tree is already fully in that state. Grouped report tables use the same controls.

Every model heading starts with a sprite and a badge naming the nearest STIG metamodel class. The Kotlin property name (when present), a colon, and the concrete Kotlin class follow, then source actions. Issue links belong in the issues attribute. The heading has no separate name line; the human-readable name appears in the attribute table. The right-hand On this page entries use the property reference and its semantic sprite, including deferred content.

Attribute values wrap within their column, and lists of references have spacing without separator lines. Failure multiplicity and evaluation use labelled sprites and coloured badges: single point and residual are amber, multiple point is blue, sufficient is green, and gap is red. Multiplicity describes the required combination of failures; its colour does not establish that the mitigation is sufficient. Narrative tables size their columns from their contents instead of assigning a fixed viewport width to the first column.

Severity uses an effect sprite and a colored badge showing its number and short name. Its full description is available on hover. S1–S10 carry automotive DFMEA effect names; S0 and noncanonical numeric values remain neutral and retain their authored number.

Port analyses are authored InterfacePointAnalysis objects that contain their member analyses, mirroring Context containment. The renderer follows this model hierarchy directly, so every analysis box has its own declaration, canonical identity, source actions, attributes, and review target.

The renderer writes deeper model bodies to separate HTML assets beside their root object's page. Expanding a box loads its body and immediate child summaries; Expand all loads the remaining descendants. The model index resolves direct links to deferred entities and properties, loading and opening the required ancestors. Review metadata and content hashes cover the complete model before bodies are separated, so deferred content retains its source and review identity.

View links are pinned to the selected commit. STIG chooses the owning repository from the source file's deepest configured repository root and emits the correct GitHub or GitLab URL shape. CodeBrowser.AUTO recognizes normal GitHub and GitLab host names; set a repository's codeBrowser explicitly for an ambiguous self-hosted URL.

Edit links are disabled by default. When enabled, STIG shows Edit only if the selected revision is exactly the fetched upstream commit of the checked-out branch. A detached checkout, an untracked branch, or a locally-ahead branch therefore has no Edit action. Normally editRef remains unset and the upstream branch is used; a repository-level editRef exists only as an explicit override.

IDEA links are enabled by default and use JetBrains' local navigation protocol. They prefer the checkout's actual Git origin and publish it with the repository-relative path and line, never an absolute workstation path. If checkout origin metadata is unavailable, the configured browser remote is the fallback. This is deliberately independent of a GitHub/GitLab publishing override, so an online report can browse a monorepo mirror while IDEA opens the matching standalone local checkout. The browser may ask permission before handing the link to the installed IDE.

Collection attributes show their item count and put each referenced model entity on a separate line. Hovering a model reference opens the referenced entity's complete attribute table, including its own traceability links; those links can be followed directly from the popup. Cross-page targets and popup tables load when a reference is hovered, focused, or clicked; opening a page does not prefetch the declarations behind all its references. A direct click waits for the model anchor to resolve. Following a link briefly flashes the destination heading or compact entry for one second, including across HTML pages, after deferred content loads and its ancestors expand. The cue uses Web Awesome's standard flash animation and respects the browser's reduced-motion preference. Reference cards reuse the canonical target page and its cached body assets; full trees no longer carry a hidden copy of every referenced entity. Preview the report through the IDEA or JDK HTTP server for the complete interactive behavior.

External sources and issue references

Declare URL templates once in a shared model library and depend on that library from the modules using them. issues contains IssueReference values; sources contains URLReference values for external evidence or origins, such as requirements and model elements:

val jiraPth = IssueReferenceTemplate(url = "https://jira.example.com/browse/{id}", prefix = "PTH-") val requirements = URLReferenceTemplate(url = "https://requirements.example.com/item/{id}", label = "Requirement {id}") val missingCommand = Failure( name = "Missing command", issues = listOf( jiraPth(123, rules = listOf(FailureEvaluationRule::class)), jiraPth("PTH-456", rules = listOf(FailureSeverityValueRule::class)), ), sources = listOf(requirements(789), url("https://example.com/analysis", "Analysis evidence")), )

Numeric IDs and full keys identify the same ticket: use jiraPth(123, listOf(FailureEvaluationRule::class)) or jiraPth("PTH-123", listOf(FailureEvaluationRule::class)). A key with another project's prefix is rejected. Single-argument calls, such as jiraPth(123), cover all rules on the declaring object. List rule classes when a ticket covers only selected rules. An explicit empty list is rejected. Rule classes come from the existing com.stigway.metamodels.create packages; no separately authored string identifiers or rule catalogue is needed. Import the two example rules from com.stigway.metamodels.create.analysis. issue(uri, label, rules) constructs a direct ticket reference. A URLReference stores its complete absolute URI and optional label; it stores no Jira status and needs no separately named model declaration. url(uri, label) is a convenience constructor. Templates without a prefix also accept string identifiers such as UUIDs and encode them when substituting {id}. A project can define its own magicdrawModel(id) template using its actual application URI. Direct application URIs, including magicdraw:// and idea://, are accepted; opening them requires the corresponding application handler. The HTML sanitizer also permits mdel: and the existing STIG jetbrains://idea/navigate/reference route; arbitrary other schemes may be filtered by the viewer.

Highway JSON derives reference fields from the Kotlin constructors and embeds url, label, and a ticket's optional rules. Rule class names are encoded only in exchange JSON and resolved against the registered default rule classes; arbitrary classes are never loaded from incoming JSON. Kotlin import preserves class literals and reuses a declared template when its URL and label match. To migrate ticket declarations, change URLReferenceTemplate to IssueReferenceTemplate and direct url(...) calls to issue(...) in issues; keep source references unchanged. HTML and exported MkDocs pages show issue and source links separately. Sources do not activate Jira widgets.

stigGenerateMarkdown writes ticket links and their model associations to build/stig/issues/issues.md in each module and at the project root for the selected scope. stigGenerateHtml adds an issues table to module pages and an issues.html index at module and project level. Each table row links back to the relevant model-tree entries.

Generation makes no Jira requests. At page opening, local ticket identities are available immediately; the browser loads the pinned Atlassian widgets and asynchronously batches Jira summary/status requests. Tabulator provides sorting, pagination, and a text filter in every column header. Kotlin module and Viewpoint list all model scopes that reference each ticket. Status filters match the values returned by Jira, and unavailable tickets remain listed. Filters remain active after refresh. Atlassian widgets provide ticket links and hover previews. The inline Smart Card shows the key and current status; hovering opens Atlassian's preview and requests the description on demand. Tables and cards share a page-local cache. Refresh, returning to an older tab, and a one-minute refresh while the page is visible update the displayed state. The retrieval time is shown beside the table.

The live adapter supports Jira's /browse/KEY links and REST API v2 under the same Jira context path. Jira access shows token storage and authentication separately. Save and check stores a personal access token, checks authentication, and refreshes the tickets while leaving the dialog open with the result. Authentication checks, ticket summaries, and hover descriptions all use POST /rest/api/2/search. The check submits the validated JQL query assignee = currentUser(), which requires an authenticated Jira user. An empty result is valid: authentication does not require assigned tickets. A successful ordinary ticket search alone does not prove authentication because Jira can expose tickets anonymously. CORS permission can differ by endpoint; the viewer does not require access to /myself or /issue/KEY. A saved token can be rejected or remain unverified when the connection fails. Check connection retries with the current credentials; an empty input does not remove them. Remove token clears the token and checks the viewer's Jira browser session. Create token opens the selected Jira Server/Data Center instance's personal access tokens profile tab in a new browser tab, preserving any Jira context path. Create the token there, then paste it into Jira access.

The default This tab choice uses sessionStorage, so the token survives navigation and reloads within the same report origin. This page only keeps it in memory until navigation or reload. Remember in this browser explicitly uses localStorage for future visits and other tabs; choose it only on a trusted device. Tokens are scoped to the exact Jira base URL, including its context path. Browser storage is scoped to the report's scheme, host, and port, so switching from a local preview to a published report does not carry credentials across. Storage failures are shown explicitly. Each new page checks authentication again; a previously successful check is not saved as current proof. Report artifacts contain no credentials.

Jira must allow the report origin through CORS. Browsers require this permission before a page on one origin can read another origin's responses, even with a valid token or an existing Jira session. Opening Jira directly is a separate operation. The dialog distinguishes readable HTTP 401 responses (authentication rejected), HTTP 403 responses (access denied), other HTTP failures, timeouts, and invalid responses. When a request fails without a readable response, page JavaScript cannot distinguish CORS from network, VPN, or TLS failures and cannot establish whether authentication was accepted. Connection help shows the report origin and authentication endpoint for diagnosis in the browser's Console and Network tabs.

For a cross-origin deployment, the Jira administrator or its reverse proxy must allow the report's exact origin, POST /rest/api/2/search, and the Authorization and Content-Type request headers, including unauthenticated OPTIONS preflight requests. Session-cookie access also needs Access-Control-Allow-Credentials: true and is subject to the browser's cookie policy. Error responses need the CORS headers too, or the report cannot read a 401/403 response. An approved server connection on the report's origin is another deployment option. A local helper would be a separate program running on the viewer's PC, serving both the report and its Jira API connection at one origin. Its HTTP client would contact Jira outside the browser, like a command-line script. Browser JavaScript, including scripts downloaded from Jira and embedded in the report, still runs with the report's origin. Adding another browser script cannot replace that external connection. This static viewer does not supply a helper. See the browser CORS guide.

Other issue repository URLs remain ordinary links. Jira fields shown in HTML describe the current service response; they are not a snapshot of the state when the report was generated.

Project navigation

The left navigation groups element modules by their compiled Highway element kind. Groups sort by Element.level, then alphabetically when levels match: activities precede components because both have level 5. Intermediate groups follow the Gradle project path and can have any depth, including no intermediate group. For example, :items:hvs appears under items, while :components:pecu:applications:Controller appears under components → pecu → applications. Intermediate groups and element modules sort alphabetically among siblings. One Kotlin/Gradle element module represents one Highway element. Shared model libraries appear separately under libraries; documentation modules without an element appear under modules.

To use domain-specific group names, configure navigationGroupNames in the root build. For example, a ROS 2 project can display its Component modules under nodes:

import com.stigway.metamodels.highway.ElementType stigProject { generateHtml { navigationGroupNames = mapOf(ElementType.COMPONENT to "nodes") } }

With this setting, :nodes:collision_guard_node appears as nodes → collision_guard_node. A leading Gradle path segment matching either the default group name or the configured name is omitted, so :components:collision_guard_node produces the same navigation. The element remains a Component, with its existing icon, level, and page URLs. Unconfigured kinds retain their default names. Names must be nonblank single segments, and effective group names must be distinct, including the reserved libraries and modules groups.

The configured element.id assigns an element to its report module even when its descriptor is declared in a parent module and referenced through a Kotlin alias. Navigation preserves that element's canonical identity and uses the configured module assignment before its Kotlin declaration location.

Within an element module, viewpoint packages appear as Context → Requirements → Design → Analysis → Tests. Linked standalone Markdown documents join the viewpoint of their nearest enclosing # Package companion in the same module. Their navigation labels use the source filename with its first letter lowercased: PecuswDfa.md appears as pecuswDfa alongside pecuswAnalysis under Analysis, with its document URL preserved. Their compact SVG icons match the module quick links. Architectural groups and element modules use the shared metamodel icons; Issues has a ticket icon. Icons scale with the navigation text and follow the current theme. The shared Highway Viewpoint enum owns this order. STIG's Kotlin Dokka extensions generate the groups, labels, and ordering; browser JavaScript does not reconstruct or sort the tree. Module and viewpoint URLs remain unchanged.

Web Awesome's wa-tree supplies tree-wide focus, keyboard navigation, and selection. Its wa-tree-item supplies individual nodes, folding, and lazy-loading events. A small STIG adapter loads the current module and expanded branches, highlights the current page, opens its ancestors, and remembers expansion and scrolling within the browser tab. The aggregate report has one root menu and one copy of each module branch, so opening a report does not download every module's complete menu.

The navigation and review panel use the bundled Shoelace theme and Shoelace color palette. The theme supplies component styling and design tokens; the palette supplies colors. Light/dark mode follows Dokka. Actions remain native HTML button elements, links remain native anchors, and Web Awesome badges display status or counts. The wa- prefix identifies a custom element supplied by Web Awesome, not a built-in HTML tag; HTML has no native tree or badge tag.

A statically supplied Web Awesome tree can fold without custom STIG JavaScript, but Web Awesome itself still uses JavaScript. This report loads its navigation through the STIG adapter: disabling that adapter leaves the menu unloaded, and disabling all JavaScript does not produce a fully expanded navigation tree.

Ordinary model and findings pages load the small page bundle; diagram pages load the separate viewer JavaScript and stylesheet when needed. JavaScript and CSS source maps are local development assets and are marked non-publishable in the HTML output manifest. Runtime bundles, model-body assets, navigation branches, and findings data remain publishable.

Browser Review Findings

Enable browser reviews in the consumer root's build.gradle.kts. Publication and review are sibling blocks inside stigProject. Reuse a declared repository for the GitHub Issues destination:

import com.stigway.gradle.dsl.ReviewProvider import com.stigway.gradle.settings.PublishProvider stigProject { val modelRepository = repo("modelRepository") { root = "." remoteUrl = "git@github.example.com:safety/model-project.git" } publish { provider = PublishProvider.GITHUB remote = "origin" pagesBranch = "github_pages" pagesSubdir = "model-project/report" publishedBaseUrl = "https://pages.example.com/safety" } review { enabled = true provider = ReviewProvider.GITHUB repo = modelRepository github { apiUrl = "https://github.example.com/api/v3" } } }

repo accepts the reference returned by repo("name") { ... }. The issue owner/repository is derived from that repository's remoteUrl, or its checkout's origin when no override is configured. The GitHub website origin is derived from the same remote. Public GitHub defaults to https://api.github.com; GitHub Enterprise defaults to the website origin plus /api/v3. github.webUrl, github.apiUrl, and github.tokenCreationUrl remain separately configurable; webUrl must match the repository's server. API and token endpoints can use a different host.

The review issue repository can differ from the repositories containing the reviewed Kotlin sources. Source links keep using the existing source repository configuration. publish.publishedBaseUrl describes the deployed report, and can use a different host from either repository. PublishProvider.GITHUB appends pagesSubdir to that base URL; PublishProvider.GITLAB uses the base URL directly for the existing CI deployment that exports the chosen subtree at the Pages artifact root. These publication providers use the existing Git branch workflow. Only ReviewProvider.GITHUB is currently implemented for findings.

projectId is the namespace for all findings belonging to this STIG consumer project. It defaults to rootProject.name; it is not an ID for one page or one work product. The discovery label defaults to <projectId>-review: stig-project-review, stig-pth-review, and stig-aeb-review can coexist in one issue repository. Set review.projectId or review.issueLabel explicitly when an existing identity must survive a Gradle project rename. Changing these values selects a different collection of findings.

Each finding also stores the canonical Kotlin ID of its work-product container, the entity ID, and the exact property name. No per-page reportId configuration is required. A requirement's description is identified separately from its name or its entire entity. Selecting across properties uses their encompassing entity; selecting across unrelated entities is rejected. Generated Review buttons use the same editor and finding record as selected-text annotations.

Reviewing A Publication

The build pipeline finishes at stigPublishHtml. Reviewers then open the deployed report and turn on Review mode. The sidebar defaults to This page/viewpoint, GitHub and automated, and Open and resolved. Generated findings are available without signing in. Choose Connect GitHub to load shared discussions or create a finding. There is no Gradle task for creating or performing reviews. Owners fix the Kotlin content and publish another report through the normal pipeline afterward. Pull requests are not required. When the existing CI provenance metadata identifies a GitHub pull request, its number and URL are stored only as optional context.

GitHub findings are shared with every reviewer who can access the configured issue repository; they are not filtered to the signed-in author's issues. Issues and replies remain in GitHub after closing the browser or restarting the computer. Reconnect if the chosen token storage has expired; forgetting a token does not delete reviews.

The connection dialog shows the GitHub server, issue repository, Create GitHub access token link, and the exact fine-grained token settings:

GitHub field

Setting

Token name

<projectId>-review, shortened to GitHub's 40-character limit.

Resource owner

The owner of the configured review repository.

Expiration

github.tokenExpirationDays, defaulting to 365 days (1 year); organization policy may require less.

Request message

github.tokenRequestMessage, defaulting to a justification naming the project and issue repository.

Repository access

Only select repositories, then select the review repository.

Repository permissions

Issues: Read and write.

Metadata

Read-only, included automatically.

Account permissions

None.

Organization permissions

None.

Select the resource owner and repository first if GitHub initially shows only Account permissions. Contents, Actions, Pull requests, and Administration permissions are not required for report findings.

By default, STIG generates a /settings/personal-access-tokens/new link with GitHub's documented name, description, target_name, expires_in, issues=write, and metadata=read parameters. Query values use UTF-8 percent encoding, including %20 for spaces. The documented parameters do not include repository selection or the organization access request message; enter these on GitHub. GitHub Enterprise Server versions may ignore prefilling, so the dialog also displays the settings to enter manually. See GitHub's token URL parameters. An explicit github.tokenCreationUrl remains an exact override, including any custom query parameters.

Kotlin resolves the token name, owner, repository, expiration, request message, and required permissions from the consumer configuration and plugin defaults. stigPrepareReviewAssets writes the resulting tokenSettings rows and creation URL to build/stig/review-assets/stig-review-config.json, which is included under images/ in the report. JavaScript loads that JSON and renders the table as plain text; it does not maintain a second set of token settings.

On GitHub, press Generate token and request access, or Generate token when approval is not required. Copy the token into the report's Access token field and save a backup in a password manager; GitHub displays the token only once. If organization approval is pending, wait for approval before connecting.

Applying labels and assignees also requires a suitable GitHub repository role, normally triage or write. A maintainer may need to create the project's discovery label first. Complete organization approval or SSO when required. Classic tokens for private repositories require the server's broader repo scope and any applicable SSO authorization.

Tokens default to sessionStorage. Reviewers can choose This page only for memory storage or explicitly select Remember in this browser for localStorage. Forget token disconnects and clears the connection's saved token. Tokens never enter Gradle configuration or generated artifacts, and the browser cannot reuse gh CLI credentials. The GitHub Enterprise API must allow direct browser requests from the report's HTTPS origin, including authorization headers and preflight requests. STIG does not provide a gateway to bypass that server requirement.

Create a defect, question, or proposal, and enter GitHub assignees explicitly. Declared model authors are shown as context; STIG does not guess their GitHub usernames. In the new-finding form, Enter submits the finding and Shift+Enter adds a new line to its description. Esc cancels creation and returns focus to the review control. Tab and Shift+Tab cycle through the title, finding description, type, assignees, and action buttons. Every issue contains searchable work-product, source repository, and repository-relative file information. For example:

is:issue label:stig-project-review assignee:owner-login is:issue label:stig-project-review "Requirements.kt" in:body

The sidebar combines this page's GitHub findings with its generated executable model-check violations and, on module pages, structured STIG task problems. Successful checks are not findings. Opening an automated finding creates no issue. Its Start discussion form creates or finds an issue when the first response is submitted; the issue contains both the automated evidence and that response. Correct the model, configuration, or source and regenerate the report to change the automated result: closing its issue does not suppress or pass the check. Kotlin emits explicit links to the findings JSON and structured task-problem data; JavaScript does not infer problems from formatted table text.

Choose All report reviews to include GitHub findings associated with other pages. Automated findings remain limited to the current page, as indicated in the sidebar. Source and status filters, source/owner search, and previous/next navigation apply to the list. The arrow buttons support Enter and Space; Left Arrow and Right Arrow move between findings when focus is in the sidebar outside an editable control. Navigation is disabled while creating a finding. Large lists initially show 50 entries, with Show more for the rest. Refresh reloads GitHub findings and generated results. While review mode is visible and connected, the browser refreshes shared findings once a minute and on focus; there is no live push connection.

Clicking a GitHub finding's ID or title in the list or discussion heading opens its issue in a new tab. Choose Open discussion to read it in the report. Opening a GitHub finding shows a chronological SVAR flow discussion with its initial message and replies by all participants. Use Send reply or Ctrl/Cmd+Enter to add an ordinary GitHub issue comment; Enter alone adds a new line. Failed submissions retain drafts. Resolve finding closes the issue with reason completed; Close as not planned uses not_planned, and Reopen finding reopens it, subject to GitHub permissions. GitHub.com also exposes Close as duplicate, requiring a canonical issue number. Add classification label offers existing repository labels: “confirmed bug” is a classification, not a built-in GitHub issue state. GitHub Projects custom Status fields and comment editing/deletion are not implemented. List filters are hidden while reading a discussion; Back to findings restores them. Refresh also reloads the open discussion. Badges count open and resolved findings for each target. Open and closed issues are loaded with pagination; discussion comments load only when a finding is opened.

One finding is one ordinary GitHub Issue, with a readable body and a versioned, encoded STIG metadata comment. Preserve that comment when editing the issue directly. Arbitrary issues without valid STIG metadata cannot be associated with a report page.

The stable automated finding key comes from the canonical problem identity (module, category, problem and subject), not a generated URL, row position or release revision. The same key is also emitted in SARIF. Later reports can reuse the original discussion, including closed issues. One element can have several independent discussions. Retry recovery checks existing records, but GitHub cannot enforce unique custom finding keys across simultaneous clients; duplicate associations require reconciliation. Version-1 manual review records remain readable alongside version 2.

GitHub removes direct custom-protocol Markdown links such as jetbrains:. New findings therefore use an Open in IDEA (via report) HTTP (S) link. The report displays an explicit Open in IntelliJ IDEA action for the validated source-navigation URL; it never launches the IDE automatically or requires GitHub sign-in for this action. The source repository must be available in a local IntelliJ IDEA checkout. Existing GitHub issue bodies are not rewritten when a report is regenerated.

Findings After Regeneration

STIG emits an inventory of the actual targets rendered by each included module. A matching entity/property and content hash is current; changed content is potentially outdated; a missing target is orphaned. A target on another page is linked there. Excluded modules and unavailable inventories are shown separately from missing targets. Text highlights are restored only after checking the quote and, when needed, finding a unique quote/context match inside the same target.

Findings retain the reviewed report revision, immutable source commit and start line, selected quote, Recogito offsets, target-relative offsets, content hash, and portable IDEA navigation URL. A report link opened on a published version keeps that version's URL. Local previews use the configured publication root when available. Source association comes from generated Kotlin metadata; browser text offsets do not pretend to identify Kotlin source positions.

Review targets are currently the source-resolvable entities and properties in executable model trees. Generated-only entities, ambiguous source declarations, and arbitrary narrative paragraphs do not receive invented target identities. The browser findings do not change model issues, document lifecycle metadata, or native transform reviewed values.

Authoring With Shared Reviews In IDEA

  1. Install the matching STIG IDEA plugin and open View → Tool Windows → STIG Reviews.

  2. Choose Connect…. Import the report's images/stig-review-config.json, or enter the same project ID, issue repository, discovery label and server URLs used by HTML. Enter your access token. IDEA stores it in PasswordSafe, separately from browser credentials; Forget token disconnects and removes it.

  3. The list shows shared findings from all reviewers, including closed issues. Filter by state, source, author or original revision; optionally restrict it to the current file. Selecting a finding loads its full discussion.

  4. Use Map source checkout… once for each source repository. Choose its local checkout and leave the prefix empty for a whole repository. For an imported subtree, enter the exact repository path mapped to that directory.

  5. Use Open source, Send reply, and the permitted workflow/classification actions. No terminal, Gradle task, pull request or changed-line diff is needed to read and answer reviews.

Open findings with verified source anchors also appear as Shared review findings inspections, Problems entries, and Kotlin gutter markers. Inspection Lens can display these existing IDE diagnostics. Their quick fix opens the discussion. Local automated inspections and SARIF remain separate evidence; ticket status does not change them. Kotlin declaration identities survive line shifts. Source-only line anchors require an exact source-content hash. Missing, changed, ambiguous or unmapped locations remain in the Reviews list without a guessed editor highlight.

IDEA restores the non-secret connection settings and uses PasswordSafe after restart. Its project-scoped service refreshes once a minute, loads open and closed issues with pagination, and backs off on API failures. Refresh requests an immediate update. The current session retains the last successful snapshot on failure and marks it stale. No network request runs inside an inspection or read action. Comments and issue state are stored in the provider, not the report, and need no report rebuild. Reviewing released content works without any PR; PR review remains a separate GitHub workflow for reviewing proposed changes.

Recogito, SVAR Comments, the review interface, and their JavaScript/CSS dependencies are included in the report's vendored bundle. Review-enabled HTML sanitizes model/document markup and uses a Content Security Policy allowing local executable scripts and connections to the configured GitHub API origin. Browser discussions render a restricted Markdown subset with raw HTML and images disabled, then sanitize the output. IDEA displays provider text without interpreting HTML. No external CDN, database, or server-side application is required. Shared versioned contracts and provider boundaries separate credentials, transport, persistence and presentation. GitLab, Jira and Confluence have explicitly unavailable skeletons; only GitHub is operational. Confluence's eventual comment anchoring and future providers' CORS/proxy requirements remain provider-specific decisions.

Build Provenance

Provenance pages record the project version, STIG version, and a repository table with Revision, Time, and Remote. A checkout at HEAD shows branch @ commit; other selections show the configured commit, tag, or branch. Only full Git object IDs are abbreviated, with the full ID on hover. Branch and tag names wrap without truncation. Revision and remote links open the configured code browser; available code-review links appear beside the revision.

Use this section to answer: "Which source revision produced this report?"

Repository history is selected with gitOwnership, independently of the configured source directory:

import com.stigway.engine.scm.GitOwnership val modelRepo = repo("model") { root = "." gitOwnership = GitOwnership.CHECKOUT }

CHECKOUT is the default. Ordinary folders and git-subrepo imports use the enclosing Git checkout's remote and revision. Source links include the directory's path within that checkout once. Standalone clones and initialized submodules use their own Git repository, including submodules whose .git is a Git-directory pointer. Keep root = "." for local model elements so their paths remain valid; do not prepend the model directory again with remotePath. A missing checkout remote leaves source links unavailable instead of borrowing a .gitrepo upstream.

Use gitOwnership = GitOwnership.SUBREPO_UPSTREAM when evidence must intentionally cite the upstream and imported revision recorded in .gitrepo. This requires import metadata; it does not infer an upstream revision from the enclosing checkout. Imported sources that previously relied on automatic .gitrepo selection must opt into this setting. Neither setting changes source directories or the synchronization workflow.

An explicitly configured repository at the enclosing Git root supplies remote, revision, and source-browser overrides to entries using that checkout; overrides on each entry take priority. A submodule or explicitly selected subrepo upstream keeps its own history. Setting remoteUrl on one repository does not replace the URL of unrelated repositories. codeBrowser = CodeBrowser.AUTO selects GitLab for hostnames containing gitlab and GitHub otherwise; set CodeBrowser.GITHUB or CodeBrowser.GITLAB explicitly when the host name does not identify the provider.

Context Viewpoint

The context viewpoint describes the element boundary:

  • what the element is;

  • what it communicates with;

  • which interface points are inputs and outputs;

  • how the element fits into the surrounding system.

For source-code-analyzed elements, interface points also drive source and sink configuration for flow analysis.

Requirements Viewpoint

The requirements viewpoint captures the requirements allocated to the element, including safety relevance, ASIL, derivation links, rationale, and validation status where modeled.

Use this section to review what the element is required to satisfy.

Design Viewpoint

The design viewpoint captures the intended design, structure, assumptions, safety mechanisms, and implementation-facing decisions for the element.

Use this section to review how the requirements are meant to be realized.

Analysis Viewpoint

The analysis viewpoint contains engineering analyses for the element. For source-code analysis, this can include:

  • expected data/control-flow results;

  • unexpected lower-ASIL-to-higher-ASIL flow checks;

  • sink/source summaries;

  • per-run analysis status;

  • diagrams and source links.

The exact sections depend on the enabled analysis modes and the consumer project's configuration.

Tests Viewpoint

The tests viewpoint links test cases and verification evidence back to the requirements, interfaces, and assumptions they cover.

Use this section to review whether modeled verification evidence exists for the element.

Check Results

Model-check and validation results are rendered as problems when the project enables them. Problems should be read as model/report quality signals, not as raw compiler errors.

Severity thresholds are configured by the consumer project.

Generated diagrams are review aids for structure and flow. Source links depend on repository configuration; when source-browse URLs are configured, the report links to the exact commit used for the build.

If a diagram appears inconsistent with the tabular source/sink result, treat it as an analyzer or renderer issue and inspect the generated analysis artifacts.

23 October 2026