Verify the change in two immutable snapshots.
Verified experiments extend graph comparison with ordered restore, build, and structured test evidence while keeping the original checkout unchanged.
Choose the evidence level explicitly
Verification is opt-in for diff and simulate. PackageMedic runs the same requested stages for the baseline and candidate, in order; it never accepts a candidate failure without first establishing passing baseline evidence for that stage.
| Option | Stages | What it establishes |
|---|---|---|
--verify restore | restore | Both dependency analyses completed in independent immutable snapshots. |
--verify build | restore → build | Both snapshots also completed dotnet build with --no-restore. |
--verify test | restore → build → test | Both snapshots also produced consistent structured TRX test evidence. |
# Compare a Git base with the committed HEAD
package-medic diff origin/main . --verify restore
# Add build verification in Release configuration
package-medic diff origin/main . --verify build --verification-configuration Release --build-timeout 900
# Test implies restore and build
package-medic diff origin/main . --verify test --build-timeout 900 --test-timeout 1200
# Verify a Time Machine candidate against the same committed HEAD
package-medic simulate Example.Package --to 2.0.0 . --verify testTimeouts are in seconds and apply per build target or test project. Values range from 1 to 3600. The default configuration is Release; configuration names accept only letters, digits, dots, underscores, and hyphens.
Interpret a comparative verdict
| Verdict | Exit | Meaning |
|---|---|---|
pass | 0 | The requested evidence passed on both sides and a dependency change was observed. |
noChange | 0 | The requested evidence passed, but no dependency change was observed. |
reject | 1 | The baseline passed and the candidate produced a deterministic restore, build, or test failure. |
incomplete | 2 | Missing, contradictory, unsafe, timed-out, or operational evidence prevents a trustworthy comparison. |
Tests use bounded structured evidence
Test projects come from evaluated MSBuild IsTestProject metadata rather than filename or package heuristics. PackageMedic supports VSTest and Microsoft Testing Platform projects, runs dotnet test without another build or restore, and reconciles the process exit code with TRX counts and stable failed-test identities.
Each project gets a private results directory that is removed with its snapshot. Raw TRX files are not a PackageMedic output or uploaded artifact. A Microsoft Testing Platform project must already be able to emit TRX; PackageMedic does not install report extensions into the repository.
Know the execution boundary
- 1Resolve commits
Require a clean worktree, resolve the base and current HEAD to immutable commit IDs, and validate archive semantics.
- 2Materialize twice
Create independent baseline and candidate snapshots with separate NuGet, .NET, home, and temporary state.
- 3Apply trusted policy
Resolve repository configuration from the immutable base and apply that policy to both sides.
- 4Run ordered stages
Analyze first, then run only the explicitly requested build and test stages.
- 5Clean before output
Remove owned state, recheck the original worktree and HEAD, then write the requested reports.
Use the Action boundary deliberately
The Action accepts verify, build-timeout, test-timeout, and verification-configuration in diff mode. It exposes the verdict, regression flags, candidate test counts, incompleteness, and the optional provenance path as outputs.
verification-status
build-regression
test-regression
tests-passed
tests-failed
tests-skipped
verification-incomplete
provenance-file| Runner | Action behavior |
|---|---|
| GitHub-hosted | Build/test verification is allowed, but the workflow still controls permissions, secrets, and network access. |
| Self-hosted | Build/test verification is refused unless allow-self-hosted-verification: 'true' is set explicitly. |
| CLI | There is no runner-type switch; the operator is responsible for the execution boundary. |
allow-self-hosted-verification is acknowledgement, not hardening. It does not isolate a persistent runner or make untrusted repository code safe. See the GitHub Action guide for the stable workflow and permission model.
Export the observed NuGet inventory as CycloneDX
# Write only the CycloneDX document
package-medic sbom . --output artifacts/packagemedic.cdx.json
# Add CycloneDX to a normal analysis
package-medic doctor . --sbom-output artifacts/packagemedic.cdx.json
package-medic audit . --sbom-output artifacts/audit.cdx.json
package-medic diff origin/main . --sbom-output artifacts/current.cdx.jsonThe output is deterministic CycloneDX 1.7 JSON with portable project/framework/runtime contexts, NuGet package URLs, direct/transitive kind, and the canonical dependency paths retained by the analysis. The standalone sbom command requires --output; --sbom-output is available on doctor, audit, and diff, but not simulate. Diff exports the current or candidate side of the comparison.
Bind completed evidence to the candidate commit
package-medic diff origin/main . --verify test --provenance-output artifacts/packagemedic.intoto.json--provenance-output is accepted only by verified diff. After a conclusive verdict, PackageMedic writes a deterministic in-toto Statement v1 whose subject is the immutable candidate Git commit. Its PackageMedic-specific predicate binds the baseline commit and deterministic comparison-report digest, then records the target, tool version, trusted configuration fingerprint, verification level, and verdict. The CycloneDX digest is included only when a complete resolved graph was available; a deterministic candidate restore rejection can therefore carry valid evidence without an SBOM claim.