Raxx · internal docs

internal · gated

ADR-0086: vcpkg Lockfile Policy — Defer for v1

Status: Accepted
Date: 2026-05-13 UTC
Author: software-architect
Incident background: docs/architecture/queue-cpp-scaffold-review-2026-05-13.md
Applies to: Queue Phase 1 and all tier-1 C++ services at v1 scope


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 for Queue Phase 1 or any tier-1 service at v1 scope.

The combination of: - Exact version pinning in vcpkg.json (ADR-0085) - Mandatory local vcpkg install verification before PR (Invariant P-1) - CI vcpkg install --dry-run guard (Card B / #2030)

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

Revisit this decision post-v1 launch if: - The dep set grows to >15 packages (transitive dep graph becomes hard to reason about without the lock). - A production incident is traced to an unexpected transitive dep resolution. - vcpkg's lockfile format stabilizes across versions (the format has changed in vcpkg 2024; pinning the vcpkg tool version alongside would be required).

This ADR is explicitly provisional. Card F tracks the post-v1 evaluation.


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). - Lower cognitive overhead for feature-developer during the v1 sprint.

Negative: - Transitive dependencies are not explicitly recorded in the repo. A baseline bump changes transitive versions invisibly. - No machine-verifiable proof of vcpkg install execution — relies on author attestation in PR description.

Net assessment: Acceptable for v1 given the mitigating controls. The exact version pinning in vcpkg.json (ADR-0085) reduces the transitive-dep ambiguity substantially: direct deps are fully pinned, and vcpkg resolves transitives deterministically from those pins + baseline.


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 during a fast-moving v1 sprint. The alternative controls (exact pinning + local verification + CI dry-run) provide equivalent safety for the direct dep surface.

Status: Deferred to post-v1 per Card F.

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.