This repository hosts the reusable workflows and helper scripts that drive manual
LVCompare runs against commits in a LabVIEW project. The primary entrypoint is the
Manual VI Compare (refs) workflow, which walks a branch/ref history, extracts the
target VI at each commit-parent pair, and invokes LVCompare in headless mode.
Scope boundary: icon editor development is out of scope for this repository. The
active icon editor project lives at svelderrainruiz/labview-icon-editor.
The canonical downstream local-first adoption proof surface for VI history is
LabVIEW-Community-CI-CD/labview-icon-editor-demo on develop.
The latest rev streamlines the workflow inputs so SMEs only need to provide:
- The branch/tag/commit to inspect (
compare_ref, defaults toHEAD) - The repository-relative VI path (
vi_path)
Additional knobs remain available but defaulted so most runs require no extra tuning.
- Supported stable release line:
v0.6.6 - Future pre-release work may use
v0.6.x-rctags only when a later stable cut is being prepared - License:
BSD-3-Clause - Full compare execution still assumes the maintained self-hosted Windows +
LabVIEW + LVCompare runtime described in
CONTRIBUTING.md - This repository publishes the compare action surface and also carries maintainer/operator platform workflows; downstream consumers should start from the action contract and usage docs first
- Product boundary:
docs/SUPPORTED_PRODUCT_BOUNDARY.md - Minimal adopter contract:
docs/MINIMAL_ADOPTER_CONTRACT.md - Maintainer continuity profile:
docs/MAINTAINER_CONTINUITY_PROFILE.md - Release evidence:
docs/release/RELEASE_EVIDENCE_v0.6.6.md - Certified downstream consumer ring:
LabVIEW-Community-CI-CD/LabviewGitHubCiTemplateondevelopandLabVIEW-Community-CI-CD/comparevi-historyonmain, monitored by the weekly/manualDownstream Onboarding Feedbackworkflow plus the consumer-native release/smoke proof lanes recorded in the checked-in repo graph policy attools/policy/downstream-repo-graph.json
Use the GitHub wiki as the public entry
portal for this repository. It is curated for fast navigation and links outward to the detailed checked-in docs.
The published wiki pages themselves live in GitHub's separate wiki backing repo,
LabVIEW-Community-CI-CD/compare-vi-cli-action.wiki.git.
The authoritative documentation still lives in this repository:
docs/for runbooks, policy, and technical contractsdocs/SUPPORTED_PRODUCT_BOUNDARY.mdfor the supported public-vs-platform scope boundarydocs/MINIMAL_ADOPTER_CONTRACT.mdfor the shortest supported downstream adoption pathdocs/FIRST_CONSUMER_SUCCESS_PATH.mdfor the fastest supported path to downstream first successdocs/MAINTAINER_CONTINUITY_PROFILE.mdfor the current ownership and recovery modeldocs/WORKFLOW_CRITICALITY_MAP.mdfor maintainer workflow tiers and release-critical lanesAGENTS.mdfor future-agent operating rulesdocs/knowledgebase/GitHub-Intake-Layer.mdfor issue/PR intake guidancedocs/knowledgebase/GitHub-Wiki-Portal.mdfor the wiki-vs-repo-docs contract
- Navigate to Actions -> Manual VI Compare (refs).
- Click Run workflow.
- Supply
vi_path(for exampleFixtures/Loop.vi) and, optionally,compare_refif you want something other than the workflow branch tip. - Run the workflow. The job summary includes a Markdown table of processed pairs, diff counts, and missing entries per mode; any differences raise a warning that points at the uploaded diff artifacts.
gh workflow run vi-compare-refs.yml `
-f vi_path='Fixtures/Loop.vi' `
-f compare_ref='develop'Use gh run watch <run-id> or the rendered summary to follow progress. The
workflow uploads two artifacts:
vi-compare-manifests- aggregate suite manifest and per-mode summariesvi-compare-diff-artifacts- only present when LVCompare detects differences
comparevi-cli now executes the real history/report backend for advanced
commands instead of returning contract-only placeholder payloads:
compare rangeshells intotools/Get-PRVIDiffManifest.ps1andtools/Invoke-PRVIHistory.ps1history runshells intotools/Invoke-PRVIHistory.ps1report consolidateshells intotools/Render-VIHistoryReport.ps1andtools/Extract-VIHistoryReportImages.ps1
Successful runs write versioned JSON plus materialized Markdown/HTML/image-index
artifacts in the selected --out-dir. --dry-run remains available when you
only want the contract envelope without invoking the backend.
Validate and release lanes now also certify the extracted CompareVI.Tools
bundle across the public history mode bundle
(default,attributes,front-panel,block-diagram). That evidence is emitted as
comparevi-history-bundle-certification@v1 JSON plus a rendered Markdown
summary under tests/results/_agent/..., so downstream consumers can inspect
the exact per-mode categories without relying on collapsed warning text alone.
When the CLI runs outside a full repository checkout, point it at a helper
bundle/repo root with COMPAREVI_CLI_SCRIPTS_ROOT (or COMPAREVI_SCRIPTS_ROOT).
For local validation and automated tests, COMPAREVI_CLI_INVOKE_SCRIPT_PATH
can override the compare invoker without changing the production workflow
contract.
Use the primary committed workspace files to keep upstream, fork, and command-center operations explicit, while preserving the legacy alias:
compare-vi-cli-action.upstream-plane.code-workspacecompare-vi-cli-action.fork-plane.code-workspacecompare-vi-cli-action.command-center.code-workspacecompare-vi-cli-action.code-workspace(legacy alias for command-center)
Folder names inside those files follow plane prefixes (PLANE_UPSTREAM__*,
PLANE_FORK__*) and all included tasks pin cwd to a named workspace folder so
commands run in the intended plane.
See docs/DUAL_PLANE_WORKSPACES.md for the expected directory layout and task
usage, including the WSL distro guardrail (Ubuntu/standard distro, not
docker-desktop).
Runbook container canary promotion/rollback policy is tracked in
docs/RUNBOOK_CONTAINER_LANE_PROMOTION_POLICY.md (decision issue #663,
evidence source #662).
Release operating governance (roles, environment approvals, escalation, and incident/rollback protocol) is documented in
docs/RELEASE_OPERATIONS_RUNBOOK.md.
Each job also emits GitHub outputs pointing at the aggregate manifest, the
history results directory, the per-mode manifest summary (mode-manifests-json),
and the generated history report paths (history-report-md and, when HTML
renders, history-report-html). Downstream workflows and reusable snippets can
consume those keys to surface the Markdown/HTML report or to dispatch follow-up
automation without spelunking the artifacts. When the renderer is unavailable,
Compare-VIHistory.ps1 writes a lightweight fallback report so the Markdown
output key always resolves to a readable summary. The stable
history-summary-json facade and rendered history report now also surface the
decision statement, the newest meaningful pair, and pair chronology (refs,
subjects, and commit dates) so reviewers can answer what changed, when it
changed, and whether it matters without opening raw manifests first.
Provide the optional notify_issue input when dispatching the workflow to post
the same summary table to a GitHub issue for stakeholders.
- Comment
/vi-stageon a pull request (or rungh workflow run pr-vi-staging.yml -f pr=<number>). - The workflow stages VI pairs via
tools/Invoke-PRVIStaging.ps1, runs LVCompare on each, and posts a summary comment with staged/skipped counts, AllowSameLeaf totals, mode breakdown, and LVCompare results. A collapsible table mirrors the Markdown summary artifact and is generated bytools/Summarize-VIStaging.ps1, so it flags the compare categories (front panel, block diagram functional/cosmetic, VI attributes) that triggered for each pair and now includes a Flags column that lists the LVCompare mode(s) executed and the flag bundle applied. - Artifacts:
vi-compare-manifest(manifest + summary) andvi-compare-staging(numberedvi-staging-XX.zipbundles). Each pair’scompare/directory now includescompare-report.htmlplus acompare-report_files/folder containing the 2025 LVCompare image assets (setCOMPAREVI_REPORT_FORMAT=html-singleif you need the legacy single-file artifact). - Labels: successful runs add
vi-staging-ready(input configurable) and remove it automatically if staging fails or finds no pairs. - Flag overrides: set repository variables
VI_STAGE_COMPARE_FLAGS_MODE(defaults toreplace),VI_STAGE_COMPARE_FLAGS(newline-separated list), andVI_STAGE_COMPARE_REPLACE_FLAGSto control LVCompare ignore bundles. Even when filters are configured, the workflow also runs an unsuppressedfullpass so block diagram/front panel edits remain visible; both passes and their flag sets appear in the summary's Flags column. - Smoke coverage:
node tools/npm/run-script.mjs smoke:vi-stage -- --DryRunprints the plan;node tools/npm/run-script.mjs smoke:vi-stagepushes a scratch branch using the baked-infixtures/vi-attrpair so every run produces deterministic LVCompare output.
- The
VI Compare (Fork PR)workflow runs on every pull request that targetsdevelop, including forks. The helper uses a custom fetch action so the fork head commit is checked out safely, generates a diff manifest, stages pairs, runs LVCompare, and uploads compare reports for reviewers. - The job is read-only (no pushes or release writes) and produces the same artifact layout as
/vi-stage, giving reviewers deterministic bundles without manual staging. The workflow executes on the trusted self-hosted Windows runner (self-hosted, Windows, X64) so the same LVCompare install used in CI handles fork PRs. - Manual
/vi-stageand/vi-historydispatches accept afetch_depthinput (default20) when you need to pull a deeper history for local tests. /vi-historyartifacts now include extracted preview assets undertests/results/pr-vi-history/<target>/previews/history-image-*plustests/results/pr-vi-history/<target>/vi-history-image-index.json(schema: pr-vi-history-image-index@v1) for deterministic image lookup.- The history summary/comment renderer adds a
### Mobile Previewblock that inlines a capped set of extracted images so reviewers can scan cosmetic changes on mobile without downloading artifacts first. - Comment-size safety guards cap preview/image payload and apply markdown truncation when needed; the summarizer writes
this state to totals (
previewImages,markdownTruncated) and emits an explicit truncation note in the PR comment. pr-vi-history-summary@v1now carries additive per-pair rows underpairTimeline[]:targetPath,baseRef,headRef,classification,diff,durationSeconds,previewStatus,reportPath,imageIndexPath.- Run-level KPI envelope (
kpi) is additive and includes:signalRecall,noisePrecisionMasscompile,previewCoverage,timingP50Seconds,timingP95Seconds,commentTruncated,truncationReason. tools/Test-PRVIHistorySmoke.ps1now emits explicit hybrid gate policy metadata (schema: vi-history-policy-gate@v1): strict (requireDiff=true) violations are hard failures, while smoke (requireDiff=false) violations are recorded as non-blocking warnings for diagnostics.- Smoke runs now emit benchmark artifacts under
tests/results/_agent/smoke/vi-history/benchmarks/:vi-history-benchmark-*.json(schema: vi-history-benchmark@v1)vi-history-benchmark-delta-*.json(schema: vi-history-benchmark-delta@v1)vi-history-benchmark-delta-*.md(PR/issue-ready KPI delta comment body)
tools/Test-PRVIHistorySmoke.ps1can post KPI delta evidence comments automatically:- always to the synthetic PR (before cleanup)
- optionally to an issue via
-EvidenceIssueNumber
- To rehearse the fork flow locally, run
pwsh -File tools/Test-ForkSimulation.ps1in three passes:-DryRunshows the steps, the default run opens a draft PR and validates the automatic compare job, and-KeepBranchpreserves the scratch branch while the staging/history dispatches finish so you can inspect the artifacts.
| Input name | Default | Description |
|---|---|---|
compare_depth |
0 |
Maximum commit pairs to evaluate (0 = no limit) |
compare_modes |
default |
Comma/semicolon list of compare modes (default,attributes,front-panel) |
compare_ignore_flags |
none |
LVCompare ignore toggles (none, default, or comma-separated flags) |
compare_additional_flags |
(empty) | Extra LVCompare switches (space-delimited) |
compare_fail_fast |
false |
Stop after the first diff |
compare_fail_on_diff |
false |
Fail the workflow when any diff is detected |
sample_id |
(empty) | Optional concurrency key (advanced use) |
notify_issue |
(empty) | Issue number to receive the summary table as a comment |
These inputs map directly onto the parameters in tools/Compare-VIHistory.ps1,
so advanced behaviour remains available without cluttering the default UX.
You can run the same compare logic locally:
pwsh -NoLogo -NoProfile -File tools/Compare-VIHistory.ps1 `
-TargetPath Fixtures/Loop.vi `
-StartRef develop `
-Detailed `
-RenderReportIf LabVIEW/LVCompare is not available locally, point the helper at the bundled stub:
pwsh -NoLogo -NoProfile -File tools/Compare-VIHistory.ps1 `
-TargetPath fixtures/vi-stage/bd-cosmetic/Head.vi `
-StartRef develop `
-MaxSignalPairs 1 `
-NoisePolicy collapse `
-InvokeScriptPath tests/stubs/Invoke-LVCompare.stub.ps1 `
-Detailed -RenderReport -KeepArtifactsOnNoDiffFor a quick summary without digging through JSON, run:
pwsh -NoLogo -NoProfile -File tools/Inspect-HistorySignalStats.ps1 -VerboseBefore running with the real LabVIEW CLI, verify your setup:
pwsh -NoLogo -NoProfile -File tools/Verify-LVCompareSetup.ps1 -ProbeCliThe helper now processes every reachable commit pair by default. Supply
-MaxPairs <n> when you need to cap the history for large or exploratory runs.
Pass -IncludeMergeParents to audit merge parents alongside the mainline; the
extra comparisons surface lineage metadata (parent index, branch head, depth)
so reports and manifests call out where each revision originated.
Signal-first helpers are built in: use -MaxSignalPairs <n> (default 2) to
limit the number of surfaced signal diffs and -NoisePolicy include|collapse|skip
(default collapse) to decide whether cosmetic-only changes are emitted,
aggregated, or skipped entirely.
Artifacts are written under tests/results/ref-compare/history/ using the same
schema as the workflow outputs.
For repeated local VI-history turns on a developer workstation, this repository now exposes four explicit runtime profiles:
proofkeeps the canonical runtime truth:nationalinstruments/labview:2026q1-linuxdev-fastuses the local-only NI-derived acceleration image:comparevi-vi-history-dev:localwarm-devreuses a long-lived local Docker runtime on top of that same dev image to remove repeated container bootstrap costwindows-mirror-proofis the first Windows mirror plane:nationalinstruments/labview:2026q1-windows
The operating rule is strict:
- local acceleration is for refinement speed only
- release and CI still prove the canonical
proofplane windows-mirror-proofis proof-only in this first slice; it is not a warm or accelerated lanewindows-mirror-proofstays pinned to the canonical NI Windows image instead of allowing arbitrary image overridescomparevi-toolsremains the non-LV/tools image and is not reused for the VI-history runtime
Build the local acceleration image once:
node tools/npm/run-script.mjs history:local:build-dev-imageRun one cold local refinement turn against the mounted working tree:
node tools/npm/run-script.mjs history:local:refine -- `
-BaseVi fixtures/vi-attr/Base.vi `
-HeadVi fixtures/vi-attr/Head.vi `
-HistoryTargetPath fixtures/vi-attr/Head.viRun the same flow against the canonical proof image:
node tools/npm/run-script.mjs history:local:proof -- `
-BaseVi fixtures/vi-attr/Base.vi `
-HeadVi fixtures/vi-attr/Head.vi `
-HistoryTargetPath fixtures/vi-attr/Head.viRun the Windows mirror proof lane on a Windows host running Windows containers:
node tools/npm/run-script.mjs history:local:windows-mirror:proof -- `
-BaseVi fixtures/vi-attr/Base.vi `
-HeadVi fixtures/vi-attr/Head.vi `
-HistoryTargetPath fixtures/vi-attr/Head.viThis plane exists for early Windows-headless defect detection before any
host-native LabVIEW 2026 32-bit promotion work. It is intentionally not a
replacement for the canonical Linux proof plane.
Start and reuse the warm local runtime:
node tools/npm/run-script.mjs history:local:warm-runtime -- `
-RepoRoot . `
-ResultsRoot tests/results/local-vi-history/warm-dev `
-RuntimeDir tests/results/local-vi-history/runtime/warm-dev
pwsh -NoLogo -NoProfile -File tools/Invoke-VIHistoryLocalRefinement.ps1 `
-Profile warm-dev `
-BaseVi fixtures/vi-attr/Base.vi `
-HeadVi fixtures/vi-attr/Head.vi `
-HistoryTargetPath fixtures/vi-attr/Head.viWhen a warm runtime is already present, warm-dev now gates reuse on a fresh
heartbeat. If the existing container is stale, stopped, or running the wrong
image, the manager deterministically replaces it instead of blindly reusing it.
You can force that recovery check without starting a review turn:
node tools/npm/run-script.mjs history:local:warm-runtime:reconcile -- `
-RepoRoot . `
-ResultsRoot tests/results/local-vi-history/warm-dev `
-RuntimeDir tests/results/local-vi-history/runtime/warm-devThe local refinement facade writes:
local-refinement.json(schema: comparevi/local-refinement@v1)local-refinement-benchmark.json(schema: comparevi/local-refinement-benchmark@v1)
The unified local operator shell writes:
local-operator-session.json(schema: comparevi/local-operator-session@v1)
Use it when one local command needs to compose the runtime plane with an optional downstream review hook while keeping review-compiler ownership outside this repository:
node tools/npm/run-script.mjs history:local:operator:review -- `
-RepoRoot . `
-HistoryTargetPath fixtures/vi-attr/Head.vi `
-ReviewCommandPath C:\dev\comparevi-history\scripts\Invoke-CompareVIHistoryLocalReview.ps1The operator session records the local-refinement receipt, benchmark receipt, optional warm-runtime artifacts, and any downstream review output paths that the review hook publishes.
The warm runtime manager writes:
local-runtime-lease.json(schema: comparevi/local-runtime-lease@v1)local-runtime-state.json(schema: comparevi/local-runtime-state@v1)local-runtime-health.json(schema: comparevi/local-runtime-health@v1)local-runtime-heartbeat.json
Benchmark receipts now select the intended sample classes:
proof-colddev-fast-coldwarm-dev-repeatwindows-mirror-proof-cold
These receipts are intentionally local-first. They allow comparevi-history
and downstream consumers to reuse the same runtime planes without changing the
review-bundle semantics or the canonical CI proof surface.
The first documented downstream consumer of that split is
LabVIEW-Community-CI-CD/labview-icon-editor-demo. Use
docs/knowledgebase/CrossRepo-VIHistory.md
for the supported comparevi-history local-review/local-proof loop that
maintainers should run before opening a PR to develop.
When those consumers resolve the backend through an extracted CompareVI.Tools
bundle, prefer the exported module facade
Invoke-CompareVIHistoryLocalRefinementFacade over hard-coded script-path
invocation. When they need one composed local command surface, prefer
Invoke-CompareVIHistoryLocalOperatorSessionFacade.
For a quicker end-to-end loop:
scripts/Run-VIHistory.ps1regenerates the history results, prints the enriched Markdown summary (including attribute coverage), surfaces the first commit pairs it processed, writestests/results/ref-compare/history/history-context.jsonwith commit metadata, and renderstests/results/ref-compare/history/history-report.md(plushistory-report.htmlwhen-HtmlReport) so reviewers get a single document with author/date context, diff outcome, and relative links to the preserved LVCompare report and artifact directory whenever a difference is detected. If the renderer throws or is missing, the script falls back to a lightweight Markdown stub so downstream tooling still has a report to reference.scripts/Dispatch-VIHistoryWorkflow.ps1wrapsgh workflow runand echoes the URL to the most recent run so you can follow progress immediately.
Need a quick, local verification of LVCompare/LabVIEWCLI behaviour? Use
tools/Verify-LocalDiffSession.ps1:
# Stubbed run (no LabVIEW required)
pwsh -NoLogo -NoProfile -File tools/Verify-LocalDiffSession.ps1 `
-BaseVi fixtures/vi-stage/bd-cosmetic/Base.vi `
-HeadVi fixtures/vi-stage/bd-cosmetic/Head.vi `
-UseStub -Mode duplicate-window -SentinelTtlSeconds 10The helper writes summary JSON under tests/results/_agent/local-diff/<timestamp>/
and prints a one-line overview for each run (exit code, whether CLI was skipped,
suppression reason, and output directory). The summary JSON includes the captured
stdout/stderr snippets, sentinel path (when applicable), and snapshots of
LabVIEW/LVCompare/LabVIEWCLI processes before/after each invocation.
- Modes include
normal,cli-suppressed,git-context, andduplicate-windowso you can validate the environment and sentinel guards without waiting for CI. - For quick iterations open the VS Code Tasks palette and run either
Local: Verify diff session (stub) or Local: Verify diff session (real). The
real task will probe LVCompare/LabVIEWCLI and can be combined with the helper’s
-AutoConfigswitch (or runtools/New-LVCompareConfig.ps1) to scaffold a localconfigs/labview-paths.local.jsonautomatically when the setup isn’t ready.
To bootstrap LVCompare/LabVIEWCLI paths, run:
pwsh -NoLogo -NoProfile -File tools/New-LVCompareConfig.ps1 -ProbeThe command discovers installed binaries, prompts for overrides (or pass
-NonInteractive to accept defaults), writes configs/labview-paths.local.json,
and optionally verifies the configuration with Verify-LVCompareSetup.ps1 -ProbeCli.
Verify-LocalDiffSession's -AutoConfig parameter uses the same helper when
-ProbeSetup fails.
The helper also maintains a versions map keyed by LabVIEW release and bitness.
Detection is automatic when the LabVIEW path resembles LabVIEW 2024 (32-bit),
and you can override it with -Version <year> / -Bitness 32|64 to register
multiple installs. Re-running with -Force merges additional version entries
instead of discarding existing ones, so the config can track several LabVIEW
installations side by side. Pass -LabVIEWVersion / -LabVIEWBitness to
Verify-LocalDiffSession.ps1 (or select the new VS Code task prompts) if you
need the auto-config step to target a specific installation explicitly. The
helper always resolves the 64-bit shared LVCompare path
(C:\Program Files\National Instruments\Shared\LabVIEW Compare\LVCompare.exe)
so diff capture consistently uses the supported engine even when 32-bit
components are installed.
Pass -Stateless when calling Verify-LocalDiffSession.ps1 if you want each
run to re-discover LVCompare/LabVIEWCLI and remove the auto-generated
configs/labview-paths.local.json afterwards (a VS Code task entry is available
for this mode as well).
Need to point the tools at non-default LabVIEW/LVCompare installs? Copy
configs/labview-paths.sample.json to configs/labview-paths.json and list any
custom paths under the lvcompare and labview arrays; the resolvers consult
those entries before falling back to environment variables and canonical Program
Files locations. Run commands with -Verbose if you need to inspect the
candidate list while debugging.
For quick iteration, call tools/Run-LocalDiffSession.ps1 (or use the updated
VS Code tasks). The wrapper delegates to Verify-LocalDiffSession.ps1, then
copies the run output to tests/results/_agent/local-diff/latest/ and zips the
same payload to tests/results/_agent/local-diff/latest.zip so reports,
captures, and CLI logs are immediately available after each run (the stub task
archives to latest-stub/ / latest-stub.zip).
The helper now runs LVCompare with no ignore filters by default so the full
signal is captured; pass -NoiseProfile legacy (or use the “legacy noise” VS
Code task) to restore the previous suppression bundle
(-noattr -nofp -nofppos -nobd -nobdcosm) when you need a quieter diff.
The backend release tag vX.Y.Z (or prerelease vX.Y.Z-rc.N) is the canonical
version for this repository. That one tag/version line governs the stable backend
surfaces:
comparevi-clirelease archives andcomparevi-cli versionCompareVi.Sharedpackage versionCompareVI.Toolsbundle metadata and release asset pin
For CompareVI.Tools, pin the bundle by backend release tag plus
SHA256SUMS.txt. The embedded PowerShell module manifest is still useful for
inspection, but consumers should not treat ModuleVersion alone as the release
identity.
Stable support promise:
- stable backend tags publish the CLI archives,
CompareVi.Shared, and theCompareVI.Toolsbundle from the same source ref - rc tags are preview/backend-validation tags and should not be treated as stable downstream pins unless explicitly called out
Facade coordination:
comparevi-historyis a separate repo with its own semver line- a backend release here does not automatically imply a facade release there
- if the backend contract consumed by the facade changes, update the facade's pinned backend ref and cut a facade release separately after its smoke/release workflows pass
Tagged releases also publish a CompareVI.Tools zip bundle for cross-repo
module consumers. Compatibility expectations for that asset are strict:
- keep all extracted bundle files together from the same release tag
- verify the zip against the release
SHA256SUMS.txt - import
tools/CompareVI.Tools/CompareVI.Tools.psd1from the extracted bundle instead of mixing helper files from multiple tags - when a downstream repo uses hosted NI Linux diagnostics, resolve
tools/Run-NILinuxContainerCompare.ps1from the extracted bundle root and keep its adjacent support scripts in place - for single-container NI Linux smoke/bootstrap lanes, prefer the runner's
runtime-injection surface (
-RuntimeInjectionScriptPath,-RuntimeInjectionEnv,-RuntimeInjectionMount) or the explicit-RuntimeBootstrapContractPathviHistoryblock so config/dependency setup, repo-branch materialization, bounded sequential VI-history pair execution, and the compare invocation stay inside one container execution - when the smoke lane is bound to a VI-history source branch, keep the
maxCommitCountsafeguard in the bootstrap contract so oversized branches fail before the container turns into a full-history sweep; budget divergence fromdevelop, not the entire baseline history