pi-microsandbox 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/images.md ADDED
@@ -0,0 +1,190 @@
1
+ # Images
2
+
3
+ [Back to README](../README.md)
4
+
5
+ pi-microsandbox publishes six Ubuntu 26.04 image variants at
6
+ `ghcr.io/hcohe/pi-microsandbox`. Every tag is a Linux multi-platform image for
7
+ AMD64 and ARM64.
8
+
9
+ ## Published variants
10
+
11
+ `VERSION` below is the independent image version, such as `1.0.0`. Release
12
+ tags are write-once. Latest tags are mutable development tags built from `main`.
13
+ Push an exact `image-vVERSION` Git tag to publish a release cohort. Package
14
+ `vX.Y.Z` tags do not invoke image builds, and manual workflow runs validate only.
15
+
16
+ | Variant | Contents | Release tag | Latest tag |
17
+ | --- | --- | --- | --- |
18
+ | `base` | Required guest commands and CA certificates, without a language toolchain | `base-VERSION` | `base-latest` |
19
+ | `node` | Base plus Node.js 24.21.0, npm, pnpm 12.3.4, Yarn 1.22.22, and native addon build support | `node-VERSION` | `node-latest` |
20
+ | `python` | Base plus Ubuntu Python 3, pip, uv/uvx 0.12.12, and native extension build support | `python-VERSION` | `python-latest` |
21
+ | `rust` | Base plus Rust 1.98.0, Cargo, rustup, and native dependency build support | `rust-VERSION` | `rust-latest` |
22
+ | `go` | Base plus Go 1.26.8 and cgo build support | `go-VERSION` | `go-latest` |
23
+ | `default` | Base plus the Node.js, Python, Rust, and Go modules above | `VERSION` | `latest` |
24
+
25
+ The base contract includes `bash`, `sh`, `git`, `rg`, `file`, `cat`, `mkdir`,
26
+ `rm`, and the other core commands used by the image verification scripts. CA
27
+ certificates support HTTPS Git operations.
28
+
29
+ Select a variant in trusted project configuration:
30
+
31
+ ```toml
32
+ # .pi-msb.toml
33
+ image = "ghcr.io/hcohe/pi-microsandbox:python-1.0.0"
34
+ pull_policy = "if-missing"
35
+ ```
36
+
37
+ If `image` is omitted, pi-microsandbox uses the configured `default` variant
38
+ release, qualified by both its `VERSION` tag and immutable index digest. Image
39
+ versions are independent of the installed package version. If `pull_policy` is
40
+ omitted, `"if-missing"` is used: Microsandbox pulls the image only when that
41
+ exact reference is absent from its cache. Use `"always"` to check a registry for
42
+ an updated mutable tag, or `"never"` to require a cached local image.
43
+
44
+ ## How the images are assembled
45
+
46
+ [`default-image/variants.json`](../default-image/variants.json) is the single
47
+ source of variant composition and tag names. The workflow passes each entry's
48
+ toolchain list to one generic
49
+ [`default-image/Dockerfile`](../default-image/Dockerfile). Modular
50
+ `default-image/install/<language>.sh` and
51
+ `default-image/verify/<language>.sh` scripts install and exercise each selected
52
+ language.
53
+
54
+ The `default` variant runs the same Node.js, Python, Rust, and Go modules as the
55
+ individual variants. It does not have a duplicate package list. This keeps an
56
+ installer, its functional checks, and every image that uses it aligned.
57
+
58
+ Release builds pin the Ubuntu multi-platform image digest and a dated Ubuntu apt
59
+ snapshot shared by every variant. The snapshot pin applies only while the image
60
+ is assembled. Published images restore Ubuntu's normal apt sources so projects
61
+ can install current packages at runtime.
62
+
63
+ ## Build a custom image
64
+
65
+ A custom image must provide `bash`, `sh`, `git`, `rg`, `file`, `cat`, `mkdir`,
66
+ and `rm`. Install CA certificates if the guest will use Git over HTTPS. With
67
+ `bootstrap_tools = "auto"`, pi-microsandbox can install missing required
68
+ commands through `apt-get` when the network policy permits it. A prepared image
69
+ is required when bootstrap is disabled or package repositories are unavailable.
70
+
71
+ Microsandbox supports registry images and images loaded into its own local
72
+ cache. Images in the Docker daemon are not automatically visible to
73
+ Microsandbox.
74
+
75
+ ### Publish to an OCI registry
76
+
77
+ Start from a versioned base tag so the guest contract does not change when
78
+ `main` is rebuilt:
79
+
80
+ ```dockerfile
81
+ FROM ghcr.io/hcohe/pi-microsandbox:base-1.0.0
82
+
83
+ RUN apt-get update \
84
+ && apt-get install -y --no-install-recommends jq \
85
+ && rm -rf /var/lib/apt/lists/*
86
+ ```
87
+
88
+ Build and push for the current host architecture with Docker:
89
+
90
+ ```sh
91
+ docker build -t registry.example.com/team/pi-image:1.0.0 .
92
+ docker push registry.example.com/team/pi-image:1.0.0
93
+ ```
94
+
95
+ Or publish both supported architectures with Buildx:
96
+
97
+ ```sh
98
+ docker buildx build \
99
+ --platform linux/amd64,linux/arm64 \
100
+ --tag registry.example.com/team/pi-image:1.0.0 \
101
+ --push .
102
+ ```
103
+
104
+ Then select it in `.pi-msb.toml`:
105
+
106
+ ```toml
107
+ image = "registry.example.com/team/pi-image:1.0.0"
108
+ pull_policy = "if-missing"
109
+ ```
110
+
111
+ For a private registry, configure authentication on the host with Microsandbox,
112
+ for example with `msb registry login`, or in
113
+ `~/.microsandbox/config.json`. Registry pull credentials belong in
114
+ Microsandbox configuration, not in pi-microsandbox guest `secrets`. See the
115
+ Microsandbox [image guide](https://docs.microsandbox.dev/images/overview) and
116
+ [configuration reference](https://docs.microsandbox.dev/configuration).
117
+
118
+ ### Load a local Docker image
119
+
120
+ Build the image, then transfer a Docker archive into the Microsandbox cache and
121
+ assign a local tag:
122
+
123
+ ```sh
124
+ docker build -t pi-image:dev .
125
+ docker save pi-image:dev | msb load --tag pi-image:local
126
+ ```
127
+
128
+ The file form is useful when a pipeline cannot be used:
129
+
130
+ ```sh
131
+ docker save -o pi-image.tar pi-image:dev
132
+ msb load --input pi-image.tar --tag pi-image:local
133
+ ```
134
+
135
+ Use the local reference without contacting a registry:
136
+
137
+ ```toml
138
+ image = "pi-image:local"
139
+ pull_policy = "never"
140
+ ```
141
+
142
+ `pull_policy = "if-missing"` also uses the loaded image while it remains in the
143
+ cache, but may try a registry if it is removed. The Microsandbox
144
+ [local image guide](https://docs.microsandbox.dev/examples/docker/local-images)
145
+ documents the same transfer requirement and `msb load` forms.
146
+
147
+ ## Add a language variant
148
+
149
+ A new language needs all three of these changes:
150
+
151
+ 1. Add an executable `default-image/install/<language>.sh`.
152
+ 2. Add an executable `default-image/verify/<language>.sh`.
153
+ 3. Add the variant and its toolchain composition to
154
+ `default-image/variants.json`.
155
+
156
+ Names become filenames and image tags. Use at most 48 characters: start with a
157
+ lowercase letter, then use only lowercase letters, digits, and hyphens. Do not
158
+ use path syntax, underscores, or the reserved names `base`, `default`,
159
+ `dispatch`, or a name beginning with `_`.
160
+
161
+ Pin downloaded tool versions. Record and verify SHA-256 checksums for both AMD64
162
+ and ARM64 artifacts, using the helpers in `install/_common.sh`. Do not pipe
163
+ network downloads into a shell. The verifier must test native functionality,
164
+ not only version output. For example, compile and run a native extension or a
165
+ small program. Add the language to the `default` variant's `toolchains` only if
166
+ it should become part of the complete image; do not copy its packages into a
167
+ second default-only installer.
168
+
169
+ Validate metadata and shell scripts locally:
170
+
171
+ ```sh
172
+ node scripts/image-variants.mjs matrix
173
+ shellcheck -e SC1091 default-image/install/*.sh default-image/verify/*.sh
174
+ ```
175
+
176
+ Build a representative variant with the same context and build arguments as CI.
177
+ The Dockerfile runs its functional verifier during the build:
178
+
179
+ ```sh
180
+ docker buildx build \
181
+ --platform linux/amd64,linux/arm64 \
182
+ --build-arg IMAGE_VARIANT=node \
183
+ --build-arg "TOOLCHAINS=node" \
184
+ --build-arg IMAGE_VERSION=dev \
185
+ --file default-image/Dockerfile \
186
+ default-image
187
+ ```
188
+
189
+ Repeat with the new variant and its exact space-separated toolchain composition.
190
+ Build the `default` variant too if its composition changed.
package/docs/safety.md ADDED
@@ -0,0 +1,39 @@
1
+ # Safety model
2
+
3
+ [Back to README](../README.md)
4
+
5
+ The default is fail-closed:
6
+
7
+ - A valid, trusted project configuration is resolved before a sandbox is
8
+ started. A boot or image/tool failure blocks the seven routed tools (`read`,
9
+ `write`, `edit`, `ls`, `find`, `grep`, and `bash`).
10
+ - `mode = "auto"` is retained as an alias for `"direct"`; both use a
11
+ same-absolute-path read/write bind. `mode = "git"`, `"direct"`, and
12
+ `"none"` select those behaviors explicitly.
13
+ - `execution_target = "host"` is an opt-in escape for routed tool calls. While
14
+ a sandbox is active it requires an interactive approval for the exact tool,
15
+ working directory, and recursively sorted arguments. It is not available in
16
+ headless operation and is never silently selected.
17
+ - `/msb off` is an explicit host-mode handoff and does not prompt. This is
18
+ different from `fallback_mode = "host"`, which automatically uses host tools
19
+ after a sandbox failure and is shown as `MSB host fallback`.
20
+ - A project cannot replace another process's sandbox: ownership is a
21
+ non-blocking kernel `flock` acquired before any sandbox or volume mutation.
22
+ Stale sandbox pruning never removes volumes.
23
+
24
+ The extension entry point does not import the native SDK. Unsupported hosts can
25
+ still load Pi and remain blocked or explicitly off. pi-microsandbox currently supports
26
+ macOS Apple Silicon and Linux with KVM; Windows is not supported.
27
+
28
+ ## Host-read exceptions
29
+
30
+ Pi-discovered `SKILL.md` reads are a narrow host-read exception. A standalone
31
+ skill grants only its exact file; a directory skill grants regular files
32
+ canonically below its directory. Symlink escapes, devices, sockets, and
33
+ unrelated host paths are denied. A successful sandbox Bash/grep result may
34
+ record one exact generated `details.fullOutputPath`; neighboring files do not
35
+ become readable.
36
+
37
+ ## Reporting vulnerabilities
38
+
39
+ Report suspected vulnerabilities privately. See the [security policy](../SECURITY.md); do not open a public issue.
@@ -0,0 +1,57 @@
1
+ # Storage modes and retained work
2
+
3
+ [Back to README](../README.md)
4
+
5
+ ## Storage modes
6
+
7
+ | Mode | Guest view | Host effect of routed writes |
8
+ | --- | --- | --- |
9
+ | `git` | A named volume at the repository root, with the same absolute path | Volume only |
10
+ | `direct` | The current directory bind-mounted at the same absolute path | Host directory |
11
+ | `none` | An empty tmpfs at the same absolute path | No host files; changes disappear with the sandbox |
12
+ | `auto` | Same as `direct` | Host directory |
13
+
14
+ `direct` is intentionally a warning-level escape from the Git isolation model:
15
+ routed edits modify the live host directory. `none` is useful for testing path
16
+ behavior and starts empty; it is not a retained workspace.
17
+
18
+ ## Git and retained volumes
19
+
20
+ Git mode never bind-mounts the host checkout. On boot, pi-microsandbox captures the
21
+ committed `HEAD` (and selected branch) into a temporary verified Git bundle,
22
+ copies it into the guest, and seeds a named volume mounted at the repository's
23
+ absolute root. Untracked files, including `.env`, and working-tree edits are
24
+ not in that bundle. The temporary host and guest bundle files are removed after
25
+ seeding, including failure paths.
26
+
27
+ Edits and commits made in Git mode land in the retained volume. The host
28
+ checkout is not changed by ordinary routed tools. A normal Pi session shutdown
29
+ removes the sandbox but keeps the managed volume; the next boot reuses it only
30
+ when the complete session/schema/mode/cwd identity matches. A copied or forked
31
+ session state is rejected by the full session ID and gets a different resource
32
+ identity.
33
+
34
+ The SDK's `VolumeHandle` returned by `Volume.get()` does not expose a host
35
+ path. pi-microsandbox therefore refuses to fabricate one: a newly created volume
36
+ may show its path, while a later retained-volume lookup may not support
37
+ `/msb volumes ls` or volume enrichment. The volume remains mountable by name
38
+ and is never automatically deleted. Use the path recorded at creation time or
39
+ the microsandbox volume tooling when host-side inspection is required.
40
+
41
+ To manually synchronize a retained checkout, use a host-side fetch deliberately
42
+ (the command is not performed automatically by pi-microsandbox):
43
+
44
+ ```sh
45
+ REPO=/absolute/path/to/checkout
46
+ VOLUME_PATH=/path/returned-for-the-managed-volume
47
+ BRANCH=$(git -C "$REPO" branch --show-current)
48
+
49
+ git -C "$VOLUME_PATH" remote remove host 2>/dev/null || true
50
+ git -C "$VOLUME_PATH" remote add host "$REPO"
51
+ git -C "$VOLUME_PATH" fetch --no-tags host "$BRANCH"
52
+ # Review before changing the retained checkout:
53
+ git -C "$VOLUME_PATH" log --oneline --decorate --all -10
54
+ ```
55
+
56
+ The host repository is an input to this explicit sync operation. Do not add a
57
+ host checkout bind mount to Git mode.
@@ -0,0 +1,20 @@
1
+ # Recovery and troubleshooting
2
+
3
+ [Back to README](../README.md)
4
+
5
+ 1. Run `/msb status` and `/msb logs`.
6
+ 2. If the state is `unavailable (blocked)`, fix the displayed configuration,
7
+ image, virtualization, or missing-tool error and run `/msb reload`.
8
+ 3. If a process died, a later startup or `/msb prune` can remove its labelled
9
+ sandbox after the owner lock is free. The named volume is retained.
10
+ 4. If a same-name resource has different managed labels, pi-microsandbox refuses to
11
+ attach or replace it. Remove only a verified managed, unmounted volume with
12
+ `/msb volumes rm NAME --yes`.
13
+ 5. On unsupported virtualization hosts, use `PI_MSB_DISABLE=1` for explicit host
14
+ mode or configure `fallback_mode = "host"` knowingly. The latter remains
15
+ visibly distinct from `/msb off`.
16
+ 6. For bootstrap failures, use an image that already contains the required
17
+ command list or allow the configured network policy to reach the package
18
+ repositories. Deny mode cannot bootstrap an image missing those commands.
19
+
20
+ For installation prerequisites, see [installation and requirements](getting-started.md). To test a live sandbox from source, see the [live test matrix](development.md#live-test-matrix).