Script Engineering
Use this skill for cross-language script selection and for the engineering rules
shared by repository automation scripts. Derive the available runtimes, supported
platforms, script layout, and validation commands from the target repository and
execution environment instead of assuming a universal tool list.
Use the matching language engineering skill when implementation needs
language-specific depth. Use justfiles when changing
the Just command surface; this skill owns the script behind that surface.
Workflow
- Inspect repository instructions, script directories, shebangs, file
extensions, manifests, version files, lockfiles, task runners, CI images,
containers, tests, and documentation.
- Identify every execution target: developer hosts, Windows or Unix-like
systems, containers, CI runners, remote hosts, or production automation.
- Decide whether the behavior should be a script. Prefer an existing command,
task-runner recipe, application module, migration framework, or service when
that is the clearer maintained boundary.
- Choose the least complex language that is already supported across the
required targets. Do not add a runtime merely to make a small script more
convenient to author.
- Define inputs, outputs, exit codes, side effects, working-directory rules,
dependencies, idempotence expectations, preview behavior, and cleanup before
implementing risky or reusable automation.
- Implement in small testable units. Keep command construction explicit,
validate arguments, quote paths and values correctly for the chosen language,
and avoid hidden ambient state.
- Run syntax/static checks and behavioral tests narrowly, then run the
repository's broader script, task-runner, and CI-equivalent quality lanes.
- Report the runtime evidence, language choice, behavior covered, commands run,
skipped target platforms, and residual risk.
Establish Runtime Availability
Treat availability as evidence about one target environment, not a fixed list:
- Repository evidence comes first: shebangs, existing scripts, version managers,
package manifests, lockfiles, toolchain files, containers, CI configuration,
setup docs, and task-runner recipes.
- Confirm the interpreter on each relevant target with a non-mutating lookup such
as
command -v <interpreter>, type <interpreter>, or PowerShell
Get-Command <interpreter>, followed by the appropriate version command when
version compatibility matters.
- Distinguish POSIX
sh, Bash, and other shells. A working interactive shell does
not prove that a script's shebang or requested shell exists elsewhere.
- Distinguish PowerShell 7+ (
pwsh) from Windows PowerShell
(powershell.exe) when features or platform support differ.
- Treat an agent permission to request or execute a command as authorization,
not proof that the interpreter is installed. A script never broadens the
agent's edit, shell, network, external-directory, or destructive-action
authority.
- If required target availability cannot be established, preserve the existing
repository convention or stop and report the uncertainty rather than silently
adding a new runtime assumption.
Decide Whether To Script
Do not create a durable script when:
- one short, readable, low-risk existing command or task-runner recipe is enough;
- the behavior is domain or application logic that callers should import and
test through the normal application boundary;
- the repository already provides a maintained generator, migration tool,
package command, or platform-native mechanism for the operation;
- the work needs a long-running process, durable state, recovery, rich
concurrency, or an interactive interface better expressed as an application;
- a new interpreter or test framework would cost more than the automation saves;
or
- the script would conceal destructive, credentialed, or remote operations, or
work around command approval, sandbox, policy, or audit requirements.
One-off does not automatically mean unscripted. Data migrations, releases, and
other high-risk operations often need a reviewed, repeatable implementation with
preview, rollback, and evidence rather than an improvised terminal sequence.
Use the smallest durable boundary that remains understandable:
- keep one short, safe command inline;
- use a task-runner or package recipe as a discoverable thin entry point;
- move reusable or branching behavior into an independently tested script; and
- promote substantial domain behavior, concurrency, state, recovery, or public
interfaces into an application module, library, or maintained CLI.
Do not keep growing a shell or package-script body after quoting, parsing,
branching, cleanup, or state management becomes the main engineering work.
Choose A Language
Prefer the repository's established language when it satisfies the target
platforms and keeps the workflow maintainable.
| Choice |
Prefer when |
Move to another language when |
POSIX sh |
The script is a small portable sequence of commands with limited branching and no Bash-only features. |
Arrays, complex data, substantial parsing, or non-POSIX features are required. |
| Bash |
Unix-like targets guarantee Bash and shell-native orchestration, pipelines, traps, or Bash data structures materially simplify the task. |
Portability excludes Bash, or quoting, parsing, branching, and state are becoming the main work. |
| zsh |
The repository explicitly owns zsh configuration or every target guarantees the required zsh version and features. |
The script is general repository automation, runs in CI/containers without zsh, or POSIX sh/Bash is sufficient. |
| Fish |
The behavior is intentionally Fish-specific interactive configuration, functions, or completions for known Fish users. |
The script is portable automation or must run under POSIX-compatible shells; Fish syntax is not POSIX shell syntax. |
| Python |
The task handles structured data, files, APIs, reusable functions, robust CLI parsing, subprocess orchestration, or meaningful cross-platform behavior. |
The repository does not support Python on every target, or a tiny shell command is clearer. |
| Ruby |
The repository already supports Ruby and the automation benefits from Ruby code, locked gems, text/data handling, or a Ruby application/Rake boundary. |
Ruby is absent from bootstrap or target hosts, or an existing supported language provides a clearer path. |
| PHP |
The repository/runtime already supports PHP and the script benefits from application code or Composer-autoloaded libraries. |
PHP is not established on all targets, or an existing simpler runtime is clearer. #!/usr/bin/env php is Unix-like CLI packaging, not proof of Windows portability. |
| PowerShell |
Windows administration, registry/services, Microsoft modules, .NET objects, or an existing cross-platform PowerShell workflow is the natural boundary. |
Required targets do not provide the needed PowerShell edition, or the repository already has a simpler supported runtime. |
| JavaScript or TypeScript |
The repository already standardizes on Node, Bun, or Deno and the script benefits from its package/tooling ecosystem. |
Adding that runtime would create a new dependency or the script is simpler in an existing shell/Python workflow. |
| Another existing runtime |
Local evidence shows it is the repository's supported automation language and all targets provide it. |
Selection is based only on author familiarity or introduces an otherwise unused toolchain. |
Load python-engineering for Python
implementation, packaging, and pytest/unittest workflow. Load
ruby-engineering for Ruby, Bundler, gems,
idioms, and Minitest/RSpec workflow. Load
powershell-engineering for idiomatic and
cross-platform PowerShell implementation, Pester, and PSScriptAnalyzer. Load
javascript-typescript-engineering
for JavaScript or TypeScript runtime, package, type, lint, and test workflow.
Load php-engineering for PHP syntax, Composer,
static analysis, process APIs, streams, and exit-code mechanics; load
php-testing-quality for PHPUnit/Pest lanes.
Do not select zsh or Fish merely because it is the author's interactive shell.
Interactive convenience is not evidence that CI, containers, developer hosts,
or production targets provide that shell.
Script Contract And Safety
- Keep scripts deterministic and non-interactive by default. Make prompts an
explicit user-facing mode, never an accidental CI or agent dependency.
- Use documented arguments and environment variables. Validate required values
and return nonzero exit codes with actionable stderr on failure.
- Keep machine-readable stdout stable when other tools consume it; send progress
and diagnostics to stderr.
- Resolve working-directory and relative-path behavior deliberately. Do not
assume the caller starts beside the script unless that is the documented
contract.
- Use temporary directories or files with collision-safe creation and guaranteed
cleanup. Load
random-data-identifiers
when generated names, nonces, tokens, fixtures, or reproducible randomness are
material.
- Prefer idempotent behavior. For destructive, remote, production, or
credentialed operations, provide a meaningful preview or dry-run, validate the
exact target, and make the apply step explicit.
- Never print secrets. Avoid
eval, dynamically assembled shell command strings,
and interpolation of untrusted values into a shell; prefer argument arrays or
direct process APIs.
- Pin or otherwise reproducibly provision non-standard interpreters, linters,
runners, and helper binaries through the repository's existing dependency
workflow.
Test Scripts
Start with observable behavior: arguments, environment inputs, stdout, stderr,
exit status, created or changed files, cleanup, and external-command boundaries.
Use temporary isolated fixtures and test failure paths as well as success.
| Script type |
Syntax and static checks |
Behavioral tests |
| POSIX shell |
Run the target shell's no-execute syntax check where supported and ShellCheck with the intended dialect. |
Run black-box tests under every shell/platform the repository claims to support. Prefer the existing runner; ShellSpec is an option when multi-shell behavior needs a framework. |
| Bash |
Run bash -n and the repository's configured ShellCheck lane. |
Prefer the existing Bash runner. bash_unit is suitable for function-oriented assertions, setup/teardown, status checks, and TAP output; Bats-core is suited to command-oriented Bash tests. |
| zsh or Fish |
Run the selected shell's parser/no-execute check where available and any configured linter. |
Test under the exact supported shell versions; do not use POSIX/Bash tests as proof of zsh or Fish behavior. |
| Python |
Run the configured formatter, linter, and type checker as applicable. |
Use the repository's pytest or unittest lane through its managed environment; test CLI behavior at process boundaries when invocation is part of the contract. |
| Ruby |
Run ruby -c on affected entry points plus configured format/lint checks. |
Use the repository's Minitest or RSpec lane through Bundler, with process-level tests when arguments, streams, or exit status are contractual. |
| PHP |
Run php -l only as a syntax check, plus configured formatter/static-analysis checks. |
Use the repository's PHPUnit/Pest or process-level behavioral lane; syntax success is not behavioral proof. |
| PowerShell |
Run the repository's parser or PSScriptAnalyzer lane when configured. |
Use Pester for functions, modules, commands, side effects, and error behavior. Test both pwsh and Windows PowerShell only when both are supported targets. |
| JavaScript or TypeScript |
Run the configured format, lint, type-check, and build lanes. |
Use the repository's configured test runner and add process-level tests when the CLI contract matters. |
Static analysis is not a substitute for behavioral tests. Conversely, do not add
a test framework for a trivial wrapper when a syntax check plus one repository
smoke test provides proportionate confidence. Adding or downloading a runner,
linter, interpreter, binary, or installer invokes
dependency-supply-chain-review;
do not copy unpinned curl | shell installation examples into project workflows.
Use test-driven-development when new
behavior or a regression can be driven through Red-Green-Refactor. Use
systematic-debugging first for an active
unexplained script failure.
Use Scripts With Just
When a repository uses Just, expose supported workflows through small,
documented recipes and keep substantial logic in independently testable scripts:
- Keep one short command inline when quoting, control flow, and reuse remain
obvious. A shebang recipe can hold a modest self-contained operation.
- Move reusable logic, functions, substantial branching, robust argument
parsing, or independently tested behavior to the repository's established
script directory. Keep the recipe a thin parameterized wrapper.
- Resolve script paths from the Justfile location rather than relying on the
caller's current directory.
- Pass deliberate arguments through the recipe instead of duplicating defaults,
environment parsing, validation, or business rules in both layers.
- Provide narrow script-test recipes and include them in the repository's normal
check or verification lane when local conventions support that shape. Derive
actual recipe names from the repository rather than inventing universal names.
- Pair risky apply recipes with preview/status recipes and preserve the same
target validation inside the script; a task-runner confirmation prompt is not
the only safety control.
Load justfiles for recipe syntax, parameters, groups,
imports/modules, shell configuration, listing behavior, and Just validation.
Workflow Routing
- Load
ci-release-engineering when the
change affects hosted workflow triggers, jobs, permissions, artifacts, or
automated release behavior; scripts own only the commands that workflow runs.
- Load
container-engineering when changing
Dockerfile, OCI image, or Compose behavior; scripts own only their contained
automation contract.
- Load
security-review for concrete scripts that
handle credentials, secrets, auth, command execution, untrusted input, paths,
privileged operations, or remote/production targets. Use
security-review-evidence when captured
output, fixtures, or reports may contain sensitive values.
- Consult current official documentation for version-specific behavior of an
external interpreter, runner, linter, task runner, or module after inspecting
the repository's pinned version and local usage.
Completion Evidence
Report:
- the repository and target-environment evidence used to establish runtimes;
- why a script was appropriate and why the selected language fit better than the
credible local alternatives;
- changed script, tests, task-runner, dependency, and documentation files;
- syntax, static-analysis, behavioral, platform, and broader quality checks run;
and
- skipped target environments, unverified interpreter assumptions, and residual
operational or security risk.
1---2name: script-engineering3description: Script and automation engineering guidance. Use when creating, changing, reviewing, or testing POSIX shell, Bash, zsh, Fish, PowerShell, Python, Ruby, PHP, Node, or other repository scripts; choosing a scripting language or interpreter; deciding whether automation belongs in a script or shell; or exposing script workflows through Just or package scripts. Do not use when only running an existing script or recipe, for ordinary application code with no automation surface, or for hosted CI/release-provider or container semantics beyond the commands scripts invoke.4---56# Script Engineering78Use this skill for cross-language script selection and for the engineering rules9shared by repository automation scripts. Derive the available runtimes, supported10platforms, script layout, and validation commands from the target repository and11execution environment instead of assuming a universal tool list.1213Use the matching language engineering skill when implementation needs14language-specific depth. Use [`justfiles`](../justfiles/SKILL.md) when changing15the Just command surface; this skill owns the script behind that surface.1617## Workflow18191. Inspect repository instructions, script directories, shebangs, file20 extensions, manifests, version files, lockfiles, task runners, CI images,21 containers, tests, and documentation.222. Identify every execution target: developer hosts, Windows or Unix-like23 systems, containers, CI runners, remote hosts, or production automation.243. Decide whether the behavior should be a script. Prefer an existing command,25 task-runner recipe, application module, migration framework, or service when26 that is the clearer maintained boundary.274. Choose the least complex language that is already supported across the28 required targets. Do not add a runtime merely to make a small script more29 convenient to author.305. Define inputs, outputs, exit codes, side effects, working-directory rules,31 dependencies, idempotence expectations, preview behavior, and cleanup before32 implementing risky or reusable automation.336. Implement in small testable units. Keep command construction explicit,34 validate arguments, quote paths and values correctly for the chosen language,35 and avoid hidden ambient state.367. Run syntax/static checks and behavioral tests narrowly, then run the37 repository's broader script, task-runner, and CI-equivalent quality lanes.388. Report the runtime evidence, language choice, behavior covered, commands run,39 skipped target platforms, and residual risk.4041## Establish Runtime Availability4243Treat availability as evidence about one target environment, not a fixed list:4445- Repository evidence comes first: shebangs, existing scripts, version managers,46 package manifests, lockfiles, toolchain files, containers, CI configuration,47 setup docs, and task-runner recipes.48- Confirm the interpreter on each relevant target with a non-mutating lookup such49 as `command -v <interpreter>`, `type <interpreter>`, or PowerShell50 `Get-Command <interpreter>`, followed by the appropriate version command when51 version compatibility matters.52- Distinguish POSIX `sh`, Bash, and other shells. A working interactive shell does53 not prove that a script's shebang or requested shell exists elsewhere.54- Distinguish PowerShell 7+ (`pwsh`) from Windows PowerShell55 (`powershell.exe`) when features or platform support differ.56- Treat an agent permission to request or execute a command as authorization,57 not proof that the interpreter is installed. A script never broadens the58 agent's edit, shell, network, external-directory, or destructive-action59 authority.60- If required target availability cannot be established, preserve the existing61 repository convention or stop and report the uncertainty rather than silently62 adding a new runtime assumption.6364## Decide Whether To Script6566Do not create a durable script when:6768- one short, readable, low-risk existing command or task-runner recipe is enough;69- the behavior is domain or application logic that callers should import and70 test through the normal application boundary;71- the repository already provides a maintained generator, migration tool,72 package command, or platform-native mechanism for the operation;73- the work needs a long-running process, durable state, recovery, rich74 concurrency, or an interactive interface better expressed as an application;75- a new interpreter or test framework would cost more than the automation saves;76 or77- the script would conceal destructive, credentialed, or remote operations, or78 work around command approval, sandbox, policy, or audit requirements.7980One-off does not automatically mean unscripted. Data migrations, releases, and81other high-risk operations often need a reviewed, repeatable implementation with82preview, rollback, and evidence rather than an improvised terminal sequence.8384Use the smallest durable boundary that remains understandable:85861. keep one short, safe command inline;872. use a task-runner or package recipe as a discoverable thin entry point;883. move reusable or branching behavior into an independently tested script; and894. promote substantial domain behavior, concurrency, state, recovery, or public90 interfaces into an application module, library, or maintained CLI.9192Do not keep growing a shell or package-script body after quoting, parsing,93branching, cleanup, or state management becomes the main engineering work.9495## Choose A Language9697Prefer the repository's established language when it satisfies the target98platforms and keeps the workflow maintainable.99100| Choice | Prefer when | Move to another language when |101| --- | --- | --- |102| POSIX `sh` | The script is a small portable sequence of commands with limited branching and no Bash-only features. | Arrays, complex data, substantial parsing, or non-POSIX features are required. |103| Bash | Unix-like targets guarantee Bash and shell-native orchestration, pipelines, traps, or Bash data structures materially simplify the task. | Portability excludes Bash, or quoting, parsing, branching, and state are becoming the main work. |104| zsh | The repository explicitly owns zsh configuration or every target guarantees the required zsh version and features. | The script is general repository automation, runs in CI/containers without zsh, or POSIX `sh`/Bash is sufficient. |105| Fish | The behavior is intentionally Fish-specific interactive configuration, functions, or completions for known Fish users. | The script is portable automation or must run under POSIX-compatible shells; Fish syntax is not POSIX shell syntax. |106| Python | The task handles structured data, files, APIs, reusable functions, robust CLI parsing, subprocess orchestration, or meaningful cross-platform behavior. | The repository does not support Python on every target, or a tiny shell command is clearer. |107| Ruby | The repository already supports Ruby and the automation benefits from Ruby code, locked gems, text/data handling, or a Ruby application/Rake boundary. | Ruby is absent from bootstrap or target hosts, or an existing supported language provides a clearer path. |108| PHP | The repository/runtime already supports PHP and the script benefits from application code or Composer-autoloaded libraries. | PHP is not established on all targets, or an existing simpler runtime is clearer. `#!/usr/bin/env php` is Unix-like CLI packaging, not proof of Windows portability. |109| PowerShell | Windows administration, registry/services, Microsoft modules, .NET objects, or an existing cross-platform PowerShell workflow is the natural boundary. | Required targets do not provide the needed PowerShell edition, or the repository already has a simpler supported runtime. |110| JavaScript or TypeScript | The repository already standardizes on Node, Bun, or Deno and the script benefits from its package/tooling ecosystem. | Adding that runtime would create a new dependency or the script is simpler in an existing shell/Python workflow. |111| Another existing runtime | Local evidence shows it is the repository's supported automation language and all targets provide it. | Selection is based only on author familiarity or introduces an otherwise unused toolchain. |112113Load [`python-engineering`](../python-engineering/SKILL.md) for Python114implementation, packaging, and pytest/unittest workflow. Load115[`ruby-engineering`](../ruby-engineering/SKILL.md) for Ruby, Bundler, gems,116idioms, and Minitest/RSpec workflow. Load117[`powershell-engineering`](../powershell-engineering/SKILL.md) for idiomatic and118cross-platform PowerShell implementation, Pester, and PSScriptAnalyzer. Load119[`javascript-typescript-engineering`](../javascript-typescript-engineering/SKILL.md)120for JavaScript or TypeScript runtime, package, type, lint, and test workflow.121Load [`php-engineering`](../php-engineering/SKILL.md) for PHP syntax, Composer,122static analysis, process APIs, streams, and exit-code mechanics; load123[`php-testing-quality`](../php-testing-quality/SKILL.md) for PHPUnit/Pest lanes.124125Do not select zsh or Fish merely because it is the author's interactive shell.126Interactive convenience is not evidence that CI, containers, developer hosts,127or production targets provide that shell.128129## Script Contract And Safety130131- Keep scripts deterministic and non-interactive by default. Make prompts an132 explicit user-facing mode, never an accidental CI or agent dependency.133- Use documented arguments and environment variables. Validate required values134 and return nonzero exit codes with actionable stderr on failure.135- Keep machine-readable stdout stable when other tools consume it; send progress136 and diagnostics to stderr.137- Resolve working-directory and relative-path behavior deliberately. Do not138 assume the caller starts beside the script unless that is the documented139 contract.140- Use temporary directories or files with collision-safe creation and guaranteed141 cleanup. Load [`random-data-identifiers`](../random-data-identifiers/SKILL.md)142 when generated names, nonces, tokens, fixtures, or reproducible randomness are143 material.144- Prefer idempotent behavior. For destructive, remote, production, or145 credentialed operations, provide a meaningful preview or dry-run, validate the146 exact target, and make the apply step explicit.147- Never print secrets. Avoid `eval`, dynamically assembled shell command strings,148 and interpolation of untrusted values into a shell; prefer argument arrays or149 direct process APIs.150- Pin or otherwise reproducibly provision non-standard interpreters, linters,151 runners, and helper binaries through the repository's existing dependency152 workflow.153154## Test Scripts155156Start with observable behavior: arguments, environment inputs, stdout, stderr,157exit status, created or changed files, cleanup, and external-command boundaries.158Use temporary isolated fixtures and test failure paths as well as success.159160| Script type | Syntax and static checks | Behavioral tests |161| --- | --- | --- |162| POSIX shell | Run the target shell's no-execute syntax check where supported and ShellCheck with the intended dialect. | Run black-box tests under every shell/platform the repository claims to support. Prefer the existing runner; [ShellSpec](https://github.com/shellspec/shellspec) is an option when multi-shell behavior needs a framework. |163| Bash | Run `bash -n` and the repository's configured ShellCheck lane. | Prefer the existing Bash runner. [`bash_unit`](https://github.com/bash-unit/bash_unit) is suitable for function-oriented assertions, setup/teardown, status checks, and TAP output; [Bats-core](https://github.com/bats-core/bats-core) is suited to command-oriented Bash tests. |164| zsh or Fish | Run the selected shell's parser/no-execute check where available and any configured linter. | Test under the exact supported shell versions; do not use POSIX/Bash tests as proof of zsh or Fish behavior. |165| Python | Run the configured formatter, linter, and type checker as applicable. | Use the repository's pytest or unittest lane through its managed environment; test CLI behavior at process boundaries when invocation is part of the contract. |166| Ruby | Run `ruby -c` on affected entry points plus configured format/lint checks. | Use the repository's Minitest or RSpec lane through Bundler, with process-level tests when arguments, streams, or exit status are contractual. |167| PHP | Run `php -l` only as a syntax check, plus configured formatter/static-analysis checks. | Use the repository's PHPUnit/Pest or process-level behavioral lane; syntax success is not behavioral proof. |168| PowerShell | Run the repository's parser or PSScriptAnalyzer lane when configured. | Use [Pester](https://pester.dev/) for functions, modules, commands, side effects, and error behavior. Test both `pwsh` and Windows PowerShell only when both are supported targets. |169| JavaScript or TypeScript | Run the configured format, lint, type-check, and build lanes. | Use the repository's configured test runner and add process-level tests when the CLI contract matters. |170171Static analysis is not a substitute for behavioral tests. Conversely, do not add172a test framework for a trivial wrapper when a syntax check plus one repository173smoke test provides proportionate confidence. Adding or downloading a runner,174linter, interpreter, binary, or installer invokes175[`dependency-supply-chain-review`](../dependency-supply-chain-review/SKILL.md);176do not copy unpinned `curl | shell` installation examples into project workflows.177178Use [`test-driven-development`](../test-driven-development/SKILL.md) when new179behavior or a regression can be driven through Red-Green-Refactor. Use180[`systematic-debugging`](../systematic-debugging/SKILL.md) first for an active181unexplained script failure.182183## Use Scripts With Just184185When a repository uses Just, expose supported workflows through small,186documented recipes and keep substantial logic in independently testable scripts:187188- Keep one short command inline when quoting, control flow, and reuse remain189 obvious. A shebang recipe can hold a modest self-contained operation.190- Move reusable logic, functions, substantial branching, robust argument191 parsing, or independently tested behavior to the repository's established192 script directory. Keep the recipe a thin parameterized wrapper.193- Resolve script paths from the Justfile location rather than relying on the194 caller's current directory.195- Pass deliberate arguments through the recipe instead of duplicating defaults,196 environment parsing, validation, or business rules in both layers.197- Provide narrow script-test recipes and include them in the repository's normal198 check or verification lane when local conventions support that shape. Derive199 actual recipe names from the repository rather than inventing universal names.200- Pair risky apply recipes with preview/status recipes and preserve the same201 target validation inside the script; a task-runner confirmation prompt is not202 the only safety control.203204Load [`justfiles`](../justfiles/SKILL.md) for recipe syntax, parameters, groups,205imports/modules, shell configuration, listing behavior, and Just validation.206207## Workflow Routing208209- Load [`ci-release-engineering`](../ci-release-engineering/SKILL.md) when the210 change affects hosted workflow triggers, jobs, permissions, artifacts, or211 automated release behavior; scripts own only the commands that workflow runs.212- Load [`container-engineering`](../container-engineering/SKILL.md) when changing213 Dockerfile, OCI image, or Compose behavior; scripts own only their contained214 automation contract.215- Load [`security-review`](../security-review/SKILL.md) for concrete scripts that216 handle credentials, secrets, auth, command execution, untrusted input, paths,217 privileged operations, or remote/production targets. Use218 [`security-review-evidence`](../security-review-evidence/SKILL.md) when captured219 output, fixtures, or reports may contain sensitive values.220- Consult current official documentation for version-specific behavior of an221 external interpreter, runner, linter, task runner, or module after inspecting222 the repository's pinned version and local usage.223224## Completion Evidence225226Report:227228- the repository and target-environment evidence used to establish runtimes;229- why a script was appropriate and why the selected language fit better than the230 credible local alternatives;231- changed script, tests, task-runner, dependency, and documentation files;232- syntax, static-analysis, behavioral, platform, and broader quality checks run;233 and234- skipped target environments, unverified interpreter assumptions, and residual235 operational or security risk.