Static analysis cannot prove runtime shell behavior, and shellwhy refuses to pretend otherwise. Every startup file in a report carries one of six labels:
Static mode
The default. It identifies the target shell from --shell, $SHELL, or parent-process metadata; infers login / interactive / SSH / terminal context from flags, argv, TTY state, and environment; applies the startup rules for that shell and mode; checks which files exist; and shows files skipped by precedence — bash reading only the first existing ~/.bash_profile, ~/.bash_login, or ~/.profile is the classic case. Simple source statements are parsed without evaluating shell code.
What it cannot do: prove conditional branches, dynamic paths, plugin-manager side effects, aliases, functions, exports, or PATH changes created at runtime. Those stay possible at best.
Trace mode
shellwhy trace launches a fresh target shell and observes file access through a platform backend — currently strace on Linux, with dtruss/fs_usage planned for macOS. Observed files are merged into the report as confirmed. The trade-off: trace mode runs the user’s startup code, because it starts a real shell. Use static mode when analysis must be non-invasive.