STIG Help

Change sync instruction

This is the canonical repository-owned workflow for STIG development submissions. It is followed directly from AGENTS.md; no installed Codex skill or plugin is required. The four numbered requests are path 0 submit through path 3 submit; commit path N remains an alias. Each changed repository gets its own commit with Commit-Path: N. For a terminal-guided PhASAR and STIG workflow, use scripts/submit.sh --interactive as described below.

  • Path 0: sync with PhASAR pin synchronization — stage/commit, pull with rebase, and push, without verification gates.

  • Path 1: sync with quick checks and PhASAR pin synchronization.

  • Path 2: sync with full checks and pin synchronization, without changelog edits.

  • Path 3: sync with full checks, pin synchronization, changelog review/update, and an explicit increment* marker.

scripts/submit.sh --help prints the comparison table. Paths 0–2 do not author changelog changes. Preserve any existing user edits; the runner still stages all intended changes in its configured repositories.

Before every submission: decide which new files belong in Git

Inspect each new file before submission. Stage files clearly required by the authorized work with git add -- <path>, including intended source, documentation, and necessary regression tests. Ask the user only when a file's intended role or suitability for Git is uncertain, especially for binaries, examples, fixtures, or potentially temporary files. A known, required new file does not need another confirmation. Ignore files only under an established repository policy or an explicit user choice, using .gitignore (shared) or .git/info/exclude (local). A new .gitignore must itself be staged if it belongs in the repository. These undecided files are untracked, not merely unstaged edits to files Git already tracks. Interactive mode asks for those decisions itself, one file at a time. Numbered paths require them before invocation.

Every path and pending-run resume first lists untracked, non-ignored files in all configured repositories using git ls-files --others --exclude-standard. If any exist, the runner stops before staging, committing, rebasing, or pushing any repository. It does not create a new submission checkpoint for this refusal. Agents must not use blanket git add -A or new ignore rules just to clear the refusal. Apply the file review above and ask only about uncertain files; an authorized submission includes adding files whose intended role is clear.

Tracked edits and deletions need not be staged in advance. The runner uses git add -u and includes new files already in the index. It stages the full current contents of tracked files, including partially staged files. It checks again before each commit so files created during a build, Graphify update, or concurrent edit require the same decision. Ignored files remain excluded, and git add -u cannot sweep in a new untracked file that appears between the check and staging. After resolving the listed files, repeat the command or use the printed resume command.

Reading map

Read the route for the requested operation, not every linked manual.

Request

Read

Path 0

Before every submission and Path 0 submit below; run the script's file preflight, Git sync, and pin refresh only

Paths 1–3, new submission

Repository roles, PhASAR ordering, verification, checked submission sequence, and the selected path below; Submission execution once

Path 3

Also Changelog writing, the complete release review window, and path 3's release-marker and whole-release subject rules

Standalone build

The requested checkout/task guidance and Waiting for builds in Submission execution; no submission preparation

Resume a checked submission

The saved checkpoint first; revalidate changed inputs and resume the pending step

Local sync

Local sync only

CI publication, versioning, or a concrete failure

The specific referenced documentation needed for that question

The selected path determines the gates; the execution guide determines reading, waiting, diagnostics, and handoff. Use the current source checkout's guidance. Do not load consumer skills, general report manuals, or a graph query merely because a known submission gate uses Gradle or generates HTML. A concrete engineering question during review or repair may need its own scoped documentation, skill, or Graphify query.

Scripted submissions

scripts/submit.sh implements interactive mode and the four numbered paths in one Bash file. Its path_0 through path_3 functions contain only calls to shared step functions, so their order is visible in one place. Run it from the STIG checkout; it does not require an agent, an AI service, or editing a dependency commit ID by hand.

Interactive submission

./scripts/ci.sh # Or invoke the underlying workflow directly: ./scripts/submit.sh --interactive # Accept every default without terminal input, including commit messages: ./scripts/submit.sh --interactive --default # Also initialize, repair, or refresh Graphify in every visited checkout: ./scripts/submit.sh --interactive --default --graphify # The local consumer wrapper accepts the same option: ./scripts/ci.sh --interactive --default # Optional consumers can be sibling names or explicit checkout paths: ./scripts/submit.sh --interactive --consumer stig-product --consumer ../stig-other

scripts/ci.sh (also accepting --interactive) starts this interactive workflow. It also reads repeated stig.ci.consumer entries from this checkout's local Git configuration. For example, git config --local --add stig.ci.consumer /path/to/stig-product adds a private consumer to future ci.sh runs; --consumer can still supply additional checkouts for one run. Keep these paths local rather than adding private project names to the public script.

This mode uses the PhASAR sibling beside the canonical STIG checkout containing the script. It needs no saved repository-role configuration. After PhASAR and STIG, it offers each supplied --consumer, followed by the public stig-project template and stig-robot example. Private consumer names belong in the invocation or local Git configuration, outside the public script. Until stig-robot is initialized, decline it or leave its checkout path blank. Explicit consumer paths are used directly. For each consumer named without a path, it checks only the named siblings of the invocation checkout, the script's logical checkout path, and the canonical STIG checkout. A missing or ambiguous checkout requires an explicit path; blank skips it. Canonical paths are deduplicated. Each consumer uses its configured STIG source; published consumers need no sibling checkout. To use the private sibling layout, invoke the script from that consumer, for example ../stig/scripts/submit.sh --interactive --consumer stig-product from stig-product. It guides the following sequence:

  1. Fetch the configured upstreams and display PhASAR's Git status, including staged, unstaged, untracked, and unpushed changes. List new files and offer A to add all remaining listed files, or y/n for individual files. Then ask before staging tracked edits/deletions, creating a commit, pulling with rebase, and pushing, in that order. The commit summary is entered at the terminal.

  2. Display STIG's status and ask about its new files. If it has changes, offer a preparation commit without a release marker, then ask to pull with rebase. A clean checkout still pulls. Declining a needed preparation commit or the pull stops STIG processing before dependency updates, cleanup, and verification.

  3. Run scripts/update-phasar-pin.sh even when PhASAR had no changes. The updater requires a clean PhASAR checkout whose HEAD matches the published stig-patches-2026.06 tip; refusing a needed PhASAR commit or push can therefore prevent pin synchronization.

  4. Ask whether to run scripts/update.sh --major, --minor, or --patch, or skip dependency updates (default). This source-maintainer updater is separate from the consumer stigUpdate task and from the STIG release choice. Its existing prompts and output remain interactive. It can also update the public template's wrapper and dependency-verification files; the final stig-project prompt lets you submit those changes.

  5. Offer ./gradlew cleanup. Display its normal output directly, without adding Gradle flags or redirecting it to a command log. Cleanup also regenerates third-party notices. Independently of that choice, refresh notices with ./gradlew generateThirdPartyNotices --console=plain --info after updating dependency pins on the rebased sources, then run ./gradlew :stig-gradle-plugin:syncJavaBootstrap --console=plain --info. The checked-in bootstrap embeds those notices, so a native dependency pin change also requires this regeneration. Both steps run when cleanup is skipped. Refresh an existing Graphify graph after source changes, and ask about any new files produced by these steps.

  6. Offer ./gradlew preReleaseCheck, defaulting to No, with the same normal output. On Linux, the script starts a private 1920×1080 Xvfb display for this gate, including on Wayland and headless hosts. Install xvfb-run, Xvfb, and Xauthority before running the gate; missing display support stops verification. No manual display wrapper is needed. A failed selected command stops the workflow with its exit code. Source changes during verification require another run.

  7. Ask for major, minor, patch, or none (default). A release choice adds incrementMajor:, incrementMinor:, or incrementPatch: to the entered STIG commit summary. If pre-release verification was skipped, offer it now; a release marker requires a successful check of the current sources. An explicitly requested release can create an empty commit when needed. Existing unpushed release markers require a matching explicit release choice.

  8. Show STIG's final status, ask again about any new files, and ask before staging, creating the final commit, and pushing. There is no second STIG pull/rebase after verification. The commit preview shows the staged diff summary and exact subject. Declining commit or push leaves the approved staging or local commit available for later use.

  9. When patch, minor, or major was selected, end the local workflow after the STIG push. Publication CI dispatches the configured consumers' update jobs, which select the latest published STIG release, verify, commit, and push their updates. Leave local consumer edits untouched while those jobs run. Successful dispatch only means GitLab accepted the requests; check each consumer job's result before synchronizing its checkout. Local --consumer options and stig.ci.consumer entries do not register GitLab release triggers. A consumer absent from the protected STIG_USER_PROJECTS list receives no automatic update. After consumer CI succeeds, synchronize the desired checkouts before any local verification. A later interactive run with release choice none can perform the normal consumer verification and submission workflow. With release choice none, offer consumer verification → add/commit → pull with rebase → push for the requested consumers, stig-project, and stig-robot, separately, using their configured STIG source without updating it. Model consumers offer version (default) or html: ./gradlew stigPrintVersion --console=plain --info verifies that the build configuration loads and reports the selected STIG source and loaded plugin version; ./gradlew stigGenerateHtml --console=plain --info generates the report and can run native source analysis. Application consumers (stigUpdateProfile=application) report the configured stigToolchainVersion and offer tasks (default) or check instead. tasks runs ./gradlew tasks to load the build and list available tasks; check runs the explicit stigApplicationCheckTasks. Both use --console=plain --info. Neither choice runs stigUpdate. A failed selected verification stops before committing or pushing that consumer. After verification, refresh its existing Graphify graph and use the same new-file, staging, commit-summary, rebase, and push prompts. Declining a consumer leaves its checkout untouched.

Every approved pull uses git -c rebase.autoStash=false pull --rebase --no-autostash with the configured upstream, including for a clean checkout with no local commits. After the first successful rebase, offer latte setup-graphify in that checkout, defaulting to No. This applies to PhASAR, STIG, and every visited consumer. Setup uses the rebased files; its changes follow the usual new-file and commit prompts. Then offer another pull/rebase before continuing, without offering setup again. The sequence is preparation commit → pull/rebase → optional setup → setup commit → pull/rebase → remaining work and push. Both STIG pulls finish before dependency updates and verification. A successful setup supplies the graph refresh for that rebase, so unchanged sources do not trigger another AST refresh. A selected setup failure stops the workflow with its exit code. Use --graphify to run setup in every visited repository without answering the setup prompt, including with --default. Latte initializes a missing index, repairs an incomplete or broken local setup, or refreshes an existing index. The flag requires --interactive; it does not visit consumers deferred by a release choice. With the flag, preparation commits retain the existing graph and defer AST refresh until setup has run after the first pull, allowing Latte to repair a broken index before ordinary incremental refreshes resume. Remaining uncommitted changes skip pull and push; for STIG they also stop the workflow before cleanup and verification. If all conflicts are in the generated Graphify outputs, interactive mode automatically restores the upstream output set and continues the rebase. This covers graph.json, manifest.json, GRAPH_REPORT.md, graph.html, .graphify_labels.json, and .graphify_labels.json.sig under graphify-out/. All six outputs come from the original rebase target, including files that merged cleanly, so the manifest and graph remain consistent. A commit left empty by this resolution is skipped. Source conflicts, saved Graphify notes, and other conflicts stop for manual resolution without changing any conflicted files. The script never auto-stashes, aborts conflicts, or force-pushes.

Git hooks remain enabled. Rebase and its continuation use the Graphify hook guard, then an existing graph is refreshed if source content changed or upstream graph outputs were restored. Restoring outputs invalidates any earlier graph refresh, even when the source content is unchanged. Any resulting files require the usual add/commit choices before pushing. This automatic conflict handling applies only to interactive mode; numbered paths retain their existing failure and review workflow.

STIG's order is preparation commit when needed → pull/rebase → PhASAR pin and dependency updates → cleanup → notice, bootstrap, and graph refresh → preReleaseCheck → release choice and final commit → push. Cleanup and verification therefore use the rebased sources. Review and commit any pin, cleanup, or graph changes through the same prompts. If upstream advances again before pushing, Git rejects a non-fast-forward push; the script does not rebase after verification. Rerun the workflow to synchronize before checking again. Commands keep their normal terminal output, including both plain Gradle invocations. Git status, diff summaries, whitespace checks, and commit lists explicitly disable paging, so a configured pager such as less cannot pause the workflow for keyboard input, including with --default.

New-file prompts use [A/y/n/q]: Enter or a adds all remaining files from the displayed list in that checkout; y adds just the current file; n offers an exact local ignore rule in Git's info/exclude. The bulk choice uses literal paths from that list, excludes tracked edits and ignored files, and does not carry over to later lists or other repositories. A new file appearing after the list was displayed still requires a separate decision. Declining both add and ignore stops for a file decision. Tracked files use git add -u; partial staging is replaced by the full current contents only after the staging prompt is accepted.

If git diff --cached --check reports whitespace errors, offer a Git-only repair and retry. This fixes whitespace introduced by the staged changes, including extra blank lines at EOF and trailing spaces, without running the full cleanup task. Prepare the correction in a temporary index, validate it, then apply it to the working tree and staging area. Unchanged lines retain their existing whitespace. A successful repair refreshes Graphify and offers to repeat any previously selected preReleaseCheck; declining that renewed check stops before committing. Declining the repair, quitting, or ending input leaves the staged changes available for manual correction. Errors Git cannot repair, such as conflict markers, still stop the workflow.

Other yes/no confirmations use [Y/n/q], so Enter accepts staging, committing, pulling with rebase, pushing, required verification, or visiting a consumer. The latte setup-graphify prompt, ./gradlew cleanup, and the initial optional ./gradlew preReleaseCheck prompt use [y/N/q], with Enter declining them. Dependency-update and release-level menus retain their explicit choices and skip/none defaults. A displayed default takes effect when Enter is pressed; q quits and end-of-input stops without answering further prompts. With --interactive --default, the runner supplies every displayed default without reading terminal input: staging, new-file bulk addition, commits, rebase and push are accepted; commit messages use Update <repository>; dependency-tool updates are skipped; Graphify setup is declined unless --graphify is supplied; cleanup and optional pre-release verification are declined; the release choice is none; consumer verification is version for models or tasks for applications. Missing or ambiguous checkout paths default to skipping that consumer. An existing unpushed release marker that needs an explicit release choice stops this mode instead of selecting a release automatically. --default requires interactive mode; ci.sh forwards it to the same runner. Git hooks remain enabled; a completed Graphify refresh uses the documented hook guard for its commit.

Graphify output is enclosed by a labeled index-refresh start and finish. This is a one-time code-navigation index update, not a Git commit or compilation. AST extraction reports parsing progress; not classified identifies unsupported file formats; parser syntax errors warn that some symbols or relationships may be missing from the index. They are not compiler diagnostics. No code-graph topology changes means the extracted relationships stayed the same, so existing graph outputs were retained. The code-only refresh needs no API key; documentation/image processing tips describe separate optional work. Tool output, warnings, and failures remain visible unchanged. Commit previews explicitly label the proposed new subject, and push previews label existing local commits and their recorded subjects.

Interactive mode has optional local STIG checks and, without a release, optional consumer submissions with a version/HTML choice for models and tasks/check for applications. A selected STIG release hands consumer updates and verification to GitLab CI. It does not create numbered-path review checkpoints or Commit-Path trailers, run the numbered paths' consumer gates, or choose a release automatically. After Maven publication, GitLab release CI triggers the configured user projects' update pipelines; each project's CI controls its checks and publication. The regular Git push can still reject a concurrent upstream update after the rebase. It rejects combination with numbered-path, resume, configuration, or release command-line options. The numbered paths below keep their existing gates and review/resume behavior.

Configure numbered submissions

Configure the checkout roles once, using paths whose roles you have confirmed from their repository guidance:

./scripts/submit.sh --configure \ --phasar ../phasar \ --template ../stig-project \ --product /absolute/path/to/product-consumer # Optionally add --consumer /absolute/path/to/another-in-scope-consumer (repeatable).

These directory names are examples, not role detection. STIG is the checkout containing the script. Canonical paths are deduplicated, including when the template is also the requested product. The configured consumers must resolve their documented ../stig sibling to this STIG checkout; configured PhASAR must be the ../phasar checkout used by STIG. The runner does not rewrite Gradle configuration or change branches. If there is no local PhASAR sibling, use --no-phasar instead of --phasar. Template and product roles remain required.

Configuration is stored in stig-submit/config.json under STIG's resolved Git metadata directory, including for a Git worktree. Re-run --configure to change roles for future runs. Existing runs keep their saved configuration. The runtime prerequisites are Bash 4.4+, Git, jq, flock, and rg, plus the selected repositories' normal build tools and Graphify where required by their source-change rules. No toolchain fallback is introduced.

./scripts/submit.sh --path 0 --message "Commit message foo bar" ./scripts/submit.sh --path 1 --message "Commit message foo bar" ./scripts/submit.sh --path 2 --message "Commit message foo bar" ./scripts/submit.sh --path 3 --message "incrementMinor" ./scripts/submit.sh --path 3 --increment minor --message "Release summary"

The final example uses STIG subject incrementMinor: Release summary. Sibling subjects use Release summary, without the marker. With a marker-only request, sibling subjects are Synchronize changes. Path 3 requires an explicit marker or --increment patch|minor|major; paths 0–2 reject release markers. A clean STIG tree can still receive the explicitly requested empty release-trigger commit, after verification. Resuming does not duplicate an already-prepared empty trigger. Path 0 defaults to Snapshot current state when no message is supplied.

Optional local CI toolchain checks

Paths 2–3 accept --local-container-checks on|off, defaulting to off for new runs. Routine submissions retain the full host and consumer verification gates without also rebuilding the Fedora CI image and repeating its jobs locally. GitLab image, build/test, compatibility, and release gates remain mandatory and unchanged.

Opt in when debugging toolchain/CI changes locally or when GitLab is unavailable:

./scripts/submit.sh --path 2 --message "Verify toolchain fixes" --local-container-checks on ./scripts/submit.sh --path 3 --increment minor --message "Release summary" --local-container-checks on

With on, the runner executes ciToolchainImageBuild then ciToolchainCheck after cleanup review and before preReleaseCheck. The first builds/refreshes the current content-derived Fedora image locally without publishing; the second runs ciBuildAndTest in that image. Both must pass. Matching image layers can be reused, but changed pins may require expensive rebuilds. The disposable check workspace does not reuse the host's incremental outputs. An enabled container check fails normally if the runtime or image is unavailable; it does not silently skip.

This option controls only those two CI toolchain tasks. Host verification, consumer builds, documentation checks, and Qodana remain required, including containers used internally by documentation or Qodana. It does not make a submission offline: Git synchronization and uncached dependencies still require their usual access.

An AI agent must leave the default off unless the user explicitly asks for local CI container work, for example: "Path 3 submit, increment minor, with local container checks." Do not infer opt-in merely from changed CI files. Paths 0–1 and repository configuration reject this option.

Resume keeps the recorded mode. Older checkpoints without a mode retain their former on behavior. To change an unfinished run before STIG has been pushed, pass the option explicitly:

./scripts/submit.sh --resume run-<the-printed-id> --local-container-checks off

The checkpoint records the change and preserves completed results and failure logs. Disabled tasks are marked not required, never passed; any recorded failure still needs its cause/correction review. Enabling the mode adds the required gates without discarding valid host/consumer results. A mode change after STIG is pushed or the run is complete requires a new submission; an ordinary resume never changes the saved choice.

Invoking a path authorizes staging all tracked edits/deletions and including explicitly added new files in its configured repositories, committing, rebasing on each current branch's configured upstream, and pushing. The runner does not decide which untracked files to add or ignore, stash changes, resolve conflicts, force-push, or repair failures automatically. Detached HEADs, unfinished Git operations, dirty submodules, or a changed branch/upstream stop checked submissions. An invocation lock prevents two runners from using the same STIG checkout concurrently.

Review, failure, and resume

Checked paths save checkpoint.json, review.md, source/history patches, and complete command logs under stig-submit/runs/<run-id>/ in Git metadata. They print each command's log link; the log records the exact command, working directory, stdout, and stderr. Execution is quiet by default. These runtime files are not staged into the source repositories.

Paths 2–3 run generateThirdPartyNotices after PhASAR pin synchronization, then cleanup, review their mutations, and run preReleaseCheck and the consumer gates. Notice generation is a logged preparation step, not a replacement for verifyThirdPartyNotices inside preReleaseCheck. It also runs on pending resumes before STIG is pushed, using Gradle's normal up-to-date behavior, so a newly refreshed pin cannot leave stale committed notices. Paths 0–1 do not add this full-verification preparation. The optional local CI toolchain checks insert image preparation and container verification before preReleaseCheck; their failures use the same repair review and resume process as other gates.

When human or AI judgment is needed, the runner exits successfully with status 0 and emits a STIG_SUBMIT_EVENT JSON line with event: "review_required" (or "paused" for a continuation without a pending review). It also writes the same object to event.json beside the checkpoint and prints the review file and resume command. This process-completion event returns control to the caller; the runner does not wait or poll for AI approval. The caller should await process completion, not poll logs or repeatedly resume a running process. Host notification and update limits still apply; a shell event does not itself invoke an AI agent.

Exit 0 does not by itself mean submission complete. Check event: "complete" means the submission finished; "review_required" and "paused" require continuation. Real failures emit "failed" when a checked run exists and preserve the actual nonzero exit code. The event includes run_id, exit_code, checkpoint, the pending review path when applicable, and the last command log path. Review the evidence, make required source/documentation corrections, and record findings in review.md. Only on path 3, review/update the changelog and set Changelog: updated or Changelog: not-needed according to Changelog writing below. Paths 1–2 use Changelog: not-required and do not edit CHANGELOG.md. Approval is the exact line Decision: approved:

./scripts/submit.sh --resume run-<the-printed-id>

If source changed since that review was created, the first resume archives it and produces a fresh review snapshot; approve that snapshot and resume again. The file names the repository groups needing renewed review and links the retained findings for unchanged groups. New source-changing commits also renew history review, even when their final tree matches the earlier tree. Review approval also covers the saved history baseline: an older path-3 run that started at a path-2 commit is widened to the preceding release and reviewed again. This does not discard unchanged build results or let a release commit prepared by that run become its own review baseline. The runner never evaluates the review or checkpoint as shell code. Ask an AI to help edit/review the named files if useful; this first version does not call an AI service itself.

AI execution and additional builds

An instruction to submit on path 0, 1, 2, or 3 authorizes the AI to run scripts/submit.sh, inspect completed step results, review the evidence, repair failures within the requested scope, and continue to completion. Reuse the saved repository configuration and user decisions. The script owns command execution and checkpoints; do not reimplement its checked paths as a second agent-authored sequence.

The successful review_required exit is a review event for the person or AI doing the submission, not completion. An AI should carry out the required review, record concrete findings and Decision: approved when justified, and execute the printed resume command. It must not approve blindly or return to the user solely because the runner needs a review. After source edits, refresh the snapshot before approving it. A failed submission operation or gate requires focused diagnosis, correction, and renewed checks; record Cause: and Correction: and resume. Resolve routine repairs and clear rebase conflicts using the existing authorization. Ask the user only for a missing release marker, an ambiguous change, or a decision beyond that scope.

During commands the runner prints log links, keeping command details, stdout and stderr inside those complete logs. On failure it identifies the failed step and preserves its exit code without dumping a stack-trace tail. Use the terminal event, exit status, and log links printed by the runner. Wait for a command or step to finish before reading its results; do not tail logs repeatedly to produce status updates. Follow Submission execution for quiet waiting, bounded failure diagnostics, and retained gates.

A separate request to build a project such as stig-project authorizes that checkout's requested Gradle task and in-scope repairs, without a submission or changelog edit. Resolve the actual checkout, run the requested task, wait for completion, and check its exit status under the same execution policy. If a build is additionally requested as part of a submission, complete it before the affected push, retain its input state/result, and renew it only when those inputs change. Extra builds do not select another submission path or a release marker.

Every failed submission operation or verification gate stops the run with its actual exit code and a log link. Read bounded failure evidence from that log. A resume requires a repair review with Cause: and Correction: before retrying. Record focused evidence and any test/contract decisions in its findings; do not approve an unexplained retry. Rebase conflicts must be resolved explicitly outside the runner. An interrupted command whose recorded process is still alive is not restarted or killed by resume.

Gate inputs include effective source content, untracked non-ignored files, tag state, and configured local STIG and PhASAR dependency states. The user's index is not changed by fingerprinting. Source/dependency changes invalidate affected results; generated graphify-out/ changes alone do not invalidate Gradle gates. Cleanup records its resulting source state and pauses for mutation review. Rebased input changes require renewed evidence before push. Once STIG is pushed, that run freezes its STIG/PhASAR input revisions and can finish remaining consumers; further changes to those published inputs need a new run.

On checked paths 1–3, changed local PhASAR is verified through the existing pinned native build/test driver, with the configured checkout passed explicitly:

bash ./stig-code-analyzer/scripts/build-analyzer.sh --local-phasar /configured/phasar --run-analyzer-tests

It must succeed before PhASAR is committed/pushed on those paths. The helper scripts/update-phasar-pin.sh then writes its clean, published commit ID before STIG gates. Path 0 also invokes that helper after the PhASAR push and again after rebasing STIG, committing any resulting pin correction before pushing STIG. The helper remains available as a standalone command; its clean-checkout and published-commit validation is shared by every path. Use --skip-phasar-pin only on a new checked run for an explicit opt-out; it is saved and reported. The runner prepares Graphify before checked commits and suppresses the redundant asynchronous Graphify post-commit hook without disabling the other checked-path hooks. Path 0 has no review or checkpoint and uses its file preflight, Git synchronization, and pin refresh without verification gates.

CI observation after checked submissions

After all repositories have been pushed on paths 1–3, the runner invokes gitlabCtrl --action ciStatus for the checkpoint's exact submitted STIG SHA, not a subsequently moving HEAD. This is an advisory snapshot, without waiting for pipeline completion. Path 0 performs Git synchronization and pin refresh without querying CI.

The observation saves its JSON and available failed-job traces in a fresh directory under the run's ci/ directory. The checkpoint's ci entry retains the commit, observed status/outcome, pipeline URL, actual command exit code, and report/log paths. A failed pipeline, missing pipeline, authentication error, or unavailable API is reported separately from successful pushes and local gates. An observation failure neither fails the completed submission nor invalidates passed gates, and no CI failure is silently presented as success.

Resume retains an already-recorded observation for that commit. If observation was interrupted before it was recorded, resume checks that its process is no longer running, then makes a fresh attempt without a repair-review pause. Each attempt uses a new output directory so an old report cannot be mistaken for fresh evidence. Resuming a completed run does not refresh CI or repeat submission commands.

To refresh the result or explicitly wait, run from STIG:

./gradlew gitlabCtrl --action ciStatus --commit <submitted-sha> ./gradlew gitlabCtrl --action ciStatus --commit <submitted-sha> --wait ./gradlew gitlabCtrl --action ciLog --commit <submitted-sha>

See Inspect CI for a submitted commit for status/log semantics, polling controls, and the structured report. These later commands produce fresh evidence without changing the completed submission checkpoint.

Reporting CI does not by itself authorize source fixes, job retries, pipeline triggers, or another push. Report the failure and evidence; repair and resubmit only when the user requests that work. Honor an existing explicit request to repair/resubmit without asking for routine approval again, and use a new checked submission for changed published revisions.

Path 0 submit: sync and pin refresh without verification gates

A path-0 request first applies Before every submission: inspect untracked, non-ignored files, stage clearly intended files, and ask about uncertain ones. Once those choices are recorded, no further confirmation is needed. The runner stages, commits, rebases, and pushes each repository's current branch and configured upstream in phasar/ → stig/ → stig-* consumer order:

git add -u git -c core.hooksPath=/dev/null commit -m "Snapshot current state" -m "Commit-Path: 0" git -c core.hooksPath=/dev/null pull --rebase git -c core.hooksPath=/dev/null push

Include explicitly added new files and stage tracked changes and deletions as they stand. Use Snapshot current state by default, or substitute the user's explicit --message subject; do not inspect changes to compose one. If commit reports nothing to commit, continue with pull and push without an empty commit. The command-local hook setting disables all hooks, including Graphify, without changing persistent Git configuration.

After pushing configured PhASAR, the runner calls scripts/update-phasar-pin.sh --phasar-dir <configured-checkout> before staging STIG. The helper updates PHASAR_COMMIT in stig-code-analyzer/scripts/pins.env only to the clean, published PhASAR HEAD. After the STIG rebase, the runner repeats the pin refresh and commit before pushing STIG, so incoming STIG history cannot silently restore a different pin. An unchanged pin produces no extra commit. Without a configured local PhASAR checkout, the existing pin remains unchanged; path 0 rejects --skip-phasar-pin.

Apart from the file-selection preflight and pin helper's validation, do not run verification gates, final checks, status/diff/history/remote audits, searches, builds, tests, cleanup, documentation or skill maintenance, graph updates, checkpoint creation, usage audits, or other analysis. Path 0 overrides the general preparation, verification, monitoring, and handoff rules.

The script stops on a Git or pin-update failure. When an AI is executing the submission, inspect that failed operation, repair it when the intended result is clear, and retry the remaining sync work. Do not change branches, force-push, or add unrelated checks. Ask only when the repair requires an unresolved user decision. Report completion from command results alone. Path 0 supplies no verification evidence; its changes remain in the next path-2 and path-3 review windows.

Repository roles and checkout locations

Resolve each role once from its scoped README.md/AGENTS.md description and Git origin; record the canonical path in the checkpoint. Historical directory names are examples, not role detection:

Role

Required checkout

STIG

The tool source, normally stig/

PhASAR

The optional local fork, normally phasar/

Public template

The generic model-only consumer, historically stig-project-real-oss-template/; it may be named stig-project/

Product consumer

The requested project, such as stig-projectname/, or the template project stig-project/

Other consumer

Any other changed in-scope stig-* checkout

Follow STIG's sibling symlinks when locating the template. Paths resolving to one checkout identify one repository for verification and submission. Local STIG/PhASAR checkouts override published versions; keep this behavior. Read local multi-repo development only if the layout is unresolved.

Mandatory PhASAR-first ordering for every submit path

Every path uses PhASAR → pin refresh → STIG → consumers ordering. Path 0 skips the verification gates and uses the sequence above. For checked paths 1–3:

  1. If the sibling PhASAR branch stig-patches-2026.06 has changes, review and verify them under its repository rules, commit with the selected trailer, then push before committing or pushing another repository.

  2. From STIG, run ./scripts/update-phasar-pin.sh to set stig-code-analyzer/scripts/pins.env PHASAR_COMMIT to its exact pushed SHA. Also synchronize the pin when PhASAR is clean but its pushed HEAD is newer than the pin.

  3. Run STIG's selected gates with that synchronized pin, then submit STIG before consumers.

Never pin a dirty tree, an unpushed commit, or a branch name. Skip the pin refresh only when the user explicitly requests it; preserve that decision in the checkpoint and final summary. The early local template commit described below is a verification step and stays unpushed until STIG has been pushed.

Required verification and failure handling for paths 1, 2, and 3

Every checked submission runs the named template and product-consumer gates even when those trees are clean. A clean consumer can still be broken by a STIG change. Path 1 uses quick checks for all Gradle repositories; paths 2–3 use full compatibility checks.

Repository

Path 1

Paths 2 and 3

STIG

./gradlew quickCheck

Generate third-party notices, cleanup, review, then preReleaseCheck; CI toolchain checks only on explicit opt-in

Public template

./gradlew stigQuickCheck

./gradlew build, clean local commit when changed, then ./gradlew stigGenerateHtml

Product consumer

./gradlew stigQuickCheck

./gradlew build

Other changed consumer

./gradlew stigQuickCheck

Its normal full build

Resolve the actual checkout for each role before using these commands. If a required checkout is missing, record its gate as not run; the path is incomplete unless the user explicitly waives that repository.

For STIG's ordered gates, use:

./gradlew --non-interactive --no-configuration-cache generateThirdPartyNotices --console=plain --info ./gradlew --no-configuration-cache cleanup --console=plain --info # Review cleanup mutations before continuing. # Only when --local-container-checks on was requested: ./gradlew --no-configuration-cache ciToolchainImageBuild --console=plain --info ./gradlew --no-configuration-cache ciToolchainCheck --console=plain --info # Always required: ./gradlew --no-daemon --stacktrace --no-configuration-cache preReleaseCheck --console=plain --info

cleanup already runs cleanupCheck. preReleaseCheck includes the complete STIG build and every subproject's build, unit/functional/integration and viewer tests, cleanupCheck, notice and coverage checks, both documentation gates, and IDEA-plugin verification. Do not add standalone build, test, integrationTest, or cleanupCheck without a concrete diagnostic, changed-input, or user-requested reason.

Path 1's quickCheck checks repository-wide IDEA formatting, every subproject's main compilation, and :stig-docs:ideaTourSourceCheck; it omits tests, assemble, the MP4 render, mutating cleanup, Writerside, and plugin verification. The consumer stigQuickCheck also omits tests and assemble. Paths 2–3 reach the tour render, verification, staging, and Writerside inspection through preReleaseCheck. These differences do not change the selected template/product gates above.

Template commit before HTML verification

Report tasks allow dirty source by default; paths 2–3 verify the template from a clean local commit. When it has intended changes:

  1. Run its ./gradlew build.

  2. Review the complete diff and run git diff --check.

  3. Create its final local commit with Commit-Path: N.

  4. Run ./gradlew stigGenerateHtml against that clean commit.

Keep the commit local until PhASAR, when applicable, and STIG have been pushed. A later template correction requires an amended or corrective local commit and renewal of the gates whose inputs changed.

Failures and renewed verification

Investigate every failed gate, fix its producing source, and rerun it plus each later gate invalidated by the fix. Fix mechanical conversion or migration errors directly. For a real or suspected bug, determine the root cause and implement a durable in-scope fix, with regression tests or contract checks when they provide meaningful evidence. Record any separate technical-debt work. Reuse decisions and authorization already given in the request or checkpoint; ask only when the correction needs a material choice outside that authorization. Finish the repair and required verification before declaring completion.

A passing unexplained retry is insufficient. Record the cause, correction, and renewed evidence. The execution guide defines how to retain valid results while marking affected gates stale.

Checked submission sequence

Use this sequence for the selected path 1–3; the path sections below supply only their differences.

  1. Record the path, user-specified release marker when required, requested scope, permissions, and resolved repositories in the compact checkpoint. Reuse current user decisions. A preparation-only request never authorizes commit or push.

  2. Review in-scope changes. Path 1 starts at each branch's upstream. Path 2 starts at the latest Commit-Path: 2, 3, or historical 4 commit. Path 3 starts at the latest Commit-Path: 3 or historical 4 commit, so earlier path-2 changes remain in its release window. Review every later commit plus staged, unstaged, and untracked changes within the agreed scope, including changes made by other threads or the user. For older history without matching trailers, bootstrap from STIG's latest CHANGELOG.md commit and corresponding sibling history. Record reviewed groups so a resume does not repeat them.

  3. Only for path 3, apply Changelog writing to the complete release window. Paths 1–2 do not edit the changelog. Update other affected documentation and contributor guidance when needed. Resolve concurrent edits without discarding them; use an isolated checkout only when needed to preserve an agreed submission snapshot.

  4. Complete the PhASAR submission and pin synchronization before STIG gates. On path 1, stage/commit and pull with rebase in the Gradle repositories before quick checks; review any rebase changes. Run the selected STIG gates, including cleanup mutation review on paths 2–3. Follow Local IDEA and server behavior.

  5. Run all remaining compatibility gates in the table, including the template's commit-before-HTML sequence. On failure, use bounded diagnostics, fix and renew affected evidence, then continue from the pending gate.

  6. Review and stage the complete final diffs; run git diff --check. Prepare Graphify once under the repository's source-change/hook rules. Commit each remaining changed repository with its path-specific subject and trailer, using the repository author without AI/tool attribution; push in PhASAR → STIG → consumer order. If a rebase, conflict resolution, or later edit changes verified inputs, renew affected gates before pushing.

  7. Observe CI for the recorded submitted STIG SHA without waiting, as described in CI observation after checked submissions. Record submitted SHAs, gate results, repairs, CI evidence, and any waived or unverified work in the checkpoint and concise final summary. Local gate success and push success do not establish CI publication; report its state separately.

Path 1 submit: quick checks with sync

Use the path-1 verification column and Commit-Path: 1. Use normal descriptive commit subjects; no release marker. After PhASAR verification/submission and pin synchronization, stage/commit and pull with rebase before running STIG quickCheck and the selected consumers' stigQuickCheck. Review changed inputs and pass all required quick checks before pushing STIG, then consumers. A later rebase or source edit renews affected checks before push. Do not edit CHANGELOG.md. Path 1's changes remain in the next accumulated path-2 and path-3 review windows. Add focused tests when required by a repair, the user, or the evidence needed for the change; full builds run only when separately requested on this path.

Path 2 submit: full checks with sync

Use the paths-2–3 verification column, the accumulated source review since the previous full submission, and Commit-Path: 2. Use normal descriptive subjects and no release marker. Do not edit CHANGELOG.md; its review field is Changelog: not-required. These changes remain in the next path-3 changelog/release review window.

Paths 2–3 refresh third-party notices, finish cleanup, then run the mutating stig.syncJavaBootstrap gate before reviewing those generated changes and starting verification. The bootstrap includes the current notices and cleaned source. preReleaseCheck remains read-only and verifies its exact bytes.

Path 3 submit: full checks, changelog, and release sync

Use the paths-2–3 verification column and the full release window, including prior path-2 submissions. Review/update the changelog under Changelog writing. The user must name exactly one STIG marker: incrementPatch, incrementMinor, or incrementMajor. Never infer it or ask for it again after it is recorded. If it is missing, ask once while continuing authorized review and preparation; wait for the answer before creating the release-trigger commit.

The STIG subject is the marker alone or <marker>: <summary of the complete accumulated release window>. An optional summary describes the whole release, not just its latest fix. All commits use Commit-Path: 3; PhASAR and consumer subjects do not contain the STIG release marker.

Changelog writing

Submission changelog work applies only to path 3. The same writing policy applies to an explicitly requested standalone edit of CHANGELOG.md. The changelog serves people installing, upgrading, configuring, and using STIG; it also supplies the public release notes and JetBrains Marketplace's What's New text. Review the complete multi-repository change window, then select the notable effects on those users. A submission with no such changes does not need a changelog entry.

  • Include features, fixes, analysis-result changes, performance, supported platforms, public APIs/DSLs, model rules, security, licensing, deprecations, and removals that affect STIG users. An internal analyzer fix belongs here when it changes results or reliability; explain the affected behavior.

  • Include a PhASAR or consumer change only when it explains an effect of the STIG release. Keep project-specific model data, ASIL classifications, investigations, and presentations in the owning project's history or documentation. Keep refactoring, test implementation, cleanup, CI mechanics, and contributor/agent procedures in developer documentation or commit history unless they have a concrete effect on users.

  • Start each entry with what users can do differently or which failure is fixed. Normally use one or two plain sentences. Avoid bold mini-headlines, per-entry dates, implementation inventories, test narratives, and claims about verification. Keep exact task/property names when they help users act; link to detailed documentation when needed.

  • State breaking changes, changed defaults, compatibility limits, and required migration steps explicitly. Preserve documented conditions and limitations. Do not replace useful detail with vague claims such as "improved analysis".

  • Consolidate related commits into the final behavior delivered by that version. Remove duplicate entries, intermediate implementation stages, and superseded approaches within the same release. Use the existing Keep a Changelog categories, omit empty categories, and put dates on release headings only.

  • When editing published history, preserve version numbers, release dates, release membership, and historical API names and behavior. Keep version comparison links valid and point [Unreleased] at the latest released tag. Do not rewrite old entries to describe today's implementation or invent details missing from the original record. If only internal maintenance was recorded, retain the release heading with a brief maintenance note.

Before submission, read the entries as an upgrading user: each should explain a relevant change and any action needed. The full-window review and release-subject rules do not require a commit-by-commit changelog. verifyChangelog checks release structure, not editorial quality. Regenerate the public copy with generateWritersideReleaseNotes after editing released sections; do not hand-edit the generated topic.

Local sync

local sync refreshes development checkouts, the consumer fallback version, and the installed consumer plugin. Follow Local sync; it authorizes no submission, pin refresh, release marker, or submit-path gates.

Documentation channel effect

The successful default-branch CI pipeline publishes documentation. Paths 0–2 update snapshot channels; path 3 requests a new release and stable-root publication. See Documentation version channels only when those outcomes are in scope. A local successful submission does not establish that CI has published them.

Local IDEA and server behavior

Desktop IDEA Code Cleanup and Optimize Imports are optional before paths 2–3. Gradle's ideaFormat reformats; it does not run those inspection/import operations. Never run mutating cleanup in CI or another clean server workspace. CI uses releaseCoreVerification and specialized jobs; local preReleaseCheck retains the complete cleanupCheck. See source cleanup when investigating those differences.

23 October 2026