@miraland-labs/conduit-bridge 0.16.181 → 0.16.184
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/dist/driver.js +11 -2
- package/dist/failure-signal.js +17 -0
- package/package.json +1 -1
package/dist/driver.js
CHANGED
|
@@ -2021,6 +2021,8 @@ export function untrustedCodeEnvironment(scratchHome) {
|
|
|
2021
2021
|
GIT_SSH_COMMAND: "ssh -F /dev/null -o BatchMode=yes -o IdentitiesOnly=yes -o IdentityAgent=none -i /dev/null",
|
|
2022
2022
|
};
|
|
2023
2023
|
}
|
|
2024
|
+
/** Where a bwrap gate sees its TMPDIR; /tmp is a fresh tmpfs per spawn, so the name never collides. */
|
|
2025
|
+
export const SANDBOX_TEMP = "/tmp/gate";
|
|
2024
2026
|
/** Pure spawn projection; parent mounts precede their writable children. */
|
|
2025
2027
|
export function buildUntrustedCodeSpawn(input, host) {
|
|
2026
2028
|
const direct = { command: input.command, argv: input.argv, cwd: input.cwd, env: input.env };
|
|
@@ -2034,6 +2036,9 @@ export function buildUntrustedCodeSpawn(input, host) {
|
|
|
2034
2036
|
const argv = ["--die-with-parent", "--new-session", "--unshare-net", "--unshare-pid", "--unshare-ipc", "--unshare-uts",
|
|
2035
2037
|
"--ro-bind", "/", "/", "--dev", "/dev", "--proc", "/proc",
|
|
2036
2038
|
...["/tmp", "/run", "/home", "/root"].flatMap((path) => ["--tmpfs", path]),
|
|
2039
|
+
// Before every path bind: a nested sandbox's cwd and home live under /tmp/gate, and a later
|
|
2040
|
+
// mount here would shadow them (CR17g, 2026-10-22: 8 of Conduit's own gate tests inside a gate).
|
|
2041
|
+
...(host.tempMount ? ["--bind", host.tempMount.source, host.tempMount.target] : []),
|
|
2037
2042
|
...(host.sourceRepository ? ["--ro-bind", host.sourceRepository, host.sourceRepository] : []),
|
|
2038
2043
|
...(host.toolchainRead ?? []).flatMap((path) => ["--ro-bind", path, path]),
|
|
2039
2044
|
...(rootWorkspace ? ["--bind", input.cwd, input.cwd] : []),
|
|
@@ -2202,8 +2207,12 @@ export async function untrustedCodeSpawn(input) {
|
|
|
2202
2207
|
const home = await realpath(input.env.HOME);
|
|
2203
2208
|
const temp = join(home, "tmp");
|
|
2204
2209
|
await mkdir(temp, { recursive: true });
|
|
2210
|
+
// CR17f (2026-10-22): under an attempt worktree this temp is ~150 bytes deep, past the 108-byte
|
|
2211
|
+
// Unix socket limit, and a listen there fails or collides. bwrap shows it at a short path instead.
|
|
2212
|
+
const tempMount = sandbox.os_sandbox === "bwrap" ? { source: temp, target: SANDBOX_TEMP } : undefined;
|
|
2213
|
+
const visibleTemp = tempMount?.target ?? temp;
|
|
2205
2214
|
const env = { ...input.env, PATH: (await sandboxPathDirectories(input.env)).join(delimiter), HOME: home, XDG_CONFIG_HOME: join(home, "config"),
|
|
2206
|
-
XDG_CACHE_HOME: join(home, "cache"), XDG_DATA_HOME: join(home, "data"), TMPDIR:
|
|
2215
|
+
XDG_CACHE_HOME: join(home, "cache"), XDG_DATA_HOME: join(home, "data"), TMPDIR: visibleTemp, TMP: visibleTemp, TEMP: visibleTemp };
|
|
2207
2216
|
const writable = [cwd, home, temp];
|
|
2208
2217
|
for (const key of ["CARGO_TARGET_DIR", "CARGO_HOME"]) {
|
|
2209
2218
|
const path = input.env[key];
|
|
@@ -2218,7 +2227,7 @@ export async function untrustedCodeSpawn(input) {
|
|
|
2218
2227
|
toolchainRead.push(await realpath(input.env.RUSTUP_HOME));
|
|
2219
2228
|
const repository = await sandboxRepositoryPaths(cwd);
|
|
2220
2229
|
return buildUntrustedCodeSpawn({ ...input, command, cwd, env, writable }, {
|
|
2221
|
-
...sandbox, home: await realpath(homedir()), toolchainRead, ...repository, ephemeral: await sandboxNodeScratch(cwd, repository.sourceRepository),
|
|
2230
|
+
...sandbox, home: await realpath(homedir()), toolchainRead, ...repository, ephemeral: await sandboxNodeScratch(cwd, repository.sourceRepository), tempMount,
|
|
2222
2231
|
});
|
|
2223
2232
|
}
|
|
2224
2233
|
const sandboxExecFile = promisify(execFile);
|
package/dist/failure-signal.js
CHANGED
|
@@ -372,6 +372,20 @@ export const VERIFICATION_FAILS_ON_BASE = "verification fails on the base commit
|
|
|
372
372
|
* red commit.
|
|
373
373
|
*/
|
|
374
374
|
export const WORKSPACE_DEPENDENCIES_MISSING_PATTERN = /(?:^|\n)\s*(?:\/(?:usr\/)?bin\/)?(?:ba|z|da)?sh:\s*(?:(?:\d+:\s*)?[^:\n]{1,120}:\s*(?:command\s+)?not found|command not found:\s*[^\n]+)\s*(?=\n|$)|(?:^|\n)\s*'[^'\n]+' is not recognized as an internal or external command/im;
|
|
375
|
+
/** A write the toolchain needs that the computer refused before any test ran: the sandbox or disk, not the base commit. */
|
|
376
|
+
export const WORKSPACE_WRITE_REFUSED_PATTERN = /\b(?:EROFS|ENOSPC)\b|read-only file system|no space left on device/i;
|
|
377
|
+
/** CR17e (2026-10-22): vitest could not write its config bundle under the sandboxed install; Bridge held the owner for its own mount. */
|
|
378
|
+
export function workspaceWriteRefusedFailure(detail) {
|
|
379
|
+
return {
|
|
380
|
+
code: "workspace_write_refused",
|
|
381
|
+
class: "environment",
|
|
382
|
+
disposition: "hold",
|
|
383
|
+
responsible_party: "conduit",
|
|
384
|
+
message: "The gate could not start: this computer refused a write the project's toolchain needs.",
|
|
385
|
+
next_action: "Nothing to repair in the base commit — no test ran. Update Bridge on this computer (or free its disk), then press Try again.",
|
|
386
|
+
diagnostic_detail: detail,
|
|
387
|
+
};
|
|
388
|
+
}
|
|
375
389
|
/** The one envelope for a gate whose tool is absent from the checkout, wherever it was noticed. */
|
|
376
390
|
export function workspaceDependenciesMissingFailure(detail) {
|
|
377
391
|
return {
|
|
@@ -602,6 +616,9 @@ export function classifyFailureSignal(signal) {
|
|
|
602
616
|
if (signal.exit_code === 127 || WORKSPACE_DEPENDENCIES_MISSING_PATTERN.test(output)) {
|
|
603
617
|
return workspaceDependenciesMissingFailure([`$ ${command}`, `exit ${signal.exit_code ?? "unknown"}`, output].filter(Boolean).join("\n"));
|
|
604
618
|
}
|
|
619
|
+
if (WORKSPACE_WRITE_REFUSED_PATTERN.test(output)) {
|
|
620
|
+
return workspaceWriteRefusedFailure([`$ ${command}`, `exit ${signal.exit_code ?? "unknown"}`, output].filter(Boolean).join("\n"));
|
|
621
|
+
}
|
|
605
622
|
return {
|
|
606
623
|
code: "verification_red_base",
|
|
607
624
|
class: "contract",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miraland-labs/conduit-bridge",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.184",
|
|
4
4
|
"description": "Conduit Bridge CLI — join, connect, disconnect, multi-driver lanes, and run Claude Code / Codex / Cursor / OpenCode / Pi / Kiro / Antigravity / Grok Build agents for a Conduit organization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|