agentleFS
nledfordnledford/engineering-review-board/skills/script-engineering/SKILL.md

script-engineering

Skill11 starsChanged 9 days agoMITView on GitHub

Script and automation engineering guidance. Use when creating, changing, reviewing, or testing POSIX shell, Bash, zsh, Fish, PowerShell, Python, Ruby, PHP, Node, Object Pascal/Delphi, 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.

  • Pipes a download into a shell

The file

Show its rules and text

We split this skill into the rules it gives an agent

24 rules. About 0 are common, 20 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈20

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill for cross-language script selection and for the engineering rules shared by repository automation scripts.

    line 8
  2. Very specific:

    Use the matching language engineering skill when implementation needs language-specific depth.

    line 13
  3. Distinctive:

    Run syntax/static checks and behavioral tests narrowly, then run the repository's broader script, task-runner, and CI-equivalent quality …

    line 36
  4. Distinctive:

    Treat availability as evidence about one target environment, not a fixed list:

    line 43
  5. Distinctive:

    Treat an agent permission to request or execute a command as authorization, not proof that the interpreter is installed.

    line 56
  6. Distinctive:

    If required target availability cannot be established, preserve the existing repository convention or stop and report the uncertainty …

    line 60
  7. Distinctive:

    Do not create a durable script when:

    line 66
  8. Distinctive:

    Use the smallest durable boundary that remains understandable:

    line 84
  9. Distinctive:

    keep one short, safe command inline.

    line 86
  10. Distinctive:

    use a task-runner or package recipe as a discoverable thin entry point.

    line 87
  11. Distinctive:

    Do not keep growing a shell or package-script body after quoting, parsing, branching, cleanup, or state management becomes the main …

    line 92
  12. Distinctive:

    Prefer the repository's established language when it satisfies the target platforms and keeps the workflow maintainable.

    line 97
  13. Distinctive:

    Do not select zsh or Fish merely because it is the author's interactive shell.

    line 121
  14. Distinctive:

    Keep scripts deterministic and non-interactive by default.

    line 127
  15. Distinctive:

    Use documented arguments and environment variables.

    line 129
  16. Distinctive:

    Keep machine-readable stdout stable when other tools consume it.

    line 131
  17. Very specific:

    Use temporary directories or files with collision-safe creation and guaranteed cleanup.

    line 136
  18. Distinctive:

    Prefer idempotent behavior.

    line 140
  19. Very specific:

    Never print secrets. Avoid eval, dynamically assembled shell command strings, and interpolation of untrusted values into a shell.

    line 143
  20. Distinctive:

    Start with observable behavior: arguments, environment inputs, stdout, stderr, exit status, created or changed files, cleanup, and …

    line 152
  21. Distinctive:

    Use temporary isolated fixtures and test failure paths as well as success.

    line 154
  22. Very specific:

    Use test-driven-development when new behavior or a regression can be driven through Red-Green-Refactor.

    line 174
  23. Distinctive:

    When a repository uses Just, expose supported workflows through small, documented recipes and keep substantial logic in independently …

    line 181
  24. Distinctive:

    Keep one short command inline when quoting, control flow, and reuse remain obvious.

    line 184

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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

  1. Inspect repository instructions, script directories, shebangs, file extensions, manifests, version files, lockfiles, task runners, CI images, containers, tests, and documentation.
  2. Identify every execution target: developer hosts, Windows or Unix-like systems, containers, CI runners, remote hosts, or production automation.
  3. 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.
  4. 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.
  5. Define inputs, outputs, exit codes, side effects, working-directory rules, dependencies, idempotence expectations, preview behavior, and cleanup before implementing risky or reusable automation.
  6. 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.
  7. Run syntax/static checks and behavioral tests narrowly, then run the repository's broader script, task-runner, and CI-equivalent quality lanes.
  8. 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:

  1. keep one short, safe command inline;
  2. use a task-runner or package recipe as a discoverable thin entry point;
  3. move reusable or branching behavior into an independently tested script; and
  4. 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.

ChoicePrefer whenMove to another language when
POSIX shThe 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.
BashUnix-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.
zshThe 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.
FishThe 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.
PythonThe 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.
RubyThe 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.
PHPThe 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.
PowerShellWindows 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 TypeScriptThe 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.
Object Pascal / DelphiThe repository already uses Delphi or Free Pascal and the automation benefits from its RTL, packages, or an existing Object Pascal codebase.The target does not provide the compiler or interpreter, or a simpler supported runtime is clearer.
Another existing runtimeLocal 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 javascript-typescript-engineering for JavaScript or TypeScript runtime, package, type, lint, and test workflow.

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 typeSyntax and static checksBehavioral tests
POSIX shellRun 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.
BashRun 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 FishRun 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.
PythonRun 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.
RubyRun 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.
PHPRun 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.
PowerShellRun 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 TypeScriptRun 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.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.