@miraland-labs/conduit-bridge 0.16.205 → 0.16.208
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 +25 -3
- package/dist/ensure-test-evidence.js +20 -3
- package/dist/investigation.js +5 -1
- package/dist/probe-run.js +7 -1
- package/package.json +1 -1
package/dist/driver.js
CHANGED
|
@@ -728,6 +728,25 @@ export function claudeCodeFuelEnv(fuelSource, model) {
|
|
|
728
728
|
return undefined;
|
|
729
729
|
return { ANTHROPIC_MODEL: model, ANTHROPIC_SMALL_FAST_MODEL: model, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1" };
|
|
730
730
|
}
|
|
731
|
+
export function codexSandboxFacts(projection) {
|
|
732
|
+
return [
|
|
733
|
+
"SANDBOX FACTS",
|
|
734
|
+
`Sandbox mode: ${projection.sandbox}.`,
|
|
735
|
+
projection.networkAccess
|
|
736
|
+
? "Network is on."
|
|
737
|
+
: "Network is off, including loopback listen.",
|
|
738
|
+
projection.sandbox === "workspace-write"
|
|
739
|
+
? "Writes are allowed only in the workspace and TMPDIR. HOME and the rest of the filesystem are read-only."
|
|
740
|
+
: "No writes are allowed. The filesystem is read-only.",
|
|
741
|
+
"Child processes inherit these limits.",
|
|
742
|
+
"A registered gate that fails only with EPERM, EROFS, or a refused listen does not test the change.",
|
|
743
|
+
"Record that run as evidence with the refused calls.",
|
|
744
|
+
"Mark each criterion that run would settle as unknown with unverified_reason needs_environment.",
|
|
745
|
+
"Set unverified_detail to name the refusal.",
|
|
746
|
+
"Do not state in outcome, verification, or limitations that the gate failed.",
|
|
747
|
+
"Bridge runs every registered gate outside this sandbox after the turn. Its result is the witness.",
|
|
748
|
+
].join("\n");
|
|
749
|
+
}
|
|
731
750
|
/**
|
|
732
751
|
* Codex exec arguments. The sandbox is the enforcement boundary: network stays
|
|
733
752
|
* off inside workspace-write unless the class/capabilities require it.
|
|
@@ -848,7 +867,7 @@ export const codexDriver = {
|
|
|
848
867
|
diagnosis: input.workRole === "diagnose",
|
|
849
868
|
});
|
|
850
869
|
// Prompt via stdin avoids ARG_MAX limits on large assignment contracts.
|
|
851
|
-
const { code, stdout, stderr } = await execute(driverExecutable(codexDriver.name, input.executable), codexExecArgs({ ...input, networkAccess: projected.networkAccess }, projected.sandbox), input.workspace, agentTurnTimeoutMs(input), fuelSource === "conduit" ? input.fuel : undefined, fuelSource, input.prompt
|
|
870
|
+
const { code, stdout, stderr } = await execute(driverExecutable(codexDriver.name, input.executable), codexExecArgs({ ...input, networkAccess: projected.networkAccess }, projected.sandbox), input.workspace, agentTurnTimeoutMs(input), fuelSource === "conduit" ? input.fuel : undefined, fuelSource, `${input.prompt}\n\n${codexSandboxFacts(projected)}`, input.signal);
|
|
852
871
|
const parsed = parseCodexJsonl(stdout);
|
|
853
872
|
const resultText = parsed.resultText ?? (stdout || null);
|
|
854
873
|
if (code !== 0) {
|
|
@@ -1389,11 +1408,14 @@ export function parseAntigravityModelList(stdout) {
|
|
|
1389
1408
|
export function parseAntigravityOutput(stdout) {
|
|
1390
1409
|
try {
|
|
1391
1410
|
const parsed = JSON.parse(stdout.trim());
|
|
1411
|
+
const earlyEnd = typeof parsed.finished_reason === "string"
|
|
1412
|
+
&& ["print_timeout", "interrupted", "error"].includes(parsed.finished_reason);
|
|
1392
1413
|
return {
|
|
1393
1414
|
resultText: typeof parsed.response === "string" ? parsed.response : null,
|
|
1394
1415
|
sessionId: typeof parsed.conversation_id === "string" ? parsed.conversation_id : null,
|
|
1395
|
-
status: typeof parsed.status === "string" ? parsed.status : null,
|
|
1396
|
-
error: typeof parsed.error === "string" && parsed.error.trim() ? parsed.error
|
|
1416
|
+
status: earlyEnd ? "ERROR" : typeof parsed.status === "string" ? parsed.status : null,
|
|
1417
|
+
error: typeof parsed.error === "string" && parsed.error.trim() ? parsed.error
|
|
1418
|
+
: earlyEnd ? `agy ended early: ${parsed.finished_reason}` : null,
|
|
1397
1419
|
};
|
|
1398
1420
|
}
|
|
1399
1421
|
catch {
|
|
@@ -572,6 +572,11 @@ async function missingNpmLockReason(directory) {
|
|
|
572
572
|
return "pnpm-lock.yaml is not an npm install";
|
|
573
573
|
return "no package-lock.json or npm-shrinkwrap.json";
|
|
574
574
|
}
|
|
575
|
+
/** Lock-pinned crates and npm packages, fetched outside the sandbox before a gate runs inside it. */
|
|
576
|
+
export async function prepareVerificationDependencies(workspace) {
|
|
577
|
+
await fetchLockedDependencies(workspace);
|
|
578
|
+
await installLockedPackages(workspace);
|
|
579
|
+
}
|
|
575
580
|
export async function installLockedPackages(workspace, options = {}) {
|
|
576
581
|
const installed = [];
|
|
577
582
|
const skipped = [];
|
|
@@ -612,7 +617,19 @@ export async function installLockedPackages(workspace, options = {}) {
|
|
|
612
617
|
* `output` is stdout and stderr together, in the order the lines arrived: a failure detail reads its
|
|
613
618
|
* tail from it.
|
|
614
619
|
*/
|
|
615
|
-
export
|
|
620
|
+
export function runBoundedVerificationCommand(command, workspace, timeoutMs = VERIFICATION_TIMEOUT_MS) {
|
|
621
|
+
return runVerificationCommand(command, workspace, timeoutMs, true);
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* The same run without the dependency preparation, for a caller that is itself inside the sandbox
|
|
625
|
+
* (the delivered probe instrument). It has no network, so its own install would fail and leave a
|
|
626
|
+
* partial `node_modules` that hides the complete one. Bridge prepares that workspace before it
|
|
627
|
+
* starts the caller (CR31).
|
|
628
|
+
*/
|
|
629
|
+
export function runPreparedVerificationCommand(command, workspace, timeoutMs = VERIFICATION_TIMEOUT_MS) {
|
|
630
|
+
return runVerificationCommand(command, workspace, timeoutMs, false);
|
|
631
|
+
}
|
|
632
|
+
async function runVerificationCommand(command, workspace, timeoutMs, prepare) {
|
|
616
633
|
const argv = argvForBoundedCommand(command);
|
|
617
634
|
const bin = argv[0];
|
|
618
635
|
if (!bin)
|
|
@@ -670,8 +687,8 @@ export async function runBoundedVerificationCommand(command, workspace, timeoutM
|
|
|
670
687
|
partial[stream].append(parts.at(-1));
|
|
671
688
|
};
|
|
672
689
|
const output = () => [lines.text().replace(/\n$/, ""), partial.stdout.text(), partial.stderr.text()].filter(Boolean).join("\n");
|
|
673
|
-
|
|
674
|
-
|
|
690
|
+
if (prepare)
|
|
691
|
+
await prepareVerificationDependencies(workspace);
|
|
675
692
|
const tempRoot = untrustedCodeTempRoot(workspace);
|
|
676
693
|
await mkdir(tempRoot, { recursive: true });
|
|
677
694
|
const scratchHome = await mkdtemp(join(tempRoot, "gate-home-"));
|
package/dist/investigation.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { redactSecrets, redactSecretsDeep } from "./secret-redaction.js";
|
|
9
9
|
import { z } from "zod";
|
|
10
|
-
import { boundedTail, runBoundedVerificationCommand, VERIFICATION_TIMEOUT_MS } from "./ensure-test-evidence.js";
|
|
10
|
+
import { boundedTail, prepareVerificationDependencies, runBoundedVerificationCommand, VERIFICATION_TIMEOUT_MS } from "./ensure-test-evidence.js";
|
|
11
11
|
import { markAttemptActive } from "./preflight.js";
|
|
12
12
|
import { createAttemptWorktree, removeAttemptWorktree } from "./attempt-worktree.js";
|
|
13
13
|
import { buildWorkspaceBrief, ensureCommitAvailable, normalizeRepositoryUrl } from "./brief.js";
|
|
@@ -690,6 +690,10 @@ async function execDeliveredProbeRun(argv, stdin, workspace, timeoutMs) {
|
|
|
690
690
|
}
|
|
691
691
|
}
|
|
692
692
|
export async function runDeliveredProbeInstrument(input) {
|
|
693
|
+
// The delivered instrument runs inside the sandbox and cannot install; its registered commands
|
|
694
|
+
// read what Bridge installs here, outside it (CR31).
|
|
695
|
+
if (input.probes.some((probe) => probe.test?.trim()))
|
|
696
|
+
await (input.prepare ?? prepareVerificationDependencies)(input.workspace);
|
|
693
697
|
const entry = join(input.workspace, PROBE_RUN_ENTRY);
|
|
694
698
|
const timeoutMs = deliveredProbeTimeoutMs(input.probes);
|
|
695
699
|
const stdin = JSON.stringify({ probes: input.probes });
|
package/dist/probe-run.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Delivered probe instrument entry. `{ "probes": [...] }` on stdin, `{ witnesses }` on stdout. */
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { runPreparedVerificationCommand } from "./ensure-test-evidence.js";
|
|
3
4
|
import { runDeliveryVerificationProbes } from "./investigation.js";
|
|
4
5
|
const probeRunInputSchema = z.object({
|
|
5
6
|
probes: z.array(z.object({
|
|
@@ -19,7 +20,12 @@ async function readStdin() {
|
|
|
19
20
|
}
|
|
20
21
|
try {
|
|
21
22
|
const parsed = probeRunInputSchema.parse(JSON.parse(await readStdin()));
|
|
22
|
-
|
|
23
|
+
// This process is inside the sandbox; Bridge prepared the workspace's dependencies before it started.
|
|
24
|
+
const witnesses = await runDeliveryVerificationProbes({
|
|
25
|
+
workspace: process.cwd(),
|
|
26
|
+
probes: parsed.probes,
|
|
27
|
+
runCommand: (command, workspace) => runPreparedVerificationCommand(command, workspace),
|
|
28
|
+
});
|
|
23
29
|
process.stdout.write(`${JSON.stringify({ witnesses })}\n`);
|
|
24
30
|
}
|
|
25
31
|
catch (error) {
|
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.208",
|
|
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": {
|