From 0b83e86c5ea684fe46e4b674bac3cb446f344a9d Mon Sep 17 00:00:00 2001 From: darken Date: Thu, 20 Aug 2026 00:06:03 +0200 Subject: [PATCH] fix(aap): Correct an overstated safety claim and a test that proved nothing Review follow-ups on the previous commit. Its claim that "nothing is learned or persisted" was wrong. BatteryEstimator buckets drain samples by the current listening mode and force-persists the accumulated window whenever that mode changes, so a misattributed mode can write a drain rate to disk under the wrong bucket, and the corrective report does not remove it. This is not new: the misreport being fixed here already mis-buckets in the same way, and more often, since the device claims OFF while the pods play Adaptive. Classifying corrects the common case and only gets it wrong on the rarer misattribution. The design stands, the claim does not. Two other claims were also too strong. The recorded echo is the first report after the verification was installed, which is not exactly the wire write, so write contention above the latency boundary can still inflate a fast refusal. And a superseded write is not left alone entirely: classification is skipped, but it still falls through to the ordinary retry path. The supersession regression test asserted nothing: it fed a fresh ADAPTIVE report in before its only assertion, overwriting either outcome, so it passed whether or not the guard existed. It now asserts on the state left by the delayed echo, and fails with the guard removed. Also drops an unused import and restores an indent lost when the remap argument was removed. --- .../pods/core/apple/aap/engine/AapSessionEngine.kt | 2 +- .../core/apple/aap/engine/AapSessionEngineTest.kt | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/eu/darken/capod/pods/core/apple/aap/engine/AapSessionEngine.kt b/app/src/main/java/eu/darken/capod/pods/core/apple/aap/engine/AapSessionEngine.kt index 8eac67f3..f7df880b 100644 --- a/app/src/main/java/eu/darken/capod/pods/core/apple/aap/engine/AapSessionEngine.kt +++ b/app/src/main/java/eu/darken/capod/pods/core/apple/aap/engine/AapSessionEngine.kt @@ -361,7 +361,7 @@ internal class AapSessionEngine( EngineTimerKey.Verification -> { applyOutboundDecisionAsync( -outboundController.onVerificationTimerFired(_state.value, runtimeState.outbound), + outboundController.onVerificationTimerFired(_state.value, runtimeState.outbound), ) } } diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/aap/engine/AapSessionEngineTest.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/aap/engine/AapSessionEngineTest.kt index d8341ff7..10e7de31 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/aap/engine/AapSessionEngineTest.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/aap/engine/AapSessionEngineTest.kt @@ -14,7 +14,6 @@ import io.kotest.matchers.collections.shouldBeEmpty import io.kotest.matchers.nulls.shouldBeNull import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.matchers.shouldBe -import io.kotest.matchers.shouldNotBe import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.flow.first @@ -882,16 +881,9 @@ class AapSessionEngineTest : BaseTest() { engine.processMessage(dummyMessage()) advanceTimeBy(AapOutboundController.VERIFICATION_TIMEOUT_MS * 2 + 100L) - // Must not have learned ADAPTIVE -> TRANSPARENCY. A later genuine ADAPTIVE report - // therefore still reads as ADAPTIVE. - nextSetting = settingPair( - AapSetting.AncMode( - current = AapSetting.AncMode.Value.ADAPTIVE, - supported = supportedModes, - ) - ) - engine.processMessage(dummyMessage()) - advanceTimeBy(1600L) + // Without supersession the classifier would call this ADAPTIVE report the answer to + // the TRANSPARENCY write and force TRANSPARENCY into state. State must instead stay + // on what the device actually reported. engine.state.value.setting()!!.current shouldBe AapSetting.AncMode.Value.ADAPTIVE }