@miraland-labs/conduit-bridge 0.16.150 → 0.16.152
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 +23 -2
- 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";
|
|
@@ -524,7 +524,10 @@ export function buildDiagnosticPrompt(input) {
|
|
|
524
524
|
...(acceptance.length ? ["", `APPROVED ACCEPTANCE CRITERIA\n${acceptance.map((item) => `- ${item}`).join("\n")}`] : []),
|
|
525
525
|
...(changeScope.length ? ["", `APPROVED CHANGE SCOPE\n${changeScope.map((item) => `- ${item}`).join("\n")}`] : []),
|
|
526
526
|
...(decisions.length ? ["", `OWNER DECISIONS\n${decisions.map((item) => `- ${item.question}: ${item.decision}`).join("\n")}`] : []),
|
|
527
|
-
|
|
527
|
+
// The next authoring agent's shell accepts these commands and git, nothing else. A brief that
|
|
528
|
+
// prescribes another command (SV1b: `cargo run … > openapi.json`) sends that run into the same failure.
|
|
529
|
+
...(input.verificationCommands.length ? ["", `BOUNDED VERIFICATION COMMANDS\n${input.verificationCommands.map((item) => `- ${item}`).join("\n")}`,
|
|
530
|
+
"The next authoring agent can edit files, but its shell accepts only these commands and git. fix_direction must not tell it to run any other command."] : []),
|
|
528
531
|
...(gate ? ["", `GATE — Bridge re-runs \`${gate}\` after the next run; the agent cannot change or replace it.`
|
|
529
532
|
+ " A fix that needs a file outside the APPROVED CHANGE SCOPE is still a grounded diagnosis."
|
|
530
533
|
+ " Answer confident:true and write the full repository path of each such file in fix_direction. Conductor makes it a scope decision."
|
|
@@ -2252,6 +2255,24 @@ async function runAttempt(client, config, driver, workspace, brief, taskId, watc
|
|
|
2252
2255
|
validateDeliveryReport(report, spec, grants, actualPaths ?? undefined, deliveryBaseCommit);
|
|
2253
2256
|
}
|
|
2254
2257
|
catch (error) {
|
|
2258
|
+
// A gate the timeout stopped never exited, so nothing says the change is at fault: the same
|
|
2259
|
+
// timeout signal the dry run emits, held on the computer operator — never a diagnosis or a
|
|
2260
|
+
// repair brief. Task ce673ef1 (2026-10-10) ran two diagnoses on a CPU-starved `npm run test`.
|
|
2261
|
+
if (error instanceof VerificationGateTimedOutError) {
|
|
2262
|
+
const response = await queueTerminal(client, taskId, {
|
|
2263
|
+
action: "fail",
|
|
2264
|
+
body: {
|
|
2265
|
+
error: error.message,
|
|
2266
|
+
retryable: false,
|
|
2267
|
+
signal: verificationGateTimeoutSignal({ command: error.command, stderr: error.stderr, stdout: error.stdout }),
|
|
2268
|
+
...(report.pull_request_url ? { pull_request_url: report.pull_request_url } : {}),
|
|
2269
|
+
idempotency_key: `bridge:verification-gate-timeout:${active.attemptId}`,
|
|
2270
|
+
},
|
|
2271
|
+
});
|
|
2272
|
+
retainAttemptWorktree = response.retain_worktree === true;
|
|
2273
|
+
console.error(`Assignment ${taskId} verification gate did not finish: ${redactSecrets(error.message)}`);
|
|
2274
|
+
return;
|
|
2275
|
+
}
|
|
2255
2276
|
// A gate that ran no tests is a misconfigured gate, not a failed verification: the delivery
|
|
2256
2277
|
// pack may be entirely correct. Emit the T1 typed signal and Hold on the computer operator —
|
|
2257
2278
|
// 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.152",
|
|
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": {
|