From 4c6df575245c6e6513c4bc75a59ef22276f56f08 Mon Sep 17 00:00:00 2001 From: Jeff <158072326+jeffrey701@users.noreply.github.com> Date: Mon, 27 Jul 2026 16:45:04 +0200 Subject: [PATCH] fix(miner): surface verification payload in attempt-cli JSON for verification_failed --- packages/loopover-miner/lib/attempt-cli.ts | 5 ++++ test/unit/miner-attempt-cli.test.ts | 29 ++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/packages/loopover-miner/lib/attempt-cli.ts b/packages/loopover-miner/lib/attempt-cli.ts index 483ec9f80..6d430e532 100644 --- a/packages/loopover-miner/lib/attempt-cli.ts +++ b/packages/loopover-miner/lib/attempt-cli.ts @@ -117,6 +117,9 @@ export type AttemptCliResult = decision?: unknown; spec?: LocalWriteActionSpec; execResult?: unknown; + // #9328: surfaced from the AttemptResult "verification_failed" outcome (#8807's target-repo gate), + // mirroring the other optional sibling fields' conditional spread in finalResult below. + verification?: unknown; claimConflict?: ClaimConflictResult; }); @@ -1018,6 +1021,8 @@ export async function runAttempt(args: string[], options: RunAttemptOptions = {} ...("decision" in result ? { decision: result.decision } : {}), ...("spec" in result ? { spec: result.spec } : {}), ...("execResult" in result ? { execResult: result.execResult } : {}), + // #9328: the "verification_failed" outcome carries a `verification` payload the CLI JSON was dropping. + ...("verification" in result ? { verification: result.verification } : {}), // Present only on a real "submitted" outcome whose PR number was recoverable from execResult -- omitted // (not fabricated as "checked: false") on every other outcome, and on a submitted outcome where the new // PR's number genuinely couldn't be parsed (an honest gap, not silently swallowed). diff --git a/test/unit/miner-attempt-cli.test.ts b/test/unit/miner-attempt-cli.test.ts index a5a0a2189..22b1c5359 100644 --- a/test/unit/miner-attempt-cli.test.ts +++ b/test/unit/miner-attempt-cli.test.ts @@ -535,6 +535,35 @@ describe("runAttempt (#5132)", () => { }); }); + it("surfaces the verification payload in the CLI JSON for a verification_failed outcome (#9328)", async () => { + const { allocator, claimLedger, eventLedger, attemptLog, governorLedger } = tempLedgers(); + const log = vi.spyOn(console, "log").mockImplementation(() => undefined); + const verification = { ok: false, expectedRepo: "acme/widgets", observedRepo: "acme/other" }; + const runMinerAttemptSpy = vi.fn().mockResolvedValue({ + outcome: "verification_failed", + verification, + loopResult: fakeLoopResult(), + }); + + await runAttempt(["acme/widgets", "7", "--miner-login", "alice", "--json"], { + env: { MINER_CODING_AGENT_PROVIDER: "noop" }, + attemptId: "fixed-attempt-id", + openWorktreeAllocator: () => allocator, + openClaimLedger: () => claimLedger, + initEventLedger: () => eventLedger, + initAttemptLog: () => attemptLog, + initGovernorLedger: () => governorLedger, + ...readyPipelineOptions({ runMinerAttempt: runMinerAttemptSpy }), + }); + + const printed = JSON.parse( + String(log.mock.calls.map((call) => call[0]).find((arg) => String(arg).includes("attempt_verification_failed"))), + ); + expect(printed.outcome).toBe("attempt_verification_failed"); + // The verification payload the "verification_failed" outcome carries is now present, not dropped. + expect(printed.verification).toEqual(verification); + }); + it("schedules an AMS attempt-started notification before the attempt runs, and no failure notification on submit (#7657)", async () => { const { allocator, claimLedger, eventLedger, attemptLog, governorLedger } = tempLedgers(); vi.spyOn(console, "log").mockImplementation(() => undefined);