Conformance policy

Rush balances POSIX, real /bin/sh behavior, and Bash-shaped user expectations.

Use this policy when those references disagree. See compatibility notes for concrete differences.

Modes

Treat modes as different contracts:

POSIX mode is strict. Default mode starts there and adds selected extensions.

POSIX mode

rush --posix targets POSIX.1-2024 / Issue 8. Use the specification as the first authority.

When POSIX specifies behavior, the specification wins

When POSIX defines grammar, expansion, redirection, execution, special builtins, assignments, diagnostics, or exit status, Rush follows POSIX in POSIX mode.

Use shell behavior as evidence, not a veto. Copy a POSIX-mode divergence only as a documented exception.

When POSIX leaves a gap, classify it first

Before copying another shell, classify the gap:

Undefined behavior carries less compatibility weight than implementation-defined behavior.

For unspecified or implementation-defined behavior, survey trusted shells

When POSIX allows more than one result, survey:

When they agree, normally follow them. When they disagree, consult platform or migration references as needed: FreeBSD /bin/sh, macOS /bin/sh, BusyBox ash, ksh93, Bash default mode, or macOS Bash 3.2.

Run platform shells when available, in platform CI, or when the decision affects those systems.

Treat macOS Bash 3.2 as a platform and legacy reference, not the main Bash target.

Bash default mode is useful for extensions, not as the POSIX-mode oracle.

When shells disagree, use stable tie-breakers

If POSIX leaves room and surveyed shells disagree, Rush prefers the behavior that is:

  1. most consistent with the POSIX execution model;
  2. most portable across real scripts and common /bin/sh implementations;
  3. least surprising to users who understand shell semantics;
  4. safest when state, files, jobs, traps, or redirections are involved;
  5. easiest to diagnose clearly when the script is non-portable or invalid.

Use friendliness last. In POSIX mode, prefer portable, predictable scripts over familiar Bashisms.

For undefined behavior, prefer diagnostics and safety

When a script relies on undefined POSIX behavior, prefer diagnostics, safety, and predictable state over shell mimicry.

Default or interactive Rush may accept extensions. That does not require rush --posix to accept them.

Default mode

Default Rush is POSIX-facing with selected compatibility extensions. Preserve POSIX script meaning while accepting common Bash-shaped workflows.

Valid POSIX scripts keep POSIX meaning

Valid POSIX scripts should normally behave the same in default mode and rush --posix.

Extensions may add syntax or features, but should not casually change portable script meaning.

Extensions should be common, useful, and mostly additive

Default mode may accept non-POSIX features when they are common, interactive, or useful for migration. Prefer additive extensions over changes to valid POSIX semantics.

If an extension conflicts with POSIX, require a stronger reason. Weigh migration value, surprise, safety, and isolation to non-POSIX syntax.

Bash is the main extension reference

For Bash extensions, use current stable GNU Bash default mode as the main reference. Treat macOS Bash 3.2 as a migration signal.

For cross-shell extensions, survey ksh93, mksh, BusyBox ash, dash, or FreeBSD sh as needed. Aim for practical compatibility, not bug-for-bug emulation.

Bash compatibility

Bash compatibility is a migration goal, not a replacement for POSIX conformance. Support Bash behavior when it unlocks real scripts or familiar interactive use without undermining the POSIX-facing core.

Do not chase bug-for-bug Bash emulation by default. Choose clearer behavior when Bash is undocumented, surprising, unsafe, or inconsistent.

Recording decisions

Turn compatibility decisions into tests when practical. Include:

Record user-facing differences in the compatibility notes.