ci / bun-nix (pull_request) Successful in 27s
ci / rust (pull_request) Failing after 33s
ci / web (pull_request) Successful in 1m10s
ci / docs-site (pull_request) Successful in 1m37s
nix / flake (pull_request) Failing after 1m28s
apple / swift (pull_request) Successful in 2m13s
apple / distribute (pull_request) Skipped
apple / screenshots (pull_request) Skipped
ci / rust-arm64 (pull_request) Successful in 5m33s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 6m47s
android / android (pull_request) Successful in 7m48s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Successful in 3m6s
Field report 2026-08-18, confirmed: the operator had moved the management API off 47990 (`PUNKTFUNK_MGMT_BIND` in host.env — the supported way to share a box with Sunshine/Apollo). The web console followed, because it reads `<config_dir>/mgmt-endpoint`, the one line the host publishes on every start with the port it REALLY bound. Nothing else did: - The plugin runner / SDK resolved `PUNKTFUNK_MGMT_URL` → literal `https://127.0.0.1:47990`. The runner is a scheduled task (Windows) / systemd unit that inherits nothing from host.env — on Windows it cannot even read it — so every plugin, and the runner's own log shipper, dialed a dead port forever. Task Running, plugins never registering, empty library, and "no logs at all". - The tray defaulted `--mgmt-port` to 47990 and told the operator to edit the autostart command line if they moved the bind. Nobody knows to do that; the tray reports a running host as unreachable. One source, two readers, no new file: - `sdk/src/config.ts::publishedMgmtUrl` reads `mgmt-endpoint`; `resolveConfig` uses it after the env override and before the 47990 default. Every plugin `connect()` follows, on every platform, with no unit/task changes. `runner-cli.ts` additionally exports it into `PUNKTFUNK_MGMT_URL` before any plugin loads, so a plugin still carrying an older vendored `@punktfunk/host` follows too (on Windows `reconcileSharedSdk` cannot refresh the read-only tree, so old copies can outlive several host upgrades). An explicit PUNKTFUNK_MGMT_URL still wins. - `pf_paths::published_mgmt_port` (std-only leaf; the tray now depends on it) parses the same line. The tray's `mgmt_port` becomes `Option<u16>`: `--mgmt-port` pins, `None` re-reads the file on every poll tick, so a host restarted on a new port is picked up without relaunching the tray. Swept the rest: the web console (`windows::service::spawn_web`, the systemd unit, NixOS module) already sourced the file; the host CLI, plugin-kit (goes through the SDK), gaming-mode console and native clients derive the port from discovery / the Welcome — no other literal remained on a loopback path. The console's web port (47992) is not operator-configurable, so the tray's literal there is not the same bug. Verified: SDK 83 tests pass (4 new: absent file → default, published line followed, env wins, blank = unset), `tsc` clean, biome clean; `pf-paths` unit test; `cargo fmt --check` clean; `cargo clippy -p pf-paths -D warnings` clean; `cargo check -p punktfunk-tray -p pf-paths` on Linux (docker rust:1.96) — the tray is cfg-gated off macOS. Not built on Windows from here.