rein-aharness/docs/sandbox-artifact-return.md
tegwick c63caf5568
Some checks are pending
Governed runtime contract / contract (push) Waiting to run
feat: import governed sandbox commits and enforce native CLI limits
Assistant: codex
Assistant-Model: gpt-5.6-luna
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-09 14:08:10 +02:00

3.4 KiB

Sandbox commit return and native CLI limits

The worker owns the original repository transaction and repository grant. Glas owns sandbox lifetime. For a granted profiled run, the worker supplies a trusted process-local capture callback. Glas invokes it after successful rein cleanup and before sandbox destruction. Callback failure is artifact_capture failure; teardown still runs. Artifact bytes are never serialized into gateway evidence.

The initial transfer supports owner-mediated local namespaces and exactly one local Git commit. It captures at most 128 KiB of bundle data, verifies the exact baseline/head and ancestry in a disposable checkout, limits new objects to 1,024 / 2 MiB, rejects symlinks/gitlinks and out-of-grant paths, and fast-forwards the original checkout only after successful teardown and another lease/baseline check. Ignored runtime caches are discarded with the sandbox. Source changes, lease loss, missing or corrupt capture, and failed teardown refuse import.

Acceptance and external metrics remain in the outer worker. The inner Glas task continues to use --no-metrics without an inner repository grant. Terminal-close replay uses the existing durable outbox and does not run the workload again. The repository lock is cooperative; unexpected external changes are detected, not rolled back. A crash or lease loss at the final mutation/receipt boundary still requires the existing recovery process to classify the resulting commit.

Native limits

Glas profile limits max_budget_usd and max_turns are carried in its generated TaskSpec into the agentic Claude adapter. A supplied task file cannot bypass these profile controls. Positive finite USD amounts and positive integer turn limits are required. A controlled run verifies Claude Code >= 2.1.217, supplies --max-budget-usd / --max-turns, and requires one successful terminal JSON result with valid cost, turn and token accounting. Limit exhaustion, missing accounting and reported overruns cannot produce a successful run. Bounded USD cost follows runner, Glas evidence and the outer close evidence; result text and artifact bytes do not enter the close outbox. Runs without these optional controls retain their legacy behavior, including its incomplete token accounting.

This is native per-run control and accounting, not a factory spend grant or a hard EUR ceiling. The Claude CLI contract is the upstream reference. Before paid admission, verify the protected binary's actual enforcement/overrun semantics, reserve daily/total worst-case costs outside the sandbox, define conservative EUR/USD treatment, and retain unknown outcomes as held reservations. No profile was enabled and no paid request was made by this change. Deploy a newly verified runtime containing the matching rein/Glas source pins before exercising the real model path.

Verification

tests/test_repository_artifact.py runs real Git export/import with adversarial artifacts. REIN_REAL_BWRAP=1 pytest tests/test_repository_artifact_bwrap.py -q adds actual sand-boxer owner execution, Glas lifecycle and worker acceptance, including response-lost close replay. Its queue and task authoring are fixtures; it proves neither a natural Activity Core claim nor model/provider admission. tests/test_native_limits.py exercises control propagation, terminal accounting, invalid/exhausted results and refusal of older CLI versions without inference.