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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -806,8 +806,8 @@ untrusted. A job resumes with another maintainer's answer
only once you approve it in the inbox. opencode runs as `opencode serve` on
localhost behind a password made for each turn.

The flake's `runner` package is a `quest` whose Claude Code and opencode (and on
Linux, bubblewrap and socat) are pinned by this repository's lock
The flake's `runner` package pins Claude Code 2.1.305 from its official release
manifest; opencode (and on Linux, bubblewrap and socat) follow this repository's lock
(`nix run github:kixelated/quest#runner -- runner`);
otherwise `claude` and `opencode` come from `QUEST_RUNNER_CLAUDE` and
`QUEST_RUNNER_OPENCODE`, or `PATH`. State lives in `$QUEST_RUNNER_HOME`, by default
Expand Down
9 changes: 7 additions & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,20 @@
config.allowUnfreePredicate = pkg: nixpkgs.lib.getName pkg == "claude-code";
};
quest = pkgs.callPackage ./nix/package.nix { };
# `quest runner` with the agent CLIs it drives pinned by this flake's lock, and on
# https://downloads.claude.ai/claude-code-releases/2.1.305/manifest.zst.json
# Keep the tested runner version independent of nixpkgs.
claudeCode = pkgs.claude-code.override {
manifest = pkgs.lib.importJSON ./nix/claude-code.json;
};
# `quest runner` with pinned agent CLIs, and on
# Linux the bubblewrap and socat Claude Code's sandbox runs its jobs' commands in.
runner = pkgs.symlinkJoin {
name = "quest-runner-${quest.version}";
paths = [ quest ];
nativeBuildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/quest \
--set-default QUEST_RUNNER_CLAUDE ${pkgs.lib.getExe pkgs.claude-code} \
--set-default QUEST_RUNNER_CLAUDE ${pkgs.lib.getExe claudeCode} \
--set-default QUEST_RUNNER_OPENCODE ${pkgs.lib.getExe pkgs.opencode} ${pkgs.lib.optionalString pkgs.stdenv.isLinux "--prefix PATH : ${
pkgs.lib.makeBinPath [
pkgs.bubblewrap
Expand Down
17 changes: 17 additions & 0 deletions nix/claude-code.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "2.1.305",
"platforms": {
"darwin-arm64": {
"binary": "claude.zst",
"checksum": "1dddc458ce8aacc49677b37c97efbba37a1b8f12bb3cbaf26388a47fbda4a6a9"
},
"linux-arm64": {
"binary": "claude.zst",
"checksum": "2823ad5678a72913e8b2f747e4a82fc6b157cb4896e13b8abafc07fbe278446b"
},
"linux-x64": {
"binary": "claude.zst",
"checksum": "45cfa7d4f6244024a3b1f0a1e6806afa254013f8065e8ea9ba937d7d696a26a3"
}
}
}
1 change: 0 additions & 1 deletion quest/m0/kix/sandbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ Shipped in [kixelated/quest#212](https://github.com/kixelated/quest/pull/212)

## Required

- [Claude Code pin](/quest/m0/kix/sandbox/claude-pin.md) - the runner's pinned Claude Code moves to the version the sandbox docs describe
- [Head approval](/quest/m0/kix/sandbox/head-approval.md) - a maintainer approves an exact head, such as one kix pushed, for host runners
- [opencode sandboxing](/quest/m0/kix/sandbox/opencode.md) - opencode jobs' commands run in the same sandbox as Claude Code's
- [macOS sandbox](/quest/m0/kix/sandbox/macos.md) - the boundary verified under Seatbelt, then the answer-approval gate removed
Expand Down
19 changes: 0 additions & 19 deletions quest/m0/kix/sandbox/claude-pin.md

This file was deleted.

2 changes: 2 additions & 0 deletions src/runner/claude.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ export function claudeSettings(sandbox: Sandbox): Record<string, unknown> {
enabled: true,
failIfUnavailable: true,
allowUnsandboxedCommands: false,
// Added in 2.1.305; enabling this lets commands escape filesystem isolation.
allowNestedUserNamespaces: false,
autoAllowBashIfSandboxed: true,
filesystem: {
denyRead: sandbox.deny,
Expand Down
1 change: 1 addition & 0 deletions test/runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,7 @@ describe("quest runner", () => {
enabled: true,
failIfUnavailable: true,
allowUnsandboxedCommands: false,
allowNestedUserNamespaces: false,
filesystem: { allowRead: [checkout, repository, launch.tmp], allowWrite: [launch.tmp] },
// A trusted revision's commands reach the package registries and nothing else.
network: { allowedDomains: REGISTRIES, strictAllowlist: true },
Expand Down
Loading