# FAQ: Shell Compatibility and Golden Rules

## Why did `audit.naming.sh` fail with `/dev/fd/62: No such file or directory`?

The first naming-audit version used Bash-specific process substitution, such as:

```bash
while read -r line; do
    ...
done < <(command)
```

Process substitution uses transient `/dev/fd/<number>` file descriptors. It is supported by Bash and some other shells, but it is not required by POSIX `sh`, and it can fail in restricted shells, some hosting environments, or shell wrappers.

## Fix

Use the POSIX version:

```bash
./audit.naming.posix.sh defapp --details --summary
```

Run it explicitly with POSIX `sh` if desired:

```bash
sh ./audit.naming.posix.sh defapp --details --summary
```

The POSIX version uses temporary files and standard shell constructs rather than Bash arrays, `[[ ... ]]`, process substitution, or `/dev/fd` streams.

## Golden rule: portable system tools

System administration and audit scripts must be POSIX `sh` compatible unless a documented platform requirement explicitly requires Bash.

A portable system script must:

- Start with `#!/bin/sh`.
- Use `[` / `test`, not Bash-only `[[ ... ]]`.
- Avoid process substitution: `< <(...)` and `>(...)`.
- Avoid Bash arrays, associative arrays, `mapfile`, `shopt`, and `BASH_SOURCE`.
- Avoid `echo -e`; use `printf`.
- Quote every expansion unless intentional word splitting is required.
- Use `set -eu` and a `trap` to clean temporary files where appropriate.
- Validate all application names and keep resolved paths inside the configured apps root.
- Never construct shell commands from browser input.
- Remain read-only by default; generate review-only plans rather than performing bulk renames.

## When Bash is allowed

Bash may be used only when all of these are true:

1. The script begins with `#!/usr/bin/env bash`.
2. The script checks that Bash is actually running.
3. Bash is installed and supported on every target environment.
4. The documentation states why POSIX `sh` is insufficient.
5. The script is not invoked through `sh scriptname`.

For cross-host, CI, macOS, and managed-host audit utilities, prefer POSIX `sh`.

## Why does the rename plan contain commented `mv` commands?

A filename rename can break PHP includes, `require` calls, HTML references, JavaScript imports, CSS URLs, public routes, deployment scripts, and case-sensitive Linux paths. The plan is a review artifact, not an automatic migration. Inspect references, update them deliberately, uncomment selected lines, test, then re-run the audits.
