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
16 changes: 11 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,16 @@ jobs:
exit 1
;;
esac
RELEASE_ARGS=(
--repo "${GITHUB_REPOSITORY}"
--verify-tag
--draft
--title "ContainerBin ${GITHUB_REF_NAME}"
--generate-notes
)
if [[ "${GITHUB_REF_NAME}" == *-* ]]; then
RELEASE_ARGS+=(--prerelease)
fi
gh release create "${GITHUB_REF_NAME}" \
--repo "${GITHUB_REPOSITORY}" \
--verify-tag \
--draft \
--title "ContainerBin ${GITHUB_REF_NAME}" \
--generate-notes \
"${RELEASE_ARGS[@]}" \
dist/cb.exe dist/*.zip dist/SHA256SUMS
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,7 @@ cb env
cb list
cb default
cb default set node 22
cb self-update --check # read-only stable-release selection; no download or file changes
```

`cb bugreport` assembles `cb version`, the Windows and PowerShell versions
Expand All @@ -807,6 +808,22 @@ failure. The Node 22 checks run when the `node22` profile is registered. An
older registry without that newer default gets an actionable skip rather than
a false failure; run `cb setup` to append the current default profiles.

### Self-update release selection

`cb self-update --check` is the first, read-only phase of transactional
self-update support. It compares a release-qualified Windows/amd64 build with
the latest stable release and reports the exact binary, archive, checksum and
provenance policy that later phases must verify. It does not download assets or
change any files, and development builds fail closed because their installed
version cannot be proved.

Stable selection is the default. Use `--prerelease` to select the highest
canonical prerelease among the 30 most recent published releases, or
`--version vX.Y.Z` to inspect one exact published release; those two selectors
are mutually exclusive. Selecting a version older
than the running build is rejected unless `--allow-downgrade` is explicit. The
current slice supports only Windows/amd64, matching the release artifacts.

### `cb self-test --json` report format

`--json` prints one JSON document to stdout and nothing else (no progress
Expand Down
15 changes: 12 additions & 3 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ the tier below it; see the exact edges further down for that):

```
main argv[0] dispatch, subcommand switch, version, usage,
exit codes + fatalf/osExit, withMutationLock's signal wrapper
exit codes + fatalf/osExit, bootstrap self-update selection,
withMutationLock's signal wrapper
↓
internal/cli setup, install, add, expose, unexpose, uninstall, inspect,
trace, env, backup, restore, lock, update
Expand All @@ -257,13 +258,14 @@ internal/registry Tool/Registry, TOML parser, defaults, registry file
internal/toml the shared TOML subset lexer (leaf)
internal/atomicio crash-safe write + .bak recovery (leaf)
internal/mutationlock the registry mutation lock primitive (leaf)
internal/selfupdate canonical release selection and read-only plan (leaf)
```

The exact import edges, from `go list -f '{{.ImportPath}} {{.Imports}}' ./...`,
project-internal imports only:

```
main -> cli, diag, dockerrun, mutationlock, policy, registry, state
main -> cli, diag, dockerrun, mutationlock, policy, registry, selfupdate, state
cli -> atomicio, diag, dockerrun, lockfile, pathmap, policy, registry, statearchive, toml
diag -> dockerrun, dockervol, lockfile, pathmap, policy, registry
dockerrun -> dockervol, lockfile, pathmap, policy, registry
Expand All @@ -273,7 +275,7 @@ lockfile -> atomicio, policy, registry, toml
pathmap -> registry
registry -> atomicio, toml
policy -> toml
atomicio, dockervol, mutationlock, toml -> (leaves)
atomicio, dockervol, mutationlock, selfupdate, toml -> (leaves)
```

Notably: `lockfile` and `pathmap` both depend on `registry` directly, not on
Expand All @@ -298,3 +300,10 @@ Two boundaries are load-bearing rather than cosmetic:
release workflow inject it with `-ldflags "-X main.version=..."`, so that symbol
path is part of the release contract. Packages that need it take it as a
parameter.

`cb self-update --check` is dispatched before machine policy and registry
loading, like the bootstrap help/version path. Release selection therefore
remains available when either local configuration source is missing or invalid.
`internal/selfupdate` has no project imports and performs only bounded metadata
queries and plan output; downloading, attestation verification and installed-file
replacement remain separate later phases.
7 changes: 7 additions & 0 deletions docs/security-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ readable, and dangerous to let others edit.
Tar extraction occurs only inside the named Docker volume through an immutable,
network-disabled helper with a read-only container root; no archive member is
turned into a Windows host path.
- **Fail-closed self-update selection.** `cb self-update --check` accepts only a
release-qualified Windows/amd64 build, queries the canonical GitHub repository
over HTTPS with a bounded response, and requires exact canonical release and
asset URLs, names and sizes. Downgrades and prereleases require explicit
flags. This phase performs no asset download and changes no installed files;
later phases must require both checksums and GitHub provenance without a
fallback before replacement is possible.

## What ContainerBin does NOT protect against

Expand Down
Loading
Loading