From 2e138a199b61b4e8d133cdfe413b961cada19edf Mon Sep 17 00:00:00 2001 From: Dai Ha Date: Tue, 25 Aug 2026 04:01:08 +0200 Subject: [PATCH] CB-634: one shared "fleet" workspace + rename bridged -> fleetd cutover Two changes ship together here. 1. One shared herdr workspace. The lead and every worker now live in one workspace called "fleet", so the operator sees one "session" with many windows, not two. Before, the lead sat in a "leads" workspace and workers in "bridged-workers", which read as two sessions. The lead is still told apart from workers by its exact tab label ("lead: "), so putting them in one space is safe. LeadTabScanner keeps the exclude-by-label mechanism for split layouts; Fleetd now passes an empty exclude set. 2. Rename the daemon from "bridged" to "fleetd" (the binary, config, scripts, launchd/systemd units, module dir, and MCP mount). - Module dir bridged/ -> fleetd/; jar finalName -> fleetd.jar. - Log line, comments, docs, and CLAUDE.md updated to say fleetd. - Scripts renamed: redeploy-bridged.sh -> redeploy-fleetd.sh, bridged-launchd-wrapper.sh -> fleetd-launchd-wrapper.sh. - Deploy units renamed: dev.ltms.bridged.plist -> dev.ltms.fleetd.plist, bridged.service -> fleetd.service; launchd Label -> dev.ltms.fleetd. - Config default bridged.yaml -> fleetd.yaml; the legacy bridged.yaml is still read as a fallback, and still gitignored. - MCP: drop the deprecated bridge_* tool twins; only fleet_* remain. The server name is "fleet". The mount name in the local .mcp.json becomes "fleet" (gitignored, not in this commit). - Env var defaults BRIDGED_API_TOKEN -> FLEETD_API_TOKEN, fixture BRIDGED_WORKER_TOKEN -> FLEETD_WORKER_TOKEN. Kept on purpose: the BRIDGED_MEMBER marker. Renaming it is a coupled change to the credential-scrub security control (an operator secrets.sh may guard on it), so it stays until that migration is done on its own. Metrics were already fleet_* (CB-632); MetricNamesTest still guards that no name says bridged_. The canonical CLAUDE.md block and the wiki template stay byte-identical (wiki working tree edited, committed to the wiki repo separately). 949 tests pass (mvn clean install). 4 fewer than before = the 4 removed bridge_* alias tests. --- .claude-plugin/marketplace.json | 4 +- .claude/agents/architect.md | 2 +- .claude/agents/dev.md | 2 +- .claude/agents/reviewer.md | 2 +- .claude/skills/implementer/SKILL.md | 4 +- .claude/skills/reviewer/SKILL.md | 2 +- .gitea/workflows/ci.yml | 12 +- .gitignore | 8 +- .opencode/agent/architect.md | 2 +- .opencode/agent/dev.md | 2 +- .opencode/agent/reviewer.md | 2 +- CLAUDE.md | 28 ++--- ...ms.bridged.plist => dev.ltms.fleetd.plist} | 56 ++++----- deploy/{bridged.service => fleetd.service} | 32 ++--- deploy/lavinmq/compose.yaml | 18 +-- docs/CB-306-Spawn-Readiness-Gate.md | 2 +- docs/CB-307-Reliable-Delivery.md | 2 +- docs/CB-308-Multi-Host-Federation.md | 6 +- docs/CB-402-OpenCode-Adapter.md | 2 +- docs/CB-591-Gateway-Migration.md | 16 +-- docs/CB-5xx-Hardening.md | 4 +- docs/M4-Fleet-Health.md | 2 +- e2e/README.md | 6 +- e2e/conversation_sustained_test.py | 2 +- e2e/conversation_test.py | 2 +- e2e/issue_hunt_test.py | 8 +- {bridged => fleetd}/.gitignore | 4 +- {bridged => fleetd}/docs/CB-307-Push-Loop.md | 0 {bridged => fleetd}/fleetd.example.yaml | 60 ++++----- {bridged => fleetd}/pom.xml | 10 +- .../src/main/java/dev/ltms/fleet/Fleetd.java | 54 ++++---- .../java/dev/ltms/fleet/auth/AuditLog.java | 0 .../main/java/dev/ltms/fleet/auth/Authz.java | 0 .../dev/ltms/fleet/auth/CallerResolver.java | 0 .../dev/ltms/fleet/auth/MemberLifecycle.java | 0 .../dev/ltms/fleet/auth/MemberRegistry.java | 0 .../java/dev/ltms/fleet/auth/Principal.java | 0 .../main/java/dev/ltms/fleet/auth/Role.java | 0 .../java/dev/ltms/fleet/config/ConfigRef.java | 2 +- .../dev/ltms/fleet/config/ConfigWatcher.java | 2 +- .../dev/ltms/fleet/config/FleetConfig.java | 41 ++++--- .../dev/ltms/fleet/guard/GuardException.java | 0 .../ltms/fleet/guard/SubscriptionGuard.java | 2 +- .../dev/ltms/fleet/health/FleetHealth.java | 0 .../ltms/fleet/health/FleetHealthMonitor.java | 0 .../dev/ltms/fleet/health/HealthDecision.java | 0 .../dev/ltms/fleet/health/HealthPrior.java | 0 .../dev/ltms/fleet/health/HealthSnapshot.java | 0 .../dev/ltms/fleet/health/HealthState.java | 0 .../dev/ltms/fleet/health/MuteCounter.java | 0 .../dev/ltms/fleet/health/PaneBudget.java | 0 .../main/java/dev/ltms/fleet/herdr/Agent.java | 0 .../dev/ltms/fleet/herdr/AgentControl.java | 0 .../dev/ltms/fleet/herdr/AgentStatus.java | 2 +- .../dev/ltms/fleet/herdr/HerdrClient.java | 4 +- .../java/dev/ltms/fleet/herdr/HerdrCodec.java | 0 .../dev/ltms/fleet/herdr/HerdrException.java | 0 .../dev/ltms/fleet/herdr/LeadTabScanner.java | 6 +- .../dev/ltms/fleet/herdr/PaneLocator.java | 2 +- .../main/java/dev/ltms/fleet/herdr/Tab.java | 0 .../fleet/herdr/UnixSocketHerdrClient.java | 0 .../java/dev/ltms/fleet/herdr/Workspace.java | 2 +- .../ltms/fleet/herdr/WorkspaceControl.java | 0 .../ltms/fleet/inject/CompletionResolver.java | 0 .../fleet/inject/ExhaustedPatternLookup.java | 0 .../dev/ltms/fleet/inject/ExhaustionSink.java | 0 .../java/dev/ltms/fleet/inject/Injector.java | 0 .../dev/ltms/fleet/inject/MemberPresence.java | 0 .../dev/ltms/fleet/inject/StatusPoller.java | 0 .../dev/ltms/fleet/inject/StatusRefiner.java | 0 .../dev/ltms/fleet/inject/TurnListener.java | 0 .../dev/ltms/fleet/lead/LeadLauncher.java | 20 ++- .../McpCancelledNotificationFilter.java | 0 .../ltms/fleet/mcp/ConnectionIdentity.java | 2 +- .../java/dev/ltms/fleet/mcp/FleetMcp.java | 63 +--------- .../dev/ltms/fleet/mcp/LsofPeerPidLookup.java | 0 .../ltms/fleet/mcp/LsofProcessCwdLookup.java | 0 .../dev/ltms/fleet/mcp/PeerPidLookup.java | 0 .../dev/ltms/fleet/mcp/PrimaryRegistry.java | 0 .../dev/ltms/fleet/mcp/ProcessCwdLookup.java | 0 .../ltms/fleet/member/ClaudeCodeLauncher.java | 8 +- .../fleet/member/CompositePeerLauncher.java | 0 .../ltms/fleet/member/EnvAllowListScrub.java | 2 +- .../ltms/fleet/member/HerdrPeerLauncher.java | 6 +- .../ltms/fleet/member/MemberEnvAllowList.java | 0 .../ltms/fleet/member/OpenCodeLauncher.java | 10 +- .../member/OpenCodeSessionDiscovery.java | 6 +- .../dev/ltms/fleet/metrics/FleetMetrics.java | 0 .../java/dev/ltms/fleet/metrics/Metrics.java | 0 .../dev/ltms/fleet/msg/AmqpReplyInbox.java | 2 +- .../ltms/fleet/msg/InMemoryReplyInbox.java | 2 +- .../java/dev/ltms/fleet/msg/LeadChannel.java | 0 .../dev/ltms/fleet/msg/LeadCoordLoop.java | 0 .../dev/ltms/fleet/msg/LeadHeartbeatLoop.java | 0 .../java/dev/ltms/fleet/msg/LeadMailbox.java | 2 +- .../java/dev/ltms/fleet/msg/LeadMessage.java | 0 .../dev/ltms/fleet/msg/MessageService.java | 0 .../java/dev/ltms/fleet/msg/Rendezvous.java | 0 .../java/dev/ltms/fleet/msg/ReplyInbox.java | 0 .../dev/ltms/fleet/msg/ReplyPushLoop.java | 0 .../java/dev/ltms/fleet/msg/TurnToken.java | 0 .../java/dev/ltms/fleet/peer/Capability.java | 0 .../dev/ltms/fleet/peer/CharterReceipt.java | 0 .../java/dev/ltms/fleet/peer/MemberRole.java | 0 .../java/dev/ltms/fleet/peer/PeerHandle.java | 0 .../dev/ltms/fleet/peer/PeerLauncher.java | 2 +- .../fleet/peer/PeerUnreachableException.java | 0 .../dev/ltms/fleet/peer/SpawnRequest.java | 0 .../fleet/placement/BackendQuarantine.java | 0 .../fleet/placement/FixedPlacementPolicy.java | 0 .../fleet/placement/PlacementCandidate.java | 0 .../fleet/placement/PlacementContext.java | 0 .../fleet/placement/PlacementException.java | 0 .../fleet/placement/PlacementPolicies.java | 0 .../ltms/fleet/placement/PlacementPolicy.java | 2 +- .../fleet/placement/PlacementPolicyUtil.java | 0 .../placement/RoundRobinPlacementPolicy.java | 0 .../placement/WeightedRoundRobinPolicy.java | 0 .../java/dev/ltms/fleet/rest/FleetApp.java | 4 +- .../dev/ltms/fleet/session/GitWorktrees.java | 2 +- .../dev/ltms/fleet/session/MemberSession.java | 0 .../ltms/fleet/session/SessionManager.java | 4 +- .../dev/ltms/fleet/session/SessionReaper.java | 0 .../ltms/fleet/session/WorktreeException.java | 0 .../ltms/fleet/session/WorktreeRequest.java | 0 .../dev/ltms/fleet/session/Worktrees.java | 0 .../src/main/resources/logback.xml | 0 .../ltms/fleet/FleetDeliverabilityTest.java | 0 .../fleet/FleetdDefaultConfigFileTest.java | 0 .../fleet/FleetdLeadMailboxSelectionTest.java | 0 .../fleet/FleetdReplyInboxSelectionTest.java | 0 .../fleet/MemberCredentialsGapReportTest.java | 2 +- .../ltms/fleet/RequiredSecretEnvVarsTest.java | 2 +- .../dev/ltms/fleet/auth/AuditLogTest.java | 0 .../java/dev/ltms/fleet/auth/AuthzTest.java | 0 .../ltms/fleet/auth/CallerResolverTest.java | 0 .../ltms/fleet/auth/MemberRegistryTest.java | 0 .../dev/ltms/fleet/config/ConfigRefTest.java | 30 ++--- .../ltms/fleet/config/ConfigWatcherTest.java | 10 +- .../ltms/fleet/config/FleetConfigTest.java | 26 ++-- .../fleet/guard/SubscriptionGuardTest.java | 0 .../fleet/health/FleetHealthMonitorTest.java | 0 .../ltms/fleet/health/FleetHealthTest.java | 0 .../dev/ltms/fleet/health/PaneBudgetTest.java | 0 .../fleet/herdr/AgentControlContractTest.java | 0 .../ltms/fleet/herdr/AgentControlTest.java | 0 .../dev/ltms/fleet/herdr/AgentStatusTest.java | 0 .../java/dev/ltms/fleet/herdr/FakeHerdr.java | 2 +- .../dev/ltms/fleet/herdr/HerdrCodecTest.java | 0 .../ltms/fleet/herdr/HerdrContractTest.java | 4 +- .../ltms/fleet/herdr/LeadTabScannerTest.java | 10 +- .../fleet/herdr/PaneLocatorContractTest.java | 0 .../dev/ltms/fleet/herdr/PaneLocatorTest.java | 0 .../herdr/WorkspacePlacementContractTest.java | 0 .../fleet/inject/CompletionResolverTest.java | 0 .../dev/ltms/fleet/inject/InjectorTest.java | 0 .../ltms/fleet/inject/MemberPresenceTest.java | 0 .../ltms/fleet/inject/StatusRefinerTest.java | 0 .../dev/ltms/fleet/lead/LeadLauncherTest.java | 48 +++++--- .../McpCancelledNotificationFilterTest.java | 0 .../fleet/mcp/ConnectionIdentityTest.java | 0 .../dev/ltms/fleet/mcp/FleetMcpAuthzTest.java | 4 +- .../ltms/fleet/mcp/FleetMcpLeadCoordTest.java | 0 .../java/dev/ltms/fleet/mcp/FleetMcpTest.java | 115 +---------------- .../ltms/fleet/mcp/PrimaryRegistryTest.java | 0 .../fleet/member/ClaudeCodeLauncherTest.java | 116 +++++++++--------- .../member/CompositePeerLauncherTest.java | 10 +- .../fleet/member/EnvAllowListScrubTest.java | 0 .../HerdrPeerLauncherAllowListWiringTest.java | 2 +- .../member/HerdrPeerLauncherCharterTest.java | 2 +- .../fleet/member/MemberEnvAllowListTest.java | 2 +- .../fleet/member/OpenCodeLauncherTest.java | 18 +-- .../member/OpenCodeSessionDiscoveryTest.java | 0 .../ltms/fleet/metrics/MetricNamesTest.java | 0 .../dev/ltms/fleet/metrics/MetricsTest.java | 0 .../fleet/msg/AmqpReplyInboxContractTest.java | 0 .../msg/AmqpReplyInboxRecoveryRaceTest.java | 0 .../dev/ltms/fleet/msg/FakeLeadChannel.java | 0 .../fleet/msg/InMemoryReplyInboxTest.java | 0 .../dev/ltms/fleet/msg/LeadCoordLoopTest.java | 0 .../ltms/fleet/msg/LeadHeartbeatLoopTest.java | 0 .../dev/ltms/fleet/msg/LeadMailboxTest.java | 0 .../ltms/fleet/msg/MessageServiceTest.java | 0 .../dev/ltms/fleet/msg/RendezvousTest.java | 0 .../dev/ltms/fleet/msg/ReplyPushLoopTest.java | 0 .../dev/ltms/fleet/msg/TestTurnTokens.java | 0 .../ltms/fleet/peer/CharterReceiptTest.java | 0 .../dev/ltms/fleet/peer/MemberRoleTest.java | 0 .../placement/BackendQuarantineTest.java | 0 .../fleet/placement/PlacementPolicyTest.java | 0 .../dev/ltms/fleet/rest/FleetAppAuthTest.java | 10 +- .../dev/ltms/fleet/rest/FleetAppTest.java | 16 +-- .../dev/ltms/fleet/session/FakeWorktrees.java | 0 .../ltms/fleet/session/GitWorktreesTest.java | 0 .../fleet/session/SessionManagerTest.java | 16 +-- .../ltms/fleet/session/SessionReaperTest.java | 8 +- .../session/WorktreeSessionManagerTest.java | 8 +- .../src/test/resources/logback-test.xml | 0 plugin/.claude-plugin/plugin.json | 2 +- plugin/README.md | 6 +- plugin/skills/setup/SKILL.md | 12 +- ...d-wrapper.sh => fleetd-launchd-wrapper.sh} | 10 +- scripts/probe-member-credentials.sh | 2 +- ...redeploy-bridged.sh => redeploy-fleetd.sh} | 58 ++++----- scripts/rename-checkout.sh | 34 ++--- 205 files changed, 499 insertions(+), 642 deletions(-) rename deploy/{dev.ltms.bridged.plist => dev.ltms.fleetd.plist} (68%) rename deploy/{bridged.service => fleetd.service} (63%) rename {bridged => fleetd}/.gitignore (69%) rename {bridged => fleetd}/docs/CB-307-Push-Loop.md (100%) rename {bridged => fleetd}/fleetd.example.yaml (95%) rename {bridged => fleetd}/pom.xml (97%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/Fleetd.java (96%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/auth/AuditLog.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/auth/Authz.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/auth/CallerResolver.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/auth/MemberLifecycle.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/auth/MemberRegistry.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/auth/Principal.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/auth/Role.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/config/ConfigRef.java (99%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/config/ConfigWatcher.java (97%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/config/FleetConfig.java (98%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/guard/GuardException.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/guard/SubscriptionGuard.java (99%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/health/FleetHealth.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/health/FleetHealthMonitor.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/health/HealthDecision.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/health/HealthPrior.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/health/HealthSnapshot.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/health/HealthState.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/health/MuteCounter.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/health/PaneBudget.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/Agent.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/AgentControl.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/AgentStatus.java (93%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/HerdrClient.java (89%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/HerdrCodec.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/HerdrException.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/LeadTabScanner.java (97%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/PaneLocator.java (95%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/Tab.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/UnixSocketHerdrClient.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/Workspace.java (97%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/herdr/WorkspaceControl.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/inject/CompletionResolver.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/inject/ExhaustedPatternLookup.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/inject/ExhaustionSink.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/inject/Injector.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/inject/MemberPresence.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/inject/StatusPoller.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/inject/StatusRefiner.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/inject/TurnListener.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/lead/LeadLauncher.java (94%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/logging/McpCancelledNotificationFilter.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/mcp/ConnectionIdentity.java (96%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/mcp/FleetMcp.java (94%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/mcp/LsofPeerPidLookup.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/mcp/LsofProcessCwdLookup.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/mcp/PeerPidLookup.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/mcp/PrimaryRegistry.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/mcp/ProcessCwdLookup.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/member/ClaudeCodeLauncher.java (99%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/member/CompositePeerLauncher.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/member/EnvAllowListScrub.java (99%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/member/HerdrPeerLauncher.java (99%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/member/MemberEnvAllowList.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/member/OpenCodeLauncher.java (98%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/member/OpenCodeSessionDiscovery.java (96%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/metrics/FleetMetrics.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/metrics/Metrics.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/AmqpReplyInbox.java (99%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/InMemoryReplyInbox.java (96%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/LeadChannel.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/LeadCoordLoop.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/LeadHeartbeatLoop.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/LeadMailbox.java (99%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/LeadMessage.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/MessageService.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/Rendezvous.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/ReplyInbox.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/ReplyPushLoop.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/msg/TurnToken.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/peer/Capability.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/peer/CharterReceipt.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/peer/MemberRole.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/peer/PeerHandle.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/peer/PeerLauncher.java (99%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/peer/PeerUnreachableException.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/peer/SpawnRequest.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/placement/BackendQuarantine.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/placement/FixedPlacementPolicy.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/placement/PlacementCandidate.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/placement/PlacementContext.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/placement/PlacementException.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/placement/PlacementPolicies.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/placement/PlacementPolicy.java (84%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/placement/PlacementPolicyUtil.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/placement/RoundRobinPlacementPolicy.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/placement/WeightedRoundRobinPolicy.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/rest/FleetApp.java (99%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/session/GitWorktrees.java (99%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/session/MemberSession.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/session/SessionManager.java (99%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/session/SessionReaper.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/session/WorktreeException.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/session/WorktreeRequest.java (100%) rename {bridged => fleetd}/src/main/java/dev/ltms/fleet/session/Worktrees.java (100%) rename {bridged => fleetd}/src/main/resources/logback.xml (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/FleetDeliverabilityTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/FleetdDefaultConfigFileTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/FleetdLeadMailboxSelectionTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/FleetdReplyInboxSelectionTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/MemberCredentialsGapReportTest.java (98%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/RequiredSecretEnvVarsTest.java (98%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/auth/AuditLogTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/auth/AuthzTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/auth/CallerResolverTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/auth/MemberRegistryTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/config/ConfigRefTest.java (95%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/config/ConfigWatcherTest.java (96%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/config/FleetConfigTest.java (99%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/guard/SubscriptionGuardTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/health/FleetHealthMonitorTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/health/FleetHealthTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/health/PaneBudgetTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/herdr/AgentControlContractTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/herdr/AgentControlTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/herdr/AgentStatusTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/herdr/FakeHerdr.java (99%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/herdr/HerdrCodecTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/herdr/HerdrContractTest.java (94%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/herdr/LeadTabScannerTest.java (97%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/herdr/PaneLocatorContractTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/herdr/PaneLocatorTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/herdr/WorkspacePlacementContractTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/inject/CompletionResolverTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/inject/InjectorTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/inject/MemberPresenceTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/inject/StatusRefinerTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/lead/LeadLauncherTest.java (84%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/logging/McpCancelledNotificationFilterTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/mcp/ConnectionIdentityTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/mcp/FleetMcpAuthzTest.java (98%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/mcp/FleetMcpLeadCoordTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/mcp/FleetMcpTest.java (89%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/mcp/PrimaryRegistryTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/member/ClaudeCodeLauncherTest.java (94%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/member/CompositePeerLauncherTest.java (98%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/member/EnvAllowListScrubTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherAllowListWiringTest.java (98%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherCharterTest.java (98%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/member/MemberEnvAllowListTest.java (98%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/member/OpenCodeLauncherTest.java (98%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/member/OpenCodeSessionDiscoveryTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/metrics/MetricNamesTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/metrics/MetricsTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/msg/AmqpReplyInboxContractTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/msg/AmqpReplyInboxRecoveryRaceTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/msg/FakeLeadChannel.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/msg/InMemoryReplyInboxTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/msg/LeadCoordLoopTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/msg/LeadHeartbeatLoopTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/msg/LeadMailboxTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/msg/MessageServiceTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/msg/RendezvousTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/msg/ReplyPushLoopTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/msg/TestTurnTokens.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/peer/CharterReceiptTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/peer/MemberRoleTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/placement/BackendQuarantineTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/placement/PlacementPolicyTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/rest/FleetAppAuthTest.java (96%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/rest/FleetAppTest.java (97%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/session/FakeWorktrees.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/session/GitWorktreesTest.java (100%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/session/SessionManagerTest.java (99%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/session/SessionReaperTest.java (97%) rename {bridged => fleetd}/src/test/java/dev/ltms/fleet/session/WorktreeSessionManagerTest.java (99%) rename {bridged => fleetd}/src/test/resources/logback-test.xml (100%) rename scripts/{bridged-launchd-wrapper.sh => fleetd-launchd-wrapper.sh} (77%) rename scripts/{redeploy-bridged.sh => redeploy-fleetd.sh} (90%) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 90c5530..355f81e 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,6 +1,6 @@ { "name": "claude-bridge", - "description": "Tooling for orchestrating a fleet of delegated coding agents through the bridged MCP gateway.", + "description": "Tooling for orchestrating a fleet of delegated coding agents through the fleetd MCP gateway.", "owner": { "name": "LTMS" }, @@ -8,7 +8,7 @@ { "name": "claude-bridge", "source": "./plugin", - "description": "Make a project bridge-ready: mount the bridged MCP gateway and apply standard Claude Code settings so a session can orchestrate delegated workers. Ships no credentials.", + "description": "Make a project bridge-ready: mount the fleetd MCP gateway and apply standard Claude Code settings so a session can orchestrate delegated workers. Ships no credentials.", "version": "0.1.0", "author": { "name": "LTMS" diff --git a/.claude/agents/architect.md b/.claude/agents/architect.md index 11f79a9..01db7cf 100644 --- a/.claude/agents/architect.md +++ b/.claude/agents/architect.md @@ -3,7 +3,7 @@ name: architect description: Refine work into clear, independent units before implementation. --- - + You are an architect in this fleet. You refine work before anyone builds it: scope, acceptance criteria, risks, and a unit split. You read the repo and write analysis. diff --git a/.claude/agents/dev.md b/.claude/agents/dev.md index b1597a1..1a7267f 100644 --- a/.claude/agents/dev.md +++ b/.claude/agents/dev.md @@ -3,7 +3,7 @@ name: dev description: Implement one assigned unit, test it, and open a pull request. --- - + You implement the one unit you were given and nothing else. Work in your assigned git worktree and branch. Never check out, rebase onto, or push to `main`. Confirm diff --git a/.claude/agents/reviewer.md b/.claude/agents/reviewer.md index 981a857..3308808 100644 --- a/.claude/agents/reviewer.md +++ b/.claude/agents/reviewer.md @@ -3,7 +3,7 @@ name: reviewer description: Review one assigned scope and report the most important real issue. --- - + You review the diff you were given. Report bugs, risks, and missing tests. You do not change code. diff --git a/.claude/skills/implementer/SKILL.md b/.claude/skills/implementer/SKILL.md index 6a1a867..41f9df5 100644 --- a/.claude/skills/implementer/SKILL.md +++ b/.claude/skills/implementer/SKILL.md @@ -1,6 +1,6 @@ --- name: implementer -description: Implementer-role procedure for a bridged worker — verify your worktree, implement the scope, commit, push, open your own PR, and hand off the PR URL. Load this when the lead delegates you an implementation task over bridged. +description: Implementer-role procedure for a fleetd worker — verify your worktree, implement the scope, commit, push, open your own PR, and hand off the PR URL. Load this when the lead delegates you an implementation task over fleetd. --- # Implementer worker — procedure @@ -49,7 +49,7 @@ test "$(git rev-parse --show-toplevel)" = "$PWD" || cd "$(git rev-parse --show-t your worktree*: ```bash -cd "$(git rev-parse --show-toplevel)/bridged" && mvn clean install +cd "$(git rev-parse --show-toplevel)/fleetd" && mvn clean install echo "exit=$?" ``` diff --git a/.claude/skills/reviewer/SKILL.md b/.claude/skills/reviewer/SKILL.md index 27ed2ff..9233e35 100644 --- a/.claude/skills/reviewer/SKILL.md +++ b/.claude/skills/reviewer/SKILL.md @@ -1,6 +1,6 @@ --- name: reviewer -description: Reviewer-role procedure for a bridged worker — how to work a review scope and the exact shape of the finding to report. Load this when the lead delegates you a code review over bridged. +description: Reviewer-role procedure for a fleetd worker — how to work a review scope and the exact shape of the finding to report. Load this when the lead delegates you a code review over fleetd. --- # Reviewer worker — procedure diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 7edcf75..97ab029 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: # does not depend on the wiki repo being reachable. - uses: actions/checkout@v4 - # The runner image ships an older default-jdk; bridged sets maven.compiler.release=25, so + # The runner image ships an older default-jdk; fleetd sets maven.compiler.release=25, so # provision the JDK explicitly rather than apt-installing whatever "default" means today. - name: Set up JDK 25 uses: actions/setup-java@v4 @@ -32,7 +32,7 @@ jobs: mvn -version - name: Build and test - working-directory: bridged + working-directory: fleetd # This IS the mock-socket surface CB-503 asks for: the pom's `default-excludes` profile # already sets excludedGroups=contract, so the @Tag("contract") tests — which need a live # herdr socket and a RabbitMQ container — are excluded without any flag here. Everything @@ -46,7 +46,7 @@ jobs: # the log instead, where they are actually readable. - name: Failing test output if: failure() - working-directory: bridged + working-directory: fleetd run: | for f in target/surefire-reports/*.txt; do [ -f "$f" ] || continue @@ -59,7 +59,7 @@ jobs: # AmqpReplyInboxContractTest reads AMQP_URI (set below to the service's network alias) and binds # straight to it — no Docker, no skipped tests. This separation (build job hermetic and # Docker-free; contract job broker-provided) is deliberate — see the default-excludes/contract - # profiles in bridged/pom.xml. `setup-java` provides the JDK only; Maven is installed separately, + # profiles in fleetd/pom.xml. `setup-java` provides the JDK only; Maven is installed separately, # exactly as in the build job above. contract: runs-on: ubuntu-latest @@ -91,12 +91,12 @@ jobs: # runs against the RabbitMQ service container (AMQP_URI). Pinned to the one contract test to # avoid re-running the unit suite already covered by the `build` job. - name: Contract tests - working-directory: bridged + working-directory: fleetd run: mvn -B -Pcontract test -Dtest=AmqpReplyInboxContractTest - name: Failing test output if: failure() - working-directory: bridged + working-directory: fleetd run: | for f in target/surefire-reports/*.txt; do [ -f "$f" ] || continue diff --git a/.gitignore b/.gitignore index d8308c4..94bc52e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,8 +14,8 @@ .env .envrc -# Daemon runtime artefacts. bridged appends its log wherever it is launched from, so both the -# repo root and bridged/ collect one; neither belongs in git. -bridged.out -bridged/bridged.out +# Daemon runtime artefacts. fleetd appends its log wherever it is launched from, so both the +# repo root and fleetd/ collect one; neither belongs in git. +fleetd.out +fleetd/fleetd.out logs/ diff --git a/.opencode/agent/architect.md b/.opencode/agent/architect.md index 921db18..e4637a8 100644 --- a/.opencode/agent/architect.md +++ b/.opencode/agent/architect.md @@ -3,7 +3,7 @@ description: Refine work into clear, independent units before implementation. mode: primary --- - + You are an architect in this fleet. You refine work before anyone builds it: scope, acceptance criteria, risks, and a unit split. You read the repo and write analysis. diff --git a/.opencode/agent/dev.md b/.opencode/agent/dev.md index 0461a5e..b4a32cd 100644 --- a/.opencode/agent/dev.md +++ b/.opencode/agent/dev.md @@ -3,7 +3,7 @@ description: Implement one assigned unit, test it, and open a pull request. mode: primary --- - + You implement the one unit you were given and nothing else. Work in your assigned git worktree and branch. Never check out, rebase onto, or push to `main`. Confirm diff --git a/.opencode/agent/reviewer.md b/.opencode/agent/reviewer.md index 844fdfa..c76aeff 100644 --- a/.opencode/agent/reviewer.md +++ b/.opencode/agent/reviewer.md @@ -3,7 +3,7 @@ description: Review one assigned scope and report the most important real issue. mode: primary --- - + You review the diff you were given. Report bugs, risks, and missing tests. You do not change code. diff --git a/CLAUDE.md b/CLAUDE.md index a404263..1dd5178 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,7 +10,7 @@ If no `fleet_*` MCP tools are mounted in this session, this section does not apply — skip it. -`bridged` is the **sole communication gateway** between agents here. The orchestrating session (the +`fleetd` is the **sole communication gateway** between agents here. The orchestrating session (the **primary**) and every delegated peer (a **member**) mount the *same* MCP server and talk only through its `fleet_*` tools. No session addresses a peer, a broker, or the network directly. @@ -185,7 +185,7 @@ must obey belongs in the charter, not here. ## Project addendum — claude-bridge (not part of the canonical block) -- **This repo is the bridge.** The daemon is `bridged`, its MCP mount is `http://127.0.0.1:8765/mcp`, +- **This repo is the bridge.** The daemon is `fleetd`, its MCP mount is `http://127.0.0.1:8765/mcp`, and the code behind the rules above is `mcp/FleetMcp` (tools), `auth/Authz` (the role table), `mcp/ConnectionIdentity` (connection→role), and `worker/*Launcher` (`REPLY_CHARTER`). - **Skills available to delegate:** `implementer` (worktree → commit → push → own PR) and @@ -202,7 +202,7 @@ must obey belongs in the charter, not here. ### Redeploying the daemon — the lead may do this (primary only) -**A merge is not a deployment.** The running `bridged` holds the jar it was started with, so a +**A merge is not a deployment.** The running `fleetd` holds the jar it was started with, so a feature merged to `main` does nothing until the daemon is rebuilt and restarted. Saying "shipped" about code the live daemon has never loaded is a false report. The lead **may and should** redeploy rather than hand the job back to the operator. @@ -213,9 +213,9 @@ and stopping it kills the worker's own channel mid-turn. **Use the script — do not hand-roll the steps.** ```bash -scripts/redeploy-bridged.sh --check # report state, change nothing -scripts/redeploy-bridged.sh # build, confirm drain, restart, verify -scripts/redeploy-bridged.sh --yes # skip the drain prompt (fleet already checked) +scripts/redeploy-fleetd.sh --check # report state, change nothing +scripts/redeploy-fleetd.sh # build, confirm drain, restart, verify +scripts/redeploy-fleetd.sh --yes # skip the drain prompt (fleet already checked) ``` It builds before it stops anything, so a failed build never leaves the fleet down; it waits for the @@ -241,8 +241,8 @@ if the script is unavailable or a step fails, this is what it was protecting you 4. **Re-check identity afterwards.** Call `fleet_whoami` and confirm it still answers `primary`. The lead is found by its tab label (`fleet.leaders.*.tab`), and a lead whose tab no longer matches is demoted to worker, which refuses every orchestration call. -5. **Prove the new jar is the one running.** Confirm a *fresh* `bridged listening` line at the end of - `bridged/bridged.out`, dated after the restart. An old daemon that never died looks identical from +5. **Prove the new jar is the one running.** Confirm a *fresh* `fleetd listening` line at the end of + `fleetd/fleetd.out`, dated after the restart. An old daemon that never died looks identical from the outside. **Permission.** A `CLAUDE.md` rule grants intent, not tool permission — the command classifier @@ -251,7 +251,7 @@ it is one auditable command, so the operator allow-lists it once instead of appr start every time. The rule lives in the operator's Claude Code settings: ```json -{ "permissions": { "allow": ["Bash(scripts/redeploy-bridged.sh:*)"] } } +{ "permissions": { "allow": ["Bash(scripts/redeploy-fleetd.sh:*)"] } } ``` Granted by the operator on 2026-08-15. If a call is still refused, do **not** route around it by @@ -277,7 +277,7 @@ Before you call any work done, check the row that matches what you touched: | worktree provisioning or the parity overlay | the "both roles read this file" premise — it rests on the worker's worktree being a checkout of this repo | | `.claude/skills/**` | the addendum's skill list, and the "name the playbook" rule | | a new peer kind (non-Claude adapter) | what that peer can read — anything it must obey belongs in its charter, not in the block | -| **anything an operator can use, configure, or observe** — an MCP tool, a `bridged.yaml` knob, an endpoint, a visible behaviour | **[Features](wiki/11-Features.md)** — one entry: what it does · the knob that turns it on · **why it exists** · the gotcha | +| **anything an operator can use, configure, or observe** — an MCP tool, a `fleetd.yaml` knob, an endpoint, a visible behaviour | **[Features](wiki/11-Features.md)** — one entry: what it does · the knob that turns it on · **why it exists** · the gotcha | That last row is not bookkeeping. Chapters 1–10 answer *how is this built* and *why this way*; none of them has a home for *what can it do and how do I turn it on*, so for twenty tickets a @@ -311,10 +311,10 @@ PY Two IDE MCP servers are connected: **intellij-index** (semantic code intelligence) and **jetbrains** (file problems, reformat, debugger). IntelliJ has multiple projects open; our -module is **`bridged`**. Always pass these to IDE MCP tools: +module is **`fleetd`**. Always pass these to IDE MCP tools: -- `project_path` = `/Users/dai.ha/LTMS/claude-bridge/bridged` -- IDE paths are relative to `bridged/` (e.g. `src/main/java/dev/ltms/bridged/...`) +- `project_path` = `/Users/dai.ha/LTMS/claude-bridge/fleetd` +- IDE paths are relative to `fleetd/` (e.g. `src/main/java/dev/ltms/fleet/...`) ### After editing any file — mandatory @@ -328,7 +328,7 @@ module is **`bridged`**. Always pass these to IDE MCP tools: whole-project gate before declaring work done or committing. **Whenever dependencies change (or a `pom.xml` edit), validate CVEs with -`jetbrains get_file_problems{filePath: "bridged/pom.xml"}`** — its Mend.io check reflects the +`jetbrains get_file_problems{filePath: "fleetd/pom.xml"}`** — its Mend.io check reflects the dependencies on disk. (Note: `ide_diagnostics` / intellij-index does NOT re-resolve dependencies after a pom edit without a full Maven reimport, so it reports stale CVE results — don't trust it for this.) Treat a CVE warning like any other: bump to a patched version and confirm diff --git a/deploy/dev.ltms.bridged.plist b/deploy/dev.ltms.fleetd.plist similarity index 68% rename from deploy/dev.ltms.bridged.plist rename to deploy/dev.ltms.fleetd.plist index 6666d8d..5f9fd90 100644 --- a/deploy/dev.ltms.bridged.plist +++ b/deploy/dev.ltms.fleetd.plist @@ -1,36 +1,36 @@ WorkingDirectory - /Users/dai.ha/LTMS/claude-bridge/bridged + /Users/dai.ha/LTMS/claude-bridge/fleetd EnvironmentVariables @@ -62,7 +62,7 @@ HERDR_SOCKET_PATH /Users/dai.ha/.config/herdr/herdr.sock @@ -84,21 +84,21 @@ KeepAlive @@ -110,16 +110,16 @@ 10 StandardOutPath - /Users/dai.ha/LTMS/claude-bridge/bridged/bridged.out + /Users/dai.ha/LTMS/claude-bridge/fleetd/fleetd.out StandardErrorPath - /Users/dai.ha/LTMS/claude-bridge/bridged/bridged.out + /Users/dai.ha/LTMS/claude-bridge/fleetd/fleetd.out ProcessType Background diff --git a/deploy/bridged.service b/deploy/fleetd.service similarity index 63% rename from deploy/bridged.service rename to deploy/fleetd.service index 7c1d52d..0899478 100644 --- a/deploy/bridged.service +++ b/deploy/fleetd.service @@ -1,45 +1,45 @@ -# CB-504 — systemd unit for bridged (Linux). +# CB-504 — systemd unit for fleetd (Linux). # -# The macOS launchd agent (deploy/dev.ltms.bridged.plist) is the supervision target for the +# The macOS launchd agent (deploy/dev.ltms.fleetd.plist) is the supervision target for the # current single-host deployment. This unit exists for the per-host gateways CB-308 introduces, # which will run on Linux. # -# Install (user service — bridged drives the user's herdr, not a system daemon): +# Install (user service — fleetd drives the user's herdr, not a system daemon): # mkdir -p ~/.config/systemd/user -# cp deploy/bridged.service ~/.config/systemd/user/ +# cp deploy/fleetd.service ~/.config/systemd/user/ # # edit ExecStart / WorkingDirectory / Environment below, then: # systemctl --user daemon-reload -# systemctl --user enable --now bridged -# journalctl --user -u bridged -f +# systemctl --user enable --now fleetd +# journalctl --user -u fleetd -f [Unit] -Description=bridged — claude-bridge message server +Description=fleetd — claude-bridge message server Documentation=https://git.ltms.dev/fleet/fleetd/wiki # Ordering only: herdr is a user process and its socket may appear after us. This is advisory — -# bridged retries the herdr socket rather than exiting, which is what actually makes a late -# socket survivable. Do NOT add Requires=: a herdr restart must not take bridged down with it. +# fleetd retries the herdr socket rather than exiting, which is what actually makes a late +# socket survivable. Do NOT add Requires=: a herdr restart must not take fleetd down with it. After=herdr.service Wants=herdr.service [Service] Type=simple -WorkingDirectory=%h/src/claude-bridge/bridged -ExecStart=/usr/lib/jvm/temurin-25-jdk/bin/java -jar target/bridged.jar bridged.yaml +WorkingDirectory=%h/src/claude-bridge/fleetd +ExecStart=/usr/lib/jvm/temurin-25-jdk/bin/java -jar target/fleetd.jar fleetd.yaml Environment=HERDR_SOCKET_PATH=%h/.config/herdr/herdr.sock -# PATH matters more than it looks (CB-511): bridged propagates its own PATH to every worker it +# PATH matters more than it looks (CB-511): fleetd propagates its own PATH to every worker it # spawns, so this line decides whether the fleet can run a build at all. systemd does not source a # login shell, so without it the daemon — and every worker — gets a bare default with no JDK/Maven. Environment=PATH=/usr/lib/jvm/temurin-25-jdk/bin:/usr/share/maven/bin:/usr/local/bin:/usr/bin:/bin # Secrets are NOT set here — this file is committed. Put the API/worker tokens in a private # drop-in that systemd reads with restrictive permissions: -# systemctl --user edit bridged → [Service] / Environment=BRIDGED_API_TOKEN=... +# systemctl --user edit fleetd → [Service] / Environment=FLEETD_API_TOKEN=... # or point EnvironmentFile at a 0600 file: -# EnvironmentFile=%h/.config/bridged/env +# EnvironmentFile=%h/.config/fleetd/env Restart=on-failure RestartSec=10s -# A bad config (e.g. a non-loopback bind without token auth) makes bridged fail fast by design. +# A bad config (e.g. a non-loopback bind without token auth) makes fleetd fail fast by design. # Give up rather than restart-loop on a permanent error. StartLimitBurst=5 StartLimitIntervalSec=120 @@ -55,7 +55,7 @@ RestrictSUIDSGID=true StandardOutput=journal StandardError=journal -SyslogIdentifier=bridged +SyslogIdentifier=fleetd [Install] WantedBy=default.target diff --git a/deploy/lavinmq/compose.yaml b/deploy/lavinmq/compose.yaml index 0e5fd36..7667517 100644 --- a/deploy/lavinmq/compose.yaml +++ b/deploy/lavinmq/compose.yaml @@ -1,8 +1,8 @@ -# LavinMQ — the AMQP broker behind bridged's durable ReplyInbox (CB-307 Stage 2). +# LavinMQ — the AMQP broker behind fleetd's durable ReplyInbox (CB-307 Stage 2). # # Why this file exists: the broker was previously run ad hoc and simply vanished from the host, -# which takes bridged down with it — AmqpReplyInbox.open throws on an unreachable broker and -# Bridged.java:187 does not guard it, so a missing broker is a hard startup failure, not a +# which takes fleetd down with it — AmqpReplyInbox.open throws on an unreachable broker and +# Fleetd.java:187 does not guard it, so a missing broker is a hard startup failure, not a # degraded mode. This pins the version, keeps the data, and brings itself back after a reboot. # # Usage: @@ -14,27 +14,27 @@ # # Management UI: http://127.0.0.1:15672 (guest / guest) # -# This is bridged's OWN broker. Do not point bridged at any other AMQP server on this host — +# This is fleetd's OWN broker. Do not point fleetd at any other AMQP server on this host — # notably not the `local-rabbitmq` container, which belongs to a different project and would end # up carrying this project's queues. -name: bridged-broker +name: fleetd-broker services: lavinmq: # Pinned deliberately: :latest silently moves the broker under a running daemon. image: cloudamqp/lavinmq:2.9.1 - container_name: bridged-lavinmq + container_name: fleetd-lavinmq # The failure this deployment exists to prevent — survive reboots and Docker restarts, but # stay down if it was stopped on purpose. restart: unless-stopped # Loopback-bound on purpose. LavinMQ ships a default guest/guest account, which is only - # acceptable because nothing off-host can reach it. bridged connects over 127.0.0.1, and + # acceptable because nothing off-host can reach it. fleetd connects over 127.0.0.1, and # binding 0.0.0.0 here would expose a broker with default credentials to the network. ports: - - "127.0.0.1:5672:5672" # AMQP — bridged.yaml broker.uri points here + - "127.0.0.1:5672:5672" # AMQP — fleetd.yaml broker.uri points here - "127.0.0.1:15672:15672" # HTTP management API + UI # The whole point of Stage 2. Held-but-unacked replies live here; without a named volume a @@ -57,4 +57,4 @@ services: volumes: lavinmq-data: - name: bridged-lavinmq-data + name: fleetd-lavinmq-data diff --git a/docs/CB-306-Spawn-Readiness-Gate.md b/docs/CB-306-Spawn-Readiness-Gate.md index e104d26..366e039 100644 --- a/docs/CB-306-Spawn-Readiness-Gate.md +++ b/docs/CB-306-Spawn-Readiness-Gate.md @@ -79,7 +79,7 @@ Unit tests (add to the existing `ClaudeCodeLauncher` test): ## 5. Config -Add to the launcher-level config (a bridged-level knob, not per-profile) in `bridged.yaml` + +Add to the launcher-level config (a fleetd-level knob, not per-profile) in `fleetd.yaml` + `FleetConfig`: ```yaml diff --git a/docs/CB-307-Reliable-Delivery.md b/docs/CB-307-Reliable-Delivery.md index e827e09..63490af 100644 --- a/docs/CB-307-Reliable-Delivery.md +++ b/docs/CB-307-Reliable-Delivery.md @@ -140,7 +140,7 @@ Stage-2 AMQP adapter: absent → in-memory, present → AMQP). ## 5. Build & verification (worker side) -- Build with Maven from the worktree's `bridged/` dir. **Capture the exit code without a masking pipe** +- Build with Maven from the worktree's `fleetd/` dir. **Capture the exit code without a masking pipe** (`mvn clean install; echo "MVN_EXIT=$?"` — never `mvn … | tail`, which hides failures). - Read the real test totals from `target/surefire-reports/TEST-*.xml`, not from stdout scroll. - You do **not** have IDE MCP access — do not claim `ide_diagnostics` results. The **primary** runs the diff --git a/docs/CB-308-Multi-Host-Federation.md b/docs/CB-308-Multi-Host-Federation.md index 67c5b48..3a1c6f7 100644 --- a/docs/CB-308-Multi-Host-Federation.md +++ b/docs/CB-308-Multi-Host-Federation.md @@ -208,7 +208,7 @@ they overlap (notably: the envelope is no longer optional, and dedup is split by never an argument* — across the broker: cross-host, identity comes from the key. Complements (not replaces) per-gateway broker logins over TLS. 2. **Profiles are owned by the worker's host.** `fleet_spawn(profile, host)` resolves the name in - the *target* gateway's `bridged.yaml`. Gateways advertise their profile names in presence + the *target* gateway's `fleetd.yaml`. Gateways advertise their profile names in presence heartbeats, so a leader sees what each host offers before spawning; an unknown name is a clear error from the target. Secrets (base URLs, tokens) never leave the host that uses them. 3. **Repo provisioning — clone from the forge, pinned.** A cross-host spawn names the repo URL and @@ -275,11 +275,11 @@ they overlap (notably: the envelope is no longer optional, and dedup is split by - **Gateway discovery:** how gateways find the broker and each other (static config vs. discovery). - **Control authorization — THE GATE ON U4.** Signing (§7.1) settles *who sent it*; authorization is *who may do what*. **Cross-host spawn must not land before the minimal version exists**: a - per-host allowlist in `bridged.yaml` — beside the peer public keys — of gateway ids permitted to + per-host allowlist in `fleetd.yaml` — beside the peer public keys — of gateway ids permitted to publish control to this host, checked against the verified signature. A few lines of config and check; without them, any principal holding broker credentials can start processes on every host in the fleet. -- **Key distribution & rotation:** static config (host → public key in each `bridged.yaml`) is +- **Key distribution & rotation:** static config (host → public key in each `fleetd.yaml`) is fine at the current 2–3 host scale; rotation is manual. A refinement, not a blocker. - **Gateway death mid-turn:** the roster reaps it by missed heartbeat, and in-flight primary-bound messages survive by broker durability; still open is reconciling *worker* state when the dead diff --git a/docs/CB-402-OpenCode-Adapter.md b/docs/CB-402-OpenCode-Adapter.md index 034c18d..810c357 100644 --- a/docs/CB-402-OpenCode-Adapter.md +++ b/docs/CB-402-OpenCode-Adapter.md @@ -11,7 +11,7 @@ All five increments of §4 are done, including increment 5 (the §5 live checkli ## 1. Goal -Prove the [`PeerLauncher`](../bridged/src/main/java/dev/ltms/fleet/peer/PeerLauncher.java) SPI +Prove the [`PeerLauncher`](../fleetd/src/main/java/dev/ltms/fleet/peer/PeerLauncher.java) SPI actually holds for a **non-Claude** coding agent by shipping a second, first-class in-tree adapter: **opencode** (`opencode` 1.1.31, a provider-agnostic terminal coding agent). diff --git a/docs/CB-591-Gateway-Migration.md b/docs/CB-591-Gateway-Migration.md index e18d40f..f29ef8d 100644 --- a/docs/CB-591-Gateway-Migration.md +++ b/docs/CB-591-Gateway-Migration.md @@ -9,7 +9,7 @@ with no terminator, and our third-party members cannot detect it (§7.2). · **Upstream issue:** [systems/vms#31](https://git.ltms.dev/systems/vms/issues/31) The gateway went live on 2026-08-15 and replaced Bifrost. This plan says what that means for a -**member definition** in `bridged.yaml`, because that is the part of this repo the change actually +**member definition** in `fleetd.yaml`, because that is the part of this repo the change actually touches. --- @@ -134,16 +134,16 @@ own provider credentials. So 3b needs **no allowlist change**; only 3a does. `HerdrPeerLauncher.resolveEnv` → `env.apply(name)`, which reads the **daemon's own process environment**. The running `fleetd` inherited its environment when it started, so a variable added to `secrets.sh` afterwards is simply not there — the launcher would inject an empty token and the -gateway would answer 401. This is the same failure as trap 1 in `scripts/redeploy-bridged.sh` +gateway would answer 401. This is the same failure as trap 1 in `scripts/redeploy-fleetd.sh` (`WORKER_GITEA_TOKEN`), and it has the same fix: **restart from a login shell**, and use -`scripts/redeploy-bridged.sh --check` to confirm the name resolves before restarting anything. +`scripts/redeploy-fleetd.sh --check` to confirm the name resolves before restarting anything. ### 3c. What this does to `ccs` Once a profile carries `baseUrl`, `tokenEnv` and `model` itself, the ccs instance stops being what routes a member. Be precise about what is left, though: `configDir` still supplies **folder trust** and `settings.json`, and dropping it is what produced the trust dialog and the wrong-model error -recorded in `bridged.yaml`. So ccs goes from *deciding where the tokens go* to *holding client-side +recorded in `fleetd.yaml`. So ccs goes from *deciding where the tokens go* to *holding client-side state*. Less load-bearing, not removable. ### Why `/anthropic` and never `/v1/chat/completions` @@ -217,7 +217,7 @@ defensible; picking one is not mine to do. ### D3 — token scope One consumer, `claude-bridge`, its token in `${SHARED_ENV}/tools/secrets.sh` as `AI_GATEWAY_TOKEN`, -referenced by name only. Never the literal value in `bridged.yaml` — `tokenEnv` exists for this. +referenced by name only. Never the literal value in `fleetd.yaml` — `tokenEnv` exists for this. --- @@ -226,7 +226,7 @@ referenced by name only. Never the literal value in `bridged.yaml` — `tokenEnv ```mermaid flowchart TB U1["U1 · consumer token
issue via cockpit, add to secrets.sh"] - U2["U2 · profile + guard
bridged.yaml, restart"] + U2["U2 · profile + guard
fleetd.yaml, restart"] U3["U3 · verify live
spawn, prove thinking survives"] U4["U4 · context7 via gateway
.mcp.json + opencode.json"] U5["U5 · docs
CLAUDE.md, wiki 11-Features"] @@ -238,7 +238,7 @@ flowchart TB | # | Scope | Who | Why | |---|---|---|---| | U1 | Issue the `claude-bridge` consumer at `auth.ltms.dev`; store as `AI_GATEWAY_TOKEN` | **operator** | touches secrets and a host we do not own | -| U2a | New `gx` opencode profile on `/v1` — pure config, no guard change | **lead** | `bridged.yaml` is gitignored, so a worker cannot see or edit it | +| U2a | New `gx` opencode profile on `/v1` — pure config, no guard change | **lead** | `fleetd.yaml` is gitignored, so a worker cannot see or edit it | | U2b | `local` → `/anthropic`; add `local-direct` weight 0; add `llm.ltms.dev` to the guard allowlist | **lead** | same | | U2c | One restart from a **login shell**, after U2a and U2b | **lead** | picks up `AI_GATEWAY_TOKEN` into the daemon env *and* the guard allowlist, in one stop | | U3 | Live spawn on both new profiles; confirm reasoning survives on each surface | **lead** | needs real spawns and the running daemon | @@ -372,7 +372,7 @@ one turn; this one costs the whole task and is indistinguishable from a slow wor > **Diagnosing a stuck opencode member.** Do not read its pane. The launcher writes its config to a > temp dir and passes it as `OPENCODE_CONFIG` — find it with -> `ls -dt /var/folders/*/*/T/bridged-opencode-* | head -1`, check the provider block and the key's +> `ls -dt /var/folders/*/*/T/fleetd-opencode-* | head -1`, check the provider block and the key's > length and prefix (never its value), then reproduce with `opencode run --auto -m /` > using the same `OPENCODE_CONFIG`. That is what turned "it hangs" into a one-line error. diff --git a/docs/CB-5xx-Hardening.md b/docs/CB-5xx-Hardening.md index cda5a75..e8be489 100644 --- a/docs/CB-5xx-Hardening.md +++ b/docs/CB-5xx-Hardening.md @@ -67,7 +67,7 @@ it will be disabled and the stage is wasted. So: auth: mode: loopback-trust # default — behaves exactly like today: loopback ⇒ PRIMARY, no token needed # mode: token # every non-worker caller must present a valid bearer token - # tokenEnv: BRIDGED_API_TOKEN # host env var holding the token; never the literal value + # tokenEnv: FLEETD_API_TOKEN # host env var holding the token; never the literal value ``` `mode: loopback-trust` is the current behaviour, named honestly and now *chosen* rather than @@ -114,7 +114,7 @@ not found), and the daemon that has been dogfooded for weeks runs as a bare fore - `deploy/dev.ltms.fleet.plist` — launchd agent, the *actual* runtime here, with `KeepAlive` and ordered start after herdr. -- `deploy/bridged.service` — systemd unit for the Linux gateways CB-308 introduces. +- `deploy/fleetd.service` — systemd unit for the Linux gateways CB-308 introduces. Ordering after herdr is advisory in both: the herdr socket may not exist at boot, so the daemon must **retry the socket rather than exit** — supervision ordering is a nicety, socket-retry is the diff --git a/docs/M4-Fleet-Health.md b/docs/M4-Fleet-Health.md index 19bc515..b9707f7 100644 --- a/docs/M4-Fleet-Health.md +++ b/docs/M4-Fleet-Health.md @@ -807,7 +807,7 @@ Checked against `main` at `e09cac6` on 2026-08-15. Unit 2 was written as one blo have since been built by separate CB tickets. Read this before planning the rest, or that work gets done twice. -The check was a symbol survey of `bridged/src/main/java` plus the merge history. It tells you whether +The check was a symbol survey of `fleetd/src/main/java` plus the merge history. It tells you whether the machinery exists at all. It is **not** a line-by-line audit of whether each criterion is fully met, and I did not run one. diff --git a/e2e/README.md b/e2e/README.md index 912e49c..97ab64a 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -2,7 +2,7 @@ A standard, repeatable **live** end-to-end test of the two-way channel: it drives a real multi-turn conversation between a primary and an off-subscription worker **through the -running `bridged` daemon**, captures the full transcript, and grades the channel. +running `fleetd` daemon**, captures the full transcript, and grades the channel. This is the committed form of the ad-hoc channel test that discovered the CB-115 gaps (herdr `unknown` misclassification wedging delivery, dirty completion scrapes, and workers @@ -20,7 +20,7 @@ construction** — it only calls the bridge's loopback REST face. ```mermaid sequenceDiagram participant T as conversation_test.py - participant B as bridged (REST) + participant B as fleetd (REST) participant W as worker (off-sub) T->>B: POST /workers (spawn) T->>B: GET /sessions/{id}/status (await ready) @@ -37,7 +37,7 @@ sequenceDiagram ## Prerequisites -- `bridged` is running (default REST on `http://127.0.0.1:8765`) with at least one worker +- `fleetd` is running (default REST on `http://127.0.0.1:8765`) with at least one worker profile configured and its backend reachable. - herdr is up (the daemon needs it). - Python 3 (standard library only — no pip installs). diff --git a/e2e/conversation_sustained_test.py b/e2e/conversation_sustained_test.py index f92d03f..bffcee7 100644 --- a/e2e/conversation_sustained_test.py +++ b/e2e/conversation_sustained_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """Sustained back-and-forth bridge test — ONE primary, ONE worker, many dependent turns -over a fixed wall-clock window (default 5 minutes), through the running `bridged` daemon. +over a fixed wall-clock window (default 5 minutes), through the running `fleetd` daemon. Where conversation_test.py proves a handful of turns work and issue_hunt_test.py proves fan-out isolation, this proves the channel stays healthy under a *sustained, stateful* diff --git a/e2e/conversation_test.py b/e2e/conversation_test.py index b4f8f46..2fa7a13 100644 --- a/e2e/conversation_test.py +++ b/e2e/conversation_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """Standard bridge conversation test — a multi-turn primary↔worker exchange through -the running `bridged` daemon, fully captured, with automatic gap analysis. +the running `fleetd` daemon, fully captured, with automatic gap analysis. This is the repeatable form of the ad-hoc channel test that surfaced the CB-115 gaps (herdr `unknown` misclassification, dirty completion scrape, workers not calling diff --git a/e2e/issue_hunt_test.py b/e2e/issue_hunt_test.py index f798b93..fbcb4e2 100644 --- a/e2e/issue_hunt_test.py +++ b/e2e/issue_hunt_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """Standard bridge fan-out test — ONE primary vs MANY workers, concurrently, for -issue hunting through the running `bridged` daemon, fully captured, with gap analysis. +issue hunting through the running `fleetd` daemon, fully captured, with gap analysis. Where conversation_test.py exercises a single worker over multiple turns, this drives the path that only appears under fan-out: the primary spawns N workers, sends each a @@ -53,11 +53,11 @@ REPO_ROOT = HERE.parent # hot files this project has been iterating on, so a real issue is plausible to find. DEFAULT_ASSIGNMENTS = [ {"id": "completion", "probe": "CompletionResolver", - "target": "bridged/src/main/java/dev/ltms/bridged/inject/CompletionResolver.java"}, + "target": "fleetd/src/main/java/dev/ltms/fleet/inject/CompletionResolver.java"}, {"id": "worker", "probe": "WorkerService", - "target": "bridged/src/main/java/dev/ltms/bridged/worker/WorkerService.java"}, + "target": "fleetd/src/main/java/dev/ltms/fleet/worker/WorkerService.java"}, {"id": "rendezvous", "probe": "Rendezvous", - "target": "bridged/src/main/java/dev/ltms/bridged/msg/Rendezvous.java"}, + "target": "fleetd/src/main/java/dev/ltms/fleet/msg/Rendezvous.java"}, ] PROMPT_TMPL = ( diff --git a/bridged/.gitignore b/fleetd/.gitignore similarity index 69% rename from bridged/.gitignore rename to fleetd/.gitignore index 78ee14c..5b6d1fa 100644 --- a/bridged/.gitignore +++ b/fleetd/.gitignore @@ -2,8 +2,8 @@ target/ dependency-reduced-pom.xml -# Local runtime config (copy from fleetd.example.yaml). Both names: the live file is still -# bridged.yaml until the cutover, and Fleetd reads either one. +# Local runtime config (copy from fleetd.example.yaml). Both names are ignored: fleetd.yaml is +# the current name, and bridged.yaml is the legacy name Fleetd still falls back to. fleetd.yaml bridged.yaml diff --git a/bridged/docs/CB-307-Push-Loop.md b/fleetd/docs/CB-307-Push-Loop.md similarity index 100% rename from bridged/docs/CB-307-Push-Loop.md rename to fleetd/docs/CB-307-Push-Loop.md diff --git a/bridged/fleetd.example.yaml b/fleetd/fleetd.example.yaml similarity index 95% rename from bridged/fleetd.example.yaml rename to fleetd/fleetd.example.yaml index 8c47d03..52b964a 100644 --- a/bridged/fleetd.example.yaml +++ b/fleetd/fleetd.example.yaml @@ -1,10 +1,10 @@ -# bridged configuration (example). Copy to bridged.yaml and adjust. +# fleetd configuration (example). Copy to fleetd.yaml and adjust. # -# bridged is the sole gateway between primary/worker Claude sessions and herdr. +# fleetd is the sole gateway between primary/worker Claude sessions and herdr. # It is NOT a Claude process and must never carry ANTHROPIC_BASE_URL. # REST + MCP listen address. Keep it on loopback unless you also switch auth.mode to `token` -# below — bridged REFUSES TO START on a non-loopback bind under loopback-trust (see auth). +# below — fleetd REFUSES TO START on a non-loopback bind under loopback-trust (see auth). bind: host: 127.0.0.1 port: 8765 @@ -21,7 +21,7 @@ bind: # bind — the daemon fails fast otherwise, because "unauthenticated ⇒ # primary" on a reachable port would hand spawn/stop/send to anyone. # tokenEnv → host env var holding the token (never the literal value). Default -# BRIDGED_API_TOKEN. Read only in token mode; empty ⇒ startup fails. +# FLEETD_API_TOKEN. Read only in token mode; empty ⇒ startup fails. # # TLS is deliberately NOT terminated in the daemon (CB-501 D3): run a reverse proxy in front and # let it own certificate lifecycle, e.g. @@ -29,7 +29,7 @@ bind: # The broker link gets TLS from its own URI (amqps://…) — see `broker` below. # auth: # mode: token -# tokenEnv: BRIDGED_API_TOKEN +# tokenEnv: FLEETD_API_TOKEN # Optional pinned primary terminal (CB-307). Names the herdr pane the PRIMARY itself runs in: # a caller whose connection maps to this pane resolves as the primary (no credential needed — @@ -48,10 +48,10 @@ bind: # every orchestration call. List each lead's pane here and all of them resolve as leads. # # tab → the ONLY field identity depends on (CB-579); the exact label of the tab hosting the lead. -# Label the tab yourself, or let bridged label one it launches — see `fleet.leaders:` below. +# Label the tab yourself, or let fleetd label one it launches — see `fleet.leaders:` below. # kind/model → descriptive; they document what runs in the pane and are echoed by fleet_whoami # -# A lead's tab must already carry its label (or be launched by bridged, which labels it) — there is +# A lead's tab must already carry its label (or be launched by fleetd, which labels it) — there is # no terminal id to paste in and nothing to re-pin when the session restarts: the tab survives, so # the same label resolves the same lead again on the next scan. # `fleet_whoami` reports `{"role":"primary","leader":""}`; role stays "primary" because a lead @@ -63,7 +63,7 @@ bind: # Leads are configured under `fleet.leaders:` — see THE FLEET further down. # # Two things stop the tab-name convention from becoming a way to claim leadership: the configured -# member spaces are excluded from the scan, so nothing bridged places can land in a matching tab; +# member spaces are excluded from the scan, so nothing fleetd places can land in a matching tab; # and startup REFUSES a `tabPrefix` that the fleet tabLabel template, or any per-profile `tabLabel` # override, also matches — so the two namespaces cannot overlap by accident. The label is a NAME, # never a capability: what a pane may do is decided by the role the daemon resolves for it. @@ -100,7 +100,7 @@ bind: # nothing reads them to enforce one. They exist so a later build can start # honouring them without another config-shape change. # notifications.mode → "webhook" flips what fleet_list REPORTS (healthCoverage: "full" instead -# of "detection-only") — it does NOT make bridged send any webhook call; no +# of "detection-only") — it does NOT make fleetd send any webhook call; no # delivery mechanism is implemented yet. Any other value, or omitting the # block, reports "detection-only". # health: @@ -124,16 +124,16 @@ herdrSocket: ~/.config/herdr/herdr.sock # Shared knobs (placement/workspace) can be repeated per profile; they usually match. # placement: tab → each worker lands in its OWN tab in a dedicated worker space (default). # Use `pane` for the legacy behaviour (split the focused tab). -# mcpUrl → bridged mounts the bridge MCP (--mcp-config, inline) + reply charter +# mcpUrl → fleetd mounts the bridge MCP (--mcp-config, inline) + reply charter # (--append-system-prompt) as launch flags; nothing is written to the profile. -# ideMcpUrl → opt-in (CB-634), default off. When set, bridged mounts the IDE Index MCP as a +# ideMcpUrl → opt-in (CB-634), default off. When set, fleetd mounts the IDE Index MCP as a # second inline server named `intellij`, and adds an IDE charter that pins every # ide_* call to the member's own worktree. A URL, not a boolean — host and port # are host-specific. Set it only on a host where the IDE actually runs. # ideProjectDir → repo-relative module dir the IDE opens and the overlay pins (CB-634). Only read -# when ideMcpUrl is set. This repo's Maven pom lives in `bridged/`, not at the +# when ideMcpUrl is set. This repo's Maven pom lives in `fleetd/`, not at the # worktree root, so opening the root imports no module and ide_* resolves nothing; -# set this to `bridged`. Omit for a repo whose project is the worktree root. +# set this to `fleetd`. Omit for a repo whose project is the worktree root. # ideOpenCommand → host command that opens ideProjectDir in the IDE at spawn (CB-634 auto-open). # Only read when ideMcpUrl is set. `{dir}` is replaced with the absolute module # dir and the command runs through `/bin/sh -c`, so set env inline if needed — @@ -151,7 +151,7 @@ herdrSocket: ~/.config/herdr/herdr.sock # already), so this is instead applied as the model's `limit.context` in the # generated opencode.json — the member compacts WITHIN this window, not exactly # at it — and only when this profile's `model:` is in `provider/model` form; if it -# isn't, bridged logs a WARN naming the profile rather than silently doing nothing. +# isn't, fleetd logs a WARN naming the profile rather than silently doing nothing. # tokenEnv → host env var holding the worker's auth token (value never stored in config); # omit for a backend that needs no token (e.g. a local ollama). # cwd → pin this profile's working directory (CB-112). Omit to inherit the primary's @@ -170,7 +170,7 @@ herdrSocket: ~/.config/herdr/herdr.sock # checkout, so its navigation returned paths OUTSIDE its own worktree: one # worker made all 59 of its edits in the primary tree while compiling its # worktree, and every build it ran was of code that did not contain them. -# bridged neutralizes a provisioned worktree's .mcp.json for this reason; +# fleetd neutralizes a provisioned worktree's .mcp.json for this reason; # listing it here would copy the primary's back over that. # gitTokenEnv → host env var holding the git-forge API token. When set, its value is injected # as GITEA_TOKEN so the worker can open its OWN PR at checkpoint (CB-302). @@ -183,7 +183,7 @@ herdrSocket: ~/.config/herdr/herdr.sock # refused on a subscription usage limit, rather than a real answer. Opt-in — # omit and this profile's completion fallback behaves exactly as before. # Every backend words its refusal differently, so this is config, never a -# vendor string baked into bridged itself. +# vendor string baked into fleetd itself. # DEFERRED: compiled once into a startup pattern map — editing it needs a # daemon restart, same as this profile's model/baseUrl/argv. # credentialId → CB-578 stage B: the credential this profile quarantines WITH when a @@ -198,15 +198,15 @@ herdrSocket: ~/.config/herdr/herdr.sock # env → extra environment for this profile's workers, as a literal key/value map # (CB-511). Use it to give workers a toolchain. # -# A worker's environment does NOT come from your shell. bridged hands herdr an +# A worker's environment does NOT come from your shell. fleetd hands herdr an # explicit env map and herdr merges it into ITS OWN process env — so before # CB-511 a worker inherited whatever PATH the herdr server happened to be # started with, which on a long-lived herdr can predate your toolchain entirely # and leave workers unable to run `mvn` or `java` at all. -# bridged now propagates ITS OWN PATH to every worker by default; set `env:` +# fleetd now propagates ITS OWN PATH to every worker by default; set `env:` # only to override that or add more (JAVA_HOME, …). Since the default is the # daemon's PATH, make sure the daemon is started with a good one — see the PATH -# lines in deploy/dev.ltms.fleet.plist and deploy/bridged.service. +# lines in deploy/dev.ltms.fleet.plist and deploy/fleetd.service. # # Adapter-owned variables always win over `env:`: ANTHROPIC_BASE_URL and the # rest of the ANTHROPIC_*/CLAUDE_* wiring are applied after it, so an `env:` @@ -219,10 +219,10 @@ profiles: baseUrl: http://gx01.gw:8000 # the vLLM host this profile targets (gx00.gw / gx01.gw) model: coder placement: tab - workspace: bridged-workers + workspace: fleetd-workers # tabLabel: an optional per-profile override; the fleet template usually covers it mcpUrl: http://127.0.0.1:8765/mcp - tokenEnv: BRIDGED_WORKER_TOKEN + tokenEnv: FLEETD_WORKER_TOKEN argv: ["ccs", "gx10"] # weight: relative selection weight for automatic placement (weighted, round-robin, and # fixed's fallback walk). Absent defaults to 1.0. An explicit 0 or negative value means @@ -266,13 +266,13 @@ profiles: # cwd: /Users/me/src/myrepo # pin the working dir; omit to inherit the primary's # parityOverlay: [".env", ".envrc"] # the default; never add .mcp.json or .claude/settings.local.json — see above # ideMcpUrl: http://127.0.0.1:29170/index-mcp/streamable-http # opt-in (CB-634): IDE code intelligence, pinned to the worktree - # ideProjectDir: bridged # CB-634: module dir the IDE opens + the overlay pins (this repo's pom is in bridged/) + # ideProjectDir: fleetd # CB-634: module dir the IDE opens + the overlay pins (this repo's pom is in fleetd/) # ideOpenCommand: env DISPLAY=:10.0 idea {dir} # CB-634 auto-open: opens {dir} in the IDE at spawn; omit to open by hand # autoCompactWindow: 250000 # opt-in: bound member context; claude-code compacts AT this, opencode within it (model limit.context) gx11: # a second backend, so `placement: weighted` has a choice baseUrl: http://gx01.gw:8000 # self-hosted; ccs handles the model + token placement: tab - workspace: bridged-workers + workspace: fleetd-workers # tabLabel: an optional per-profile override; the fleet template usually covers it mcpUrl: http://127.0.0.1:8765/mcp argv: ["ccs", "gx11"] @@ -298,7 +298,7 @@ profiles: # kind: opencode # model: opencode/north-mini-code-free # `provider/model` selector, injected as `-m` # placement: tab - # workspace: bridged-workers + # workspace: fleetd-workers # tabLabel: "opencode: {profile} #{n}" # mcpUrl: http://127.0.0.1:8765/mcp # argv: ["opencode"] @@ -323,7 +323,7 @@ profiles: # baseUrl: http://127.0.0.1:8000 # model: local-vllm/deepseek-v4-flash # placement: tab - # workspace: bridged-workers + # workspace: fleetd-workers # tabLabel: "opencode: {profile} #{n}" # mcpUrl: http://127.0.0.1:8765/mcp # argv: ["opencode"] @@ -361,8 +361,8 @@ placement: weighted # quarantineCooldownSeconds: 1800 # Re-read this file without restarting the daemon (CB-559). Off unless you add this block, so an -# upgraded bridged keeps the old behaviour: the file is read once at boot and never again. -# enabled → turn the watch on. bridged checks the file's modified time on a timer and +# upgraded fleetd keeps the old behaviour: the file is read once at boot and never again. +# enabled → turn the watch on. fleetd checks the file's modified time on a timer and # reloads when it moves. # intervalSeconds → how often to check (default 10). One `stat` per tick, so this is cheap. # @@ -477,7 +477,7 @@ fleet: # workspace: leads # where a launched lead's tab is created (default "leads"). # # MUST NOT be a member workspace — those are excluded from the # # scan, so a lead placed in one is never found again. - # cwd: /path/to/repo # the launched lead's working directory (default: bridged's own) + # cwd: /path/to/repo # the launched lead's working directory (default: fleetd's own) # kind: claude # descriptive; reported by fleet_whoami # gpt-sol-5.6: # tab: "lead: gpt-sol-5.6" @@ -506,7 +506,7 @@ guard: # Member credential policy (CB-596, gitea issue #82). A herdr pane runs a LOGIN shell, and that # shell re-sources the operator's own secret store — so a spawned member inherits every credential -# the operator's shell holds, not just the ones bridged means to give it. Measured on this host: +# the operator's shell holds, not just the ones fleetd means to give it. Measured on this host: # 31 credential names, all set, with only ONE (GITEA_ACCESS_TOKEN) blocked before this — and that # block was a single name hardcoded in HerdrPeerLauncher.java, not driven by this file. This block # replaces that hardcoded shadow with a config-driven list of names. @@ -695,7 +695,7 @@ guard: # # REQUIRED (CB-522) if the primary itself runs inside a herdr pane. Caller # identity resolves a loopback PID to its herdr pane, and PaneLocator scans -# EVERY pane — not just bridged-spawned ones — so such a primary is otherwise +# EVERY pane — not just fleetd-spawned ones — so such a primary is otherwise # classified as a WORKER and refused SPAWN/SEND/STOP. That failure is # self-locking: the learned terminal is populated by the very orchestration # calls being refused, so only this pinned value can break the cycle. Read the diff --git a/bridged/pom.xml b/fleetd/pom.xml similarity index 97% rename from bridged/pom.xml rename to fleetd/pom.xml index cc5a2fa..18d48cb 100644 --- a/bridged/pom.xml +++ b/fleetd/pom.xml @@ -161,10 +161,10 @@ - - bridged + + fleetd org.apache.maven.plugins @@ -206,7 +206,7 @@ - + org.apache.maven.plugins maven-shade-plugin diff --git a/bridged/src/main/java/dev/ltms/fleet/Fleetd.java b/fleetd/src/main/java/dev/ltms/fleet/Fleetd.java similarity index 96% rename from bridged/src/main/java/dev/ltms/fleet/Fleetd.java rename to fleetd/src/main/java/dev/ltms/fleet/Fleetd.java index 88fc751..67bf198 100644 --- a/bridged/src/main/java/dev/ltms/fleet/Fleetd.java +++ b/fleetd/src/main/java/dev/ltms/fleet/Fleetd.java @@ -60,7 +60,6 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -70,12 +69,11 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.regex.Pattern; -import java.util.stream.Collectors; /** - * {@code bridged} entry point. Wires the real herdr socket client to the REST app and + * {@code fleetd} entry point. Wires the real herdr socket client to the REST app and * starts listening. Before anything else it asserts its own environment is clean — - * {@code bridged} is not a Claude process and must never carry a base_url. + * {@code fleetd} is not a Claude process and must never carry a base_url. */ public final class Fleetd { @@ -94,9 +92,10 @@ public final class Fleetd { private static final long HERDR_WAIT_POLL_MILLIS = 500; /** - * CB-632: prefer {@code fleetd.yaml} in {@code dir}; fall back to {@code bridged.yaml} when - * the new name is not there. The operator's live file is still named {@code bridged.yaml}, - * so the old name keeps working until that file moves. + * CB-632/CB-634: prefer {@code fleetd.yaml} in {@code dir}; fall back to the legacy + * {@code bridged.yaml} when the new name is not there. The product renamed to {@code fleetd}, + * but a deployment whose local config file is still {@code bridged.yaml} keeps working until + * that file is renamed. */ static Path chooseDefaultConfigFile(Path dir) { Path fleetd = dir.resolve("fleetd.yaml"); @@ -108,8 +107,8 @@ public final class Fleetd { static void main(String[] args) { Path configPath = args.length > 0 ? Path.of(args[0]) : chooseDefaultConfigFile(Path.of("")); - // CB-632: the config file is being renamed bridged.yaml -> fleetd.yaml. Name the file we - // actually loaded, whichever of the two names it carries. + // The config file was renamed bridged.yaml -> fleetd.yaml. Name the file we actually + // loaded, whichever of the two names it carries. log.info("Using configuration file {}", configPath); FleetConfig cfg = FleetConfig.load(configPath); // CB-594: report which secret env vars the config actually needs, by name, before anything @@ -127,7 +126,7 @@ public final class Fleetd { // contract; adding a reader here does not make a key reloadable by itself. ConfigRef config = new ConfigRef(configPath, cfg); - // The primary/host env that launched bridged must not be tainted. + // The primary/host env that launched fleetd must not be tainted. SubscriptionGuard guard = new SubscriptionGuard(cfg.guard().hostSet()); guard.assertPrimaryClean(System.getenv()); @@ -196,7 +195,7 @@ public final class Fleetd { config, profileName -> liveCountRef.get().apply(profileName), quarantine); - // CB-504: under supervision (launchd/systemd) bridged can start before herdr's socket + // CB-504: under supervision (launchd/systemd) fleetd can start before herdr's socket // exists. The client itself is lazy — it connects per call — but the orphan reap below is // the first thing that actually talks to herdr, so without this wait a boot-order race // would crash the daemon into a restart loop. Wait, then degrade rather than die: serving @@ -255,24 +254,27 @@ public final class Fleetd { final Supplier> leads; var leaders = cfg.fleet().leaders(); if (!leaders.isEmpty()) { - Set memberSpaces = cfg.profiles().values().stream() - .map(FleetConfig.Profile::workspace) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); Map tabToName = new LinkedHashMap<>(); leaders.forEach((name, leader) -> { if (leader != null && leader.tab() != null && !leader.tab().isBlank()) { tabToName.put(leader.tab(), name); } }); + // The lead and the members now share ONE workspace (the operator asked for a single + // "session" with many tabs), so no workspace can be excluded — the lead lives in the + // members' space by design. A lead is told from a member by its exact tab label alone: + // a lead carries its configured `tab`, a member its `worker: {profile} #{n}` template, + // and the two never collide. (The scanner still supports an exclusion set for a split + // layout; the fleet's policy here is simply not to use one.) + // // One shared rescan cadence: still taken from the first entry, as before — it is an // operational cadence, not identity, so there is no correctness reason to give every // lead its own scanner. int scanIntervalSeconds = leaders.values().iterator().next().scanIntervalSeconds(); - leads = new LeadTabScanner(herdr, tabToName, memberSpaces, + leads = new LeadTabScanner(herdr, tabToName, Set.of(), TimeUnit.SECONDS.toNanos(scanIntervalSeconds), System::nanoTime); - log.info("lead scan: tabs {} host a lead (rescan every {}s, member spaces {} excluded)", - tabToName.keySet(), scanIntervalSeconds, memberSpaces); + log.info("lead scan: tabs {} host a lead (rescan every {}s, shared fleet space)", + tabToName.keySet(), scanIntervalSeconds); } else { leads = () -> leadTerminals; } @@ -384,7 +386,7 @@ public final class Fleetd { poller.start(); // CB-307: reply inbox. A broker: block selects the AMQP-backed durable adapter; absent (or - // unusable), bridged stays soft-state on the in-memory inbox. The AMQP inbox owns a broker + // unusable), fleetd stays soft-state on the in-memory inbox. The AMQP inbox owns a broker // connection, so keep the reference to close it in the ordered shutdown hook. final ReplyInbox replyInbox = selectReplyInbox(cfg.broker(), System.getenv(), AmqpReplyInbox::open); // CB-637: this daemon's lead-to-lead mailbox on the SHARED coordination vhost — a separate @@ -497,7 +499,7 @@ public final class Fleetd { String token = System.getenv(cfg.auth().tokenEnv()); if (token == null || token.isBlank()) { throw new IllegalStateException("auth.mode=token but env var " + cfg.auth().tokenEnv() - + " is unset or empty — export it before starting bridged"); + + " is unset or empty — export it before starting fleetd"); } callers = CallerResolver.withLeadsAndMembers(identity, true, token, leads, members); log.info("auth: token mode (bearer required for non-worker callers, env {})", @@ -591,7 +593,7 @@ public final class Fleetd { Javalin app = new FleetApp(herdr, workers, sessions, messages, presence, mcp.servlet(), callers, metrics).build(); app.start(cfg.bind().host(), cfg.bind().port()); - log.info("bridged listening on {}:{}, herdr socket {}", + log.info("fleetd listening on {}:{}, herdr socket {}", cfg.bind().host(), cfg.bind().port(), socket); } @@ -665,7 +667,7 @@ public final class Fleetd { log.warn("coordinator.selfId is unset — lead coordination is OFF. A lead mailbox is the " + "queue named after the coord-id that owns it, so with no id there is nothing to " + "own and no sender identity to publish as. Set coordinator.selfId to a name that " - + "is unique across every daemon sharing {} and restart bridged.", + + "is unique across every daemon sharing {} and restart fleetd.", stripCredentials(uri)); return null; } @@ -708,7 +710,7 @@ public final class Fleetd { if (effectiveUri == null) { log.warn("broker.uriEnv={} is unset or blank — durable AMQP reply inbox DISABLED. " + "Replies are soft-state and will not survive a restart. Set {} in the " - + "daemon's environment (see scripts/redeploy-bridged.sh) and restart to " + + "daemon's environment (see scripts/redeploy-fleetd.sh) and restart to " + "use the durable broker inbox.", broker.uriEnv(), broker.uriEnv()); log.info("reply inbox: in-memory (soft-state)"); @@ -823,8 +825,8 @@ public final class Fleetd { } else { log.warn("startup secret {}: MISSING ({}) — the daemon will start anyway, and this " + "failure stays invisible until a worker actually needs it. Fix " - + "${SHARED_ENV}/tools/secrets.sh and restart bridged from a LOGIN " - + "shell (see scripts/redeploy-bridged.sh).", + + "${SHARED_ENV}/tools/secrets.sh and restart fleetd from a LOGIN " + + "shell (see scripts/redeploy-fleetd.sh).", varName, String.join(", ", sources)); } }); @@ -856,7 +858,7 @@ public final class Fleetd { log.warn("memberCredentials: absent or empty — the daemon will start anyway, and every " + "member pane inherits the operator's WHOLE secret store, unblocked (CB-592's " + "protection is lost). Add a memberCredentials: block (policy/allow/known) to " - + "bridged.yaml — see fleetd.example.yaml — and restart."); + + "fleetd.yaml — see fleetd.example.yaml — and restart."); } /** diff --git a/bridged/src/main/java/dev/ltms/fleet/auth/AuditLog.java b/fleetd/src/main/java/dev/ltms/fleet/auth/AuditLog.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/auth/AuditLog.java rename to fleetd/src/main/java/dev/ltms/fleet/auth/AuditLog.java diff --git a/bridged/src/main/java/dev/ltms/fleet/auth/Authz.java b/fleetd/src/main/java/dev/ltms/fleet/auth/Authz.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/auth/Authz.java rename to fleetd/src/main/java/dev/ltms/fleet/auth/Authz.java diff --git a/bridged/src/main/java/dev/ltms/fleet/auth/CallerResolver.java b/fleetd/src/main/java/dev/ltms/fleet/auth/CallerResolver.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/auth/CallerResolver.java rename to fleetd/src/main/java/dev/ltms/fleet/auth/CallerResolver.java diff --git a/bridged/src/main/java/dev/ltms/fleet/auth/MemberLifecycle.java b/fleetd/src/main/java/dev/ltms/fleet/auth/MemberLifecycle.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/auth/MemberLifecycle.java rename to fleetd/src/main/java/dev/ltms/fleet/auth/MemberLifecycle.java diff --git a/bridged/src/main/java/dev/ltms/fleet/auth/MemberRegistry.java b/fleetd/src/main/java/dev/ltms/fleet/auth/MemberRegistry.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/auth/MemberRegistry.java rename to fleetd/src/main/java/dev/ltms/fleet/auth/MemberRegistry.java diff --git a/bridged/src/main/java/dev/ltms/fleet/auth/Principal.java b/fleetd/src/main/java/dev/ltms/fleet/auth/Principal.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/auth/Principal.java rename to fleetd/src/main/java/dev/ltms/fleet/auth/Principal.java diff --git a/bridged/src/main/java/dev/ltms/fleet/auth/Role.java b/fleetd/src/main/java/dev/ltms/fleet/auth/Role.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/auth/Role.java rename to fleetd/src/main/java/dev/ltms/fleet/auth/Role.java diff --git a/bridged/src/main/java/dev/ltms/fleet/config/ConfigRef.java b/fleetd/src/main/java/dev/ltms/fleet/config/ConfigRef.java similarity index 99% rename from bridged/src/main/java/dev/ltms/fleet/config/ConfigRef.java rename to fleetd/src/main/java/dev/ltms/fleet/config/ConfigRef.java index f230e3b..45d6360 100644 --- a/bridged/src/main/java/dev/ltms/fleet/config/ConfigRef.java +++ b/fleetd/src/main/java/dev/ltms/fleet/config/ConfigRef.java @@ -128,7 +128,7 @@ public final class ConfigRef implements Supplier { } if (!applied) { return "config reload refused — these keys cannot change under a running daemon: " - + String.join(", ", coldKeys) + ". Restart bridged to apply them."; + + String.join(", ", coldKeys) + ". Restart fleetd to apply them."; } if (!deferred.isEmpty()) { return "config reloaded; these changes need a restart to take effect: " diff --git a/bridged/src/main/java/dev/ltms/fleet/config/ConfigWatcher.java b/fleetd/src/main/java/dev/ltms/fleet/config/ConfigWatcher.java similarity index 97% rename from bridged/src/main/java/dev/ltms/fleet/config/ConfigWatcher.java rename to fleetd/src/main/java/dev/ltms/fleet/config/ConfigWatcher.java index f521c0a..4c6aef7 100644 --- a/bridged/src/main/java/dev/ltms/fleet/config/ConfigWatcher.java +++ b/fleetd/src/main/java/dev/ltms/fleet/config/ConfigWatcher.java @@ -11,7 +11,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** - * Polls {@code bridged.yaml}'s modified time and asks {@link ConfigRef} to reload when it moves + * Polls {@code fleetd.yaml}'s modified time and asks {@link ConfigRef} to reload when it moves * (CB-559). Opt-in through {@code configReload.enabled}. * *

Why polling and not a filesystem watch. {@code WatchService} on macOS has no diff --git a/bridged/src/main/java/dev/ltms/fleet/config/FleetConfig.java b/fleetd/src/main/java/dev/ltms/fleet/config/FleetConfig.java similarity index 98% rename from bridged/src/main/java/dev/ltms/fleet/config/FleetConfig.java rename to fleetd/src/main/java/dev/ltms/fleet/config/FleetConfig.java index 5a34371..b486f60 100644 --- a/bridged/src/main/java/dev/ltms/fleet/config/FleetConfig.java +++ b/fleetd/src/main/java/dev/ltms/fleet/config/FleetConfig.java @@ -26,7 +26,7 @@ import java.util.Map; import java.util.Set; /** - * {@code bridged} configuration, loaded from a YAML file (see + * {@code fleetd} configuration, loaded from a YAML file (see * {@code fleetd.example.yaml}). Unknown keys are ignored so config can grow ahead * of the code — but an unknown top-level key is logged as a WARN at load (CB-530), because * silently dropping a whole block is indistinguishable from honouring it. @@ -196,9 +196,9 @@ public record FleetConfig( * @param argv launch command; defaults to {@code ["claude"]} * @param placement where a worker lands: {@code "tab"} (default — its own tab in the * worker space) or {@code "pane"} (legacy — split the focused tab) - * @param workspace label of the dedicated worker space; found-or-created on first - * spawn (default {@code "bridged-workers"}). A future per-session - * layout is just a distinct label here — the shared space is default. + * @param workspace label of the shared fleet space; found-or-created on first spawn + * (default {@code "fleet"}). The lead and every member share this one + * space so the operator sees a single "session" with many tabs. * @param tabLabel template for a worker tab's label; {@code {profile}}/{@code {model}} * and {@code {n}} (per-worker number, to keep sibling tabs distinct) * are substituted (default {@code "worker: {profile} #{n}"}) @@ -218,7 +218,7 @@ public record FleetConfig( * worktrees then accumulate with no error anywhere. *

Checked on 2026-08-15 (CB-581): inert as configured. Tracked overlay * files carry {@code --skip-worktree} so {@code --porcelain} cannot see them, - * {@code bridged.yaml} is gitignored, and the default pair {@code .env} / + * {@code fleetd.yaml} is gitignored, and the default pair {@code .env} / * {@code .envrc} does not exist in this repo. Note the default applies to * every profile, so creating either file at the repo root is enough * to make it live. Add a new overlay path to {@code .gitignore} in the same @@ -341,9 +341,9 @@ public record FleetConfig( ? (KIND_CLAUDE_CODE.equals(k) ? List.of("claude") : List.of(k)) : List.copyOf(argv); kind = k; - tokenEnv = (tokenEnv == null || tokenEnv.isBlank()) ? "BRIDGED_WORKER_TOKEN" : tokenEnv; + tokenEnv = (tokenEnv == null || tokenEnv.isBlank()) ? "FLEETD_WORKER_TOKEN" : tokenEnv; placement = (placement == null || placement.isBlank()) ? "tab" : placement.toLowerCase(); - workspace = (workspace == null || workspace.isBlank()) ? "bridged-workers" : workspace; + workspace = (workspace == null || workspace.isBlank()) ? "fleet" : workspace; // CB-557: no per-profile default any more. A label is generated from the member's ROLE // ("dev: sonnet #2"), which a profile cannot know, so the template lives on `fleet:` and // this field is only an override for a profile that wants its own. Blank ⇒ defer. @@ -389,7 +389,7 @@ public record FleetConfig( // (pinned to its own worktree via the charter). Blank ⇒ off. ideMcpUrl = (ideMcpUrl == null || ideMcpUrl.isBlank()) ? null : ideMcpUrl; // CB-634 auto-open: both are only read when hasIdeMcp(). ideProjectDir is the repo-relative - // module dir IntelliJ must open (this repo's pom lives in `bridged/`, not at the root), and + // module dir IntelliJ must open (this repo's pom lives in `fleetd/`, not at the root), and // it is also the project_path the overlay pins. Blank ⇒ the worktree root (unchanged before // auto-open). ideOpenCommand is the host command that opens that dir in the IDE, with {dir} // substituted; blank ⇒ no auto-open (the operator opens the module by hand). @@ -649,7 +649,7 @@ public record FleetConfig( /** * External AMQP broker for durable, cross-restart reply delivery (CB-307 Stage 2). Its mere - * presence swaps the in-memory {@code ReplyInbox} for the AMQP-backed adapter; absent, bridged + * presence swaps the in-memory {@code ReplyInbox} for the AMQP-backed adapter; absent, fleetd * stays soft-state. Production default is LavinMQ; a stock RabbitMQ speaks the same AMQP 0-9-1 * and is a URI-only swap. * @@ -857,11 +857,12 @@ public record FleetConfig( String workspace, String cwd) { /** - * Where an auto-launched lead's tab is created (CB-558). It must NOT be a member workspace: - * {@code LeadTabScanner} excludes those wholesale, so a lead placed in one would never be - * discovered and the daemon would relaunch it on every boot. + * Where an auto-launched lead's tab is created (CB-558). It defaults to the SAME shared + * {@code "fleet"} space the members use, so the operator sees one "session" with many tabs. + * The scanner no longer excludes member spaces — it tells a lead from a member by the exact + * tab label, so a lead sharing the members' space is still discovered (see LeadLauncher). */ - public static final String DEFAULT_WORKSPACE = "leads"; + public static final String DEFAULT_WORKSPACE = "fleet"; public Leader { instances = (instances == null || instances < 0) ? 1 : instances; @@ -1060,7 +1061,7 @@ public record FleetConfig( } /** - * Watch {@code bridged.yaml} and re-read it when it changes (CB-559). + * Watch {@code fleetd.yaml} and re-read it when it changes (CB-559). * *

Opt-in, like every other block that acts on its own initiative. A daemon that reloads * whenever a file is saved would apply a half-finished edit the moment an editor writes it, and @@ -1118,7 +1119,7 @@ public record FleetConfig( * a caller must present {@code Authorization: Bearer } or it is * {@code ANONYMOUS} and authorized for nothing. * @param tokenEnv name of the host env var holding the bearer token; the literal value is - * never stored in config. Defaults to {@code BRIDGED_API_TOKEN}. Only read + * never stored in config. Defaults to {@code FLEETD_API_TOKEN}. Only read * when {@code mode} is {@code token}. */ @JsonIgnoreProperties(ignoreUnknown = true) @@ -1131,7 +1132,7 @@ public record FleetConfig( public Auth { mode = (mode == null || mode.isBlank()) ? MODE_LOOPBACK_TRUST : mode.toLowerCase(); - tokenEnv = (tokenEnv == null || tokenEnv.isBlank()) ? "BRIDGED_API_TOKEN" : tokenEnv; + tokenEnv = (tokenEnv == null || tokenEnv.isBlank()) ? "FLEETD_API_TOKEN" : tokenEnv; } /** True when a bearer token is required of every non-worker caller. */ @@ -1313,7 +1314,7 @@ public record FleetConfig( * *

Package-private (not {@code private}) so a test can assert every key here is documented in * {@code fleetd.example.yaml} — the only committed description of the config schema, since - * {@code bridged.yaml} itself is gitignored. + * {@code fleetd.yaml} itself is gitignored. */ static final Set KNOWN_TOP_LEVEL_KEYS = Set.of( "bind", "herdrSocket", "profiles", "guard", "worktreeRoot", @@ -1342,7 +1343,7 @@ public record FleetConfig( rejectUnknownPlacementPolicy(cfg.placement()); return cfg.withDefaults(); } catch (IOException e) { - throw new UncheckedIOException("cannot read bridged config at " + path, e); + throw new UncheckedIOException("cannot read fleetd config at " + path, e); } } @@ -1929,7 +1930,7 @@ public record FleetConfig( // guard/lifecycle, an absent block is not a safe "feature off" default here, it is a gap. It // is deliberately not pre-populated with a Java-side name list (that would just reintroduce // the hardcoded-list defect this record replaces); the block must be configured in - // bridged.yaml to protect anything. See fleetd.example.yaml's memberCredentials: comment. + // fleetd.yaml to protect anything. See fleetd.example.yaml's memberCredentials: comment. // CB-633: policy stays deny-by-default here — the allow-list scrub is opt-in, because it is // stricter than today's behaviour (it blanks every non-derived name, not just known ones) // and an upgrade must not change what a running deployment's members inherit. @@ -1969,7 +1970,7 @@ public record FleetConfig( /** * Reject a lead-scan convention that a worker tab would also satisfy (CB-531). * - *

The scan reads a tab label and concludes "a lead lives here". bridged also writes + *

The scan reads a tab label and concludes "a lead lives here". fleetd also writes * tab labels — every member gets one rendered into its tab. Choose a lead {@code tabPrefix} that * a member template matches and the daemon starts labelling its own members as leads, promoting * the entire fleet to {@link dev.ltms.fleet.auth.Role#PRIMARY} with no message and no diff. diff --git a/bridged/src/main/java/dev/ltms/fleet/guard/GuardException.java b/fleetd/src/main/java/dev/ltms/fleet/guard/GuardException.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/guard/GuardException.java rename to fleetd/src/main/java/dev/ltms/fleet/guard/GuardException.java diff --git a/bridged/src/main/java/dev/ltms/fleet/guard/SubscriptionGuard.java b/fleetd/src/main/java/dev/ltms/fleet/guard/SubscriptionGuard.java similarity index 99% rename from bridged/src/main/java/dev/ltms/fleet/guard/SubscriptionGuard.java rename to fleetd/src/main/java/dev/ltms/fleet/guard/SubscriptionGuard.java index f29386e..f2ed318 100644 --- a/bridged/src/main/java/dev/ltms/fleet/guard/SubscriptionGuard.java +++ b/fleetd/src/main/java/dev/ltms/fleet/guard/SubscriptionGuard.java @@ -16,7 +16,7 @@ import java.util.Set; * means its traffic would leave the subscription. That is a hard stop. * * - * Both checks throw {@link GuardException} on violation. {@code bridged} calls + * Both checks throw {@link GuardException} on violation. {@code fleetd} calls * {@link #assertWorker} before spawning a worker and {@link #assertPrimaryClean} * against its own environment at startup. */ diff --git a/bridged/src/main/java/dev/ltms/fleet/health/FleetHealth.java b/fleetd/src/main/java/dev/ltms/fleet/health/FleetHealth.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/health/FleetHealth.java rename to fleetd/src/main/java/dev/ltms/fleet/health/FleetHealth.java diff --git a/bridged/src/main/java/dev/ltms/fleet/health/FleetHealthMonitor.java b/fleetd/src/main/java/dev/ltms/fleet/health/FleetHealthMonitor.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/health/FleetHealthMonitor.java rename to fleetd/src/main/java/dev/ltms/fleet/health/FleetHealthMonitor.java diff --git a/bridged/src/main/java/dev/ltms/fleet/health/HealthDecision.java b/fleetd/src/main/java/dev/ltms/fleet/health/HealthDecision.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/health/HealthDecision.java rename to fleetd/src/main/java/dev/ltms/fleet/health/HealthDecision.java diff --git a/bridged/src/main/java/dev/ltms/fleet/health/HealthPrior.java b/fleetd/src/main/java/dev/ltms/fleet/health/HealthPrior.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/health/HealthPrior.java rename to fleetd/src/main/java/dev/ltms/fleet/health/HealthPrior.java diff --git a/bridged/src/main/java/dev/ltms/fleet/health/HealthSnapshot.java b/fleetd/src/main/java/dev/ltms/fleet/health/HealthSnapshot.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/health/HealthSnapshot.java rename to fleetd/src/main/java/dev/ltms/fleet/health/HealthSnapshot.java diff --git a/bridged/src/main/java/dev/ltms/fleet/health/HealthState.java b/fleetd/src/main/java/dev/ltms/fleet/health/HealthState.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/health/HealthState.java rename to fleetd/src/main/java/dev/ltms/fleet/health/HealthState.java diff --git a/bridged/src/main/java/dev/ltms/fleet/health/MuteCounter.java b/fleetd/src/main/java/dev/ltms/fleet/health/MuteCounter.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/health/MuteCounter.java rename to fleetd/src/main/java/dev/ltms/fleet/health/MuteCounter.java diff --git a/bridged/src/main/java/dev/ltms/fleet/health/PaneBudget.java b/fleetd/src/main/java/dev/ltms/fleet/health/PaneBudget.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/health/PaneBudget.java rename to fleetd/src/main/java/dev/ltms/fleet/health/PaneBudget.java diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/Agent.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/Agent.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/herdr/Agent.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/Agent.java diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/AgentControl.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/AgentControl.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/herdr/AgentControl.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/AgentControl.java diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/AgentStatus.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/AgentStatus.java similarity index 93% rename from bridged/src/main/java/dev/ltms/fleet/herdr/AgentStatus.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/AgentStatus.java index 407e7db..0567ca7 100644 --- a/bridged/src/main/java/dev/ltms/fleet/herdr/AgentStatus.java +++ b/fleetd/src/main/java/dev/ltms/fleet/herdr/AgentStatus.java @@ -32,7 +32,7 @@ public enum AgentStatus { }; } - /** Whether {@code bridged} may inject a message now without stepping on a live turn. */ + /** Whether {@code fleetd} may inject a message now without stepping on a live turn. */ public boolean injectable() { return this == IDLE || this == BLOCKED || this == DONE; } diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/HerdrClient.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/HerdrClient.java similarity index 89% rename from bridged/src/main/java/dev/ltms/fleet/herdr/HerdrClient.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/HerdrClient.java index 2b333b4..ac83b52 100644 --- a/bridged/src/main/java/dev/ltms/fleet/herdr/HerdrClient.java +++ b/fleetd/src/main/java/dev/ltms/fleet/herdr/HerdrClient.java @@ -5,13 +5,13 @@ import com.fasterxml.jackson.databind.JsonNode; /** * Client face onto the herdr daemon (protocol 14, herdr 0.7.0). * - *

This is the ONLY thing in {@code bridged} that speaks to herdr. Every method + *

This is the ONLY thing in {@code fleetd} that speaks to herdr. Every method * maps to a herdr JSON-RPC call over its Unix domain socket. Requests are * newline-delimited JSON with a string id; responses carry either a * {@code result} object (whose {@code type} field discriminates the payload) or an * {@code error} object. * - *

Higher layers ({@code bridged}'s policy brain, REST endpoints, MCP adapters) + *

Higher layers ({@code fleetd}'s policy brain, REST endpoints, MCP adapters) * depend on this interface, not on the socket. Tests substitute a fake; the * {@code contract}-tagged suite exercises the real implementation against a running * herdr to catch protocol drift. diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/HerdrCodec.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/HerdrCodec.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/herdr/HerdrCodec.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/HerdrCodec.java diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/HerdrException.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/HerdrException.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/herdr/HerdrException.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/HerdrException.java diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/LeadTabScanner.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/LeadTabScanner.java similarity index 97% rename from bridged/src/main/java/dev/ltms/fleet/herdr/LeadTabScanner.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/LeadTabScanner.java index 45ad227..9b0a3c4 100644 --- a/bridged/src/main/java/dev/ltms/fleet/herdr/LeadTabScanner.java +++ b/fleetd/src/main/java/dev/ltms/fleet/herdr/LeadTabScanner.java @@ -46,11 +46,11 @@ import java.util.function.Supplier; * lead still cannot act as one unless the daemon's own registry agrees. * * - *

CB-558 — bridged now writes lead labels too. This class used to be able to say - * that bridged never renames a lead tab, so the label was always the human's own writing and there + *

CB-558 — fleetd now writes lead labels too. This class used to be able to say + * that fleetd never renames a lead tab, so the label was always the human's own writing and there * was no round-trip from the daemon's rename back into its next decision. * {@code dev.ltms.fleet.lead.LeadLauncher} ends that: an auto-launched lead is labelled by the - * daemon and found again by this scan. The trust direction above is unaffected — bridged writing a + * daemon and found again by this scan. The trust direction above is unaffected — fleetd writing a * name for a lead it just started is not a pane promoting itself — but staleness becomes * real: a label left behind by a session that has since died would read as a live lead forever. * This scanner does not solve that (its job is naming, and a stale name costs nothing here); the diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/PaneLocator.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/PaneLocator.java similarity index 95% rename from bridged/src/main/java/dev/ltms/fleet/herdr/PaneLocator.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/PaneLocator.java index 8eaa8bd..9e2e355 100644 --- a/bridged/src/main/java/dev/ltms/fleet/herdr/PaneLocator.java +++ b/fleetd/src/main/java/dev/ltms/fleet/herdr/PaneLocator.java @@ -7,7 +7,7 @@ import java.util.Map; /** * Resolves which herdr pane a process belongs to — the herdr half of connection-based MCP * identity (CB-105). Given the PID that opened an MCP connection, {@link #terminalForPid} finds - * the agent pane whose process tree contains it, so {@code bridged} can tell which worker + * the agent pane whose process tree contains it, so {@code fleetd} can tell which worker * is calling without the worker sending anything spoofable. * *

herdr owns the PID→pane truth: {@code pane.process_info} reports each pane's {@code shell_pid} diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/Tab.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/Tab.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/herdr/Tab.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/Tab.java diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/UnixSocketHerdrClient.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/UnixSocketHerdrClient.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/herdr/UnixSocketHerdrClient.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/UnixSocketHerdrClient.java diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/Workspace.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/Workspace.java similarity index 97% rename from bridged/src/main/java/dev/ltms/fleet/herdr/Workspace.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/Workspace.java index 7724c27..1efcbc0 100644 --- a/bridged/src/main/java/dev/ltms/fleet/herdr/Workspace.java +++ b/fleetd/src/main/java/dev/ltms/fleet/herdr/Workspace.java @@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.JsonNode; * dedicated worker space so they never split or clutter the user's real work spaces. * * @param workspaceId herdr's stable id (e.g. {@code "w4"}) - * @param label display label shown in herdr's UI (e.g. {@code "bridged-workers"}) + * @param label display label shown in herdr's UI (e.g. {@code "fleetd-workers"}) * @param activeTabId the workspace's currently-focused tab, or {@code null} */ public record Workspace(String workspaceId, String label, String activeTabId) { diff --git a/bridged/src/main/java/dev/ltms/fleet/herdr/WorkspaceControl.java b/fleetd/src/main/java/dev/ltms/fleet/herdr/WorkspaceControl.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/herdr/WorkspaceControl.java rename to fleetd/src/main/java/dev/ltms/fleet/herdr/WorkspaceControl.java diff --git a/bridged/src/main/java/dev/ltms/fleet/inject/CompletionResolver.java b/fleetd/src/main/java/dev/ltms/fleet/inject/CompletionResolver.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/inject/CompletionResolver.java rename to fleetd/src/main/java/dev/ltms/fleet/inject/CompletionResolver.java diff --git a/bridged/src/main/java/dev/ltms/fleet/inject/ExhaustedPatternLookup.java b/fleetd/src/main/java/dev/ltms/fleet/inject/ExhaustedPatternLookup.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/inject/ExhaustedPatternLookup.java rename to fleetd/src/main/java/dev/ltms/fleet/inject/ExhaustedPatternLookup.java diff --git a/bridged/src/main/java/dev/ltms/fleet/inject/ExhaustionSink.java b/fleetd/src/main/java/dev/ltms/fleet/inject/ExhaustionSink.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/inject/ExhaustionSink.java rename to fleetd/src/main/java/dev/ltms/fleet/inject/ExhaustionSink.java diff --git a/bridged/src/main/java/dev/ltms/fleet/inject/Injector.java b/fleetd/src/main/java/dev/ltms/fleet/inject/Injector.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/inject/Injector.java rename to fleetd/src/main/java/dev/ltms/fleet/inject/Injector.java diff --git a/bridged/src/main/java/dev/ltms/fleet/inject/MemberPresence.java b/fleetd/src/main/java/dev/ltms/fleet/inject/MemberPresence.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/inject/MemberPresence.java rename to fleetd/src/main/java/dev/ltms/fleet/inject/MemberPresence.java diff --git a/bridged/src/main/java/dev/ltms/fleet/inject/StatusPoller.java b/fleetd/src/main/java/dev/ltms/fleet/inject/StatusPoller.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/inject/StatusPoller.java rename to fleetd/src/main/java/dev/ltms/fleet/inject/StatusPoller.java diff --git a/bridged/src/main/java/dev/ltms/fleet/inject/StatusRefiner.java b/fleetd/src/main/java/dev/ltms/fleet/inject/StatusRefiner.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/inject/StatusRefiner.java rename to fleetd/src/main/java/dev/ltms/fleet/inject/StatusRefiner.java diff --git a/bridged/src/main/java/dev/ltms/fleet/inject/TurnListener.java b/fleetd/src/main/java/dev/ltms/fleet/inject/TurnListener.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/inject/TurnListener.java rename to fleetd/src/main/java/dev/ltms/fleet/inject/TurnListener.java diff --git a/bridged/src/main/java/dev/ltms/fleet/lead/LeadLauncher.java b/fleetd/src/main/java/dev/ltms/fleet/lead/LeadLauncher.java similarity index 94% rename from bridged/src/main/java/dev/ltms/fleet/lead/LeadLauncher.java rename to fleetd/src/main/java/dev/ltms/fleet/lead/LeadLauncher.java index dd5e565..a852eac 100644 --- a/bridged/src/main/java/dev/ltms/fleet/lead/LeadLauncher.java +++ b/fleetd/src/main/java/dev/ltms/fleet/lead/LeadLauncher.java @@ -15,8 +15,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; import dev.ltms.fleet.peer.PeerLauncher; /** @@ -41,7 +39,7 @@ import dev.ltms.fleet.peer.PeerLauncher; * broken later, quietly. * *

Liveness, and the label round-trip. {@code LeadTabScanner} used to be able to - * promise that bridged never writes a lead label. That is no longer true — an auto-launched lead is + * promise that fleetd never writes a lead label. That is no longer true — an auto-launched lead is * labelled by this class, and the scanner reads that label back. The risk this opens is not * privilege escalation (the tab label never granted anything a pane could take for itself; see that * class's javadoc), but staleness: a label left behind by a crashed session would otherwise @@ -106,7 +104,7 @@ public final class LeadLauncher { // A lead with a `tab:` but no `profile:` is recognise-only by design: the operator // opens it by hand. Say so once rather than looking like a silent failure. log.info("lead '{}' is not live, and names no profile — it can be recognised but not " - + "launched. Add `profile:` under fleet.leaders.{} to have bridged start it.", + + "launched. Add `profile:` under fleet.leaders.{} to have fleetd start it.", name, name); continue; } @@ -140,15 +138,15 @@ public final class LeadLauncher { * auto-launched one is — by labelling its tab to match. */ private Map liveLeads(Map leaders) { - Set memberSpaces = cfg.profiles().values().stream() - .map(FleetConfig.Profile::workspace) - .filter(w -> w != null && !w.isBlank()) - .collect(Collectors.toSet()); - - // tabId → the lead name its label declares. + // A lead and the members share ONE workspace now (the operator asked for a single "session" + // with many tabs), so a workspace can no longer be excluded wholesale — the lead lives in the + // member workspace by design. The sole discriminator is the exact tab label: a lead carries + // its configured `fleet.leaders..tab` ("lead: opus"), while a member carries its + // profile's `worker: {profile} #{n}` template. These never collide, so an exact-label match + // separates them without needing to know which workspace anyone is in. Map nameByTab = new LinkedHashMap<>(); for (Workspace ws : spaces.listWorkspaces()) { - if (ws.workspaceId() == null || memberSpaces.contains(ws.label())) { + if (ws.workspaceId() == null) { continue; } for (Tab tab : spaces.listTabs(ws.workspaceId())) { diff --git a/bridged/src/main/java/dev/ltms/fleet/logging/McpCancelledNotificationFilter.java b/fleetd/src/main/java/dev/ltms/fleet/logging/McpCancelledNotificationFilter.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/logging/McpCancelledNotificationFilter.java rename to fleetd/src/main/java/dev/ltms/fleet/logging/McpCancelledNotificationFilter.java diff --git a/bridged/src/main/java/dev/ltms/fleet/mcp/ConnectionIdentity.java b/fleetd/src/main/java/dev/ltms/fleet/mcp/ConnectionIdentity.java similarity index 96% rename from bridged/src/main/java/dev/ltms/fleet/mcp/ConnectionIdentity.java rename to fleetd/src/main/java/dev/ltms/fleet/mcp/ConnectionIdentity.java index 53b58e0..60b66d1 100644 --- a/bridged/src/main/java/dev/ltms/fleet/mcp/ConnectionIdentity.java +++ b/fleetd/src/main/java/dev/ltms/fleet/mcp/ConnectionIdentity.java @@ -10,7 +10,7 @@ import dev.ltms.fleet.herdr.PaneLocator; * *

Both sources are authoritative and unforgeable: the OS reports the real connecting PID, and * herdr owns the PID→pane mapping. A worker cannot claim to be another worker, nor the primary. - * Single-host only (the herd shares the {@code bridged} host); the token path is the split-host + * Single-host only (the herd shares the {@code fleetd} host); the token path is the split-host * fallback. */ public final class ConnectionIdentity { diff --git a/bridged/src/main/java/dev/ltms/fleet/mcp/FleetMcp.java b/fleetd/src/main/java/dev/ltms/fleet/mcp/FleetMcp.java similarity index 94% rename from bridged/src/main/java/dev/ltms/fleet/mcp/FleetMcp.java rename to fleetd/src/main/java/dev/ltms/fleet/mcp/FleetMcp.java index 7e5ef03..4572f5e 100644 --- a/bridged/src/main/java/dev/ltms/fleet/mcp/FleetMcp.java +++ b/fleetd/src/main/java/dev/ltms/fleet/mcp/FleetMcp.java @@ -76,14 +76,6 @@ public final class FleetMcp { private static final long ASK_MAX_TIMEOUT_MS = 115_000; private static final ObjectMapper MAPPER = new ObjectMapper(); // worker-view JSON projections - /** - * CB-622: the product is renaming {@code bridge_*} tools to {@code fleet_*}. Both names reach - * the same handler (registered below); this set makes the "old name used" WARN fire once per - * old name for the life of the process, not once per call — a per-name flag, not a numeric - * sentinel, so it survives concurrent callers cleanly and reads unambiguously in a log. - */ - private static final Set WARNED_DEPRECATED_NAMES = ConcurrentHashMap.newKeySet(); - /** Transport-context key under which the extractor stashes the resolved caller identity. */ static final String CALLER_TERMINAL = "callerTerminal"; /** Transport-context key under which the extractor stashes the caller's PID (for cwd inherit). */ @@ -320,30 +312,19 @@ public final class FleetMcp { McpSchema.Tool fleetWhoami = whoamiTool(); this.server = McpServer.sync(transport) - .serverInfo("bridge", "0.1.0") + .serverInfo("fleet", "0.1.0") .capabilities(McpSchema.ServerCapabilities.builder().tools(true).build()) .toolCall(fleetSend, sendHandler) - .toolCall(deprecatedTwin(fleetSend, "bridge_send"), deprecatedHandler(fleetSend, "bridge_send", sendHandler)) .toolCall(fleetReply, replyHandler) - .toolCall(deprecatedTwin(fleetReply, "bridge_reply"), deprecatedHandler(fleetReply, "bridge_reply", replyHandler)) .toolCall(fleetAsk, askHandler) - .toolCall(deprecatedTwin(fleetAsk, "bridge_ask"), deprecatedHandler(fleetAsk, "bridge_ask", askHandler)) .toolCall(fleetStatus, statusHandler) - .toolCall(deprecatedTwin(fleetStatus, "bridge_status"), deprecatedHandler(fleetStatus, "bridge_status", statusHandler)) .toolCall(fleetPoll, pollHandler) - .toolCall(deprecatedTwin(fleetPoll, "bridge_poll"), deprecatedHandler(fleetPoll, "bridge_poll", pollHandler)) .toolCall(fleetAck, ackHandler) - .toolCall(deprecatedTwin(fleetAck, "bridge_ack"), deprecatedHandler(fleetAck, "bridge_ack", ackHandler)) .toolCall(fleetSpawn, spawnHandler) - .toolCall(deprecatedTwin(fleetSpawn, "bridge_spawn"), deprecatedHandler(fleetSpawn, "bridge_spawn", spawnHandler)) .toolCall(fleetList, listHandler) - .toolCall(deprecatedTwin(fleetList, "bridge_list"), deprecatedHandler(fleetList, "bridge_list", listHandler)) .toolCall(fleetStop, stopHandler) - .toolCall(deprecatedTwin(fleetStop, "bridge_stop"), deprecatedHandler(fleetStop, "bridge_stop", stopHandler)) .toolCall(fleetProfiles, profilesHandler) - .toolCall(deprecatedTwin(fleetProfiles, "bridge_profiles"), deprecatedHandler(fleetProfiles, "bridge_profiles", profilesHandler)) .toolCall(fleetWhoami, whoamiHandler) - .toolCall(deprecatedTwin(fleetWhoami, "bridge_whoami"), deprecatedHandler(fleetWhoami, "bridge_whoami", whoamiHandler)) .build(); this.authz = callers; this.metrics = metrics; @@ -647,7 +628,7 @@ public final class FleetMcp { if (leadChannel == null) { return error("lead coordination is not configured (no coordinator: block) — cannot send to " + "peer lead \"" + coordId + "\". Add a coordinator: block with a shared broker uri " - + "and this daemon's selfId, then restart bridged."); + + "and this daemon's selfId, then restart fleetd."); } LeadMessage msg = new LeadMessage(UUID.randomUUID().toString(), leadChannel.selfCoordId(), coordId, content); @@ -993,7 +974,7 @@ public final class FleetMcp { } /** - * Capacity is advisory only. {@code reclaimable} says there is no bridge work, not that bridged + * Capacity is advisory only. {@code reclaimable} says there is no bridge work, not that fleetd * may stop the member: the bridge has capacity facts but no work list, and choosing work needs * authority it does not have. {@code idleForSeconds} is derived from monotonic nanoTime and has * no wall-clock meaning across a daemon restart. @@ -1265,44 +1246,6 @@ public final class FleetMcp { objectSchema(Map.of(), List.of())); } - // --- CB-622: bridge_* -> fleet_* rename, kept working under both names ------------------- - - /** - * The deprecated {@code bridge_*} twin of {@code fleetTool}: same name-minus-prefix schema, - * with a description that leads with the deprecation notice so a client listing tools sees it - * immediately. Reuses {@code fleetTool}'s input schema rather than restating it, so the two - * can never drift on parameters. - */ - static McpSchema.Tool deprecatedTwin(McpSchema.Tool fleetTool, String oldName) { - return tool(oldName, "DEPRECATED: use " + fleetTool.name() + " instead. " + fleetTool.description(), - fleetTool.inputSchema()); - } - - /** - * Wrap {@code handler} so a call under the deprecated {@code oldName} logs one WARN naming - * the old and new name, then runs the exact SAME handler {@code fleetTool}'s name uses — no - * logic is duplicated between the two registrations. - */ - static BiFunction deprecatedHandler( - McpSchema.Tool fleetTool, String oldName, - BiFunction handler) { - return (exchange, req) -> { - warnDeprecatedOnce(oldName, fleetTool.name()); - return handler.apply(exchange, req); - }; - } - - /** - * Log one WARN naming {@code oldName} and {@code newName} — once per {@code oldName} for the - * life of the process, not once per call. {@link #WARNED_DEPRECATED_NAMES} is a per-name flag - * (a {@link Set}), not a call counter, so this never conflates "warned" with any numeric state. - */ - static void warnDeprecatedOnce(String oldName, String newName) { - if (WARNED_DEPRECATED_NAMES.add(oldName)) { - log.warn("{} is deprecated; use {} instead", oldName, newName); - } - } - // --- small helpers ------------------------------------------------------------------------- // The SDK 2.0.0 deprecates its own Tool builders without a stable replacement — isolate it here. diff --git a/bridged/src/main/java/dev/ltms/fleet/mcp/LsofPeerPidLookup.java b/fleetd/src/main/java/dev/ltms/fleet/mcp/LsofPeerPidLookup.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/mcp/LsofPeerPidLookup.java rename to fleetd/src/main/java/dev/ltms/fleet/mcp/LsofPeerPidLookup.java diff --git a/bridged/src/main/java/dev/ltms/fleet/mcp/LsofProcessCwdLookup.java b/fleetd/src/main/java/dev/ltms/fleet/mcp/LsofProcessCwdLookup.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/mcp/LsofProcessCwdLookup.java rename to fleetd/src/main/java/dev/ltms/fleet/mcp/LsofProcessCwdLookup.java diff --git a/bridged/src/main/java/dev/ltms/fleet/mcp/PeerPidLookup.java b/fleetd/src/main/java/dev/ltms/fleet/mcp/PeerPidLookup.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/mcp/PeerPidLookup.java rename to fleetd/src/main/java/dev/ltms/fleet/mcp/PeerPidLookup.java diff --git a/bridged/src/main/java/dev/ltms/fleet/mcp/PrimaryRegistry.java b/fleetd/src/main/java/dev/ltms/fleet/mcp/PrimaryRegistry.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/mcp/PrimaryRegistry.java rename to fleetd/src/main/java/dev/ltms/fleet/mcp/PrimaryRegistry.java diff --git a/bridged/src/main/java/dev/ltms/fleet/mcp/ProcessCwdLookup.java b/fleetd/src/main/java/dev/ltms/fleet/mcp/ProcessCwdLookup.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/mcp/ProcessCwdLookup.java rename to fleetd/src/main/java/dev/ltms/fleet/mcp/ProcessCwdLookup.java diff --git a/bridged/src/main/java/dev/ltms/fleet/member/ClaudeCodeLauncher.java b/fleetd/src/main/java/dev/ltms/fleet/member/ClaudeCodeLauncher.java similarity index 99% rename from bridged/src/main/java/dev/ltms/fleet/member/ClaudeCodeLauncher.java rename to fleetd/src/main/java/dev/ltms/fleet/member/ClaudeCodeLauncher.java index 1a58907..3079c0e 100644 --- a/bridged/src/main/java/dev/ltms/fleet/member/ClaudeCodeLauncher.java +++ b/fleetd/src/main/java/dev/ltms/fleet/member/ClaudeCodeLauncher.java @@ -36,7 +36,7 @@ import java.util.function.Supplier; *

  • {@link #buildLaunch}, which encodes the subscription boundary: build the worker env with * {@code ANTHROPIC_BASE_URL}, assert that host is on the allowlist before touching * herdr, and mount the bridge MCP + reply charter as inline launch flags. A worker's base_url - * lives in the env map handed to herdr and nowhere else; {@code bridged}'s own environment is + * lives in the env map handed to herdr and nowhere else; {@code fleetd}'s own environment is * never mutated, and nothing is written to the worker's profile.
  • * */ @@ -216,7 +216,7 @@ public final class ClaudeCodeLauncher extends HerdrPeerLauncher { // the charter — the charter returns to role -> reply only. Best-effort: a failed overlay // must never fail the spawn, and `writeIdeOverlay` no-ops unless the cwd is a provisioned // worktree (see its .git-file safety gate). The overlay pins, and the auto-open opens, the - // module dir (this repo's pom is in `bridged/`, not at the worktree root) — see ideProjectPath. + // module dir (this repo's pom is in `fleetd/`, not at the worktree root) — see ideProjectPath. if (cfg.hasIdeMcp()) { String projectPath = PeerLauncher.ideProjectPath(spec.cwd(), cfg.ideProjectDir()); writeIdeOverlay(spec.cwd(), projectPath); @@ -239,7 +239,7 @@ public final class ClaudeCodeLauncher extends HerdrPeerLauncher { putIfPresent(workerEnv, "CLAUDE_CONFIG_DIR", cfg.configDir()); applyGitToken(workerEnv, cfg); - // CB-547a: Claude Code can MINT its own session id, so bridged chooses it — a fresh spawn + // CB-547a: Claude Code can MINT its own session id, so fleetd chooses it — a fresh spawn // gets a UUID we pass as --session-id and return from agentSessionId(), so the resume // handle is known BEFORE the agent has written anything; a resume spawn adopts its prior // id via -r and passes no --session-id (the two conflict). Both are injected before the @@ -428,7 +428,7 @@ public final class ClaudeCodeLauncher extends HerdrPeerLauncher { */ private static Path writeCharterFile(String charterText) { try { - Path file = Files.createTempFile("bridged-role-charter-", ".md"); + Path file = Files.createTempFile("fleetd-role-charter-", ".md"); Files.writeString(file, charterText); file.toFile().deleteOnExit(); return file; diff --git a/bridged/src/main/java/dev/ltms/fleet/member/CompositePeerLauncher.java b/fleetd/src/main/java/dev/ltms/fleet/member/CompositePeerLauncher.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/member/CompositePeerLauncher.java rename to fleetd/src/main/java/dev/ltms/fleet/member/CompositePeerLauncher.java diff --git a/bridged/src/main/java/dev/ltms/fleet/member/EnvAllowListScrub.java b/fleetd/src/main/java/dev/ltms/fleet/member/EnvAllowListScrub.java similarity index 99% rename from bridged/src/main/java/dev/ltms/fleet/member/EnvAllowListScrub.java rename to fleetd/src/main/java/dev/ltms/fleet/member/EnvAllowListScrub.java index be8839c..dee7134 100644 --- a/bridged/src/main/java/dev/ltms/fleet/member/EnvAllowListScrub.java +++ b/fleetd/src/main/java/dev/ltms/fleet/member/EnvAllowListScrub.java @@ -64,7 +64,7 @@ public final class EnvAllowListScrub { static final String SCRUB_FILE = "scrub.zsh"; /** Prefix of every generated directory — also what {@link #reapOrphans} matches on. */ - static final String DIR_PREFIX = "bridged-zdotdir-"; + static final String DIR_PREFIX = "fleetd-zdotdir-"; /** * How old an orphan must be before {@link #reapOrphans} removes it. Comfortably longer than any diff --git a/bridged/src/main/java/dev/ltms/fleet/member/HerdrPeerLauncher.java b/fleetd/src/main/java/dev/ltms/fleet/member/HerdrPeerLauncher.java similarity index 99% rename from bridged/src/main/java/dev/ltms/fleet/member/HerdrPeerLauncher.java rename to fleetd/src/main/java/dev/ltms/fleet/member/HerdrPeerLauncher.java index 07e26da..eaaf1ae 100644 --- a/bridged/src/main/java/dev/ltms/fleet/member/HerdrPeerLauncher.java +++ b/fleetd/src/main/java/dev/ltms/fleet/member/HerdrPeerLauncher.java @@ -926,10 +926,10 @@ public abstract class HerdrPeerLauncher implements PeerLauncher { * start a login shell, and it makes the intent explicit at the one place every adapter passes. */ private static final String BLOCKED_CREDENTIAL_SENTINEL = - "blocked-by-bridged-cb596-see-gitea-issue-82"; + "blocked-by-fleetd-cb596-see-gitea-issue-82"; /** - * CB-592: marks a pane as a bridged member so a shell startup file can decline to export + * CB-592: marks a pane as a fleetd member so a shell startup file can decline to export * operator-only credentials into it (gitea issue #77). * *

    This name is deliberately one that {@code secrets.sh} never exports, which is exactly why @@ -952,7 +952,7 @@ public abstract class HerdrPeerLauncher implements PeerLauncher { * Seed a worker's environment (CB-511): the daemon's own {@code PATH}, then the profile's * {@code env:} entries, then the CB-592 admin-token shadow. * - *

    Why this exists: bridged passes herdr an explicit env map, and herdr merges it into + *

    Why this exists: fleetd passes herdr an explicit env map, and herdr merges it into * its own process environment. So before this, a worker inherited whatever PATH the * herdr server happened to be started with — on this host, one from weeks earlier with no JDK * and no Maven, which left workers unable to run the build they were being asked to run. The diff --git a/bridged/src/main/java/dev/ltms/fleet/member/MemberEnvAllowList.java b/fleetd/src/main/java/dev/ltms/fleet/member/MemberEnvAllowList.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/member/MemberEnvAllowList.java rename to fleetd/src/main/java/dev/ltms/fleet/member/MemberEnvAllowList.java diff --git a/bridged/src/main/java/dev/ltms/fleet/member/OpenCodeLauncher.java b/fleetd/src/main/java/dev/ltms/fleet/member/OpenCodeLauncher.java similarity index 98% rename from bridged/src/main/java/dev/ltms/fleet/member/OpenCodeLauncher.java rename to fleetd/src/main/java/dev/ltms/fleet/member/OpenCodeLauncher.java index 673284a..0401d07 100644 --- a/bridged/src/main/java/dev/ltms/fleet/member/OpenCodeLauncher.java +++ b/fleetd/src/main/java/dev/ltms/fleet/member/OpenCodeLauncher.java @@ -308,14 +308,14 @@ public final class OpenCodeLauncher extends HerdrPeerLauncher { */ private Path writeConfig(FleetConfig.Profile cfg, String charterText, String cwd) { try { - Path dir = Files.createTempDirectory(configRoot, "bridged-opencode-"); + Path dir = Files.createTempDirectory(configRoot, "fleetd-opencode-"); dir.toFile().deleteOnExit(); ObjectNode root = JSON.createObjectNode(); root.put("$schema", "https://opencode.ai/config.json"); // CB-523, opencode side: a worker that runs out of context dies mid-turn, and its reply // — the entire point of the turn — is lost with it. Auto-compaction is therefore not an - // operator preference for a bridged worker, it is a condition of the turn contract. + // operator preference for a fleetd worker, it is a condition of the turn contract. // // Stated deliberately even though it is redundant today: OPENCODE_CONFIG is MERGED over // ~/.config/opencode/config.json rather than replacing it, so a worker already inherits @@ -324,7 +324,7 @@ public final class OpenCodeLauncher extends HerdrPeerLauncher { // // Know the cost before removing it: this key WINS over the home config (verified — an // OPENCODE_CONFIG value overrides the home value, it does not defer to it), so an - // operator who sets `compaction.auto: false` at home cannot turn it off for bridged + // operator who sets `compaction.auto: false` at home cannot turn it off for fleetd // workers. That is the intended trade for peers we spawn and whose turns we must land; // if per-profile control is ever wanted, add a profile knob rather than dropping this. root.putObject("compaction").put("auto", true); @@ -357,7 +357,7 @@ public final class OpenCodeLauncher extends HerdrPeerLauncher { ide.put("enabled", true); // CB-634: pin the overlay and open the IDE at the module dir (this repo's pom is - // in `bridged/`, not at the worktree root) — see PeerLauncher.ideProjectPath. + // in `fleetd/`, not at the worktree root) — see PeerLauncher.ideProjectPath. String projectPath = PeerLauncher.ideProjectPath(cwd, cfg.ideProjectDir()); Path rules = dir.resolve("ide-rules.md"); Files.writeString(rules, PeerLauncher.ideOverlayText(projectPath)); @@ -400,7 +400,7 @@ public final class OpenCodeLauncher extends HerdrPeerLauncher { ObjectNode provider = root.putObject("provider").putObject(providerId); provider.put("npm", "@ai-sdk/openai-compatible"); - provider.put("name", providerId + " (bridged)"); + provider.put("name", providerId + " (fleetd)"); ObjectNode options = provider.putObject("options"); options.put("baseURL", openAiBaseUrl(cfg.baseUrl())); diff --git a/bridged/src/main/java/dev/ltms/fleet/member/OpenCodeSessionDiscovery.java b/fleetd/src/main/java/dev/ltms/fleet/member/OpenCodeSessionDiscovery.java similarity index 96% rename from bridged/src/main/java/dev/ltms/fleet/member/OpenCodeSessionDiscovery.java rename to fleetd/src/main/java/dev/ltms/fleet/member/OpenCodeSessionDiscovery.java index ba38179..a5ea50f 100644 --- a/bridged/src/main/java/dev/ltms/fleet/member/OpenCodeSessionDiscovery.java +++ b/fleetd/src/main/java/dev/ltms/fleet/member/OpenCodeSessionDiscovery.java @@ -9,7 +9,7 @@ import java.nio.file.Path; import java.util.stream.Stream; /** - * Resolves the opencode session id for a bridged worker from opencode's on-disk storage — the + * Resolves the opencode session id for a fleetd worker from opencode's on-disk storage — the * only place this adapter touches opencode's private layout, and deliberately the only * class that does. * @@ -22,7 +22,7 @@ import java.util.stream.Stream; * its shape, naming, and field names — lives here, so a layout change, or a switch to the HTTP * server, changes exactly one class and nothing in {@link OpenCodeLauncher}. * - *

    The determinism that makes this useful is structural, not a guess: every bridged worker runs + *

    The determinism that makes this useful is structural, not a guess: every fleetd worker runs * in its own unique git worktree, so the record's {@code directory} (its project root) equals the * worker's cwd identifies its session unambiguously. We match on {@code directory} rather * than diffing {@code opencode session list} before/after — that races under concurrent spawns, and @@ -50,7 +50,7 @@ final class OpenCodeSessionDiscovery { * *

    Never throws: a missing {@code storageRoot}, an unreadable/malformed record, or a * directory that has not been persisted yet all resolve to {@code null} rather than failing a - * spawn. A bridged worker's session record is written lazily (when the session is first + * spawn. A fleetd worker's session record is written lazily (when the session is first * persisted), so {@code null} here is the normal answer right after the pane is ready, and the * caller retries later. * diff --git a/bridged/src/main/java/dev/ltms/fleet/metrics/FleetMetrics.java b/fleetd/src/main/java/dev/ltms/fleet/metrics/FleetMetrics.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/metrics/FleetMetrics.java rename to fleetd/src/main/java/dev/ltms/fleet/metrics/FleetMetrics.java diff --git a/bridged/src/main/java/dev/ltms/fleet/metrics/Metrics.java b/fleetd/src/main/java/dev/ltms/fleet/metrics/Metrics.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/metrics/Metrics.java rename to fleetd/src/main/java/dev/ltms/fleet/metrics/Metrics.java diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/AmqpReplyInbox.java b/fleetd/src/main/java/dev/ltms/fleet/msg/AmqpReplyInbox.java similarity index 99% rename from bridged/src/main/java/dev/ltms/fleet/msg/AmqpReplyInbox.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/AmqpReplyInbox.java index ffd549a..bbb2d9f 100644 --- a/bridged/src/main/java/dev/ltms/fleet/msg/AmqpReplyInbox.java +++ b/fleetd/src/main/java/dev/ltms/fleet/msg/AmqpReplyInbox.java @@ -141,7 +141,7 @@ public final class AmqpReplyInbox implements ReplyInbox, AutoCloseable { // Self-heal transient blips; topology recovery re-declares queues and re-attaches consumers. factory.setAutomaticRecoveryEnabled(true); factory.setTopologyRecoveryEnabled(true); - return new AmqpReplyInbox(factory.newConnection("bridged-reply-inbox"), prefetch); + return new AmqpReplyInbox(factory.newConnection("fleetd-reply-inbox"), prefetch); } catch (Exception e) { throw new IllegalStateException("cannot connect to AMQP broker at " + uri, e); } diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/InMemoryReplyInbox.java b/fleetd/src/main/java/dev/ltms/fleet/msg/InMemoryReplyInbox.java similarity index 96% rename from bridged/src/main/java/dev/ltms/fleet/msg/InMemoryReplyInbox.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/InMemoryReplyInbox.java index 2506473..69d72c9 100644 --- a/bridged/src/main/java/dev/ltms/fleet/msg/InMemoryReplyInbox.java +++ b/fleetd/src/main/java/dev/ltms/fleet/msg/InMemoryReplyInbox.java @@ -16,7 +16,7 @@ import java.util.concurrent.ConcurrentHashMap; * non-broker path stays interchangeable. * *

    This is soft-state, NOT persistence. Lost on a {@code java -jar} bounce — that - * is correct and consistent with "bridged stays soft-state." The Stage-2 AMQP adapter replaces this. + * is correct and consistent with "fleetd stays soft-state." The Stage-2 AMQP adapter replaces this. */ public final class InMemoryReplyInbox implements ReplyInbox { diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/LeadChannel.java b/fleetd/src/main/java/dev/ltms/fleet/msg/LeadChannel.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/msg/LeadChannel.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/LeadChannel.java diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/LeadCoordLoop.java b/fleetd/src/main/java/dev/ltms/fleet/msg/LeadCoordLoop.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/msg/LeadCoordLoop.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/LeadCoordLoop.java diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/LeadHeartbeatLoop.java b/fleetd/src/main/java/dev/ltms/fleet/msg/LeadHeartbeatLoop.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/msg/LeadHeartbeatLoop.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/LeadHeartbeatLoop.java diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/LeadMailbox.java b/fleetd/src/main/java/dev/ltms/fleet/msg/LeadMailbox.java similarity index 99% rename from bridged/src/main/java/dev/ltms/fleet/msg/LeadMailbox.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/LeadMailbox.java index f3c8e68..b99046d 100644 --- a/bridged/src/main/java/dev/ltms/fleet/msg/LeadMailbox.java +++ b/fleetd/src/main/java/dev/ltms/fleet/msg/LeadMailbox.java @@ -127,7 +127,7 @@ public final class LeadMailbox implements LeadChannel, AutoCloseable { // Self-heal transient blips; topology recovery re-declares the queue and re-attaches the consumer. factory.setAutomaticRecoveryEnabled(true); factory.setTopologyRecoveryEnabled(true); - return new LeadMailbox(factory.newConnection("bridged-lead-mailbox"), selfCoordId, prefetch); + return new LeadMailbox(factory.newConnection("fleetd-lead-mailbox"), selfCoordId, prefetch); } catch (Exception e) { throw new IllegalStateException("cannot connect to AMQP coordination broker at " + uri, e); } diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/LeadMessage.java b/fleetd/src/main/java/dev/ltms/fleet/msg/LeadMessage.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/msg/LeadMessage.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/LeadMessage.java diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/MessageService.java b/fleetd/src/main/java/dev/ltms/fleet/msg/MessageService.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/msg/MessageService.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/MessageService.java diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/Rendezvous.java b/fleetd/src/main/java/dev/ltms/fleet/msg/Rendezvous.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/msg/Rendezvous.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/Rendezvous.java diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/ReplyInbox.java b/fleetd/src/main/java/dev/ltms/fleet/msg/ReplyInbox.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/msg/ReplyInbox.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/ReplyInbox.java diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/ReplyPushLoop.java b/fleetd/src/main/java/dev/ltms/fleet/msg/ReplyPushLoop.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/msg/ReplyPushLoop.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/ReplyPushLoop.java diff --git a/bridged/src/main/java/dev/ltms/fleet/msg/TurnToken.java b/fleetd/src/main/java/dev/ltms/fleet/msg/TurnToken.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/msg/TurnToken.java rename to fleetd/src/main/java/dev/ltms/fleet/msg/TurnToken.java diff --git a/bridged/src/main/java/dev/ltms/fleet/peer/Capability.java b/fleetd/src/main/java/dev/ltms/fleet/peer/Capability.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/peer/Capability.java rename to fleetd/src/main/java/dev/ltms/fleet/peer/Capability.java diff --git a/bridged/src/main/java/dev/ltms/fleet/peer/CharterReceipt.java b/fleetd/src/main/java/dev/ltms/fleet/peer/CharterReceipt.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/peer/CharterReceipt.java rename to fleetd/src/main/java/dev/ltms/fleet/peer/CharterReceipt.java diff --git a/bridged/src/main/java/dev/ltms/fleet/peer/MemberRole.java b/fleetd/src/main/java/dev/ltms/fleet/peer/MemberRole.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/peer/MemberRole.java rename to fleetd/src/main/java/dev/ltms/fleet/peer/MemberRole.java diff --git a/bridged/src/main/java/dev/ltms/fleet/peer/PeerHandle.java b/fleetd/src/main/java/dev/ltms/fleet/peer/PeerHandle.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/peer/PeerHandle.java rename to fleetd/src/main/java/dev/ltms/fleet/peer/PeerHandle.java diff --git a/bridged/src/main/java/dev/ltms/fleet/peer/PeerLauncher.java b/fleetd/src/main/java/dev/ltms/fleet/peer/PeerLauncher.java similarity index 99% rename from bridged/src/main/java/dev/ltms/fleet/peer/PeerLauncher.java rename to fleetd/src/main/java/dev/ltms/fleet/peer/PeerLauncher.java index 8b36f66..a80184c 100644 --- a/bridged/src/main/java/dev/ltms/fleet/peer/PeerLauncher.java +++ b/fleetd/src/main/java/dev/ltms/fleet/peer/PeerLauncher.java @@ -59,7 +59,7 @@ public interface PeerLauncher { * The absolute path IntelliJ must open as the project, and the {@code project_path} the overlay * pins (CB-634). It is {@code cwd} resolved against {@code ideProjectDir}. The distinction * matters because this repo (like {@code fleet/fleetd}) keeps its Maven module in a subdir - * ({@code bridged/}), not at the worktree root: opening the root imports no module and + * ({@code fleetd/}), not at the worktree root: opening the root imports no module and * {@code ide_*} resolves nothing, so the module dir is the correct pin and open target. * * @param cwd the member's worktree root diff --git a/bridged/src/main/java/dev/ltms/fleet/peer/PeerUnreachableException.java b/fleetd/src/main/java/dev/ltms/fleet/peer/PeerUnreachableException.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/peer/PeerUnreachableException.java rename to fleetd/src/main/java/dev/ltms/fleet/peer/PeerUnreachableException.java diff --git a/bridged/src/main/java/dev/ltms/fleet/peer/SpawnRequest.java b/fleetd/src/main/java/dev/ltms/fleet/peer/SpawnRequest.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/peer/SpawnRequest.java rename to fleetd/src/main/java/dev/ltms/fleet/peer/SpawnRequest.java diff --git a/bridged/src/main/java/dev/ltms/fleet/placement/BackendQuarantine.java b/fleetd/src/main/java/dev/ltms/fleet/placement/BackendQuarantine.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/placement/BackendQuarantine.java rename to fleetd/src/main/java/dev/ltms/fleet/placement/BackendQuarantine.java diff --git a/bridged/src/main/java/dev/ltms/fleet/placement/FixedPlacementPolicy.java b/fleetd/src/main/java/dev/ltms/fleet/placement/FixedPlacementPolicy.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/placement/FixedPlacementPolicy.java rename to fleetd/src/main/java/dev/ltms/fleet/placement/FixedPlacementPolicy.java diff --git a/bridged/src/main/java/dev/ltms/fleet/placement/PlacementCandidate.java b/fleetd/src/main/java/dev/ltms/fleet/placement/PlacementCandidate.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/placement/PlacementCandidate.java rename to fleetd/src/main/java/dev/ltms/fleet/placement/PlacementCandidate.java diff --git a/bridged/src/main/java/dev/ltms/fleet/placement/PlacementContext.java b/fleetd/src/main/java/dev/ltms/fleet/placement/PlacementContext.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/placement/PlacementContext.java rename to fleetd/src/main/java/dev/ltms/fleet/placement/PlacementContext.java diff --git a/bridged/src/main/java/dev/ltms/fleet/placement/PlacementException.java b/fleetd/src/main/java/dev/ltms/fleet/placement/PlacementException.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/placement/PlacementException.java rename to fleetd/src/main/java/dev/ltms/fleet/placement/PlacementException.java diff --git a/bridged/src/main/java/dev/ltms/fleet/placement/PlacementPolicies.java b/fleetd/src/main/java/dev/ltms/fleet/placement/PlacementPolicies.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/placement/PlacementPolicies.java rename to fleetd/src/main/java/dev/ltms/fleet/placement/PlacementPolicies.java diff --git a/bridged/src/main/java/dev/ltms/fleet/placement/PlacementPolicy.java b/fleetd/src/main/java/dev/ltms/fleet/placement/PlacementPolicy.java similarity index 84% rename from bridged/src/main/java/dev/ltms/fleet/placement/PlacementPolicy.java rename to fleetd/src/main/java/dev/ltms/fleet/placement/PlacementPolicy.java index ced0f5d..771a6da 100644 --- a/bridged/src/main/java/dev/ltms/fleet/placement/PlacementPolicy.java +++ b/fleetd/src/main/java/dev/ltms/fleet/placement/PlacementPolicy.java @@ -1,7 +1,7 @@ package dev.ltms.fleet.placement; /** - * How {@code bridged} chooses a worker profile when a spawn names none. Implementations are + * How {@code fleetd} chooses a worker profile when a spawn names none. Implementations are * deterministic and unit-testable; the caller (the composite launcher) handles failover retries. */ public interface PlacementPolicy { diff --git a/bridged/src/main/java/dev/ltms/fleet/placement/PlacementPolicyUtil.java b/fleetd/src/main/java/dev/ltms/fleet/placement/PlacementPolicyUtil.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/placement/PlacementPolicyUtil.java rename to fleetd/src/main/java/dev/ltms/fleet/placement/PlacementPolicyUtil.java diff --git a/bridged/src/main/java/dev/ltms/fleet/placement/RoundRobinPlacementPolicy.java b/fleetd/src/main/java/dev/ltms/fleet/placement/RoundRobinPlacementPolicy.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/placement/RoundRobinPlacementPolicy.java rename to fleetd/src/main/java/dev/ltms/fleet/placement/RoundRobinPlacementPolicy.java diff --git a/bridged/src/main/java/dev/ltms/fleet/placement/WeightedRoundRobinPolicy.java b/fleetd/src/main/java/dev/ltms/fleet/placement/WeightedRoundRobinPolicy.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/placement/WeightedRoundRobinPolicy.java rename to fleetd/src/main/java/dev/ltms/fleet/placement/WeightedRoundRobinPolicy.java diff --git a/bridged/src/main/java/dev/ltms/fleet/rest/FleetApp.java b/fleetd/src/main/java/dev/ltms/fleet/rest/FleetApp.java similarity index 99% rename from bridged/src/main/java/dev/ltms/fleet/rest/FleetApp.java rename to fleetd/src/main/java/dev/ltms/fleet/rest/FleetApp.java index 04f1b49..0b2d247 100644 --- a/bridged/src/main/java/dev/ltms/fleet/rest/FleetApp.java +++ b/fleetd/src/main/java/dev/ltms/fleet/rest/FleetApp.java @@ -34,7 +34,7 @@ import java.util.function.Function; import java.util.stream.Collectors; /** - * The REST surface — {@code bridged}'s contract and its testability seam. Every + * The REST surface — {@code fleetd}'s contract and its testability seam. Every * feature is reachable here without Claude or MCP in the loop, so each is an * acceptance test against plain HTTP. MCP tools (later) are thin adapters over these * same endpoints and are validated by parity, not by re-implementing behaviour. @@ -52,7 +52,7 @@ public final class FleetApp { private static final long MAX_ASK_TIMEOUT_MS = 115_000; /** Context attribute under which the resolved caller is stashed by the auth filter. */ - private static final String CALLER = "bridged.caller"; + private static final String CALLER = "fleetd.caller"; private final HerdrClient herdr; private final PeerLauncher workers; diff --git a/bridged/src/main/java/dev/ltms/fleet/session/GitWorktrees.java b/fleetd/src/main/java/dev/ltms/fleet/session/GitWorktrees.java similarity index 99% rename from bridged/src/main/java/dev/ltms/fleet/session/GitWorktrees.java rename to fleetd/src/main/java/dev/ltms/fleet/session/GitWorktrees.java index 990534a..ceaf80b 100644 --- a/bridged/src/main/java/dev/ltms/fleet/session/GitWorktrees.java +++ b/fleetd/src/main/java/dev/ltms/fleet/session/GitWorktrees.java @@ -252,7 +252,7 @@ public final class GitWorktrees implements Worktrees { } Path tempIndex; try { - tempIndex = Files.createTempFile("bridged-wip-index-", ".tmp"); + tempIndex = Files.createTempFile("fleetd-wip-index-", ".tmp"); } catch (IOException e) { throw new WorktreeException("cannot create a temporary index for snapshot: " + e.getMessage(), e); } diff --git a/bridged/src/main/java/dev/ltms/fleet/session/MemberSession.java b/fleetd/src/main/java/dev/ltms/fleet/session/MemberSession.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/session/MemberSession.java rename to fleetd/src/main/java/dev/ltms/fleet/session/MemberSession.java diff --git a/bridged/src/main/java/dev/ltms/fleet/session/SessionManager.java b/fleetd/src/main/java/dev/ltms/fleet/session/SessionManager.java similarity index 99% rename from bridged/src/main/java/dev/ltms/fleet/session/SessionManager.java rename to fleetd/src/main/java/dev/ltms/fleet/session/SessionManager.java index a69c424..c502dbe 100644 --- a/bridged/src/main/java/dev/ltms/fleet/session/SessionManager.java +++ b/fleetd/src/main/java/dev/ltms/fleet/session/SessionManager.java @@ -26,7 +26,7 @@ import java.util.function.Consumer; import java.util.function.LongSupplier; /** - * Authoritative in-daemon registry of the worker sessions this {@code bridged} process spawned. + * Authoritative in-daemon registry of the worker sessions this {@code fleetd} process spawned. * Delegates spawn/teardown to a {@link PeerLauncher} (which performs subscription-guarded env * setup and process/materialization) and adds lifecycle tracking, ownership, and deterministic * teardown on top. @@ -57,7 +57,7 @@ public final class SessionManager implements TurnListener { * CB-586: the repo root the fleet actually works in, remembered the first time a worktree * session is spawned (worktrees are checkouts of it). {@code refs/wip/*} live there, and this * single cached value is what the snapshot retention sweep and the operator-visible census run - * against. The daemon is bridged into one project at a time, so "the first worktree's repo" is + * against. The daemon is fleetd into one project at a time, so "the first worktree's repo" is * the repo; {@code null} until any worktree is spawned, meaning nothing to sweep or measure. */ private volatile String fleetRepoRoot; diff --git a/bridged/src/main/java/dev/ltms/fleet/session/SessionReaper.java b/fleetd/src/main/java/dev/ltms/fleet/session/SessionReaper.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/session/SessionReaper.java rename to fleetd/src/main/java/dev/ltms/fleet/session/SessionReaper.java diff --git a/bridged/src/main/java/dev/ltms/fleet/session/WorktreeException.java b/fleetd/src/main/java/dev/ltms/fleet/session/WorktreeException.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/session/WorktreeException.java rename to fleetd/src/main/java/dev/ltms/fleet/session/WorktreeException.java diff --git a/bridged/src/main/java/dev/ltms/fleet/session/WorktreeRequest.java b/fleetd/src/main/java/dev/ltms/fleet/session/WorktreeRequest.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/session/WorktreeRequest.java rename to fleetd/src/main/java/dev/ltms/fleet/session/WorktreeRequest.java diff --git a/bridged/src/main/java/dev/ltms/fleet/session/Worktrees.java b/fleetd/src/main/java/dev/ltms/fleet/session/Worktrees.java similarity index 100% rename from bridged/src/main/java/dev/ltms/fleet/session/Worktrees.java rename to fleetd/src/main/java/dev/ltms/fleet/session/Worktrees.java diff --git a/bridged/src/main/resources/logback.xml b/fleetd/src/main/resources/logback.xml similarity index 100% rename from bridged/src/main/resources/logback.xml rename to fleetd/src/main/resources/logback.xml diff --git a/bridged/src/test/java/dev/ltms/fleet/FleetDeliverabilityTest.java b/fleetd/src/test/java/dev/ltms/fleet/FleetDeliverabilityTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/FleetDeliverabilityTest.java rename to fleetd/src/test/java/dev/ltms/fleet/FleetDeliverabilityTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/FleetdDefaultConfigFileTest.java b/fleetd/src/test/java/dev/ltms/fleet/FleetdDefaultConfigFileTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/FleetdDefaultConfigFileTest.java rename to fleetd/src/test/java/dev/ltms/fleet/FleetdDefaultConfigFileTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/FleetdLeadMailboxSelectionTest.java b/fleetd/src/test/java/dev/ltms/fleet/FleetdLeadMailboxSelectionTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/FleetdLeadMailboxSelectionTest.java rename to fleetd/src/test/java/dev/ltms/fleet/FleetdLeadMailboxSelectionTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/FleetdReplyInboxSelectionTest.java b/fleetd/src/test/java/dev/ltms/fleet/FleetdReplyInboxSelectionTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/FleetdReplyInboxSelectionTest.java rename to fleetd/src/test/java/dev/ltms/fleet/FleetdReplyInboxSelectionTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/MemberCredentialsGapReportTest.java b/fleetd/src/test/java/dev/ltms/fleet/MemberCredentialsGapReportTest.java similarity index 98% rename from bridged/src/test/java/dev/ltms/fleet/MemberCredentialsGapReportTest.java rename to fleetd/src/test/java/dev/ltms/fleet/MemberCredentialsGapReportTest.java index b60aa04..3410df3 100644 --- a/bridged/src/test/java/dev/ltms/fleet/MemberCredentialsGapReportTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/MemberCredentialsGapReportTest.java @@ -23,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class MemberCredentialsGapReportTest { private static FleetConfig load(Path dir, String yaml) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml); return FleetConfig.load(f); } diff --git a/bridged/src/test/java/dev/ltms/fleet/RequiredSecretEnvVarsTest.java b/fleetd/src/test/java/dev/ltms/fleet/RequiredSecretEnvVarsTest.java similarity index 98% rename from bridged/src/test/java/dev/ltms/fleet/RequiredSecretEnvVarsTest.java rename to fleetd/src/test/java/dev/ltms/fleet/RequiredSecretEnvVarsTest.java index 8f9d648..d8dbfde 100644 --- a/bridged/src/test/java/dev/ltms/fleet/RequiredSecretEnvVarsTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/RequiredSecretEnvVarsTest.java @@ -21,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class RequiredSecretEnvVarsTest { private static FleetConfig load(Path dir, String yaml) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml); return FleetConfig.load(f); } diff --git a/bridged/src/test/java/dev/ltms/fleet/auth/AuditLogTest.java b/fleetd/src/test/java/dev/ltms/fleet/auth/AuditLogTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/auth/AuditLogTest.java rename to fleetd/src/test/java/dev/ltms/fleet/auth/AuditLogTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/auth/AuthzTest.java b/fleetd/src/test/java/dev/ltms/fleet/auth/AuthzTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/auth/AuthzTest.java rename to fleetd/src/test/java/dev/ltms/fleet/auth/AuthzTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/auth/CallerResolverTest.java b/fleetd/src/test/java/dev/ltms/fleet/auth/CallerResolverTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/auth/CallerResolverTest.java rename to fleetd/src/test/java/dev/ltms/fleet/auth/CallerResolverTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/auth/MemberRegistryTest.java b/fleetd/src/test/java/dev/ltms/fleet/auth/MemberRegistryTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/auth/MemberRegistryTest.java rename to fleetd/src/test/java/dev/ltms/fleet/auth/MemberRegistryTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/config/ConfigRefTest.java b/fleetd/src/test/java/dev/ltms/fleet/config/ConfigRefTest.java similarity index 95% rename from bridged/src/test/java/dev/ltms/fleet/config/ConfigRefTest.java rename to fleetd/src/test/java/dev/ltms/fleet/config/ConfigRefTest.java index 3f8e393..44ea0fe 100644 --- a/bridged/src/test/java/dev/ltms/fleet/config/ConfigRefTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/config/ConfigRefTest.java @@ -9,7 +9,7 @@ import java.nio.file.Path; import static org.junit.jupiter.api.Assertions.*; /** - * CB-559: re-reading {@code bridged.yaml} under a running daemon. + * CB-559: re-reading {@code fleetd.yaml} under a running daemon. * *

    The tests that matter here are the refusals. A reload that applies a good file is the easy * half; the half that protects an operator is the one that keeps the running config when the new @@ -40,7 +40,7 @@ class ConfigRefTest { @Test void aHotChangeIsAppliedAndReadThroughGet(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml(""" fleet: tabLabel: "{role}: {profile} #{n}" @@ -68,7 +68,7 @@ class ConfigRefTest { @Test void aCharterChangeIsHotAndReachesTheLiveConfig(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml(""" fleet: charters: @@ -93,7 +93,7 @@ class ConfigRefTest { @Test void invalidChartersRefuseReloadAndKeepTheRunningConfig(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml(""" fleet: charters: @@ -130,7 +130,7 @@ class ConfigRefTest { */ @Test void aConsumerHoldingTheRefSeesTheNewValue(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml("placement: weighted\n")); ConfigRef ref = refFor(f); java.util.function.Supplier reader = () -> ref.get().placement(); @@ -144,7 +144,7 @@ class ConfigRefTest { @Test void aChangedColdKeyRefusesTheWholeReload(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml("placement: weighted\n")); ConfigRef ref = refFor(f); @@ -154,7 +154,7 @@ class ConfigRefTest { assertFalse(out.applied()); assertEquals(java.util.List.of("bind"), out.coldKeys()); - assertTrue(out.summary().contains("Restart bridged"), out.summary()); + assertTrue(out.summary().contains("Restart fleetd"), out.summary()); // The hot half must NOT have leaked in. A half-applied reload leaves the daemon matching no // file on disk, which is worse for an operator than no reload at all. assertEquals("weighted", ref.get().placement()); @@ -163,7 +163,7 @@ class ConfigRefTest { @Test void aFileThatNoLongerParsesKeepsTheRunningConfig(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml("placement: weighted\n")); ConfigRef ref = refFor(f); FleetConfig before = ref.get(); @@ -180,7 +180,7 @@ class ConfigRefTest { /** A file that would have refused to boot must not be able to slip in through a reload. */ @Test void aFileThatFailsAValidatorKeepsTheRunningConfig(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml("placement: weighted\n")); ConfigRef ref = refFor(f); FleetConfig before = ref.get(); @@ -202,7 +202,7 @@ class ConfigRefTest { @Test void aDeletedFileIsRefusedRatherThanCrashing(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml("")); ConfigRef ref = refFor(f); FleetConfig before = ref.get(); @@ -218,7 +218,7 @@ class ConfigRefTest { /** A deferred change applies to the snapshot but the operator is told it needs a restart. */ @Test void aDeferredChangeIsAppliedAndReported(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml(""" lifecycle: drainTimeoutSeconds: 30 @@ -244,7 +244,7 @@ class ConfigRefTest { */ @Test void addingAProfileIsReportedAsDeferred(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml("")); ConfigRef ref = refFor(f); @@ -277,7 +277,7 @@ class ConfigRefTest { */ @Test void changingAProfilesWeightOrMaxLoadIsHot(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml("")); ConfigRef ref = refFor(f); @@ -311,7 +311,7 @@ class ConfigRefTest { */ @Test void changingAProfilesLaunchSettingsIsReportedAsDeferred(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, yaml("")); ConfigRef ref = refFor(f); @@ -345,7 +345,7 @@ class ConfigRefTest { */ @Test void changingAProfilesExhaustedPatternIsReportedAsDeferred(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, """ bind: host: 127.0.0.1 diff --git a/bridged/src/test/java/dev/ltms/fleet/config/ConfigWatcherTest.java b/fleetd/src/test/java/dev/ltms/fleet/config/ConfigWatcherTest.java similarity index 96% rename from bridged/src/test/java/dev/ltms/fleet/config/ConfigWatcherTest.java rename to fleetd/src/test/java/dev/ltms/fleet/config/ConfigWatcherTest.java index b4b7942..482e23e 100644 --- a/bridged/src/test/java/dev/ltms/fleet/config/ConfigWatcherTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/config/ConfigWatcherTest.java @@ -39,7 +39,7 @@ class ConfigWatcherTest { @Test void aChangedMtimeTriggersAReload(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); write(f, yaml("weighted"), 1_000L); ConfigRef ref = new ConfigRef(f, FleetConfig.load(f)); @@ -56,7 +56,7 @@ class ConfigWatcherTest { @Test void anUnchangedFileIsNotReloaded(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); write(f, yaml("weighted"), 1_000L); ConfigRef ref = new ConfigRef(f, FleetConfig.load(f)); FleetConfig before = ref.get(); @@ -79,7 +79,7 @@ class ConfigWatcherTest { */ @Test void aRefusedReloadIsNotRetriedUntilTheFileChangesAgain(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); write(f, yaml("weighted"), 1_000L); ConfigRef ref = new ConfigRef(f, FleetConfig.load(f)); FleetConfig before = ref.get(); @@ -110,7 +110,7 @@ class ConfigWatcherTest { */ @Test void aMissingFileIsSkippedAndTheNextTickTriesAgain(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); write(f, yaml("weighted"), 1_000L); ConfigRef ref = new ConfigRef(f, FleetConfig.load(f)); FleetConfig before = ref.get(); @@ -145,7 +145,7 @@ class ConfigWatcherTest { @Test void configReloadIsOffUnlessTheBlockSaysOtherwise(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); write(f, yaml("weighted"), 1_000L); assertNull(FleetConfig.load(f).configReload()); diff --git a/bridged/src/test/java/dev/ltms/fleet/config/FleetConfigTest.java b/fleetd/src/test/java/dev/ltms/fleet/config/FleetConfigTest.java similarity index 99% rename from bridged/src/test/java/dev/ltms/fleet/config/FleetConfigTest.java rename to fleetd/src/test/java/dev/ltms/fleet/config/FleetConfigTest.java index d98990d..7b90c71 100644 --- a/bridged/src/test/java/dev/ltms/fleet/config/FleetConfigTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/config/FleetConfigTest.java @@ -19,7 +19,7 @@ class FleetConfigTest { @Test void loadsFullConfig(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, """ bind: host: 127.0.0.1 @@ -438,7 +438,7 @@ class FleetConfigTest { } /** - * The hazard the guard exists for: bridged writes worker tab labels and reads lead tab labels. + * The hazard the guard exists for: fleetd writes worker tab labels and reads lead tab labels. * Overlap the two and every worker it spawns is read back as a lead. */ @Test @@ -1190,7 +1190,7 @@ class FleetConfigTest { FleetConfig cfg = FleetConfig.load(f); assertNotNull(cfg.auth(), "auth must default rather than be null"); assertFalse(cfg.auth().tokenMode()); - assertEquals("BRIDGED_API_TOKEN", cfg.auth().tokenEnv(), "documented default env var"); + assertEquals("FLEETD_API_TOKEN", cfg.auth().tokenEnv(), "documented default env var"); assertDoesNotThrow(cfg::validateAuthExposure, "loopback + loopback-trust is the safe pairing"); } @@ -1343,7 +1343,7 @@ class FleetConfigTest { /** * A top-level key {@code FleetConfig} reads but that appears nowhere in - * {@code fleetd.example.yaml} — live or commented — is invisible drift: {@code bridged.yaml} + * {@code fleetd.example.yaml} — live or commented — is invisible drift: {@code fleetd.yaml} * is gitignored, so the example is the ONLY committed description of the config schema, and * neither {@link #shippedExampleConfigParses} (example → code: does the example still parse) * nor {@link #everyOptionalKnobDocumentedInTheExampleBinds} (a hand-maintained list of keys @@ -1366,7 +1366,7 @@ class FleetConfigTest { assertTrue(undocumented.isEmpty(), () -> "key(s) " + undocumented + " are read by FleetConfig but appear nowhere in fleetd.example.yaml — " - + "document each one there, commented out if optional. bridged.yaml is " + + "document each one there, commented out if optional. fleetd.yaml is " + "gitignored, so this file is the only committed description of the config " + "schema an operator or a worker can see."); } @@ -1874,7 +1874,7 @@ class FleetConfigTest { */ @Test void aConfigStillUsingTheOldWorkersKeyIsRejectedAndNamesTheNewKey(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, """ workers: gx10: @@ -1888,7 +1888,7 @@ class FleetConfigTest { @Test void everyRenamedTopLevelKeyIsReportedAtOnce(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, """ workers: gx10: @@ -1907,7 +1907,7 @@ class FleetConfigTest { @Test void aMemberSlotCarriesBothItsRoleAndItsProfile(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, """ profiles: gx10: @@ -1937,7 +1937,7 @@ class FleetConfigTest { */ @Test void twoMembersWithDifferentRolesMayShareOneProfile(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, """ profiles: gx10: @@ -1968,7 +1968,7 @@ class FleetConfigTest { @Test void aMisspelledPoolNameDeclaresNoMembersRatherThanRolelessOnes(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, """ profiles: gx10: @@ -1999,7 +1999,7 @@ class FleetConfigTest { @Test void aSlotWithNoProfileIsRejectedAndNamesItsPool(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, """ profiles: gx10: @@ -2017,7 +2017,7 @@ class FleetConfigTest { @Test void theProfilesMapIsNormalizedOnceAtConstruction(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, """ profiles: gx10: @@ -2038,7 +2038,7 @@ class FleetConfigTest { @Test void effectiveDefaultProfileFallsBackToTheFirstConfiguredProfile(@TempDir Path dir) throws Exception { - Path f = dir.resolve("bridged.yaml"); + Path f = dir.resolve("fleetd.yaml"); Files.writeString(f, """ profiles: gx10: diff --git a/bridged/src/test/java/dev/ltms/fleet/guard/SubscriptionGuardTest.java b/fleetd/src/test/java/dev/ltms/fleet/guard/SubscriptionGuardTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/guard/SubscriptionGuardTest.java rename to fleetd/src/test/java/dev/ltms/fleet/guard/SubscriptionGuardTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/health/FleetHealthMonitorTest.java b/fleetd/src/test/java/dev/ltms/fleet/health/FleetHealthMonitorTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/health/FleetHealthMonitorTest.java rename to fleetd/src/test/java/dev/ltms/fleet/health/FleetHealthMonitorTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/health/FleetHealthTest.java b/fleetd/src/test/java/dev/ltms/fleet/health/FleetHealthTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/health/FleetHealthTest.java rename to fleetd/src/test/java/dev/ltms/fleet/health/FleetHealthTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/health/PaneBudgetTest.java b/fleetd/src/test/java/dev/ltms/fleet/health/PaneBudgetTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/health/PaneBudgetTest.java rename to fleetd/src/test/java/dev/ltms/fleet/health/PaneBudgetTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/herdr/AgentControlContractTest.java b/fleetd/src/test/java/dev/ltms/fleet/herdr/AgentControlContractTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/herdr/AgentControlContractTest.java rename to fleetd/src/test/java/dev/ltms/fleet/herdr/AgentControlContractTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/herdr/AgentControlTest.java b/fleetd/src/test/java/dev/ltms/fleet/herdr/AgentControlTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/herdr/AgentControlTest.java rename to fleetd/src/test/java/dev/ltms/fleet/herdr/AgentControlTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/herdr/AgentStatusTest.java b/fleetd/src/test/java/dev/ltms/fleet/herdr/AgentStatusTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/herdr/AgentStatusTest.java rename to fleetd/src/test/java/dev/ltms/fleet/herdr/AgentStatusTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/herdr/FakeHerdr.java b/fleetd/src/test/java/dev/ltms/fleet/herdr/FakeHerdr.java similarity index 99% rename from bridged/src/test/java/dev/ltms/fleet/herdr/FakeHerdr.java rename to fleetd/src/test/java/dev/ltms/fleet/herdr/FakeHerdr.java index 27b5af2..cf86610 100644 --- a/bridged/src/test/java/dev/ltms/fleet/herdr/FakeHerdr.java +++ b/fleetd/src/test/java/dev/ltms/fleet/herdr/FakeHerdr.java @@ -234,7 +234,7 @@ public final class FakeHerdr implements HerdrClient { "tab_id":"w1:t1"}}"""); case "workspace.create" -> mapper.readTree(""" {"type":"workspace_created", - "workspace":{"workspace_id":"w9","label":"bridged-workers","focused":false, + "workspace":{"workspace_id":"w9","label":"fleetd-workers","focused":false, "pane_count":1,"tab_count":1,"active_tab_id":"w9:t1","agent_status":"unknown"}, "tab":{"tab_id":"w9:t1","workspace_id":"w9","label":"1","pane_count":1}, "root_pane":{"pane_id":"w9:p1","workspace_id":"w9","tab_id":"w9:t1"}}"""); diff --git a/bridged/src/test/java/dev/ltms/fleet/herdr/HerdrCodecTest.java b/fleetd/src/test/java/dev/ltms/fleet/herdr/HerdrCodecTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/herdr/HerdrCodecTest.java rename to fleetd/src/test/java/dev/ltms/fleet/herdr/HerdrCodecTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/herdr/HerdrContractTest.java b/fleetd/src/test/java/dev/ltms/fleet/herdr/HerdrContractTest.java similarity index 94% rename from bridged/src/test/java/dev/ltms/fleet/herdr/HerdrContractTest.java rename to fleetd/src/test/java/dev/ltms/fleet/herdr/HerdrContractTest.java index b0278af..49c8c32 100644 --- a/bridged/src/test/java/dev/ltms/fleet/herdr/HerdrContractTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/herdr/HerdrContractTest.java @@ -13,7 +13,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * Contract test against a REAL running herdr. Tagged {@code contract} so it is * excluded from {@code mvn test}; run it with {@code mvn test -Pcontract}. It fails - * loudly if herdr drifts from the protocol {@code bridged} was built against + * loudly if herdr drifts from the protocol {@code fleetd} was built against * (0.7.0, protocol 14) — catching breakage that unit tests with canned frames cannot. */ @Tag("contract") @@ -30,7 +30,7 @@ class HerdrContractTest { JsonNode pong = herdr.call("ping"); assertEquals("pong", pong.get("type").asText()); assertEquals(14, pong.get("protocol").asInt(), - "bridged is built against herdr protocol 14"); + "fleetd is built against herdr protocol 14"); assertFalse(pong.get("version").asText().isBlank()); } } diff --git a/bridged/src/test/java/dev/ltms/fleet/herdr/LeadTabScannerTest.java b/fleetd/src/test/java/dev/ltms/fleet/herdr/LeadTabScannerTest.java similarity index 97% rename from bridged/src/test/java/dev/ltms/fleet/herdr/LeadTabScannerTest.java rename to fleetd/src/test/java/dev/ltms/fleet/herdr/LeadTabScannerTest.java index f581806..baea30c 100644 --- a/bridged/src/test/java/dev/ltms/fleet/herdr/LeadTabScannerTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/herdr/LeadTabScannerTest.java @@ -101,7 +101,7 @@ class LeadTabScannerTest { } /** - * The usual shape: one user space with lead tabs, one worker space bridged owns. + * The usual shape: one user space with lead tabs, one worker space fleetd owns. * *

    Not closed: {@code close()} is a no-op on this fake, and every test needs the handle after * the scanner is built (to mutate the topology or read {@code calls}). @@ -110,7 +110,7 @@ class LeadTabScannerTest { private TopologyHerdr twoLeads() { return new TopologyHerdr() .workspace("w1", "main") - .workspace("w9", "bridged-workers") + .workspace("w9", "fleetd-workers") .tab("w1:t1", "w1", "lead: opus-5.0") .tab("w1:t2", "w1", "lead: gpt-sol-5.6") .tab("w1:t3", "w1", "notes") @@ -128,7 +128,7 @@ class LeadTabScannerTest { private LeadTabScanner scanner(TopologyHerdr herdr, Map tabToName, AtomicLong clock) { - return new LeadTabScanner(herdr, tabToName, Set.of("bridged-workers"), TTL, clock::get); + return new LeadTabScanner(herdr, tabToName, Set.of("fleetd-workers"), TTL, clock::get); } @Test @@ -166,7 +166,7 @@ class LeadTabScannerTest { } /** - * The guard that matters: bridged labels its own worker tabs, so if a worker space were scanned + * The guard that matters: fleetd labels its own worker tabs, so if a worker space were scanned * a naming accident would promote the fleet. The exclusion is by workspace, not by hoping the * worker template never collides. */ @@ -201,7 +201,7 @@ class LeadTabScannerTest { @Test void everyPaneInALeadTabResolvesAsThatLead() { // A human may split their own lead tab. Both panes are theirs, so both are that lead — - // nothing bridged placed can land here (see the worker-space test above). + // nothing fleetd placed can land here (see the worker-space test above). TopologyHerdr herdr = twoLeads().pane("w1:p1b", "w1:t1", "term_opus_split"); assertEquals("opus-5.0", diff --git a/bridged/src/test/java/dev/ltms/fleet/herdr/PaneLocatorContractTest.java b/fleetd/src/test/java/dev/ltms/fleet/herdr/PaneLocatorContractTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/herdr/PaneLocatorContractTest.java rename to fleetd/src/test/java/dev/ltms/fleet/herdr/PaneLocatorContractTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/herdr/PaneLocatorTest.java b/fleetd/src/test/java/dev/ltms/fleet/herdr/PaneLocatorTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/herdr/PaneLocatorTest.java rename to fleetd/src/test/java/dev/ltms/fleet/herdr/PaneLocatorTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/herdr/WorkspacePlacementContractTest.java b/fleetd/src/test/java/dev/ltms/fleet/herdr/WorkspacePlacementContractTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/herdr/WorkspacePlacementContractTest.java rename to fleetd/src/test/java/dev/ltms/fleet/herdr/WorkspacePlacementContractTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/inject/CompletionResolverTest.java b/fleetd/src/test/java/dev/ltms/fleet/inject/CompletionResolverTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/inject/CompletionResolverTest.java rename to fleetd/src/test/java/dev/ltms/fleet/inject/CompletionResolverTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/inject/InjectorTest.java b/fleetd/src/test/java/dev/ltms/fleet/inject/InjectorTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/inject/InjectorTest.java rename to fleetd/src/test/java/dev/ltms/fleet/inject/InjectorTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/inject/MemberPresenceTest.java b/fleetd/src/test/java/dev/ltms/fleet/inject/MemberPresenceTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/inject/MemberPresenceTest.java rename to fleetd/src/test/java/dev/ltms/fleet/inject/MemberPresenceTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/inject/StatusRefinerTest.java b/fleetd/src/test/java/dev/ltms/fleet/inject/StatusRefinerTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/inject/StatusRefinerTest.java rename to fleetd/src/test/java/dev/ltms/fleet/inject/StatusRefinerTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/lead/LeadLauncherTest.java b/fleetd/src/test/java/dev/ltms/fleet/lead/LeadLauncherTest.java similarity index 84% rename from bridged/src/test/java/dev/ltms/fleet/lead/LeadLauncherTest.java rename to fleetd/src/test/java/dev/ltms/fleet/lead/LeadLauncherTest.java index 1616a92..d0afddd 100644 --- a/bridged/src/test/java/dev/ltms/fleet/lead/LeadLauncherTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/lead/LeadLauncherTest.java @@ -24,8 +24,8 @@ class LeadLauncherTest { /** The lead's backend: a subscription profile with the bridge mounted, as `opus` really is. */ private static FleetConfig.Profile opusProfile() { return new FleetConfig.Profile( - "opus", null, "claude-opus-5", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "ltms"), "tab", "bridged-workers", null, + "opus", null, "claude-opus-5", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "ltms"), "tab", "fleet", null, "http://127.0.0.1:8765/mcp", null, null, null, null, null, Map.of("CLAUDE_CODE_AUTO_COMPACT_WINDOW", "300000"), null, null, true, null); @@ -43,7 +43,7 @@ class LeadLauncherTest { private static FleetConfig.Leader lead(String profile, String tab, int instances) { return new FleetConfig.Leader(profile, tab, instances, "lead:", 10, null, null, - "leads", "/repo"); + "fleet", "/repo"); } private static LeadLauncher launcher(FakeHerdr herdr, FleetConfig cfg) { @@ -100,7 +100,7 @@ class LeadLauncherTest { @Test void doesNotStartASecondLeadWhenOneIsAlreadyRunning() { FakeHerdr herdr = new FakeHerdr() - .withWorkspace("wL", "leads") + .withWorkspace("wL", "fleet") .withTab("wL", "wL:t1", "lead: opus") .withAgent("lead-opus", "term_lead", "wL:p1", "wL:t1"); @@ -115,7 +115,7 @@ class LeadLauncherTest { @Test void aLabelledTabWithNoRunningAgentIsNotALiveLead() { FakeHerdr herdr = new FakeHerdr() - .withWorkspace("wL", "leads") + .withWorkspace("wL", "fleet") .withTab("wL", "wL:t1", "lead: opus"); // label only — nothing running in it assertEquals(1, launcher(herdr, configWith(lead("opus", "lead: opus", 1))).ensureLeads(), @@ -138,16 +138,35 @@ class LeadLauncherTest { assertFalse(herdr.called("agent.start")); } - /** A member sitting in a matching tab must never be counted — or spawn a lead — as one. */ + /** + * The lead and the members now share ONE workspace, so a member's tab is told from a lead's by + * its LABEL, not its workspace. A member carries its `worker: {profile} #{n}` label, which never + * matches a lead's configured tab, so it is not counted as a lead. + */ @Test - void aMemberWorkspaceIsNeverScannedForLeads() { + void aMemberInTheSharedWorkspaceIsNotCountedAsALead() { FakeHerdr herdr = new FakeHerdr() - .withWorkspace("wM", "bridged-workers") // a configured member space - .withTab("wM", "wM:t1", "lead: opus") // a member tab that looks like a lead - .withAgent("claude-opus-x", "term_m", "wM:p1", "wM:t1"); + .withWorkspace("wF", "fleet") // the shared fleet space + .withTab("wF", "wF:t1", "worker: opus #1") // a member tab, member label + .withAgent("claude-opus-x", "term_m", "wF:p1", "wF:t1"); assertEquals(1, launcher(herdr, configWith(lead("opus", "lead: opus", 1))).ensureLeads(), - "a member in a lead-labelled tab is not a lead, so the real lead is still missing"); + "a member tab does not carry the lead label, so the real lead is still missing"); + } + + /** A lead sharing the members' workspace is still discovered — by its exact tab label. */ + @Test + void aLeadIsFoundInTheSharedMemberWorkspace() { + FakeHerdr herdr = new FakeHerdr() + .withWorkspace("wF", "fleet") // the shared fleet space + .withTab("wF", "wF:t1", "worker: opus #1") // a member tab next to it + .withAgent("claude-opus-x", "term_m", "wF:p1", "wF:t1") + .withTab("wF", "wF:t2", "lead: opus") // the lead, same workspace + .withAgent("lead-opus", "term_lead", "wF:p2", "wF:t2"); + + assertEquals(0, launcher(herdr, configWith(lead("opus", "lead: opus", 1))).ensureLeads(), + "the live lead is found even though it shares the workspace with a member"); + assertFalse(herdr.called("agent.start"), "the live lead must not be duplicated"); } /** If herdr cannot be counted, start nothing: guessing risks a second orchestrator. */ @@ -207,15 +226,14 @@ class LeadLauncherTest { "the profile's own env: still applies"); } - /** The lead's tab goes in its own workspace, never a member one — the scanner skips those. */ + /** The lead's tab goes in the one shared "fleet" workspace — the same space the members use. */ @Test - void theLeadTabIsCreatedOutsideEveryMemberWorkspace() { + void theLeadTabIsCreatedInTheSharedFleetWorkspace() { FakeHerdr herdr = new FakeHerdr(); launcher(herdr, configWith(lead("opus", "lead: opus", 1))).ensureLeads(); String label = (String) ((Map) herdr.lastCall("workspace.create").params()).get("label"); - assertEquals("leads", label); - assertNotEquals("bridged-workers", label); + assertEquals("fleet", label); } // ── recognise-only and misconfiguration ─────────────────────────────────────────────────── diff --git a/bridged/src/test/java/dev/ltms/fleet/logging/McpCancelledNotificationFilterTest.java b/fleetd/src/test/java/dev/ltms/fleet/logging/McpCancelledNotificationFilterTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/logging/McpCancelledNotificationFilterTest.java rename to fleetd/src/test/java/dev/ltms/fleet/logging/McpCancelledNotificationFilterTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/mcp/ConnectionIdentityTest.java b/fleetd/src/test/java/dev/ltms/fleet/mcp/ConnectionIdentityTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/mcp/ConnectionIdentityTest.java rename to fleetd/src/test/java/dev/ltms/fleet/mcp/ConnectionIdentityTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/mcp/FleetMcpAuthzTest.java b/fleetd/src/test/java/dev/ltms/fleet/mcp/FleetMcpAuthzTest.java similarity index 98% rename from bridged/src/test/java/dev/ltms/fleet/mcp/FleetMcpAuthzTest.java rename to fleetd/src/test/java/dev/ltms/fleet/mcp/FleetMcpAuthzTest.java index f308418..61e31a4 100644 --- a/bridged/src/test/java/dev/ltms/fleet/mcp/FleetMcpAuthzTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/mcp/FleetMcpAuthzTest.java @@ -57,8 +57,8 @@ class FleetMcpAuthzTest { /** A fully wired FleetMcp on fakes — constructing it is itself part of what is under test. */ private FleetMcp mcp(boolean enforce) { FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", null, - "tab", "bridged-workers", "worker: {profile} #{n}", null, null, null); + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", null, + "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); ClaudeCodeLauncher workers = new ClaudeCodeLauncher(agents, new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> "tok"); diff --git a/bridged/src/test/java/dev/ltms/fleet/mcp/FleetMcpLeadCoordTest.java b/fleetd/src/test/java/dev/ltms/fleet/mcp/FleetMcpLeadCoordTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/mcp/FleetMcpLeadCoordTest.java rename to fleetd/src/test/java/dev/ltms/fleet/mcp/FleetMcpLeadCoordTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/mcp/FleetMcpTest.java b/fleetd/src/test/java/dev/ltms/fleet/mcp/FleetMcpTest.java similarity index 89% rename from bridged/src/test/java/dev/ltms/fleet/mcp/FleetMcpTest.java rename to fleetd/src/test/java/dev/ltms/fleet/mcp/FleetMcpTest.java index f99872c..e53cbfb 100644 --- a/bridged/src/test/java/dev/ltms/fleet/mcp/FleetMcpTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/mcp/FleetMcpTest.java @@ -19,16 +19,10 @@ import dev.ltms.fleet.member.ClaudeCodeLauncher; import dev.ltms.fleet.member.CompositePeerLauncher; import dev.ltms.fleet.placement.BackendQuarantine; import dev.ltms.fleet.placement.PlacementPolicies; -import io.modelcontextprotocol.server.McpSyncServerExchange; import io.modelcontextprotocol.spec.McpSchema; import dev.ltms.fleet.msg.InMemoryReplyInbox; -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; @@ -36,7 +30,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; -import java.util.function.BiFunction; import static org.junit.jupiter.api.Assertions.*; @@ -79,8 +72,8 @@ class FleetMcpTest { private static ClaudeCodeLauncher workerService(FakeHerdr h, String baseUrl, Set allow) { FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", baseUrl, "coder", null, "BRIDGED_WORKER_TOKEN", null, - "tab", "bridged-workers", "worker: {profile} #{n}", null, null, null); + "ltms-local", baseUrl, "coder", null, "FLEETD_WORKER_TOKEN", null, + "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); return new ClaudeCodeLauncher(new AgentControl(h), new WorkspaceControl(h), new SubscriptionGuard(allow), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> "tok"); } @@ -442,13 +435,13 @@ class FleetMcpTest { void spawnAtMaxLoadSurfacesTheCapacityReason() { FakeHerdr h = new FakeHerdr(); FleetConfig.Profile wcfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", null, - "tab", "bridged-workers", "worker: {profile} #{n}", null, + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", null, + "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null, null, null, null, null, null, 0, null, null, null, null); Map profiles = Map.of(wcfg.profile(), wcfg); ClaudeCodeLauncher delegate = new ClaudeCodeLauncher( new AgentControl(h), new WorkspaceControl(h), new SubscriptionGuard(Set.of("gx00.gw")), - profiles, wcfg.profile(), k -> "BRIDGED_WORKER_TOKEN".equals(k) ? "tok" : null); + profiles, wcfg.profile(), k -> "FLEETD_WORKER_TOKEN".equals(k) ? "tok" : null); CompositePeerLauncher composite = new CompositePeerLauncher( List.of(delegate), wcfg.profile(), profiles, PlacementPolicies.fixed(), _ -> 0); SessionManager sm = new SessionManager(composite); @@ -1058,102 +1051,4 @@ class FleetMcpTest { assertTrue(textOf(res).contains("explicit profile"), textOf(res)); } - // ── CB-622: bridge_* -> fleet_* rename, both names answer through the SAME handler ──────── - // - // These are unit tests of the wiring helpers (deprecatedTwin/deprecatedHandler/ - // warnDeprecatedOnce), not a live MCP client call — proving the tool is REGISTERED and - // ROUTES correctly. Whether a real MCP client can actually invoke a tool by either name is - // the live check the lead runs; see CB-618's lesson that a green build here is not proof of - // that. - - private static McpSchema.Tool fakeTool(String name) { - return McpSchema.Tool.builder(name) - .description("does the thing") - .inputSchema(Map.of("type", "object", "properties", Map.of(), "required", List.of())) - .build(); - } - - @Test - void deprecatedTwinNamesTheOldToolAndDefersToTheFleetDescription() { - McpSchema.Tool fleetTool = fakeTool("fleet_cb622_twin"); - McpSchema.Tool twin = FleetMcp.deprecatedTwin(fleetTool, "bridge_cb622_twin"); - - assertEquals("bridge_cb622_twin", twin.name()); - assertTrue(twin.description().startsWith("DEPRECATED: use fleet_cb622_twin instead."), - twin.description()); - assertTrue(twin.description().contains(fleetTool.description()), twin.description()); - assertEquals(fleetTool.inputSchema(), twin.inputSchema(), "the twin must not restate the schema"); - } - - @Test - void oldNameAndNewNameReachTheExactSameHandler() { - McpSchema.Tool fleetTool = fakeTool("fleet_cb622_dual"); - List handlerCalls = new ArrayList<>(); - BiFunction handler = - (exchange, req) -> { - handlerCalls.add(req.name()); - return McpSchema.CallToolResult.builder().addTextContent("handled:" + req.name()).build(); - }; - - BiFunction deprecated = - FleetMcp.deprecatedHandler(fleetTool, "bridge_cb622_dual", handler); - - // Calling the fleet_* name directly and calling the wrapped bridge_* name both end up - // running the SAME `handler` instance — not a copy of its logic. - McpSchema.CallToolResult viaFleet = handler.apply(null, new McpSchema.CallToolRequest("fleet_cb622_dual", Map.of())); - McpSchema.CallToolResult viaBridge = deprecated.apply(null, new McpSchema.CallToolRequest("bridge_cb622_dual", Map.of())); - - assertEquals(textOf(viaFleet), "handled:fleet_cb622_dual"); - assertEquals(textOf(viaBridge), "handled:bridge_cb622_dual"); - assertEquals(2, handlerCalls.size(), "the same handler ran for both calls"); - } - - @Test - void deprecatedNameWarnsOnceForTheProcessNotOncePerCall() { - Logger logger = (Logger) LoggerFactory.getLogger(FleetMcp.class); - ListAppender appender = new ListAppender<>(); - appender.start(); - logger.addAppender(appender); - // A name unique to this test run so another test's use of the mechanism (or a re-run in - // the same JVM) cannot leave the "already warned" flag set before this assertion. - String oldName = "bridge_cb622_warnonce_" + System.identityHashCode(appender); - try { - FleetMcp.warnDeprecatedOnce(oldName, "fleet_cb622_warnonce"); - FleetMcp.warnDeprecatedOnce(oldName, "fleet_cb622_warnonce"); - FleetMcp.warnDeprecatedOnce(oldName, "fleet_cb622_warnonce"); - - List matching = appender.list.stream() - .filter(e -> e.getFormattedMessage().contains(oldName)) - .toList(); - assertEquals(1, matching.size(), "three calls with the same old name must warn exactly once"); - assertEquals(Level.WARN, matching.get(0).getLevel()); - assertTrue(matching.get(0).getFormattedMessage().contains("fleet_cb622_warnonce"), - "the warning must name the new tool too"); - } finally { - logger.detachAppender(appender); - } - } - - @Test - void deprecatedNameWarnsAgainForADifferentOldName() { - Logger logger = (Logger) LoggerFactory.getLogger(FleetMcp.class); - ListAppender appender = new ListAppender<>(); - appender.start(); - logger.addAppender(appender); - String suffix = System.identityHashCode(appender) + ""; - String nameA = "bridge_cb622_multi_a_" + suffix; - String nameB = "bridge_cb622_multi_b_" + suffix; - try { - FleetMcp.warnDeprecatedOnce(nameA, "fleet_cb622_multi_a"); - FleetMcp.warnDeprecatedOnce(nameB, "fleet_cb622_multi_b"); - - long distinctNamesWarned = appender.list.stream() - .map(ILoggingEvent::getFormattedMessage) - .filter(m -> m.contains(nameA) || m.contains(nameB)) - .count(); - assertEquals(2, distinctNamesWarned, "each distinct old name gets its own warning"); - } finally { - logger.detachAppender(appender); - } - } } diff --git a/bridged/src/test/java/dev/ltms/fleet/mcp/PrimaryRegistryTest.java b/fleetd/src/test/java/dev/ltms/fleet/mcp/PrimaryRegistryTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/mcp/PrimaryRegistryTest.java rename to fleetd/src/test/java/dev/ltms/fleet/mcp/PrimaryRegistryTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/member/ClaudeCodeLauncherTest.java b/fleetd/src/test/java/dev/ltms/fleet/member/ClaudeCodeLauncherTest.java similarity index 94% rename from bridged/src/test/java/dev/ltms/fleet/member/ClaudeCodeLauncherTest.java rename to fleetd/src/test/java/dev/ltms/fleet/member/ClaudeCodeLauncherTest.java index 175181b..12508ec 100644 --- a/bridged/src/test/java/dev/ltms/fleet/member/ClaudeCodeLauncherTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/member/ClaudeCodeLauncherTest.java @@ -36,8 +36,8 @@ class ClaudeCodeLauncherTest { private ClaudeCodeLauncher service(FakeHerdr herdr, List argv, String mcpUrl) { FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - argv, "tab", "bridged-workers", "worker: {profile} #{n}", mcpUrl, null, null); + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + argv, "tab", "fleetd-workers", "worker: {profile} #{n}", mcpUrl, null, null); return new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null); } @@ -70,8 +70,8 @@ class ClaudeCodeLauncherTest { /** A profile carrying an ideMcpUrl (plus optional bridge mcpUrl and cwd). ideMcpUrl is the last record component. */ private FleetConfig.Profile ideProfile(String mcpUrl, String ideMcpUrl, String cwd) { return new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "w #{n}", mcpUrl, cwd, null, + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "w #{n}", mcpUrl, cwd, null, null, null, null, null, null, null, null, null, null, ideMcpUrl); } @@ -79,8 +79,8 @@ class ClaudeCodeLauncherTest { private FleetConfig.Profile ideProfileModule(String ideMcpUrl, String cwd, String ideProjectDir, String ideOpenCommand) { return new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "w #{n}", null, cwd, null, + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, cwd, null, null, null, null, null, null, null, null, null, null, ideMcpUrl, ideProjectDir, ideOpenCommand); } @@ -178,7 +178,7 @@ class ClaudeCodeLauncherTest { } // CB-634 auto-open pin fix: for a repo whose Maven module is a subdir (this repo's pom lives in - // `bridged/`, not at the worktree root), the overlay must pin project_path to the MODULE dir the + // `fleetd/`, not at the worktree root), the overlay must pin project_path to the MODULE dir the // IDE opened, not the worktree root — else ide_* resolves against a root that imports no module. @Test void writeIdeOverlayPinsModuleDirWhenIdeProjectDirSet(@TempDir Path root) throws Exception { @@ -188,13 +188,13 @@ class ClaudeCodeLauncherTest { Files.writeString(worktree.resolve(".git"), "gitdir: " + gitDir); FakeHerdr herdr = new FakeHerdr(); - // ideProjectDir "bridged" ⇒ the pin is /bridged, not . + // ideProjectDir "fleetd" ⇒ the pin is /fleetd, not . launcher(herdr, ideProfileModule("http://127.0.0.1:29170/index-mcp/streamable-http", - worktree.toString(), "bridged", null)).spawn(); + worktree.toString(), "fleetd", null)).spawn(); Path overlay = worktree.resolve("CLAUDE.local.md"); assertTrue(Files.exists(overlay), "the overlay file still lives at the worktree root"); - String module = worktree.resolve("bridged").toString(); + String module = worktree.resolve("fleetd").toString(); assertTrue(Files.readString(overlay).contains("project_path: \"" + module + "\""), "the overlay pins the MODULE dir the IDE opened, not the worktree root"); assertFalse(Files.readString(overlay).contains("project_path: \"" + worktree + "\""), @@ -203,7 +203,7 @@ class ClaudeCodeLauncherTest { @Test void ideProjectPathResolvesModuleSubdirAndDefaultsToWorktreeRoot() { - assertEquals("/wt/x/bridged", PeerLauncher.ideProjectPath("/wt/x", "bridged"), + assertEquals("/wt/x/fleetd", PeerLauncher.ideProjectPath("/wt/x", "fleetd"), "a module subdir resolves under the worktree root"); assertEquals("/wt/x", PeerLauncher.ideProjectPath("/wt/x", null), "no module subdir ⇒ the worktree root itself"); @@ -242,8 +242,8 @@ class ClaudeCodeLauncherTest { new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of("ltms-local", new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "w #{n}", null, null, null)), + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null)), "ltms-local", _ -> null, 0, () -> clock[0], () -> clock[0] += 50); @@ -300,8 +300,8 @@ class ClaudeCodeLauncherTest { FakeHerdr herdr = new FakeHerdr(); String roleCharter = "You review changes.\nLine two.\nLine three."; FleetConfig.Profile cfg = new FleetConfig.Profile( - "sonnet", "http://gx00.gw:8000", null, null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "w #{n}", + "sonnet", "http://gx00.gw:8000", null, null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "w #{n}", "http://127.0.0.1:8765/mcp", null, null); ClaudeCodeLauncher svc = new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null, @@ -364,8 +364,8 @@ class ClaudeCodeLauncherTest { Path agentsDir = Files.createDirectories(cwd.resolve(".claude/agents")); Files.writeString(agentsDir.resolve("reviewer.md"), "---\nname: reviewer\n---\nBe a reviewer."); FleetConfig.Profile cfg = new FleetConfig.Profile( - "sonnet", "http://gx00.gw:8000", null, null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "w #{n}", null, null, null); + "sonnet", "http://gx00.gw:8000", null, null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null); ClaudeCodeLauncher svc = new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null); @@ -381,8 +381,8 @@ class ClaudeCodeLauncherTest { void noAgentFlagWhenTheRoleAgentDefinitionFileIsAbsent(@TempDir Path cwd) { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "sonnet", "http://gx00.gw:8000", null, null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "w #{n}", null, null, null); + "sonnet", "http://gx00.gw:8000", null, null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null); ClaudeCodeLauncher svc = new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null); @@ -395,9 +395,9 @@ class ClaudeCodeLauncherTest { private ClaudeCodeLauncher multiProfile(FakeHerdr herdr) { FleetConfig.Profile gx10 = new FleetConfig.Profile("gx10", "http://gx10.gw:8000", "coder", - null, "BRIDGED_WORKER_TOKEN", List.of("claude"), "tab", "bridged-workers", "w #{n}", null, null, null); + null, "FLEETD_WORKER_TOKEN", List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null); FleetConfig.Profile ollama = new FleetConfig.Profile("ollama", "http://ollama.ltms.dev", null, - null, "BRIDGED_WORKER_TOKEN", List.of("claude"), "tab", "bridged-workers", "w #{n}", null, null, null); + null, "FLEETD_WORKER_TOKEN", List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null); return new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx10.gw", "ollama.ltms.dev")), Map.of("gx10", gx10, "ollama", ollama), "gx10", _ -> "tok"); @@ -438,7 +438,7 @@ class ClaudeCodeLauncherTest { void profileConfigCwdBeatsTheCallerCwd() { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile("ltms-local", "http://gx00.gw:8000", "coder", - null, "BRIDGED_WORKER_TOKEN", List.of("ccs", "ltms-local"), "tab", "bridged-workers", + null, "FLEETD_WORKER_TOKEN", List.of("ccs", "ltms-local"), "tab", "fleetd-workers", "w #{n}", null, "/pinned/dir", null); ClaudeCodeLauncher svc = new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of("ltms-local", cfg), "ltms-local", _ -> null); @@ -465,8 +465,8 @@ class ClaudeCodeLauncherTest { void injectsForgeTokenAndHostWhenProfileGrantsIt() { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "impl", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "impl"), "tab", "bridged-workers", "w #{n}", null, null, null, + "impl", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "impl"), "tab", "fleetd-workers", "w #{n}", null, null, null, "GITEA_ACCESS_TOKEN", null); // parityOverlay null; gitHostEnv null → defaults to GITEA_HOST Function host = name -> switch (name) { case "GITEA_ACCESS_TOKEN" -> "gt-secret"; @@ -487,7 +487,7 @@ class ClaudeCodeLauncherTest { // gitTokenEnv unset (12-arg ctor); the env would resolve a token if asked, proving the gate // is the profile config, not a missing env var. FleetConfig.Profile cfg = new FleetConfig.Profile("ltms-local", "http://gx00.gw:8000", "coder", - null, "BRIDGED_WORKER_TOKEN", List.of("ccs"), "tab", "bridged-workers", "w #{n}", + null, "FLEETD_WORKER_TOKEN", List.of("ccs"), "tab", "fleetd-workers", "w #{n}", null, null, null); new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of("ltms-local", cfg), "ltms-local", @@ -618,8 +618,8 @@ class ClaudeCodeLauncherTest { void capabilitiesIncludeSelfPrWhenProfileHasGitToken() { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "impl", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "impl"), "tab", "bridged-workers", "w #{n}", null, null, null, + "impl", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "impl"), "tab", "fleetd-workers", "w #{n}", null, null, null, "GITEA_ACCESS_TOKEN", null); ClaudeCodeLauncher svc = new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of("impl", cfg), "impl", @@ -772,8 +772,8 @@ class ClaudeCodeLauncherTest { private static Map workerConfigMap(String profile, String mcpUrl) { FleetConfig.Profile cfg = new FleetConfig.Profile( - profile, "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", profile), "tab", "bridged-workers", + profile, "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", profile), "tab", "fleetd-workers", "worker: {profile} #{n}", mcpUrl, null, null); return Map.of(cfg.profile(), cfg); } @@ -874,8 +874,8 @@ class ClaudeCodeLauncherTest { void workerInheritsTheDaemonPath() { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "w #{n}", null, null, null); + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null); new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), k -> "PATH".equals(k) ? "/opt/tools/bin:/usr/bin" : null).spawn(); @@ -888,8 +888,8 @@ class ClaudeCodeLauncherTest { void profileEnvIsInjectedIntoTheWorker() { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "w #{n}", null, null, null, null, null, + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null, null, null, null, Map.of("JAVA_HOME", "/opt/jdk", "PATH", "/profile/bin"), null, null); new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), @@ -909,8 +909,8 @@ class ClaudeCodeLauncherTest { void profileEnvCannotOverrideGuardCheckedAnthropicVars() { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "w #{n}", null, null, null, null, null, + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null, null, null, null, Map.of("ANTHROPIC_BASE_URL", "http://evil.example.com"), null, null); new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), @@ -931,8 +931,8 @@ class ClaudeCodeLauncherTest { private ClaudeCodeLauncher serviceWithCredentials(FakeHerdr herdr, FleetConfig.MemberCredentials creds) { FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "worker: {profile} #{n}", null, null, null); + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); return new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null, 0, System::currentTimeMillis, () -> {}, null, () -> creds); @@ -984,7 +984,7 @@ class ClaudeCodeLauncherTest { /** * No {@code memberCredentials} configured (the pre-CB-596 constructor overloads still used - * throughout this file, and the shape a fresh {@code bridged.yaml} with no memberCredentials: + * throughout this file, and the shape a fresh {@code fleetd.yaml} with no memberCredentials: * block resolves to) blocks NOTHING. This documents the transitional gap rather than hiding it — * see {@code HerdrPeerLauncher#applyMemberCredentialPolicy}'s javadoc. */ @@ -1006,8 +1006,8 @@ class ClaudeCodeLauncherTest { void aProfileEnvEntryCannotRestoreABlockedName() { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "w #{n}", null, null, null, null, null, + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null, null, null, null, Map.of("GITEA_ACCESS_TOKEN", "admin-secret-from-profile-config"), null, null); new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), @@ -1028,8 +1028,8 @@ class ClaudeCodeLauncherTest { void aCredentialShapedNameOnNeitherListIsLoggedAsAGap() { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "worker: {profile} #{n}", null, null, null); + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); ClaudeCodeLauncher svc = new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null, 0, System::currentTimeMillis, () -> {}, null, () -> TEST_MEMBER_CREDENTIALS, @@ -1077,8 +1077,8 @@ class ClaudeCodeLauncherTest { void aProfileEnvEntryCannotClearTheMemberMarker() { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "w #{n}", null, null, null, null, null, + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null, null, null, null, Map.of("BRIDGED_MEMBER", ""), null, null); new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), @@ -1100,7 +1100,7 @@ class ClaudeCodeLauncherTest { private static FleetConfig.Profile profileWithModel(String model) { return new FleetConfig.Profile("sonnet", "http://gx00.gw:8000", model, null, - "BRIDGED_WORKER_TOKEN", List.of("ccs", "sonnet"), "tab", "bridged-workers", + "FLEETD_WORKER_TOKEN", List.of("ccs", "sonnet"), "tab", "fleetd-workers", "w #{n}", "http://127.0.0.1:8765/mcp", null, null); } @@ -1150,7 +1150,7 @@ class ClaudeCodeLauncherTest { private static FleetConfig.Profile profileWithAutoCompactWindow(Integer window) { return new FleetConfig.Profile("sonnet", "http://gx00.gw:8000", "claude-sonnet-5", null, - "BRIDGED_WORKER_TOKEN", List.of("ccs", "sonnet"), "tab", "bridged-workers", + "FLEETD_WORKER_TOKEN", List.of("ccs", "sonnet"), "tab", "fleetd-workers", "w #{n}", "http://127.0.0.1:8765/mcp", null, null, null, null, null, Map.of(), null, null, null, null, null, null, null, null, window); } @@ -1179,8 +1179,8 @@ class ClaudeCodeLauncherTest { /** A claude-code profile on the subscription: no baseUrl (by design), no off-sub endpoint. */ private static FleetConfig.Profile subscriptionCfg(String profile, String baseUrl) { return new FleetConfig.Profile( - profile, baseUrl, "sonnet", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", profile), "tab", "bridged-workers", "w #{n}", null, null, null, + profile, baseUrl, "sonnet", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", profile), "tab", "fleetd-workers", "w #{n}", null, null, null, null, null, null, Map.of(), null, null, true, null); } @@ -1190,8 +1190,8 @@ class ClaudeCodeLauncherTest { // profile with no baseUrl and no subscription must still be refused (it would bill the sub). FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", null, "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "ltms-local"), "tab", "bridged-workers", "w #{n}", null, null, null); + "ltms-local", null, "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "ltms-local"), "tab", "fleetd-workers", "w #{n}", null, null, null); ClaudeCodeLauncher svc = new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null); @@ -1243,8 +1243,8 @@ class ClaudeCodeLauncherTest { // not on the allowlist is still refused, whether or not any subscription profile exists. FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile rogue = new FleetConfig.Profile( - "rogue", "http://evil.example.com:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "rogue"), "tab", "bridged-workers", "w #{n}", null, null, null); + "rogue", "http://evil.example.com:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "rogue"), "tab", "fleetd-workers", "w #{n}", null, null, null); ClaudeCodeLauncher svc = new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(rogue.profile(), rogue), rogue.profile(), _ -> null); @@ -1262,8 +1262,8 @@ class ClaudeCodeLauncherTest { // invariant hold for a profile built in code that never passed through that validation. FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "sonnet", null, "sonnet", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "sonnet"), "tab", "bridged-workers", "w #{n}", null, null, null, + "sonnet", null, "sonnet", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "sonnet"), "tab", "fleetd-workers", "w #{n}", null, null, null, null, null, null, Map.of("ANTHROPIC_BASE_URL", "http://evil.example.com", "ANTHROPIC_AUTH_TOKEN", "sk-ant-bad", "JAVA_HOME", "/opt/jdk"), @@ -1298,8 +1298,8 @@ class ClaudeCodeLauncherTest { /** A profile with no {@code tabLabel:} of its own — the fleet template decides. */ private ClaudeCodeLauncher labelService(FakeHerdr herdr, Supplier fleet) { FleetConfig.Profile cfg = new FleetConfig.Profile( - "sonnet", "http://gx00.gw:8000", "sonnet", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", null, null, null, null); + "sonnet", "http://gx00.gw:8000", "sonnet", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", null, null, null, null); return new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null, 0, 0L, fleet); @@ -1350,8 +1350,8 @@ class ClaudeCodeLauncherTest { void aProfileTabLabelOverridesTheFleetTemplate() { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "sonnet", "http://gx00.gw:8000", "sonnet", null, "BRIDGED_WORKER_TOKEN", - List.of("claude"), "tab", "bridged-workers", "pinned {profile}", null, null, null); + "sonnet", "http://gx00.gw:8000", "sonnet", null, "FLEETD_WORKER_TOKEN", + List.of("claude"), "tab", "fleetd-workers", "pinned {profile}", null, null, null); new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null, 0, 0L, () -> fleet(null, "{role}: {profile} #{n}")) diff --git a/bridged/src/test/java/dev/ltms/fleet/member/CompositePeerLauncherTest.java b/fleetd/src/test/java/dev/ltms/fleet/member/CompositePeerLauncherTest.java similarity index 98% rename from bridged/src/test/java/dev/ltms/fleet/member/CompositePeerLauncherTest.java rename to fleetd/src/test/java/dev/ltms/fleet/member/CompositePeerLauncherTest.java index f8cf234..48ed960 100644 --- a/bridged/src/test/java/dev/ltms/fleet/member/CompositePeerLauncherTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/member/CompositePeerLauncherTest.java @@ -44,7 +44,7 @@ class CompositePeerLauncherTest { private ClaudeCodeLauncher claudeAdapter(FakeHerdr herdr) { // 12-arg back-compat Worker ctor → kind defaults to claude-code. FleetConfig.Profile claude = new FleetConfig.Profile("claude", "http://gx00.gw:8000", "coder", - null, "BRIDGED_WORKER_TOKEN", List.of("claude"), "tab", "bridged-workers", "w #{n}", + null, "FLEETD_WORKER_TOKEN", List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null); return new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of("claude", claude), "claude", _ -> null); @@ -52,7 +52,7 @@ class CompositePeerLauncherTest { private OpenCodeLauncher opencodeAdapter(FakeHerdr herdr) { FleetConfig.Profile gemini = new FleetConfig.Profile("gemini", null, "google/gemini-2.5-pro", - null, "BRIDGED_WORKER_TOKEN", List.of("opencode"), "tab", "bridged-workers", "w #{n}", + null, "FLEETD_WORKER_TOKEN", List.of("opencode"), "tab", "fleetd-workers", "w #{n}", null, null, null, "GITEA_ACCESS_TOKEN", null, FleetConfig.Profile.KIND_OPENCODE); return new OpenCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), Map.of("gemini", gemini), "gemini", _ -> "tok"); @@ -121,20 +121,20 @@ class CompositePeerLauncherTest { private static FleetConfig.Profile stubWorker(String profile) { return new FleetConfig.Profile(profile, "http://gx00.gw:8000", "coder", - null, "BRIDGED_WORKER_TOKEN", List.of("claude"), "tab", "bridged-workers", + null, "FLEETD_WORKER_TOKEN", List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null, null, null, null, null, null, null); } private static FleetConfig.Profile stubWorker(String profile, float weight, Integer maxLoad) { return new FleetConfig.Profile(profile, "http://gx00.gw:8000", "coder", - null, "BRIDGED_WORKER_TOKEN", List.of("claude"), "tab", "bridged-workers", + null, "FLEETD_WORKER_TOKEN", List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null, null, null, null, null, weight, maxLoad); } private static FleetConfig.Profile stubWorker(String profile, String credentialId) { return new FleetConfig.Profile(profile, "http://gx00.gw:8000", "coder", - null, "BRIDGED_WORKER_TOKEN", List.of("claude"), "tab", "bridged-workers", + null, "FLEETD_WORKER_TOKEN", List.of("claude"), "tab", "fleetd-workers", "w #{n}", null, null, null, null, null, null, null, null, null, null, null, credentialId, null); } diff --git a/bridged/src/test/java/dev/ltms/fleet/member/EnvAllowListScrubTest.java b/fleetd/src/test/java/dev/ltms/fleet/member/EnvAllowListScrubTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/member/EnvAllowListScrubTest.java rename to fleetd/src/test/java/dev/ltms/fleet/member/EnvAllowListScrubTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherAllowListWiringTest.java b/fleetd/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherAllowListWiringTest.java similarity index 98% rename from bridged/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherAllowListWiringTest.java rename to fleetd/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherAllowListWiringTest.java index 785597c..7b85062 100644 --- a/bridged/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherAllowListWiringTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherAllowListWiringTest.java @@ -118,7 +118,7 @@ class HerdrPeerLauncherAllowListWiringTest { private static FleetConfig.Profile profile() { return new FleetConfig.Profile("test", "http://gx00.gw:8000", null, null, - "BRIDGED_WORKER_TOKEN", List.of("test"), "pane", null, null, null, null, null); + "FLEETD_WORKER_TOKEN", List.of("test"), "pane", null, null, null, null, null); } /** diff --git a/bridged/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherCharterTest.java b/fleetd/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherCharterTest.java similarity index 98% rename from bridged/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherCharterTest.java rename to fleetd/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherCharterTest.java index af2c011..84e6f9c 100644 --- a/bridged/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherCharterTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/member/HerdrPeerLauncherCharterTest.java @@ -85,7 +85,7 @@ class HerdrPeerLauncherCharterTest { private static FleetConfig.Profile profile(String name, String mcpUrl) { return new FleetConfig.Profile(name, "http://gx00.gw:8000", null, null, - "BRIDGED_WORKER_TOKEN", List.of("test"), "pane", null, null, mcpUrl, null, null); + "FLEETD_WORKER_TOKEN", List.of("test"), "pane", null, null, mcpUrl, null, null); } /** diff --git a/bridged/src/test/java/dev/ltms/fleet/member/MemberEnvAllowListTest.java b/fleetd/src/test/java/dev/ltms/fleet/member/MemberEnvAllowListTest.java similarity index 98% rename from bridged/src/test/java/dev/ltms/fleet/member/MemberEnvAllowListTest.java rename to fleetd/src/test/java/dev/ltms/fleet/member/MemberEnvAllowListTest.java index bb7f983..92312b2 100644 --- a/bridged/src/test/java/dev/ltms/fleet/member/MemberEnvAllowListTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/member/MemberEnvAllowListTest.java @@ -73,7 +73,7 @@ class MemberEnvAllowListTest { /** * The property the ticket hangs the design on: ADDING a profile only ever widens the set, so a - * new profile in bridged.yaml cannot break an existing spawn's scrub. + * new profile in fleetd.yaml cannot break an existing spawn's scrub. */ @Test void addingAProfileOnlyWidensTheDerivedSetNeverShrinksIt() { diff --git a/bridged/src/test/java/dev/ltms/fleet/member/OpenCodeLauncherTest.java b/fleetd/src/test/java/dev/ltms/fleet/member/OpenCodeLauncherTest.java similarity index 98% rename from bridged/src/test/java/dev/ltms/fleet/member/OpenCodeLauncherTest.java rename to fleetd/src/test/java/dev/ltms/fleet/member/OpenCodeLauncherTest.java index e0a2c5d..6bcc820 100644 --- a/bridged/src/test/java/dev/ltms/fleet/member/OpenCodeLauncherTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/member/OpenCodeLauncherTest.java @@ -34,8 +34,8 @@ import static org.junit.jupiter.api.Assertions.*; class OpenCodeLauncherTest { private static FleetConfig.Profile opencodeCfg(String model, String mcpUrl, String gitTokenEnv) { - return new FleetConfig.Profile("gemini", null, model, null, "BRIDGED_WORKER_TOKEN", - List.of("opencode"), "tab", "bridged-workers", "opencode: {model} #{n}", mcpUrl, + return new FleetConfig.Profile("gemini", null, model, null, "FLEETD_WORKER_TOKEN", + List.of("opencode"), "tab", "fleetd-workers", "opencode: {model} #{n}", mcpUrl, null, null, gitTokenEnv, null, FleetConfig.Profile.KIND_OPENCODE); } @@ -417,8 +417,8 @@ class OpenCodeLauncherTest { /** A profile with a baseUrl but no model provider prefix cannot be resolved — fail loudly. */ private static FleetConfig.Profile pinnedCfg(String model, String baseUrl, String mcpUrl) { - return new FleetConfig.Profile("local", baseUrl, model, null, "BRIDGED_WORKER_TOKEN", - List.of("opencode"), "tab", "bridged-workers", "opencode: {model} #{n}", mcpUrl, + return new FleetConfig.Profile("local", baseUrl, model, null, "FLEETD_WORKER_TOKEN", + List.of("opencode"), "tab", "fleetd-workers", "opencode: {model} #{n}", mcpUrl, null, null, null, null, FleetConfig.Profile.KIND_OPENCODE); } @@ -500,8 +500,8 @@ class OpenCodeLauncherTest { private static FleetConfig.Profile opencodeCfgWithAutoCompactWindow(String model, String baseUrl, Integer window) { - return new FleetConfig.Profile("gemini", baseUrl, model, null, "BRIDGED_WORKER_TOKEN", - List.of("opencode"), "tab", "bridged-workers", "opencode: {model} #{n}", null, + return new FleetConfig.Profile("gemini", baseUrl, model, null, "FLEETD_WORKER_TOKEN", + List.of("opencode"), "tab", "fleetd-workers", "opencode: {model} #{n}", null, null, null, null, null, FleetConfig.Profile.KIND_OPENCODE, Map.of(), null, null, null, null, null, null, null, null, window); } @@ -548,7 +548,7 @@ class OpenCodeLauncherTest { // with no other config-triggering knob would leave OPENCODE_CONFIG unset entirely, which is // also correct (nothing to write) but not what this test is asserting. service(herdr, root, new FleetConfig.Profile("gemini", null, "some-free-model", null, - "BRIDGED_WORKER_TOKEN", List.of("opencode"), "tab", "bridged-workers", + "FLEETD_WORKER_TOKEN", List.of("opencode"), "tab", "fleetd-workers", "opencode: {model} #{n}", "http://127.0.0.1:8765/mcp", null, null, null, null, FleetConfig.Profile.KIND_OPENCODE, Map.of(), null, null, null, null, null, null, null, null, 250_000)).spawn(); @@ -563,8 +563,8 @@ class OpenCodeLauncherTest { // --- CB-634: IDE Index MCP + guidance overlay (opencode does not read CLAUDE.local.md) ------- private static FleetConfig.Profile opencodeIdeCfg(String mcpUrl, String ideUrl, String cwd) { - return new FleetConfig.Profile("gemini", null, null, null, "BRIDGED_WORKER_TOKEN", - List.of("opencode"), "tab", "bridged-workers", "opencode: {model} #{n}", mcpUrl, + return new FleetConfig.Profile("gemini", null, null, null, "FLEETD_WORKER_TOKEN", + List.of("opencode"), "tab", "fleetd-workers", "opencode: {model} #{n}", mcpUrl, cwd, null, null, null, FleetConfig.Profile.KIND_OPENCODE, null, null, null, null, null, null, ideUrl); } diff --git a/bridged/src/test/java/dev/ltms/fleet/member/OpenCodeSessionDiscoveryTest.java b/fleetd/src/test/java/dev/ltms/fleet/member/OpenCodeSessionDiscoveryTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/member/OpenCodeSessionDiscoveryTest.java rename to fleetd/src/test/java/dev/ltms/fleet/member/OpenCodeSessionDiscoveryTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/metrics/MetricNamesTest.java b/fleetd/src/test/java/dev/ltms/fleet/metrics/MetricNamesTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/metrics/MetricNamesTest.java rename to fleetd/src/test/java/dev/ltms/fleet/metrics/MetricNamesTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/metrics/MetricsTest.java b/fleetd/src/test/java/dev/ltms/fleet/metrics/MetricsTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/metrics/MetricsTest.java rename to fleetd/src/test/java/dev/ltms/fleet/metrics/MetricsTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/msg/AmqpReplyInboxContractTest.java b/fleetd/src/test/java/dev/ltms/fleet/msg/AmqpReplyInboxContractTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/msg/AmqpReplyInboxContractTest.java rename to fleetd/src/test/java/dev/ltms/fleet/msg/AmqpReplyInboxContractTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/msg/AmqpReplyInboxRecoveryRaceTest.java b/fleetd/src/test/java/dev/ltms/fleet/msg/AmqpReplyInboxRecoveryRaceTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/msg/AmqpReplyInboxRecoveryRaceTest.java rename to fleetd/src/test/java/dev/ltms/fleet/msg/AmqpReplyInboxRecoveryRaceTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/msg/FakeLeadChannel.java b/fleetd/src/test/java/dev/ltms/fleet/msg/FakeLeadChannel.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/msg/FakeLeadChannel.java rename to fleetd/src/test/java/dev/ltms/fleet/msg/FakeLeadChannel.java diff --git a/bridged/src/test/java/dev/ltms/fleet/msg/InMemoryReplyInboxTest.java b/fleetd/src/test/java/dev/ltms/fleet/msg/InMemoryReplyInboxTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/msg/InMemoryReplyInboxTest.java rename to fleetd/src/test/java/dev/ltms/fleet/msg/InMemoryReplyInboxTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/msg/LeadCoordLoopTest.java b/fleetd/src/test/java/dev/ltms/fleet/msg/LeadCoordLoopTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/msg/LeadCoordLoopTest.java rename to fleetd/src/test/java/dev/ltms/fleet/msg/LeadCoordLoopTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/msg/LeadHeartbeatLoopTest.java b/fleetd/src/test/java/dev/ltms/fleet/msg/LeadHeartbeatLoopTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/msg/LeadHeartbeatLoopTest.java rename to fleetd/src/test/java/dev/ltms/fleet/msg/LeadHeartbeatLoopTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/msg/LeadMailboxTest.java b/fleetd/src/test/java/dev/ltms/fleet/msg/LeadMailboxTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/msg/LeadMailboxTest.java rename to fleetd/src/test/java/dev/ltms/fleet/msg/LeadMailboxTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/msg/MessageServiceTest.java b/fleetd/src/test/java/dev/ltms/fleet/msg/MessageServiceTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/msg/MessageServiceTest.java rename to fleetd/src/test/java/dev/ltms/fleet/msg/MessageServiceTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/msg/RendezvousTest.java b/fleetd/src/test/java/dev/ltms/fleet/msg/RendezvousTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/msg/RendezvousTest.java rename to fleetd/src/test/java/dev/ltms/fleet/msg/RendezvousTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/msg/ReplyPushLoopTest.java b/fleetd/src/test/java/dev/ltms/fleet/msg/ReplyPushLoopTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/msg/ReplyPushLoopTest.java rename to fleetd/src/test/java/dev/ltms/fleet/msg/ReplyPushLoopTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/msg/TestTurnTokens.java b/fleetd/src/test/java/dev/ltms/fleet/msg/TestTurnTokens.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/msg/TestTurnTokens.java rename to fleetd/src/test/java/dev/ltms/fleet/msg/TestTurnTokens.java diff --git a/bridged/src/test/java/dev/ltms/fleet/peer/CharterReceiptTest.java b/fleetd/src/test/java/dev/ltms/fleet/peer/CharterReceiptTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/peer/CharterReceiptTest.java rename to fleetd/src/test/java/dev/ltms/fleet/peer/CharterReceiptTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/peer/MemberRoleTest.java b/fleetd/src/test/java/dev/ltms/fleet/peer/MemberRoleTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/peer/MemberRoleTest.java rename to fleetd/src/test/java/dev/ltms/fleet/peer/MemberRoleTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/placement/BackendQuarantineTest.java b/fleetd/src/test/java/dev/ltms/fleet/placement/BackendQuarantineTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/placement/BackendQuarantineTest.java rename to fleetd/src/test/java/dev/ltms/fleet/placement/BackendQuarantineTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/placement/PlacementPolicyTest.java b/fleetd/src/test/java/dev/ltms/fleet/placement/PlacementPolicyTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/placement/PlacementPolicyTest.java rename to fleetd/src/test/java/dev/ltms/fleet/placement/PlacementPolicyTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/rest/FleetAppAuthTest.java b/fleetd/src/test/java/dev/ltms/fleet/rest/FleetAppAuthTest.java similarity index 96% rename from bridged/src/test/java/dev/ltms/fleet/rest/FleetAppAuthTest.java rename to fleetd/src/test/java/dev/ltms/fleet/rest/FleetAppAuthTest.java index 881db6f..28db15c 100644 --- a/bridged/src/test/java/dev/ltms/fleet/rest/FleetAppAuthTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/rest/FleetAppAuthTest.java @@ -54,13 +54,13 @@ class FleetAppAuthTest { private int start(long pid, boolean tokenMode, String token) { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile wcfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", null, - "tab", "bridged-workers", "worker: {profile} #{n}", null, null, null); + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", null, + "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); AgentControl agents = new AgentControl(herdr); ClaudeCodeLauncher workers = new ClaudeCodeLauncher( agents, new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(wcfg.profile(), wcfg), wcfg.profile(), - k -> "BRIDGED_WORKER_TOKEN".equals(k) ? "tok-abc" : null); + k -> "FLEETD_WORKER_TOKEN".equals(k) ? "tok-abc" : null); SessionManager sessions = new SessionManager(workers, new FakeWorktrees()); Injector injector = new Injector(agents); MessageService messages = new MessageService(agents, injector, new Rendezvous()); @@ -207,8 +207,8 @@ class FleetAppAuthTest { FakeHerdr herdr = new FakeHerdr(); AgentControl agents = new AgentControl(herdr); FleetConfig.Profile wcfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", null, - "tab", "bridged-workers", "worker: {profile} #{n}", null, null, null); + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", null, + "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); ClaudeCodeLauncher workers = new ClaudeCodeLauncher( agents, new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(wcfg.profile(), wcfg), wcfg.profile(), _ -> "tok"); diff --git a/bridged/src/test/java/dev/ltms/fleet/rest/FleetAppTest.java b/fleetd/src/test/java/dev/ltms/fleet/rest/FleetAppTest.java similarity index 97% rename from bridged/src/test/java/dev/ltms/fleet/rest/FleetAppTest.java rename to fleetd/src/test/java/dev/ltms/fleet/rest/FleetAppTest.java index 5e3778b..d0d098b 100644 --- a/bridged/src/test/java/dev/ltms/fleet/rest/FleetAppTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/rest/FleetAppTest.java @@ -65,13 +65,13 @@ class FleetAppTest { private int start(FakeHerdr herdr, String workerBaseUrl, Set allow, String placement, Worktrees worktrees) { FleetConfig.Profile wcfg = new FleetConfig.Profile( - "ltms-local", workerBaseUrl, "coder", null, "BRIDGED_WORKER_TOKEN", null, - placement, "bridged-workers", "worker: {profile} #{n}", null, null, null); + "ltms-local", workerBaseUrl, "coder", null, "FLEETD_WORKER_TOKEN", null, + placement, "fleet", "worker: {profile} #{n}", null, null, null); AgentControl agents = new AgentControl(herdr); ClaudeCodeLauncher workers = new ClaudeCodeLauncher( agents, new WorkspaceControl(herdr), new SubscriptionGuard(allow), Map.of(wcfg.profile(), wcfg), wcfg.profile(), - k -> "BRIDGED_WORKER_TOKEN".equals(k) ? "tok-abc" : null); + k -> "FLEETD_WORKER_TOKEN".equals(k) ? "tok-abc" : null); SessionManager sessions = new SessionManager(workers, worktrees); this.presence = sessions.asPresence(); Injector injector = new Injector(agents); @@ -250,13 +250,13 @@ class FleetAppTest { void spawnAtMaxLoadIs503WithTheCapacityReasonNotABare500() throws Exception { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile wcfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", null, - "tab", "bridged-workers", "worker: {profile} #{n}", null, + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", null, + "tab", "fleet", "worker: {profile} #{n}", null, null, null, null, null, null, null, null, 0, null, null, null, null); Map profiles = Map.of(wcfg.profile(), wcfg); ClaudeCodeLauncher delegate = new ClaudeCodeLauncher( new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), - profiles, wcfg.profile(), k -> "BRIDGED_WORKER_TOKEN".equals(k) ? "tok-abc" : null); + profiles, wcfg.profile(), k -> "FLEETD_WORKER_TOKEN".equals(k) ? "tok-abc" : null); CompositePeerLauncher workers = new CompositePeerLauncher( List.of(delegate), wcfg.profile(), profiles, PlacementPolicies.fixed(), _ -> 0); SessionManager sessions = new SessionManager(workers, new GitWorktrees()); @@ -281,8 +281,8 @@ class FleetAppTest { @Test void spawnWorkerReusesExistingWorkerSpace() throws Exception { - // A space labelled "bridged-workers" already exists → no second workspace.create. - FakeHerdr herdr = new FakeHerdr().withWorkspace("w9", "bridged-workers"); + // A space labelled "fleet" already exists → no second workspace.create. + FakeHerdr herdr = new FakeHerdr().withWorkspace("w9", "fleet"); int port = start(herdr, "http://gx00.gw:8000", Set.of("gx00.gw")); assertEquals(201, req(port, "POST", "/members").statusCode()); diff --git a/bridged/src/test/java/dev/ltms/fleet/session/FakeWorktrees.java b/fleetd/src/test/java/dev/ltms/fleet/session/FakeWorktrees.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/session/FakeWorktrees.java rename to fleetd/src/test/java/dev/ltms/fleet/session/FakeWorktrees.java diff --git a/bridged/src/test/java/dev/ltms/fleet/session/GitWorktreesTest.java b/fleetd/src/test/java/dev/ltms/fleet/session/GitWorktreesTest.java similarity index 100% rename from bridged/src/test/java/dev/ltms/fleet/session/GitWorktreesTest.java rename to fleetd/src/test/java/dev/ltms/fleet/session/GitWorktreesTest.java diff --git a/bridged/src/test/java/dev/ltms/fleet/session/SessionManagerTest.java b/fleetd/src/test/java/dev/ltms/fleet/session/SessionManagerTest.java similarity index 99% rename from bridged/src/test/java/dev/ltms/fleet/session/SessionManagerTest.java rename to fleetd/src/test/java/dev/ltms/fleet/session/SessionManagerTest.java index e49cb8b..89bfc87 100644 --- a/bridged/src/test/java/dev/ltms/fleet/session/SessionManagerTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/session/SessionManagerTest.java @@ -38,8 +38,8 @@ class SessionManagerTest { private SessionManager sessionManager(FakeHerdr herdr) { FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "ltms-local"), "tab", "bridged-workers", + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "ltms-local"), "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); ClaudeCodeLauncher workers = new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null); @@ -56,8 +56,8 @@ class SessionManagerTest { private SessionManager sessionManager(FakeHerdr herdr, Worktrees worktrees, LongSupplier clock) { FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "ltms-local"), "tab", "bridged-workers", + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "ltms-local"), "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); ClaudeCodeLauncher workers = new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null); @@ -164,8 +164,8 @@ class SessionManagerTest { private SessionManager sessionManager(FakeHerdr herdr, LongSupplier clock, int contextCap, boolean clearAfterTurn) { FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "ltms-local"), "tab", "bridged-workers", + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "ltms-local"), "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); ClaudeCodeLauncher workers = new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null); @@ -576,8 +576,8 @@ class SessionManagerTest { // Gate-enabled launcher (1 ms timeout + no-op sleeper that advances clock past deadline) FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "ltms-local"), "tab", "bridged-workers", + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "ltms-local"), "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); ClaudeCodeLauncher workers = new ClaudeCodeLauncher( new AgentControl(herdr), new WorkspaceControl(herdr), diff --git a/bridged/src/test/java/dev/ltms/fleet/session/SessionReaperTest.java b/fleetd/src/test/java/dev/ltms/fleet/session/SessionReaperTest.java similarity index 97% rename from bridged/src/test/java/dev/ltms/fleet/session/SessionReaperTest.java rename to fleetd/src/test/java/dev/ltms/fleet/session/SessionReaperTest.java index db61c3b..908e88f 100644 --- a/bridged/src/test/java/dev/ltms/fleet/session/SessionReaperTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/session/SessionReaperTest.java @@ -32,8 +32,8 @@ class SessionReaperTest { private static ClaudeCodeLauncher launcher() { FakeHerdr herdr = new FakeHerdr(); FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "ltms-local"), "tab", "bridged-workers", + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "ltms-local"), "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); return new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null); @@ -138,8 +138,8 @@ class SessionReaperTest { /** As {@link #launcher()}, on a caller-supplied herdr so the test can inspect it. */ private static ClaudeCodeLauncher launcher(FakeHerdr herdr) { FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "ltms-local"), "tab", "bridged-workers", + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "ltms-local"), "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); return new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null); diff --git a/bridged/src/test/java/dev/ltms/fleet/session/WorktreeSessionManagerTest.java b/fleetd/src/test/java/dev/ltms/fleet/session/WorktreeSessionManagerTest.java similarity index 99% rename from bridged/src/test/java/dev/ltms/fleet/session/WorktreeSessionManagerTest.java rename to fleetd/src/test/java/dev/ltms/fleet/session/WorktreeSessionManagerTest.java index 5d2a1e1..5e1b0eb 100644 --- a/bridged/src/test/java/dev/ltms/fleet/session/WorktreeSessionManagerTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/session/WorktreeSessionManagerTest.java @@ -39,8 +39,8 @@ class WorktreeSessionManagerTest { private static ClaudeCodeLauncher workerService(FakeHerdr herdr) { FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "ltms-local"), "tab", "bridged-workers", + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "ltms-local"), "tab", "fleetd-workers", "worker: {profile} #{n}", null, null, null); return new ClaudeCodeLauncher(new AgentControl(herdr), new WorkspaceControl(herdr), new SubscriptionGuard(Set.of("gx00.gw")), Map.of(cfg.profile(), cfg), cfg.profile(), _ -> null); @@ -347,8 +347,8 @@ class WorktreeSessionManagerTest { FakeWorktrees worktrees = new FakeWorktrees().withRepoRoot("/repo").withPrefix("/wt"); // Argument order matters: configDir is the 4th parameter, cwd the 11th (after mcpUrl). FleetConfig.Profile cfg = new FleetConfig.Profile( - "ltms-local", "http://gx00.gw:8000", "coder", null, "BRIDGED_WORKER_TOKEN", - List.of("ccs", "ltms-local"), "tab", "bridged-workers", + "ltms-local", "http://gx00.gw:8000", "coder", null, "FLEETD_WORKER_TOKEN", + List.of("ccs", "ltms-local"), "tab", "fleetd-workers", "worker: {profile} #{n}", null, "/pinned/dir", null); ClaudeCodeLauncher launcher = new ClaudeCodeLauncher( new AgentControl(herdr), new WorkspaceControl(herdr), diff --git a/bridged/src/test/resources/logback-test.xml b/fleetd/src/test/resources/logback-test.xml similarity index 100% rename from bridged/src/test/resources/logback-test.xml rename to fleetd/src/test/resources/logback-test.xml diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json index 6d38086..fb7e874 100644 --- a/plugin/.claude-plugin/plugin.json +++ b/plugin/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "claude-bridge", - "description": "Make a project bridge-ready: mount the bridged MCP gateway and set up standard Claude Code settings so this session can orchestrate a fleet of delegated workers. Ships no credentials.", + "description": "Make a project bridge-ready: mount the fleetd MCP gateway and set up standard Claude Code settings so this session can orchestrate a fleet of delegated workers. Ships no credentials.", "version": "0.1.0", "author": { "name": "LTMS" diff --git a/plugin/README.md b/plugin/README.md index 54efabd..a1fe065 100644 --- a/plugin/README.md +++ b/plugin/README.md @@ -1,6 +1,6 @@ # claude-bridge (Claude Code plugin) -Makes a project **bridge-ready**: mounts the `bridged` MCP gateway and applies standard Claude Code +Makes a project **bridge-ready**: mounts the `fleetd` MCP gateway and applies standard Claude Code settings, so the session can orchestrate a fleet of delegated workers. **This plugin ships no credentials.** Every secret is referenced by environment-variable *name*; @@ -8,7 +8,7 @@ the values stay with the user. Nothing the plugin writes is unsafe to commit. ## What it is not -The plugin is the **client-side setup**, not the bridge. `bridged` is a separate daemon and `herdr` +The plugin is the **client-side setup**, not the bridge. `fleetd` is a separate daemon and `herdr` is a separate PTY multiplexer, each with its own lifecycle and install. The plugin mounts an already-running daemon and tells you what is missing when one isn't there — it deliberately does not try to install system services on your behalf. @@ -30,7 +30,7 @@ Then, in the project you want to onboard: | Component | Effect | |---|---| -| `.mcp.json` | mounts `bridged` at `http://127.0.0.1:8765/mcp` for any session with the plugin enabled | +| `.mcp.json` | mounts `fleetd` at `http://127.0.0.1:8765/mcp` for any session with the plugin enabled | | `skills/setup` | `/claude-bridge:setup` — preflight, project settings, credential guidance, and verification | Because the plugin carries its own `.mcp.json`, an installed plugin needs no project-level MCP diff --git a/plugin/skills/setup/SKILL.md b/plugin/skills/setup/SKILL.md index 65b7d52..64180d5 100644 --- a/plugin/skills/setup/SKILL.md +++ b/plugin/skills/setup/SKILL.md @@ -1,12 +1,12 @@ --- name: setup -description: Make the current project bridge-ready — check the prerequisites, mount the bridged MCP gateway into the project's .mcp.json, apply standard Claude Code settings, and verify this session resolves as the primary. Writes no credentials. Load this when asked to set up, install, configure, or onboard a project onto claude-bridge, or when fleet_* tools are expected but absent. +description: Make the current project bridge-ready — check the prerequisites, mount the fleetd MCP gateway into the project's .mcp.json, apply standard Claude Code settings, and verify this session resolves as the primary. Writes no credentials. Load this when asked to set up, install, configure, or onboard a project onto claude-bridge, or when fleet_* tools are expected but absent. --- # Bridge setup — make this project bridge-ready This skill configures **the project you are currently in** so that this Claude Code session can -orchestrate a fleet of delegated workers through `bridged`. +orchestrate a fleet of delegated workers through `fleetd`. **It writes no credentials, ever.** Every secret is referenced by environment-variable *name*, and the user exports the value themselves. Nothing this skill creates is unsafe to commit. If you are @@ -36,7 +36,7 @@ a time. command -v herdr && herdr --version 2>&1 | head -1 || echo "MISSING: herdr" command -v ccs && ccs version 2>&1 | head -1 || echo "MISSING: ccs (needed for worker profiles)" command -v codex && codex --version 2>&1 | head -1 || echo "absent: codex (optional)" -curl -s -m 5 http://127.0.0.1:8765/healthz || echo "MISSING: bridged daemon is not reachable" +curl -s -m 5 http://127.0.0.1:8765/healthz || echo "MISSING: fleetd daemon is not reachable" ``` A healthy daemon answers with its status **and the herdr protocol it negotiated**: @@ -48,7 +48,7 @@ A healthy daemon answers with its status **and the herdr protocol it negotiated* | Missing | What to tell the user | |---|---| | `herdr` | The PTY multiplexer that owns worker terminals. Install it first; nothing else works without it. | -| `bridged` | The daemon. It is a separate service, not part of this plugin — the plugin only *mounts* it. Point the user at the project's own install instructions. | +| `fleetd` | The daemon. It is a separate service, not part of this plugin — the plugin only *mounts* it. Point the user at the project's own install instructions. | | `ccs` | Only needed to launch worker profiles. The bridge itself will still start. | | `codex` | Optional. Only needed if this fleet will run Codex peers. | @@ -136,7 +136,7 @@ collect or store them. | Variable | Needed for | Notes | |---|---|---| -| `BRIDGED_WORKER_TOKEN` | authenticating a worker to the daemon | only when the daemon is configured with `tokenEnv` | +| `FLEETD_WORKER_TOKEN` | authenticating a worker to the daemon | only when the daemon is configured with `tokenEnv` | | `GITEA_TOKEN` / equivalent | letting a worker open its own PR | **minimal `write:repository` scope** — see below | | `GITEA_HOST` | the forge base URL | no secret; safe anywhere | @@ -214,7 +214,7 @@ interactively; leave anything the bridge spawns isolated. Always `--dry-run` fir State plainly: ``` -prereqs: herdr · bridged · ccs · codex +prereqs: herdr · fleetd · ccs · codex written: role: spawn: diff --git a/scripts/bridged-launchd-wrapper.sh b/scripts/fleetd-launchd-wrapper.sh similarity index 77% rename from scripts/bridged-launchd-wrapper.sh rename to scripts/fleetd-launchd-wrapper.sh index 3c54527..746bb23 100755 --- a/scripts/bridged-launchd-wrapper.sh +++ b/scripts/fleetd-launchd-wrapper.sh @@ -8,8 +8,8 @@ # A daemon started that way boots fine and looks healthy; the failure is invisible until a worker # tries to open a PR (WORKER_GITEA_TOKEN empty) or a gateway profile gets a 401 (AI_GATEWAY_TOKEN # empty) — hours later, with nothing tying the two together (CB-591, CLAUDE.md "Redeploying the -# daemon"). Bridged now also logs which required secret names resolved at startup (see -# Bridged.reportRequiredSecrets), but that log line can only tell the truth if the tokens had a +# daemon"). Fleetd now also logs which required secret names resolved at startup (see +# Fleetd.reportRequiredSecrets), but that log line can only tell the truth if the tokens had a # chance to be sourced in the first place — which is this script's entire job. # # So: launchd execs THIS script instead of java directly. This script execs a login shell @@ -18,14 +18,14 @@ # StandardOut/ErrorPath all still see the one process they expect. # # The plist passes the full command as THIS script's own arguments, e.g.: -# ProgramArguments = [ .../bridged-launchd-wrapper.sh, /path/to/java, -jar, /path/to/bridged.jar, -# bridged.yaml ] +# ProgramArguments = [ .../fleetd-launchd-wrapper.sh, /path/to/java, -jar, /path/to/fleetd.jar, +# fleetd.yaml ] # so the wrapper stays generic and the actual command lives in exactly one place (the plist), not # duplicated here. set -euo pipefail if [ "$#" -eq 0 ]; then - echo "bridged-launchd-wrapper.sh: no command given — check the plist's ProgramArguments" >&2 + echo "fleetd-launchd-wrapper.sh: no command given — check the plist's ProgramArguments" >&2 exit 2 fi diff --git a/scripts/probe-member-credentials.sh b/scripts/probe-member-credentials.sh index 8dabaea..209a94b 100755 --- a/scripts/probe-member-credentials.sh +++ b/scripts/probe-member-credentials.sh @@ -127,7 +127,7 @@ How to read this: * GITEA_ACCESS_TOKEN is the control. CB-592 replaces it with a blocked sentinel, so its hash should DIFFER between the two readings. If it matches, CB-592 is not working and that is the most urgent thing on this page. - * AI_GATEWAY_TOKEN matching is expected and correct, not a leak: bridged.yaml names it in + * AI_GATEWAY_TOKEN matching is expected and correct, not a leak: fleetd.yaml names it in `tokenEnv:` for the local and gx profiles, so a member reaching the gateway is by design. * A name that is set here but is NOT in the list above will not appear at all. The list was recorded on 2026-08-16 and does not update itself. Anything added to secrets.sh since then is diff --git a/scripts/redeploy-bridged.sh b/scripts/redeploy-fleetd.sh similarity index 90% rename from scripts/redeploy-bridged.sh rename to scripts/redeploy-fleetd.sh index ae7c511..a2ee281 100755 --- a/scripts/redeploy-bridged.sh +++ b/scripts/redeploy-fleetd.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Rebuild and restart the bridged daemon. +# Rebuild and restart the fleetd daemon. # # A merge is not a deployment: the running daemon holds the jar it was started with, so code merged # to main does nothing until this runs. See CLAUDE.md -> "Redeploying the daemon". @@ -12,7 +12,7 @@ # WORKER_GITEA_TOKEN (workers cannot open a PR) and AI_GATEWAY_TOKEN (401 at llm.ltms.dev). # Both are read from the DAEMON's own environment at spawn time, so a value added to # secrets.sh after startup is absent. Nothing logs this here, so the script checks and says -# so — and since CB-594, bridged's own startup log says so too, by env var name. +# so — and since CB-594, fleetd's own startup log says so too, by env var name. # 3. An old daemon that never actually died looks identical from the outside, so the script waits # for the process to exit and for the port to free before it starts a new one. # 4. "It started" is not "it works": the script polls /healthz until it answers, and reports the @@ -20,7 +20,7 @@ # mismatch. # 5. Restarting under live members drops their tickets, so the script refuses unless you confirm # the fleet is drained. -# 6. CB-594 — the launchd agent (deploy/dev.ltms.bridged.plist), if installed and loaded, is a +# 6. CB-594 — the launchd agent (deploy/dev.ltms.fleetd.plist), if installed and loaded, is a # SECOND supervisor: its KeepAlive.SuccessfulExit=false restarts the daemon on any nonzero # exit, and a bare SIGTERM makes this JVM exit 143 even with its shutdown hook running to # completion (measured — see the CB-594 report). A plain `kill` here would race launchd's own @@ -29,30 +29,30 @@ # at any moment is whichever one you asked to act, never both. # # Usage: -# scripts/redeploy-bridged.sh # build, confirm, restart, verify -# scripts/redeploy-bridged.sh --yes # skip the drain confirmation (fleet already checked) -# scripts/redeploy-bridged.sh --no-build # restart the jar already on disk -# scripts/redeploy-bridged.sh --check # report state and exit; changes nothing +# scripts/redeploy-fleetd.sh # build, confirm, restart, verify +# scripts/redeploy-fleetd.sh --yes # skip the drain confirmation (fleet already checked) +# scripts/redeploy-fleetd.sh --no-build # restart the jar already on disk +# scripts/redeploy-fleetd.sh --check # report state and exit; changes nothing # # Exits non-zero on any failure. A failed build never stops the running daemon. set -euo pipefail REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -BRIDGED="$REPO/bridged" -JAR="$BRIDGED/target/bridged.jar" -OUT="$BRIDGED/bridged.out" -# Matches BOTH the absolute form and the relative `java -jar target/bridged.jar` a hand-start -# produces from inside bridged/. Anchoring on the absolute path alone was a real bug: the daemon +MODULE="$REPO/fleetd" +JAR="$MODULE/target/fleetd.jar" +OUT="$MODULE/fleetd.out" +# Matches BOTH the absolute form and the relative `java -jar target/fleetd.jar` a hand-start +# produces from inside fleetd/. Anchoring on the absolute path alone was a real bug: the daemon # restarted correctly and the script still reported "no process appeared", because it launched with # a relative path and then looked for an absolute one. -PATTERN='target/bridged.jar' +PATTERN='target/fleetd.jar' HEALTH='http://127.0.0.1:8765/healthz' STOP_WAIT=30 # seconds to wait for a clean exit before reporting failure HEALTH_WAIT=60 # seconds to wait for /healthz to answer after start # CB-594: the launchd agent this script must not fight with (see trap 6 above). -LAUNCHD_LABEL='dev.ltms.bridged' +LAUNCHD_LABEL='dev.ltms.fleetd' LAUNCHD_PLIST="$HOME/Library/LaunchAgents/$LAUNCHD_LABEL.plist" DO_BUILD=1; ASSUME_YES=0; CHECK_ONLY=0 @@ -82,7 +82,7 @@ launchd_loaded() { launchctl list "$LAUNCHD_LABEL" >/dev/null 2>&1; } # CB-600: the script computes its own log path from where it sits on disk (REPO, above); the # plist hard-codes an absolute StandardOutPath. Nothing forced the two to agree — if this script # were ever run from a checkout other than the one the loaded plist names, launchd would start and -# log the daemon correctly, while every check below (the fresh "bridged listening" line, the +# log the daemon correctly, while every check below (the fresh "fleetd listening" line, the # ERROR-count scan) would read a different, empty or stale file and the script would report a # clean restart while the daemon crash-loops. Pure and side-effect-free besides `die`/`ok` — reads # the two paths, resolves them, compares — so it never touches launchd or the daemon and can be @@ -108,7 +108,7 @@ check_log_path_matches_plist() { but the loaded plist's StandardOutPath is $plist_out (resolved: ${resolved_plist_out:-}) Under supervision the daemon writes to the PLIST's path, not necessarily this script's — every - post-restart check below (the fresh 'bridged listening' line, the ERROR-count scan) would read + post-restart check below (the fresh 'fleetd listening' line, the ERROR-count scan) would read the wrong file and could report a clean restart while the daemon crash-loops. Fix the mismatch (move this checkout to match the plist, or edit the plist's StandardOutPath/StandardErrorPath) before redeploying supervised." @@ -119,7 +119,7 @@ check_log_path_matches_plist() { # CB-600: sourceable for testing. When this file is SOURCED (not executed) it stops here — nothing # below runs — so a test harness can `source` it to call check_log_path_matches_plist (or the # other pure helpers above) against a throwaway plist fixture without ever reaching the mutating -# flow (build/stop/start) or touching the real daemon or launchd. On a normal `./redeploy-bridged.sh` +# flow (build/stop/start) or touching the real daemon or launchd. On a normal `./redeploy-fleetd.sh` # invocation `(return 0 2>/dev/null)` fails (return is illegal at top level of an executed script), # so this whole block is a no-op and every line below still runs exactly as before. if (return 0 2>/dev/null); then @@ -180,11 +180,11 @@ else fi # Third variable, same trap (CB-635). broker.uriEnv names the env var holding the AMQP URI, so the -# password stays out of bridged.yaml — but that moves the failure into the environment. If the +# password stays out of fleetd.yaml — but that moves the failure into the environment. If the # variable is empty the daemon still starts: since #152 it warns and falls back to the in-memory # reply inbox, so nothing crashes and replies simply stop surviving a restart. Only this check says # so before the fact. Read the name out of the config so a renamed key cannot make the check lie. -BROKER_URI_ENV=$(sed -n 's/^[[:space:]]*uriEnv:[[:space:]]*\([A-Za-z_][A-Za-z0-9_]*\).*/\1/p' "$BRIDGED/bridged.yaml" | head -1) +BROKER_URI_ENV=$(sed -n 's/^[[:space:]]*uriEnv:[[:space:]]*\([A-Za-z_][A-Za-z0-9_]*\).*/\1/p' "$MODULE/fleetd.yaml" | head -1) if [ -z "$BROKER_URI_ENV" ]; then ok "no broker.uriEnv configured — reply inbox is in-memory by design" elif zsh -lc "[ -n \"\${$BROKER_URI_ENV:-}\" ]" 2>/dev/null; then @@ -205,9 +205,9 @@ fi if [ "$DO_BUILD" = 1 ]; then say "build" - BUILD_LOG="$(mktemp -t bridged-build)" + BUILD_LOG="$(mktemp -t fleetd-build)" echo " log: $BUILD_LOG" - if ! mvn -f "$BRIDGED/pom.xml" clean install > "$BUILD_LOG" 2>&1; then + if ! mvn -f "$MODULE/pom.xml" clean install > "$BUILD_LOG" 2>&1; then grep -E 'ERROR|BUILD FAILURE|Tests run:.*Failures: [1-9]|Tests run:.*Errors: [1-9]' "$BUILD_LOG" \ | head -20 || true die "build failed — the running daemon was NOT touched. Full log: $BUILD_LOG" @@ -279,10 +279,10 @@ fi # ------------------------------------------------------------------ start # Unsupervised: login shell (zsh -l) is what puts the secrets on the daemon's environment, and cwd -# must be bridged/ because the daemon resolves bridged.yaml, logs/ and target/ relative to it. -# Supervised: launchd does both — deploy/dev.ltms.bridged.plist points ProgramArguments at -# scripts/bridged-launchd-wrapper.sh (CB-594), which is what execs the login shell in launchd's -# place, and WorkingDirectory in the plist already pins bridged/. +# must be fleetd/ because the daemon resolves fleetd.yaml, logs/ and target/ relative to it. +# Supervised: launchd does both — deploy/dev.ltms.fleetd.plist points ProgramArguments at +# scripts/fleetd-launchd-wrapper.sh (CB-594), which is what execs the login shell in launchd's +# place, and WorkingDirectory in the plist already pins fleetd/. say "start" if [ "$SUPERVISED" = 1 ]; then @@ -306,7 +306,7 @@ if [ "$SUPERVISED" = 1 ]; then fi else # Absolute jar path so `ps` names which checkout is running. - ( cd "$BRIDGED" && zsh -lc "nohup java -jar '$JAR' >> bridged.out 2>&1 &" ) + ( cd "$MODULE" && zsh -lc "nohup java -jar '$JAR' >> fleetd.out 2>&1 &" ) fi for _ in $(seq 10); do @@ -349,10 +349,10 @@ fi # A fresh listening line, strictly after the restart mark. An old daemon that never died would # otherwise let an old line pass for a new one. -if tail -n "+$((RESTART_MARK + 1))" "$OUT" 2>/dev/null | grep -q 'bridged listening'; then - ok "$(tail -n "+$((RESTART_MARK + 1))" "$OUT" | grep 'bridged listening' | tail -1)" +if tail -n "+$((RESTART_MARK + 1))" "$OUT" 2>/dev/null | grep -q 'fleetd listening'; then + ok "$(tail -n "+$((RESTART_MARK + 1))" "$OUT" | grep 'fleetd listening' | tail -1)" else - warn "no fresh 'bridged listening' line after the restart — check $OUT yourself" + warn "no fresh 'fleetd listening' line after the restart — check $OUT yourself" fi # Config keys the daemon accepted or deferred at boot. This is usually WHY you restarted. diff --git a/scripts/rename-checkout.sh b/scripts/rename-checkout.sh index 69dbbc7..93509ed 100755 --- a/scripts/rename-checkout.sh +++ b/scripts/rename-checkout.sh @@ -6,7 +6,7 @@ # name. Renaming it by hand misses surfaces, because the absolute path is written down in more # places than the directory itself: # -# 1. The launchd agent (~/Library/LaunchAgents/dev.ltms.bridged.plist) hard-codes absolute paths +# 1. The launchd agent (~/Library/LaunchAgents/dev.ltms.fleetd.plist) hard-codes absolute paths # to the wrapper script and the jar. Move the checkout without fixing it and the daemon never # starts again after a reboot. # 2. Every git worktree carries a `.git` FILE with an ABSOLUTE pointer into the main checkout @@ -15,13 +15,13 @@ # 3. Claude Code keys saved sessions and memory by a slug derived from the working directory, # with `/` and `.` replaced by `-`. Move the checkout and it computes a NEW slug, finds # nothing, and silently starts empty — every saved session is still on disk, just unreachable. -# 4. bridged/bridged.yaml is gitignored, so it survives only in the live checkout and holds +# 4. fleetd/fleetd.yaml is gitignored, so it survives only in the live checkout and holds # `fleet.leaders.*.cwd` and `configDir` — both absolute, both old. # 5. A running daemon holds the old paths open. Moving underneath it corrupts its state, so the # daemon stops FIRST, and the script waits for the process to actually exit rather than -# assuming (same trap as redeploy-bridged.sh). +# assuming (same trap as redeploy-fleetd.sh). # 6. An old daemon that never died looks identical from the outside, so verification polls -# /healthz AND demands a FRESH "bridged listening" log line dated after the restart, anchored +# /healthz AND demands a FRESH "fleetd listening" log line dated after the restart, anchored # to a line-count marker taken before anything moved. # # Three more surfaces hold the old path but this script REPORTS them and never rewrites them. @@ -54,9 +54,9 @@ set -euo pipefail OLD_PATH="/Users/dai.ha/LTMS/claude-bridge" NEW_PATH="/Users/dai.ha/LTMS/fleetd" -BRIDGED_SUB="bridged" # daemon lives at /bridged/ -JAR_NAME="bridged.jar" -OUT_NAME="bridged.out" +MODULE_SUB="fleetd" # daemon lives at /fleetd/ +JAR_NAME="fleetd.jar" +OUT_NAME="fleetd.out" CC_INSTANCE="ltms" CC_PROJECTS="$HOME/.ccs/instances/$CC_INSTANCE/projects" @@ -67,7 +67,7 @@ HERDR_SESSION="$HOME/.config/herdr/session.json" JETBRAINS_ROOT="$HOME/Library/Application Support/JetBrains" JETBRAINS_FILES=(recentProjects.xml trusted-paths.xml) -LAUNCHD_LABEL='dev.ltms.bridged' +LAUNCHD_LABEL='dev.ltms.fleetd' LAUNCHD_PLIST="$HOME/Library/LaunchAgents/$LAUNCHD_LABEL.plist" HEALTH='http://127.0.0.1:8765/healthz' @@ -99,8 +99,8 @@ launchd_loaded() { launchctl list "$LAUNCHD_LABEL" >/dev/null 2>&1; } # endpoint path ever changes again. cc_slug() { printf '%s' "$1" | tr '/.' '-'; } -OLD_OUT="$OLD_PATH/$BRIDGED_SUB/$OUT_NAME" -NEW_OUT="$NEW_PATH/$BRIDGED_SUB/$OUT_NAME" +OLD_OUT="$OLD_PATH/$MODULE_SUB/$OUT_NAME" +NEW_OUT="$NEW_PATH/$MODULE_SUB/$OUT_NAME" # Files under a directory that contain the literal old path, with a hit count each. Read-only. # Skips .git internals, build output and node_modules: they are generated, huge, and repaired by @@ -391,7 +391,7 @@ else fi # ------------------------------------- rewrite gitignored config, if it survived -YAML="$NEW_PATH/$BRIDGED_SUB/bridged.yaml" +YAML="$NEW_PATH/$MODULE_SUB/fleetd.yaml" if [ -f "$YAML" ]; then if grep -qF "$OLD_PATH" "$YAML"; then cp "$YAML" "$YAML.pre-rename.bak" @@ -425,9 +425,9 @@ say "start" if [ "$SUPERVISED" = 1 ]; then launchctl load -w "$LAUNCHD_PLIST" || die "launchctl load failed — recover with: launchctl load -w \"$LAUNCHD_PLIST\"" else - JAR="$NEW_PATH/$BRIDGED_SUB/target/$JAR_NAME" + JAR="$NEW_PATH/$MODULE_SUB/target/$JAR_NAME" [ -f "$JAR" ] || die "no jar at $JAR — build in the new location, then rerun" - ( cd "$NEW_PATH/$BRIDGED_SUB" && zsh -lc "nohup java -jar '$JAR' >> $OUT_NAME 2>&1 &" ) + ( cd "$NEW_PATH/$MODULE_SUB" && zsh -lc "nohup java -jar '$JAR' >> $OUT_NAME 2>&1 &" ) fi for _ in $(seq 10); do @@ -451,10 +451,10 @@ for _ in $(seq "$HEALTH_WAIT"); do done [ "$HEALTH_OK" = 1 ] || die "/healthz never answered within ${HEALTH_WAIT}s (last code: ${CODE:-000})" -if tail -n "+$((RESTART_MARK + 1))" "$NEW_OUT" 2>/dev/null | grep -q 'bridged listening'; then - ok "$(tail -n "+$((RESTART_MARK + 1))" "$NEW_OUT" | grep 'bridged listening' | tail -1)" +if tail -n "+$((RESTART_MARK + 1))" "$NEW_OUT" 2>/dev/null | grep -q 'fleetd listening'; then + ok "$(tail -n "+$((RESTART_MARK + 1))" "$NEW_OUT" | grep 'fleetd listening' | tail -1)" else - warn "no fresh 'bridged listening' line after the restart — check $NEW_OUT yourself" + warn "no fresh 'fleetd listening' line after the restart — check $NEW_OUT yourself" fi # ------------------------------------------------------------------- summary @@ -462,7 +462,7 @@ say "changed" echo " checkout: $OLD_PATH -> $NEW_PATH" echo " claude code state: $CC_PROJECTS/$OLD_SLUG -> $CC_PROJECTS/$NEW_SLUG (when present)" echo " worktree .git ptr: rewritten where they named the old path" -[ -f "$YAML" ] && echo " bridged.yaml: rewritten (backup kept)" +[ -f "$YAML" ] && echo " fleetd.yaml: rewritten (backup kept)" launchd_installed && echo " launchd plist: rewritten (backup kept)" say "still referencing the old path (left alone on purpose)"