# Changelog 2026-07-10 -- DOCFIX-178: workstation prerequisite install scripts

**Context.** First real execution of `runbooks/dc-dc-phase0-vcloud-prep.md` on the
vcloud host surfaced that `tofu` was not installed, and the runbook's Step 6 only
hand-waved ("install per OpenTofu's official instructions ... not prescribed
here"). Operator ruling (2026-07-10): a runbook must not assume prereq runtimes
are present, and new operators should have individual, repo-provided install
scripts to get a workstation/workspace ready. This delivers that.

## What changed

### NEW: `scripts/prereqs/` (idempotent Debian/Ubuntu installers)
- `lib-prereq.sh` -- shared helpers (sourced): `pq_have`, `pq_require_apt`,
  `pq_parse_mode` (--check/--dry-run/--help), `pq_run` (dry-run-aware runner).
- `install-opentofu.sh` -- OpenTofu `tofu` >= 1.6.0 via the official **deb**
  method (lands `/usr/bin/tofu`, the command name every runbook step +
  `scripts/opentofu-validate.sh` expect; the `opentofu` snap may not expose it).
  Version-checks and skips if already new enough.
- `install-virtualization.sh` -- libvirt-daemon-system + qemu-kvm + libvirt-clients
  + virtinst, and adds the invoking user to the `libvirt` group (re-login noted).
- `install-jq.sh` -- jq (a known cause of harness-gauntlet failures when absent).
- `install-image-tools.sh` -- qemu-utils (`qemu-img`) + `xorriso`, for the Stage
  2/3 OPNsense build path (`opnsense-prep-image.sh`, `opnsense-build-config-iso.sh`).
- `check-prereqs.sh` -- read-only report (all of the above + curl/python3/sudo),
  exit 0 all-required-present / 1 missing; each miss names its fixer script.
- `install-all.sh` -- orchestrator (virtualization -> tofu -> jq -> image-tools)
  + final check; passes `--dry-run` through.
- `README.md` -- quick start, per-script table, scope/conventions.
- Each installer supports `--check` (read-only) and `--dry-run` (mutate nothing);
  `sudo` is used only for the actual package/group mutation, never in check/dry-run.
  Non-Debian/Ubuntu OS -> fail loud (exit 3), no package-manager guessing.

### NEW: `tests/prereqs/run-tests.sh`
- Exercises the parse/guard/`--check`/`--dry-run` paths only (never a real apt
  install -- same posture as the opnsense-* harnesses). Includes the safety
  assertion that `pq_run` under dry-run does NOT execute its command. **24/24 PASS.**

### MODIFIED: `runbooks/dc-dc-phase0-vcloud-prep.md`
- New **Prerequisites** section (before "Known gap") with the one-pass
  `check-prereqs`/`install-all` flow + a per-prereq table pointing at the installers.
- Step 6's vague "install per official instructions" replaced with a concrete
  `bash scripts/prereqs/install-opentofu.sh` pointer + the >=1.6.0 floor.

## Verification
- `bash tests/prereqs/run-tests.sh` -> `prereqs: 24/24 PASS`.
- `bash scripts/repo-lint.sh` -> 0 fail (1 documented legacy WARN).
- `bash scripts/ledger-scan.sh` -> DOCFIX next-free was 178 before this entry.

## Revert
- `git rm -r scripts/prereqs tests/prereqs docs/changelog-20260710-prereq-install-scripts.md`
- Revert the two `runbooks/dc-dc-phase0-vcloud-prep.md` edits (Prerequisites
  section + Step 6 paragraph) back to their pre-DOCFIX-178 text.

## Follow-up (logged, not actioned)
- The other `dc-dc-phaseN` runbooks should gain the same short "see
  `scripts/prereqs/`" pointer in their intros (their prereq sets overlap: tofu,
  libvirt, and Stage 2/3 additionally need qemu-img/xorriso). One-line-per-runbook
  sweep, its own DOCFIX. `scripts/prereqs/` itself is already stage-agnostic.
- macOS/RHEL install paths (currently exit-3 fail-loud) if a non-Ubuntu control
  point ever appears.
