v2 architecture and production guide

August 6, 2026 ยท View on GitHub

Architecture

The framework has a passive stdlib foundation and single-file modules. Source the stdlib, call base_init once with the application argv, then import only the modules the application uses. Imports are package-relative and guarded; the caller's working directory is not a dependency.

LayerResponsibilityStart here
launcherBash selection, package identity, checks, scaffold, script boundarybin/base-bash
stdlogging, statuses, command execution, PATH, prompts, temp/cleanup, importslib/bash/std/README.md
modulesfile, Git, GitHub, string, argument, list helpersbase_api_manifest.yaml
applicationCLI schema, config, standard options, lifecycle and dispatchgenerated lib/app.sh and docs/v2-api-contract.md

Execution and initialization

Sourcing is passive: it does not parse application arguments, change strict options, or install application traps. base_init publishes the filtered argv/context and is idempotent. base_cli_run parses the declared command schema; application code receives validated values rather than raw shell text.

Modules and imports

Each public sourceable library remains a single file. Use base_std_import module/lib_module.sh; never source a library by a path derived from untrusted input. The API manifest is the machine-readable module graph and the generated reference is checked in CI.

Application contract

  • Command schemas: declare commands, flags, scalar values, and repeatable values before dispatch; unknown options are errors.
  • Configuration: define typed keys with defaults and environment/file precedence. Files are data (key=value), never executable shell.
  • Lifecycle: register cleanup hooks in LIFO order. A shared EXIT dispatcher runs each hook once and preserves the application's original status.
  • Outputs/statuses: stdout is data; diagnostics and logs use stderr. A recoverable helper returns a documented nonzero status; process termination is reserved for the launcher boundary.
  • Observability: use categories and levels, redact sensitive values, and make terminal color/TTY behavior explicit.
  • Signals: applications may add signal policy through the lifecycle API; they must not replace the framework's dispatcher without preserving status and cleanup semantics.

Delivery

Run the generated BATS suite and base-bash check --project in CI. Keep the framework pinned by tag plus full commit, vendor only verified assets, and use docs/single-file-distribution.md for a deterministic bundle. Release tags, checksums, SBOM/provenance, and downstream cutover follow docs/release-process.md and the support policy.

Platform notes

The supported minimum is Bash 4.2.53. macOS /bin/bash 3.2 is outside the contract; install Homebrew Bash and use base-bash or a Bash 4.2+ shebang. Ubuntu/glibc and Alpine/musl paths are exercised where the release workflow has the required runner/container. BSD and other userlands are advisory until a consumer runs the compatibility matrix there. Locale, filesystem permissions, TTY availability, and optional external commands remain caller choices.