diff --git a/fleetd/src/test/java/dev/ltms/fleet/FleetdLeadConfigDirSourceAssemblyTest.java b/fleetd/src/test/java/dev/ltms/fleet/FleetdLeadConfigDirSourceAssemblyTest.java
new file mode 100644
index 0000000..07652cf
--- /dev/null
+++ b/fleetd/src/test/java/dev/ltms/fleet/FleetdLeadConfigDirSourceAssemblyTest.java
@@ -0,0 +1,213 @@
+package dev.ltms.fleet;
+
+import dev.ltms.fleet.config.ConfigRef;
+import dev.ltms.fleet.config.FleetConfig;
+import dev.ltms.fleet.guard.SubscriptionGuard;
+import dev.ltms.fleet.herdr.FakeHerdr;
+import dev.ltms.fleet.herdr.HerdrClient;
+import dev.ltms.fleet.mcp.FleetMcp;
+import dev.ltms.fleet.msg.ReplyInbox;
+import io.javalin.Javalin;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import java.lang.reflect.Field;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.function.LongSupplier;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+/**
+ * fleetd #612 Shape A, unit r5 — {@code FleetdAssembly.java:488} wires {@link
+ * FleetMcp.LeadConfigDirSource} with {@code Fleetd.leadConfigDirSource(() -> config.get().profiles(),
+ * leaders)}. {@link FleetdLeadConfigDirSourceWiringTest} already pins that the FACTORY itself
+ * delegates to the real {@link Fleetd#leadConfigDirLookup} — but, by its own javadoc, it "does not
+ * and structurally cannot cover" whether the real call site in {@code FleetdAssembly} still calls
+ * that factory at all. Measured there: swapping that one-line call for a bare {@code
+ * FleetMcp.LeadConfigDirSource.none()} compiles with 0 errors and leaves the full suite green.
+ *
+ *
This is the literal fleetd #602/#606 defect, one call site away from its own fix: {@code main}
+ * (now {@code FleetdAssembly}) used to build {@code LeadConfigDirSource.none()} inline, the whole
+ * suite passed, and the live daemon reported {@code "state":"unknown"} for every lead's context,
+ * forever, with no test noticing. The fix extracted the factory; this test is the one that proves
+ * {@code FleetdAssembly}'s own call site still reaches it.
+ *
+ *
This test drives the REAL {@link FleetMcp} the real {@link FleetdAssembly#assembleAndStart}
+ * builds, reached through {@link FleetdRuntime#mcp()}, and reads the {@code leadConfigDirs} field it
+ * was constructed with via reflection — {@code FleetMcp} exposes no public accessor for it (unlike
+ * {@code quarantineSource()}/{@code leadSeatSource()}), so there is no non-reflective route to the
+ * live instance. The assertion resolves a REAL lead name against a REAL configured {@code
+ * configDir:}: {@link FleetMcp.LeadConfigDirSource#none()} (the historical defect, and the
+ * mis-wire this test's mutation cycles reintroduce) always returns {@code null} regardless of the
+ * input, so a non-null, config-matching answer is a property {@code none()} can never produce by
+ * accident.
+ */
+class FleetdLeadConfigDirSourceAssemblyTest {
+
+ private static final String LEAD_NAME = "opus";
+ private static final String LEAD_TAB = "lead: opus";
+ private static final String LEAD_PROFILE = "sonnet";
+
+ private static final class RecordingResourcePorts implements ResourcePorts {
+
+ final FakeHerdr herdr = new FakeHerdr();
+ final SentinelReplyInbox replyInbox = new SentinelReplyInbox();
+
+ @Override
+ public Map environment() {
+ return Map.of();
+ }
+
+ @Override
+ public HerdrClient connectHerdr(Path socketPath) {
+ return herdr;
+ }
+
+ @Override
+ public Fleetd.AmqpOpener replyInboxOpener() {
+ return (uri, prefetch) -> replyInbox;
+ }
+
+ @Override
+ public Fleetd.LeadMailboxOpener leadMailboxOpener() {
+ return (uri, selfCoordId, prefetch) -> {
+ throw new UnsupportedOperationException(
+ "leadMailboxOpener must not be called — no coordinator: block is configured");
+ };
+ }
+
+ @Override
+ public LongSupplier nanoClock() {
+ return System::nanoTime;
+ }
+
+ @Override
+ public LongSupplier wallClockNanos() {
+ return System::nanoTime;
+ }
+
+ @Override
+ public ScheduledExecutorService newScheduler(String purpose) {
+ return Executors.newSingleThreadScheduledExecutor();
+ }
+
+ @Override
+ public void addShutdownHook(Runnable hook) {
+ }
+
+ @Override
+ public void startHttp(Javalin app, String host, int port) {
+ }
+
+ @Override
+ public Runnable herdrPollWait() {
+ // Never invoked: this test's FakeHerdr answers immediately, so awaitHerdr never polls.
+ return () -> {
+ throw new UnsupportedOperationException("herdrPollWait must not be called — herdr is healthy");
+ };
+ }
+ }
+
+ private static final class SentinelReplyInbox implements ReplyInbox, AutoCloseable {
+ @Override
+ public void own(String target) {
+ }
+
+ @Override
+ public void release(String target) {
+ }
+
+ @Override
+ public void publish(String target, String msgId, String content) {
+ }
+
+ @Override
+ public List peek(String target) {
+ return List.of();
+ }
+
+ @Override
+ public boolean ack(String target, String msgId) {
+ return false;
+ }
+
+ @Override
+ public void close() {
+ }
+ }
+
+ private static FleetConfig writeConfig(Path dir, String configDir) throws Exception {
+ Path f = dir.resolve("fleetd.yaml");
+ Files.writeString(f, """
+ bind:
+ host: 127.0.0.1
+ port: 8765
+ idleSleepGuard:
+ enabled: false
+ broker:
+ uri: "amqp://fake-test-broker/vh"
+ fleet:
+ leaders:
+ %s:
+ tab: "%s"
+ profile: %s
+ profiles:
+ %s:
+ subscription: true
+ argv: ["ccs", "sonnet"]
+ configDir: "%s"
+ """.formatted(LEAD_NAME, LEAD_TAB, LEAD_PROFILE, LEAD_PROFILE, configDir));
+ return FleetConfig.load(f);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static FleetMcp.LeadConfigDirSource leadConfigDirSourceOf(FleetMcp mcp) throws Exception {
+ Field field = FleetMcp.class.getDeclaredField("leadConfigDirs");
+ field.setAccessible(true);
+ return (FleetMcp.LeadConfigDirSource) field.get(mcp);
+ }
+
+ @Test
+ @DisplayName("[BEHAVIOURAL] the real assembled LeadConfigDirSource resolves a lead's REAL "
+ + "configured configDir, not the none() stand-in's hardcoded null")
+ void assembledLeadConfigDirSourceResolvesTheRealConfiguredConfigDir(@TempDir Path dir) throws Exception {
+ String configuredConfigDir = "/mnt/fake-lead-configdir";
+ FleetConfig cfg = writeConfig(dir, configuredConfigDir);
+ ConfigRef config = new ConfigRef(dir.resolve("fleetd.yaml"), cfg);
+ SubscriptionGuard guard = new SubscriptionGuard(cfg.guard().hostSet());
+ RecordingResourcePorts ports = new RecordingResourcePorts();
+ // Label FakeHerdr's own default pane's tab (term_a / w2:p7 / w2:t7, already carrying a live
+ // agent) to match fleet.leaders.opus.tab exactly, so LeadLauncher.ensureLeads() sees the
+ // lead as already live and does not try to auto-launch a second one.
+ ports.herdr.withTab("w2", "w2:t7", LEAD_TAB);
+
+ FleetdRuntime runtime = FleetdAssembly.assembleAndStart(new AssemblyInputs(cfg, config, guard), ports);
+ try {
+ FleetMcp.LeadConfigDirSource source = leadConfigDirSourceOf(runtime.mcp());
+
+ assertEquals(configuredConfigDir, source.configDirFor().apply(LEAD_NAME),
+ "fleet.leaders." + LEAD_NAME + ".profile (" + LEAD_PROFILE + ") configures "
+ + "configDir: " + configuredConfigDir + " — the real assembled source must "
+ + "resolve it. FleetMcp.LeadConfigDirSource.none() (the inert stand-in "
+ + "this test's mutation cycles swap the call site for, and the historical "
+ + "fleetd #602/#606 defect) always reports null here, whatever the input");
+
+ // A lead name the config does not recognise still resolves to null, not a crash — the
+ // same source, applied to an input that must stay at the inert answer even on the real,
+ // non-inert instance.
+ assertNull(source.configDirFor().apply("no-such-lead"));
+ } finally {
+ // Surefire runs the whole suite in one JVM fork (fleetd/pom.xml sets no forkCount /
+ // reuseForks), so the scheduler/loops this assembly starts must be torn down here, on the
+ // failure path too — hence try/finally rather than a bare statement at the end.
+ runtime.close();
+ }
+ }
+}