@miraland-labs/conduit-bridge 0.16.135 → 0.16.138
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 +14 -2
- package/dist/execution.js +25 -13
- package/dist/work-package-schema.js +2 -0
- package/package.json +1 -1
|
@@ -210,7 +210,7 @@ export async function captureVerificationFailure(input) {
|
|
|
210
210
|
// shown to be the same bug.
|
|
211
211
|
const text = boundedFailureDetail(command, result.stdout.trim() ? result.stdout.trim().split("\n") : [], result.stderr.trim() ? result.stderr.trim().split("\n") : [], result.code, DIAGNOSIS_DETAIL_MAX_CHARS);
|
|
212
212
|
if (text.trim())
|
|
213
|
-
return text;
|
|
213
|
+
return { command, detail: text };
|
|
214
214
|
}
|
|
215
215
|
// Every bounded command passed (or none could start): agent failed for another reason.
|
|
216
216
|
return null;
|
|
@@ -456,6 +456,18 @@ export function detectGateRanNothing(command, stdout, stderr, code) {
|
|
|
456
456
|
}
|
|
457
457
|
return null;
|
|
458
458
|
}
|
|
459
|
+
/**
|
|
460
|
+
* A declared gate that ran and failed. Carries the command as a field so the verification signal
|
|
461
|
+
* can name the gate without reading it back out of this error's text.
|
|
462
|
+
*/
|
|
463
|
+
export class VerificationFailedError extends Error {
|
|
464
|
+
command;
|
|
465
|
+
constructor(command, detail) {
|
|
466
|
+
super(`Agent report: Verification failed (${command}): ${detail}`);
|
|
467
|
+
this.name = "VerificationFailedError";
|
|
468
|
+
this.command = command;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
459
471
|
/**
|
|
460
472
|
* A declared gate that ran no tests, or that only printed its own usage text: a misconfigured gate,
|
|
461
473
|
* not a failed one. Carries the typed fields `execution.ts` needs to emit the T1 signal — the
|
|
@@ -520,7 +532,7 @@ export async function ensureTestEvidence(input) {
|
|
|
520
532
|
elided: detail.includes("omitted"),
|
|
521
533
|
ends_with_exit: detail.trimEnd().endsWith(`exit ${result.code}`),
|
|
522
534
|
}));
|
|
523
|
-
throw new
|
|
535
|
+
throw new VerificationFailedError(command, detail);
|
|
524
536
|
}
|
|
525
537
|
// Empty exit-0 is not proof — a no-op recipe (`@true`) must not clear required_evidence: test.
|
|
526
538
|
if (stdoutLines.length === 0 && stderrLines.length === 0) {
|
package/dist/execution.js
CHANGED
|
@@ -26,7 +26,7 @@ import { ensureLandCommit } from "./ensure-land-commit.js";
|
|
|
26
26
|
import { AGENT_NO_LAND_COMMIT_PREFIX, AgentNoLandCommitError, agentNoLandCommitMessage, requiresLandCommit } from "./land-contract.js";
|
|
27
27
|
import { agentClaimsRepositoryWork, claimsVsGitMismatch, isLandTreeEmpty, reportClaimsRepositoryWork, } from "./land-git-reality.js";
|
|
28
28
|
const execFileAsync = promisify(execFile);
|
|
29
|
-
import { boundedTail, captureVerificationFailure, detectGateRanNothing, ensureTestEvidence, needsTestEvidence, runBoundedVerificationCommand, verificationEvidenceCommands, VerificationGateRanNothingError } from "./ensure-test-evidence.js";
|
|
29
|
+
import { boundedTail, captureVerificationFailure, detectGateRanNothing, ensureTestEvidence, needsTestEvidence, runBoundedVerificationCommand, verificationEvidenceCommands, VerificationFailedError, VerificationGateRanNothingError } from "./ensure-test-evidence.js";
|
|
30
30
|
import { ensureChangeEvidence } from "./ensure-change-evidence.js";
|
|
31
31
|
import { ensureDemonstrationEvidence } from "./ensure-demonstration-evidence.js";
|
|
32
32
|
import { ensureNormativeEvidence } from "./ensure-normative-evidence.js";
|
|
@@ -471,11 +471,6 @@ export function parseDiagnosticRepairBrief(text) {
|
|
|
471
471
|
}
|
|
472
472
|
return parsed.data;
|
|
473
473
|
}
|
|
474
|
-
/**
|
|
475
|
-
* The gate command inside the witness line Bridge itself wrote. Mirrored as
|
|
476
|
-
* VERIFICATION_GATE_PATTERN in src/conductor/repair.ts.
|
|
477
|
-
*/
|
|
478
|
-
const VERIFICATION_GATE_PATTERN = /Verification failed \(([^)]+)\)/;
|
|
479
474
|
/** Prompt for Option C: IDE-depth understanding in the retained tree, with write authority absent. */
|
|
480
475
|
export function buildDiagnosticPrompt(input) {
|
|
481
476
|
const pkg = input.workPackage;
|
|
@@ -488,7 +483,7 @@ export function buildDiagnosticPrompt(input) {
|
|
|
488
483
|
// Bridge re-runs the gate itself after the next authoring run. Without this rule the diagnosis
|
|
489
484
|
// reads the gate as the agent's own command and briefs the agent to run a different one, which
|
|
490
485
|
// cannot change what Bridge runs: the briefed run then fails on identical output.
|
|
491
|
-
const gate =
|
|
486
|
+
const gate = input.gateCommand;
|
|
492
487
|
return [
|
|
493
488
|
"You are Conductor's read-only diagnosis lane. Diagnose the exact failed authoring run in the current retained worktree.",
|
|
494
489
|
"Inspect the actual code, git diff, nearby callers, and relevant tests. Run only the supplied project verification commands when useful.",
|
|
@@ -1413,6 +1408,7 @@ async function runAttempt(client, config, driver, workspace, brief, taskId, watc
|
|
|
1413
1408
|
spec,
|
|
1414
1409
|
workPackage,
|
|
1415
1410
|
failureOutput: diagnosticFailure,
|
|
1411
|
+
gateCommand: workPackage.diagnostic_context?.gate_command ?? null,
|
|
1416
1412
|
verificationCommands: attemptBrief?.verification ?? [],
|
|
1417
1413
|
})
|
|
1418
1414
|
: buildAssignmentPrompt({
|
|
@@ -1484,7 +1480,7 @@ async function runAttempt(client, config, driver, workspace, brief, taskId, watc
|
|
|
1484
1480
|
// gate that moved instead of showing two hex strings.
|
|
1485
1481
|
await client.updateAttempt(taskId, { executionFacts, verificationCommands });
|
|
1486
1482
|
await client.attemptRequest(taskId, "progress", {
|
|
1487
|
-
phase: diagnosis ? "inspecting" : "
|
|
1483
|
+
phase: diagnosis ? "inspecting" : "agent_running",
|
|
1488
1484
|
execution_facts: executionFacts,
|
|
1489
1485
|
message: resuming
|
|
1490
1486
|
? `Resuming ${driver.name} after Bridge restart with proven session and worktree.`
|
|
@@ -1728,15 +1724,22 @@ async function runAttempt(client, config, driver, workspace, brief, taskId, watc
|
|
|
1728
1724
|
// transient retry — the one verdict that would run the capped work again at the same price.
|
|
1729
1725
|
const turnCapReached = result.signal?.kind === "turn_cap";
|
|
1730
1726
|
const recoverVerification = grants.includes("test_run") && !subscriptionExhausted(agentMessage) && !turnCapReached;
|
|
1731
|
-
if (recoverVerification)
|
|
1727
|
+
if (recoverVerification) {
|
|
1732
1728
|
watchdog.phase("verification");
|
|
1733
|
-
|
|
1729
|
+
await client.attemptRequest(taskId, "progress", {
|
|
1730
|
+
phase: "verifying",
|
|
1731
|
+
message: "Bridge is running the project's verification commands to read the failure.",
|
|
1732
|
+
idempotency_key: `bridge:progress:${active.attemptId}:verify-failure`,
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
const capturedVerification = recoverVerification
|
|
1734
1736
|
? await captureVerificationFailure({
|
|
1735
1737
|
workspace: attemptWorkspace,
|
|
1736
1738
|
verificationCommands: attemptBrief?.verification ?? [],
|
|
1737
1739
|
acceptance: spec.acceptance ?? [],
|
|
1738
1740
|
})
|
|
1739
1741
|
: null;
|
|
1742
|
+
const verificationDetail = capturedVerification?.detail ?? null;
|
|
1740
1743
|
// The vendor named the model as the cause, so the model is what the retry must change. The
|
|
1741
1744
|
// model rides in the prefix: the control plane cannot read Bridge's selection any other way.
|
|
1742
1745
|
const diffStat = verificationDetail && attemptWorkspace && startCommit
|
|
@@ -1771,8 +1774,8 @@ async function runAttempt(client, config, driver, workspace, brief, taskId, watc
|
|
|
1771
1774
|
: subscriptionExhausted(agentMessage)
|
|
1772
1775
|
? { phase: "agent", witness: "vendor", kind: "quota", vendor_message: agentMessage.slice(0, 2_000) }
|
|
1773
1776
|
: result.signal
|
|
1774
|
-
?
|
|
1775
|
-
? { ...result.signal, phase: "verification", witness: "bridge", stderr_tail: undefined, stdout_tail: undefined, ...(diffStat ? { diff_stat: diffStat } : {}) }
|
|
1777
|
+
? capturedVerification
|
|
1778
|
+
? { ...result.signal, phase: "verification", witness: "bridge", kind: "verification_failed", command: capturedVerification.command, stderr_tail: undefined, stdout_tail: undefined, ...(diffStat ? { diff_stat: diffStat } : {}) }
|
|
1776
1779
|
: result.signal
|
|
1777
1780
|
: undefined;
|
|
1778
1781
|
const response = await queueTerminal(client, taskId, { action: "fail", body: {
|
|
@@ -2144,6 +2147,13 @@ async function runAttempt(client, config, driver, workspace, brief, taskId, watc
|
|
|
2144
2147
|
? await changedPathsSince(attemptWorkspace, deliveryBaseCommit)
|
|
2145
2148
|
: null;
|
|
2146
2149
|
// Mechanical test path: agent often forgets verbatim make test / npm test output.
|
|
2150
|
+
if (grants.includes("test_run")) {
|
|
2151
|
+
await client.attemptRequest(taskId, "progress", {
|
|
2152
|
+
phase: "verifying",
|
|
2153
|
+
message: "Bridge is running the project's verification commands.",
|
|
2154
|
+
idempotency_key: `bridge:progress:${active.attemptId}:verify`,
|
|
2155
|
+
});
|
|
2156
|
+
}
|
|
2147
2157
|
report = await ensureTestEvidence({
|
|
2148
2158
|
workspace: attemptWorkspace,
|
|
2149
2159
|
report,
|
|
@@ -2221,7 +2231,8 @@ async function runAttempt(client, config, driver, workspace, brief, taskId, watc
|
|
|
2221
2231
|
// the same verify-class pre-delivery failure as the driver-failed path above: preserve the
|
|
2222
2232
|
// exact tree and send the witness marker that arms Conductor diagnosis. Treating it as a
|
|
2223
2233
|
// delivery-envelope defect would stop before Invariant 23 ever ran.
|
|
2224
|
-
|
|
2234
|
+
// The command is the field on the throw, never a parse of this message.
|
|
2235
|
+
const verificationFailed = error instanceof VerificationFailedError;
|
|
2225
2236
|
const diffStat = verificationFailed && attemptWorkspace
|
|
2226
2237
|
? await diffStatSince(attemptWorkspace, deliveryBaseCommit)
|
|
2227
2238
|
.then((stat) => stat?.slice(0, 8_000) ?? null)
|
|
@@ -2244,6 +2255,7 @@ async function runAttempt(client, config, driver, workspace, brief, taskId, watc
|
|
|
2244
2255
|
phase: "verification",
|
|
2245
2256
|
witness: "bridge",
|
|
2246
2257
|
kind: "verification_failed",
|
|
2258
|
+
command: error.command,
|
|
2247
2259
|
...(diffStat ? { diff_stat: diffStat } : {}),
|
|
2248
2260
|
} } : {}),
|
|
2249
2261
|
// A rework's own PR may already be open (ensureDeliveryPullRequest ran before this
|
|
@@ -56,6 +56,8 @@ export const workPackageSchema = z.object({
|
|
|
56
56
|
diagnostic_context: z.object({
|
|
57
57
|
source_attempt_id: z.string().uuid(),
|
|
58
58
|
failure_output: z.string().min(1).max(12_000),
|
|
59
|
+
/** The gate Bridge re-runs, from the failed attempt's verification signal; null names no gate. */
|
|
60
|
+
gate_command: z.string().min(1).max(2_000).nullable(),
|
|
59
61
|
}).strict().optional(),
|
|
60
62
|
/** Working/Delivery language for Bridge assignment prose. */
|
|
61
63
|
working_language: z.enum(["en", "zh"]).optional(),
|
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.138",
|
|
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": {
|