Raxx · internal docs

internal · gated ↑ index

Queue C++ Scaffold — QA Validation Plan

Status: Active — awaiting Card A PR open Date: 2026-05-13 UTC Owner: qa-agent (file findings only; operator decides per [[project_qa_agent]]) Triggering design doc: docs/architecture/queue-cpp-scaffold-review-2026-05-13.md (#2032, merged 2026-05-13T23:55:56Z UTC) ADRs in scope: ADR-0085 (vcpkg version pinning), ADR-0086 (lockfile policy), ADR-0087 (CI manifest guard) Refs: #2021, #2028, #2030, #2031


0. Persona stance

This plan is written by the qa-agent persona. It validates that reality matches architectural intent. It does not gate merges. Findings are surfaced to the operator as inline PR review comments and the operator decides remediation. Read-only against in-flight branches; this worktree never modifies Card A, D, or B.


1. Workstreams in flight

Card Owner Scope Critical path Status as of 2026-05-13 UTC
A feature-developer queue/vcpkg.json full audit + exact-pin migration against builtin-baseline=3508985146f1b1d248c67ead13f8f54be5b4f5da. Unblocks #2021. Yes PR not yet opened
D software-architect ADR-0085 status ProposedAccepted No (parallel) ADR drafted at Proposed
B feature-developer (post-D, post-A) CI vcpkg-manifest-check job for #2030 No (hardening) Sequenced after Card A merges green

Cards C, E, F are out of scope for this validation pass (see §6).


2. Per-card acceptance verification checklists

2.1 Card A — queue/vcpkg.json audit + exact-pin

# Check How it is verified Pass signal
A-1 Clean Docker build from a fresh clone of Card A's branch git clone … && git checkout <card-a-branch> && docker build queue/ (or equivalent heroku container:push simulation) vcpkg install phase exits 0; compile phase produces /app/bin/queue-server; final image tag created
A-2 No vcpkg version/feature errors in build log grep -E "(does not have a feature|could not satisfy|not in database|version not found)" build.log Zero matches
A-3 Exact-pin migration complete git diff origin/main..HEAD -- queue/vcpkg.json Every dependency block has "version" and no "version>=" remains
A-4 Baseline SHA unchanged jq -r .['"'"'builtin-baseline'"'"'] queue/vcpkg.json on Card A's branch Returns 3508985146f1b1d248c67ead13f8f54be5b4f5da (baseline bump is Card E, not Card A — per design doc §F + §15-E)
A-5 Version rationale documented queue/vcpkg-notes.md exists (per design doc §C and Card A AC) or PR body contains per-package rationale or inline comments in vcpkg.json One of the three present
A-6 --depth 1 not reintroduced in Dockerfile grep -n "git clone" queue/Dockerfile Line 32 (or wherever the vcpkg clone lives) contains git clone https://github.com/microsoft/vcpkg.git with no --depth flag
A-7 drogon feature set correct jq '.dependencies[] \| select(.name=="drogon") \| .features' queue/vcpkg.json ["postgres"] exactly — openssl is not in the list (regression check for #2031)
A-8 libpqxx version resolves jq '.dependencies[] \| select(.name=="libpqxx") \| .version' queue/vcpkg.json Returns a version that exists at the pinned baseline (expected 7.9.2 per design doc §3 timeline, but any baseline-resident exact version satisfies this AC)
A-9 All 9 packages exact-pinned jq '.dependencies[] \| .name' queue/vcpkg.json \| wc -l and jq '.dependencies[] \| select(.version)' queue/vcpkg.json \| jq -s length Both equal 9 (drogon, nlohmann-json, spdlog, sentry-native, curl, openssl, libpqxx, jwt-cpp, gtest)
A-10 No scope creep: application code untouched git diff --name-only origin/main..HEAD Only queue/vcpkg.json and optionally queue/vcpkg-notes.md modified. CMakeLists.txt, src/, include/, tests/ unchanged. Flag — do NOT reject — if Dockerfile changes are present, since Dockerfile-side fixes are explicitly in #2028 scope
A-11 PR body attests local verification PR description contains "Verified: vcpkg install ran clean in container on YYYY-MM-DD UTC" per design doc §C (Invariant P-1) Present
A-12 Staging deploy proof (post-merge) After Card A merges to main, SRE attempts heroku container:push web -a raxx-queue-staging and runs Phases 1-5 of #2021 Deploy progresses through Phases 1-5 without a 4th vcpkg-class bug. If a 4th bug surfaces, Card A is incomplete — file a follow-up finding rather than re-open A

Note on A-12: SRE executes the deploy. QA monitors the result. QA does not gate the deploy attempt.

2.2 Card D — ADR-0085 status flip

# Check How it is verified Pass signal
D-1 ADR status is Accepted grep -E "^\\*\\*Status:\\*\\*" docs/architecture/adr/0085-vcpkg-version-pinning-policy.md Reads **Status:** Accepted
D-2 Acceptance date stamp present Same file, **Date:** or new acceptance footer 2026-05-13 UTC (or a later date if operator review takes additional time — UTC always per [[feedback_utc_times]])
D-3 Acceptance notes reference the triggering incident ADR body Mentions the 2026-05-13 UTC three-bug deploy incident OR explicitly links to docs/architecture/queue-cpp-scaffold-review-2026-05-13.md
D-4 References design doc + Card A as first implementation ADR body Both links present
D-5 ADR lives in docs/architecture/adr/ ls docs/architecture/adr/0085-vcpkg-version-pinning-policy.md File exists at expected path
D-6 Consequences section addresses operator objections (if any surface) ADR body Either: no objections surfaced, OR each objection has a one-paragraph rebuttal in the Consequences section

2.3 Card B — CI vcpkg-manifest-check (sketch only; full plan post-D)

This sketch will be re-validated against Card B's actual PR when it opens.

# Check How it is verified Pass signal
B-1 New job exists in .github/workflows/ git diff --name-only origin/main..HEAD -- .github/workflows/ New workflow file OR addition to an existing queue-specific workflow
B-2 Trigger is correct Workflow on.pull_request.paths block Includes queue/vcpkg.json and queue/Dockerfile
B-3 Runs vcpkg install --dry-run Workflow run: step Contains vcpkg install --dry-run --triplet x64-linux --x-manifest-root=queue/
B-4 Full vcpkg clone (no --depth 1) Workflow setup step git clone https://github.com/microsoft/vcpkg.git with no --depth flag
B-5 Cache configured for <2 min completion Workflow contains actions/cache@v3 (or v4) keyed on hashFiles('queue/vcpkg.json') Cache step present; target warm-cache time documented in PR body
B-6 Dockerfile --depth regression check Workflow contains a grep step that fails if queue/Dockerfile contains git clone --depth for the vcpkg clone Present per design doc §6
B-7 Negative test evidence PR body or workflow comment shows a deliberately-broken vcpkg.json (invalid feature) failed the check Demonstrated
B-8 Non-queue/** PRs unaffected Workflow paths filter limits firing to queue-touching PRs Verified — does not add CI time to other PRs
B-9 Fails PR on non-zero vcpkg exit Default GH Actions behavior; confirm no continue-on-error: true No suppression

3. Architectural intent verification

These checks validate the spirit of the design doc, not just the letter of each card's AC.

3.1 Invariant P-1 — vcpkg.json as executable specification

Design doc §2 declares: "A vcpkg.json must be verified against its pinned builtin-baseline via a clean vcpkg install in a fresh container before any PR that touches it is opened. No exceptions. No fix-forward."

Card A's end state must satisfy this. Verification: - The PR body contains the verification attestation (A-11). - The CI guard (Card B) will, post-merge, enforce this on every subsequent PR. - Until Card B lands, A-11 + the operator's "no more fix-forwards" rule are the controls.

3.2 No fix-forward regression

The design doc §3 ("Why fix-forward is wrong here") rejects the bug-by-bug-one-line-PR pattern. Card A must be one PR that audits all 9 packages at once, not a chain of small PRs.

Verification: Card A's PR diff covers all 9 packages with documented version choices. If only the libpqxx fix lands and other packages stay on version>=, Card A is incomplete and QA flags this as a process-invariant violation (P-1 + the operator's stated remediation pattern).

3.3 Tier-1 service alignment — propagation to Velvet C++ rewrite

Per [[project_language_tier_philosophy]], Queue is the first tier-1 C++ service; Velvet and MQ-A rewrites are anticipated. ADR-0085's policy is written as a tier-1 policy, not a Queue-specific policy.

Verification: - ADR-0085 §"Applies to" names Queue and future tier-1 services (already correct in the draft). - The policy does not depend on Queue-specific facts (e.g., Drogon, libpqxx) — it applies generically to any vcpkg manifest at a pinned baseline. - The mandatory-validation step is service-agnostic.

If Velvet's C++ rewrite scaffold PR opens at a later date, this validation plan can be re-used by swapping queue/ paths for velvet/ paths. No re-derivation of policy needed.


4. Test execution plan

4.1 When Card A's PR opens

  1. Detect: Watch the gh pr list --search "vcpkg audit" or similar for the Card A PR opening. The branch will originate from main per _shared-conventions.md.
  2. Clone PR branch into this worktree's checkout space (read-only); do not push.
  3. Run static checks (A-3, A-4, A-6, A-7, A-8, A-9, A-10, A-11) using git diff, jq, grep. ~5 min.
  4. Run Docker build (A-1, A-2): sh cd $(mktemp -d) git clone https://github.com/raxx-app/TradeMasterAPI.git cd TradeMasterAPI && git checkout <card-a-branch> docker build queue/ 2>&1 | tee /tmp/card-a-build.log Expected wall-clock: ~20 min cold-cache, <2 min warm.
  5. Post inline review on Card A's PR with: - Per-AC checkbox table (the §2.1 grid filled in). - Build log summary (lines around any errors, or "build clean — vcpkg install resolved 9 packages in N seconds"). - Any P-1 / fix-forward findings as separate inline comments at specific file:line locations. - Recommendation (advisory only): pass / pass-with-followups / request-changes-non-blocking. QA never sets the PR to "Request changes" in the GitHub UI sense; recommendation lives in the comment body.
  6. Post-merge monitoring (A-12): subscribe to raxx-queue-staging deploy attempts. If a 4th vcpkg-class bug surfaces, file a follow-up issue (type:reliability, area:queue, link to this plan).

4.2 When Card D lands (status flip on existing ADR file)

ADR-0085 is a doc-only change. Validation is purely static: 1. Read the post-merge ADR file. 2. Run §2.2 checks D-1 through D-6. 3. Post a single inline review on the Card D PR with the checklist outcome. ~10 min.

4.3 When Card B opens (post-D, sketch refined into full plan)

When Card B's PR opens, re-derive the §2.3 checklist into a full plan and execute: 1. Static workflow YAML review (B-1 through B-9). 2. Trigger the workflow on the PR itself (it self-tests when modifying .github/workflows/). Confirm pass on the current valid manifest. 3. Validate negative-test evidence in PR body (B-7). 4. Post inline review.


5. Pass/fail criteria

QA does not block merges. These criteria are advisory and surface as recommendations to the operator.

5.1 Card A — recommendation matrix

Outcome Trigger
Pass (recommend merge) All A-1 through A-11 green. A-12 deferred to post-merge SRE deploy.
Pass with follow-up A-1 through A-9 green; A-10 shows scope creep that operator may want to accept (e.g., a typo fix in a comment in CMakeLists.txt) or A-5 has rationale in only one of the three accepted locations and that location is shallow. File follow-up issue but do not block.
Recommend changes (non-blocking) One or more of: A-3 incomplete (still version>= somewhere); A-4 baseline changed without explicit Card-E scope claim; A-6 --depth 1 regression; A-7 openssl feature back in drogon list. Comment surfaces the specific gap; operator decides.
Recommend hold A-1 fails (build broken). The PR cannot demonstrate Invariant P-1. Comment recommends author re-runs vcpkg install locally and iterates before re-requesting review.

5.2 Card D — recommendation matrix

Outcome Trigger
Pass D-1 through D-5 green; D-6 either no-objections-surfaced or addressed in Consequences.
Pass with follow-up D-1 through D-5 green; D-6 reveals operator objection that ADR acknowledges without resolution — file follow-up to track.
Recommend changes D-1 not flipped (still says Proposed); D-3 missing incident reference; D-4 missing design-doc link.

5.3 Card B — recommendation matrix

Refined when Card B opens. Initial sketch: pass if B-1 through B-9 green; recommend changes if any of the regression checks (B-4, B-6) are missing — those are the ones that prevent today's incident from recurring.

5.4 How findings surface to the operator


6. Out of scope

This validation plan does not cover:


7. Risks and assumptions

Risk R-1: Card A's audit may surface a 4th or 5th package whose pinned version is unavailable at the baseline. The design doc anticipated this (§3 "Bug catalogue" row 4+). If this happens, Card A's PR may take longer than the 2-4 hour size estimate. QA does not block on duration — just notes it.

Risk R-2: If the operator decides during Card D review to flip the policy to version#N (port-revision pin, per ADR-0085 §"Alternatives Considered"), Card A's exact-version choices will need to be re-evaluated. Low probability — design doc §C explicitly rejects version#N as overkill for v1.

Risk R-3: Card B may surface a vcpkg tooling version mismatch (the dry-run flag's behavior varies across vcpkg releases). The design doc OQ-3 anticipates this. If Card B's CI uses a different vcpkg HEAD than the Card A author's local container, version-resolution differences could produce false-positive CI failures. Mitigation: Card B pins the vcpkg tool clone to the baseline SHA, matching Card A's authoring environment.

Assumption A-1: SRE executes the post-Card-A staging deploy attempt and surfaces the result. QA does not run heroku container:push against raxx-queue-staging.

Assumption A-2: Card A's PR author follows _shared-conventions.md and branches from main. QA verifies via git log origin/main..HEAD showing only Card-A-authored commits.


8. Acknowledgments

This plan implements the qa-agent persona's stated responsibility per [[project_qa_agent]]: confirm reality matches architectural intent, file findings, do not gatekeep. The design doc author (software-architect) and the Card A implementer (feature-developer) own the work; this plan validates whether the work meets the design's bar.