Skip to content

set -Eeuo pipefail Is Bash-Only, but the Shell Rules' Own Target Discovery Includes sh Shebangs #1182

Description

@ptr727

Raised by CodeRabbit on the develop -> main promotion PR #1179, and it holds up against the fleet's own tooling.

The Contradiction

CODESTYLE.md "Shell" and .agents/skills/shell-codestyle/SKILL.md "Rules" both mandate:

set -Eeuo pipefail, before the first command the script runs.

Neither -E nor pipefail is POSIX. A #!/bin/sh script running under dash rejects the line before its first command:

$ dash -c 'set -Eeuo pipefail'
dash: 1: set: Illegal option -E

Meanwhile the same rules define their own target set to include sh:

Neither is scoped to the *.sh glob alone: a tracked, extension-less script whose shebang names bash or sh joins the target list too.

And scripts/docker_lint.py's shellcheck and shfmt entries both set discover_shebang=True on that same shape, as does .github/workflows/validate-task.yml's target-building step.

So a repository carrying a #!/bin/sh script is inside the rule's declared scope and cannot satisfy the rule.

Why It Is Not Just Theoretical

CODESTYLE.md "Shell" scopes shell to "Bash, and only where a program cannot be Python", which reads as forbidding sh outright. If that is the intent, then the discovery shape is what is wrong, since it goes looking for sh scripts the fleet does not permit. If sh is permitted for the narrow bootstrap cases the same sentence describes, a script that must run before a toolchain exists, then the strict-mode line needs a POSIX form for them.

Either way one of the two is wrong today, and a carrier reading only the rule cannot tell which.

What Settling It Needs

A decision, which is why this is filed rather than patched:

  1. sh is not permitted. Say so in the rule, and narrow the discovery in docker_lint.py and validate-task.yml to bash shebangs, so the tooling stops claiming targets the rules disown.
  2. sh is permitted for bootstraps. Give it its own strict-mode line, set -eu being the portable subset, and say which shape takes which.

Option 2 looks likelier given the bootstrap carve-out already in the text, but the rule as written admits neither.

Provenance

CodeRabbit on #1179. Verified here against dash, scripts/docker_lint.py's discover_shebang entries, and .github/workflows/validate-task.yml's target discovery.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions