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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ and versions are tracked in the repo-root `VERSION` file.
documented context instead of silently accepting and discarding them.
- Isolated application run status per model while retaining the process-global
last-status value as a compatibility view of the most recently active model.
- Added a manifest-bound lock to standalone applications' embedded vendor copy
so it passes the same offline vendor verification as ordinary installs.
- Prevented list, CLI, and application call paths from creating or overwriting
caller-visible variables through undeclared internal scratch assignments.
- Eliminated an intermittent macOS Bash process-group race in supervised
Expand Down
20 changes: 15 additions & 5 deletions docs/vendor-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,18 @@ scripts/vendor standalone . /tmp/base-bash-libs-v2 dist/app
PATH="$PWD/dist/app/bin:$PATH" dist/app/bin/app --help
```

The standalone payload contains the verified launcher and framework under its
own root plus an auditable vendor copy and `BASE_BASH_STANDALONE.release`. The
launcher resolves its colocated `lib/bash` tree, so runtime network access and
ambient `BASE_BASH_LIBS_DIR` are unnecessary. No command downloads, executes,
or evaluates remote content.
The standalone payload contains two deterministic copies of the same verified
framework bundle. The root copy is the authoritative runtime layout and is
bound by `BASE_BASH_STANDALONE.release`; the launcher resolves its colocated
`lib/bash` tree without ambient `BASE_BASH_LIBS_DIR`. The
`vendor/base-bash-libs` copy is the authoritative audit/vendor layout and has
its own `base-bash-libs.lock`, so consumers can verify it independently:

```bash
scripts/vendor verify dist/app/vendor/base-bash-libs
```

Both copies carry the same `MANIFEST.sha256`, version, and source commit from
the input bundle. Standalone creation stages the complete payload and its lock
before one atomic move. No command downloads, executes, or evaluates remote
content.
21 changes: 18 additions & 3 deletions scripts/vendor
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,10 @@ rollback_bundle() {
}

verify_destination() {
local destination="$1" expected path actual lock_hash
[[ -f "$destination/base-bash-libs.lock" && -f "$destination/MANIFEST.sha256" ]] || {
local destination="$1" expected path actual lock_hash lock_version lock_commit
local bundle_version bundle_commit
[[ -f "$destination/base-bash-libs.lock" && -f "$destination/MANIFEST.sha256" &&
-f "$destination/BUNDLE.release" ]] || {
error "vendor destination lacks lock or hash metadata: $destination"
return 1
}
Expand All @@ -178,6 +180,18 @@ verify_destination() {
error 'vendor lock does not match MANIFEST.sha256'
return 1
}
lock_version="$(sed -n 's/^version=//p' "$destination/base-bash-libs.lock" | sed -n '1p')"
lock_commit="$(sed -n 's/^source_commit=//p' "$destination/base-bash-libs.lock" | sed -n '1p')"
bundle_version="$(sed -n 's/^source_version=//p' "$destination/BUNDLE.release" | sed -n '1p')"
bundle_commit="$(sed -n 's/^source_commit=//p' "$destination/BUNDLE.release" | sed -n '1p')"
[[ -n "$lock_version" && "$lock_version" == "$bundle_version" ]] || {
error 'vendor lock version does not match BUNDLE.release'
return 1
}
[[ -n "$lock_commit" && "$lock_commit" == "$bundle_commit" ]] || {
error 'vendor lock source commit does not match BUNDLE.release'
return 1
}
printf 'Vendor lock and hashes are valid: %s\n' "$destination"
}

Expand All @@ -202,10 +216,11 @@ standalone_bundle() {
fi
# Put the verified framework at the standalone root so the copied
# launcher resolves lib/bash without ambient environment variables, and
# retain an explicit vendor copy for provenance/audit consumers.
# retain an independently locked vendor copy for provenance/audit consumers.
if ! copy_tree "$framework_bundle" "$temporary" ||
! mkdir -p "$temporary/vendor/base-bash-libs" "$temporary/bin" ||
! copy_tree "$framework_bundle" "$temporary/vendor/base-bash-libs" ||
! write_lock "$temporary/vendor/base-bash-libs" "$framework_bundle" standalone ||
! cp -- "$framework_bundle/bin/base-bash" "$temporary/bin/base-bash" ||
! chmod +x "$temporary/bin/base-bash" "$temporary/bin/app"; then
rm -rf -- "$temporary"
Expand Down
9 changes: 8 additions & 1 deletion tests/vendor.bats
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,14 @@ setup() {
[ "$status" -eq 0 ]
[ -x "$standalone/bin/base-bash" ]
[ -x "$standalone/bin/app" ]
[ -f "$standalone/vendor/base-bash-libs/base-bash-libs.lock" ] || true
[ -f "$standalone/vendor/base-bash-libs/base-bash-libs.lock" ]
bats_run "$BASE_REPO_ROOT/scripts/vendor" verify "$standalone/vendor/base-bash-libs"
[ "$status" -eq 0 ]
[[ "$output" == *"Vendor lock and hashes are valid"* ]]
[ "$(sed -n 's/^version=//p' "$standalone/vendor/base-bash-libs/base-bash-libs.lock")" = \
"$(sed -n 's/^source_version=//p' "$standalone/vendor/base-bash-libs/BUNDLE.release")" ]
[ "$(sed -n 's/^source_commit=//p' "$standalone/vendor/base-bash-libs/base-bash-libs.lock")" = \
"$(sed -n 's/^source_commit=//p' "$standalone/vendor/base-bash-libs/BUNDLE.release")" ]
bats_run env PATH="$standalone/bin:$PATH" "$standalone/bin/app" run
[ "$status" -eq 0 ]
[[ "$output" == *"hello=world"* ]]
Expand Down
Loading