PackageMedicDocs
Verified experiments

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.

OptionStagesWhat it establishes
--verify restorerestoreBoth dependency analyses completed in independent immutable snapshots.
--verify buildrestore → buildBoth snapshots also completed dotnet build with --no-restore.
--verify testrestore → build → testBoth snapshots also produced consistent structured TRX test evidence.
Terminal
# 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 test

Timeouts 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

VerdictExitMeaning
pass0The requested evidence passed on both sides and a dependency change was observed.
noChange0The requested evidence passed, but no dependency change was observed.
reject1The baseline passed and the candidate produced a deterministic restore, build, or test failure.
incomplete2Missing, 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

  1. 1
    Resolve commits

    Require a clean worktree, resolve the base and current HEAD to immutable commit IDs, and validate archive semantics.

  2. 2
    Materialize twice

    Create independent baseline and candidate snapshots with separate NuGet, .NET, home, and temporary state.

  3. 3
    Apply trusted policy

    Resolve repository configuration from the immutable base and apply that policy to both sides.

  4. 4
    Run ordered stages

    Analyze first, then run only the explicitly requested build and test stages.

  5. 5
    Clean 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.

Action outputs
verification-status
build-regression
test-regression
tests-passed
tests-failed
tests-skipped
verification-incomplete
provenance-file
RunnerAction behavior
GitHub-hostedBuild/test verification is allowed, but the workflow still controls permissions, secrets, and network access.
Self-hostedBuild/test verification is refused unless allow-self-hosted-verification: 'true' is set explicitly.
CLIThere 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

Terminal
# 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.json

The 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

Terminal
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.