A templated script is opaque to every tool that reads shell. shellcheck parses Jinja as syntax errors, the repository's own .sh guards skip the file because it is not a .sh, and nothing can execute it to test it: what runs on the host never exists in the repository, so a defect in the rendered half is found by deploying it.
The lint reports any *.sh.j2 under roles and points at the static slot sys-service already resolves, files/shell/script.sh, with the values passed as ExecStart arguments or Environment entries the way this repository's python scripts already take them.
None of the seven templates present meets the bar the marker is for, which is a script whose shape is generated rather than its values. Each is grandfathered with a marker naming what it interpolates, because converting a deployed script to argv changes what runs on the host. The guard exists to stop the next one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3529 invalid comments in 528 files, grandfathered in while the linter
only saw the working-tree diff. Removal ran through the linter's own
collectors, so detection and deletion cannot drift: a comment whose
opener line is blank before it and whose closer line is blank after it
loses all its lines, anything else loses only the comment region, and a
line left holding a bare delimiter goes with it.
Five files keep their comments behind a nocheck marker instead. Four are
upstream configs whose inline docs are upstream's own (mautrix, systemd
journald, nextcloud-oidc-login, MediaWiki). In littlejs the
commented-out entries ARE the deactivation mechanism for an example
tile, so deleting them would delete configuration.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Improved get_service_name filter plugin (clearer suffix handling, consistent var names).
- Added MODE_ASSERT flag to optionally execute validation/assertion tasks.
- Fixed systemd unit handling: consistent use of %I instead of %i, correct escaping of instance names.
- Unified on_failure behavior and alarm composer scripts.
- Cleaned up redundant logging, handlers, and debug config.
- Strengthened sys-service template resolution with assert (only active when MODE_ASSERT).
- Simplified timer and suffix handling with get_service_name filter.
- Hardened sensitive tasks with no_log.
- Added conditional asserts across roles (Keycloak, DNS, Mailu, Discourse, etc.).
These changes improve consistency, safety, and validation across the automation stack.
Conversation: https://chatgpt.com/share/68a4ae28-483c-800f-b2f7-f64c7124c274
- Fixed bug where not both alarm services (email + telegram) were triggered.
- Removed direct OnFailure references for email and telegram,
now handled by unified compose service.
- Introduced 01_core.yml in sys-ctl-alm-compose to structure
role execution (subservices → core service → test run).
- Added configurable variables SYSTEMCTL_ALARM_COMPOSER_SUBSERVICES
and SYSTEMCTL_ALARM_COMPOSER_DUMMY_MESSAGE.
- Replaced dedicated @.service template with generic systemctl template
using systemctl_tpl_* variables for flexibility.
- Updated script.sh.j2 to collect exit codes and print clear errors.
- Fixed typos and streamlined vars in sys-systemctl.
See conversation: https://chatgpt.com/share/68a46172-7c3c-800f-a69c-0cb9edd6839f