Raxx · internal docs

internal · gated

ADR-0086: vcpkg Lockfile Policy — Decline (Path B)

Status: Accepted — updated post-v1 (2026-05-29 UTC) Original date: 2026-05-13 UTC Updated date: 2026-05-29 UTC (Card F evaluation — #2041) Author: software-architect Incident background: docs/architecture/queue-cpp-scaffold-review-2026-05-13.md Applies to: Queue and all tier-1 C++ services


Context

vcpkg supports a machine-generated lockfile (generated during vcpkg install) that records the exact resolved package graph, including transitive dependencies, port overlay revisions, and binary cache identifiers. Committing this file alongside vcpkg.json provides:

  1. Machine-verifiable proof that the author ran vcpkg install.
  2. Fully deterministic builds independent of vcpkg.json version declarations (even version>= resolves to a specific version in the lock).
  3. A diff-visible record of every transitive dependency change.

The question: should tier-1 C++ services commit vcpkg-lock.json to the repository?


Decision

Do not commit vcpkg-lock.json. (Path B — Decline)

This decision was originally deferred to post-v1 evaluation (Card F / #2041). The post-v1 evaluation is now complete. The decision remains: no lockfile.

The combination of: - Exact version pinning in vcpkg.json (ADR-0085) - Mandatory CI vcpkg install --dry-run guard (ADR-0087 / #2030) - Author attestation in PR description ("Verified: vcpkg install ran clean...") - Shallow-clone regression guard in vcpkg-manifest-check.yml

...provides equivalent reproducibility guarantees to a committed lockfile, without the maintenance overhead.

Post-v1 operational rationale (2026-05-29 UTC):

  1. The dep set remained at 9 packages. The >15-package threshold for lockfile adoption has not been reached. Direct deps are fully pinned; transitive graph is deterministic from those pins + baseline.
  2. No production incident traced to transitive dep resolution. The 2026-05-27 shallow-clone incident (docs/ops/incidents/2026-05-27-queue-deploy-vcpkg-shallow-clone.md) was a Dockerfile/CI configuration error, not a dep resolution ambiguity. The lockfile would not have prevented it.
  3. vcpkg lockfile format is not stable across vcpkg tool versions. As of 2026-05 the format has changed in the vcpkg 2024.x series. Adopting lockfiles requires pinning the vcpkg tool version itself (additional maintenance surface). Not worth the cost at this stage.
  4. Maintenance cost of lockfile is ongoing. Every vcpkg.json change — including baseline bumps — requires regenerating the lock. With a quarterly bump cadence this adds a non-trivial regeneration step with no marginal safety benefit over exact pinning.

This decision is now closed. Do not defer or revisit absent a concrete incident where exact-pin + CI dry-run failed to catch a reproducibility problem.


Consequences

Positive: - No regeneration step on every vcpkg.json change. PR diffs are clean: only the lines changed in vcpkg.json. - No vcpkg tool version pinning required (lockfiles are not forward-compatible across all vcpkg versions). - CI vcpkg-manifest-check (ADR-0087) provides an automated correctness gate without the lockfile overhead.

Negative: - Transitive dependencies are not explicitly recorded in the repo. A baseline bump changes transitive versions without a lockfile diff. - No machine-verifiable proof of vcpkg install execution — relies on CI dry-run gate + author attestation.

Net assessment: Acceptable. Direct deps are fully pinned via overrides; vcpkg resolves transitives deterministically from those pins + baseline. The CI gate (ADR-0087) catches version-not-in-registry and feature-not-found classes. Post-v1 operational experience confirmed no transitive-dep incidents.


Alternatives Considered

Commit vcpkg-lock.json now

Arguments for: Stronger reproducibility story; machine-generated proof of authorship; enables security tooling to scan the full transitive dep graph.

Arguments against: vcpkg lockfile format is not stable across vcpkg tool versions (must pin the vcpkg tool version). Large machine-generated files create noise in PR diffs and git history. The maintenance step (regenerate on every dep change) adds friction. The alternative controls (exact pinning + CI dry-run) provide equivalent safety for the direct dep surface.

Status: Declined (Path B). Post-v1 evaluation completed 2026-05-29 UTC; decision closed.

Use a Conan lockfile instead (switch dep managers)

Conan has a more mature lockfile story. However, switching from vcpkg to Conan is a significant change to the build infrastructure and would require re-validating all 9 packages. Out of scope for this decision.