diff --git a/fleetd/src/main/java/dev/ltms/fleet/auth/MemberRegistry.java b/fleetd/src/main/java/dev/ltms/fleet/auth/MemberRegistry.java index 3007842..5adb19e 100644 --- a/fleetd/src/main/java/dev/ltms/fleet/auth/MemberRegistry.java +++ b/fleetd/src/main/java/dev/ltms/fleet/auth/MemberRegistry.java @@ -177,7 +177,15 @@ public final class MemberRegistry implements MemberLifecycle { } /** - * The strong-model profile a slot runs under — what the spawn lifecycle reads. + * The strong-model profile a slot runs under, as of this call. + * + *
Nothing in {@code src/main} calls this (fleetd #431 — grepped both the {@code + * .profileForSlot(} and the {@code ::profileForSlot} form). This javadoc used to say "what the + * spawn lifecycle reads", and that seam does not exist: the spawn lifecycle takes its profile + * from the {@link MemberLifecycle.SlotReservation} that {@code reserve} returns, never from + * here. Kept and pinned rather than deleted because it is the natural accessor for that seam + * if one is added; live for the same reason as {@link #roleForSlot}, so a reload cannot leave + * it answering for the old config. * * @return the slot's configured {@code profile}, or {@code null} if the slot is unknown or * declares none diff --git a/fleetd/src/test/java/dev/ltms/fleet/auth/MemberRegistryLiveTest.java b/fleetd/src/test/java/dev/ltms/fleet/auth/MemberRegistryLiveTest.java index fde51aa..5ca1904 100644 --- a/fleetd/src/test/java/dev/ltms/fleet/auth/MemberRegistryLiveTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/auth/MemberRegistryLiveTest.java @@ -174,10 +174,16 @@ class MemberRegistryLiveTest { // ── profileForSlot, isSlot and nameForSlot are live too (fleetd #431) ───────────────────────── // #424 pinned roleForSlot against a live reload but left these three untested — proved by // mutating each to read a snapshot flattened once at construction: the full suite stayed green - // for all three. profileForSlot is the one with a real production stake: the spawn lifecycle - // reads it to pick an architect slot's backend, and fleetd has no call site for it yet (grepped - // "profileForSlot" across src/main — only this file and MemberRegistryTest reference it), so - // there is no seam to drive this test through beyond the accessor itself. + // for all three. + // + // The three differ in how much production behaviour depends on them, and the ticket first got + // this ranking wrong. nameForSlot is wired: CallerResolver passes members::nameForSlot, next to + // members::roleForSlot. isSlot is reached through bind, which calls it to refuse an unknown + // slot. profileForSlot has NO caller in src/main at all — grepped both the ".profileForSlot(" + // and the "::profileForSlot" form — so there is no seam to drive its test through beyond the + // accessor itself, and its own javadoc ("what the spawn lifecycle reads") describes a caller + // that does not exist. These tests pin the accessors as they are; whether profileForSlot should + // be wired or deleted is a separate question. @Test void profileForSlotReflectsAProfileChangedByReload(@TempDir Path dir) throws Exception { @@ -194,8 +200,7 @@ class MemberRegistryLiveTest { assertTrue(out.applied(), "the reload must actually take effect: " + out.summary()); assertEquals("opus", registry.profileForSlot("architect:designer"), - "repointing the slot to a different profile must take effect with no restart — " - + "this is what the spawn lifecycle reads to pick an architect's backend"); + "repointing the slot to a different profile must take effect with no restart"); } @Test