Add layered environment model and taskfile composition rules

Fold two overlapping local skills (scripts-shell, shell-scripts-module)
into this one, keeping only what it did not already cover.

- Add references/environment-model.md: the three-layer .env selector model,
  why set -a dot-sourcing beats export $(grep|xargs), tracked samples, the
  no-re-sourcing rule for module readers, and the deployment boundary
  (repo-presence is not git-tracked is not deployed).
- Extend references/taskfile.md with the one-env-driven-task rule (no
  :default pairs) and composing commands through the task surface.
- Add the lifecycle-hook module type to references/module-patterns.md.
- Keep this skill's _moduleExampleV1_ naming as canonical; the retired
  skills' HL_V1_ and double-underscore dialects were not carried over.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 22:45:32 +03:00
co-authored by Claude Opus 5
parent b0aabae566
commit 6c8446cf90
5 changed files with 191 additions and 2 deletions
+36
View File
@@ -41,6 +41,42 @@ task module-example-v1:initialize-one -- --name demo --dry-run
Without the `--`, task treats the flags as its own and the script never sees them.
### One env-driven task, not a `:default` pair
Where the repository uses the layered environment model
(`references/environment-model.md`), the env layers already supply every value a task needs.
A module therefore needs **one** task, not a `<task>` + `<task>:default` pair that hardcodes
what the environment already provides:
```yaml
tasks:
initialize-one:
desc: Initialize using the .env layers (override with --flag=…)
cmds:
- ./.scripts/module-example-v1/api/initialize-one.sh {{.CLI_ARGS}}
silent: true
```
A `:default` wrapper duplicates configuration in a second place, and the two drift.
Environment-specific behaviour belongs in `.env-<env>`; one-off overrides belong in flags
after `--`.
### Composing commands
When an operator-facing command already exists, prefer calling it through `task` rather than
re-implementing or sourcing its internals, and pass parameters explicitly:
```bash
task keycloak:realm-registration-enable-one -- --realm-id="${KEYCLOAK_ROOT_REALM_ID}"
```
Composing at the task surface keeps the public contract the only contract. Reaching into
another module's `lib/` couples you to its internals and bypasses its reader and validator.
Do not add a second entrypoint for an operation that already has one unless it carries clear
operator value — duplicate entrypoints drift apart and it stops being obvious which is
authoritative.
---
## 2. Root `Taskfile.yml` include