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
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -877,13 +877,26 @@ 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 or
Windows/arm64 build with the latest stable release and reports the exact
artifact, archive, checksum and provenance policy that later phases must
verify. It does not download assets or change any files, and development builds
`cb self-update --check` is the currently exposed, read-only command. It
compares a release-qualified Windows/amd64 or Windows/arm64 build with the latest
stable release and reports the exact artifact, archive, checksum and provenance
policy. It does not download assets or change any files, and development builds
fail closed because their installed version cannot be proved.

The internal next phases use private same-volume staging, exact checksum plus
GitHub build-provenance verification, and a rollback-safe Windows replacement
transaction. That transaction re-hashes the verified bytes before mutation,
serializes with registry/shim changes, discovers only shims proven to contain
the installed ContainerBin bytes, replaces and checks the complete proven set,
and restores the prior set after any smoke-test or identity failure. The helper
that waits for the invoking process to exit and the user-facing apply command
are not wired yet, so `--check` remains the only accepted command mode.

A hard process or host crash can leave a private `.container-bin-update-*`
staging/rollback directory or `.cb.exe-update-*.tmp` file beside `cb.exe`.
ContainerBin does not wildcard-delete these names on a later run because a name
alone does not prove ownership; inspect the object before removing it manually.

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
Expand Down
32 changes: 18 additions & 14 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,15 +304,15 @@ internal/atomicio crash-safe write + .bak recovery (leaf)
internal/mutationlock the registry mutation lock primitive (leaf)
internal/hostenv host classification and gated WSL layout (leaf)
internal/wslfs native WSL filesystem ownership/mode preflight
internal/selfupdate canonical release selection and read-only plan (leaf)
internal/selfupdate release selection, staging, verification and replacement
```

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

```
main -> cli, diag, dockerrun, hostenv, mutationlock, policy, projectconfig, registry, selfupdate, state
cli -> atomicio, diag, dockerrun, lockfile, pathmap, policy, registry, statearchive, toml
cli -> atomicio, diag, dockerrun, dockervol, lockfile, pathmap, policy, registry, statearchive, toml
projectconfig -> atomicio, pathmap, policy, registry, toml
diag -> dockerrun, dockervol, lockfile, pathmap, policy, registry
dockerrun -> dockervol, lockfile, pathmap, policy, registry
Expand All @@ -323,15 +323,16 @@ pathmap -> registry
registry -> atomicio, toml
policy -> toml
wslfs -> hostenv
atomicio, dockervol, hostenv, mutationlock, selfupdate, toml -> (leaves)
selfupdate -> mutationlock, registry
atomicio, dockervol, hostenv, mutationlock, toml -> (leaves)
```

Notably: `lockfile` and `pathmap` both depend on `registry` directly, not on
each other; `dockervol` is a true leaf with no internal dependencies at all
(not "beneath" `lockfile`/`pathmap` in any dependency sense — every one of
`diag`/`dockerrun`/`state` reaches it independently); and `mutationlock` is
reached only from `main`, unrelated to the `registry`/`lockfile`/`pathmap`
chain.
reached from `main` and the self-update replacement transaction. The latter
also reaches `registry` to scope managed shim names without guessing.

Two boundaries are load-bearing rather than cosmetic:

Expand Down Expand Up @@ -361,12 +362,15 @@ After the host runtime boundary is enforced, `cb self-update --check` is
dispatched before machine policy and registry loading. Release selection
therefore remains available when either local configuration source is missing
or invalid without allowing unsupported frontends to perform network work.
`internal/selfupdate` has no project imports. The CLI currently performs only
bounded metadata queries and plan output. The package also has an unexposed
same-volume staging phase that requires the installed executable path, then
downloads the directly attested executable and checksum manifest into private,
exact-size temporary files through a narrowly allowed GitHub release redirect.
Windows staging replaces inherited permissions with a protected DACL granting
access only to the current user. Attestation/checksum verification and
installed-file replacement remain separate later phases, so no download path
can yet mutate the installed binary.
The exposed CLI currently performs only bounded metadata queries and plan
output; that path does not load project or registry state. The package imports
`mutationlock` and `registry` only for its unexposed replacement transaction,
which serializes with registry/shim mutations and limits discovery to valid,
non-reserved managed shim names. Its other unexposed phases provide private
same-volume staging, exact checksum and GitHub build-provenance verification,
and rollback-safe replacement of the management executable plus the complete
proven shim set. Windows staging and recovery files use protected
current-user-only DACLs; installed replacements inherit installation-directory
ACLs. The temporary helper that waits for the invoking process to exit and the
user-facing apply command remain separate later work, so the exposed command
still cannot mutate the installed binary.
14 changes: 9 additions & 5 deletions docs/roadmap-decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ items from being repeatedly rediscovered as if they were immediately actionable.
| Image trust | **Policy-driven Sigstore/cosign at lock time** | Ready after signed-registry policy. Digest locking remains default where policy permits. Required trust never silently falls back to digest-only. |
| Per-project overlays | **Explicit digest-bound, add-only trust model** | Implementation-ready on the merged policy foundation. Initial overlays exclude host mounts, env prefixes and shared cross-project volumes. |
| Plugin/provider architecture | **Intentionally deferred** | Reopen only after at least two concrete integrations cannot be expressed safely by the declarative model. |
| RM-31 self-update | **Explicit transactional, attestation-verifying update** | Selection/check foundation shipped in PR #76. Staging, `gh attestation verify`, Windows apply, complete managed-set rollback and E2E remain. |
| RM-31 self-update | **Explicit transactional, attestation-verifying update** | Selection/check, staging, verification and ARM64 artifact selection are implemented; the internal Windows transaction now replaces and rolls back the complete proven managed set. Helper/user-facing apply wiring and release E2E remain. |
| RM-30 Authenticode | **Design accepted; externally blocked** | Implement only after a real code-signing certificate and protected signing mechanism exist. Stable and prerelease release artifacts are both signed. |
| RM-29 Windows ARM64 | **Lowest priority** | Native GitHub Windows ARM64 CI shipped in PR #78 and reproducible release packaging in PR #86. ARM64 self-update selection and real Windows-on-Arm + Docker Desktop qualification remain. Do not delay other roadmap work. |
| RM-29 Windows ARM64 | **Lowest priority** | Native GitHub Windows ARM64 CI shipped in PR #78, reproducible release packaging in PR #86 and ARM64 self-update selection in PR #91. Real Windows-on-Arm + Docker Desktop qualification remains. Do not delay other roadmap work. |
| Standalone Linux/macOS | **Demand-gated** | No support claim yet. WSL should create reusable narrow Linux host abstractions, but standalone hosts require their own contract and real Docker qualification. |
| RM-23 8.3 mount alias | **Intentionally deferred** | Current comma-path rejection remains supported behavior. Reopen only on demonstrated user demand. |
| RM-19 reserved-name migration | **Conditionally deferred** | Implement only when a future release actually proposes reserving a previously legal name. |
Expand Down Expand Up @@ -300,8 +300,9 @@ Merged foundations are removed from the remaining queue: RM-26 shipped in PR
#74, enterprise policy and signed registries in PRs #75 and #84, per-project
overlay trust in PR #80, RM-31 selection/staging/verification in PRs #76, #81
and #82, the WSL host boundary and native layout identity in PRs #77 and #83,
native Windows ARM64 CI in PR #78, and reproducible ARM64 release packaging in
PR #86. Unmerged pull-request coverage is not completion.
native Windows ARM64 CI in PR #78, reproducible ARM64 release packaging in PR
#86, and ARM64 self-update selection in PR #91. Unmerged pull-request coverage
is not completion.

1. **Image trust**
- cosign verifier configuration and verifier hash validation;
Expand All @@ -312,7 +313,10 @@ PR #86. Unmerged pull-request coverage is not completion.
2. **Remaining RM-31 self-update**
- selection/check, bounded staging and `gh attestation verify` are merged in
PRs #76, #81 and #82;
- Windows helper transaction, managed-shim reconciliation and rollback;
- ARM64 archive selection, verification and exact extraction are merged in
PR #91;
- rollback-safe Windows transaction and managed-shim reconciliation are implemented internally;
- temporary wait helper and user-facing apply wiring;
- release/self-test E2E.

3. **Remaining WSL2**
Expand Down
18 changes: 10 additions & 8 deletions docs/roadmap-implementation-requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ The minimum delivery gate for a code change is:
| RM-23 8.3 path alias | **Intentionally deferred** | Keep explicit comma-path rejection; reconsider only on demonstrated user demand |
| RM-24 Python/uv provider choice | **Decision complete — keep both** | No provider migration; Python provider and uv/uvx remain separate |
| RM-26 Python global CLI exposure | **Completed in PR #74** | Stateful pipx + `cb expose pipx` shipped; plain pip `/venv/bin` remains intentionally unexposed |
| RM-29 Windows ARM64 | **Native CI and release packaging shipped / update and hardware work remain** | PR #78 added native hosted ARM64 CI and PR #86 added reproducible release packaging; ARM64 self-update selection and real Windows-on-Arm + Docker Desktop E2E remain |
| RM-29 Windows ARM64 | **Native CI, release packaging and update selection shipped / hardware work remains** | PR #78 added native hosted ARM64 CI, PR #86 added reproducible release packaging and PR #91 added ARM64 self-update selection; real Windows-on-Arm + Docker Desktop E2E remains |
| RM-30 Authenticode | **Design complete / externally blocked** | Provision real code-signing certificate and protected signing mechanism |
| RM-31 self-update | **Selection, staging and verification shipped / ARM64 selection implemented** | PRs #76, #81 and #82 shipped the read-only plan, fail-closed staging and provenance verification; this tree adds ARM64 artifact selection, while transactional apply wiring and E2E remain |
| RM-31 self-update | **Selection, staging and verification shipped / ARM64 selection and transaction implemented** | PRs #76, #81, #82 and #91 shipped the read-only plan, fail-closed staging, provenance verification and ARM64 artifact selection; this tree adds the rollback-safe replacement transaction, while the temporary helper, user-facing apply wiring and release E2E remain |
| RM-34 Cargo expose enhancement | **Intentionally deferred** | Existing expose-all/explicit selection are sufficient; reopen only for concrete unmet use case |
| Linux/macOS hosts | **Demand-gated** | WSL may factor reusable Linux host code; standalone support needs its own demand and qualification |
| Enterprise policy | **Foundation and signed registry shipped / image trust remains** | PRs #75 and #84 shipped the machine-owned constraint layer and authenticated registry; image trust remains |
Expand Down Expand Up @@ -401,9 +401,10 @@ PR #76 shipped the command surface, release selection, check/dry-run behavior,
strict Windows/amd64 asset selection and bounded metadata rules. Private
same-volume staging and provenance verification followed. The current pipeline
also selects, stages and verifies the Windows/arm64 archive from native
`GOARCH`; unsupported architectures still fail closed. Transactional helper
and user-facing apply wiring plus release E2E remain incomplete until their
implementations merge.
`GOARCH`; unsupported architectures still fail closed. This tree also
implements the unexposed rollback-safe Windows replacement transaction and
complete proven-shim reconciliation. The temporary helper, user-facing apply
wiring and release E2E remain incomplete.

### Command and selection requirements

Expand Down Expand Up @@ -659,16 +660,17 @@ implementation task in this roadmap document.
Merged foundations are not remaining queue entries: RM-26 shipped in PR #74,
enterprise-policy foundation in PR #75, RM-31 selection/check in PR #76, the
WSL host boundary in PR #77, native Windows ARM64 CI in PR #78, and
reproducible ARM64 release packaging in PR #86.
reproducible ARM64 release packaging in PR #86, and ARM64 self-update selection
in PR #91.

1. Per-project overlay trust foundation.
2. Signed-registry enterprise policy.
3. Image trust at lock time, after signed-registry policy merges.
4. Remaining RM-31 helper/user-facing transactional apply wiring and E2E.
5. Remaining WSL2 native layout, Docker Desktop integration and real E2E.
6. RM-30 Authenticode only after certificate/protected-signing prerequisites exist.
7. RM-29 ARM64 self-update selection and real Windows-on-Arm + Docker Desktop
qualification last; do not delay higher-value work for them.
7. RM-29 real Windows-on-Arm + Docker Desktop qualification last; do not delay
higher-value work for it.

RM-19, RM-23, RM-34, standalone Linux/macOS, plugins, SBOM and Snyk are dormant
until their documented triggers occur. The govulncheck pin is recurring
Expand Down
Loading
Loading