fleetd #415: split coverage() feature-state wording by pattern fallback semantics #423

Merged
ltms merged 2 commits from worker/415-coverage-wording-2cbf9c-5 into main 2026-09-10 06:57:34 +02:00
Member

Ticket #415

CompletionResolver.coverage() measured pattern coverage (how many profiles set a key), but its empty-case wording (off (...)) read as feature state. That is false for errorPattern: a profile with no configured errorPattern still runs backend-error classification against the built-in BACKEND_ERROR pattern (CompletionResolver.java:84), so "off" was wrong for that key. For exhaustedPattern there is no fallback, so "off" is correct there.

Fix

Added CompletionResolver.UnsetMeaning (OFF / BUILT_IN_DEFAULT) as a required parameter to coverage() — no defaulted overload, so a third pattern key added later cannot compile without stating what unset means for it (per the ticket's acceptance criteria: prefer a required parameter over a defaulted one).

Fleetd.java now passes:

  • UnsetMeaning.OFF for exhaustedPattern (CB-578 stage A — no fallback exists)
  • UnsetMeaning.BUILT_IN_DEFAULT for errorPattern (fleetd #201 Unit 5 — falls back to the built-in compatibility pattern)

New wording:

  • empty + OFF → off (no profile has an <key> configured; profiles: [...]) (unchanged)
  • empty + BUILT_IN_DEFAULT → built-in default for all profiles (no profile customises <key>; profiles: [...])
  • partial/full unchanged for both keys

Tests

  • Updated the three existing empty/full/partial CompletionResolverTest cases to pass the new UnsetMeaning parameter.
  • Corrected coverageNamesTheConfigKeyItsCallerMeansRatherThanAlwaysSayingExhaustedPattern, which had pinned the old, wrong errorPattern wording ("off") — it now asserts the corrected built-in-default wording.
  • Added coverageDistinguishesOffFromBuiltInDefaultForTheSameEmptyInput, which feeds the same empty-coverage shape through both keys and asserts the two resulting lines are different (per the ticket: "a test that only checks a line was emitted would pass today — that is not acceptable").

Mutation proof (done and reverted before this push)

  • Mutation A (make the errorPattern/BUILT_IN_DEFAULT case fall back to the old off wording): CompletionResolverTest.coverageNamesTheConfigKeyItsCallerMeansRatherThanAlwaysSayingExhaustedPattern and coverageDistinguishesOffFromBuiltInDefaultForTheSameEmptyInput both failed with AssertionFailedError: expected: <built-in default for all profiles (...)> but was: <off (...)>.
  • Mutation B (make the exhaustedPattern/OFF case use the built-in wording too): CompletionResolverTest.coverageIsOffWhenNoProfileHasAPatternConfigured and coverageDistinguishesOffFromBuiltInDefaultForTheSameEmptyInput both failed with the mirrored assertion error.
  • Each mutation was applied alone, confirmed red, then reverted before the final build.

Build

mvn clean install from the worktree root's fleetd/ directory:

[INFO] Tests run: 1506, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS

0 compile errors, 0 test failures/errors.

Also noted, not fixed (per ticket #407 / #415 instructions)

  • FleetHealthMonitor.coverage(boolean, boolean) (fleetd/src/main/java/dev/ltms/fleet/health/FleetHealthMonitor.java:377) is logged at startup the same way, and I found no test anywhere under fleetd/src/test that calls it directly — deleting its body would very likely leave the suite green.
## Ticket #415 `CompletionResolver.coverage()` measured **pattern coverage** (how many profiles set a key), but its empty-case wording (`off (...)`) read as **feature state**. That is false for `errorPattern`: a profile with no configured `errorPattern` still runs backend-error classification against the built-in `BACKEND_ERROR` pattern (`CompletionResolver.java:84`), so "off" was wrong for that key. For `exhaustedPattern` there is no fallback, so "off" is correct there. ## Fix Added `CompletionResolver.UnsetMeaning` (`OFF` / `BUILT_IN_DEFAULT`) as a **required** parameter to `coverage()` — no defaulted overload, so a third pattern key added later cannot compile without stating what unset means for it (per the ticket's acceptance criteria: prefer a required parameter over a defaulted one). `Fleetd.java` now passes: - `UnsetMeaning.OFF` for `exhaustedPattern` (CB-578 stage A — no fallback exists) - `UnsetMeaning.BUILT_IN_DEFAULT` for `errorPattern` (fleetd #201 Unit 5 — falls back to the built-in compatibility pattern) New wording: - empty + `OFF` → `off (no profile has an <key> configured; profiles: [...])` (unchanged) - empty + `BUILT_IN_DEFAULT` → `built-in default for all profiles (no profile customises <key>; profiles: [...])` - `partial`/`full` unchanged for both keys ## Tests - Updated the three existing empty/full/partial `CompletionResolverTest` cases to pass the new `UnsetMeaning` parameter. - Corrected `coverageNamesTheConfigKeyItsCallerMeansRatherThanAlwaysSayingExhaustedPattern`, which had pinned the **old, wrong** `errorPattern` wording ("off") — it now asserts the corrected built-in-default wording. - Added `coverageDistinguishesOffFromBuiltInDefaultForTheSameEmptyInput`, which feeds the same empty-coverage shape through both keys and asserts the two resulting lines are **different** (per the ticket: "a test that only checks a line was emitted would pass today — that is not acceptable"). ### Mutation proof (done and reverted before this push) - **Mutation A** (make the `errorPattern`/`BUILT_IN_DEFAULT` case fall back to the old `off` wording): `CompletionResolverTest.coverageNamesTheConfigKeyItsCallerMeansRatherThanAlwaysSayingExhaustedPattern` and `coverageDistinguishesOffFromBuiltInDefaultForTheSameEmptyInput` both failed with `AssertionFailedError: expected: <built-in default for all profiles (...)> but was: <off (...)>`. - **Mutation B** (make the `exhaustedPattern`/`OFF` case use the built-in wording too): `CompletionResolverTest.coverageIsOffWhenNoProfileHasAPatternConfigured` and `coverageDistinguishesOffFromBuiltInDefaultForTheSameEmptyInput` both failed with the mirrored assertion error. - Each mutation was applied alone, confirmed red, then reverted before the final build. ## Build `mvn clean install` from the worktree root's `fleetd/` directory: ``` [INFO] Tests run: 1506, Failures: 0, Errors: 0, Skipped: 0 [INFO] BUILD SUCCESS ``` 0 compile errors, 0 test failures/errors. ## Also noted, not fixed (per ticket #407 / #415 instructions) - `FleetHealthMonitor.coverage(boolean, boolean)` (`fleetd/src/main/java/dev/ltms/fleet/health/FleetHealthMonitor.java:377`) is logged at startup the same way, and I found no test anywhere under `fleetd/src/test` that calls it directly — deleting its body would very likely leave the suite green.
agent added 1 commit 2026-09-10 06:41:01 +02:00
fleetd #415: split coverage() feature-state wording by pattern-key fallback semantics
CI / contract (pull_request) Successful in 46s
CI / build (pull_request) Successful in 2m4s
be123d0ac7
CompletionResolver.coverage() measured pattern coverage (how many profiles set
a key) but its 'off' wording read as feature state. That is false for
errorPattern: an unset errorPattern still runs the classification against the
built-in BACKEND_ERROR pattern (CompletionResolver.java:84), so the empty case
is not off.

Add CompletionResolver.UnsetMeaning (OFF / BUILT_IN_DEFAULT), a required
parameter every coverage() call must supply — no defaulted overload, so a
future third pattern key cannot compile without stating what unset means for
it. Fleetd.java now passes UnsetMeaning.OFF for exhaustedPattern (no fallback
exists) and UnsetMeaning.BUILT_IN_DEFAULT for errorPattern.

Tests: updated the three existing empty/full/partial cases to pass the new
parameter, corrected the one test that pinned the old (wrong) errorPattern
wording, and added a test that asserts the same empty-coverage input produces
different wording for the two keys.
agent added 1 commit 2026-09-10 06:54:11 +02:00
fleetd #415: pin which UnsetMeaning Fleetd pairs with which pattern key
CI / contract (pull_request) Successful in 50s
CI / build (pull_request) Successful in 1m54s
ce05886831
Review found a gap: the earlier tests all called CompletionResolver.coverage()
directly, supplying the UnsetMeaning themselves — proving the enum's wording,
never that Fleetd's two call sites pair the right meaning with the right key.
Swapping the two UnsetMeaning arguments at those call sites (recreating #415's
defect with exhaustedPattern and errorPattern exchanged) compiled with 0 errors
and left all 1506 tests green.

Extract the two coverage-line call sites out of main() into package-private
static factories (Fleetd.exhaustedPatternCoverageLine /
errorPatternCoverageLine), the same pattern already used for capacitySource
and worktreeBranchLookup. Add FleetdPatternCoverageLineTest, which calls both
factories directly and asserts the actual wording each produces for the same
empty-coverage input, including that the two differ.

Also recorded the swap-mutation measurement (0 errors, 1506 green) in
UnsetMeaning's javadoc so a future reader does not delete the new test as
redundant with CompletionResolverTest.
ltms merged commit e60f892efd into main 2026-09-10 06:57:34 +02:00
Sign in to join this conversation.