# Rationale Why a ~400-500 line orchestrator/subscript script set is worth more than a one-line `sudo zypper install X Y Z`, and when it isn't. ## The core argument The complexity here isn't overhead wrapped around a trivial task — the logging and verification machinery *is* the actual value being built. A one-liner installs packages. This project installs packages **and produces a record of having done so correctly.** ## What the pre-flight/test machinery actually buys you - **Audit trail.** Pre-flight state, exactly what was already installed vs. newly installed, post-install verification per package, and cache-cleanup outcome — all captured permanently in `~/.local/logs/ceos_installer/`, rather than scrolling past in a terminal and gone. - **Transparency.** Nothing happens invisibly. Every check, skip, install, and verification is logged as it happens. - **No silent failure.** A bare `zypper install X Y Z` gives no structured signal when one package among several fails or is skipped — you find out later, indirectly, when something that depended on it doesn't work. `test_package_available` and the post-install `run_test` check surface that class of problem at the point it happens, not downstream. - **Correct handling of naming and dependency quirks.** Not hypothetical — see `~/.local/opt/INSTALLER_NOTES.md`'s `tinkerpad-stt` entry: `ffmpeg` doesn't exist as a bare package name on Tumbleweed (only `ffmpeg-8` etc. do), and a naive `zypper install ffmpeg` just fails with no clear diagnostic path. The warn-not-fail design here exists specifically to surface that kind of problem cleanly instead of aborting the whole run or failing silently. - **Reproducibility.** The package list itself is a declarative spec of "what should be installed here." Rebuilding this machine, or standing up a second one needing the same tooling, is "run this list" instead of trying to recall what got installed by hand over months. - **Disaster recovery.** After a wipe or hardware failure, the list plus its log history is the recovery runbook — not just what to reinstall, but a record proving the last known-good state and confirming each package actually verified present afterward, not just that the install command didn't error. ## Who this is actually for A single, private user is entirely free to use the one-liner to their heart's content — nothing here claims that's wrong for personal use. The case for this project's thoroughness is specifically: 1. **A regulated business context**, where a documented, auditable change process is a real requirement, not a preference. This isn't just opinion — it lines up with how established frameworks are actually written: - **NIST SP 800-53, CM-3 (Configuration Change Control)** requires documenting configuration change decisions and retaining records of configuration-controlled changes for a defined period. - **SOC 2, CC8.1** expects a reconstructable change history and evidence of testing — the `run_test` PASS/FAIL/WARN lines in this project's logs are exactly that evidence. - **ISO 27001, Annex A Control 8.32** requires changes to be planned, assessed, authorised, tested, documented, and communicated. These frameworks scope themselves to organizations under audit or compliance obligation — a private individual has no external party requiring this evidence, which is exactly why the one-liner remains a legitimate choice for that case. 2. **A machine you intend to keep documenting and maintaining long past this session** — the specific motivating case for this repo is tinkerpad13, John's first SUSE machine, being deliberately built as an opinionated Dev/SysAdmin OS. Every install is scripted specifically *for* the documentation this produces, not incidentally. The payoff comes from repetition and time, not the first run — it's overkill for a machine you're about to reinstall next week anyway. ## Removal is not just install-in-reverse Apps that get installed and later turn out not to be worth keeping should have their removal documented with the same rigor as their install — an incomplete history that only records what was kept, not what was tried and rejected, isn't a complete build record. This is **not yet built** (only `10_zypper-packages.sh`, the install subscript, exists as of this writing). When it is, it must not simply mirror the install subscript with `zypper remove` swapped in — removal is inherently more dangerous than install, because it can break dependencies that other, still-wanted packages rely on. The removal subscript's design needs a `zypper remove --dry-run`-equivalent step that surfaces what else would be pulled out as a dependent, shown for confirmation *before* the real removal runs — not just a bare y/N on the package name itself. ## Supporting sources - [CM-3: Configuration Change Control (NIST SP 800-53 r5)](https://csf.tools/reference/nist-sp-800-53/r5/cm/cm-3/) - [A Practical Guide to SOC 2 Change Management Controls](https://soc2auditors.org/insights/soc-2-change-management-controls/) - [SOC 2 Change Management (CC8.1 Controls & Evidence)](https://episki.com/frameworks/soc2/change-management) - [ISO 27001:2022 Annex A Control 8.32 Explained](https://www.isms.online/iso-27001/annex-a-2022/8-32-change-management-2022/) - [ISO 27001 Change Management Policy: A Complete Guide](https://sprinto.com/blog/iso-27001-change-management-policy/) - [Mastering `set -e` in Linux](https://linuxvox.com/blog/linux-set-e/) - [Google SRE Book — Eliminating Toil](https://sre.google/workbook/eliminating-toil/) - [Testing Idempotence for Infrastructure as Code](https://www.researchgate.net/publication/255978303_Testing_Idempotence_for_Infrastructure_as_Code) - [Google Cloud Anthos — Running preflight checks](https://docs.cloud.google.com/anthos/clusters/docs/on-prem/1.11/how-to/preflight-checks)