--- id: SAND-WP-0015 type: workplan title: "Provide a pinned bwrap rein runtime and private state" domain: infotech repo: sand-boxer status: blocked flavor: implementation owner: codex topic_slug: bwrap-runtime-and-private-state created: "2026-09-05" updated: "2026-09-09" state_hub_workstream_id: "d3f12387-fd23-58f0-b979-9c811507614d" --- # Provide a pinned bwrap rein runtime and private state Implement the runtime prerequisites returned by Glas in `GLAS-WP-0012` and `docs/local-profile-acceptance.md`. Continue owner work `SAND-WP-0014-T05` and live residual `GLAS-IN-0002`. Runtime startup is a separate acceptance gate from credential delivery, enforced provider egress, and a real model task. ## Mount an owner-selected, digest-pinned Python runtime ```task id: SAND-WP-0015-T01 status: done priority: high state_hub_task_id: "93e4aad8-ba9b-5850-93d4-b5bf78ac8978" ``` Add exact artifact verification to trusted extension configuration and mount the standalone runtime read-only at a fixed namespace path. Reject altered content/modes, unexpected files, escaping symlinks, special files, and source or workspace overlap. A caller cannot choose runtime paths through exec input. Provide a non-editable rein-aharness/llm-connect bundle builder with recorded source revisions and resolved dependency versions. Completed 2026-09-05. `extensions/runtime.py` verifies complete artifact contents/modes before a read-only mount; the builder installed committed rein-aharness `1429db5` and llm-connect `0056094` without editable source paths. Candidate digest and source/package evidence are in `docs/bwrap-runtime.md`. ## Keep writable runtime state outside the repository ```task id: SAND-WP-0015-T02 status: done priority: high state_hub_task_id: "c8a689f8-bdf2-57a2-8521-a1c0ca44e750" ``` Create private mode-0700 HOME/config/cache/state/tmp directories within the namespace, preserve them across exec requests, and remove them with teardown. Keep the command environment sanitized and disable Python user-site/bytecode writes. Fail closed on profile network/setup-credential declarations that the current bwrap implementation cannot honor. Completed 2026-09-05. Mode-0700 namespace HOME and XDG/TMP directories sit outside the copied Git tree. Explicit runtime PATH selection remains owner controlled. Unsupported egress/default-allow and setup credentials now refuse before workspace creation; regression tests cover these boundaries. ## Verify the real rein runtime and owner regression paths ```task id: SAND-WP-0015-T03 status: done priority: high state_hub_task_id: "1a3002f6-c6a8-59d0-9d38-942028419de5" ``` Run `make check`, the existing authenticated cross-request owner smoke, and a real runtime startup smoke. Verify the actual rein CLI and adapter imports, read-only runtime, private HOME, clean worktree, absent source, loopback-only network, and teardown. Keep the production Glas profile blocked. Completed 2026-09-05. `make check`: lint clean, 132 tests passed. Authenticated owner API smoke `223db65b` returned HTTP 200 and proved exact consumer identity, stdin delivery, absent source, loopback-only network and complete teardown. Pinned runtime smoke `d4de9531` ran the actual rein CLI and imported its Claude adapter, proved read-only runtime/private HOME/clean worktree, retained private state across a second exec, and removed the workspace. No model call or credential acquisition occurred; T04 remains waiting. ## Resolve Claude credentials, enforced egress, and production acceptance ```task id: SAND-WP-0015-T04 status: wait priority: high state_hub_task_id: "58817ef6-76d9-5e34-908f-c024e6c99f93" ``` The 2026-09-05 routing lookup found no concrete Anthropic/Claude workload lane. The generic OpenBao template is not a delegable lane; the OpenRouter AppRole belongs to another rein. Credential owner railiance-platform/OpenBao plus rein-aharness must establish a concrete Claude-compatible route and delivery/ revocation contract before values can be requested or supplied to the runtime. Sand-boxer must then implement the matching enforced provider egress contract (including DNS/TLS and denied-destination proof) and pin/deploy the actual Claude executable. No unrestricted-network or interactive-login substitute is permitted. Review the deployed runtime/profile with Glas, run its real-rein acceptance fixture, and update only the proven profile's readiness. No production schedule is enabled by the runtime-startup smoke. This task and SAND-WP-0014-T05 remain open until those gates pass. The detailed return contract and runtime proof are in `docs/bwrap-runtime.md`; the live cross-repo residual remains `GLAS-IN-0002`. ## 2026-09-05 transport implementation evidence T04 remains waiting on owner machine authentication, protected credential delivery, pinned Claude startup and the real model proof. CCR-2026-0016 custody is confirmed by a metadata-only check of live version 2; no value was read. HTTPS egress is now implemented as an exact owner/profile allowlisted CONNECT proxy while retaining an isolated network namespace. Non-secret live smoke sandbox e290e788 verified provider TLS response, undeclared destination and direct-IP denial, and proxy/workspace teardown. See docs/bwrap-egress.md. ## 2026-09-05 credential transport owner return Owner-bound exec-env transport is implemented and proved with a synthetic provider in real sandbox 0e5fb35a. Exact route/profile/project/actor/run binding, child-only key injection, pre-truncation redaction, next-exec absence and teardown pass. No real key read or production profile activation. See docs/bwrap-credentials.md. SECRETS-WP-0009 now owns native AppRole adoption for CCR-2026-0016, including a data-only consumer read policy. Its production exec refuses before OpenBao until SECRETS-WP-0007-T04 and SECRETS-WP-0008-T02/T06 deliver canonical authorization/consume and service authority. T04 remains waiting on that live owner path, the pinned Claude executable and real model acceptance. ## 2026-09-06 combined-runtime candidate returned to Glas Answered the GLAS-WP-0015 handoff. Added candidate profile `profile.claude-agent-dev-proof` version 1.1.0 (`ext.bwrap`, localhost-only, `default: deny` with declared `api.anthropic.com:443`) for GLAS-WP-0012 review. The committed profile grants no egress by itself: `ext.bwrap` refuses it unless the owner extension config allowlists the destination, and a regression test now asserts that fail-closed default. `make check`: lint clean, 172 tests passed. Resolved the differing project examples in favour of the acceptance runner's `actor: agt` / `project: glas-local-proof`, and bound the documented credential route to that single project rather than broadening it. The full return contract — profile id/revision, host scope, consumer tuple, runtime digest and mount paths, declared egress, and the value-free denial/cleanup receipts — is in `docs/bwrap-runtime.md`. T04 stays `wait`: the concrete Claude credential lane and delivery/revocation contract, owner machine authentication, the pinned Claude executable with its own proxy startup proof, and the real-model acceptance are still operator and upstream-owner gated. Provider workspace scope and spend limit remain operator inputs. `SAND-WP-0014-T05` remains open on the same gates. ## Package and prove the pinned Claude executable independently of custody ```task id: SAND-WP-0015-T05 status: done priority: high state_hub_task_id: "f0163cda-b581-56a0-a0dd-9c8a436f5bbe" ``` Split the independent executable packaging/startup portion from T04 so credential custody does not hide completed local runtime work. Implement explicit binary pinning, reject mismatches/host wrappers, and prove actual startup with the broker proxy environment and complete cleanup. T04 retains protected deployment, credential adoption and real-provider acceptance. ## Pinned Claude candidate and isolated startup — 2026-09-06 The builder now accepts `--claude-binary`, `--claude-sha256` and `--claude-version` together. It requires a regular native ELF file, verifies the exact copied bytes, refuses symlinks/wrappers/mismatches and existing destination files, and copies only the executable as bin/claude mode 0755. The expected version is metadata until the sandbox smoke checks the actual output. No interactive HOME, provider key or login state is copied. Candidate provenance: the explicitly selected installed native release `/home/worsch/.local/share/claude/versions/2.1.263`, SHA-256 `26d020351e8112f4006790f3cfce43b4c9df0c1bb1d0e542364d64151b81d5ba`. This is a digest pin of the selected local artifact, not an upstream signature verification claim. Complete runtime candidate: `/tmp/sandboxer-claude-runtime-20260906`, SHA-256 `5cf9a16c5d77a16bdb2cb5b3df06ea655356bc2d44741791e3fedfee20d7e922`. Mount remains `/opt/sandboxer/runtime`; Claude is `/opt/sandboxer/runtime/bin/claude`. Rein sources remain 1429db5 / llm-connect 0056094; resolved dependency versions are recorded in the evidence. Rebuilding may resolve different dependencies; the complete digest pins this artifact, not future builds. Sandbox f8821ec2 ran real `claude --version` -> `2.1.263 (Claude Code)` plus rein CLI/import checks, with owner allowlisted provider egress and HTTPS_PROXY set by the broker. Runtime read-only, private 0700 HOME/state persistence, clean Git, absent source and loopback-only interfaces passed; workspace and proxy removed. `make check`: lint passed, 175 tests passed. Evidence: docs/evidence/SAND-WP-0015-claude-startup-2026-09-06.json. Reproduce with the builder options above and `scripts/smoke-bwrap-runtime.py --runtime-path --runtime-sha256 --claude-version 2.1.263`. Limits: `--version` proves startup with the proxy environment, not that Claude has sent a provider request through it. No credential acquisition or model run. The /tmp candidate is not production placement; protected artifact installation, owner configuration, credential adoption and real-model proof remain T04 gates. ## Install the pinned runtime in the local owner's protected store ```task id: SAND-WP-0015-T06 status: done priority: high assignee: the-custodian state_hub_task_id: "f85f54c9-1081-5d0c-95ad-aca20ede8d66" ``` HFACT-WP-0001-T04 consumes this independent installation return. Reuse the already verified combined candidate with digest `5cf9a16c5d77a16bdb2cb5b3df06ea655356bc2d44741791e3fedfee20d7e922`; do not rebuild resolved dependencies. Publish it under the local owner's private artifact store, verify exact copied content/modes and refusal of unsafe or corrupted destinations, and prove startup/read-only access/teardown through the installed path. The owner remains trusted; this is not root-owned storage. T04 retains real credential adoption, owner configuration, model acceptance and production placement. No credential route or profile is activated here. `scripts/install-bwrap-runtime.py` installs below the owner's home into a mode-0700 store, verifies before and after copying, preserves artifact modes and internal symlinks, serializes publishers and never overwrites a published artifact. Existing modified artifacts are refused rather than repaired silently. Group/other-writable ancestors, unsafe permission bits and store aliases refuse. Unit tests cover integrity, idempotence, copy-time corruption and access modes. T06 completed 2026-09-08 on bnt-lap001, local owner UID 1000. Installed the unchanged 358-entry / 245176062-byte candidate at `/home/worsch/.local/share/sandboxer/runtimes/5cf9a16c5d77a16bdb2cb5b3df06ea655356bc2d44741791e3fedfee20d7e922`. The private store is mode 0700; the installing owner remains trusted. A root-owned system installation was not claimed or required for this local owner contract. The installed-path sandbox smoke `51b59587` passed real Claude 2.1.263 and rein startup, read-only mount, private state persistence, clean worktree, absent source, loopback-only interfaces and complete workspace/proxy teardown. No model call or credential acquisition occurred. `make check`: lint clean, 188 tests passed. Two existing tests require the checkout directory name `sand-boxer`; the final full check used that canonical basename. Evidence: `docs/evidence/SAND-WP-0015-protected-local-install-2026-09-08.json`. T04 retains owner execution configuration, native credential/egress and real-model acceptance; Railiance installation needs its own target-specific return. ## 2026-09-09 factory metered route source return Implemented the trusted, ephemeral Messages route described in [docs/bwrap-messages-route.md](../docs/bwrap-messages-route.md). Actual local bwrap owner transport proves provider key/ledger separation, direct-route denial, revocation and teardown; rein also proves metered request plus commit import and close replay. `make check`: lint clean, 199 passed. T04 remains waiting for the admitted provider-to-owner bootstrap, updated protected runtime/profile, Railiance placement, live compatibility and G0. Existing child-provider-key/direct-CONNECT proofs do not admit this different credential holder or metered profile. No CCR, secret read, deployment or paid request was performed. ## 2026-09-09 standalone owner packaging and runtime selection Added frozen-lock owner build mode for the matched rein/llm/Glas/sandboxer set, with non-editable installation and recorded lock/source/package pins. Sand-boxer wheels now carry their profile and extension definitions, fixing a bwrap owner failure that source-checkout tests could hide. The trusted Messages binding can select the digest-pinned runtime without adding an API or profile override. `make check`: lint clean, 205 passed. Existing standalone workload builds remain supported. See docs/bwrap-runtime.md and rein's docs/owner-bootstrap.md. The project's `evidence/2026-09-09-owner-bootstrap.json` records the actual candidate build and isolated installed-interpreter/CLI proof. T04 remains wait for accepted credential-to-owner delivery, current protected installation and Railiance placement, provider compatibility and G0. Source packaging does not reopen completed T01-T03, T05-T06, broaden the old CCRs or activate the previously installed 2.1.263 artifact. The first standalone candidate exposed a stale cached local wheel despite current Git metadata. Owner builds now refresh all local distributions and compare every installed package source/definition file with its tracked source; stale, missing or extra files refuse the build. Four content-conformance regressions cover that gap.