⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
packages/loopover-miner/lib/attempt-runner.ts defines a named constant enumerating the attempt
outcomes:
export const ATTEMPT_OUTCOMES: readonly ["abandon", "stale", "blocked", "governed", "submitted"] =
Object.freeze([...]);
but the real AttemptResult return-type union (around line 96) includes a sixth outcome,
"verification_failed", returned at a real call site (around line 235:
return { outcome: "verification_failed", verification, loopResult };) whenever the target
repo's own build/lint/test verification fails during the attempt. ATTEMPT_OUTCOMES was never
updated to include it.
packages/loopover-miner/lib/attempt-cli.ts maps each named outcome to a dedicated process exit
code:
switch (result.outcome) {
case "submitted": return 0;
case "abandon": return 7;
case "stale": return 8;
case "blocked": return 9;
case "governed": return 10;
default: return 2;
}
Every outcome in ATTEMPT_OUTCOMES has its own dedicated exit code except the one missing from
that constant: "verification_failed" falls through to the default: return 2 branch —
reportCliFailure's own generic "invalid arguments, or the run hit an unexpected error" code. A
scheduler or operator alerting on this CLI's exit code (the documented pattern this codebase's own
sibling commands use) cannot distinguish "the target repo's own verification gate rejected the
change" (an expected, informative outcome with its own JSON verification payload) from "the
attempt CLI itself crashed with an unhandled error."
test/unit/miner-attempt-cli.test.ts has a test asserting the printed JSON payload's
outcome/verification fields for this case, but never asserts the process's returned exit code —
the exit-code gap itself is untested.
Requirements
- Add
"verification_failed" to the ATTEMPT_OUTCOMES constant in attempt-runner.ts, so the
constant's type and value match the real AttemptResult union it is meant to enumerate.
- Add a dedicated
case "verification_failed": branch to the exit-code switch in attempt-cli.ts,
returning a new, previously-unused exit code (the existing codes in use in this file are 0, 2,
and 4 through 11 inclusive, per the surrounding switch/cases — pick the next unused small integer
(e.g. 12) and use it consistently; do not reuse an exit code already assigned to a different
outcome).
- Document the new exit code alongside the others, in whatever comment or doc block already
enumerates this CLI's exit-code contract in attempt-cli.ts (if the sibling exit codes are
documented inline, add this one in the same place and format).
Deliverables
All deliverables are required in one PR — updating ATTEMPT_OUTCOMES without adding the dedicated
exit-code case (or vice versa) does not resolve this issue.
Test Coverage Requirements
This repo's Codecov patch gate is 99%+ (branch-counted) on packages/loopover-miner/lib/**. The
new switch branch must be exercised by the new regression test asserting the specific exit code
(not just that some non-zero, non-generic code was returned).
Expected Outcome
verification_failed is a fully first-class attempt outcome: it's included in
ATTEMPT_OUTCOMES, and a scheduler or operator can distinguish it from a genuine CLI crash purely
by exit code, matching every other named outcome.
Links & Resources
packages/loopover-miner/lib/attempt-runner.ts — ATTEMPT_OUTCOMES (~lines 32-38), the
AttemptResult union (~lines 94-100), and the real return site (~line 235).
packages/loopover-miner/lib/attempt-cli.ts — the exit-code switch (~lines 1076-1089).
packages/loopover-miner/lib/cli-error.ts — reportCliFailure's generic exit code (line ~4)
that this outcome currently, incorrectly, falls through to.
Context
packages/loopover-miner/lib/attempt-runner.tsdefines a named constant enumerating the attemptoutcomes:
but the real
AttemptResultreturn-type union (around line 96) includes a sixth outcome,"verification_failed", returned at a real call site (around line 235:return { outcome: "verification_failed", verification, loopResult };) whenever the targetrepo's own build/lint/test verification fails during the attempt.
ATTEMPT_OUTCOMESwas neverupdated to include it.
packages/loopover-miner/lib/attempt-cli.tsmaps each named outcome to a dedicated process exitcode:
Every outcome in
ATTEMPT_OUTCOMEShas its own dedicated exit code except the one missing fromthat constant:
"verification_failed"falls through to thedefault: return 2branch —reportCliFailure's own generic "invalid arguments, or the run hit an unexpected error" code. Ascheduler or operator alerting on this CLI's exit code (the documented pattern this codebase's own
sibling commands use) cannot distinguish "the target repo's own verification gate rejected the
change" (an expected, informative outcome with its own JSON
verificationpayload) from "theattempt CLI itself crashed with an unhandled error."
test/unit/miner-attempt-cli.test.tshas a test asserting the printed JSON payload'soutcome/verificationfields for this case, but never asserts the process's returned exit code —the exit-code gap itself is untested.
Requirements
"verification_failed"to theATTEMPT_OUTCOMESconstant inattempt-runner.ts, so theconstant's type and value match the real
AttemptResultunion it is meant to enumerate.case "verification_failed":branch to the exit-code switch inattempt-cli.ts,returning a new, previously-unused exit code (the existing codes in use in this file are 0, 2,
and 4 through 11 inclusive, per the surrounding switch/cases — pick the next unused small integer
(e.g. 12) and use it consistently; do not reuse an exit code already assigned to a different
outcome).
enumerates this CLI's exit-code contract in
attempt-cli.ts(if the sibling exit codes aredocumented inline, add this one in the same place and format).
Deliverables
ATTEMPT_OUTCOMESinattempt-runner.tsincludes"verification_failed"and its TypeScripttype reflects all six real outcomes.
attempt-cli.ts's exit-code switch has a dedicated case for"verification_failed"returning a new, previously-unused exit code (not the generic
2).test/unit/miner-attempt-cli.test.tsasserting the process'sreturned exit code (not just the JSON payload) for a
verification_failedoutcome equals thenew dedicated code.
All deliverables are required in one PR — updating
ATTEMPT_OUTCOMESwithout adding the dedicatedexit-code case (or vice versa) does not resolve this issue.
Test Coverage Requirements
This repo's Codecov patch gate is 99%+ (branch-counted) on
packages/loopover-miner/lib/**. Thenew switch branch must be exercised by the new regression test asserting the specific exit code
(not just that some non-zero, non-generic code was returned).
Expected Outcome
verification_failedis a fully first-class attempt outcome: it's included inATTEMPT_OUTCOMES, and a scheduler or operator can distinguish it from a genuine CLI crash purelyby exit code, matching every other named outcome.
Links & Resources
packages/loopover-miner/lib/attempt-runner.ts—ATTEMPT_OUTCOMES(~lines 32-38), theAttemptResultunion (~lines 94-100), and the real return site (~line 235).packages/loopover-miner/lib/attempt-cli.ts— the exit-code switch (~lines 1076-1089).packages/loopover-miner/lib/cli-error.ts—reportCliFailure's generic exit code (line ~4)that this outcome currently, incorrectly, falls through to.