From 26db69c9eb38fda8d03f39f2728fc184f3b0f5f9 Mon Sep 17 00:00:00 2001 From: vickydotbat Date: Thu, 7 May 2026 15:12:00 +0200 Subject: [PATCH] Script Wrapper Contract --- SCRIPT_WRAPPER_CONTRACT.md | 267 +++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 SCRIPT_WRAPPER_CONTRACT.md diff --git a/SCRIPT_WRAPPER_CONTRACT.md b/SCRIPT_WRAPPER_CONTRACT.md new file mode 100644 index 0000000..74cceeb --- /dev/null +++ b/SCRIPT_WRAPPER_CONTRACT.md @@ -0,0 +1,267 @@ +Refactor and harden all shell wrapper scripts across the module and assets repositories. + +# Problem + +The current `.sh` and `.ps1` wrapper scripts do not properly forward arbitrary CLI arguments to the underlying toolkit commands. + +Example: + +- `--verbose` +- `--debug` +- `--dry-run` +- `--config` +- `--dataset` +- `--force` +- future flags + +Many wrappers only support fixed commands or partially forward arguments. + +Additionally, after recent refactors — including: + +- YAML configuration migration +- configuration hardening +- toolkit restructuring +- command refactors +- repository abstraction changes + +— several wrapper scripts are now outdated and no longer correctly reflect the current toolkit behavior. + +Example of a recent error produced: + +```bash +$ ./build-haks.sh +run-nwn-tool.sh: Updating sow-toolkit to match latest sow-tools release... +installed: ${HOME}/Projects/nwnee-shadowsoverwestgate/assets/tools/sow-toolkit +run-nwn-tool.sh: Refreshing credits cache before build-haks... +Traceback (most recent call last): + File "${HOME}/Projects/nwnee-shadowsoverwestgate/assets/./scripts/sync-credits-cache.py", line 61, in + main() + ~~~~^^ + File "${HOME}/Projects/nwnee-shadowsoverwestgate/assets/./scripts/sync-credits-cache.py", line 46, in main + music_configs = load_music_configs() + File "${HOME}/Projects/nwnee-shadowsoverwestgate/assets/./scripts/sync-credits-cache.py", line 16, in load_music_configs + config = json.loads(CONFIG_PATH.read_text(encoding="utf-8")) + ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^ + File "/usr/lib/python3.14/pathlib/__init__.py", line 787, in read_text + with self.open(mode='r', encoding=encoding, errors=errors, newline=newline) as f: + ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/usr/lib/python3.14/pathlib/__init__.py", line 771, in open + return io.open(self, mode, buffering, encoding, errors, newline) + ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +FileNotFoundError: [Errno 2] No such file or directory: '${HOME}/Projects/nwnee-shadowsoverwestgate/assets/nwn-tool.json' +``` + +# Goal + +Make all wrapper scripts: + +- consistent +- argument-transparent +- future-safe +- deterministic +- repository-agnostic where possible + +# Core requirements + +## Global argument forwarding + +All wrappers must forward arbitrary arguments transparently to the underlying command. + +Examples: + +```bash +./run-tool.sh build-haks --verbose +./run-tool.sh music build --dataset westgate --dry-run +./extract-module.sh --debug --force +``` + +Must correctly pass all additional arguments through unchanged. + +PowerShell wrappers must behave equivalently: + +```powershell +.\run-tool.ps1 build-haks --verbose +``` + +No wrapper should: + +- silently swallow arguments +- hardcode known flags only +- require updating for every new CLI option +- partially parse arguments unless absolutely necessary + +Wrappers should behave as thin passthrough layers. + +# Wrapper audit + +Audit all `.sh` and `.ps1` scripts in: + +- module repositories +- assets repositories +- toolkit-related repositories + +Identify wrappers that: + +- no longer match current toolkit commands +- reference outdated config paths +- reference old JSON config names +- assume old directory layouts +- assume deprecated commands +- hardcode obsolete arguments +- bypass the new normalized YAML config system +- duplicate logic now handled in the toolkit + +# Consistency requirements + +All wrappers should follow consistent conventions: + +- argument forwarding +- environment setup +- working directory resolution +- config resolution +- logging behavior +- error handling +- exit code propagation +- path normalization +- quoting/escaping + +# Behavior requirements + +## Argument passthrough + +Shell wrappers should use safe passthrough semantics. + +Examples: + +- Bash: `"$@"` +- PowerShell: `@args` + +Arguments must preserve: + +- ordering +- quoting +- spaces +- special characters + +## Exit codes + +Wrappers must propagate underlying command exit codes correctly. + +No swallowing failures. + +## Logging + +Wrappers should: + +- print concise execution summaries +- show the underlying toolkit command being executed +- optionally support wrapper-level debug logging +- avoid duplicating toolkit logs + +## Configuration awareness + +Wrappers must support: + +- YAML config paths +- overridden config locations +- repository-local config resolution +- future config expansion + +No wrapper should assume: + +- `config.json` +- fixed build paths +- fixed repository names +- fixed datasets +- fixed HAK names + +# Repository hardening alignment + +Wrappers must align with the broader configuration hardening effort: + +- no repository-specific hardcoding +- no hidden defaults +- no implicit assumptions +- no duplicated business logic + +Wrappers should invoke toolkit functionality, not reimplement it. + +# Desired architecture + +Wrappers should become: + +- thin launchers +- environment bootstrap layers +- argument passthrough adapters + +The toolkit itself should contain: + +- validation +- command parsing +- config loading +- business logic +- deterministic behavior + +# Cross-platform behavior + +Ensure `.sh` and `.ps1` wrappers behave equivalently where possible. + +Validate: + +- quoting +- argument escaping +- relative path handling +- environment variable handling +- error propagation +- working directory behavior + +# Migration tasks + +1. Inventory all wrappers. +2. Classify active vs obsolete wrappers. +3. Update wrappers to support transparent argument forwarding. +4. Remove outdated assumptions. +5. Align wrappers with YAML config loading. +6. Update docs/examples/help text. +7. Add regression tests. +8. Ensure compatibility with current toolkit commands. +9. Remove duplicated wrapper logic where possible. +10. Consolidate shared wrapper behavior if appropriate. + +# Testing requirements + +Add tests for: + +- argument passthrough +- quoted arguments +- multi-argument forwarding +- verbose/debug forwarding +- config override forwarding +- dataset override forwarding +- exit code propagation +- invalid command handling +- PowerShell parity +- shell parity +- wrapper execution from different working directories + +Examples: + +- `--verbose` +- `--debug` +- `--dry-run` +- `--config path/to/config.yaml` +- `--dataset westgate` +- `--force` +- unknown future flags + +# Acceptance criteria + +- All wrappers forward arbitrary arguments correctly. +- Wrappers reflect the current toolkit architecture. +- No wrappers assume old JSON config behavior. +- No wrappers contain obsolete repository-specific logic. +- Wrapper behavior is deterministic and cross-platform. +- Exit codes propagate correctly. +- Wrapper maintenance burden is minimized. +- New CLI flags work automatically without wrapper updates. +- The toolkit, not wrappers, owns application logic.