PackageMedicDocs
Policy as code

Make every scan repeatable.

Store PackageMedic policy beside the code so local runs and CI evaluate the same rules, severities, exclusions, and operational limits.

Create the configuration

Terminal
package-medic init

The CLI searches for .packagemedic.json from the selected target toward the repository root. Use --config for a different file or --no-configto disable discovery. CLI values win over configuration, which wins over safe defaults.

Complete example

.packagemedic.json
{
  "$schema": "https://raw.githubusercontent.com/GonzMeza/package-medic/main/schemas/packagemedic.schema.json",
  "schemaVersion": 1,
  "failOn": "none",
  "failOnNew": "warning",
  "baseline": ".packagemedic-baseline.json",
  "maxParallelism": 4,
  "exclude": ["**/bin/**", "**/obj/**"],
  "rules": {
    "PM006": { "enabled": true, "severity": "warning" },
    "PM007": { "enabled": true, "severity": "error" },
    "PM008": { "enabled": true, "severity": "warning" }
  },
  "suppressions": [
    {
      "rule": "PM003",
      "path": "src/Legacy/**",
      "package": "Example.Legacy",
      "reason": "Intentional exception tracked in issue 42"
    }
  ],
  "impact": {
    "failOnDowngrade": true,
    "failOnDirectToTransitive": true,
    "maxAddedPackages": 40,
    "maxAddedTransitivePackages": 25,
    "failOnSourceChange": true,
    "failOnContentChange": true,
    "requirePackageSourceMapping": true,
    "requireLockedMode": true,
    "allowedSources": ["https://api.nuget.org/v3/index.json"]
  },
  "timeouts": {
    "restoreSeconds": 300,
    "evaluationSeconds": 60
  }
}

Configuration properties

PropertyAccepted valuePurpose
schemaVersion1Required configuration contract version; independent of the product version.
failOnnone, warning, errorDefault threshold for all effective findings.
failOnNewnone, warning, errorDefault threshold for findings absent from a baseline.
baselineRelative pathBaseline resolved relative to this configuration file.
excludeGlob arrayPortable repository paths that should not be analyzed.
rulesPM001–PM008 mapEnable a rule and optionally override its severity.
suppressionsRule selectorsDocument intentional exceptions by path and/or exact package.
impactImpact Gate objectSet dependency growth, downgrade, source-trust, source-mapping, and locked-restore policy for diff.
maxParallelism1–32Maximum concurrent restore, audit, and MSBuild processes.
timeouts1–3600 secondsBound restore and per-project evaluation.

Impact policy is a separate gate

The impact object applies to complete Git comparisons. Downgrades, direct-to-transitive transitions, source changes, and loss/gain of source evidence fail by default. Package growth budgets, an allowlist, Package Source Mapping, and locked restore are opt-in so teams can adopt them deliberately. A SHA-512 content change under the same package ID/version identity is rejected by default because it deserves explicit supply-chain review.

Allowed sources must be credential-free HTTPS URLs; local is supported only as an explicit value. With an active allowlist, unknown source metadata fails closed. Impact violations are not diagnostic suppressions: change the policy through review when the repository boundary genuinely changes.

Suppress intentionally, not invisibly

Every suppression requires a non-empty reason. A selector always names one rule and may narrow the match with a repository-relative path glob, an exact package ID, or both. Suppressed findings do not reach failure gates, but remain counted in report policy metadata and retain their reason in detailed text and JSON.

Fail-closed input boundaries

Configuration is bounded to 1 MiB, 1,000 exclusions, 1,000 suppressions, and 4,096 characters per glob. Invalid, oversized, unknown, or mistyped properties cause exit code2; PackageMedic never silently continues with partial policy.