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
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ real Linux CLI/runtime in an ephemeral container
|---|---|
| Windows 10/11 x64 + Docker Desktop (Linux containers) + PowerShell | **Supported** — this is the validated configuration |
| cmd.exe invocation of shims | Works for the common cases; less battle-tested than PowerShell |
| WSL2 | **v2 runtime wired; activation gated.** The native Linux runtime uses the fixed private WSL layout and Docker Desktop's WSL integration directly, including proof-bound retained-container orphan recovery, but production dispatch remains fail-closed until native state commands, integration coverage and real WSL2 qualification land. See [docs/wsl.md](docs/wsl.md) |
| WSL2 | **v2 runtime and state lifecycle wired; activation gated.** The native Linux runtime uses the fixed private WSL layout and Docker Desktop's WSL integration directly, including proof-bound retained-container and volume cleanup, but managed-tool dispatch remains fail-closed until integration coverage and real WSL2 qualification land. See [docs/wsl.md](docs/wsl.md) |
| Windows 11 ARM64 | **CI/release-artifact/update-path qualified only, not supported yet.** Native tests/build/dispatch run on GitHub-hosted ARM64 hardware, the release workflow produces a reproducible ARM64 archive, and self-update selects and verifies that archive by `GOARCH`; real Docker Desktop ARM64 E2E qualification remains |
| Linux / macOS hosts | **Not supported.** The program is Go and cross-compiles, but shim installation, path mapping and doctor checks are Windows-specific |
| Windows containers | Not supported; images are Linux images |
Expand Down Expand Up @@ -904,6 +904,9 @@ cb wsl prepare --check # native WSL2 only; read-only fixed-layout va
cb wsl prepare --apply # create missing fixed-layout directories, then revalidate
cb wsl install --check # read-only native install/config/shim plan
cb wsl install --apply # install this native binary, registry and fixed symlinks
cb state # native WSL: list only exactly proven namespace volumes
cb gc [TOOL|STATE_GROUP] # native WSL: dry-run current project cleanup
cb gc [TOOL|STATE_GROUP] --orphans # native WSL: dry-run missing-project cleanup
```

`cb bugreport` assembles `cb version`, the Windows and PowerShell versions
Expand Down Expand Up @@ -949,8 +952,8 @@ creation/upgrades and requires an already provisioned authenticated registry.
The bootstrap executable must itself be a bounded, current-user-owned regular
non-symlink file with safe executable permissions. This command still does not
contact Docker itself. Install reports the wired-but-gated runtime state;
managed tool dispatch remains fail-closed until native state commands,
integration coverage and real WSL2 qualification land. See
managed tool dispatch remains fail-closed until integration coverage and real
WSL2 qualification land. See
[docs/wsl.md](docs/wsl.md).

`cb wsl cleanup --check` reports exact namespace-owned retained runtime
Expand All @@ -962,6 +965,19 @@ publication so cleanup cannot guess across that race. Unlocked lease evidence
whose exact namespace no longer contains a matching retained container is
reported and reaped by `--apply`; locked leases are always preserved.

`cb state` and `cb gc` are also available natively in WSL before general tool
activation. They validate the fixed installation and authenticated registry,
discover only the current distribution/machine/user namespace, then reconstruct
and exactly prove every candidate before producing output or mutation. `cb gc`
is a dry run unless `--apply` is explicit, never selects shared volumes, and
uses non-force deletion with an absence check. `--orphans` requires the recorded
canonical Linux project path to be missing below a currently proven supported
storage boundary; a vanished `/mnt/<drive>` mount, symlinked ancestry and
non-directory objects are unsafe rather than guessed to be orphans. Apply
re-proves absence immediately before each removal. Native state
backup/restore remains separate future work and is not part of this v2 runtime
activation gate.

### Self-update release selection

`cb self-update --check` compares a release-qualified Windows/amd64 or
Expand Down Expand Up @@ -1123,9 +1139,9 @@ benchmark methodology and the disposable-container tradeoff are in
- Windows x64 + Docker Desktop (Linux containers) is the currently qualified
release target. The native WSL2 runtime, fixed-layout installation, project
mapping, managed volumes, Engine lifecycle, stdio/TTY, resize, signal and exit
propagation plus retained-container orphan reconciliation are wired, but
activation still requires native state commands, integration coverage and
real WSL2 + Docker Desktop qualification. Windows
propagation plus retained-container and volume cleanup are wired, but
activation still requires integration coverage and real WSL2 + Docker
Desktop qualification. Windows
ARM64 has native non-Docker CI
coverage and published release artifacts, but no Docker support claim.
- First invocation of a tool after `cb lock` may still need images present
Expand Down
16 changes: 11 additions & 5 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,14 +352,15 @@ internal/wsldocker native WSL Docker Desktop integration proof
internal/wslvolume native WSL namespaced volume identity/lifecycle and
stateful-tool binding planning
internal/wslrun native WSL fixed-layout tool runtime orchestration
internal/wslstate native WSL proof-bound state inventory and cleanup
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, wslfs, wslinstall, wslrun
main -> cli, diag, dockerrun, hostenv, mutationlock, policy, projectconfig, registry, selfupdate, state, wslfs, wslinstall, wslrun, wslstate
cli -> atomicio, diag, dockerrun, dockervol, lockfile, pathmap, policy, registry, statearchive, toml
projectconfig -> atomicio, pathmap, policy, registry, toml
diag -> dockerrun, dockervol, lockfile, pathmap, policy, registry
Expand All @@ -378,6 +379,7 @@ wslpathmap -> registry, wslproject
wsldocker -> hostenv
wslvolume -> hostenv, registry, wsldocker, wslproject
wslrun -> hostenv, lockfile, policy, registry, wsldocker, wslfs, wslpathmap, wslproject, wslshim, wslvolume
wslstate -> hostenv, policy, registry, wslfs, wslproject, wslvolume
selfupdate -> mutationlock, registry
atomicio, dockervol, hostenv, mutationlock, terminal, toml -> (leaves)
```
Expand Down Expand Up @@ -491,8 +493,9 @@ identity constructed by this package and its complete labels plus local
driver/scope. The package also preflights an entire stateful profile's
project/shared binding set, re-proves the exact project root before deriving
project identities, and ensures each distinct identity only after the complete
plan validates. Tool-time composition is wired but the host boundary keeps it
activation-gated while native state commands and qualification remain.
plan validates. Tool-time composition and the v2 state/GC lifecycle are wired,
but the host boundary keeps managed tools activation-gated while integration
coverage and real qualification remain.

`internal/wslrun` is the native WSL vertical orchestrator. It requires the
fixed layout, private registry, managed binary and exact invoked shim; resolves
Expand All @@ -514,8 +517,11 @@ all orphan removal uses the same proof-bound non-force lifecycle. Explicit
coordinator-held pass enumerates managed lease names and reaps an unlocked
lease only when complete namespace discovery contains no matching run; locked
lease-only records remain untouched. The production host
boundary still does not dispatch into this orchestrator until native state
commands, integration coverage and real WSL qualification complete.
boundary still does not dispatch into this orchestrator until integration
coverage and real WSL qualification complete. `internal/wslstate` is dispatched
separately before that gate; it plans current project/shared identities from
the fixed registry, consumes only exactly proven namespace volumes, and offers
dry-run-by-default non-force project cleanup without selecting shared state.

After the host runtime boundary is enforced, `cb self-update` is dispatched
before machine policy and registry loading. Release selection therefore remains
Expand Down
6 changes: 3 additions & 3 deletions docs/roadmap-decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ items from being repeatedly rediscovered as if they were immediately actionable.
| RM-24 Python / uv | **Keep both** | Decision complete. Built-in `python`/`pip` keep the dedicated Python provider; `uv`/`uvx` remain separate opt-in stateful profiles. |
| RM-26 Python global CLI exposure | **pipx yes; plain pip expose no** | Completed in PR #74. The separate stateful pipx profile and managed store shipped; project/compat `/venv/bin` remains intentionally unexposed. |
| RM-34 Cargo expose enhancement | **Intentionally deferred** | Existing expose-all and explicit binary selection are sufficient. Reopen only for a concrete unmet use case. |
| WSL2 | **Native WSL frontend** | Fixed-layout install, managed-tool runtime/Docker composition and proof-bound retained-container orphan reconciliation are wired behind the host gate. Native state commands, integration corpus and real WSL qualification remain before activation. No Windows↔WSL path/state guessing. |
| WSL2 | **Native WSL frontend** | Fixed-layout install, managed-tool runtime/Docker composition, proof-bound retained-container reconciliation, and the v2-required state/GC lifecycle are wired. Integration corpus and real WSL qualification remain before activation. No Windows↔WSL path/state guessing. |
| Enterprise policy | **Machine-owned constraint layer** | Foundation shipped in PR #75. Authenticated registry and image-trust follow-ups must extend this boundary and cannot be weakened by lower layers. |
| 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. |
Expand Down Expand Up @@ -349,15 +349,15 @@ is not completion.
- explicit read-only/apply Linux ownership, permission and symlink layout
preparation plus the fixed-path native install/config lifecycle are
implemented; ordinary managed tool dispatch is composed but remains
activation-gated pending state-command integration and qualification;
activation-gated pending integration coverage and real qualification;
- Docker Desktop WSL integration proof, proof-bound bounded control requests,
the separately constrained attach transport, strict raw-stream decoder,
exact container inspection, wait, TTY-resize, signal, start, creation and
stopped-container cleanup operations are wired with terminal events,
host-signal forwarding, retained-container cleanup and exit propagation;
- namespace-prefixed/labeled WSL volume identity plus proof-bound exact
inspect/create/remove and namespace discovery are implemented; tool-time
creation is wired while state/GC/backup/restore command integration remains;
creation and v2 state/GC are wired while backup/restore remains deferred;
- profile-aware nearest/outermost/trusted project-root selection, canonical
project and descendant storage classification (including symlink and
nested-mount rejection), and proof-consuming argument mapping are wired;
Expand Down
22 changes: 18 additions & 4 deletions docs/roadmap-implementation-requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ The minimum delivery gate for a code change is:
| 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 |
| Image trust | **Online/offline production and runtime authorization implemented / private-registry work remains** | Add an explicit private-registry credential bridge |
| Plugin/provider architecture | **Intentionally deferred** | Reopen only after at least two real integrations cannot fit the declarative model |
| WSL2 | **Native tool runtime wired / activation remaining** | The fixed install/config/shim lifecycle, project proof/mapping, namespaced tool-time volumes, direct Docker Desktop Engine lifecycle, stdin/output framing, raw TTY, resize, signal forwarding, retained-container cleanup, orphan reconciliation and exit propagation are composed behind the fail-closed host gate. Native state-management commands, integration corpus and real WSL2 + Docker Desktop qualification remain before activation. |
| WSL2 | **Native runtime/state wired / activation remaining** | The fixed install/config/shim lifecycle, project proof/mapping, namespaced tool-time volumes, direct Docker Desktop Engine lifecycle, stdin/output framing, raw TTY, resize, signal forwarding, retained-container cleanup, proof-bound state/GC, orphan reconciliation and exit propagation are composed. Integration corpus and real WSL2 + Docker Desktop qualification remain before activation. |
| Per-project overlays | **Completed in PR #80** | Add-only digest-bound trust model shipped on the merged enterprise-policy foundation |
| Release SBOM | **Conditionally deferred** | Trigger on shipped third-party/runtime dependencies or concrete compliance/consumer demand |
| Snyk | **Conditionally deferred** | Trigger only for a real coverage gap plus owner/account/token and triage/outage policy |
Expand Down Expand Up @@ -617,8 +617,11 @@ until wait records the exit status and are then removed through the proof-bound
cleanup path, avoiding an auto-remove race for fast tools. Process-held run
leases and a namespace coordinator close the create-before-lease race; automatic
startup and explicit `cb wsl cleanup --check|--apply` re-prove and recover only
exact unlocked or lease-less retained runs. Native state-command integration,
project/cross-boundary integration coverage and real WSL qualification remain.
exact unlocked or lease-less retained runs. Native `cb state`/`cb gc` now
reconcile only completely proven namespace volumes, never delete shared state,
and require an absent recorded Linux path before orphan deletion. Native state
backup/restore remains deferred; project/cross-boundary integration coverage
and real WSL qualification remain for v2 activation.

Implementation must define native config/shim location, Docker endpoint,
project identity, named-volume behavior, file permissions, case sensitivity,
Expand Down Expand Up @@ -647,6 +650,17 @@ domain. Later Docker lifecycle wiring may use the exact prefix and namespace
label for discovery, but adoption, backup, restore, GC or deletion must match
the complete constructed name and label identity.

The v2-required native state subset is now composed. `cb state` and `cb gc`
consume only the fixed layout and authenticated registry, prove the complete
discovered namespace before output or mutation, never select shared volumes for
deletion, and classify an orphan only when the recorded canonical Linux project
path is missing below a currently live supported storage boundary. Vanished
default drive mounts, symlinked ancestry and non-directory objects are unsafe
rather than orphan evidence. Apply re-proves orphan status immediately before
proof-bound non-force removal and verifies absence. Native state backup/restore
remains deferred and is not an activation prerequisite for the supported
runtime contract.

Qualification must include both Windows-filesystem and WSL-filesystem projects
plus mixed invocation rejection cases.

Expand Down Expand Up @@ -729,7 +743,7 @@ in PR #91.
2. Signed-registry enterprise policy.
3. Image trust at lock time, after signed-registry policy merges.
4. Remaining RM-31 real published-release/self-test E2E qualification.
5. Native WSL remaining state commands, integration corpus and real E2E.
5. Native WSL integration corpus and real E2E.
6. RM-30 Authenticode only after certificate/protected-signing prerequisites exist.
7. RM-29 real Windows-on-Arm + Docker Desktop qualification last; do not delay
higher-value work for it.
Expand Down
11 changes: 10 additions & 1 deletion docs/security-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ readable, and dangerous to let others edit.
authenticates signed registries when required, and reconciles only the fixed
managed binary and provenance-checked symlinks. The ordinary managed-tool
runtime is composed and tested but remains behind this host gate until
native state commands, integration coverage and real qualification land;
integration coverage and real qualification land;
unsupported native management commands remain rejected.
- **Native WSL installation does not adopt ambient files.** The bootstrap
executable is the exact OS-reported running image and must be a bounded,
Expand Down Expand Up @@ -151,6 +151,15 @@ readable, and dangerous to let others edit.
requires that same proof immediately before deletion and verifies absence
afterward. Prefix/label filters are discovery-only and cannot authorize
adoption or mutation. Windows and other WSL scopes remain foreign state.
- **Native WSL state cleanup proves before it classifies or mutates.** `cb state`
and `cb gc` require the fixed layout and authenticated registry, reconstruct
every namespace discovery result into an exact immutable volume identity,
and complete the whole plan before the first deletion. Shared volumes are
never GC candidates. A project volume is orphaned only when its recorded
canonical Linux path is absent below a currently live supported storage
boundary; vanished default drive mounts, symlinked ancestry, non-directories
and inspection errors are preserved and fail closed. Apply re-proves orphan
status immediately before each non-force deletion and proves absence afterward.
- **Native WSL run containers are transaction-bound.** The create
primitive accepts no raw Engine body, endpoint, privilege or Docker-socket
mount controls. It admits at most one existing, symlink-free canonical project
Expand Down
6 changes: 3 additions & 3 deletions docs/wsl-process-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

This document defines the process semantics implemented by ContainerBin's
native-Linux frontend inside WSL2. The runtime is composed and covered in this
tree, but production dispatch remains activation-gated until the required
native state commands, integration corpus and real WSL2 + Docker Desktop
qualification land.
tree, but managed-tool dispatch remains activation-gated until the integration
corpus and real WSL2 + Docker Desktop qualification land. The v2-required
native state inventory and cleanup surface is wired independently of that gate.
The corresponding Windows behavior is documented separately in
[the Windows shell/process contract](shell-contract.md).

Expand Down
Loading
Loading