# QA Review — MC #8845 / MC #8241 DropSrbija Phase 4 Infra

# QA Review — MC #8845 (review of MC #8241)

**Reviewer:** John / Proveo QA posture (tool-verified in Pi session `019fa7de-42c2-7d86-80f0-ee5d2a91ea05`)  
**Date:** 2026-07-28  
**Subject task:** MC #8241 — `[DropSrbija v2 I4.12 Phase 4 validation Proveo infra smoke tests`  
**Subject status:** `done`  
**BookStack:** https://docs.alai.no/books/drop-srbija/page/qa-review-mc-8845-mc-8241-dropsrbija-phase-4-infra  
**Subject DoD claim:** Phase 4 code validated: I4.1 terraform 11 modules PASS; I4.3 3 Caddyfiles PASS; I4.5 PARTIAL; I4.8 PASS; I4.9 PASS; I4.10 PASS; I4.11 PASS; 4 CEO-gated skipped.

## Verdict

**CONDITIONAL PASS.** The core artifact/count/validator claims from MC #8241 are mostly reproducible from the DropSrbija worktree. The strongest checks passed: all 11 Terraform modules validate, all 3 Caddyfiles validate with real `caddy validate`, YAML/JSON parse checks pass, backup scripts are executable, alert count is 16, release/approval artifacts exist.

Conditions / caveats:

1. **Root Terraform stack validation was not reproduced on this host** because installed Terraform is `v1.5.7` while `infrastructure/terraform/versions.tf` requires `>= 1.7.0`. Module-level validation passed; full root validation requires Terraform >=1.7.
2. **Backup verification workflow is disabled by filename:** `.github/workflows/backup-verify.yml.SLACK_DISABLED` exists and parses as YAML, but `.github/workflows/backup-verify.yml` does not exist, so GitHub Actions will not schedule/run it.
3. **Secret-name documentation drift:** `docs/RELEASE/release-process.md` documents `SLACK_WEBHOOK_ALAI_ALERTS`; `deploy-production.yml` references `SLACK_CHANNEL_ALAI_ALERTS`.
4. **"Bootstrap dir empty" not confirmed literally:** no repo-owned bootstrap directory was found; only `scripts/secrets/bootstrap-dev-env.sh` and dependency files under `node_modules` matched `*bootstrap*`.
5. **"4 CEO-gated skipped" only partially corroborated:** repo docs confirm CEO-gated blockers exist, but no single Phase-4 list enumerating exactly four skipped items was found.

## Evidence written

- `qa-reviews/evidence-8845/modules.txt`
- `qa-reviews/evidence-8845/terraform-validate.log`
- `qa-reviews/evidence-8845/terraform-root-validate.log`
- `qa-reviews/evidence-8845/root-tfinit.out`
- `qa-reviews/evidence-8845/generated-terraform-artifacts-present.txt`

Terraform init artifacts generated during validation were removed after the check; no `.terraform` directories or `.terraform.lock.hcl` files remained under `infrastructure/terraform` after cleanup.

## Checks performed

### I4.1 — Terraform modules

**Result:** PASS for the claimed 11 module validations; root stack blocked by local Terraform version.

Verified:

- `find infrastructure/terraform/modules -mindepth 1 -maxdepth 1 -type d | wc -l` → `11`
- Module directories found: `backup`, `cdn`, `container-apps`, `container-registry`, `dns`, `iam`, `monitoring`, `network`, `postgres`, `redis`, `secrets`
- For each module, ran:
  - `terraform -chdir=<module> init -backend=false -input=false -no-color`
  - `terraform -chdir=<module> validate -no-color`
- All 11 module validations returned `validate_rc=0` with `Success! The configuration is valid.`

Limitation:

- Root check `terraform -chdir=infrastructure/terraform init -backend=false -input=false -no-color` returned `root_init_rc=1` due to Terraform core version mismatch: local host has `Terraform v1.5.7`; root config requires `>= 1.7.0`.

### I4.3 — Caddyfiles

**Result:** PASS.

Validated with `caddy v2.11.2`:

- `Caddyfile.dev` → `Valid configuration`, rc `0`
- `Caddyfile.prod` → `Valid configuration`, rc `0`
- `Caddyfile.staging` → `Valid configuration`, rc `0`

### I4.5 — Secrets module / bootstrap

**Result:** PARTIAL, matching the original PARTIAL posture.

Verified in `infrastructure/terraform/modules/secrets/main.tf`:

- `azurerm_key_vault_secret.jwt_secret`
- `azurerm_key_vault_secret.nbs_ips_api_key`
- `azurerm_key_vault_secret.twilio_account_sid`
- `azurerm_key_vault_secret.twilio_auth_token`
- `azurerm_key_vault_secret.twilio_from_number`

Count: `5`.

Not verified literally:

- No repo-owned bootstrap directory was found. `find` only matched `scripts/secrets/bootstrap-dev-env.sh` plus `node_modules` bootstrap implementation files.

### I4.8 — Backup scripts, runbook, backup workflow YAML

**Result:** PASS for scripts/runbook/YAML syntax; operational caveat for disabled workflow filename.

Verified:

- `scripts/backup/` has exactly 3 files:
  - `pg-nightly.sh` (`-rwxr-xr-x`)
  - `restore-drill.sh` (`-rwxr-xr-x`)
  - `wal-archive.sh` (`-rwxr-xr-x`)
- `docs/runbooks/backup-recovery.md` documents:
  - `RPO: 1 hour`
  - `RTO: 4 hours`
- `.github/workflows/backup-verify.yml.SLACK_DISABLED` exists and parses as YAML.

Caveat:

- `.github/workflows/backup-verify.yml` does **not** exist. The present `.SLACK_DISABLED` file is inert for GitHub Actions scheduling.

### I4.9 — Alert rules

**Result:** PASS.

Verified:

- `observability/alerts/prometheus-rules.yaml` parses as YAML.
- Alert rule count: `16` (`grep -c '^[[:space:]]*- alert:'`).

### I4.10 — Release metadata

**Result:** PASS.

Verified:

- `.releaserc.json` parses with `jq empty`.
- `commitlint.config.js` exists (`1917` bytes).
- `CHANGELOG.md` exists and contains `Phase 0-3 Summary (Architecture & Core Implementation)`.

### I4.11 — Production deploy gate and secrets docs

**Result:** PASS with doc/code drift note.

Verified in `.github/workflows/deploy-production.yml`:

- `manual-approval` job exists.
- `environment: production` is used.
- deploy job has `needs: manual-approval`.
- workflow YAML parses successfully.

Verified in `docs/RELEASE/release-process.md`:

- Required GitHub Secrets table documents 7 entries: `GITHUB_TOKEN`, `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_SUBSCRIPTION_ID`, `SLACK_WEBHOOK_ALAI_ALERTS`, `SLACK_BOT_TOKEN`, `ACR_REGISTRY`.

Drift:

- Workflow references 6 unique secrets: `ACR_REGISTRY`, `AZURE_CLIENT_ID`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `SLACK_BOT_TOKEN`, `SLACK_CHANNEL_ALAI_ALERTS`.
- Docs name `SLACK_WEBHOOK_ALAI_ALERTS`; workflow names `SLACK_CHANNEL_ALAI_ALERTS`.

### CEO-gated skipped items

**Result:** PARTIAL corroboration.

Repo docs confirm CEO-gated blockers exist:

- `docs/bookstack/06-phase4-infrastructure.md` lists Azure subscription, `drop.rs` domain, and production Key Vault secrets as CEO-pending.
- `docs/bookstack/09-pending-ceo-actions.md` contains broader CEO-gated actions across incorporation, legal, Azure budget, and RFP/partner work.

No single repo source found in this review enumerated exactly **4** Phase-4-specific skipped items.

## Follow-up recommendations

1. Run root Terraform validation with Terraform `>= 1.7.0` and attach output to this review.
2. Re-enable backup verification by renaming/wiring `.github/workflows/backup-verify.yml.SLACK_DISABLED` to an active `.yml` workflow when Slack dependency is resolved.
3. Reconcile Slack secret naming between `deploy-production.yml` and `docs/RELEASE/release-process.md`.
4. Clarify or remove the stale/imprecise “bootstrap dir empty” claim in future DoD wording.