Rubash Bash Compatibility Matrix

This matrix keeps the boundary clear: rubash owns shell language semantics, while Niubash owns Windows host integration, REPL behavior, completion, plugin routing, and winuxcmd command discovery. Use it when deciding whether a fix belongs in rubash or in the Niubash host layer.

Verification Layers

LayerScopeCurrent evidence
Local compat fixturesFocused Niubash binary tests for common bash semantics that depend on rubash plus winuxcmd command links.CARGO_TARGET_DIR=target/codex-verify-phase17 cargo test --test compat --locked -- --ignored passed 18/18 on 2026-07-31.
Host contract testsWindows process, cwd, stdin, script, env, and stdio behavior around rubash execution.Covered by tests/host_contract.rs; full workspace test passed in the Phase 16 verification run.
GNU Bash upstream local gateBroader upstream bash fixture from a sibling rubash checkout, intentionally local-only and not vendored.docs/planning/bash-upstream-local.md records the Niubash local gate; the current rubash upstream ledger is the rubash README "Compatibility at a Glance" section: 83 suites, 82 pass, 1 residual (nameref), re-run 2026-09-25 on rubash master 71c933eb.

Focused Compat Fixtures

CapabilityEvidence fixture(s)StatusBoundary
Variables and simple parameter expansionvar_expansion, string_paramPassingrubash parser/executor.
Command substitutioncommand_substitution, command_substitution_quoted_newline, command_substitution_function_pipelinePassingrubash command substitution; host still owns -c quoting and process invocation.
Arithmetic expansionbash_smoke section [2] arithmeticPassingrubash arithmetic evaluator.
Indexed arraysbash_smoke sections [3] arrays, [16] array slicePassingrubash arrays and parameter expansion.
Associative arraysbash_smoke section [4] assoc arraysPassingrubash declare -A and associative lookup.
Boolean list statusand_or_status, bash_smoke section [20] exit statusPassingrubash &&, `
If / elif / elseif_else, multiline_if, bash_smoke section [11] ifPassingrubash compound commands; Niubash must feed full scripts to rubash.
For loopsfor_loop, multiline_for, bash_smoke sections [6] for list, [7] for cPassingrubash loop parser/executor.
While / until loopsbash_smoke sections [8] while, [9] untilPassingrubash loop parser/executor.
Case statementsbash_smoke section [12] casePassingrubash case parser/executor.
Functionsfunction, command_substitution_function_pipeline, bash_smoke section [10] functionPassingrubash function definition and invocation.
AliasesaliasPassingNiubash installs aliases into rubash; expansion is rubash-owned.
Pipelinespipeline, command_substitution_function_pipeline, bash_smoke section [13] pipelinePassingrubash pipeline execution plus winuxcmd command links.
Redirectionbash_smoke section [14] redirectPassingrubash redirection with Niubash/winuxcmd filesystem behavior.
HeredocsheredocPassingrubash whole-script parsing; host stdin/script path must avoid line-by-line splitting.
Backslash continuationscontinuationPassingrubash whole-script parsing.
Echo flagsecho_flagsPassingshell builtin behavior as exposed through rubash/winuxsh.
Export to Windows child processbash_smoke section [19] exportPassingrubash environment plus Niubash process environment synchronization.
File testsbash_smoke section [18] file testsPassingrubash test builtin plus host filesystem paths.

Host Contract Coverage

Host surfaceEvidenceNotes
cwd authoritycwd_cd_pwd_and_windows_child_process_agree, drive_only_cd_and_bare_drive_commands_switch_to_drive_rootNiubash normalizes/synchronizes shell PWD with Windows child process cwd.
startup isolationwinshrc_does_not_run_for_non_interactive_modesNon-interactive -c, script file, and stdin script paths do not source REPL startup rc.
temporary assignmentstemporary_assignment_reaches_nested_winuxsh_childAssignment semantics are observable by nested Niubash child processes.
stdin scriptspiped_stdin_without_args_runs_plain_script_surface, piped_stdin_without_args_runs_multiline_compound_block, piped_stdin_without_args_runs_heredoc_as_one_chunkHost feeds complete stdin scripts to rubash for multiline/heredoc semantics.
script positional parametersscript_file_args_populate_positional_parametersHost script path preserves $0/positional parameter behavior.
Windows child envexported_env_reaches_windows_child_processes, sourced_rc_keeps_winuxcmd_visible_to_windows_childrenNiubash bridges rubash env changes into Windows child process launches.
stdio and exit codestdout_stderr_and_exit_code_are_preserved, closed_stdout_pipe_does_not_print_broken_pipe_errorHost preserves process surfaces expected by agents.
command-mode parsing edge casescommand_mode_accepts_base_prefixed_arithmetic_in_function_body, command_mode_parameter_pattern_removal_handles_escaped_quotes, command_mode_set_positional_splits_custom_ifsFocused regressions for rubash-facing -c script delivery.

Known Gaps and Routing

GapRoute
Full GNU Bash upstream gate is local-only and not normal CI.Keep using docs/planning/bash-upstream-local.md for the Niubash local gate; source rubash suite numbers from the rubash README compatibility ledger. Do not vendor upstream bash tests.
niu -c still has host-side rough edges around POSIX assignment prefixes, env VAR=value cmd, heredoc temp-file flows, and complex quoting in agent commands.Track as Niubash command-mode/host issues, not as rubash language failures unless a direct rubash fixture reproduces it.
Job control and interactive terminal process-group semantics are not covered by the focused compat matrix.Route through rubash first; add Niubash host tests only for Windows process integration.
Plugin runtime behavior is intentionally outside current shell compatibility scope.Keep in plugin docs; do not mix with bash language compatibility claims.

Maintenance Rules

  • Add one focused fixture under tests/compat/fixtures/ before claiming a new bash-language capability in README or roadmap.
  • Prefer host contract tests for Windows cwd/env/stdin/stdout issues that happen around rubash rather than inside rubash.
  • Re-run the ignored compat suite before updating this matrix: CARGO_TARGET_DIR=target/codex-verify-phase17 cargo test --test compat --locked -- --ignored.
  • Use the upstream local gate only when parser/executor behavior changes or when syncing a new rubash revision.