22ad24db6c
CI / build (push) Successful in 1m17s
Workers could not run `mvn` or `java`. Every delegated task that asked for a build came back "mvn is not on PATH", and the worker was right. Root cause: HerdrPeerLauncher seeded the worker environment with an EMPTY map, so bridged passed only the vars it explicitly set (OPENCODE_CONFIG, GITEA_TOKEN, ANTHROPIC_*) and never PATH. herdr merges that map into its own process env, so a worker inherited whatever PATH the herdr SERVER was started with. On this host that server (pid 79870, PPID 1) had been up since Jul 4 with a PATH containing neither the JDK nor Maven. Confirmed on a live worker: its PATH was byte-identical to herdr's, and the only var bridged had contributed was OPENCODE_CONFIG. The failure was invisible and non-deterministic: the fleet's capabilities depended on how a long-lived daemon happened to be launched weeks earlier. There are three herdr processes on this box with three different PATHs; the one owning the socket is the one without a toolchain. bridged itself HAD Maven on PATH the whole time — it just never passed it on. It also quietly contradicted the project's own principle that "a worker is a full peer of the primary", and the implementer skill's instruction to build, commit and open a PR. Every delegation so far has depended on the primary running the build gate. Fix: baseEnv(cfg) seeds each worker with the daemon's own PATH, then applies the profile's new optional env: map. Adapter-specific vars are layered on top and therefore win — that ordering is load-bearing, not incidental: it stops an env: entry from overwriting ANTHROPIC_BASE_URL and slipping past SubscriptionGuard, which is checked against the profile's baseUrl alone. Pinned by a test. Because the default is now the daemon's PATH, both supervision units set PATH explicitly — launchd and systemd do not source a login shell, so under CB-504 the daemon (and every worker) would otherwise get a bare /usr/bin:/bin and this bug would silently return in production. 324 tests (was 321): daemon-PATH propagation, profile env: passthrough including an explicit PATH override, and the guard-bypass ordering. Verified live: daemon restarted, worker spawned, and asked to run the tools — "Apache Maven 3.9.16", "java version 25.0.2". Previously both were absent.
81 lines
3.4 KiB
Plaintext
81 lines
3.4 KiB
Plaintext
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<!--
|
|
CB-504 — launchd agent for bridged (macOS).
|
|
|
|
This is the real supervision target today: the dogfooded daemon runs on macOS, where there is
|
|
no systemd. A systemd unit ships alongside (deploy/bridged.service) for the Linux gateways
|
|
CB-308 introduces.
|
|
|
|
Install:
|
|
cp deploy/dev.ltms.bridged.plist ~/Library/LaunchAgents/
|
|
# edit the paths + JAVA_HOME below to match this host, then:
|
|
launchctl load -w ~/Library/LaunchAgents/dev.ltms.bridged.plist
|
|
launchctl list | grep bridged
|
|
|
|
Note on ordering: launchd has no "start after herdr" primitive for user agents, and neither
|
|
does systemd in a way that survives a socket appearing late. bridged retries the herdr socket
|
|
on startup instead, so an agent that comes up before herdr converges rather than dying — that
|
|
retry is the actual fix; KeepAlive below is the backstop.
|
|
-->
|
|
<plist version="1.0">
|
|
<dict>
|
|
<key>Label</key>
|
|
<string>dev.ltms.bridged</string>
|
|
|
|
<key>ProgramArguments</key>
|
|
<array>
|
|
<string>/Users/CHANGEME/Tool/jdk-25.0.2.jdk/Contents/Home/bin/java</string>
|
|
<string>-jar</string>
|
|
<string>/Users/CHANGEME/src/claude-bridge/bridged/target/bridged.jar</string>
|
|
<string>bridged.yaml</string>
|
|
</array>
|
|
|
|
<!-- Config path in ProgramArguments is relative, so the working directory must be the module. -->
|
|
<key>WorkingDirectory</key>
|
|
<string>/Users/CHANGEME/src/claude-bridge/bridged</string>
|
|
|
|
<key>EnvironmentVariables</key>
|
|
<dict>
|
|
<key>JAVA_HOME</key>
|
|
<string>/Users/CHANGEME/Tool/jdk-25.0.2.jdk/Contents/Home</string>
|
|
<key>HERDR_SOCKET_PATH</key>
|
|
<string>/Users/CHANGEME/.config/herdr/herdr.sock</string>
|
|
<!--
|
|
PATH matters more than it looks (CB-511): bridged propagates its own PATH to every worker
|
|
it spawns, so this line decides whether the fleet can run a build at all. launchd does NOT
|
|
source .zprofile/.zshrc, so without this the daemon (and therefore every worker) gets a
|
|
bare /usr/bin:/bin and no JDK or Maven. Keep the toolchain entries first.
|
|
-->
|
|
<key>PATH</key>
|
|
<string>/Users/CHANGEME/Tool/jdk-25.0.2.jdk/Contents/Home/bin:/Users/CHANGEME/Tool/apache-maven-3.9.16/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
<!--
|
|
Worker/API tokens are NOT set here: this file is committed. Export them from a private
|
|
launchd override or a wrapper script. bridged reads the API token from the env var named
|
|
by auth.tokenEnv (default BRIDGED_API_TOKEN) and only in auth.mode: token.
|
|
-->
|
|
</dict>
|
|
|
|
<key>RunAtLoad</key>
|
|
<true/>
|
|
|
|
<!-- Restart on crash, but not in a tight loop if the config is bad (bridged fails fast on a
|
|
non-loopback bind without token auth — that is a config error, not a transient one). -->
|
|
<key>KeepAlive</key>
|
|
<dict>
|
|
<key>SuccessfulExit</key>
|
|
<false/>
|
|
</dict>
|
|
<key>ThrottleInterval</key>
|
|
<integer>10</integer>
|
|
|
|
<key>StandardOutPath</key>
|
|
<string>/Users/CHANGEME/src/claude-bridge/bridged/logs/bridged.out.log</string>
|
|
<key>StandardErrorPath</key>
|
|
<string>/Users/CHANGEME/src/claude-bridge/bridged/logs/bridged.err.log</string>
|
|
|
|
<key>ProcessType</key>
|
|
<string>Background</string>
|
|
</dict>
|
|
</plist>
|