Raxx · internal docs

internal · gated

ADR-0085: vcpkg Version Pinning Policy for Tier-1 C++ Services

Status: Accepted (2026-05-13 UTC) Date: 2026-05-13 UTC
Author: software-architect
Context issue: #2030
Incident background: docs/architecture/queue-cpp-scaffold-review-2026-05-13.md
Applies to: Queue, and all future tier-1 C++ services (Velvet rewrite, MQ-A rewrite)


Acceptance Notes

When accepted: 2026-05-13 UTC

Authorized by: Operator (Kristerpher)

Triggering incident: Three layered vcpkg/Dockerfile bugs during Queue staging deploy attempts on 2026-05-13 UTC. The failure chain — shallow clone breaking builtin-baseline resolution (#2028), followed by an invalid drogon openssl feature declaration (#2031), followed by a libpqxx 7.9.1 version mismatch against the pinned baseline — demonstrated that version>= authoring without local vcpkg install verification is not viable for tier-1 services. All three failures were symptoms of the same root cause: the manifest was authored without being verified.

First implementation under this policy: Card A (Queue vcpkg.json audit — convert version>= to exact version pins and verify against baseline). Work in flight as of 2026-05-13 UTC.

Future scope: This policy applies to all tier-1 C++ services as defined in the language tier philosophy ([project_language_tier_philosophy]): Queue (current), Velvet rewrite, MQ-A, and any subsequent service promoted to tier-1. Every new tier-1 C++ service scaffold must land with exact-pinned vcpkg.json as a prerequisite for the initial CI passing run.

Unblocked by acceptance: Card B (CI manifest guard, ADR-0087) can now finalize its guard implementation against a locked policy. The guard enforces the exact-version constraint programmatically so that version>= declarations are rejected at PR time, codifying this decision in the pipeline rather than relying solely on authoring discipline.


Context

On 2026-05-13 UTC, three sequential vcpkg failures during the Queue staging deploy attempt (#2021) revealed that queue/vcpkg.json was authored using version>= constraints without verifying them against the pinned builtin-baseline SHA. The version>= format declares a minimum version, which is convenient during authoring but makes it easy to declare a minimum that does not exist in the registry at the pinned baseline — because the author never ran vcpkg install to check.

The decision to be made: should tier-1 C++ services use version>= (minimum bound) or exact version (fixed pin) in their vcpkg.json manifests?


Decision

Tier-1 C++ services use exact version pinning, not version>=, for all dependencies in vcpkg.json.

The exact pinned version must be available at the declared builtin-baseline SHA. This is verified by running vcpkg install in a fresh container before the PR is opened.


Consequences

Positive: - Every build anywhere resolves the identical package graph. No ambiguity between "version >= X" resolving to X on one runner and Y on another. - The PR diff for a dependency change is unambiguous: old version to new version, one line change. - Exact pins are trivially scanned by security tooling (Dependabot, Snyk). version>= declarations that haven't been resolved are opaque to scanners. - The mandatory local vcpkg install verification step (Invariant P-1) is easier to reason about: the author pins the exact version vcpkg resolved, and that is the version that ships.

Negative: - Upgrading a dependency requires an explicit PR. With version>=, a baseline bump might automatically pull in a newer satisfying version without a manifest change. - More maintenance churn: every baseline bump requires reviewing each package's exact version against the new baseline.

Net assessment: The maintenance overhead is low and bounded. The CI guard (#2030, Card B) makes baseline bumps safe by catching any unavailable versions at PR time. The reproducibility and security-scanning benefits outweigh the churn.


Alternatives Considered

version>= (minimum bound, current state)

The current queue/vcpkg.json uses version>= throughout. This is vcpkg's recommended approach for manifests that want to track reasonable updates within a baseline.

Rejected because: The flexibility of >= is only useful if the author actually verifies the minimum is available at the baseline. Today's incident proves the author did not, and there was no process gate to catch this. For tier-1 services, flexibility in the dependency graph is a liability, not a benefit. Reproducibility and auditability are the priority.

No pinning (omit version constraints entirely, rely on baseline)

vcpkg allows dependency declarations with no version constraint, resolved entirely from the baseline. This is maximally flexible and maximally unpredictable.

Rejected because: Any baseline bump changes package versions silently with no diff evidence. Unacceptable for a billing service with a money-state audit chain.

version# (exact port version including port-specific revision)

vcpkg version strings can include a #N suffix (e.g., 7.9.0#1) that pins both the upstream version and the port overlay revision. This is the most precise pin.

Not required for now. Exact version without the #N suffix is sufficient for v1. If port overlay revisions become relevant (multiple #N versions of the same upstream release), revisit with explicit version# pins.


Mandatory Validation Step

Per Invariant P-1 in docs/architecture/queue-cpp-scaffold-review-2026-05-13.md:

Before any PR touching queue/vcpkg.json is opened, the author runs:

docker run --rm -v $(pwd)/queue:/src gcc:13-bookworm bash -c "
  apt-get update -qq && apt-get install -y -qq cmake ninja-build git curl zip unzip pkg-config ca-certificates &&
  git clone https://github.com/microsoft/vcpkg.git /opt/vcpkg &&
  /opt/vcpkg/bootstrap-vcpkg.sh -disableMetrics &&
  /opt/vcpkg/vcpkg install --triplet x64-linux --x-manifest-root=/src/
"

This command must exit 0. The PR description must include: "Verified: vcpkg install ran clean in container on [DATE] UTC."

The CI guard (ADR-0087 / Card B) is a second gate, not a replacement for local verification.