fleetd #474 follow-up: pin main's config wiring against M2 #476

Closed
agent wants to merge 0 commits from worker/474-followup-source-pin-f54a55-17 into main
Member

Follow-up to #474/#475 (merged as 4466ee0 on main). Your mutation battery on the merged commit found M2 survives: reverting Fleetd.java:154 from the three-argument ConfigRef constructor back to the plain two-argument one compiles with 0 errors and leaves the whole suite green, because ConfigRefTest and FleetdConfigRefCharterToolSurfaceWiringTest each build their own ConfigRef directly rather than through Fleetd.main. This PR closes that hole with one new source-text test file. No production code changed.

What I added

fleetd/src/test/java/dev/ltms/fleet/FleetdConfigRefWiringTest.java, following the FleetdBackendQuarantineWiringTest/FleetdLeadSeatWiringTest/FleetdCompletionResolverWiringTest pattern (Pattern 2: read Fleetd.java's source text and assert main still contains the exact call) rather than the FleetdExhaustionDetectionArmedWiringTest pattern (Pattern 1: build the same wiring and drive it) I'd used before, which — as you pointed out — can prove the combination works but can never prove main chose it.

The test:

  1. Reads src/main/java/dev/ltms/fleet/Fleetd.java as a string (fleetdSource(), identical helper shape to the three precedents).
  2. First asserts the source contains "public final class Fleetd" — an anchor unrelated to this mutation — so a broken/empty read fails loudly here instead of making the assertFalse below pass vacuously. (Your "zero match reads as a clean pass" trap.)
  3. Asserts the source contains the exact one-line text ConfigRef config = new ConfigRef(configPath, cfg, Fleetd::assertChartersNameOnlyRegisteredTools);.
  4. Asserts, as a negative, that the source does NOT contain ConfigRef config = new ConfigRef(configPath, cfg); (the M2 form) at that declaration.
  5. Carries a @DisplayName starting [SOURCE TEXT], and a javadoc stating plainly what a green result proves and does not: the exact text is present, not that the call executes at startup, not that the gate works.

Acceptance criteria

1. mvn -B clean test is green, counts read from a file, never a piped tail.

Initial run with the new test added (source untouched): Tests run: 1634, Failures: 0, Errors: 0, Skipped: 0 — BUILD SUCCESS — EXIT_CODE=0 (1633 baseline + 1 new test).

2. Proof the new test kills M2. Applied your exact mutation — changed Fleetd.java:154 from the 3-arg form to new ConfigRef(configPath, cfg); — and ran the full suite:

[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.004 s <<< FAILURE! -- in dev.ltms.fleet.FleetdConfigRefWiringTest
[ERROR] dev.ltms.fleet.FleetdConfigRefWiringTest.mainStillWiresTheThreeArgumentConfigRefConstructor -- Time elapsed: 0.003 s <<< FAILURE!
...
[INFO] Tests run: 1634, Failures: 1, Errors: 0, Skipped: 0
[INFO] BUILD FAILURE
EXIT_CODE=1

Only that one test failed — the new source-text check, by name, exactly as intended. Restored Fleetd.java:154 byte-identical (git diff --stat -- fleetd/src/main/java/dev/ltms/fleet/Fleetd.java came back empty) and reran: Tests run: 1634, Failures: 0, Errors: 0, Skipped: 0 — BUILD SUCCESS — EXIT_CODE=0. git status --porcelain at that point showed only the new test file as untracked — nothing else touched.

3. Proof the new test is not vacuous. Reflowed the anchored line — same tokens, split across two lines with different whitespace, behaviour byte-identical at runtime:

ConfigRef config = new ConfigRef(configPath, cfg,
        Fleetd::assertChartersNameOnlyRegisteredTools);

Ran just the new test class: Tests run: 1, Failures: 1 — dev.ltms.fleet.FleetdConfigRefWiringTest.mainStillWiresTheThreeArgumentConfigRefConstructor failed, EXIT_CODE=1. This is the expected/intended result, not tolerated: the test's whole value is reading the exact text main contains, so it must go red the moment that text moves, the same trade FleetdBackendQuarantineWiringTest's multi-line anchor already makes. I did not add reflow-tolerance — that would reopen a gap the precedent already accepts closing this way. Restored the line byte-identical afterward (git diff --stat on Fleetd.java empty again) and reran the full suite green (see acceptance criterion 1's final number below).

4. What else pins Fleetd.java:154? Nothing, checked directly: grep -rln "Fleetd::assertChartersNameOnlyRegisteredTools" fleetd/src/test/java returns only FleetdConfigRefCharterToolSurfaceWiringTest.java (builds its own ConfigRef with that reference, doesn't read main's source) and this new FleetdConfigRefWiringTest.java. grep -rln 'Path.of("src/main/java/dev/ltms/fleet/Fleetd.java")' fleetd/src/test/java lists the other six source-text tests (FleetdFleetAppConstructionTest, FleetdCompletionResolverWiringTest, FleetdLeadSeatWiringTest, FleetdConnectionIdentityConstructionTest, FleetdHerdrControlConstructionTest, FleetdBackendQuarantineWiringTest, plus this one) — I checked the three not already discussed for any incidental ConfigRef mention (grep -n "ConfigRef" on each) and found none. So this new test is the only thing pinning this call site.

Final build

mvn -B clean test, unpiped, exit code read from the log file: Tests run: 1634, Failures: 0, Errors: 0, Skipped: 0 — BUILD SUCCESS — EXIT_CODE=0.

Files changed

  • fleetd/src/test/java/dev/ltms/fleet/FleetdConfigRefWiringTest.java (new) — only file in this PR.

Caveats

  • Could not run the wiki-sync check — wiki/ is uninitialized in this worker's worktree.
  • Branch was created fresh from origin/main (post-merge, at 4466ee0) rather than continuing the old worker/474-charter-check-on-reload-f54a55-17 branch, since that one was already merged; noting this in case the branch name looks unfamiliar.
  • Scope was exactly this follow-up; nothing else touched, no production code changed.
Follow-up to #474/#475 (merged as `4466ee0` on `main`). Your mutation battery on the merged commit found M2 survives: reverting `Fleetd.java:154` from the three-argument `ConfigRef` constructor back to the plain two-argument one compiles with 0 errors and leaves the whole suite green, because `ConfigRefTest` and `FleetdConfigRefCharterToolSurfaceWiringTest` each build their own `ConfigRef` directly rather than through `Fleetd.main`. This PR closes that hole with one new source-text test file. No production code changed. ## What I added `fleetd/src/test/java/dev/ltms/fleet/FleetdConfigRefWiringTest.java`, following the `FleetdBackendQuarantineWiringTest`/`FleetdLeadSeatWiringTest`/`FleetdCompletionResolverWiringTest` pattern (Pattern 2: read `Fleetd.java`'s source text and assert `main` still contains the exact call) rather than the `FleetdExhaustionDetectionArmedWiringTest` pattern (Pattern 1: build the same wiring and drive it) I'd used before, which — as you pointed out — can prove the combination works but can never prove `main` chose it. The test: 1. Reads `src/main/java/dev/ltms/fleet/Fleetd.java` as a string (`fleetdSource()`, identical helper shape to the three precedents). 2. First asserts the source contains `"public final class Fleetd"` — an anchor unrelated to this mutation — so a broken/empty read fails loudly here instead of making the `assertFalse` below pass vacuously. (Your "zero match reads as a clean pass" trap.) 3. Asserts the source contains the exact one-line text `ConfigRef config = new ConfigRef(configPath, cfg, Fleetd::assertChartersNameOnlyRegisteredTools);`. 4. Asserts, as a negative, that the source does NOT contain `ConfigRef config = new ConfigRef(configPath, cfg);` (the M2 form) at that declaration. 5. Carries a `@DisplayName` starting `[SOURCE TEXT]`, and a javadoc stating plainly what a green result proves and does not: the exact text is present, not that the call executes at startup, not that the gate works. ## Acceptance criteria **1. `mvn -B clean test` is green, counts read from a file, never a piped tail.** Initial run with the new test added (source untouched): `Tests run: 1634, Failures: 0, Errors: 0, Skipped: 0` — `BUILD SUCCESS` — `EXIT_CODE=0` (1633 baseline + 1 new test). **2. Proof the new test kills M2.** Applied your exact mutation — changed `Fleetd.java:154` from the 3-arg form to `new ConfigRef(configPath, cfg);` — and ran the full suite: ``` [ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.004 s <<< FAILURE! -- in dev.ltms.fleet.FleetdConfigRefWiringTest [ERROR] dev.ltms.fleet.FleetdConfigRefWiringTest.mainStillWiresTheThreeArgumentConfigRefConstructor -- Time elapsed: 0.003 s <<< FAILURE! ... [INFO] Tests run: 1634, Failures: 1, Errors: 0, Skipped: 0 [INFO] BUILD FAILURE EXIT_CODE=1 ``` Only that one test failed — the new source-text check, by name, exactly as intended. Restored `Fleetd.java:154` byte-identical (`git diff --stat -- fleetd/src/main/java/dev/ltms/fleet/Fleetd.java` came back empty) and reran: `Tests run: 1634, Failures: 0, Errors: 0, Skipped: 0` — `BUILD SUCCESS` — `EXIT_CODE=0`. `git status --porcelain` at that point showed only the new test file as untracked — nothing else touched. **3. Proof the new test is not vacuous.** Reflowed the anchored line — same tokens, split across two lines with different whitespace, behaviour byte-identical at runtime: ```java ConfigRef config = new ConfigRef(configPath, cfg, Fleetd::assertChartersNameOnlyRegisteredTools); ``` Ran just the new test class: `Tests run: 1, Failures: 1` — `dev.ltms.fleet.FleetdConfigRefWiringTest.mainStillWiresTheThreeArgumentConfigRefConstructor` failed, `EXIT_CODE=1`. This is the expected/intended result, not tolerated: the test's whole value is reading the exact text `main` contains, so it must go red the moment that text moves, the same trade `FleetdBackendQuarantineWiringTest`'s multi-line anchor already makes. I did not add reflow-tolerance — that would reopen a gap the precedent already accepts closing this way. Restored the line byte-identical afterward (`git diff --stat` on `Fleetd.java` empty again) and reran the full suite green (see acceptance criterion 1's final number below). **4. What else pins `Fleetd.java:154`?** Nothing, checked directly: `grep -rln "Fleetd::assertChartersNameOnlyRegisteredTools" fleetd/src/test/java` returns only `FleetdConfigRefCharterToolSurfaceWiringTest.java` (builds its own `ConfigRef` with that reference, doesn't read `main`'s source) and this new `FleetdConfigRefWiringTest.java`. `grep -rln 'Path.of("src/main/java/dev/ltms/fleet/Fleetd.java")' fleetd/src/test/java` lists the other six source-text tests (`FleetdFleetAppConstructionTest`, `FleetdCompletionResolverWiringTest`, `FleetdLeadSeatWiringTest`, `FleetdConnectionIdentityConstructionTest`, `FleetdHerdrControlConstructionTest`, `FleetdBackendQuarantineWiringTest`, plus this one) — I checked the three not already discussed for any incidental `ConfigRef` mention (`grep -n "ConfigRef"` on each) and found none. So this new test is the only thing pinning this call site. ## Final build `mvn -B clean test`, unpiped, exit code read from the log file: `Tests run: 1634, Failures: 0, Errors: 0, Skipped: 0` — `BUILD SUCCESS` — `EXIT_CODE=0`. ## Files changed - `fleetd/src/test/java/dev/ltms/fleet/FleetdConfigRefWiringTest.java` (new) — only file in this PR. ## Caveats - Could not run the wiki-sync check — `wiki/` is uninitialized in this worker's worktree. - Branch was created fresh from `origin/main` (post-merge, at `4466ee0`) rather than continuing the old `worker/474-charter-check-on-reload-f54a55-17` branch, since that one was already merged; noting this in case the branch name looks unfamiliar. - Scope was exactly this follow-up; nothing else touched, no production code changed.
agent added 1 commit 2026-09-10 15:48:39 +02:00
fleetd #474 follow-up: pin main's config wiring against M2
CI / contract (pull_request) Successful in 1m16s
CI / build (pull_request) Successful in 1m32s
72d6a6878b
Fleetd.main's own choice of the three-argument ConfigRef constructor
(with Fleetd::assertChartersNameOnlyRegisteredTools as extraValidation)
was unpinned. Reverting Fleetd.java:154 to the plain two-argument
constructor compiled with 0 errors and left the whole suite green,
because ConfigRefTest and FleetdConfigRefCharterToolSurfaceWiringTest
each build their own ConfigRef directly rather than through main.

Adds FleetdConfigRefWiringTest, a source-text check on Fleetd.java
following the FleetdBackendQuarantineWiringTest/FleetdLeadSeatWiringTest/
FleetdCompletionResolverWiringTest precedent: asserts the exact
three-argument construction is present, asserts the plain two-argument
form is absent, and guards against a vacuous pass on a broken/empty
source read by first asserting an unrelated anchor is present.
Owner

Merged locally as 49a404d and pushed. git rev-list --count origin/main..HEAD = 0, origin/main = 49a404d. Closing this PR by hand — a local --no-ff merge does not close a Gitea PR.

I re-ran the battery myself on the merge commit, not on your branch. Tree 701bf041fb19c38701a9d8eb4874b7677149053e, load { 3.23 7.02 5.46 }, each cell a full mvn -B clean test, every count read from a file.

CONTROL 0 — the shape

main 3-arg wiring, exact text:   1
new test file present:           1
it reads Fleetd.java:            2   <- my annotation said "must be 1" and was WRONG
vacuity guard, unrelated anchor: 1
positive + negative assertions:  2+1
source-text tests reading Fleetd.java: 7  (was 6)
CONTROL, must be non-zero:       19

The 2 is mine, not yours: the path string src/main/java/dev/ltms/fleet/Fleetd.java legitimately appears twice in your file — once in fleetdSource() and once inside the guard's own assertion message. My expected value was wrong; the cell still stands because every other line is independently checked. That is the third battery in a row where my own "must be N" annotation was wrong and the cell survived only because it had a second proof. Recording it here rather than quietly fixing it.

CONTROL 1 — the unmutated merge

rc=0   surefire summary lines=117
[INFO] Tests run: 1634, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS

M2r — reproduce the survivor

Fleetd.java:154 back to new ConfigRef(configPath, cfg);. Mutation proved applied two ways: 3-arg form left = 0, 2-arg form present = 1.

rc=1   [ERROR] Tests run: 1634, Failures: 1, Errors: 0, Skipped: 0
failed method: FleetdConfigRefWiringTest.mainStillWiresTheThreeArgumentConfigRefConstructor
assertion message: "must still be built from the three-argument"

KILLED, by name, and by the negative assertion. On the previous merge this exact mutation left 1633 green with the live reload gate off. That is the whole point of this PR and it is now closed.

M3v — is the anchor real?

Reflowed the anchored call onto two lines. Same tokens, byte-identical behaviour; only the source text moves. Proved applied two ways: still calls the 3-arg ctor = 1 (behaviour unchanged), one-line form left = 0 (text moved).

rc=1   [ERROR] Tests run: 1634, Failures: 1, Errors: 0, Skipped: 0
failed method: FleetdConfigRefWiringTest.mainStillWiresTheThreeArgumentConfigRefConstructor

Fails loudly. The test is reading the real text, not passing on a scrape that found nothing. Your criterion-3 answer — that a reflow should break it, and you would not add reflow tolerance — is the right call and I am not asking you to change it.

M4g — does the vacuity guard work?

Pointed fleetdSource() at a path that does not exist.

rc=1   [ERROR] Tests run: 1634, Failures: 0, Errors: 1, Skipped: 0
failed method: FleetdConfigRefWiringTest.mainStillWiresTheThreeArgumentConfigRefConstructor
assertion message seen: (empty)

Read this precisely, because the result is not quite what the cell asked for. The test fails loudly and by name, which is what matters — the silent-pass case is closed. But it fails as an Error, not a Failure, and the guard's own message never printed: Files.readString threw NoSuchFileException before any assertion ran. So this cell proves a missing file cannot pass silently. It does not exercise the guard, because the guard only earns its keep when the read succeeds and returns the wrong thing — a truncated file, or a right-shaped file at a wrong path. I am not asking for another test; I am recording that the guard is still unproven against that narrower case, so nobody later reads M4g as proof that it works.

Where this leaves the shape

This is the fifth Fleetd.main call site to survive a battery here (#446 M5/M7, #466 M1, #474 M2) and the pattern is now settled: extracting a check into a well-tested helper moves the untested surface up, into the one line that chooses to call it. Your own read of the two sibling patterns was correct and is the reason this took one small PR instead of a rediscovery — and branching fresh from 4466ee0 rather than reusing the merged branch gave the merge one merge base and an 80-line single-file diff.

Merged locally as `49a404d` and pushed. `git rev-list --count origin/main..HEAD` = 0, `origin/main` = `49a404d`. Closing this PR by hand — a local `--no-ff` merge does not close a Gitea PR. I re-ran the battery myself on the merge commit, not on your branch. Tree `701bf041fb19c38701a9d8eb4874b7677149053e`, load `{ 3.23 7.02 5.46 }`, each cell a full `mvn -B clean test`, every count read from a file. ## CONTROL 0 — the shape ``` main 3-arg wiring, exact text: 1 new test file present: 1 it reads Fleetd.java: 2 <- my annotation said "must be 1" and was WRONG vacuity guard, unrelated anchor: 1 positive + negative assertions: 2+1 source-text tests reading Fleetd.java: 7 (was 6) CONTROL, must be non-zero: 19 ``` The `2` is mine, not yours: the path string `src/main/java/dev/ltms/fleet/Fleetd.java` legitimately appears twice in your file — once in `fleetdSource()` and once inside the guard's own assertion message. My expected value was wrong; the cell still stands because every other line is independently checked. That is the **third battery in a row** where my own "must be N" annotation was wrong and the cell survived only because it had a second proof. Recording it here rather than quietly fixing it. ## CONTROL 1 — the unmutated merge ``` rc=0 surefire summary lines=117 [INFO] Tests run: 1634, Failures: 0, Errors: 0, Skipped: 0 BUILD SUCCESS ``` ## M2r — reproduce the survivor `Fleetd.java:154` back to `new ConfigRef(configPath, cfg);`. Mutation proved applied two ways: 3-arg form left = 0, 2-arg form present = 1. ``` rc=1 [ERROR] Tests run: 1634, Failures: 1, Errors: 0, Skipped: 0 failed method: FleetdConfigRefWiringTest.mainStillWiresTheThreeArgumentConfigRefConstructor assertion message: "must still be built from the three-argument" ``` **KILLED, by name, and by the negative assertion.** On the previous merge this exact mutation left 1633 green with the live reload gate off. That is the whole point of this PR and it is now closed. ## M3v — is the anchor real? Reflowed the anchored call onto two lines. Same tokens, byte-identical behaviour; only the source text moves. Proved applied two ways: still calls the 3-arg ctor = 1 (behaviour unchanged), one-line form left = 0 (text moved). ``` rc=1 [ERROR] Tests run: 1634, Failures: 1, Errors: 0, Skipped: 0 failed method: FleetdConfigRefWiringTest.mainStillWiresTheThreeArgumentConfigRefConstructor ``` Fails loudly. The test is reading the real text, not passing on a scrape that found nothing. Your criterion-3 answer — that a reflow *should* break it, and you would not add reflow tolerance — is the right call and I am not asking you to change it. ## M4g — does the vacuity guard work? Pointed `fleetdSource()` at a path that does not exist. ``` rc=1 [ERROR] Tests run: 1634, Failures: 0, Errors: 1, Skipped: 0 failed method: FleetdConfigRefWiringTest.mainStillWiresTheThreeArgumentConfigRefConstructor assertion message seen: (empty) ``` Read this precisely, because the result is not quite what the cell asked for. The test fails **loudly and by name**, which is what matters — the silent-pass case is closed. But it fails as an **Error**, not a Failure, and the guard's own message never printed: `Files.readString` threw `NoSuchFileException` before any assertion ran. So this cell proves a missing file cannot pass silently. It does **not** exercise the guard, because the guard only earns its keep when the read *succeeds* and returns the wrong thing — a truncated file, or a right-shaped file at a wrong path. I am not asking for another test; I am recording that the guard is still unproven against that narrower case, so nobody later reads M4g as proof that it works. ## Where this leaves the shape This is the fifth `Fleetd.main` call site to survive a battery here (#446 M5/M7, #466 M1, #474 M2) and the pattern is now settled: extracting a check into a well-tested helper moves the untested surface **up**, into the one line that chooses to call it. Your own read of the two sibling patterns was correct and is the reason this took one small PR instead of a rediscovery — and branching fresh from `4466ee0` rather than reusing the merged branch gave the merge one merge base and an 80-line single-file diff.
ltms closed this pull request 2026-09-10 23:15:05 +02:00
Some checks are pending
CI / contract (pull_request) Successful in 1m16s
CI / build (pull_request) Successful in 1m32s

Pull request closed

Sign in to join this conversation.