@miraland-labs/conduit-bridge 0.16.150 → 0.16.151
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/ensure-test-evidence.js +24 -0
- package/dist/execution.js +19 -1
- package/dist/failure-signal.js +9 -3
- package/package.json +1 -1
|
@@ -569,6 +569,23 @@ export class VerificationGateRanNothingError extends Error {
|
|
|
569
569
|
this.vendorMessage = vendorMessage;
|
|
570
570
|
}
|
|
571
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* A declared gate the verification timeout stopped after the agent run: it never exited, so it says
|
|
574
|
+
* nothing about the change. Carries the command and the output tails the timeout signal needs — the
|
|
575
|
+
* classifier holds this on the computer operator and never diagnoses or repairs it.
|
|
576
|
+
*/
|
|
577
|
+
export class VerificationGateTimedOutError extends Error {
|
|
578
|
+
command;
|
|
579
|
+
stdout;
|
|
580
|
+
stderr;
|
|
581
|
+
constructor(command, stdout, stderr, detail) {
|
|
582
|
+
super(`Agent report: Verification gate did not finish (${command}): ${detail}`);
|
|
583
|
+
this.name = "VerificationGateTimedOutError";
|
|
584
|
+
this.command = command;
|
|
585
|
+
this.stdout = stdout;
|
|
586
|
+
this.stderr = stderr;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
572
589
|
/**
|
|
573
590
|
* If test evidence is required, run the bounded verification commands in the attempt workspace
|
|
574
591
|
* and attach verbatim stdout/stderr with Bridge witness markers.
|
|
@@ -593,6 +610,13 @@ export async function ensureTestEvidence(input) {
|
|
|
593
610
|
const result = await run(command, input.workspace);
|
|
594
611
|
const stdoutLines = result.stdout.trim() ? result.stdout.trim().split("\n") : [];
|
|
595
612
|
const stderrLines = result.stderr.trim() ? result.stderr.trim().split("\n") : [];
|
|
613
|
+
// First, as in the dry run: a gate the timeout stopped never exited, so its partial output and
|
|
614
|
+
// exit code say nothing about the change. Read as a failed test, it sent a slow computer's
|
|
615
|
+
// timeout to diagnosis and repair (2026-10-10).
|
|
616
|
+
if (result.timedOut) {
|
|
617
|
+
const detail = boundedFailureDetail(command, outputLines(result), result.code);
|
|
618
|
+
throw new VerificationGateTimedOutError(command, result.stdout, result.stderr, detail);
|
|
619
|
+
}
|
|
596
620
|
// Checked ahead of both the exit-code and the pass path: `go test` on an empty package exits 0
|
|
597
621
|
// and would otherwise be witnessed as a passing test run that tested nothing.
|
|
598
622
|
const ranNothing = detectGateRanNothing(command, result.stdout, result.stderr, result.code);
|
package/dist/execution.js
CHANGED
|
@@ -28,7 +28,7 @@ import { checkpointWorkInProgress, ensureLandCommit } from "./ensure-land-commit
|
|
|
28
28
|
import { AGENT_NO_LAND_COMMIT_PREFIX, AgentNoLandCommitError, agentNoLandCommitMessage, requiresLandCommit } from "./land-contract.js";
|
|
29
29
|
import { agentClaimsRepositoryWork, claimsVsGitMismatch, isLandTreeEmpty, reportClaimsRepositoryWork, } from "./land-git-reality.js";
|
|
30
30
|
const execFileAsync = promisify(execFile);
|
|
31
|
-
import { boundedTail, captureVerificationFailure, DeliveryReportDefectError, detectGateRanNothing, ensureTestEvidence, needsTestEvidence, runBoundedVerificationCommand, verificationEvidenceCommands, VerificationFailedError, VerificationGateRanNothingError, VERIFICATION_TIMEOUT_MS } from "./ensure-test-evidence.js";
|
|
31
|
+
import { boundedTail, captureVerificationFailure, DeliveryReportDefectError, detectGateRanNothing, ensureTestEvidence, needsTestEvidence, runBoundedVerificationCommand, verificationEvidenceCommands, VerificationFailedError, VerificationGateRanNothingError, VerificationGateTimedOutError, VERIFICATION_TIMEOUT_MS } from "./ensure-test-evidence.js";
|
|
32
32
|
import { ensureChangeEvidence } from "./ensure-change-evidence.js";
|
|
33
33
|
import { ensureDemonstrationEvidence } from "./ensure-demonstration-evidence.js";
|
|
34
34
|
import { ensureNormativeEvidence } from "./ensure-normative-evidence.js";
|
|
@@ -2252,6 +2252,24 @@ async function runAttempt(client, config, driver, workspace, brief, taskId, watc
|
|
|
2252
2252
|
validateDeliveryReport(report, spec, grants, actualPaths ?? undefined, deliveryBaseCommit);
|
|
2253
2253
|
}
|
|
2254
2254
|
catch (error) {
|
|
2255
|
+
// A gate the timeout stopped never exited, so nothing says the change is at fault: the same
|
|
2256
|
+
// timeout signal the dry run emits, held on the computer operator — never a diagnosis or a
|
|
2257
|
+
// repair brief. Task ce673ef1 (2026-10-10) ran two diagnoses on a CPU-starved `npm run test`.
|
|
2258
|
+
if (error instanceof VerificationGateTimedOutError) {
|
|
2259
|
+
const response = await queueTerminal(client, taskId, {
|
|
2260
|
+
action: "fail",
|
|
2261
|
+
body: {
|
|
2262
|
+
error: error.message,
|
|
2263
|
+
retryable: false,
|
|
2264
|
+
signal: verificationGateTimeoutSignal({ command: error.command, stderr: error.stderr, stdout: error.stdout }),
|
|
2265
|
+
...(report.pull_request_url ? { pull_request_url: report.pull_request_url } : {}),
|
|
2266
|
+
idempotency_key: `bridge:verification-gate-timeout:${active.attemptId}`,
|
|
2267
|
+
},
|
|
2268
|
+
});
|
|
2269
|
+
retainAttemptWorktree = response.retain_worktree === true;
|
|
2270
|
+
console.error(`Assignment ${taskId} verification gate did not finish: ${redactSecrets(error.message)}`);
|
|
2271
|
+
return;
|
|
2272
|
+
}
|
|
2255
2273
|
// A gate that ran no tests is a misconfigured gate, not a failed verification: the delivery
|
|
2256
2274
|
// pack may be entirely correct. Emit the T1 typed signal and Hold on the computer operator —
|
|
2257
2275
|
// never a repair attempt or a blind retry, which is what burned six deliveries on 2026-09-04
|
package/dist/failure-signal.js
CHANGED
|
@@ -403,6 +403,9 @@ export function verificationRedBaseSignal(input) {
|
|
|
403
403
|
* The signal Bridge emits when the verification timeout stops a gate on the base commit, before the
|
|
404
404
|
* agent starts. The gate never exited, so it says nothing about the base: read as exit 1, a gate
|
|
405
405
|
* that hung (waiting for input or the network, or on a slow computer) was a red base on the author.
|
|
406
|
+
*
|
|
407
|
+
* The delivery gate after the agent run emits it without a base commit: the gate ran on the change,
|
|
408
|
+
* and a gate that never exited says nothing about the change either.
|
|
406
409
|
*/
|
|
407
410
|
export function verificationGateTimeoutSignal(input) {
|
|
408
411
|
return {
|
|
@@ -410,7 +413,7 @@ export function verificationGateTimeoutSignal(input) {
|
|
|
410
413
|
witness: "bridge",
|
|
411
414
|
kind: "timeout",
|
|
412
415
|
command: input.command,
|
|
413
|
-
base_commit: input.baseCommit,
|
|
416
|
+
...(input.baseCommit ? { base_commit: input.baseCommit } : {}),
|
|
414
417
|
exit_code: null,
|
|
415
418
|
...(input.stderr?.trim() ? { stderr_tail: bounded2k(input.stderr) } : {}),
|
|
416
419
|
...(input.stdout?.trim() ? { stdout_tail: bounded2k(input.stdout) } : {}),
|
|
@@ -562,13 +565,16 @@ export function classifyFailureSignal(signal) {
|
|
|
562
565
|
// base commit nor a change is known to be at fault. The generic rule read it as a failed test.
|
|
563
566
|
if (signal.phase === "verification" && signal.kind === "timeout") {
|
|
564
567
|
const command = signal.command ?? "the declared gate";
|
|
565
|
-
|
|
568
|
+
// No base commit: the delivery gate after the agent run, on the agent's change.
|
|
569
|
+
const message = signal.base_commit
|
|
570
|
+
? `The verification gate \`${command}\` did not finish on the base commit ${shortCommit(signal.base_commit)} within Bridge's 10-minute limit, so Bridge stopped it before any change was made.`
|
|
571
|
+
: `The verification gate \`${command}\` did not finish on the agent's change within Bridge's 10-minute limit, so Bridge stopped it before delivery.`;
|
|
566
572
|
return {
|
|
567
573
|
code: "verification_gate_timeout",
|
|
568
574
|
class: "environment",
|
|
569
575
|
disposition: "hold",
|
|
570
576
|
responsible_party: "computer_operator",
|
|
571
|
-
message
|
|
577
|
+
message,
|
|
572
578
|
next_action: `Run \`${command}\` on this computer and find where it hangs — a test that waits for input or the network, or a computer too slow for the gate — then fix it and Recheck. Conduit does not retry or repair a gate that does not finish.`,
|
|
573
579
|
diagnostic_detail: [`$ ${command}`, "stopped after 10 minutes", signal.stderr_tail, signal.stdout_tail].filter(Boolean).join("\n"),
|
|
574
580
|
};
|
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.151",
|
|
4
4
|
"description": "Conduit Bridge CLI \u2014 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": {
|