Skip to content

Commit fe03101

Browse files
fryanpanclaude
andcommitted
ADFA-4128: keep the tap when an invalidation lands where the ask lives
InvalidationDetected(userInitiated = true) means the orchestrator consumed a tap to reach the invalidation, and the ask has to travel with it. Three arms dropped it: the parked Invalidated arm rebuilt the state with userInitiated = false, the in-flight Invalidated arm kept the state as it was, and Provisioning ignored the event entirely. Each now ORs the event's flag into the state's, so a tap that arrived before or during the invalidation still brings the proxy app forward. Red before this change, from SessionReducerInvariantsTest: (3) InvalidationDetected(userInitiated = true) keeps the ask expected to be empty but was: [Provisioning(userInitiated=false, ...) + InvalidationDetected(reason=GRADLE_CONFIG_CHANGED, userInitiated=true) -> Provisioning(userInitiated=false, ...) []: the tap on the invalidation is dropped, ...] (10 pairs) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0153YfwDnqn7ktHcVgXSNNe8
1 parent 1a73e6d commit fe03101

1 file changed

Lines changed: 16 additions & 5 deletions

File tree

  • quickbuild/core/src/main/java/org/appdevforall/cotg/quickbuild/domain/session

quickbuild/core/src/main/java/org/appdevforall/cotg/quickbuild/domain/session/SessionReducer.kt

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,13 @@ class SessionReducer {
272272
)
273273
}
274274

275+
is SessionEvent.InvalidationDetected -> {
276+
// The Gradle build in flight already reads current disk, so the invalidation
277+
// itself changes nothing here. The tap it may carry is answered when this
278+
// build lands, so only the ask is taken from it.
279+
SessionTransition(state.copy(userInitiated = state.userInitiated || event.userInitiated))
280+
}
281+
275282
else -> {
276283
SessionTransition(state)
277284
}
@@ -492,17 +499,21 @@ class SessionReducer {
492499
// foreground return, so nothing else would unpark it. The budget resets because
493500
// a changed file is a genuinely new attempt, not a retry of the failure.
494501
SessionTransition(
495-
QuickBuildSessionState.Invalidated(
496-
event.reason,
497-
state.deployedGeneration,
502+
state.copy(
503+
reason = event.reason,
498504
awaitingRetry = false,
499505
installAutoRetries = 0,
506+
// The save that unparks may be a tap's own save-all, so the ask
507+
// rides on the event and is kept, never rebuilt from defaults.
508+
userInitiated = state.userInitiated || event.userInitiated,
500509
),
501510
listOf(SessionEffect.RunProxyAppRebuild),
502511
)
503512
} else {
504-
// A proxy app rebuild is already in flight; it will build from current disk.
505-
SessionTransition(state)
513+
// A proxy app rebuild is already in flight; it will build from current
514+
// disk. Only the ask is news: a tap consumed by this batch is answered
515+
// when that rebuild lands, so it must not vanish with the duplicate report.
516+
SessionTransition(state.copy(userInitiated = state.userInitiated || event.userInitiated))
506517
}
507518
}
508519

0 commit comments

Comments
 (0)