Monk translates an admitted subset of Bash into Fish under a versioned execution contract. Unsupported semantics produce structured diagnostics and a failure in both normal and strict mode. Named approximations require an explicit opt-in.
The roadmap records implemented behavior, deliberate exclusions and remaining acceptance gates. The Rust verification report identifies the tested runtime, local results and unverified target execution.
Use the pinned devenv project (GHC 9.14.1 by default, with a GHC 9.12.2 compatibility lane, Cabal 3.16.1, and the locked Rust nightly). See dependency and packaging commands, including the devenv MCP launch configuration:
devenv shell -- bash -e <<'SCRIPT'
monk-build
monk-rust-build
runtime="$PWD/target/debug/monk-runtime"
cabal run monk -- script.bash --strict --runtime "$runtime" --output script.fish
"$runtime" --abi 2 launch script.fish
SCRIPTThe explicit runtime path works directly from the build tree; building alone
does not install monk-runtime on PATH.
The initial profile is Bash 5.3, signed 64-bit arithmetic, UTF-8 source and C
locale. The reference pair is Bash 5.3.9 and Fish 4.6.0; compatibility with a newer
Fish requires separate evidence. Generated programs use native Fish directly where
equivalence is proved. External commands use a bounded replace-self dispatch
shim for Bash-compatible launch errors. Source output uses a bounded writer to
preserve Bash diagnostics and signal termination on failed writes, including
closed stdout and SIGPIPE. Scalar expressions and control flow stay in Fish.
All standalone output uses the ABI 2 native launcher so initially closed
streams are recorded before Fish starts. Byte operations use bounded helpers; supervised programs keep control flow in a private Fish
evaluator while the native owner manages user processes and descriptors. Install both executables with
cabal install exe:monk and cargo install --path runtime --locked, or select a
provider with --runtime FILE.
--managed --output script.fish captures that provider in an immutable bundle.
The captured bin/monk-runtime can launch the bundle entry without an installed
provider. Sourceable output retains its declared Fish caller interface.
Generated support requires no Python and never evaluates Bash expression strings.
See the execution contract
for startup conditions and caller obligations.
# Combined output on stdout:
cabal run monk -- script.bash --strict
# Literal dependencies, using the declared execution cwd and PATH:
cabal run monk -- script.bash --strict --recursive --sources inline
# Explicitly permit the readonly enforcement approximation:
cabal run monk -- script.bash --allow-approximation readonly-unchecked
# Output intended to be sourced by a declared caller:
cabal run monk -- script.bash --strict --entry sourceable \
--caller-contract caller.json --output script.fish--target-profile bash-5.3-fish-4.6 names the initial profile. --strict cannot be
combined with --allow-approximation. Warnings, notes and runtime requirements
go to stderr; --quiet-warnings suppresses them, not translation failures.
The implementation supports exact words, integer arithmetic, control flow, definite function calls and literal sources. Quotation, empty arguments, field splitting, lazy expansion effects and invocation order are part of the contract. Child execution has an explicit isolation plan. Sourceable output has an owned return/status/argv boundary and declared scalar and function effects.
Standalone coverage includes foreground pipelines and background jobs, $!
and wait, ordered file and descriptor redirections, here-documents and
here-strings, admitted read flags, dense indexed arrays, composed word
expansion, owned process substitution, compiled EXIT/ERR traps, and finitely
proved eval and immutable sources. These features have explicit context and
operand restrictions. Session effects do not extend the sourceable contract.
Admission depends on context, not just syntax. Sparse/associative arrays,
arbitrary runtime-generated eval, unknown dynamic dispatch, recursion,
mutable computed sources, source cycles, interactive job control and arbitrary
signal callbacks remain rejected. A rejection test
establishes an exclusion; it does not establish implemented functionality.
Consult the semantic audit and
constructor policy for exact
boundaries. Old best-effort support claims do not apply to this translator.
ShellCheck syntax and immutable source input
-> private semantic plan
-> admitted materialization plan, including helpers and execution boundaries
-> structural Fish DSL
-> rendering and publication
Monk.Translation owns parse/translate entry points. Monk.Source discovers
literal dependencies through the same semantic analysis. Monk.Output plans
output separately from filesystem writes. Translation results, source graphs
and output bundles are opaque, with inspection functions. General
Language.Fish.DSL / Monk.AST construction remains available without allowing
arbitrary constructed scripts to become certified translations.
import Monk.Translation
translateFile = do
result <- translateBashFile strictConfig "script.bash"
case result of
Left failure -> print failure
Right translation -> do
print (renderTranslation translation)
print (translationDiagnostics translation)
print (translationRuntimeRequirements translation)Sourceable callers declare binding access, initial export attributes, lookup and ambient effects in a versioned JSON contract. Runtime guards check observable preconditions; equivalence of imported functions and absence of relevant callbacks remain caller obligations. See the migration guide for the deliberate API/CLI changes.
Managed publication stages immutable generations on the destination filesystem and replaces one entry loader atomically. Child references remain pinned to a generation and prior generations remain available. This guarantee concerns publication and reader consistency; executing scripts can still have their declared effects. Use the output publisher, rather than manually writing the files returned by inspection accessors.
devenv shell -- monk-build
devenv shell -- monk-rust-build
devenv shell -- monk-rust-test
devenv shell -- monk-rust-quality
devenv shell -- monk-integration
devenv shell -- monk-quality
devenv shell -- monk-docs
devenv shell -- monk-sdist
devenv shell -- monk-benchmark
devenv shell -- monk-packageThe development flag retains warnings as errors without making release package
metadata reject unconditional -Werror. Tests compare output, status, argument
boundaries, filesystem effects and declared caller updates. Generated
compositions include shrinking and classify zero-diagnostic mismatches
separately. Compile-fail checks include positive controls. Publication tests
exercise failure recovery and concurrent readers and publishers. Skipped
runtime and platform checks remain explicit evidence gaps.
The Babelfish comparison separates successful translation from agreement with independently executed Bash. Comparison cohorts retain their own denominators; rejections, mismatches and unavailable executions remain distinct.
Release definitions cover x86_64 Linux and arm64 Linux with static musl, plus Apple Silicon macOS with permitted Apple system-library dependencies. The current Rust runtime has native execution evidence on Apple Silicon macOS. Native Linux execution and execution on the minimum supported macOS version remain unverified.