@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.
@@ -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
@@ -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
- const base = signal.base_commit ? shortCommit(signal.base_commit) : "the base commit";
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: `The verification gate \`${command}\` did not finish on the base commit ${base} within Bridge's 10-minute limit, so Bridge stopped it before any change was made.`,
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.150",
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": {