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:
- Machine-verifiable proof that the author ran
vcpkg install. - Fully deterministic builds independent of
vcpkg.jsonversion declarations (evenversion>=resolves to a specific version in the lock). - 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.