diff --git a/11-Features.md b/11-Features.md index 8973144..9afb314 100644 --- a/11-Features.md +++ b/11-Features.md @@ -5019,3 +5019,56 @@ reading `free: 3` had no way to tell that number from a real one, and only found fleetd #416. Found by the fleet01 lead on a live daemon; the same shape as #404, where a status field read a different source than the behaviour it described. + +## The startup log tells "off" apart from "running on the built-in default" + +**What.** Two startup lines report whether a backend-classification is running. The +backend-**error** line no longer says `off` when no profile sets an `errorPattern`, because that +classification is still running — it falls back to a built-in pattern. The backend-**exhausted** +line still says `off`, because for that key it is true. + +``` +backend-error classification: built-in default for all profiles + (no profile customises errorPattern; profiles: [gx, local, opus, xf]) +backend-exhausted classification: off + (no profile has an exhaustedPattern configured; profiles: [gx, local, opus, xf]) +``` + +**The knob.** None. Both lines are logged at INFO at every startup. + +**Why it exists.** The old line was produced by one shared helper that knew only the key's name, so +it worded both keys the same way. But the two keys disagree on what "unset" means: + +- an unset `errorPattern` falls back to `CompletionResolver`'s built-in + `(?i)\bAPI Error\s*:` compatibility pattern, so classification keeps running; +- an unset `exhaustedPattern` has no fallback, so it really is off. + +One string, two meanings — and the false one was the reassuring direction. It told an operator a +live classifier was disabled while it was running, which is the worst thing to read when you are +debugging a false quarantine. The fact needed to word it correctly was written down about 1600 +lines away, in `FleetConfig`'s javadoc, and the method that got it wrong had no way to reach it. + +**Gotchas.** + +- **The classification really is live even with no `errorPattern` anywhere.** The built-in pattern + is narrow but it can still fire on a member's own prose that quotes an `API Error:` line. That is + why the outage policy needs the line twice before it acts. +- **"no profile customises it" is the useful reading**, not "nothing is configured". If you want a + different pattern for a backend, set it; the absence of the key is a choice of the default, not + an off switch. +- **`off` for `exhaustedPattern` is real.** Do not assume symmetry between the two lines — that + assumption is the bug this entry describes. +- **The wording is now the caller's responsibility.** `coverage()` takes a required + `UnsetMeaning` argument, so a third pattern key cannot compile without stating what unset means + for it. There is no permissive default to inherit. + +**Measured, and worth keeping.** The first fix was correct and still not safe: its tests all passed +the meaning in themselves, so they proved the wording and not the pairing. Swapping the two +arguments at the two call sites recreates the original bug with the keys exchanged, and that left +**all 1506 tests green with `BUILD SUCCESS`**. The call sites are now extracted into two named +factories and pinned by `FleetdPatternCoverageLineTest`; the same swap gives 3 failures. The +general rule: when a fix adds a parameter so the caller can supply a missing fact, test the +**caller's choice of value** — a test that passes the value in itself tests the half that was never +broken. + +fleetd #415. Found by the fleet01 lead on their own startup log.