@@ -122,7 +122,11 @@ function collected(overrides: {
122122
123123describe ( "runPrePrChecksWithFixes" , ( ) => {
124124 beforeEach ( ( ) => {
125- vi . clearAllMocks ( ) ;
125+ // resetAllMocks, not clearAllMocks: clear leaves queued mockImplementationOnce
126+ // entries behind, so a test that consumes fewer of them than it queued leaks
127+ // the rest into whatever runs next. That made five unrelated tests fail the
128+ // moment the repair loop stopped running by default.
129+ vi . resetAllMocks ( ) ;
126130 mocks . pollPhaseUntilDone . mockImplementation ( pollEnds ( "finished" , 30_000 ) ) ;
127131 mocks . startRepoCheckBatchStep . mockImplementation ( async (
128132 _sandboxId : string ,
@@ -446,7 +450,7 @@ describe("runPrePrChecksWithFixes", () => {
446450 } ) ;
447451 mocks . collectPrePrRepairStep . mockResolvedValue ( { usage : null } ) ;
448452
449- const result = await runPrePrChecksWithFixes ( options ( ) ) ;
453+ const result = await runPrePrChecksWithFixes ( options ( { maxFixCycles : 3 } ) ) ;
450454
451455 expect ( result . passed ) . toBe ( true ) ;
452456 expect ( result . fixCycles ) . toBe ( 1 ) ;
@@ -619,7 +623,7 @@ describe("runPrePrChecksWithFixes", () => {
619623 } ) ;
620624 mocks . collectPrePrRepairStep . mockResolvedValue ( { usage : null } ) ;
621625
622- const result = await runPrePrChecksWithFixes ( options ( { config } ) ) ;
626+ const result = await runPrePrChecksWithFixes ( options ( { maxFixCycles : 3 , config } ) ) ;
623627
624628 expect ( result . setupFailed ) . toBe ( false ) ;
625629 expect ( mocks . startPrePrRepairStep ) . toHaveBeenCalledTimes ( 1 ) ;
@@ -735,6 +739,32 @@ describe("runPrePrChecksWithFixes", () => {
735739 expect ( mocks . startPrePrRepairStep ) . not . toHaveBeenCalled ( ) ;
736740 } ) ;
737741
742+ it ( "runs no fix cycles when the graph does not author maxFixCycles" , async ( ) => {
743+ // Pins the shipped default. Repair before the pull request re-ran the whole
744+ // batch on every cycle and could not tell a broken environment from broken
745+ // code, so remediation moved behind the pull request. A graph that wants the
746+ // old behaviour has to ask for it by number.
747+ mocks . collectRepoCheckBatchStep . mockResolvedValue (
748+ collected ( {
749+ results : [ { provider : "github" , repoPath : "acme/web" , command : "pnpm typecheck" , exitCode : 1 } ] ,
750+ failures : [ {
751+ provider : "github" ,
752+ repoPath : "acme/web" ,
753+ command : "pnpm typecheck" ,
754+ exitCode : 1 ,
755+ stdout : "" ,
756+ stderr : "still failing" ,
757+ } ] ,
758+ } ) ,
759+ ) ;
760+
761+ const result = await runPrePrChecksWithFixes ( options ( ) ) ;
762+
763+ expect ( result . fixCycles ) . toBe ( 0 ) ;
764+ expect ( result . passed ) . toBe ( false ) ;
765+ expect ( mocks . startPrePrRepairStep ) . not . toHaveBeenCalled ( ) ;
766+ } ) ;
767+
738768 it ( "returns a repair agent failure without starting another cycle" , async ( ) => {
739769 mocks . collectRepoCheckBatchStep . mockResolvedValue (
740770 collected ( {
@@ -754,7 +784,7 @@ describe("runPrePrChecksWithFixes", () => {
754784 failure : { ok : false , category : "provider" , diagnostic : { failureKind : "setup_failed" } } ,
755785 } ) ;
756786
757- const result = await runPrePrChecksWithFixes ( options ( ) ) ;
787+ const result = await runPrePrChecksWithFixes ( options ( { maxFixCycles : 3 } ) ) ;
758788
759789 expect ( result . fixCycles ) . toBe ( 1 ) ;
760790 expect ( result . agentFailure ) . toMatchObject ( {
@@ -843,6 +873,7 @@ describe("runPrePrChecksWithFixes", () => {
843873
844874 const result = await runPrePrChecksWithFixes (
845875 options ( {
876+ maxFixCycles : 3 ,
846877 budget : {
847878 state : createRunBudgetState ( ) ,
848879 limits : { maxDurationMs : 60_000 , maxTokens : 12 } ,
0 commit comments