diff --git a/fleetd/src/main/java/dev/ltms/fleet/Fleetd.java b/fleetd/src/main/java/dev/ltms/fleet/Fleetd.java index 30a7081..7181b7a 100644 --- a/fleetd/src/main/java/dev/ltms/fleet/Fleetd.java +++ b/fleetd/src/main/java/dev/ltms/fleet/Fleetd.java @@ -380,8 +380,7 @@ public final class Fleetd { .map(session -> exhaustedPatternsByProfile.get(session.profile())) .orElse(null); log.info("backend-exhausted classification (CB-578 stage A): {}", - CompletionResolver.coverage("exhaustedPattern", CompletionResolver.UnsetMeaning.OFF, - cfg.profiles().keySet(), exhaustedPatternsByProfile.keySet())); + exhaustedPatternCoverageLine(cfg.profiles().keySet(), exhaustedPatternsByProfile.keySet())); // fleetd #201 Unit 5: classify a completion-fallback scrape that matches a profile's // configured backend-error refusal (a credential outage, a provider 5xx) as a backend error // rather than handing it back as a real answer. Compiled once at startup, keyed by profile @@ -401,8 +400,7 @@ public final class Fleetd { BackendErrorPatternLookup backendErrorPatterns = backendErrorPatternLookup(sessions::roster, errorPatternsByProfile); log.info("backend-error classification (fleetd #201 Unit 5): {}", - CompletionResolver.coverage("errorPattern", CompletionResolver.UnsetMeaning.BUILT_IN_DEFAULT, - cfg.profiles().keySet(), errorPatternsByProfile.keySet())); + errorPatternCoverageLine(cfg.profiles().keySet(), errorPatternsByProfile.keySet())); // CB-578 stage B: on a classification that actually wins, quarantine the exhausted profile's // CREDENTIAL — not the profile name — so a profile sharing that credential (e.g. two models // on one OpenAI account) is refused too, not just the one that happened to report it. Reads @@ -807,6 +805,41 @@ public final class Fleetd { }, quarantine, profile -> startupExhaustedPatterns.containsKey(profile)); } + /** + * fleetd #415 (review follow-up): package-private factory for the CB-578 stage A {@code + * exhaustedPattern} startup coverage line, paired explicitly with {@link + * CompletionResolver.UnsetMeaning#OFF} — {@code exhaustedPattern} has no fallback, so a + * profile with none configured really does have the classification off. + * + *
Extracted out of {@code main} for the same reason {@link #capacitySource} and {@link
+ * #worktreeBranchLookup} were: {@code coverage()}'s own tests ({@code CompletionResolverTest})
+ * prove it words {@code OFF} and {@link CompletionResolver.UnsetMeaning#BUILT_IN_DEFAULT}
+ * correctly when a test supplies the meaning itself — they cannot prove {@code main} pairs the
+ * right meaning with the right key, which is the actual fleetd #415 defect. Measured:
+ * swapping the {@code UnsetMeaning} arguments between this method and {@link
+ * #errorPatternCoverageLine} — recreating #415's defect with the two keys exchanged — compiled
+ * with 0 errors and left all 1506 existing tests green before {@code
+ * FleetdPatternCoverageLineTest} was added to catch exactly that swap.
+ */
+ static String exhaustedPatternCoverageLine(Set This alone does not prove a caller passes the right one for its key. A
+ * test that calls {@code coverage()} directly and supplies the meaning itself only proves this
+ * enum is worded correctly, never that {@code Fleetd}'s two call sites pair each key with its
+ * true meaning — that pairing is #415's actual defect. Measured on review: swapping the two
+ * {@code UnsetMeaning} arguments at those call sites (giving {@code exhaustedPattern} the
+ * built-in-default wording and {@code errorPattern} the off wording — #415's exact defect with
+ * the keys exchanged) compiled with 0 errors and left all 1506 existing tests green. See
+ * {@code dev.ltms.fleet.Fleetd#exhaustedPatternCoverageLine}/{@code #errorPatternCoverageLine}
+ * and {@code FleetdPatternCoverageLineTest}, which exists specifically to catch that swap.
*/
public enum UnsetMeaning {
/** No fallback exists: a profile with no configured pattern truly has this classification off. */
diff --git a/fleetd/src/test/java/dev/ltms/fleet/FleetdPatternCoverageLineTest.java b/fleetd/src/test/java/dev/ltms/fleet/FleetdPatternCoverageLineTest.java
new file mode 100644
index 0000000..fdc7edb
--- /dev/null
+++ b/fleetd/src/test/java/dev/ltms/fleet/FleetdPatternCoverageLineTest.java
@@ -0,0 +1,67 @@
+package dev.ltms.fleet;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+/**
+ * fleetd #415 (review follow-up): {@code CompletionResolverTest} proves {@code coverage()} words
+ * {@code UnsetMeaning.OFF} and {@code UnsetMeaning.BUILT_IN_DEFAULT} correctly — but every one of
+ * those tests supplies the meaning itself. That proves the enum's wording, never that {@code
+ * Fleetd} pairs the right meaning with the right pattern key. That pairing is #415's actual
+ * defect: {@code coverage()} had no way to know what unset meant for its key, so the fix moved
+ * the fact to the caller — and nothing yet proved the caller states it correctly.
+ *
+ * Measured or it didn't happen: swapping the two {@code UnsetMeaning} arguments at
+ * {@code Fleetd}'s two coverage call sites — giving {@code exhaustedPattern} the built-in-default
+ * wording and {@code errorPattern} the off wording, #415's exact defect with the keys exchanged —
+ * compiled with 0 errors and left all 1506 existing tests green. This class exists to turn that
+ * swap red.
+ *
+ * It calls {@link Fleetd#exhaustedPatternCoverageLine} and {@link Fleetd#errorPatternCoverageLine}
+ * directly rather than reading {@code Fleetd.java} as source text (the shape {@code
+ * FleetdCompletionResolverWiringTest} uses for a different wiring gap): those two methods are the
+ * extracted call sites {@code main} actually invokes, following the same {@code static} factory +
+ * dedicated-test pattern as {@link Fleetd#capacitySource} and {@link Fleetd#worktreeBranchLookup}.
+ */
+class FleetdPatternCoverageLineTest {
+
+ private static final Set