Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ and versions are tracked in the repo-root `VERSION` file.
- Added a repository-owned v2 release guard that permits only the planned
alpha, beta, release-candidate, and GA identifiers while locking publication
until the verified-artifact and pre-GA release-candidate gates are complete.
- Added the versioned `base_api_manifest.yaml` module/API contract, its
Bash-native validator and generators, and manifest-driven module/test/artifact
discovery for repository validation.

### Security

Expand Down Expand Up @@ -59,8 +62,8 @@ and versions are tracked in the repo-root `VERSION` file.
`base_init` lifecycle API. Wrapper flags now return through a
caller-owned array without hidden positional-parameter mutation; launchers,
examples, and companion-library tests initialize explicitly.
- Namespaced the v2 public API, runtime globals, environment controls, load
guards, and internal symbols under the `base_bash_libs_` contract. Legacy
- Namespaced the v2 public API under the coherent `base_` contract while
retaining `BASE_BASH_LIBS_` globals and `__base_bash_libs_` internals. Legacy
generic names are removed; see `docs/v2-symbol-map.md` for migration.
- Made timed foreground-TTY invocations fail closed with a safe diagnostic;
callers must provide a pipe or explicit non-terminal stdin for the v2 hard
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ See [`lib/bash/README.md`](lib/bash/README.md) for the package layout.
The v2 API charter, effect/status contract, and complete public-surface audit
are in [`docs/v2-api-contract.md`](docs/v2-api-contract.md). The symbol-level
mapping and migration aid are in [`docs/v2-symbol-map.md`](docs/v2-symbol-map.md).
The machine-readable module/API contract is in
[`base_api_manifest.yaml`](base_api_manifest.yaml), with its schema documented
in [`docs/api-manifest-schema.md`](docs/api-manifest-schema.md) and its
generated reference in [`docs/api-reference.md`](docs/api-reference.md).

## Installation and Usage

Expand Down Expand Up @@ -197,7 +201,9 @@ event, immutable consumption, and the post-GA support contract.

Release preparation and downstream Homebrew/Base handoffs are documented in
[`docs/release-process.md`](docs/release-process.md). The machine-readable
release contract lives in [`base_manifest.yaml`](base_manifest.yaml).
release contract lives in [`base_manifest.yaml`](base_manifest.yaml); the
machine-readable API and module contract lives in
[`base_api_manifest.yaml`](base_api_manifest.yaml).

## License

Expand Down
5 changes: 3 additions & 2 deletions STANDARDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ or chained source fragments.
The v2 public namespace is deliberately collision-resistant so a library can
be sourced into an existing application without taking generic names:

- Public functions use `base_bash_libs_<module>_<name>` (with the two stdlib
lifecycle exceptions documented in `lib/bash/README.md`).
- Public functions use `base_<module>_<name>` (with the two stdlib lifecycle
functions `base_init` and `base_require_version` documented in
`lib/bash/README.md`).
- Framework-owned globals, environment controls, metadata, and load guards use
`BASE_BASH_LIBS_...`.
- Internal functions use `__base_bash_libs_<module>_...__` and are not callable
Expand Down
179 changes: 179 additions & 0 deletions base_api_manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
schema_version: 1
manifest_kind: base-bash-libs-api
manifest_version: 2.0.0
minimum_bash: "4.2"
generated_reference: docs/api-reference.md
migration_inventory: docs/v2-api-contract.md

namespace:
public_function_prefix: base_
global_prefix: BASE_BASH_LIBS_
internal_function_prefix: __base_bash_libs_
lifecycle_functions: base_init,base_require_version

# These fields are intentionally flat and line-oriented. Consumers can inspect
# the manifest with ordinary shell tools without installing a YAML runtime.
environment:
- BASE_BASH_LIBS_VERSION|readonly-global|loaded package version
- BASE_BASH_LIBS_DRY_RUN|caller-control|dry-run policy requested by the caller
- BASE_BASH_LIBS_PRIMARY_LOG|caller-control|primary persistent log sink
- BASE_CLI_PRIMARY_LOG|caller-input|Base shared primary log sink
- BASE_BASH_LIBS_LOG_DEBUG|caller-control|enable debug diagnostics
- BASE_BASH_LIBS_LOG_UTC|caller-control|render log timestamps in UTC
- BASE_BASH_LIBS_GIT_PULL_MAX_ATTEMPTS|caller-control|maximum git pull attempts
- NO_COLOR|caller-input|disable color output when set
- TMPDIR|caller-input|temporary directory policy
- GH_TOKEN|caller-input|GitHub CLI authentication input
- TZ|caller-input|caller-selected timezone for diagnostics

optional_commands: git,gh,timeout,gtimeout

artifacts:
- base_api_manifest.yaml|source|canonical API and module manifest
- docs/api-reference.md|generated|scripts/api-manifest generate|checked-in
- docs/api-manifest-schema.md|documentation|API manifest schema and tooling
- docs/v2-api-contract.md|documentation|normative API behavior charter
- docs/v2-symbol-map.md|documentation|v2 migration and symbol map
- lib/bash/README.md|documentation|package layout and namespace contract
- lib/bash/tests/test_helper.sh|test-support|shared BATS helpers

# Every module remains one sourceable file (or the standalone launcher). The
# module-level contract applies to each symbol listed in public_symbols; the
# module README carries the call-specific signature and examples.
modules:
- name: std
kind: sourceable-library
source: lib/bash/std/lib_std.sh
documentation: lib/bash/std/README.md
tests: lib/bash/std/tests/lib_std.bats
dependencies: none
optional_commands: awk,basename,cat,command,cp,date,grep,mktemp,mv,printf,rm,sed,tput
artifacts: lib/bash/std/lib_std.sh,lib/bash/std/README.md,lib/bash/std/tests/lib_std.bats
public_symbols: base_init,base_require_version,base_std_add_to_path,base_std_ask_yes_no,base_std_assert_arg_count,base_std_assert_associative_array,base_std_assert_command_exists,base_std_assert_dir_exists,base_std_assert_executable,base_std_assert_file_exists,base_std_assert_function_exists,base_std_assert_indexed_array,base_std_assert_integer,base_std_assert_integer_range,base_std_assert_not_null,base_std_assert_variable_name,base_std_check_bash_version,base_std_command_path,base_std_dedupe_path,base_std_dump_trace,base_std_exit_if_error,base_std_fatal_error,base_std_function_exists,base_std_get_my_source_dir,base_std_import,base_std_is_dry_run,base_std_is_interactive,base_std_log_debug,base_std_log_debug_enter,base_std_log_debug_file,base_std_log_debug_leave,base_std_log_error,base_std_log_fatal,base_std_log_info,base_std_log_info_enter,base_std_log_info_file,base_std_log_info_leave,base_std_log_is_enabled,base_std_log_verbose,base_std_log_verbose_enter,base_std_log_verbose_file,base_std_log_verbose_leave,base_std_log_warn,base_std_make_temp_dir,base_std_make_temp_file,base_std_print_bold,base_std_print_error,base_std_print_info,base_std_print_message,base_std_print_path,base_std_print_success,base_std_print_tty,base_std_print_warn,base_std_register_cleanup_hook,base_std_register_cleanup_path,base_std_run,base_std_safe_cd,base_std_safe_mkdir,base_std_safe_touch,base_std_safe_truncate,base_std_safe_unalias,base_std_set_log_category_level,base_std_set_log_level,base_std_unregister_cleanup_hook,base_std_unregister_cleanup_path,base_std_wait_for_enter
signature_source: lib/bash/std/README.md
inputs: documented per symbol in the module README and API charter
outputs: documented per symbol; named outputs are caller-owned
statuses: documented per symbol; recoverable failures return status
side_effects: documented per symbol; sourcing is passive
stability: stable
since: 2.0.0
deprecated: false
- name: file
kind: sourceable-library
source: lib/bash/file/lib_file.sh
documentation: lib/bash/file/README.md
tests: lib/bash/file/tests/lib_file.bats
dependencies: std
optional_commands: awk,cmp,cp,mv,rm,stat
artifacts: lib/bash/file/lib_file.sh,lib/bash/file/README.md,lib/bash/file/tests/lib_file.bats
public_symbols: base_file_section_exists,base_file_section_needs_update,base_file_update_file_section
signature_source: lib/bash/file/README.md
inputs: documented per symbol in the module README and API charter
outputs: documented per symbol; named outputs are caller-owned
statuses: documented per symbol; recoverable failures return status
side_effects: documented per symbol; sourcing is passive
stability: stable
since: 2.0.0
deprecated: false
- name: git
kind: sourceable-library
source: lib/bash/git/lib_git.sh
documentation: lib/bash/git/README.md
tests: lib/bash/git/tests/lib_git.bats
dependencies: std
optional_commands: git,awk,grep,mktemp,rm,sleep
artifacts: lib/bash/git/lib_git.sh,lib/bash/git/README.md,lib/bash/git/tests/lib_git.bats
public_symbols: base_git_branch_merged_to_ref,base_git_branch_upstream,base_git_check_script_up_to_date,base_git_detect_default_branch,base_git_get_current_branch,base_git_list_remote_branches,base_git_list_worktree_branches,base_git_update_repo,base_git_worktree_path_for_branch
signature_source: lib/bash/git/README.md
inputs: documented per symbol in the module README and API charter
outputs: documented per symbol; named outputs are caller-owned
statuses: documented per symbol; recoverable failures return status
side_effects: documented per symbol; sourcing is passive
stability: stable
since: 2.0.0
deprecated: false
- name: gh
kind: sourceable-library
source: lib/bash/gh/lib_gh.sh
documentation: lib/bash/gh/README.md
tests: lib/bash/gh/tests/lib_gh.bats
dependencies: std
optional_commands: gh,awk,grep,mktemp,rm,sleep,timeout,gtimeout
artifacts: lib/bash/gh/lib_gh.sh,lib/bash/gh/README.md,lib/bash/gh/tests/lib_gh.bats
public_symbols: base_gh_api_with_retry,base_gh_auth_status_diagnostics,base_gh_infer_repo_from_origin,base_gh_repo_default_branch,base_gh_repo_from_remote_url,base_gh_report_command_failure,base_gh_require_cli,base_gh_run
signature_source: lib/bash/gh/README.md
inputs: documented per symbol in the module README and API charter
outputs: documented per symbol; named outputs are caller-owned
statuses: documented per symbol; recoverable failures return status
side_effects: documented per symbol; sourcing is passive
stability: stable
since: 2.0.0
deprecated: false
- name: str
kind: sourceable-library
source: lib/bash/str/lib_str.sh
documentation: lib/bash/str/README.md
tests: lib/bash/str/tests/lib_str.bats
dependencies: std
optional_commands: none
artifacts: lib/bash/str/lib_str.sh,lib/bash/str/README.md,lib/bash/str/tests/lib_str.bats
public_symbols: base_str_contains,base_str_ends_with,base_str_join,base_str_lower,base_str_ltrim,base_str_rtrim,base_str_split,base_str_starts_with,base_str_trim,base_str_upper
signature_source: lib/bash/str/README.md
inputs: documented per symbol in the module README and API charter
outputs: documented per symbol; named outputs are caller-owned
statuses: documented per symbol; recoverable failures return status
side_effects: documented per symbol; sourcing is passive
stability: stable
since: 2.0.0
deprecated: false
- name: arg
kind: sourceable-library
source: lib/bash/arg/lib_arg.sh
documentation: lib/bash/arg/README.md
tests: lib/bash/arg/tests/lib_arg.bats
dependencies: std
optional_commands: awk,grep
artifacts: lib/bash/arg/lib_arg.sh,lib/bash/arg/README.md,lib/bash/arg/tests/lib_arg.bats
public_symbols: base_arg_parse
signature_source: lib/bash/arg/README.md
inputs: documented per symbol in the module README and API charter
outputs: documented per symbol; named outputs are caller-owned
statuses: documented per symbol; recoverable failures return status
side_effects: documented per symbol; sourcing is passive
stability: stable
since: 2.0.0
deprecated: false
- name: list
kind: sourceable-library
source: lib/bash/list/lib_list.sh
documentation: lib/bash/list/README.md
tests: lib/bash/list/tests/lib_list.bats
dependencies: std
optional_commands: none
artifacts: lib/bash/list/lib_list.sh,lib/bash/list/README.md,lib/bash/list/tests/lib_list.bats
public_symbols: base_list_append,base_list_contains,base_list_length,base_list_prepend,base_list_remove,base_list_unique
signature_source: lib/bash/list/README.md
inputs: documented per symbol in the module README and API charter
outputs: documented per symbol; named outputs are caller-owned
statuses: documented per symbol; recoverable failures return status
side_effects: documented per symbol; sourcing is passive
stability: stable
since: 2.0.0
deprecated: false
- name: launcher
kind: executable-launcher
source: bin/base-bash
documentation: docs/v2-api-contract.md
tests: tests/launcher.bats
dependencies: std
optional_commands: bash,basename,dirname,realpath,readlink
artifacts: bin/base-bash,docs/v2-api-contract.md,tests/launcher.bats
public_symbols: base_launcher_die,base_launcher_ensure_supported_bash,base_launcher_import_base_bash_lib,base_launcher_lib_dir_is_usable,base_launcher_package_root,base_launcher_resolve_lib_dir,base_launcher_resolve_path,base_launcher_run_script,base_launcher_source_stdlib,base_launcher_usage
signature_source: docs/v2-api-contract.md
inputs: executable arguments and package paths documented by the launcher
outputs: process status and delegated script output
statuses: launcher boundary may terminate; helpers return documented status
side_effects: starts a child script and sources the stdlib at the boundary
stability: stable
since: 2.0.0
deprecated: false
75 changes: 75 additions & 0 deletions docs/api-manifest-schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# API and module manifest

`base_api_manifest.yaml` is the authoritative v2 API/module inventory. It is
deliberately separate from `base_manifest.yaml`, which is the Base release and
developer-tooling manifest. The API manifest is a small, line-oriented YAML
subset so that consumers can inspect it with Bash, `awk`, or another YAML
reader; no Python, Ruby, `yq`, or `jq` runtime is required to consume the
library.

## Schema

The current schema is `1` and the manifest identifies itself with
`manifest_kind: base-bash-libs-api`. The required top-level fields are:

| Field | Meaning |
| --- | --- |
| `schema_version` | Manifest schema compatibility number. |
| `manifest_version` | API release line represented by the manifest (`2.0.0` during v2 development). |
| `minimum_bash` | Minimum supported Bash runtime (`4.2`). |
| `generated_reference` | Checked-in API reference generated from this manifest. |
| `migration_inventory` | Normative v1-to-v2 behavior and symbol migration record. |
| `namespace` | Public function, global, internal, and lifecycle naming contract. |
| `environment` | Caller inputs and framework-owned globals, with kind and purpose. |
| `optional_commands` | External commands that are optional runtime capabilities. |
| `artifacts` | Manifest-owned source, documentation, generated, and test-support files. |
| `modules` | Ordered module records described below. |

Each module declares its single source boundary, documentation, BATS suite,
dependencies, optional commands, package artifacts, public symbols, and API
metadata:

- `kind` is `sourceable-library` for a sourceable `.sh` library or
`executable-launcher` for `bin/base-bash`.
- `dependencies` names other manifest modules. `scripts/api-manifest check`
rejects missing modules and dependency cycles.
- `public_symbols` is the complete exported function set. The checker compares
it with declarations in the source file and rejects both undocumented and
duplicate symbols.
- `signature_source` points to the README or charter containing call-specific
signatures and examples. `inputs`, `outputs`, `statuses`, and `side_effects`
provide the module-level contract inherited by each listed symbol.
- `stability`, `since`, and `deprecated` are required release metadata. A
future deprecation must add a migration-inventory entry before changing the
symbol.

The artifact list makes packaging membership reviewable. Every module must
package its source, documentation, and tests. Generated files are checked for
drift rather than silently rewritten by validation.

## Commands

The Bash-native consumer tool is [`scripts/api-manifest`](../scripts/api-manifest):

```bash
scripts/api-manifest check
scripts/api-manifest generate
scripts/api-manifest symbols
scripts/api-manifest module-paths
scripts/api-manifest source-paths
scripts/api-manifest test-paths
scripts/api-manifest artifact-paths
```

`check` validates schema and metadata, module/file existence, duplicate symbols,
source/manifest drift, dependency cycles, unsafe paths, packaging membership,
and the generated API reference. The repository validation suite obtains its
module source, test, and artifact paths from these commands instead of keeping
another hardcoded module list.

## Single-file boundary

The manifest describes library boundaries; it does not create a loader graph.
Each public sourceable library remains one physical file as required by
[`STANDARDS.md`](../STANDARDS.md). Adding a concern means adding or extending a
documented module boundary, not splitting an existing library into fragments.
Loading
Loading