Skip to content

The Trial sandbox: bwrap, its own processes, fresh homes and logins #1012

Closed

Description

@JacobStephens2

Parent

#977

What to build

A sandbox launcher runs a Trial's or a Grader's session in bwrap, with a process namespace of its own.

  • It binds only:
    • the prepared repository;
    • the Arm's build and the Harness's binary;
    • the Factory skills folder;
    • a fresh home;
    • the toolchains the session needs, read-only.
  • The fresh home holds the login, and the user-level instructions, rules, settings and hooks a Run's session reads, those read-only.
    • Codex's auth.json is bound read-write in place, so a refresh reaches the file production uses. Its binary's release folder is bound, not the binary alone, since Codex looks for codex-code-mode-host beside it.
    • Claude gets CLAUDE_CODE_OAUTH_TOKEN from the Credentials' claude.setup_token.
    • Muse binds ~/.config/muse/auth.json and its .auth.json.lock. agy binds ~/.gemini/antigravity-cli/antigravity-oauth-token. Each is bound read-write in place, since each writes in place (Live checks for the Trial sandbox #1009).
    • Grok gets a home of its own for Trials, ~/.thirdshift/trials/grok, signed in once with GROK_HOME=~/.thirdshift/trials/grok grok login. Grok renews its 6-hour key by renaming a new auth.json into place, and a single-file bind refuses that rename (Live checks for the Trial sandbox #1009, research note §11). Production's ~/.grok is never bound.
      • Before each Trial, the launcher deletes everything in that home but auth.json and auth.json.lock, then binds the folder as the Trial's ~/.grok.
      • Grok Trials run one at a time, so no two share that home.
      • Grok's binary lives under ~/.grok/downloads, which the Trials home hides. So the launcher binds the binary read-only at a path outside the home, after binding the home.
      • If the home has no login, a Grok Trial fails before its session starts, naming the grok login command above.
    • OpenCode gets its provider's key through its environment, never production's opencode.db, which holds its credentials beside its sessions. 2.0.24 no longer reads OPENCODE_AUTH_CONTENT.
      • The key comes from a new opencode.api_key in the Credentials, added the way claude.setup_token was (Save Claude setup tokens in Credentials #1125).
      • The user's opencode.json is bound read-only, and the Trial's config sets the provider's apiKey to {env:…} naming the variable that carries the key.
      • thirdshift setup asking for it can be a later Ticket. Without it, an OpenCode Trial fails before its session starts.
  • Harness flags stay as ADR 0013 has them.
  • The network is still the host's here. The Trial sandbox's network: an allowlisting proxy #1013 gives the sandbox its own.

Its tests run where bwrap works, and anywhere else they report themselves skipped rather than passing silently.

Acceptance criteria

  • A sandboxed process can't see an unbound path, such as the evals folder or another checkout.
  • It can't read the host's processes' command lines, and everything it starts ends with it.
  • A refresh of the bound Codex login reaches the real file, tested with a fake.
  • A Grok login renewed by rename inside the sandbox is saved in the Trials Grok home, tested with a fake. Production's ~/.grok is untouched.
  • Before a Grok Trial, the Trials Grok home holds nothing but its login and lock, and two Grok Trials never run at once.
  • An OpenCode Trial gets its key only from opencode.api_key, and never sees opencode.db.
  • Where bwrap can't run, the tests report themselves skipped.

Activity

  1. JacobStephens2 commented on Oct 23, 2026

    @JacobStephens2
    OwnerAuthor

    This was generated by AI.

    The body changed after #1009's live checks (research note §11, #1179). The single-login-file design fails for two Harnesses:

    • Grok renews its 6-hour key by rename, which a single-file bind refuses. Trials now use a Grok home of their own, and Grok Trials run one at a time.
    • OpenCode 2.0.24 keeps its key in opencode.db, beside its sessions. Its key now comes from a new opencode.api_key in the Credentials, through its environment.

    Codex also needs its release folder bound. Three acceptance criteria were added for these.

    Before the first Grok Trial, the user runs GROK_HOME=~/.thirdshift/trials/grok grok login once.

  2. JacobStephens2 commented on Oct 23, 2026

    @JacobStephens2
    OwnerAuthor

    This was generated by AI.

    The Trials Grok home is signed in, and checked on the thirdshift host:

    • Grok 1.0.67 answered in bwrap with ~/.thirdshift/trials/grok bound as ~/.grok, through api.x.ai, cli-chat-proxy.grok.com, grok.com and api.mixpanel.com.
    • Production's ~/.grok/auth.json was unchanged, and production Grok still answered after the second sign-in.
    • One run left sessions, memory-v2 and more in the Trials home, which confirms the wipe before each Trial is needed.
    • Grok's binary is under ~/.grok/downloads, so the Trials home hides it. It has to be bound outside the home. The body now says so.
  3. JacobStephens2 commented on Oct 24, 2026

    @JacobStephens2
    OwnerAuthor

    Closed by #1199, merged into issue-977 by a thirdshift Ticket run with Self-merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agent

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions